diff --git a/http/httpraw/parse.go b/http/httpraw/parse.go index 8e258b4..b8b947e 100644 --- a/http/httpraw/parse.go +++ b/http/httpraw/parse.go @@ -98,6 +98,12 @@ func (hb *headerBuf) offBuf() []byte { return hb.buf[hb.off:] } +func (hb *headerBuf) skipLeadingCRLF() { + for hb.off < len(hb.buf) && (hb.buf[hb.off] == '\n' || hb.buf[hb.off] == '\r') { + hb.off++ + } +} + func (hb *headerBuf) scanLine() []byte { buf := hb.scanUntilByte('\n') if len(buf) > 0 && buf[len(buf)-1] == '\r' { @@ -122,9 +128,8 @@ func (hb *headerBuf) scanUntilByte(c byte) []byte { func (hb *headerBuf) parseFirstLineRequest(initFlags flags) (method, uri, proto headerSlice, flags flags, err error) { hb.off = 0 // Parsing first line resets offset. var b []byte - for len(b) == 0 { - b = hb.scanLine() - } + hb.skipLeadingCRLF() + b = hb.scanLine() flags = initFlags if len(b) < 5 { return method, uri, proto, flags, errNeedMore @@ -154,9 +159,8 @@ func (hb *headerBuf) parseFirstLineRequest(initFlags flags) (method, uri, proto func (hb *headerBuf) parseFirstLineResponse(initFlags flags) (statusCode, statusText headerSlice, flags flags, err error) { hb.off = 0 // Parsing first line resets offset. var b []byte - for len(b) == 0 { - b = hb.scanLine() - } + hb.skipLeadingCRLF() + b = hb.scanLine() flags = initFlags if len(b) < 5 { return statusCode, statusText, flags, errNeedMore diff --git a/x/xnet/xnet_test.go b/x/xnet/xnet_test.go index 9f56c30..a3d1102 100644 --- a/x/xnet/xnet_test.go +++ b/x/xnet/xnet_test.go @@ -28,28 +28,40 @@ func TestStackAsyncTCP_multipacket(t *testing.T) { tst := testerFrom(t, MTU) rng := rand.New(rand.NewSource(seed)) client2, sv2, clconn2, svconn2 := newTCPStacks(t, seed, MTU) - _, _, _, _ = client2, sv2, clconn2, svconn2 - tst.TestTCPSetupAndEstablish(sv, client, svconn, clconn, svPort, 1337) - tst.TestTCPClose(client, sv, clconn, svconn) - var buf [MTU]byte - for i := 0; i < 1; i++ { - payloadSize := rng.Intn(maxPktLen) + 1 + + for _, clientCloses := range []bool{true, false} { + testClose := func() { + t.Helper() + if clientCloses { + tst.TestTCPClose(client, sv, clconn, svconn) + } else { + tst.TestTCPClose(sv, client, svconn, clconn) + } + } tst.TestTCPSetupAndEstablish(sv, client, svconn, clconn, svPort, 1337) - // npkt := rng.Intn(maxNPkt-1) + 2 - a, _ := rng.Read(buf[:payloadSize]) - tst.TestTCPEstablishedSingleData(sv, client, svconn, clconn, buf[:a]) - a, _ = rng.Read(buf[:payloadSize]) - tst.TestTCPEstablishedSingleData(sv, client, svconn, clconn, buf[:a]) - // for ipkt := 0; ipkt < npkt; ipkt++ { - // a, _ := rng.Read(buf[:payloadSize]) - // tst.TestTCPEstablishedSingleData(sv, client, svconn, clconn, buf[:a]) - // } - tst.TestTCPClose(client, sv, clconn, svconn) - if t.Failed() { - t.Error("multi failed") - t.FailNow() + testClose() + var buf [MTU]byte + for i := 0; i < 20; i++ { + payloadSize := rng.Intn(maxPktLen) + 1 + tst.TestTCPSetupAndEstablish(sv, client, svconn, clconn, svPort, 1337) + // npkt := rng.Intn(maxNPkt-1) + 2 + a, _ := rng.Read(buf[:payloadSize]) + tst.TestTCPEstablishedSingleData(sv, client, svconn, clconn, buf[:a]) + a, _ = rng.Read(buf[:payloadSize]) + tst.TestTCPEstablishedSingleData(sv, client, svconn, clconn, buf[:a]) + // for ipkt := 0; ipkt < npkt; ipkt++ { + // a, _ := rng.Read(buf[:payloadSize]) + // tst.TestTCPEstablishedSingleData(sv, client, svconn, clconn, buf[:a]) + // } + testClose() + if t.Failed() { + t.Error("multi failed") + t.FailNow() + } } } + _, _, _, _ = client2, sv2, clconn2, svconn2 + } func TestStackAsyncTCP_singlepacket(t *testing.T) {