mirror of
https://github.com/valyala/fasthttp.git
synced 2026-06-24 17:35:53 +03:00
Optimize request uri parsing - defer Host header reading
This commit is contained in:
@@ -160,7 +160,7 @@ func (c *Client) DoTimeout(req *Request, resp *Response, timeout time.Duration)
|
||||
// to the requested host are busy.
|
||||
func (c *Client) Do(req *Request, resp *Response) error {
|
||||
uri := req.URI()
|
||||
host := uri.Host
|
||||
host := uri.Host()
|
||||
|
||||
isTLS := false
|
||||
if bytes.Equal(uri.Scheme, strHTTPS) {
|
||||
|
||||
@@ -187,7 +187,7 @@ func (req *Request) parseURI() {
|
||||
}
|
||||
req.parsedURI = true
|
||||
|
||||
req.uri.Parse(req.Header.Host(), req.Header.RequestURI())
|
||||
req.uri.parseQuick(req.Header.RequestURI(), &req.Header)
|
||||
}
|
||||
|
||||
// PostArgs returns POST arguments.
|
||||
@@ -290,7 +290,7 @@ func isSkipResponseBody(statusCode int) bool {
|
||||
func (req *Request) Write(w *bufio.Writer) error {
|
||||
if len(req.Header.Host()) == 0 {
|
||||
uri := req.URI()
|
||||
req.Header.SetHostBytes(uri.Host)
|
||||
req.Header.SetHostBytes(uri.Host())
|
||||
req.Header.SetRequestURIBytes(uri.RequestURI())
|
||||
}
|
||||
req.Header.SetContentLength(len(req.body))
|
||||
|
||||
+2
-2
@@ -491,8 +491,8 @@ func TestRequestURI(t *testing.T) {
|
||||
req.Header.SetRequestURI(requestURI)
|
||||
|
||||
uri := req.URI()
|
||||
if string(uri.Host) != host {
|
||||
t.Fatalf("Unexpected host %q. Expected %q", uri.Host, host)
|
||||
if string(uri.Host()) != host {
|
||||
t.Fatalf("Unexpected host %q. Expected %q", uri.Host(), host)
|
||||
}
|
||||
if string(uri.PathOriginal) != expectedPathOriginal {
|
||||
t.Fatalf("Unexpected source path %q. Expected %q", uri.PathOriginal, expectedPathOriginal)
|
||||
|
||||
@@ -345,7 +345,7 @@ func (ctx *RequestCtx) Path() []byte {
|
||||
//
|
||||
// The host is valid until returning from RequestHandler.
|
||||
func (ctx *RequestCtx) Host() []byte {
|
||||
return ctx.URI().Host
|
||||
return ctx.URI().Host()
|
||||
}
|
||||
|
||||
// QueryArgs returns query arguments from RequestURI.
|
||||
|
||||
@@ -16,11 +16,6 @@ type URI struct {
|
||||
// Scheme is always lowercased.
|
||||
Scheme []byte
|
||||
|
||||
// Host part, i.e. aaa.com of http://aaa.com/foo/bar?baz=123#qwe .
|
||||
//
|
||||
// Host is always lowercased.
|
||||
Host []byte
|
||||
|
||||
// Path part, i.e. /foo/bar of http://aaa.com/foo/bar?baz=123#qwe .
|
||||
//
|
||||
// Path is always urldecoded and normalized,
|
||||
@@ -33,39 +28,66 @@ type URI struct {
|
||||
// Hash part, i.e. qwe of http://aaa.com/foo/bar?baz=123#qwe .
|
||||
Hash []byte
|
||||
|
||||
host []byte
|
||||
|
||||
queryArgs Args
|
||||
parsedQueryArgs bool
|
||||
|
||||
fullURI []byte
|
||||
requestURI []byte
|
||||
|
||||
h *RequestHeader
|
||||
}
|
||||
|
||||
// Reset clears uri.
|
||||
func (x *URI) Reset() {
|
||||
x.PathOriginal = x.PathOriginal[:0]
|
||||
x.Scheme = x.Scheme[:0]
|
||||
x.Host = x.Host[:0]
|
||||
x.Path = x.Path[:0]
|
||||
x.QueryString = x.QueryString[:0]
|
||||
x.Hash = x.Hash[:0]
|
||||
|
||||
x.host = x.host[:0]
|
||||
x.queryArgs.Reset()
|
||||
x.parsedQueryArgs = false
|
||||
|
||||
x.fullURI = x.fullURI[:0]
|
||||
x.requestURI = x.requestURI[:0]
|
||||
x.h = nil
|
||||
}
|
||||
|
||||
// Host returns host part, i.e. aaa.com of http://aaa.com/foo/bar?baz=123#qwe .
|
||||
//
|
||||
// Host is always lowercased.
|
||||
func (x *URI) Host() []byte {
|
||||
if len(x.host) == 0 && x.h != nil {
|
||||
x.host = append(x.host[:0], x.h.Host()...)
|
||||
lowercaseBytes(x.host)
|
||||
x.h = nil
|
||||
}
|
||||
return x.host
|
||||
}
|
||||
|
||||
// Parse initializes URI from the given host and uri.
|
||||
//
|
||||
// It is safe modifying host and uri buffers after the Parse call.
|
||||
func (x *URI) Parse(host, uri []byte) {
|
||||
x.parse(host, uri, nil)
|
||||
}
|
||||
|
||||
func (x *URI) parseQuick(uri []byte, h *RequestHeader) {
|
||||
x.parse(nil, uri, h)
|
||||
}
|
||||
|
||||
func (x *URI) parse(host, uri []byte, h *RequestHeader) {
|
||||
x.Reset()
|
||||
x.h = h
|
||||
|
||||
scheme, host, uri := splitHostUri(host, uri)
|
||||
x.Scheme = append(x.Scheme, scheme...)
|
||||
lowercaseBytes(x.Scheme)
|
||||
x.Host = append(x.Host, host...)
|
||||
lowercaseBytes(x.Host)
|
||||
x.host = append(x.host, host...)
|
||||
lowercaseBytes(x.host)
|
||||
|
||||
b := uri
|
||||
n := bytes.IndexByte(b, '?')
|
||||
@@ -172,7 +194,7 @@ func (x *URI) FullURI() []byte {
|
||||
}
|
||||
dst := append(x.fullURI[:0], scheme...)
|
||||
dst = append(dst, strColonSlashSlash...)
|
||||
dst = append(dst, x.Host...)
|
||||
dst = append(dst, x.Host()...)
|
||||
lowercaseBytes(dst)
|
||||
x.fullURI = append(dst, x.RequestURI()...)
|
||||
return x.fullURI
|
||||
|
||||
+3
-3
@@ -88,7 +88,7 @@ func testURIFullURI(t *testing.T, scheme, host, path, hash string, args *Args, e
|
||||
var u URI
|
||||
|
||||
u.Scheme = []byte(scheme)
|
||||
u.Host = []byte(host)
|
||||
u.host = []byte(host)
|
||||
u.Path = []byte(path)
|
||||
u.Hash = []byte(hash)
|
||||
args.CopyTo(u.QueryArgs())
|
||||
@@ -164,8 +164,8 @@ func testURIParse(t *testing.T, u *URI, host, uri,
|
||||
if !bytes.Equal(u.FullURI(), []byte(expectedURI)) {
|
||||
t.Fatalf("Unexpected uri %q. Expected %q. host=%q, uri=%q", u.FullURI(), expectedURI, host, uri)
|
||||
}
|
||||
if !bytes.Equal(u.Host, []byte(expectedHost)) {
|
||||
t.Fatalf("Unexpected host %q. Expected %q. host=%q, uri=%q", u.Host, expectedHost, host, uri)
|
||||
if !bytes.Equal(u.Host(), []byte(expectedHost)) {
|
||||
t.Fatalf("Unexpected host %q. Expected %q. host=%q, uri=%q", u.Host(), expectedHost, host, uri)
|
||||
}
|
||||
if !bytes.Equal(u.PathOriginal, []byte(expectedPathOriginal)) {
|
||||
t.Fatalf("Unexpected original path %q. Expected %q. host=%q, uri=%q", u.PathOriginal, expectedPathOriginal, host, uri)
|
||||
|
||||
Reference in New Issue
Block a user