Copyright 2009 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.
HTTP Request reading and parsing.

package http

import (
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	urlpkg 
	
	
	

	
)

const (
	defaultMaxMemory = 32 << 20 // 32 MB
)
ErrMissingFile is returned by FormFile when the provided file field name is either not present in the request or not a file field.
var ErrMissingFile = errors.New("http: no such file")
ProtocolError represents an HTTP protocol error. Deprecated: Not all errors in the http package related to protocol errors are of type ProtocolError.
type ProtocolError struct {
	ErrorString string
}

func ( *ProtocolError) () string { return .ErrorString }

ErrNotSupported is returned by the Push method of Pusher implementations to indicate that HTTP/2 Push support is not available.
	ErrNotSupported = &ProtocolError{"feature not supported"}
Deprecated: ErrUnexpectedTrailer is no longer returned by anything in the net/http package. Callers should not compare errors against this variable.
	ErrUnexpectedTrailer = &ProtocolError{"trailer header without chunked transfer encoding"}
ErrMissingBoundary is returned by Request.MultipartReader when the request's Content-Type does not include a "boundary" parameter.
	ErrMissingBoundary = &ProtocolError{"no multipart boundary param in Content-Type"}
ErrNotMultipart is returned by Request.MultipartReader when the request's Content-Type is not multipart/form-data.
	ErrNotMultipart = &ProtocolError{"request Content-Type isn't multipart/form-data"}
Deprecated: ErrHeaderTooLong is no longer returned by anything in the net/http package. Callers should not compare errors against this variable.
	ErrHeaderTooLong = &ProtocolError{"header too long"}
Deprecated: ErrShortBody is no longer returned by anything in the net/http package. Callers should not compare errors against this variable.
	ErrShortBody = &ProtocolError{"entity body too short"}
Deprecated: ErrMissingContentLength is no longer returned by anything in the net/http package. Callers should not compare errors against this variable.
	ErrMissingContentLength = &ProtocolError{"missing ContentLength in HEAD response"}
)

func (,  string) error { return fmt.Errorf("%s %q", , ) }
Headers that Request.Write handles itself and should be skipped.
var reqWriteExcludeHeader = map[string]bool{
	"Host":              true, // not in Header map anyway
	"User-Agent":        true,
	"Content-Length":    true,
	"Transfer-Encoding": true,
	"Trailer":           true,
}
A Request represents an HTTP request received by a server or to be sent by a client. The field semantics differ slightly between client and server usage. In addition to the notes on the fields below, see the documentation for Request.Write and RoundTripper.
Method specifies the HTTP method (GET, POST, PUT, etc.). For client requests, an empty string means GET. Go's HTTP client does not support sending a request with the CONNECT method. See the documentation on Transport for details.
URL specifies either the URI being requested (for server requests) or the URL to access (for client requests). For server requests, the URL is parsed from the URI supplied on the Request-Line as stored in RequestURI. For most requests, fields other than Path and RawQuery will be empty. (See RFC 7230, Section 5.3) For client requests, the URL's Host specifies the server to connect to, while the Request's Host field optionally specifies the Host header value to send in the HTTP request.
The protocol version for incoming server requests. For client requests, these fields are ignored. The HTTP client code always uses either HTTP/1.1 or HTTP/2. See the docs on Transport for details.
	Proto      string // "HTTP/1.0"
	ProtoMajor int    // 1
	ProtoMinor int    // 0
