From 5407951c0650fd8dc3b4815f2c824f0c2f61449a Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Sun, 22 Nov 2015 00:41:06 +0200 Subject: [PATCH] Do not parse raw headers when writing request headers. This should improve request proxying speed --- header.go | 10 ++++++++-- header_test.go | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/header.go b/header.go index 083e347..1bf9895 100644 --- a/header.go +++ b/header.go @@ -943,7 +943,7 @@ func (h *ResponseHeader) Write(w *bufio.Writer) error { // Write writes request header to w. func (h *RequestHeader) Write(w *bufio.Writer) error { - h.parseRawHeaders() + // there is no need in h.parseRawHeaders() here - raw headers are specially handled below. method := h.Method() w.Write(method) w.WriteByte(' ') @@ -954,6 +954,11 @@ func (h *RequestHeader) Write(w *bufio.Writer) error { w.Write(strHTTP11) w.Write(strCRLF) + if !h.rawHeadersParsed && len(h.rawHeaders) > 0 { + _, err := w.Write(h.rawHeaders) + return err + } + userAgent := h.UserAgent() if len(userAgent) == 0 { userAgent = defaultUserAgent @@ -983,7 +988,8 @@ func (h *RequestHeader) Write(w *bufio.Writer) error { writeHeaderLine(w, kv.key, kv.value) } - h.collectCookies() + // there is no need in h.collectCookies() here, since if cookies aren't collected yet, + // they all are located in h.h. n := len(h.cookies) if n > 0 { h.bufKV.value = appendRequestCookieBytes(h.bufKV.value[:0], h.cookies) diff --git a/header_test.go b/header_test.go index 56b3006..f0333a8 100644 --- a/header_test.go +++ b/header_test.go @@ -10,6 +10,51 @@ import ( "testing" ) +func TestRequestHeaderProxyWithCookie(t *testing.T) { + // Proxy request header (read it, then write it without touching any headers). + var h RequestHeader + r := bytes.NewBufferString("GET /foo HTTP/1.1\r\nFoo: bar\r\nHost: aaa.com\r\nCookie: foo=bar; bazzz=aaaaaaa; x=y\r\nCookie: aqqqqq=123\r\n\r\n") + br := bufio.NewReader(r) + if err := h.Read(br); err != nil { + t.Fatalf("unexpected error: %s", err) + } + w := &bytes.Buffer{} + bw := bufio.NewWriter(w) + if err := h.Write(bw); err != nil { + t.Fatalf("unexpected error: %s", err) + } + if err := bw.Flush(); err != nil { + t.Fatalf("unexpected error: %s", err) + } + + var h1 RequestHeader + br.Reset(w) + if err := h1.Read(br); err != nil { + t.Fatalf("unexpected error: %s", err) + } + if string(h1.RequestURI()) != "/foo" { + t.Fatalf("unexpected requestURI: %q. Expecting %q", h1.RequestURI(), "/foo") + } + if string(h1.Host()) != "aaa.com" { + t.Fatalf("unexpected host: %q. Expecting %q", h1.Host(), "aaa.com") + } + if string(h1.Peek("Foo")) != "bar" { + t.Fatalf("unexpected Foo: %q. Expecting %q", h1.Peek("Foo"), "bar") + } + if string(h1.PeekCookie("foo")) != "bar" { + t.Fatalf("unexpected coookie foo=%q. Expecting %q", h1.PeekCookie("foo"), "bar") + } + if string(h1.PeekCookie("bazzz")) != "aaaaaaa" { + t.Fatalf("unexpected cookie bazzz=%q. Expecting %q", h1.PeekCookie("bazzz"), "aaaaaaa") + } + if string(h1.PeekCookie("x")) != "y" { + t.Fatalf("unexpected cookie x=%q. Expecting %q", h1.PeekCookie("x"), "y") + } + if string(h1.PeekCookie("aqqqqq")) != "123" { + t.Fatalf("unexpected cookie aqqqqq=%q. Expecting %q", h1.PeekCookie("aqqqqq"), "123") + } +} + func TestPeekRawHeader(t *testing.T) { // empty header testPeekRawHeader(t, "", "Foo-Bar", "")