From 3ac1ee16f377d31a0fb80c8dae28b6239ac4229e Mon Sep 17 00:00:00 2001 From: Terin Stock Date: Sun, 9 Mar 2025 17:47:56 +0100 Subject: [chore] remove vendor --- .../x/net/internal/httpcommon/request.go | 379 --------------------- 1 file changed, 379 deletions(-) delete mode 100644 vendor/golang.org/x/net/internal/httpcommon/request.go (limited to 'vendor/golang.org/x/net/internal/httpcommon/request.go') diff --git a/vendor/golang.org/x/net/internal/httpcommon/request.go b/vendor/golang.org/x/net/internal/httpcommon/request.go deleted file mode 100644 index 343914773..000000000 --- a/vendor/golang.org/x/net/internal/httpcommon/request.go +++ /dev/null @@ -1,379 +0,0 @@ -// Copyright 2025 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package httpcommon - -import ( - "errors" - "fmt" - "net/http" - "net/http/httptrace" - "sort" - "strconv" - "strings" - - "golang.org/x/net/http/httpguts" - "golang.org/x/net/http2/hpack" -) - -var ( - ErrRequestHeaderListSize = errors.New("request header list larger than peer's advertised limit") -) - -// EncodeHeadersParam is parameters to EncodeHeaders. -type EncodeHeadersParam struct { - Request *http.Request - - // AddGzipHeader indicates that an "accept-encoding: gzip" header should be - // added to the request. - AddGzipHeader bool - - // PeerMaxHeaderListSize, when non-zero, is the peer's MAX_HEADER_LIST_SIZE setting. - PeerMaxHeaderListSize uint64 - - // DefaultUserAgent is the User-Agent header to send when the request - // neither contains a User-Agent nor disables it. - DefaultUserAgent string -} - -// EncodeHeadersParam is the result of EncodeHeaders. -type EncodeHeadersResult struct { - HasBody bool - HasTrailers bool -} - -// EncodeHeaders constructs request headers common to HTTP/2 and HTTP/3. -// It validates a request and calls headerf with each pseudo-header and header -// for the request. -// The headerf function is called with the validated, canonicalized header name. -func EncodeHeaders(param EncodeHeadersParam, headerf func(name, value string)) (res EncodeHeadersResult, _ error) { - req := param.Request - - // Check for invalid connection-level headers. - if err := checkConnHeaders(req); err != nil { - return res, err - } - - if req.URL == nil { - return res, errors.New("Request.URL is nil") - } - - host := req.Host - if host == "" { - host = req.URL.Host - } - host, err := httpguts.PunycodeHostPort(host) - if err != nil { - return res, err - } - if !httpguts.ValidHostHeader(host) { - return res, errors.New("invalid Host header") - } - - // isNormalConnect is true if this is a non-extended CONNECT request. - isNormalConnect := false - protocol := req.Header.Get(":protocol") - if req.Method == "CONNECT" && protocol == "" { - isNormalConnect = true - } else if protocol != "" && req.Method != "CONNECT" { - return res, errors.New("invalid :protocol header in non-CONNECT request") - } - - // Validate the path, except for non-extended CONNECT requests which have no path. - var path string - if !isNormalConnect { - path = req.URL.RequestURI() - if !validPseudoPath(path) { - orig := path - path = strings.TrimPrefix(path, req.URL.Scheme+"://"+host) - if !validPseudoPath(path) { - if req.URL.Opaque != "" { - return res, fmt.Errorf("invalid request :path %q from URL.Opaque = %q", orig, req.URL.Opaque) - } else { - return res, fmt.Errorf("invalid request :path %q", orig) - } - } - } - } - - // Check for any invalid headers+trailers and return an error before we - // potentially pollute our hpack state. (We want to be able to - // continue to reuse the hpack encoder for future requests) - if err := validateHeaders(req.Header); err != "" { - return res, fmt.Errorf("invalid HTTP header %s", err) - } - if err := validateHeaders(req.Trailer); err != "" { - return res, fmt.Errorf("invalid HTTP trailer %s", err) - } - - contentLength := ActualContentLength(req) - - trailers, err := commaSeparatedTrailers(req) - if err != nil { - return res, err - } - - enumerateHeaders := func(f func(name, value string)) { - // 8.1.2.3 Request Pseudo-Header Fields - // The :path pseudo-header field includes the path and query parts of the - // target URI (the path-absolute production and optionally a '?' character - // followed by the query production, see Sections 3.3 and 3.4 of - // [RFC3986]). - f(":authority", host) - m := req.Method - if m == "" { - m = http.MethodGet - } - f(":method", m) - if !isNormalConnect { - f(":path", path) - f(":scheme", req.URL.Scheme) - } - if protocol != "" { - f(":protocol", protocol) - } - if trailers != "" { - f("trailer", trailers) - } - - var didUA bool - for k, vv := range req.Header { - if asciiEqualFold(k, "host") || asciiEqualFold(k, "content-length") { - // Host is :authority, already sent. - // Content-Length is automatic, set below. - continue - } else if asciiEqualFold(k, "connection") || - asciiEqualFold(k, "proxy-connection") || - asciiEqualFold(k, "transfer-encoding") || - asciiEqualFold(k, "upgrade") || - asciiEqualFold(k, "keep-alive") { - // 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. - continue - } else if asciiEqualFold(k, "user-agent") { - // Match Go's http1 behavior: at most one - // User-Agent. If set to nil or empty string, - // then omit it. Otherwise if not mentioned, - // include the default (below). - didUA = true - if len(vv) < 1 { - continue - } - vv = vv[:1] - if vv[0] == "" { - continue - } - } else if asciiEqualFold(k, "cookie") { - // Per 8.1.2.5 To allow for better compression efficiency, the - // Cookie header field MAY be split into separate header fields, - // each with one or more cookie-pairs. - for _, v := range vv { - for { - p := strings.IndexByte(v, ';') - if p < 0 { - break - } - f("cookie", v[:p]) - p++ - // strip space after semicolon if any. - for p+1 <= len(v) && v[p] == ' ' { - p++ - } - v = v[p:] - } - if len(v) > 0 { - f("cookie", v) - } - } - continue - } else if k == ":protocol" { - // :protocol pseudo-header was already sent above. - continue - } - - for _, v := range vv { - f(k, v) - } - } - if shouldSendReqContentLength(req.Method, contentLength) { - f("content-length", strconv.FormatInt(contentLength, 10)) - } - if param.AddGzipHeader { - f("accept-encoding", "gzip") - } - if !didUA { - f("user-agent", param.DefaultUserAgent) - } - } - - // Do a first pass over the headers counting bytes to ensure - // we don't exceed cc.peerMaxHeaderListSize. This is done as a - // separate pass before encoding the headers to prevent - // modifying the hpack state. - if param.PeerMaxHeaderListSize > 0 { - hlSize := uint64(0) - enumerateHeaders(func(name, value string) { - hf := hpack.HeaderField{Name: name, Value: value} - hlSize += uint64(hf.Size()) - }) - - if hlSize > param.PeerMaxHeaderListSize { - return res, ErrRequestHeaderListSize - } - } - - trace := httptrace.ContextClientTrace(req.Context()) - - // Header list size is ok. Write the headers. - enumerateHeaders(func(name, value string) { - name, ascii := LowerHeader(name) - if !ascii { - // Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header - // field names have to be ASCII characters (just as in HTTP/1.x). - return - } - - headerf(name, value) - - if trace != nil && trace.WroteHeaderField != nil { - trace.WroteHeaderField(name, []string{value}) - } - }) - - res.HasBody = contentLength != 0 - res.HasTrailers = trailers != "" - return res, nil -} - -// IsRequestGzip reports whether we should add an Accept-Encoding: gzip header -// for a request. -func IsRequestGzip(req *http.Request, disableCompression bool) bool { - // TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere? - if !disableCompression && - req.Header.Get("Accept-Encoding") == "" && - req.Header.Get("Range") == "" && - req.Method != "HEAD" { - // Request gzip only, not deflate. Deflate is ambiguous and - // not as universally supported anyway. - // See: https://zlib.net/zlib_faq.html#faq39 - // - // Note that we don't request this for HEAD requests, - // due to a bug in nginx: - // http://trac.nginx.org/nginx/ticket/358 - // https://golang.org/issue/5522 - // - // We don't request gzip if the request is for a range, since - // auto-decoding a portion of a gzipped document will just fail - // anyway. See https://golang.org/issue/8923 - return true - } - return false -} - -// checkConnHeaders checks whether req has any invalid connection-level headers. -// -// https://www.rfc-editor.org/rfc/rfc9114.html#section-4.2-3 -// https://www.rfc-editor.org/rfc/rfc9113.html#section-8.2.2-1 -// -// Certain headers are special-cased as okay but not transmitted later. -// For example, we allow "Transfer-Encoding: chunked", but drop the header when encoding. -func checkConnHeaders(req *http.Request) error { - if v := req.Header.Get("Upgrade"); v != "" { - return fmt.Errorf("invalid Upgrade request header: %q", req.Header["Upgrade"]) - } - if vv := req.Header["Transfer-Encoding"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "chunked") { - return fmt.Errorf("invalid Transfer-Encoding request header: %q", vv) - } - if vv := req.Header["Connection"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && !asciiEqualFold(vv[0], "close") && !asciiEqualFold(vv[0], "keep-alive")) { - return fmt.Errorf("invalid Connection request header: %q", vv) - } - return nil -} - -func commaSeparatedTrailers(req *http.Request) (string, error) { - keys := make([]string, 0, len(req.Trailer)) - for k := range req.Trailer { - k = CanonicalHeader(k) - switch k { - case "Transfer-Encoding", "Trailer", "Content-Length": - return "", fmt.Errorf("invalid Trailer key %q", k) - } - keys = append(keys, k) - } - if len(keys) > 0 { - sort.Strings(keys) - return strings.Join(keys, ","), nil - } - return "", nil -} - -// ActualContentLength returns a sanitized version of -// req.ContentLength, where 0 actually means zero (not unknown) and -1 -// means unknown. -func ActualContentLength(req *http.Request) int64 { - if req.Body == nil || req.Body == http.NoBody { - return 0 - } - if req.ContentLength != 0 { - return req.ContentLength - } - return -1 -} - -// validPseudoPath reports whether v is a valid :path pseudo-header -// value. It must be either: -// -// - a non-empty string starting with '/' -// - the string '*', for OPTIONS requests. -// -// For now this is only used a quick check for deciding when to clean -// up Opaque URLs before sending requests from the Transport. -// See golang.org/issue/16847 -// -// We used to enforce that the path also didn't start with "//", but -// Google's GFE accepts such paths and Chrome sends them, so ignore -// that part of the spec. See golang.org/issue/19103. -func validPseudoPath(v string) bool { - return (len(v) > 0 && v[0] == '/') || v == "*" -} - -func validateHeaders(hdrs http.Header) string { - for k, vv := range hdrs { - if !httpguts.ValidHeaderFieldName(k) && k != ":protocol" { - return fmt.Sprintf("name %q", k) - } - for _, v := range vv { - if !httpguts.ValidHeaderFieldValue(v) { - // Don't include the value in the error, - // because it may be sensitive. - return fmt.Sprintf("value for header %q", k) - } - } - } - return "" -} - -// shouldSendReqContentLength reports whether we should send -// a "content-length" request header. This logic is basically a copy of the net/http -// transferWriter.shouldSendContentLength. -// The contentLength is the corrected contentLength (so 0 means actually 0, not unknown). -// -1 means unknown. -func shouldSendReqContentLength(method string, contentLength int64) bool { - if contentLength > 0 { - return true - } - if contentLength < 0 { - return false - } - // For zero bodies, whether we send a content-length depends on the method. - // It also kinda doesn't matter for http2 either way, with END_STREAM. - switch method { - case "POST", "PUT", "PATCH": - return true - default: - return false - } -} -- cgit v1.2.3