Header contains the request header fields either received by the server or to be sent by the client. If a server received a request with header lines, Host: example.com accept-encoding: gzip, deflate Accept-Language: en-us fOO: Bar foo: two then Header = map[string][]string{ "Accept-Encoding": {"gzip, deflate"}, "Accept-Language": {"en-us"}, "Foo": {"Bar", "two"}, } For incoming requests, the Host header is promoted to the Request.Host field and removed from the Header map. HTTP defines that header names are case-insensitive. The request parser implements this by using CanonicalHeaderKey, making the first character and any characters following a hyphen uppercase and the rest lowercase. For client requests, certain headers such as Content-Length and Connection are automatically written when needed and values in Header may be ignored. See the documentation for the Request.Write method.
Body is the request's body. For client requests, a nil body means the request has no body, such as a GET request. The HTTP Client's Transport is responsible for calling the Close method. For server requests, the Request Body is always non-nil but will return EOF immediately when no body is present. The Server will close the request body. The ServeHTTP Handler does not need to. Body must allow Read to be called concurrently with Close. In particular, calling Close should unblock a Read waiting for input.
GetBody defines an optional func to return a new copy of Body. It is used for client requests when a redirect requires reading the body more than once. Use of GetBody still requires setting Body. For server requests, it is unused.
ContentLength records the length of the associated content. The value -1 indicates that the length is unknown. Values >= 0 indicate that the given number of bytes may be read from Body. For client requests, a value of 0 with a non-nil Body is also treated as unknown.
TransferEncoding lists the transfer encodings from outermost to innermost. An empty list denotes the "identity" encoding. TransferEncoding can usually be ignored; chunked encoding is automatically added and removed as necessary when sending and receiving requests.
Close indicates whether to close the connection after replying to this request (for servers) or after sending this request and reading its response (for clients). For server requests, the HTTP server handles this automatically and this field is not needed by Handlers. For client requests, setting this field prevents re-use of TCP connections between requests to the same hosts, as if Transport.DisableKeepAlives were set.
For server requests, Host specifies the host on which the URL is sought. For HTTP/1 (per RFC 7230, section 5.4), this is either the value of the "Host" header or the host name given in the URL itself. For HTTP/2, it is the value of the ":authority" pseudo-header field. It may be of the form "host:port". For international domain names, Host may be in Punycode or Unicode form. Use golang.org/x/net/idna to convert it to either format if needed. To prevent DNS rebinding attacks, server Handlers should validate that the Host header has a value for which the Handler considers itself authoritative. The included ServeMux supports patterns registered to particular host names and thus protects its registered Handlers. For client requests, Host optionally overrides the Host header to send. If empty, the Request.Write method uses the value of URL.Host. Host may contain an international domain name.
Form contains the parsed form data, including both the URL field's query parameters and the PATCH, POST, or PUT form data. This field is only available after ParseForm is called. The HTTP client ignores Form and uses Body instead.
PostForm contains the parsed form data from PATCH, POST or PUT body parameters. This field is only available after ParseForm is called. The HTTP client ignores PostForm and uses Body instead.
MultipartForm is the parsed multipart form, including file uploads. This field is only available after ParseMultipartForm is called. The HTTP client ignores MultipartForm and uses Body instead.
Trailer specifies additional headers that are sent after the request body. For server requests, the Trailer map initially contains only the trailer keys, with nil values. (The client declares which trailers it will later send.) While the handler is reading from Body, it must not reference Trailer. After reading from Body returns EOF, Trailer can be read again and will contain non-nil values, if they were sent by the client. For client requests, Trailer must be initialized to a map containing the trailer keys to later send. The values may be nil or their final values. The ContentLength must be 0 or -1, to send a chunked request. After the HTTP request is sent the map values can be updated while the request body is read. Once the body returns EOF, the caller must not mutate Trailer. Few HTTP clients, servers, or proxies support HTTP trailers.
RemoteAddr allows HTTP servers and other software to record the network address that sent the request, usually for logging. This field is not filled in by ReadRequest and has no defined format. The HTTP server in this package sets RemoteAddr to an "IP:port" address before invoking a handler. This field is ignored by the HTTP client.
RequestURI is the unmodified request-target of the Request-Line (RFC 7230, Section 3.1.1) as sent by the client to a server. Usually the URL field should be used instead. It is an error to set this field in an HTTP client request.
TLS allows HTTP servers and other software to record information about the TLS connection on which the request was received. This field is not filled in by ReadRequest. The HTTP server in this package sets the field for TLS-enabled connections before invoking a handler; otherwise it leaves the field nil. This field is ignored by the HTTP client.
Cancel is an optional channel whose closure indicates that the client request should be regarded as canceled. Not all implementations of RoundTripper may support Cancel. For server requests, this field is not applicable. Deprecated: Set the Request's context with NewRequestWithContext instead. If a Request's Cancel field and context are both set, it is undefined whether Cancel is respected.
	Cancel <-chan struct{}
