处理AI胡乱生成的乱摊子
This commit is contained in:
8
vendor/golang.org/x/net/http2/client_conn_pool.go
generated
vendored
8
vendor/golang.org/x/net/http2/client_conn_pool.go
generated
vendored
@@ -8,8 +8,8 @@ package http2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"net"
|
||||
"net/http"
|
||||
"sync"
|
||||
)
|
||||
@@ -158,7 +158,7 @@ func (c *dialCall) dial(ctx context.Context, addr string) {
|
||||
// This code decides which ones live or die.
|
||||
// The return value used is whether c was used.
|
||||
// c is never closed.
|
||||
func (p *clientConnPool) addConnIfNeeded(key string, t *Transport, c *tls.Conn) (used bool, err error) {
|
||||
func (p *clientConnPool) addConnIfNeeded(key string, t *Transport, c net.Conn) (used bool, err error) {
|
||||
p.mu.Lock()
|
||||
for _, cc := range p.conns[key] {
|
||||
if cc.CanTakeNewRequest() {
|
||||
@@ -194,8 +194,8 @@ type addConnCall struct {
|
||||
err error
|
||||
}
|
||||
|
||||
func (c *addConnCall) run(t *Transport, key string, tc *tls.Conn) {
|
||||
cc, err := t.NewClientConn(tc)
|
||||
func (c *addConnCall) run(t *Transport, key string, nc net.Conn) {
|
||||
cc, err := t.NewClientConn(nc)
|
||||
|
||||
p := c.p
|
||||
p.mu.Lock()
|
||||
|
||||
29
vendor/golang.org/x/net/http2/frame.go
generated
vendored
29
vendor/golang.org/x/net/http2/frame.go
generated
vendored
@@ -39,7 +39,7 @@ const (
|
||||
FrameContinuation FrameType = 0x9
|
||||
)
|
||||
|
||||
var frameName = map[FrameType]string{
|
||||
var frameNames = [...]string{
|
||||
FrameData: "DATA",
|
||||
FrameHeaders: "HEADERS",
|
||||
FramePriority: "PRIORITY",
|
||||
@@ -53,10 +53,10 @@ var frameName = map[FrameType]string{
|
||||
}
|
||||
|
||||
func (t FrameType) String() string {
|
||||
if s, ok := frameName[t]; ok {
|
||||
return s
|
||||
if int(t) < len(frameNames) {
|
||||
return frameNames[t]
|
||||
}
|
||||
return fmt.Sprintf("UNKNOWN_FRAME_TYPE_%d", uint8(t))
|
||||
return fmt.Sprintf("UNKNOWN_FRAME_TYPE_%d", t)
|
||||
}
|
||||
|
||||
// Flags is a bitmask of HTTP/2 flags.
|
||||
@@ -124,7 +124,7 @@ var flagName = map[FrameType]map[Flags]string{
|
||||
// might be 0).
|
||||
type frameParser func(fc *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error)
|
||||
|
||||
var frameParsers = map[FrameType]frameParser{
|
||||
var frameParsers = [...]frameParser{
|
||||
FrameData: parseDataFrame,
|
||||
FrameHeaders: parseHeadersFrame,
|
||||
FramePriority: parsePriorityFrame,
|
||||
@@ -138,8 +138,8 @@ var frameParsers = map[FrameType]frameParser{
|
||||
}
|
||||
|
||||
func typeFrameParser(t FrameType) frameParser {
|
||||
if f := frameParsers[t]; f != nil {
|
||||
return f
|
||||
if int(t) < len(frameParsers) {
|
||||
return frameParsers[t]
|
||||
}
|
||||
return parseUnknownFrame
|
||||
}
|
||||
@@ -225,6 +225,11 @@ var fhBytes = sync.Pool{
|
||||
},
|
||||
}
|
||||
|
||||
func invalidHTTP1LookingFrameHeader() FrameHeader {
|
||||
fh, _ := readFrameHeader(make([]byte, frameHeaderLen), strings.NewReader("HTTP/1.1 "))
|
||||
return fh
|
||||
}
|
||||
|
||||
// ReadFrameHeader reads 9 bytes from r and returns a FrameHeader.
|
||||
// Most users should use Framer.ReadFrame instead.
|
||||
func ReadFrameHeader(r io.Reader) (FrameHeader, error) {
|
||||
@@ -503,10 +508,16 @@ func (fr *Framer) ReadFrame() (Frame, error) {
|
||||
return nil, err
|
||||
}
|
||||
if fh.Length > fr.maxReadSize {
|
||||
if fh == invalidHTTP1LookingFrameHeader() {
|
||||
return nil, fmt.Errorf("http2: failed reading the frame payload: %w, note that the frame header looked like an HTTP/1.1 header", ErrFrameTooLarge)
|
||||
}
|
||||
return nil, ErrFrameTooLarge
|
||||
}
|
||||
payload := fr.getReadBuf(fh.Length)
|
||||
if _, err := io.ReadFull(fr.r, payload); err != nil {
|
||||
if fh == invalidHTTP1LookingFrameHeader() {
|
||||
return nil, fmt.Errorf("http2: failed reading the frame payload: %w, note that the frame header looked like an HTTP/1.1 header", err)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
f, err := typeFrameParser(fh.Type)(fr.frameCache, fh, fr.countError, payload)
|
||||
@@ -1490,7 +1501,7 @@ func (mh *MetaHeadersFrame) checkPseudos() error {
|
||||
pf := mh.PseudoFields()
|
||||
for i, hf := range pf {
|
||||
switch hf.Name {
|
||||
case ":method", ":path", ":scheme", ":authority":
|
||||
case ":method", ":path", ":scheme", ":authority", ":protocol":
|
||||
isRequest = true
|
||||
case ":status":
|
||||
isResponse = true
|
||||
@@ -1498,7 +1509,7 @@ func (mh *MetaHeadersFrame) checkPseudos() error {
|
||||
return pseudoHeaderError(hf.Name)
|
||||
}
|
||||
// Check for duplicates.
|
||||
// This would be a bad algorithm, but N is 4.
|
||||
// This would be a bad algorithm, but N is 5.
|
||||
// And this doesn't allocate.
|
||||
for _, hf2 := range pf[:i] {
|
||||
if hf.Name == hf2.Name {
|
||||
|
||||
14
vendor/golang.org/x/net/http2/h2c/h2c.go
generated
vendored
14
vendor/golang.org/x/net/http2/h2c/h2c.go
generated
vendored
@@ -132,11 +132,8 @@ func (s h2cHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
// of the body, and reforward the client preface on the net.Conn this function
|
||||
// creates.
|
||||
func initH2CWithPriorKnowledge(w http.ResponseWriter) (net.Conn, error) {
|
||||
hijacker, ok := w.(http.Hijacker)
|
||||
if !ok {
|
||||
return nil, errors.New("h2c: connection does not support Hijack")
|
||||
}
|
||||
conn, rw, err := hijacker.Hijack()
|
||||
rc := http.NewResponseController(w)
|
||||
conn, rw, err := rc.Hijack()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -163,10 +160,6 @@ func h2cUpgrade(w http.ResponseWriter, r *http.Request) (_ net.Conn, settings []
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
hijacker, ok := w.(http.Hijacker)
|
||||
if !ok {
|
||||
return nil, nil, errors.New("h2c: connection does not support Hijack")
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
@@ -174,7 +167,8 @@ func h2cUpgrade(w http.ResponseWriter, r *http.Request) (_ net.Conn, settings []
|
||||
}
|
||||
r.Body = io.NopCloser(bytes.NewBuffer(body))
|
||||
|
||||
conn, rw, err := hijacker.Hijack()
|
||||
rc := http.NewResponseController(w)
|
||||
conn, rw, err := rc.Hijack()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
105
vendor/golang.org/x/net/http2/headermap.go
generated
vendored
105
vendor/golang.org/x/net/http2/headermap.go
generated
vendored
@@ -1,105 +0,0 @@
|
||||
// Copyright 2014 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 http2
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
commonBuildOnce sync.Once
|
||||
commonLowerHeader map[string]string // Go-Canonical-Case -> lower-case
|
||||
commonCanonHeader map[string]string // lower-case -> Go-Canonical-Case
|
||||
)
|
||||
|
||||
func buildCommonHeaderMapsOnce() {
|
||||
commonBuildOnce.Do(buildCommonHeaderMaps)
|
||||
}
|
||||
|
||||
func buildCommonHeaderMaps() {
|
||||
common := []string{
|
||||
"accept",
|
||||
"accept-charset",
|
||||
"accept-encoding",
|
||||
"accept-language",
|
||||
"accept-ranges",
|
||||
"age",
|
||||
"access-control-allow-credentials",
|
||||
"access-control-allow-headers",
|
||||
"access-control-allow-methods",
|
||||
"access-control-allow-origin",
|
||||
"access-control-expose-headers",
|
||||
"access-control-max-age",
|
||||
"access-control-request-headers",
|
||||
"access-control-request-method",
|
||||
"allow",
|
||||
"authorization",
|
||||
"cache-control",
|
||||
"content-disposition",
|
||||
"content-encoding",
|
||||
"content-language",
|
||||
"content-length",
|
||||
"content-location",
|
||||
"content-range",
|
||||
"content-type",
|
||||
"cookie",
|
||||
"date",
|
||||
"etag",
|
||||
"expect",
|
||||
"expires",
|
||||
"from",
|
||||
"host",
|
||||
"if-match",
|
||||
"if-modified-since",
|
||||
"if-none-match",
|
||||
"if-unmodified-since",
|
||||
"last-modified",
|
||||
"link",
|
||||
"location",
|
||||
"max-forwards",
|
||||
"origin",
|
||||
"proxy-authenticate",
|
||||
"proxy-authorization",
|
||||
"range",
|
||||
"referer",
|
||||
"refresh",
|
||||
"retry-after",
|
||||
"server",
|
||||
"set-cookie",
|
||||
"strict-transport-security",
|
||||
"trailer",
|
||||
"transfer-encoding",
|
||||
"user-agent",
|
||||
"vary",
|
||||
"via",
|
||||
"www-authenticate",
|
||||
"x-forwarded-for",
|
||||
"x-forwarded-proto",
|
||||
}
|
||||
commonLowerHeader = make(map[string]string, len(common))
|
||||
commonCanonHeader = make(map[string]string, len(common))
|
||||
for _, v := range common {
|
||||
chk := http.CanonicalHeaderKey(v)
|
||||
commonLowerHeader[chk] = v
|
||||
commonCanonHeader[v] = chk
|
||||
}
|
||||
}
|
||||
|
||||
func lowerHeader(v string) (lower string, ascii bool) {
|
||||
buildCommonHeaderMapsOnce()
|
||||
if s, ok := commonLowerHeader[v]; ok {
|
||||
return s, true
|
||||
}
|
||||
return asciiToLower(v)
|
||||
}
|
||||
|
||||
func canonicalHeader(v string) string {
|
||||
buildCommonHeaderMapsOnce()
|
||||
if s, ok := commonCanonHeader[v]; ok {
|
||||
return s
|
||||
}
|
||||
return http.CanonicalHeaderKey(v)
|
||||
}
|
||||
61
vendor/golang.org/x/net/http2/http2.go
generated
vendored
61
vendor/golang.org/x/net/http2/http2.go
generated
vendored
@@ -11,8 +11,6 @@
|
||||
// requires Go 1.6 or later)
|
||||
//
|
||||
// See https://http2.github.io/ for more information on HTTP/2.
|
||||
//
|
||||
// See https://http2.golang.org/ for a test server running this code.
|
||||
package http2 // import "golang.org/x/net/http2"
|
||||
|
||||
import (
|
||||
@@ -38,6 +36,15 @@ var (
|
||||
logFrameWrites bool
|
||||
logFrameReads bool
|
||||
inTests bool
|
||||
|
||||
// Enabling extended CONNECT by causes browsers to attempt to use
|
||||
// WebSockets-over-HTTP/2. This results in problems when the server's websocket
|
||||
// package doesn't support extended CONNECT.
|
||||
//
|
||||
// Disable extended CONNECT by default for now.
|
||||
//
|
||||
// Issue #71128.
|
||||
disableExtendedConnectProtocol = true
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -50,6 +57,9 @@ func init() {
|
||||
logFrameWrites = true
|
||||
logFrameReads = true
|
||||
}
|
||||
if strings.Contains(e, "http2xconnect=1") {
|
||||
disableExtendedConnectProtocol = false
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -141,6 +151,10 @@ func (s Setting) Valid() error {
|
||||
if s.Val < 16384 || s.Val > 1<<24-1 {
|
||||
return ConnectionError(ErrCodeProtocol)
|
||||
}
|
||||
case SettingEnableConnectProtocol:
|
||||
if s.Val != 1 && s.Val != 0 {
|
||||
return ConnectionError(ErrCodeProtocol)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -150,21 +164,23 @@ func (s Setting) Valid() error {
|
||||
type SettingID uint16
|
||||
|
||||
const (
|
||||
SettingHeaderTableSize SettingID = 0x1
|
||||
SettingEnablePush SettingID = 0x2
|
||||
SettingMaxConcurrentStreams SettingID = 0x3
|
||||
SettingInitialWindowSize SettingID = 0x4
|
||||
SettingMaxFrameSize SettingID = 0x5
|
||||
SettingMaxHeaderListSize SettingID = 0x6
|
||||
SettingHeaderTableSize SettingID = 0x1
|
||||
SettingEnablePush SettingID = 0x2
|
||||
SettingMaxConcurrentStreams SettingID = 0x3
|
||||
SettingInitialWindowSize SettingID = 0x4
|
||||
SettingMaxFrameSize SettingID = 0x5
|
||||
SettingMaxHeaderListSize SettingID = 0x6
|
||||
SettingEnableConnectProtocol SettingID = 0x8
|
||||
)
|
||||
|
||||
var settingName = map[SettingID]string{
|
||||
SettingHeaderTableSize: "HEADER_TABLE_SIZE",
|
||||
SettingEnablePush: "ENABLE_PUSH",
|
||||
SettingMaxConcurrentStreams: "MAX_CONCURRENT_STREAMS",
|
||||
SettingInitialWindowSize: "INITIAL_WINDOW_SIZE",
|
||||
SettingMaxFrameSize: "MAX_FRAME_SIZE",
|
||||
SettingMaxHeaderListSize: "MAX_HEADER_LIST_SIZE",
|
||||
SettingHeaderTableSize: "HEADER_TABLE_SIZE",
|
||||
SettingEnablePush: "ENABLE_PUSH",
|
||||
SettingMaxConcurrentStreams: "MAX_CONCURRENT_STREAMS",
|
||||
SettingInitialWindowSize: "INITIAL_WINDOW_SIZE",
|
||||
SettingMaxFrameSize: "MAX_FRAME_SIZE",
|
||||
SettingMaxHeaderListSize: "MAX_HEADER_LIST_SIZE",
|
||||
SettingEnableConnectProtocol: "ENABLE_CONNECT_PROTOCOL",
|
||||
}
|
||||
|
||||
func (s SettingID) String() string {
|
||||
@@ -397,23 +413,6 @@ func (s *sorter) SortStrings(ss []string) {
|
||||
s.v = save
|
||||
}
|
||||
|
||||
// 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 == "*"
|
||||
}
|
||||
|
||||
// incomparable is a zero-width, non-comparable type. Adding it to a struct
|
||||
// makes that struct also non-comparable, and generally doesn't add
|
||||
// any size (as long as it's first).
|
||||
|
||||
185
vendor/golang.org/x/net/http2/server.go
generated
vendored
185
vendor/golang.org/x/net/http2/server.go
generated
vendored
@@ -50,6 +50,7 @@ import (
|
||||
|
||||
"golang.org/x/net/http/httpguts"
|
||||
"golang.org/x/net/http2/hpack"
|
||||
"golang.org/x/net/internal/httpcommon"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -306,7 +307,7 @@ func ConfigureServer(s *http.Server, conf *Server) error {
|
||||
if s.TLSNextProto == nil {
|
||||
s.TLSNextProto = map[string]func(*http.Server, *tls.Conn, http.Handler){}
|
||||
}
|
||||
protoHandler := func(hs *http.Server, c *tls.Conn, h http.Handler) {
|
||||
protoHandler := func(hs *http.Server, c net.Conn, h http.Handler, sawClientPreface bool) {
|
||||
if testHookOnConn != nil {
|
||||
testHookOnConn()
|
||||
}
|
||||
@@ -323,12 +324,31 @@ func ConfigureServer(s *http.Server, conf *Server) error {
|
||||
ctx = bc.BaseContext()
|
||||
}
|
||||
conf.ServeConn(c, &ServeConnOpts{
|
||||
Context: ctx,
|
||||
Handler: h,
|
||||
BaseConfig: hs,
|
||||
Context: ctx,
|
||||
Handler: h,
|
||||
BaseConfig: hs,
|
||||
SawClientPreface: sawClientPreface,
|
||||
})
|
||||
}
|
||||
s.TLSNextProto[NextProtoTLS] = protoHandler
|
||||
s.TLSNextProto[NextProtoTLS] = func(hs *http.Server, c *tls.Conn, h http.Handler) {
|
||||
protoHandler(hs, c, h, false)
|
||||
}
|
||||
// The "unencrypted_http2" TLSNextProto key is used to pass off non-TLS HTTP/2 conns.
|
||||
//
|
||||
// A connection passed in this method has already had the HTTP/2 preface read from it.
|
||||
s.TLSNextProto[nextProtoUnencryptedHTTP2] = func(hs *http.Server, c *tls.Conn, h http.Handler) {
|
||||
nc, err := unencryptedNetConnFromTLSConn(c)
|
||||
if err != nil {
|
||||
if lg := hs.ErrorLog; lg != nil {
|
||||
lg.Print(err)
|
||||
} else {
|
||||
log.Print(err)
|
||||
}
|
||||
go c.Close()
|
||||
return
|
||||
}
|
||||
protoHandler(hs, nc, h, true)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -793,8 +813,7 @@ const maxCachedCanonicalHeadersKeysSize = 2048
|
||||
|
||||
func (sc *serverConn) canonicalHeader(v string) string {
|
||||
sc.serveG.check()
|
||||
buildCommonHeaderMapsOnce()
|
||||
cv, ok := commonCanonHeader[v]
|
||||
cv, ok := httpcommon.CachedCanonicalHeader(v)
|
||||
if ok {
|
||||
return cv
|
||||
}
|
||||
@@ -913,14 +932,18 @@ func (sc *serverConn) serve(conf http2Config) {
|
||||
sc.vlogf("http2: server connection from %v on %p", sc.conn.RemoteAddr(), sc.hs)
|
||||
}
|
||||
|
||||
settings := writeSettings{
|
||||
{SettingMaxFrameSize, conf.MaxReadFrameSize},
|
||||
{SettingMaxConcurrentStreams, sc.advMaxStreams},
|
||||
{SettingMaxHeaderListSize, sc.maxHeaderListSize()},
|
||||
{SettingHeaderTableSize, conf.MaxDecoderHeaderTableSize},
|
||||
{SettingInitialWindowSize, uint32(sc.initialStreamRecvWindowSize)},
|
||||
}
|
||||
if !disableExtendedConnectProtocol {
|
||||
settings = append(settings, Setting{SettingEnableConnectProtocol, 1})
|
||||
}
|
||||
sc.writeFrame(FrameWriteRequest{
|
||||
write: writeSettings{
|
||||
{SettingMaxFrameSize, conf.MaxReadFrameSize},
|
||||
{SettingMaxConcurrentStreams, sc.advMaxStreams},
|
||||
{SettingMaxHeaderListSize, sc.maxHeaderListSize()},
|
||||
{SettingHeaderTableSize, conf.MaxDecoderHeaderTableSize},
|
||||
{SettingInitialWindowSize, uint32(sc.initialStreamRecvWindowSize)},
|
||||
},
|
||||
write: settings,
|
||||
})
|
||||
sc.unackedSettings++
|
||||
|
||||
@@ -1045,7 +1068,10 @@ func (sc *serverConn) serve(conf http2Config) {
|
||||
|
||||
func (sc *serverConn) handlePingTimer(lastFrameReadTime time.Time) {
|
||||
if sc.pingSent {
|
||||
sc.vlogf("timeout waiting for PING response")
|
||||
sc.logf("timeout waiting for PING response")
|
||||
if f := sc.countErrorFunc; f != nil {
|
||||
f("conn_close_lost_ping")
|
||||
}
|
||||
sc.conn.Close()
|
||||
return
|
||||
}
|
||||
@@ -1782,6 +1808,9 @@ func (sc *serverConn) processSetting(s Setting) error {
|
||||
sc.maxFrameSize = int32(s.Val) // the maximum valid s.Val is < 2^31
|
||||
case SettingMaxHeaderListSize:
|
||||
sc.peerMaxHeaderListSize = s.Val
|
||||
case SettingEnableConnectProtocol:
|
||||
// Receipt of this parameter by a server does not
|
||||
// have any impact
|
||||
default:
|
||||
// Unknown setting: "An endpoint that receives a SETTINGS
|
||||
// frame with any unknown or unsupported identifier MUST
|
||||
@@ -2207,19 +2236,25 @@ func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream
|
||||
func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*responseWriter, *http.Request, error) {
|
||||
sc.serveG.check()
|
||||
|
||||
rp := requestParam{
|
||||
method: f.PseudoValue("method"),
|
||||
scheme: f.PseudoValue("scheme"),
|
||||
authority: f.PseudoValue("authority"),
|
||||
path: f.PseudoValue("path"),
|
||||
rp := httpcommon.ServerRequestParam{
|
||||
Method: f.PseudoValue("method"),
|
||||
Scheme: f.PseudoValue("scheme"),
|
||||
Authority: f.PseudoValue("authority"),
|
||||
Path: f.PseudoValue("path"),
|
||||
Protocol: f.PseudoValue("protocol"),
|
||||
}
|
||||
|
||||
isConnect := rp.method == "CONNECT"
|
||||
// extended connect is disabled, so we should not see :protocol
|
||||
if disableExtendedConnectProtocol && rp.Protocol != "" {
|
||||
return nil, nil, sc.countError("bad_connect", streamError(f.StreamID, ErrCodeProtocol))
|
||||
}
|
||||
|
||||
isConnect := rp.Method == "CONNECT"
|
||||
if isConnect {
|
||||
if rp.path != "" || rp.scheme != "" || rp.authority == "" {
|
||||
if rp.Protocol == "" && (rp.Path != "" || rp.Scheme != "" || rp.Authority == "") {
|
||||
return nil, nil, sc.countError("bad_connect", streamError(f.StreamID, ErrCodeProtocol))
|
||||
}
|
||||
} else if rp.method == "" || rp.path == "" || (rp.scheme != "https" && rp.scheme != "http") {
|
||||
} else if rp.Method == "" || rp.Path == "" || (rp.Scheme != "https" && rp.Scheme != "http") {
|
||||
// See 8.1.2.6 Malformed Requests and Responses:
|
||||
//
|
||||
// Malformed requests or responses that are detected
|
||||
@@ -2233,12 +2268,16 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res
|
||||
return nil, nil, sc.countError("bad_path_method", streamError(f.StreamID, ErrCodeProtocol))
|
||||
}
|
||||
|
||||
rp.header = make(http.Header)
|
||||
header := make(http.Header)
|
||||
rp.Header = header
|
||||
for _, hf := range f.RegularFields() {
|
||||
rp.header.Add(sc.canonicalHeader(hf.Name), hf.Value)
|
||||
header.Add(sc.canonicalHeader(hf.Name), hf.Value)
|
||||
}
|
||||
if rp.authority == "" {
|
||||
rp.authority = rp.header.Get("Host")
|
||||
if rp.Authority == "" {
|
||||
rp.Authority = header.Get("Host")
|
||||
}
|
||||
if rp.Protocol != "" {
|
||||
header.Set(":protocol", rp.Protocol)
|
||||
}
|
||||
|
||||
rw, req, err := sc.newWriterAndRequestNoBody(st, rp)
|
||||
@@ -2247,7 +2286,7 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res
|
||||
}
|
||||
bodyOpen := !f.StreamEnded()
|
||||
if bodyOpen {
|
||||
if vv, ok := rp.header["Content-Length"]; ok {
|
||||
if vv, ok := rp.Header["Content-Length"]; ok {
|
||||
if cl, err := strconv.ParseUint(vv[0], 10, 63); err == nil {
|
||||
req.ContentLength = int64(cl)
|
||||
} else {
|
||||
@@ -2263,83 +2302,38 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res
|
||||
return rw, req, nil
|
||||
}
|
||||
|
||||
type requestParam struct {
|
||||
method string
|
||||
scheme, authority, path string
|
||||
header http.Header
|
||||
}
|
||||
|
||||
func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*responseWriter, *http.Request, error) {
|
||||
func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp httpcommon.ServerRequestParam) (*responseWriter, *http.Request, error) {
|
||||
sc.serveG.check()
|
||||
|
||||
var tlsState *tls.ConnectionState // nil if not scheme https
|
||||
if rp.scheme == "https" {
|
||||
if rp.Scheme == "https" {
|
||||
tlsState = sc.tlsState
|
||||
}
|
||||
|
||||
needsContinue := httpguts.HeaderValuesContainsToken(rp.header["Expect"], "100-continue")
|
||||
if needsContinue {
|
||||
rp.header.Del("Expect")
|
||||
}
|
||||
// Merge Cookie headers into one "; "-delimited value.
|
||||
if cookies := rp.header["Cookie"]; len(cookies) > 1 {
|
||||
rp.header.Set("Cookie", strings.Join(cookies, "; "))
|
||||
}
|
||||
|
||||
// Setup Trailers
|
||||
var trailer http.Header
|
||||
for _, v := range rp.header["Trailer"] {
|
||||
for _, key := range strings.Split(v, ",") {
|
||||
key = http.CanonicalHeaderKey(textproto.TrimString(key))
|
||||
switch key {
|
||||
case "Transfer-Encoding", "Trailer", "Content-Length":
|
||||
// Bogus. (copy of http1 rules)
|
||||
// Ignore.
|
||||
default:
|
||||
if trailer == nil {
|
||||
trailer = make(http.Header)
|
||||
}
|
||||
trailer[key] = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
delete(rp.header, "Trailer")
|
||||
|
||||
var url_ *url.URL
|
||||
var requestURI string
|
||||
if rp.method == "CONNECT" {
|
||||
url_ = &url.URL{Host: rp.authority}
|
||||
requestURI = rp.authority // mimic HTTP/1 server behavior
|
||||
} else {
|
||||
var err error
|
||||
url_, err = url.ParseRequestURI(rp.path)
|
||||
if err != nil {
|
||||
return nil, nil, sc.countError("bad_path", streamError(st.id, ErrCodeProtocol))
|
||||
}
|
||||
requestURI = rp.path
|
||||
res := httpcommon.NewServerRequest(rp)
|
||||
if res.InvalidReason != "" {
|
||||
return nil, nil, sc.countError(res.InvalidReason, streamError(st.id, ErrCodeProtocol))
|
||||
}
|
||||
|
||||
body := &requestBody{
|
||||
conn: sc,
|
||||
stream: st,
|
||||
needsContinue: needsContinue,
|
||||
needsContinue: res.NeedsContinue,
|
||||
}
|
||||
req := &http.Request{
|
||||
Method: rp.method,
|
||||
URL: url_,
|
||||
req := (&http.Request{
|
||||
Method: rp.Method,
|
||||
URL: res.URL,
|
||||
RemoteAddr: sc.remoteAddrStr,
|
||||
Header: rp.header,
|
||||
RequestURI: requestURI,
|
||||
Header: rp.Header,
|
||||
RequestURI: res.RequestURI,
|
||||
Proto: "HTTP/2.0",
|
||||
ProtoMajor: 2,
|
||||
ProtoMinor: 0,
|
||||
TLS: tlsState,
|
||||
Host: rp.authority,
|
||||
Host: rp.Authority,
|
||||
Body: body,
|
||||
Trailer: trailer,
|
||||
}
|
||||
req = req.WithContext(st.ctx)
|
||||
|
||||
Trailer: res.Trailer,
|
||||
}).WithContext(st.ctx)
|
||||
rw := sc.newResponseWriter(st, req)
|
||||
return rw, req, nil
|
||||
}
|
||||
@@ -2880,6 +2874,11 @@ func (w *responseWriter) SetWriteDeadline(deadline time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *responseWriter) EnableFullDuplex() error {
|
||||
// We always support full duplex responses, so this is a no-op.
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *responseWriter) Flush() {
|
||||
w.FlushError()
|
||||
}
|
||||
@@ -3229,12 +3228,12 @@ func (sc *serverConn) startPush(msg *startPushRequest) {
|
||||
// we start in "half closed (remote)" for simplicity.
|
||||
// See further comments at the definition of stateHalfClosedRemote.
|
||||
promised := sc.newStream(promisedID, msg.parent.id, stateHalfClosedRemote)
|
||||
rw, req, err := sc.newWriterAndRequestNoBody(promised, requestParam{
|
||||
method: msg.method,
|
||||
scheme: msg.url.Scheme,
|
||||
authority: msg.url.Host,
|
||||
path: msg.url.RequestURI(),
|
||||
header: cloneHeader(msg.header), // clone since handler runs concurrently with writing the PUSH_PROMISE
|
||||
rw, req, err := sc.newWriterAndRequestNoBody(promised, httpcommon.ServerRequestParam{
|
||||
Method: msg.method,
|
||||
Scheme: msg.url.Scheme,
|
||||
Authority: msg.url.Host,
|
||||
Path: msg.url.RequestURI(),
|
||||
Header: cloneHeader(msg.header), // clone since handler runs concurrently with writing the PUSH_PROMISE
|
||||
})
|
||||
if err != nil {
|
||||
// Should not happen, since we've already validated msg.url.
|
||||
|
||||
690
vendor/golang.org/x/net/http2/transport.go
generated
vendored
690
vendor/golang.org/x/net/http2/transport.go
generated
vendored
File diff suppressed because it is too large
Load Diff
3
vendor/golang.org/x/net/http2/write.go
generated
vendored
3
vendor/golang.org/x/net/http2/write.go
generated
vendored
@@ -13,6 +13,7 @@ import (
|
||||
|
||||
"golang.org/x/net/http/httpguts"
|
||||
"golang.org/x/net/http2/hpack"
|
||||
"golang.org/x/net/internal/httpcommon"
|
||||
)
|
||||
|
||||
// writeFramer is implemented by any type that is used to write frames.
|
||||
@@ -351,7 +352,7 @@ func encodeHeaders(enc *hpack.Encoder, h http.Header, keys []string) {
|
||||
}
|
||||
for _, k := range keys {
|
||||
vv := h[k]
|
||||
k, ascii := lowerHeader(k)
|
||||
k, ascii := httpcommon.LowerHeader(k)
|
||||
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).
|
||||
|
||||
Reference in New Issue
Block a user