Skip to content

Commit 95892a2

Browse files
improved hhtp parsing, fixed tls fragmented messages
1 parent d6cbb7a commit 95892a2

File tree

3 files changed

+248
-49
lines changed

3 files changed

+248
-49
lines changed

layers/http.go

Lines changed: 52 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,78 @@
11
package layers
22

33
import (
4+
"bufio"
45
"bytes"
56
"fmt"
7+
"net/http"
8+
"net/http/httputil"
9+
)
10+
11+
var (
12+
protohttp10 = []byte("HTTP/1.0")
13+
protohttp11 = []byte("HTTP/1.1")
614
)
715

816
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages
917
// port 80
1018
type HTTPMessage struct {
11-
summary []byte
12-
data []byte
19+
Request *http.Request
20+
Response *http.Response
21+
}
22+
23+
func (h *HTTPMessage) IsEmpty() bool {
24+
return h.Request == nil && h.Response == nil
1325
}
1426

1527
func (h *HTTPMessage) String() string {
28+
m := ellipsis
29+
if h.Request != nil {
30+
m, _ = httputil.DumpRequest(h.Request, false)
31+
m = joinBytes(dash, bytes.TrimRight(bytes.TrimSuffix(bytes.Join(bytes.Split(m, crlf), lfd), crlf), slfd))
32+
} else if h.Response != nil {
33+
m, _ = httputil.DumpResponse(h.Response, false)
34+
m = joinBytes(dash, bytes.TrimRight(bytes.TrimSuffix(bytes.Join(bytes.Split(m, crlf), lfd), crlf), slfd))
35+
}
1636
return fmt.Sprintf(`%s
1737
%s
18-
`, h.Summary(), h.data)
19-
}
20-
func (h *HTTPMessage) Summary() string {
21-
return fmt.Sprintf("HTTP Message: %s", h.summary)
38+
`, h.Summary(), m)
2239
}
2340

24-
func (h *HTTPMessage) ellipsify() {
25-
h.summary = contdata
26-
h.data = ellipsis
41+
func (h *HTTPMessage) Summary() string {
42+
m := fmt.Sprintf("HTTP Message: %s", contdata)
43+
if h.Request != nil {
44+
m = fmt.Sprintf("HTTP Request: %s %s%s%s %s Content-Length: %d",
45+
h.Request.Method, h.Request.Host, h.Request.URL.Path, h.Request.URL.RawQuery, h.Request.Proto, h.Request.ContentLength)
46+
} else if h.Response != nil {
47+
m = fmt.Sprintf("HTTP Response: %s %s Content-Length: %d",
48+
h.Response.Proto, h.Response.Status, h.Response.ContentLength)
49+
}
50+
return fmt.Sprintf("%s", m)
2751
}
2852

2953
func (h *HTTPMessage) Parse(data []byte) error {
3054

31-
if !bytes.Contains(data, proto) {
32-
h.ellipsify()
33-
return nil
34-
}
35-
36-
var idx int
37-
if idx = bytes.Index(data, dcrlf); idx == -1 {
38-
h.ellipsify()
55+
if !bytes.Contains(data, protohttp10) && !bytes.Contains(data, protohttp11) {
56+
h.Request = nil
57+
h.Response = nil
3958
return nil
4059
}
41-
42-
sp := bytes.Split(data[:idx], crlf)
43-
lsp := len(sp)
44-
switch {
45-
case lsp > 2:
46-
h.summary = bytes.Join(sp[:2], bspace)
47-
sp[0] = joinBytes(dash, sp[0])
48-
h.data = bytes.TrimSuffix(bytes.Join(sp, lfd), crlf)
49-
case lsp > 1:
50-
h.summary = sp[0]
51-
sp[0] = joinBytes(dash, sp[0])
52-
h.data = bytes.TrimSuffix(bytes.Join(sp, lfd), crlf)
53-
default:
54-
h.ellipsify()
60+
reader := bufio.NewReader(bytes.NewReader(data))
61+
if bytes.HasPrefix(data, protohttp11) || bytes.HasPrefix(data, protohttp10) {
62+
resp, err := http.ReadResponse(reader, nil)
63+
if err != nil {
64+
return err
65+
}
66+
h.Response = resp
67+
h.Request = nil
68+
} else {
69+
reader := bufio.NewReader(bytes.NewReader(data))
70+
req, err := http.ReadRequest(reader)
71+
if err != nil {
72+
return err
73+
}
74+
h.Request = req
75+
h.Response = nil
5576
}
5677
return nil
5778
}

layers/layers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ var (
2828
bspace = []byte(" ")
2929
dash = []byte("- ")
3030
lfd = []byte("\n- ")
31+
slfd = "\n- "
3132
lf = []byte("\n")
3233
crlf = []byte("\r\n")
3334
dcrlf = []byte("\r\n\r\n")
34-
proto = []byte("HTTP/1.1")
3535
ellipsis = []byte("...")
3636
contdata = []byte("Continuation data")
3737
)

0 commit comments

Comments
 (0)