Response is the redirect response which caused this request to be created. This field is only populated during client redirects.
ctx is either the client or server context. It should only be modified via copying the whole Request using WithContext. It is unexported to prevent people from using Context wrong and mutating the contexts held by callers of the same request.
Context returns the request's context. To change the context, use WithContext. The returned context is always non-nil; it defaults to the background context. For outgoing client requests, the context controls cancellation. For incoming server requests, the context is canceled when the client's connection closes, the request is canceled (with HTTP/2), or when the ServeHTTP method returns.
func ( *Request) () context.Context {
	if .ctx != nil {
		return .ctx
	}
	return context.Background()
}
WithContext returns a shallow copy of r with its context changed to ctx. The provided ctx must be non-nil. For outgoing client request, the context controls the entire lifetime of a request and its response: obtaining a connection, sending the request, and reading the response headers and body. To create a new request with a context, use NewRequestWithContext. To change the context of a request, such as an incoming request you want to modify before sending back out, use Request.Clone. Between those two uses, it's rare to need WithContext.
func ( *Request) ( context.Context) *Request {
	if  == nil {
		panic("nil context")
	}
	 := new(Request)
	* = *
	.ctx = 
	.URL = cloneURL(.URL) // legacy behavior; TODO: try to remove. Issue 23544
	return 
}
Clone returns a deep copy of r with its context changed to ctx. The provided ctx must be non-nil. For an outgoing client request, the context controls the entire lifetime of a request and its response: obtaining a connection, sending the request, and reading the response headers and body.
func ( *Request) ( context.Context) *Request {
	if  == nil {
		panic("nil context")
	}
	 := new(Request)
	* = *
	.ctx = 
	.URL = cloneURL(.URL)
	if .Header != nil {
		.Header = .Header.Clone()
	}
	if .Trailer != nil {
		.Trailer = .Trailer.Clone()
	}
	if  := .TransferEncoding;  != nil {
		 := make([]string, len())
		copy(, )
		.TransferEncoding = 
	}
	.Form = cloneURLValues(.Form)
	.PostForm = cloneURLValues(.PostForm)
	.MultipartForm = cloneMultipartForm(.MultipartForm)
	return 
}
ProtoAtLeast reports whether the HTTP protocol used in the request is at least major.minor.
func ( *Request) (,  int) bool {
	return .ProtoMajor >  ||
		.ProtoMajor ==  && .ProtoMinor >= 
}
UserAgent returns the client's User-Agent, if sent in the request.
func ( *Request) () string {
	return .Header.Get("User-Agent")
}
Cookies parses and returns the HTTP cookies sent with the request.
func ( *Request) () []*Cookie {
	return readCookies(.Header, "")
}
ErrNoCookie is returned by Request's Cookie method when a cookie is not found.
var ErrNoCookie = errors.New("http: named cookie not present")
Cookie returns the named cookie provided in the request or ErrNoCookie if not found. If multiple cookies match the given name, only one cookie will be returned.
func ( *Request) ( string) (*Cookie, error) {
	for ,  := range readCookies(.Header, ) {
		return , nil
	}
	return nil, ErrNoCookie
}
AddCookie adds a cookie to the request. Per RFC 6265 section 5.4, AddCookie does not attach more than one Cookie header field. That means all cookies, if any, are written into the same line, separated by semicolon. AddCookie only sanitizes c's name and value, and does not sanitize a Cookie header already present in the request.
func ( *Request) ( *Cookie) {
	 := fmt.Sprintf("%s=%s", sanitizeCookieName(.Name), sanitizeCookieValue(.Value))
	if  := .Header.Get("Cookie");  != "" {
		.Header.Set("Cookie", +"; "+)
	} else {
		.Header.Set("Cookie", )
	}
}
Referer returns the referring URL, if sent in the request. Referer is misspelled as in the request itself, a mistake from the earliest days of HTTP. This value can also be fetched from the Header map as Header["Referer"]; the benefit of making it available as a method is that the compiler can diagnose programs that use the alternate (correct English) spelling req.Referrer() but cannot diagnose programs that use Header["Referrer"].
func ( *Request) () string {
	return .Header.Get("Referer")
}
multipartByReader is a sentinel value. Its presence in Request.MultipartForm indicates that parsing of the request body has been handed off to a MultipartReader instead of ParseMultipartForm.
MultipartReader returns a MIME multipart reader if this is a multipart/form-data or a multipart/mixed POST request, else returns nil and an error. Use this function instead of ParseMultipartForm to process the request body as a stream.
func ( *Request) () (*multipart.Reader, error) {
	if .MultipartForm == multipartByReader {
		return nil, errors.New("http: MultipartReader called twice")
	}
	if .MultipartForm != nil {
		return nil, errors.New("http: multipart handled by ParseMultipartForm")
	}
	.MultipartForm = multipartByReader
	return .multipartReader(true)
}

