From 68815fd4175a10b43e1debcf56118a7c4bf86069 Mon Sep 17 00:00:00 2001 From: roc Date: Mon, 31 Jul 2023 17:03:23 +0800 Subject: [PATCH] Refactor: share excluded headers between http2 and http3 --- internal/header/header.go | 28 ++++++++++++++++++++++++++++ internal/http2/transport.go | 21 +-------------------- internal/http3/request_writer.go | 21 +-------------------- 3 files changed, 30 insertions(+), 40 deletions(-) diff --git a/internal/header/header.go b/internal/header/header.go index 33e779bc..4098febe 100644 --- a/internal/header/header.go +++ b/internal/header/header.go @@ -1,5 +1,7 @@ package header +import "strings" + const ( DefaultUserAgent = "req/v3 (https://github.com/imroc/req)" UserAgent = "User-Agent" @@ -14,3 +16,29 @@ const ( HeaderOderKey = "__header_order__" PseudoHeaderOderKey = "__pseudo_header_order__" ) + +var reqWriteExcludeHeader = map[string]bool{ + // Host is :authority, already sent. + // Content-Length is automatic. + "host": true, + "content-length": true, + // Per 8.1.2.2 Connection-Specific Header + // Fields, don't send connection-specific + // fields. We have already checked if any + // are error-worthy so just ignore the rest. + "connection": true, + "proxy-connection": true, + "transfer-encoding": true, + "upgrade": true, + "keep-alive": true, + // Ignore header order keys which is only used internally. + HeaderOderKey: true, + PseudoHeaderOderKey: true, +} + +func IsExcluded(key string) bool { + if reqWriteExcludeHeader[strings.ToLower(key)] { + return true + } + return false +} diff --git a/internal/http2/transport.go b/internal/http2/transport.go index 1208cbeb..75b100e3 100644 --- a/internal/http2/transport.go +++ b/internal/http2/transport.go @@ -1748,25 +1748,6 @@ func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error) } } -var reqWriteExcludeHeader = map[string]bool{ - // Host is :authority, already sent. - // Content-Length is automatic. - "host": true, - "content-length": true, - // Per 8.1.2.2 Connection-Specific Header - // Fields, don't send connection-specific - // fields. We have already checked if any - // are error-worthy so just ignore the rest. - "connection": true, - "proxy-connection": true, - "transfer-encoding": true, - "upgrade": true, - "keep-alive": true, - // Ignore header order keys which is only used internally. - header.HeaderOderKey: true, - header.PseudoHeaderOderKey: true, -} - var errNilRequestURL = errors.New("http2: Request.URI is nil") // requires cc.wmu be held. @@ -1884,7 +1865,7 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail var didUA bool for k, vv := range req.Header { - if reqWriteExcludeHeader[strings.ToLower(k)] { + if header.IsExcluded(k) { continue } else if ascii.EqualFold(k, "user-agent") { // Match Go's http1 behavior: at most one diff --git a/internal/http3/request_writer.go b/internal/http3/request_writer.go index 1f6ce445..443b34c2 100644 --- a/internal/http3/request_writer.go +++ b/internal/http3/request_writer.go @@ -71,25 +71,6 @@ func (w *requestWriter) writeHeaders(wr io.Writer, req *http.Request, gzip bool, return err } -var reqWriteExcludeHeader = map[string]bool{ - // Host is :authority, already sent. - // Content-Length is automatic. - "host": true, - "content-length": true, - // Per 8.1.2.2 Connection-Specific Header - // Fields, don't send connection-specific - // fields. We have already checked if any - // are error-worthy so just ignore the rest. - "connection": true, - "proxy-connection": true, - "transfer-encoding": true, - "upgrade": true, - "keep-alive": true, - // Ignore header order keys which is only used internally. - header.HeaderOderKey: true, - header.PseudoHeaderOderKey: true, -} - // copied from net/transport.go // Modified to support Extended CONNECT: // Contrary to what the godoc for the http.Request says, @@ -207,7 +188,7 @@ func (w *requestWriter) encodeHeaders(req *http.Request, addGzipHeader bool, tra var didUA bool for k, vv := range req.Header { - if reqWriteExcludeHeader[strings.ToLower(k)] { + if header.IsExcluded(k) { continue } else if strings.EqualFold(k, "user-agent") { // Match Go's http1 behavior: at most one