/
response.go
109 lines (96 loc) · 2.49 KB
/
response.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package httpx
import (
"strings"
"time"
"github.com/khulnasoft-lab/tlsx/pkg/tlsx/clients"
httputil "github.com/khulnasoft-lab/utils/http"
)
// Response contains the response to a server
type Response struct {
StatusCode int
Headers map[string][]string
RawData []byte // undecoded data
Data []byte // decoded data
ContentLength int
Raw string
RawHeaders string
Words int
Lines int
TLSData *clients.Response
CSPData *CSPData
HTTP2 bool
Pipeline bool
Duration time.Duration
Chain []httputil.ChainItem
}
// ChainItem request=>response
type ChainItem struct {
Request string `json:"request,omitempty"`
Response string `json:"response,omitempty"`
StatusCode int `json:"status_code,omitempty"`
Location string `json:"location,omitempty"`
RequestURL string `json:"request-url,omitempty"`
}
// GetHeader value
func (r *Response) GetHeader(name string) string {
v, ok := r.Headers[name]
if ok {
return strings.Join(v, " ")
}
return ""
}
// GetHeaderPart with offset
func (r *Response) GetHeaderPart(name, sep string) string {
v, ok := r.Headers[name]
if ok && len(v) > 0 {
tokens := strings.Split(strings.Join(v, " "), sep)
return tokens[0]
}
return ""
}
// GetChainStatusCodes from redirects
func (r *Response) GetChainStatusCodes() []int {
var statusCodes []int
for _, chainItem := range r.Chain {
statusCodes = append(statusCodes, chainItem.StatusCode)
}
return statusCodes
}
// GetChain dump the whole redirect chain as string
func (r *Response) GetChain() string {
var respchain strings.Builder
for counter, chainItem := range r.Chain {
if counter != 0 {
respchain.Write(chainItem.Request)
}
if counter < len(r.Chain)-1 {
respchain.Write(chainItem.Response)
}
}
return respchain.String()
}
// GetChainAsSlice dump the whole redirect chain as structuerd slice
func (r *Response) GetChainAsSlice() (chain []ChainItem) {
for _, chainItem := range r.Chain {
chain = append(chain, ChainItem{
Request: string(chainItem.Request),
Response: string(chainItem.Response),
StatusCode: chainItem.StatusCode,
Location: chainItem.Location,
RequestURL: chainItem.RequestURL,
})
}
return
}
// HasChain redirects
func (r *Response) HasChain() bool {
return len(r.Chain) > 1
}
// GetChainLastURL returns the final URL
func (r *Response) GetChainLastURL() string {
if r.HasChain() {
lastitem := r.Chain[len(r.Chain)-1]
return lastitem.RequestURL
}
return ""
}