func ( *Request) ( bool) (*multipart.Reader, error) {
	 := .Header.Get("Content-Type")
	if  == "" {
		return nil, ErrNotMultipart
	}
	, ,  := mime.ParseMediaType()
	if  != nil || !( == "multipart/form-data" ||  &&  == "multipart/mixed") {
		return nil, ErrNotMultipart
	}
	,  := ["boundary"]
	if ! {
		return nil, ErrMissingBoundary
	}
	return multipart.NewReader(.Body, ), nil
}
isH2Upgrade reports whether r represents the http2 "client preface" magic string.
func ( *Request) () bool {
	return .Method == "PRI" && len(.Header) == 0 && .URL.Path == "*" && .Proto == "HTTP/2.0"
}
Return value if nonempty, def otherwise.
func (,  string) string {
	if  != "" {
		return 
	}
	return 
}
NOTE: This is not intended to reflect the actual Go version being used. It was changed at the time of Go 1.1 release because the former User-Agent had ended up blocked by some intrusion detection systems. See https://codereview.appspot.com/7532043.
const defaultUserAgent = "Go-http-client/1.1"
Write writes an HTTP/1.1 request, which is the header and body, in wire format. This method consults the following fields of the request: Host URL Method (defaults to "GET") Header ContentLength TransferEncoding Body If Body is present, Content-Length is <= 0 and TransferEncoding hasn't been set to "identity", Write adds "Transfer-Encoding: chunked" to the header. Body is closed after it is sent.
func ( *Request) ( io.Writer) error {
	return .write(, false, nil, nil)
}
WriteProxy is like Write but writes the request in the form expected by an HTTP proxy. In particular, WriteProxy writes the initial Request-URI line of the request with an absolute URI, per section 5.3 of RFC 7230, including the scheme and host. In either case, WriteProxy also writes a Host header, using either r.Host or r.URL.Host.
func ( *Request) ( io.Writer) error {
	return .write(, true, nil, nil)
}
errMissingHost is returned by Write when there is no Host or URL present in the Request.
var errMissingHost = errors.New("http: Request.Write on Request with no Host or URL set")
extraHeaders may be nil waitForContinue may be nil always closes body
func ( *Request) ( io.Writer,  bool,  Header,  func() bool) ( error) {
	 := httptrace.ContextClientTrace(.Context())
	if  != nil && .WroteRequest != nil {
		defer func() {
			.WroteRequest(httptrace.WroteRequestInfo{
				Err: ,
			})
		}()
	}
	 := false
	defer func() {
		if  {
			return
		}
		if  := .closeBody();  != nil &&  == nil {
			 = 
		}
	}()
Find the target host. Prefer the Host: header, but if that is not given, use the host from the request URL. Clean the host, in case it arrives with unexpected stuff in it.
	 := cleanHost(.Host)
	if  == "" {
		if .URL == nil {
			return errMissingHost
		}
		 = cleanHost(.URL.Host)
	}
According to RFC 6874, an HTTP client, proxy, or other intermediary must remove any IPv6 zone identifier attached to an outgoing URI.
	 = removeZone()

	 := .URL.RequestURI()
	if  && .URL.Scheme != "" && .URL.Opaque == "" {
		 = .URL.Scheme + "://" +  + 
CONNECT requests normally give just the host and port, not a full URL.
		 = 
		if .URL.Opaque != "" {
			 = .URL.Opaque
		}
	}
	if stringContainsCTLByte() {
		return errors.New("net/http: can't write control character in Request.URL")
TODO: validate r.Method too? At least it's less likely to come from an attacker (more likely to be a constant in code).
Wrap the writer in a bufio Writer if it's not already buffered. Don't always call NewWriter, as that forces a bytes.Buffer and other small bufio Writers to have a minimum 4k buffer size.
	var  *bufio.Writer
	if ,  := .(io.ByteWriter); ! {
		 = bufio.NewWriter()
		 = 
	}

	_,  = fmt.Fprintf(, "%s %s HTTP/1.1\r\n", valueOrDefault(.Method, "GET"), )
	if  != nil {
		return 
	}
Header lines
	_,  = fmt.Fprintf(, "Host: %s\r\n", )
	if  != nil {
		return 
	}
	if  != nil && .WroteHeaderField != nil {
		.WroteHeaderField("Host", []string{})
	}
Use the defaultUserAgent unless the Header contains one, which may be blank to not send the header.
	 := defaultUserAgent
	if .Header.has("User-Agent") {
		 = .Header.Get("User-Agent")
	}
	if  != "" {
		_,  = fmt.Fprintf(, "User-Agent: %s\r\n", )
		if  != nil {
			return 
		}
		if  != nil && .WroteHeaderField != nil {
			.WroteHeaderField("User-Agent", []string{})
		}
	}
Process Body,ContentLength,Close,Trailer
	,  := newTransferWriter()
	if  != nil {
		return 
	}
	 = .writeHeader(, )
	if  != nil {
		return 
	}

	 = .Header.writeSubset(, reqWriteExcludeHeader, )
	if  != nil {
		return 
	}

	if  != nil {
		 = .write(, )
		if  != nil {
			return 
		}
	}

	_,  = io.WriteString(, "\r\n")
	if  != nil {
		return 
	}

	if  != nil && .WroteHeaders != nil {
		.WroteHeaders()
	}
Flush and wait for 100-continue if expected.
	if  != nil {
		if ,  := .(*bufio.Writer);  {
			 = .Flush()
			if  != nil {
				return 
			}
		}
		if  != nil && .Wait100Continue != nil {
			.Wait100Continue()
		}
		if !() {
			 = true
			.closeBody()
			return nil
		}
	}

	if ,  := .(*bufio.Writer);  && .FlushHeaders {
		if  := .Flush();  != nil {
			return 
		}
	}
Write body and trailer
	 = true
	 = .writeBody()
	if  != nil {
		if .bodyReadError ==  {
			 = requestBodyReadError{}
		}
		return 
	}

	if  != nil {
		return .Flush()
	}
	return nil
}
requestBodyReadError wraps an error from (*Request).write to indicate that the error came from a Read call on the Request.Body. This error type should not escape the net/http package to users.
type requestBodyReadError struct{ error }

TODO: Consider removing this check after verifying performance is okay. Right now punycode verification, length checks, context checks, and the permissible character tests are all omitted. It also prevents the ToASCII call from salvaging an invalid IDN, when possible. As a result it may be possible to have two IDNs that appear identical to the user where the ASCII-only version causes an error downstream whereas the non-ASCII version does not. Note that for correct ASCII IDNs ToASCII will only do considerably more work, but it will not cause an allocation.
	if isASCII() {
		return , nil
	}
	return idna.Lookup.ToASCII()
}
cleanHost cleans up the host sent in request's Host header. It both strips anything after '/' or ' ', and puts the value into Punycode form, if necessary. Ideally we'd clean the Host header according to the spec: https://tools.ietf.org/html/rfc7230#section-5.4 (Host = uri-host [ ":" port ]") https://tools.ietf.org/html/rfc7230#section-2.7 (uri-host -> rfc3986's host) https://tools.ietf.org/html/rfc3986#section-3.2.2 (definition of host) But practically, what we are trying to avoid is the situation in issue 11206, where a malformed Host header used in the proxy context would create a bad request. So it is enough to just truncate at the first offending character.
func ( string) string {
	if  := strings.IndexAny(, " /");  != -1 {
		 = [:]
	}
	, ,  := net.SplitHostPort()
	if  != nil { // input was just a host
		,  := idnaASCII()
		if  != nil {
			return  // garbage in, garbage out
		}
		return 
	}
	,  := idnaASCII()
	if  != nil {
		return  // garbage in, garbage out
	}
	return net.JoinHostPort(, )
}
removeZone removes IPv6 zone identifier from host. E.g., "[fe80::1%en0]:8080" to "[fe80::1]:8080"
func ( string) string {
	if !strings.HasPrefix(, "[") {
		return 
	}
	 := strings.LastIndex(, "]")
	if  < 0 {
		return 
	}
	 := strings.LastIndex([:], "%")
	if  < 0 {
		return 
	}
	return [:] + [:]
}
ParseHTTPVersion parses an HTTP version string. "HTTP/1.0" returns (1, 0, true).
func ( string) (,  int,  bool) {
	const  = 1000000 // arbitrary upper bound
	switch  {
	case "HTTP/1.1":
		return 1, 1, true
	case "HTTP/1.0":
		return 1, 0, true
	}
	if !strings.HasPrefix(, "HTTP/") {
		return 0, 0, false
	}
	 := strings.Index(, ".")
	if  < 0 {
		return 0, 0, false
	}
	,  := strconv.Atoi([5:])
	if  != nil ||  < 0 ||  >  {
		return 0, 0, false
	}
	,  = strconv.Atoi([+1:])
	if  != nil ||  < 0 ||  >  {
		return 0, 0, false
	}
	return , , true
}

