...

Source file src/net/http/http.go

Documentation: net/http

		 1  // Copyright 2016 The Go Authors. All rights reserved.
		 2  // Use of this source code is governed by a BSD-style
		 3  // license that can be found in the LICENSE file.
		 4  
		 5  //go:generate bundle -o=h2_bundle.go -prefix=http2 -tags=!nethttpomithttp2 golang.org/x/net/http2
		 6  
		 7  package http
		 8  
		 9  import (
		10  	"io"
		11  	"strconv"
		12  	"strings"
		13  	"time"
		14  	"unicode/utf8"
		15  
		16  	"golang.org/x/net/http/httpguts"
		17  )
		18  
		19  // incomparable is a zero-width, non-comparable type. Adding it to a struct
		20  // makes that struct also non-comparable, and generally doesn't add
		21  // any size (as long as it's first).
		22  type incomparable [0]func()
		23  
		24  // maxInt64 is the effective "infinite" value for the Server and
		25  // Transport's byte-limiting readers.
		26  const maxInt64 = 1<<63 - 1
		27  
		28  // aLongTimeAgo is a non-zero time, far in the past, used for
		29  // immediate cancellation of network operations.
		30  var aLongTimeAgo = time.Unix(1, 0)
		31  
		32  // omitBundledHTTP2 is set by omithttp2.go when the nethttpomithttp2
		33  // build tag is set. That means h2_bundle.go isn't compiled in and we
		34  // shouldn't try to use it.
		35  var omitBundledHTTP2 bool
		36  
		37  // TODO(bradfitz): move common stuff here. The other files have accumulated
		38  // generic http stuff in random places.
		39  
		40  // contextKey is a value for use with context.WithValue. It's used as
		41  // a pointer so it fits in an interface{} without allocation.
		42  type contextKey struct {
		43  	name string
		44  }
		45  
		46  func (k *contextKey) String() string { return "net/http context value " + k.name }
		47  
		48  // Given a string of the form "host", "host:port", or "[ipv6::address]:port",
		49  // return true if the string includes a port.
		50  func hasPort(s string) bool { return strings.LastIndex(s, ":") > strings.LastIndex(s, "]") }
		51  
		52  // removeEmptyPort strips the empty port in ":port" to ""
		53  // as mandated by RFC 3986 Section 6.2.3.
		54  func removeEmptyPort(host string) string {
		55  	if hasPort(host) {
		56  		return strings.TrimSuffix(host, ":")
		57  	}
		58  	return host
		59  }
		60  
		61  func isNotToken(r rune) bool {
		62  	return !httpguts.IsTokenRune(r)
		63  }
		64  
		65  // stringContainsCTLByte reports whether s contains any ASCII control character.
		66  func stringContainsCTLByte(s string) bool {
		67  	for i := 0; i < len(s); i++ {
		68  		b := s[i]
		69  		if b < ' ' || b == 0x7f {
		70  			return true
		71  		}
		72  	}
		73  	return false
		74  }
		75  
		76  func hexEscapeNonASCII(s string) string {
		77  	newLen := 0
		78  	for i := 0; i < len(s); i++ {
		79  		if s[i] >= utf8.RuneSelf {
		80  			newLen += 3
		81  		} else {
		82  			newLen++
		83  		}
		84  	}
		85  	if newLen == len(s) {
		86  		return s
		87  	}
		88  	b := make([]byte, 0, newLen)
		89  	for i := 0; i < len(s); i++ {
		90  		if s[i] >= utf8.RuneSelf {
		91  			b = append(b, '%')
		92  			b = strconv.AppendInt(b, int64(s[i]), 16)
		93  		} else {
		94  			b = append(b, s[i])
		95  		}
		96  	}
		97  	return string(b)
		98  }
		99  
	 100  // NoBody is an io.ReadCloser with no bytes. Read always returns EOF
	 101  // and Close always returns nil. It can be used in an outgoing client
	 102  // request to explicitly signal that a request has zero bytes.
	 103  // An alternative, however, is to simply set Request.Body to nil.
	 104  var NoBody = noBody{}
	 105  
	 106  type noBody struct{}
	 107  
	 108  func (noBody) Read([]byte) (int, error)				 { return 0, io.EOF }
	 109  func (noBody) Close() error										 { return nil }
	 110  func (noBody) WriteTo(io.Writer) (int64, error) { return 0, nil }
	 111  
	 112  var (
	 113  	// verify that an io.Copy from NoBody won't require a buffer:
	 114  	_ io.WriterTo	 = NoBody
	 115  	_ io.ReadCloser = NoBody
	 116  )
	 117  
	 118  // PushOptions describes options for Pusher.Push.
	 119  type PushOptions struct {
	 120  	// Method specifies the HTTP method for the promised request.
	 121  	// If set, it must be "GET" or "HEAD". Empty means "GET".
	 122  	Method string
	 123  
	 124  	// Header specifies additional promised request headers. This cannot
	 125  	// include HTTP/2 pseudo header fields like ":path" and ":scheme",
	 126  	// which will be added automatically.
	 127  	Header Header
	 128  }
	 129  
	 130  // Pusher is the interface implemented by ResponseWriters that support
	 131  // HTTP/2 server push. For more background, see
	 132  // https://tools.ietf.org/html/rfc7540#section-8.2.
	 133  type Pusher interface {
	 134  	// Push initiates an HTTP/2 server push. This constructs a synthetic
	 135  	// request using the given target and options, serializes that request
	 136  	// into a PUSH_PROMISE frame, then dispatches that request using the
	 137  	// server's request handler. If opts is nil, default options are used.
	 138  	//
	 139  	// The target must either be an absolute path (like "/path") or an absolute
	 140  	// URL that contains a valid host and the same scheme as the parent request.
	 141  	// If the target is a path, it will inherit the scheme and host of the
	 142  	// parent request.
	 143  	//
	 144  	// The HTTP/2 spec disallows recursive pushes and cross-authority pushes.
	 145  	// Push may or may not detect these invalid pushes; however, invalid
	 146  	// pushes will be detected and canceled by conforming clients.
	 147  	//
	 148  	// Handlers that wish to push URL X should call Push before sending any
	 149  	// data that may trigger a request for URL X. This avoids a race where the
	 150  	// client issues requests for X before receiving the PUSH_PROMISE for X.
	 151  	//
	 152  	// Push will run in a separate goroutine making the order of arrival
	 153  	// non-deterministic. Any required synchronization needs to be implemented
	 154  	// by the caller.
	 155  	//
	 156  	// Push returns ErrNotSupported if the client has disabled push or if push
	 157  	// is not supported on the underlying connection.
	 158  	Push(target string, opts *PushOptions) error
	 159  }
	 160  

View as plain text