mirror of
https://github.com/buger/goreplay.git
synced 2024-04-21 12:32:02 +00:00
Fix responses when header end line separated by multiple packets
This commit is contained in:
@@ -445,12 +445,12 @@ func (t *Listener) readPcap() {
|
||||
of = 4
|
||||
case layers.LinkTypeLoop:
|
||||
of = 4
|
||||
case layers.LinkTypeRaw:
|
||||
case layers.LinkTypeRaw, layers.LayerTypeIPv4:
|
||||
of = 0
|
||||
case layers.LinkTypeLinuxSLL:
|
||||
of = 16
|
||||
default:
|
||||
log.Println("Unknown packet layer", packet)
|
||||
log.Println("Unknown packet layer", decoder, packet)
|
||||
break
|
||||
}
|
||||
|
||||
@@ -714,8 +714,6 @@ func (t *Listener) processTCPPacket(packet *TCPPacket) {
|
||||
}
|
||||
}()
|
||||
|
||||
// log.Println("PACKET:", packet, t.seqWithData)
|
||||
|
||||
var responseRequest *TCPMessage
|
||||
var message *TCPMessage
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
func TestRawListenerInput(t *testing.T) {
|
||||
var req, resp *TCPMessage
|
||||
|
||||
listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "")
|
||||
listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "", "")
|
||||
defer listener.Close()
|
||||
|
||||
reqPacket := buildPacket(true, 1, 1, []byte("GET / HTTP/1.1\r\n\r\n"), time.Now())
|
||||
@@ -77,7 +77,7 @@ func responsePacket(prev *TCPPacket, payload []byte) *TCPPacket {
|
||||
}
|
||||
|
||||
func TestSingleAck100Continue(t *testing.T) {
|
||||
listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "")
|
||||
listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "", "")
|
||||
defer listener.Close()
|
||||
|
||||
reqPacket1 := firstPacket([]byte("POST / HTTP/1.1\r\nExpect: 100-continue\r\nContent-Length: 4\r\n\r\n"))
|
||||
@@ -96,7 +96,7 @@ func TestSingleAck100Continue(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test100ContinueWithoutWaiting(t *testing.T) {
|
||||
listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "")
|
||||
listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "", "")
|
||||
defer listener.Close()
|
||||
|
||||
req1 := firstPacket([]byte("POST / HTTP/1.1\r\nExpect: 100-continue\r\nContent-Length: 4\r\n\r\n"))
|
||||
@@ -112,7 +112,7 @@ func Test100ContinueWithoutWaiting(t *testing.T) {
|
||||
|
||||
// Client first sends data without waiting 100-continue, but once response received, generate packets based on Ack payload
|
||||
func Test100ContinueMixed(t *testing.T) {
|
||||
listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "")
|
||||
listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "", "")
|
||||
defer listener.Close()
|
||||
|
||||
req1 := firstPacket([]byte("POST / HTTP/1.1\r\nExpect: 100-continue\r\nContent-Length: 12\r\n\r\n"))
|
||||
@@ -130,7 +130,7 @@ func Test100ContinueMixed(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDoubleAck100Continue(t *testing.T) {
|
||||
listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "")
|
||||
listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "", "")
|
||||
defer listener.Close()
|
||||
|
||||
reqPacket1 := firstPacket([]byte("POST / HTTP/1.1\r\nExpect: 100-continue\r\nContent-Length: 4\r\n\r\n"))
|
||||
@@ -153,7 +153,7 @@ func TestDoubleAck100Continue(t *testing.T) {
|
||||
func TestRawListenerInputResponseByClose(t *testing.T) {
|
||||
var req, resp *TCPMessage
|
||||
|
||||
listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "")
|
||||
listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "", "")
|
||||
defer listener.Close()
|
||||
|
||||
reqPacket := buildPacket(true, 1, 1, []byte("GET / HTTP/1.1\r\n\r\n"), time.Now())
|
||||
@@ -193,7 +193,7 @@ func TestRawListenerInputResponseByClose(t *testing.T) {
|
||||
func TestRawListenerInputWithoutResponse(t *testing.T) {
|
||||
var req *TCPMessage
|
||||
|
||||
listener := NewListener("", "0", EnginePcap, false, 10*time.Millisecond, "")
|
||||
listener := NewListener("", "0", EnginePcap, false, 10*time.Millisecond, "", "")
|
||||
defer listener.Close()
|
||||
|
||||
reqPacket := buildPacket(true, 1, 1, []byte("GET / HTTP/1.1\r\n\r\n"), time.Now())
|
||||
@@ -215,7 +215,7 @@ func TestRawListenerInputWithoutResponse(t *testing.T) {
|
||||
func TestRawListenerResponse(t *testing.T) {
|
||||
var req, resp *TCPMessage
|
||||
|
||||
listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "")
|
||||
listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "", "")
|
||||
defer listener.Close()
|
||||
|
||||
reqPacket := firstPacket([]byte("GET / HTTP/1.1\r\n\r\n"))
|
||||
@@ -263,7 +263,7 @@ func get100ContinuePackets() (req []*TCPPacket, resp []*TCPPacket) {
|
||||
}
|
||||
|
||||
func TestShort100Continue(t *testing.T) {
|
||||
listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "")
|
||||
listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "", "")
|
||||
defer listener.Close()
|
||||
|
||||
req, resp := get100ContinuePackets()
|
||||
@@ -275,7 +275,7 @@ func TestShort100Continue(t *testing.T) {
|
||||
|
||||
// Response comes before Request
|
||||
func Test100ContinueWrongOrder(t *testing.T) {
|
||||
listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "")
|
||||
listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "", "")
|
||||
defer listener.Close()
|
||||
|
||||
req, resp := get100ContinuePackets()
|
||||
@@ -428,7 +428,7 @@ func permutation(n int, list []*TCPPacket) []*TCPPacket {
|
||||
|
||||
// Response comes before Request
|
||||
func TestRawListenerChunkedWrongOrder(t *testing.T) {
|
||||
listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "")
|
||||
listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "", "")
|
||||
defer listener.Close()
|
||||
|
||||
reqPacket1 := firstPacket([]byte("POST / HTTP/1.1\r\nTransfer-Encoding: chunked\r\nExpect: 100-continue\r\n\r\n"))
|
||||
@@ -498,7 +498,7 @@ func getMessage() []*TCPPacket {
|
||||
|
||||
// Response comes before Request
|
||||
func TestRawListenerBench(t *testing.T) {
|
||||
l := NewListener("", "0", EnginePcap, true, 200*time.Millisecond, "")
|
||||
l := NewListener("", "0", EnginePcap, true, 200*time.Millisecond, "", "")
|
||||
defer l.Close()
|
||||
|
||||
// Should re-construct message from all possible combinations
|
||||
|
||||
@@ -199,6 +199,7 @@ func (t *TCPMessage) checkSeqIntegrity() {
|
||||
}
|
||||
|
||||
var bEmptyLine = []byte("\r\n\r\n")
|
||||
var bBR = []byte("\r\n")
|
||||
var bChunkEnd = []byte("0\r\n\r\n")
|
||||
|
||||
func (t *TCPMessage) updateHeadersPacket() {
|
||||
@@ -215,9 +216,16 @@ func (t *TCPMessage) updateHeadersPacket() {
|
||||
}
|
||||
|
||||
for i, p := range t.packets {
|
||||
if bytes.LastIndex(p.Data, bEmptyLine) != -1 {
|
||||
t.headerPacket = i
|
||||
return
|
||||
if len(p.Data) >= len(bEmptyLine) {
|
||||
if bytes.LastIndex(p.Data, bEmptyLine) != -1 {
|
||||
t.headerPacket = i
|
||||
return
|
||||
}
|
||||
} else if bytes.Equal(p.Data, bBR) {
|
||||
if bytes.LastIndex(t.packets[i-1].Data, bBR) != -1 {
|
||||
t.headerPacket = i
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,18 +235,23 @@ func (t *TCPMessage) updateHeadersPacket() {
|
||||
// checkIfComplete returns true if all of the packets that compse the message arrived.
|
||||
func (t *TCPMessage) checkIfComplete() {
|
||||
if t.seqMissing || t.headerPacket == -1 {
|
||||
// log.Println("Seq missing", t.seqMissing, t.packets)
|
||||
return
|
||||
}
|
||||
|
||||
if t.methodType == httpMethodNotFound {
|
||||
// log.Println("Method missing", t.methodType, t.packets)
|
||||
return
|
||||
}
|
||||
|
||||
// Responses can be emitted only if we found request
|
||||
if !t.IsIncoming && t.AssocMessage == nil {
|
||||
// log.Println("Assoc not found", t)
|
||||
return
|
||||
}
|
||||
|
||||
// log.Println("Found?", t)
|
||||
|
||||
switch t.bodyType {
|
||||
case httpBodyEmpty:
|
||||
t.complete = true
|
||||
|
||||
Reference in New Issue
Block a user