Method = "OPTIONS" ; Section 9.2 | "GET" ; Section 9.3 | "HEAD" ; Section 9.4 | "POST" ; Section 9.5 | "PUT" ; Section 9.6 | "DELETE" ; Section 9.7 | "TRACE" ; Section 9.8 | "CONNECT" ; Section 9.9 | extension-method extension-method = token token = 1*<any CHAR except CTLs or separators>
	return len() > 0 && strings.IndexFunc(, isNotToken) == -1
}
NewRequest wraps NewRequestWithContext using the background context.
func (,  string,  io.Reader) (*Request, error) {
	return NewRequestWithContext(context.Background(), , , )
}
NewRequestWithContext returns a new Request given a method, URL, and optional body. If the provided body is also an io.Closer, the returned Request.Body is set to body and will be closed by the Client methods Do, Post, and PostForm, and Transport.RoundTrip. NewRequestWithContext returns a Request suitable for use with Client.Do or Transport.RoundTrip. To create a request for use with testing a Server Handler, either use the NewRequest function in the net/http/httptest package, use ReadRequest, or manually update the Request fields. For an outgoing client request, the context controls the entire lifetime of a request and its response: obtaining a connection, sending the request, and reading the response headers and body. See the Request type's documentation for the difference between inbound and outbound request fields. If body is of type *bytes.Buffer, *bytes.Reader, or *strings.Reader, the returned request's ContentLength is set to its exact value (instead of -1), GetBody is populated (so 307 and 308 redirects can replay the body), and Body is set to NoBody if the ContentLength is 0.
func ( context.Context, ,  string,  io.Reader) (*Request, error) {
We document that "" means "GET" for Request.Method, and people have relied on that from NewRequest, so keep that working. We still enforce validMethod for non-empty methods.
		 = "GET"
	}
	if !validMethod() {
		return nil, fmt.Errorf("net/http: invalid method %q", )
	}
	if  == nil {
		return nil, errors.New("net/http: nil Context")
	}
	,  := urlpkg.Parse()
	if  != nil {
		return nil, 
	}
	,  := .(io.ReadCloser)
	if ! &&  != nil {
		 = io.NopCloser()
The host's colon:port should be normalized. See Issue 14836.
	.Host = removeEmptyPort(.Host)
	 := &Request{
		ctx:        ,
		Method:     ,
		URL:        ,
		Proto:      "HTTP/1.1",
		ProtoMajor: 1,
		ProtoMinor: 1,
		Header:     make(Header),
		Body:       ,
		Host:       .Host,
	}
	if  != nil {
		switch v := .(type) {
		case *bytes.Buffer:
			.ContentLength = int64(.Len())
			 := .Bytes()
			.GetBody = func() (io.ReadCloser, error) {
				 := bytes.NewReader()
				return io.NopCloser(), nil
			}
		case *bytes.Reader:
			.ContentLength = int64(.Len())
			 := *
			.GetBody = func() (io.ReadCloser, error) {
				 := 
				return io.NopCloser(&), nil
			}
		case *strings.Reader:
			.ContentLength = int64(.Len())
			 := *
			.GetBody = func() (io.ReadCloser, error) {
				 := 
				return io.NopCloser(&), nil
			}
This is where we'd set it to -1 (at least if body != NoBody) to mean unknown, but that broke people during the Go 1.8 testing period. People depend on it being 0 I guess. Maybe retry later. See Issue 18117.
For client requests, Request.ContentLength of 0 means either actually 0, or unknown. The only way to explicitly say that the ContentLength is zero is to set the Body to nil. But turns out too much code depends on NewRequest returning a non-nil Body, so we use a well-known ReadCloser variable instead and have the http package also treat that sentinel variable to mean explicitly zero.
		if .GetBody != nil && .ContentLength == 0 {
			.Body = NoBody
			.GetBody = func() (io.ReadCloser, error) { return NoBody, nil }
		}
	}

	return , nil
}
BasicAuth returns the username and password provided in the request's Authorization header, if the request uses HTTP Basic Authentication. See RFC 2617, Section 2.
func ( *Request) () (,  string,  bool) {
	 := .Header.Get("Authorization")
	if  == "" {
		return
	}
	return parseBasicAuth()
}
parseBasicAuth parses an HTTP Basic Authentication string. "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" returns ("Aladdin", "open sesame", true).
func ( string) (,  string,  bool) {
Case insensitive prefix match. See Issue 22736.
	if len() < len() || !strings.EqualFold([:len()], ) {
		return
	}
	,  := base64.StdEncoding.DecodeString([len():])
	if  != nil {
		return
	}
	 := string()
	 := strings.IndexByte(, ':')
	if  < 0 {
		return
	}
	return [:], [+1:], true
}
SetBasicAuth sets the request's Authorization header to use HTTP Basic Authentication with the provided username and password. With HTTP Basic Authentication the provided username and password are not encrypted. Some protocols may impose additional requirements on pre-escaping the username and password. For instance, when used with OAuth2, both arguments must be URL encoded first with url.QueryEscape.
func ( *Request) (,  string) {
	.Header.Set("Authorization", "Basic "+basicAuth(, ))
}
parseRequestLine parses "GET /foo HTTP/1.1" into its three parts.
func ( string) (, ,  string,  bool) {
	 := strings.Index(, " ")
	 := strings.Index([+1:], " ")
	if  < 0 ||  < 0 {
		return
	}
	 +=  + 1
	return [:], [+1 : ], [+1:], true
}

var textprotoReaderPool sync.Pool

func ( *bufio.Reader) *textproto.Reader {
	if  := textprotoReaderPool.Get();  != nil {
		 := .(*textproto.Reader)
		.R = 
		return 
	}
	return textproto.NewReader()
}

func ( *textproto.Reader) {
	.R = nil
	textprotoReaderPool.Put()
}
ReadRequest reads and parses an incoming request from b. ReadRequest is a low-level function and should only be used for specialized applications; most code should use the Server to read requests and handle them via the Handler interface. ReadRequest only supports HTTP/1.x requests. For HTTP/2, use golang.org/x/net/http2.
Constants for readRequest's deleteHostHeader parameter.
const (
	deleteHostHeader = true
	keepHostHeader   = false
)

func ( *bufio.Reader,  bool) ( *Request,  error) {
	 := newTextprotoReader()
	 = new(Request)
First line: GET /index.html HTTP/1.0
	var  string
	if ,  = .ReadLine();  != nil {
		return nil, 
	}
	defer func() {
		putTextprotoReader()
		if  == io.EOF {
			 = io.ErrUnexpectedEOF
		}
	}()

	var  bool
	.Method, .RequestURI, .Proto,  = parseRequestLine()
	if ! {
		return nil, badStringError("malformed HTTP request", )
	}
	if !validMethod(.Method) {
		return nil, badStringError("invalid method", .Method)
	}
	 := .RequestURI
	if .ProtoMajor, .ProtoMinor,  = ParseHTTPVersion(.Proto); ! {
		return nil, badStringError("malformed HTTP version", .Proto)
	}
CONNECT requests are used two different ways, and neither uses a full URL: The standard use is to tunnel HTTPS through an HTTP proxy. It looks like "CONNECT www.google.com:443 HTTP/1.1", and the parameter is just the authority section of a URL. This information should go in req.URL.Host. The net/rpc package also uses CONNECT, but there the parameter is a path that starts with a slash. It can be parsed with the regular URL parser, and the path will end up in req.URL.Path, where it needs to be in order for RPC to work.
	 := .Method == "CONNECT" && !strings.HasPrefix(, "/")
	if  {
		 = "http://" + 
	}

	if .URL,  = url.ParseRequestURI();  != nil {
		return nil, 
	}

Strip the bogus "http://" back off.
		.URL.Scheme = ""
	}
Subsequent lines: Key: value.
	,  := .ReadMIMEHeader()
	if  != nil {
		return nil, 
	}
	.Header = Header()
RFC 7230, section 5.3: Must treat GET /index.html HTTP/1.1 Host: www.google.com and GET http://www.google.com/index.html HTTP/1.1 Host: doesntmatter the same. In the second case, any Host line is ignored.
	.Host = .URL.Host
	if .Host == "" {
		.Host = .Header.get("Host")
	}
	if  {
		delete(.Header, "Host")
	}

	fixPragmaCacheControl(.Header)

	.Close = shouldClose(.ProtoMajor, .ProtoMinor, .Header, false)

	 = readTransfer(, )
	if  != nil {
		return nil, 
	}

Because it's neither chunked, nor declared:
		.ContentLength = -1
We want to give handlers a chance to hijack the connection, but we need to prevent the Server from dealing with the connection further if it's not hijacked. Set Close to ensure that:
		.Close = true
	}
	return , nil
}
MaxBytesReader is similar to io.LimitReader but is intended for limiting the size of incoming request bodies. In contrast to io.LimitReader, MaxBytesReader's result is a ReadCloser, returns a non-EOF error for a Read beyond the limit, and closes the underlying reader when its Close method is called. MaxBytesReader prevents clients from accidentally or maliciously sending a large request and wasting server resources.
func ( ResponseWriter,  io.ReadCloser,  int64) io.ReadCloser {
	return &maxBytesReader{w: , r: , n: }
}

