-
Notifications
You must be signed in to change notification settings - Fork 218
/
userdata.go
108 lines (93 loc) · 2.97 KB
/
userdata.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
package types
import (
"io"
"net/http"
"net/http/httputil"
"strings"
pdhttpUtils "github.com/projectdiscovery/utils/http"
)
// UserData is context used to identify a http
// transaction and its state like match, response etc.
type UserData struct {
ID string
Match *bool
HasResponse bool
Host string
}
// HTTPTransaction is a struct for http transaction
// it contains data of every request/response obtained
// from proxy
type HTTPTransaction struct {
Userdata UserData
RawData []byte
Data []byte
DataString string
Name string
PartSuffix string
Format string
Request *http.Request
Response *http.Response
}
// HTTPRequestResponseLog is a struct for http request and response log
// it is a processed version of http transaction for logging
// in more structured format than just raw bytes
type HTTPRequestResponseLog struct {
Timestamp string `json:"timestamp,omitempty"`
URL string `json:"url,omitempty"`
Request *HTTPRequest `json:"request,omitempty"`
Response *HTTPResponse `json:"response,omitempty"`
}
// HTTPRequest is a struct for http request
type HTTPRequest struct {
Header map[string]string `json:"header,omitempty"`
Body string `json:"body,omitempty"`
Raw string `json:"raw,omitempty"`
}
// NewHttpRequestData creates a new HttpRequest with data extracted from an http.Request
func NewHttpRequestData(req *http.Request) (*HTTPRequest, error) {
httpRequest := &HTTPRequest{
Header: make(map[string]string),
}
// Extract headers from the request
httpRequest.Header["scheme"] = req.URL.Scheme
httpRequest.Header["method"] = req.Method
httpRequest.Header["path"] = req.URL.Path
httpRequest.Header["host"] = req.URL.Host
for key, values := range req.Header {
httpRequest.Header[key] = strings.Join(values, ", ")
}
// Extract body from the request
reqBody, err := io.ReadAll(req.Body)
if err != nil {
return nil, err
}
defer req.Body.Close()
req.Body = io.NopCloser(strings.NewReader(string(reqBody)))
httpRequest.Body = string(reqBody)
// Extract raw request
reqdumpNoBody, err := httputil.DumpRequest(req, false)
if err != nil {
return nil, err
}
httpRequest.Raw = string(reqdumpNoBody)
return httpRequest, nil
}
// HTTPResponse is a struct for http response
type HTTPResponse struct {
Header map[string]string `json:"header,omitempty"`
Body string `json:"body,omitempty"`
Raw string `json:"raw,omitempty"`
}
// NewHttpResponseData creates a new HttpResponse with data extracted from an http.Response
func NewHttpResponseData(resp *pdhttpUtils.ResponseChain) (*HTTPResponse, error) {
httpResponse := &HTTPResponse{
Header: make(map[string]string),
}
// Extract headers from the response
for key, values := range resp.Response().Header {
httpResponse.Header[key] = strings.Join(values, ", ")
}
httpResponse.Body = resp.Body().String()
httpResponse.Raw = resp.Headers().String() // doesn't include body
return httpResponse, nil
}