type maxBytesReader struct {
	w   ResponseWriter
	r   io.ReadCloser // underlying reader
	n   int64         // max bytes remaining
	err error         // sticky error
}

func ( *maxBytesReader) ( []byte) ( int,  error) {
	if .err != nil {
		return 0, .err
	}
	if len() == 0 {
		return 0, nil
If they asked for a 32KB byte read but only 5 bytes are remaining, no need to read 32KB. 6 bytes will answer the question of the whether we hit the limit or go past it.
	if int64(len()) > .n+1 {
		 = [:.n+1]
	}
	,  = .r.Read()

	if int64() <= .n {
		.n -= int64()
		.err = 
		return , 
	}

	 = int(.n)
	.n = 0
The server code and client code both use maxBytesReader. This "requestTooLarge" check is only used by the server code. To prevent binaries which only using the HTTP Client code (such as cmd/go) from also linking in the HTTP server, don't use a static type assertion to the server "*response" type. Check this interface instead:
	type  interface {
		()
	}
	if ,  := .w.();  {
		.()
	}
	.err = errors.New("http: request body too large")
	return , .err
}

func ( *maxBytesReader) () error {
	return .r.Close()
}

func (,  url.Values) {
	for ,  := range  {
		[] = append([], ...)
	}
}

func ( *Request) ( url.Values,  error) {
	if .Body == nil {
		 = errors.New("missing form body")
		return
	}
RFC 7231, section 3.1.1.5 - empty type MAY be treated as application/octet-stream
	if  == "" {
		 = "application/octet-stream"
	}
	, _,  = mime.ParseMediaType()
	switch {
	case  == "application/x-www-form-urlencoded":
		var  io.Reader = .Body
		 := int64(1<<63 - 1)
		if ,  := .Body.(*maxBytesReader); ! {
			 = int64(10 << 20) // 10 MB is a lot of text.
			 = io.LimitReader(.Body, +1)
		}
		,  := io.ReadAll()
		if  != nil {
			if  == nil {
				 = 
			}
			break
		}
		if int64(len()) >  {
			 = errors.New("http: POST too large")
			return
		}
		,  = url.ParseQuery(string())
		if  == nil {
			 = 
		}
handled by ParseMultipartForm (which is calling us, or should be) TODO(bradfitz): there are too many possible orders to call too many functions here. Clean this up and write more tests. request_test.go contains the start of this, in TestParseMultipartFormOrder and others.
	}
	return
}
ParseForm populates r.Form and r.PostForm. For all requests, ParseForm parses the raw query from the URL and updates r.Form. For POST, PUT, and PATCH requests, it also reads the request body, parses it as a form and puts the results into both r.PostForm and r.Form. Request body parameters take precedence over URL query string values in r.Form. If the request Body's size has not already been limited by MaxBytesReader, the size is capped at 10MB. For other HTTP methods, or when the Content-Type is not application/x-www-form-urlencoded, the request Body is not read, and r.PostForm is initialized to a non-nil, empty value. ParseMultipartForm calls ParseForm automatically. ParseForm is idempotent.
func ( *Request) () error {
	var  error
	if .PostForm == nil {
		if .Method == "POST" || .Method == "PUT" || .Method == "PATCH" {
			.PostForm,  = parsePostForm()
		}
		if .PostForm == nil {
			.PostForm = make(url.Values)
		}
	}
	if .Form == nil {
		if len(.PostForm) > 0 {
			.Form = make(url.Values)
			copyValues(.Form, .PostForm)
		}
		var  url.Values
		if .URL != nil {
			var  error
			,  = url.ParseQuery(.URL.RawQuery)
			if  == nil {
				 = 
			}
		}
		if  == nil {
			 = make(url.Values)
		}
		if .Form == nil {
			.Form = 
		} else {
			copyValues(.Form, )
		}
	}
	return 
}
ParseMultipartForm parses a request body as multipart/form-data. The whole request body is parsed and up to a total of maxMemory bytes of its file parts are stored in memory, with the remainder stored on disk in temporary files. ParseMultipartForm calls ParseForm if necessary. After one call to ParseMultipartForm, subsequent calls have no effect.
func ( *Request) ( int64) error {
	if .MultipartForm == multipartByReader {
		return errors.New("http: multipart handled by MultipartReader")
	}
	if .Form == nil {
		 := .ParseForm()
		if  != nil {
			return 
		}
	}
	if .MultipartForm != nil {
		return nil
	}

	,  := .multipartReader(false)
	if  != nil {
		return 
	}

	,  := .ReadForm()
	if  != nil {
		return 
	}

	if .PostForm == nil {
		.PostForm = make(url.Values)
	}
	for ,  := range .Value {
r.PostForm should also be populated. See Issue 9305.
		.PostForm[] = append(.PostForm[], ...)
	}

	.MultipartForm = 

	return nil
}
FormValue returns the first value for the named component of the query. POST and PUT body parameters take precedence over URL query string values. FormValue calls ParseMultipartForm and ParseForm if necessary and ignores any errors returned by these functions. If key is not present, FormValue returns the empty string. To access multiple values of the same key, call ParseForm and then inspect Request.Form directly.
func ( *Request) ( string) string {
	if .Form == nil {
		.ParseMultipartForm(defaultMaxMemory)
	}
	if  := .Form[]; len() > 0 {
		return [0]
	}
	return ""
}
PostFormValue returns the first value for the named component of the POST, PATCH, or PUT request body. URL query parameters are ignored. PostFormValue calls ParseMultipartForm and ParseForm if necessary and ignores any errors returned by these functions. If key is not present, PostFormValue returns the empty string.
func ( *Request) ( string) string {
	if .PostForm == nil {
		.ParseMultipartForm(defaultMaxMemory)
	}
	if  := .PostForm[]; len() > 0 {
		return [0]
	}
	return ""
}
FormFile returns the first file for the provided form key. FormFile calls ParseMultipartForm and ParseForm if necessary.
func ( *Request) ( string) (multipart.File, *multipart.FileHeader, error) {
	if .MultipartForm == multipartByReader {
		return nil, nil, errors.New("http: multipart handled by MultipartReader")
	}
	if .MultipartForm == nil {
		 := .ParseMultipartForm(defaultMaxMemory)
		if  != nil {
			return nil, nil, 
		}
	}
	if .MultipartForm != nil && .MultipartForm.File != nil {
		if  := .MultipartForm.File[]; len() > 0 {
			,  := [0].Open()
			return , [0], 
		}
	}
	return nil, nil, ErrMissingFile
}

func ( *Request) () bool {
	return hasToken(.Header.get("Expect"), "100-continue")
}

func ( *Request) () bool {
	if .ProtoMajor != 1 || .ProtoMinor != 0 {
		return false
	}
	return hasToken(.Header.get("Connection"), "keep-alive")
}

func ( *Request) () bool {
	if .Close {
		return true
	}
	return hasToken(.Header.get("Connection"), "close")
}

func ( *Request) () error {
	if .Body == nil {
		return nil
	}
	return .Body.Close()
}

func ( *Request) () bool {
	if .Body == nil || .Body == NoBody || .GetBody != nil {
		switch valueOrDefault(.Method, "GET") {
		case "GET", "HEAD", "OPTIONS", "TRACE":
			return true
The Idempotency-Key, while non-standard, is widely used to mean a POST or other request is idempotent. See https://golang.org/issue/19943#issuecomment-421092421
		if .Header.has("Idempotency-Key") || .Header.has("X-Idempotency-Key") {
			return true
		}
	}
	return false
}
outgoingLength reports the Content-Length of this outgoing (Client) request. It maps 0 into -1 (unknown) when the Body is non-nil.
func ( *Request) () int64 {
	if .Body == nil || .Body == NoBody {
		return 0
	}
	if .ContentLength != 0 {
		return .ContentLength
	}
	return -1
}
requestMethodUsuallyLacksBody reports whether the given request method is one that typically does not involve a request body. This is used by the Transport (via transferWriter.shouldSendChunkedRequestBody) to determine whether we try to test-read a byte from a non-nil Request.Body when Request.outgoingLength() returns -1. See the comments in shouldSendChunkedRequestBody.
func ( string) bool {
	switch  {
	case "GET", "HEAD", "DELETE", "OPTIONS", "PROPFIND", "SEARCH":
		return true
	}
	return false
}
requiresHTTP1 reports whether this request requires being sent on an HTTP/1 connection.
func ( *Request) () bool {
	return hasToken(.Header.Get("Connection"), "upgrade") &&
		strings.EqualFold(.Header.Get("Upgrade"), "websocket")