Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
e5ed62e8
Commit
e5ed62e8
authored
Jul 15, 2016
by
Timothy St. Clair
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update golang.org/x/net godep for http2 issues being seen during scale
tests
parent
6193335b
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
31 changed files
with
1541 additions
and
634 deletions
+1541
-634
Godeps.json
Godeps/Godeps.json
+15
-15
LICENSES
Godeps/LICENSES
+35
-0
context.go
vendor/golang.org/x/net/context/context.go
+2
-293
cancelreq.go
vendor/golang.org/x/net/context/ctxhttp/cancelreq.go
+0
-19
cancelreq_go14.go
vendor/golang.org/x/net/context/ctxhttp/cancelreq_go14.go
+0
-23
ctxhttp.go
vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go
+10
-86
ctxhttp_pre17.go
vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17.go
+147
-0
go17.go
vendor/golang.org/x/net/context/go17.go
+72
-0
pre_go17.go
vendor/golang.org/x/net/context/pre_go17.go
+300
-0
client_conn_pool.go
vendor/golang.org/x/net/http2/client_conn_pool.go
+31
-1
configure_transport.go
vendor/golang.org/x/net/http2/configure_transport.go
+1
-10
errors.go
vendor/golang.org/x/net/http2/errors.go
+33
-1
frame.go
vendor/golang.org/x/net/http2/frame.go
+244
-6
go15.go
vendor/golang.org/x/net/http2/go15.go
+0
-11
go16.go
vendor/golang.org/x/net/http2/go16.go
+43
-0
go17.go
vendor/golang.org/x/net/http2/go17.go
+94
-0
encode.go
vendor/golang.org/x/net/http2/hpack/encode.go
+1
-1
hpack.go
vendor/golang.org/x/net/http2/hpack/hpack.go
+12
-3
huffman.go
vendor/golang.org/x/net/http2/hpack/huffman.go
+32
-10
http2.go
vendor/golang.org/x/net/http2/http2.go
+43
-121
not_go15.go
vendor/golang.org/x/net/http2/not_go15.go
+0
-11
not_go16.go
vendor/golang.org/x/net/http2/not_go16.go
+34
-1
not_go17.go
vendor/golang.org/x/net/http2/not_go17.go
+51
-0
pipe.go
vendor/golang.org/x/net/http2/pipe.go
+6
-0
server.go
vendor/golang.org/x/net/http2/server.go
+0
-0
transport.go
vendor/golang.org/x/net/http2/transport.go
+0
-0
write.go
vendor/golang.org/x/net/http2/write.go
+12
-11
httplex.go
vendor/golang.org/x/net/lex/httplex/httplex.go
+312
-0
trace.go
vendor/golang.org/x/net/trace/trace.go
+9
-5
hybi.go
vendor/golang.org/x/net/websocket/hybi.go
+0
-3
websocket.go
vendor/golang.org/x/net/websocket/websocket.go
+2
-3
No files found.
Godeps/Godeps.json
View file @
e5ed62e8
...
...
@@ -225,7 +225,7 @@
},
{
"ImportPath"
:
"github.com/codegangsta/negroni"
,
"Comment"
:
"v0.1
.0
-62-g8d75e11"
,
"Comment"
:
"v0.1-62-g8d75e11"
,
"Rev"
:
"8d75e11374a1928608c906fe745b538483e7aeb2"
},
{
...
...
@@ -1987,43 +1987,47 @@
},
{
"ImportPath"
:
"golang.org/x/net/context"
,
"Rev"
:
"
62685c2d7ca23c807425dca88b11a3e2323dab41
"
"Rev"
:
"
e90d6d0afc4c315a0d87a568ae68577cc15149a0
"
},
{
"ImportPath"
:
"golang.org/x/net/context/ctxhttp"
,
"Rev"
:
"
62685c2d7ca23c807425dca88b11a3e2323dab41
"
"Rev"
:
"
e90d6d0afc4c315a0d87a568ae68577cc15149a0
"
},
{
"ImportPath"
:
"golang.org/x/net/html"
,
"Rev"
:
"
62685c2d7ca23c807425dca88b11a3e2323dab41
"
"Rev"
:
"
e90d6d0afc4c315a0d87a568ae68577cc15149a0
"
},
{
"ImportPath"
:
"golang.org/x/net/html/atom"
,
"Rev"
:
"
62685c2d7ca23c807425dca88b11a3e2323dab41
"
"Rev"
:
"
e90d6d0afc4c315a0d87a568ae68577cc15149a0
"
},
{
"ImportPath"
:
"golang.org/x/net/http2"
,
"Rev"
:
"
62685c2d7ca23c807425dca88b11a3e2323dab41
"
"Rev"
:
"
e90d6d0afc4c315a0d87a568ae68577cc15149a0
"
},
{
"ImportPath"
:
"golang.org/x/net/http2/hpack"
,
"Rev"
:
"
62685c2d7ca23c807425dca88b11a3e2323dab41
"
"Rev"
:
"
e90d6d0afc4c315a0d87a568ae68577cc15149a0
"
},
{
"ImportPath"
:
"golang.org/x/net/internal/timeseries"
,
"Rev"
:
"62685c2d7ca23c807425dca88b11a3e2323dab41"
"Rev"
:
"e90d6d0afc4c315a0d87a568ae68577cc15149a0"
},
{
"ImportPath"
:
"golang.org/x/net/lex/httplex"
,
"Rev"
:
"e90d6d0afc4c315a0d87a568ae68577cc15149a0"
},
{
"ImportPath"
:
"golang.org/x/net/proxy"
,
"Rev"
:
"
62685c2d7ca23c807425dca88b11a3e2323dab41
"
"Rev"
:
"
e90d6d0afc4c315a0d87a568ae68577cc15149a0
"
},
{
"ImportPath"
:
"golang.org/x/net/trace"
,
"Rev"
:
"
62685c2d7ca23c807425dca88b11a3e2323dab41
"
"Rev"
:
"
e90d6d0afc4c315a0d87a568ae68577cc15149a0
"
},
{
"ImportPath"
:
"golang.org/x/net/websocket"
,
"Rev"
:
"
62685c2d7ca23c807425dca88b11a3e2323dab41
"
"Rev"
:
"
e90d6d0afc4c315a0d87a568ae68577cc15149a0
"
},
{
"ImportPath"
:
"golang.org/x/oauth2"
,
...
...
@@ -2119,22 +2123,18 @@
},
{
"ImportPath"
:
"gopkg.in/gcfg.v1"
,
"Comment"
:
"v1.0.0"
,
"Rev"
:
"083575c3955c85df16fe9590cceab64d03f5eb6e"
},
{
"ImportPath"
:
"gopkg.in/gcfg.v1/scanner"
,
"Comment"
:
"v1.0.0"
,
"Rev"
:
"083575c3955c85df16fe9590cceab64d03f5eb6e"
},
{
"ImportPath"
:
"gopkg.in/gcfg.v1/token"
,
"Comment"
:
"v1.0.0"
,
"Rev"
:
"083575c3955c85df16fe9590cceab64d03f5eb6e"
},
{
"ImportPath"
:
"gopkg.in/gcfg.v1/types"
,
"Comment"
:
"v1.0.0"
,
"Rev"
:
"083575c3955c85df16fe9590cceab64d03f5eb6e"
},
{
...
...
Godeps/LICENSES
View file @
e5ed62e8
...
...
@@ -62698,6 +62698,41 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================================================
=
vendor
/
golang
.
org
/
x
/
net
/
lex
/
httplex
licensed
under
:
=
Copyright
(
c
)
2009
The
Go
Authors
.
All
rights
reserved
.
Redistribution
and
use
in
source
and
binary
forms
,
with
or
without
modification
,
are
permitted
provided
that
the
following
conditions
are
met
:
*
Redistributions
of
source
code
must
retain
the
above
copyright
notice
,
this
list
of
conditions
and
the
following
disclaimer
.
*
Redistributions
in
binary
form
must
reproduce
the
above
copyright
notice
,
this
list
of
conditions
and
the
following
disclaimer
in
the
documentation
and
/
or
other
materials
provided
with
the
distribution
.
*
Neither
the
name
of
Google
Inc
.
nor
the
names
of
its
contributors
may
be
used
to
endorse
or
promote
products
derived
from
this
software
without
specific
prior
written
permission
.
THIS
SOFTWARE
IS
PROVIDED
BY
THE
COPYRIGHT
HOLDERS
AND
CONTRIBUTORS
"AS IS"
AND
ANY
EXPRESS
OR
IMPLIED
WARRANTIES
,
INCLUDING
,
BUT
NOT
LIMITED
TO
,
THE
IMPLIED
WARRANTIES
OF
MERCHANTABILITY
AND
FITNESS
FOR
A
PARTICULAR
PURPOSE
ARE
DISCLAIMED
.
IN
NO
EVENT
SHALL
THE
COPYRIGHT
OWNER
OR
CONTRIBUTORS
BE
LIABLE
FOR
ANY
DIRECT
,
INDIRECT
,
INCIDENTAL
,
SPECIAL
,
EXEMPLARY
,
OR
CONSEQUENTIAL
DAMAGES
(
INCLUDING
,
BUT
NOT
LIMITED
TO
,
PROCUREMENT
OF
SUBSTITUTE
GOODS
OR
SERVICES
;
LOSS
OF
USE
,
DATA
,
OR
PROFITS
;
OR
BUSINESS
INTERRUPTION
)
HOWEVER
CAUSED
AND
ON
ANY
THEORY
OF
LIABILITY
,
WHETHER
IN
CONTRACT
,
STRICT
LIABILITY
,
OR
TORT
(
INCLUDING
NEGLIGENCE
OR
OTHERWISE
)
ARISING
IN
ANY
WAY
OUT
OF
THE
USE
OF
THIS
SOFTWARE
,
EVEN
IF
ADVISED
OF
THE
POSSIBILITY
OF
SUCH
DAMAGE
.
=
vendor
/
golang
.
org
/
x
/
net
/
LICENSE
5
d4950ecb7b26d2c5e4e7b4e0dd74707
-
================================================================================
================================================================================
=
vendor
/
golang
.
org
/
x
/
net
/
proxy
licensed
under
:
=
Copyright
(
c
)
2009
The
Go
Authors
.
All
rights
reserved
.
vendor/golang.org/x/net/context/context.go
View file @
e5ed62e8
...
...
@@ -36,12 +36,7 @@
// Contexts.
package
context
import
(
"errors"
"fmt"
"sync"
"time"
)
import
"time"
// A Context carries a deadline, a cancelation signal, and other values across
// API boundaries.
...
...
@@ -66,7 +61,7 @@ type Context interface {
//
// // Stream generates values with DoSomething and sends them to out
// // until DoSomething returns an error or ctx.Done is closed.
// func Stream(ctx context.Context, out
<-chan
Value) error {
// func Stream(ctx context.Context, out
chan<-
Value) error {
// for {
// v, err := DoSomething(ctx)
// if err != nil {
...
...
@@ -138,48 +133,6 @@ type Context interface {
Value
(
key
interface
{})
interface
{}
}
// Canceled is the error returned by Context.Err when the context is canceled.
var
Canceled
=
errors
.
New
(
"context canceled"
)
// DeadlineExceeded is the error returned by Context.Err when the context's
// deadline passes.
var
DeadlineExceeded
=
errors
.
New
(
"context deadline exceeded"
)
// An emptyCtx is never canceled, has no values, and has no deadline. It is not
// struct{}, since vars of this type must have distinct addresses.
type
emptyCtx
int
func
(
*
emptyCtx
)
Deadline
()
(
deadline
time
.
Time
,
ok
bool
)
{
return
}
func
(
*
emptyCtx
)
Done
()
<-
chan
struct
{}
{
return
nil
}
func
(
*
emptyCtx
)
Err
()
error
{
return
nil
}
func
(
*
emptyCtx
)
Value
(
key
interface
{})
interface
{}
{
return
nil
}
func
(
e
*
emptyCtx
)
String
()
string
{
switch
e
{
case
background
:
return
"context.Background"
case
todo
:
return
"context.TODO"
}
return
"unknown empty Context"
}
var
(
background
=
new
(
emptyCtx
)
todo
=
new
(
emptyCtx
)
)
// Background returns a non-nil, empty Context. It is never canceled, has no
// values, and has no deadline. It is typically used by the main function,
// initialization, and tests, and as the top-level Context for incoming
...
...
@@ -201,247 +154,3 @@ func TODO() Context {
// A CancelFunc does not wait for the work to stop.
// After the first call, subsequent calls to a CancelFunc do nothing.
type
CancelFunc
func
()
// WithCancel returns a copy of parent with a new Done channel. The returned
// context's Done channel is closed when the returned cancel function is called
// or when the parent context's Done channel is closed, whichever happens first.
//
// Canceling this context releases resources associated with it, so code should
// call cancel as soon as the operations running in this Context complete.
func
WithCancel
(
parent
Context
)
(
ctx
Context
,
cancel
CancelFunc
)
{
c
:=
newCancelCtx
(
parent
)
propagateCancel
(
parent
,
&
c
)
return
&
c
,
func
()
{
c
.
cancel
(
true
,
Canceled
)
}
}
// newCancelCtx returns an initialized cancelCtx.
func
newCancelCtx
(
parent
Context
)
cancelCtx
{
return
cancelCtx
{
Context
:
parent
,
done
:
make
(
chan
struct
{}),
}
}
// propagateCancel arranges for child to be canceled when parent is.
func
propagateCancel
(
parent
Context
,
child
canceler
)
{
if
parent
.
Done
()
==
nil
{
return
// parent is never canceled
}
if
p
,
ok
:=
parentCancelCtx
(
parent
);
ok
{
p
.
mu
.
Lock
()
if
p
.
err
!=
nil
{
// parent has already been canceled
child
.
cancel
(
false
,
p
.
err
)
}
else
{
if
p
.
children
==
nil
{
p
.
children
=
make
(
map
[
canceler
]
bool
)
}
p
.
children
[
child
]
=
true
}
p
.
mu
.
Unlock
()
}
else
{
go
func
()
{
select
{
case
<-
parent
.
Done
()
:
child
.
cancel
(
false
,
parent
.
Err
())
case
<-
child
.
Done
()
:
}
}()
}
}
// parentCancelCtx follows a chain of parent references until it finds a
// *cancelCtx. This function understands how each of the concrete types in this
// package represents its parent.
func
parentCancelCtx
(
parent
Context
)
(
*
cancelCtx
,
bool
)
{
for
{
switch
c
:=
parent
.
(
type
)
{
case
*
cancelCtx
:
return
c
,
true
case
*
timerCtx
:
return
&
c
.
cancelCtx
,
true
case
*
valueCtx
:
parent
=
c
.
Context
default
:
return
nil
,
false
}
}
}
// removeChild removes a context from its parent.
func
removeChild
(
parent
Context
,
child
canceler
)
{
p
,
ok
:=
parentCancelCtx
(
parent
)
if
!
ok
{
return
}
p
.
mu
.
Lock
()
if
p
.
children
!=
nil
{
delete
(
p
.
children
,
child
)
}
p
.
mu
.
Unlock
()
}
// A canceler is a context type that can be canceled directly. The
// implementations are *cancelCtx and *timerCtx.
type
canceler
interface
{
cancel
(
removeFromParent
bool
,
err
error
)
Done
()
<-
chan
struct
{}
}
// A cancelCtx can be canceled. When canceled, it also cancels any children
// that implement canceler.
type
cancelCtx
struct
{
Context
done
chan
struct
{}
// closed by the first cancel call.
mu
sync
.
Mutex
children
map
[
canceler
]
bool
// set to nil by the first cancel call
err
error
// set to non-nil by the first cancel call
}
func
(
c
*
cancelCtx
)
Done
()
<-
chan
struct
{}
{
return
c
.
done
}
func
(
c
*
cancelCtx
)
Err
()
error
{
c
.
mu
.
Lock
()
defer
c
.
mu
.
Unlock
()
return
c
.
err
}
func
(
c
*
cancelCtx
)
String
()
string
{
return
fmt
.
Sprintf
(
"%v.WithCancel"
,
c
.
Context
)
}
// cancel closes c.done, cancels each of c's children, and, if
// removeFromParent is true, removes c from its parent's children.
func
(
c
*
cancelCtx
)
cancel
(
removeFromParent
bool
,
err
error
)
{
if
err
==
nil
{
panic
(
"context: internal error: missing cancel error"
)
}
c
.
mu
.
Lock
()
if
c
.
err
!=
nil
{
c
.
mu
.
Unlock
()
return
// already canceled
}
c
.
err
=
err
close
(
c
.
done
)
for
child
:=
range
c
.
children
{
// NOTE: acquiring the child's lock while holding parent's lock.
child
.
cancel
(
false
,
err
)
}
c
.
children
=
nil
c
.
mu
.
Unlock
()
if
removeFromParent
{
removeChild
(
c
.
Context
,
c
)
}
}
// WithDeadline returns a copy of the parent context with the deadline adjusted
// to be no later than d. If the parent's deadline is already earlier than d,
// WithDeadline(parent, d) is semantically equivalent to parent. The returned
// context's Done channel is closed when the deadline expires, when the returned
// cancel function is called, or when the parent context's Done channel is
// closed, whichever happens first.
//
// Canceling this context releases resources associated with it, so code should
// call cancel as soon as the operations running in this Context complete.
func
WithDeadline
(
parent
Context
,
deadline
time
.
Time
)
(
Context
,
CancelFunc
)
{
if
cur
,
ok
:=
parent
.
Deadline
();
ok
&&
cur
.
Before
(
deadline
)
{
// The current deadline is already sooner than the new one.
return
WithCancel
(
parent
)
}
c
:=
&
timerCtx
{
cancelCtx
:
newCancelCtx
(
parent
),
deadline
:
deadline
,
}
propagateCancel
(
parent
,
c
)
d
:=
deadline
.
Sub
(
time
.
Now
())
if
d
<=
0
{
c
.
cancel
(
true
,
DeadlineExceeded
)
// deadline has already passed
return
c
,
func
()
{
c
.
cancel
(
true
,
Canceled
)
}
}
c
.
mu
.
Lock
()
defer
c
.
mu
.
Unlock
()
if
c
.
err
==
nil
{
c
.
timer
=
time
.
AfterFunc
(
d
,
func
()
{
c
.
cancel
(
true
,
DeadlineExceeded
)
})
}
return
c
,
func
()
{
c
.
cancel
(
true
,
Canceled
)
}
}
// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to
// implement Done and Err. It implements cancel by stopping its timer then
// delegating to cancelCtx.cancel.
type
timerCtx
struct
{
cancelCtx
timer
*
time
.
Timer
// Under cancelCtx.mu.
deadline
time
.
Time
}
func
(
c
*
timerCtx
)
Deadline
()
(
deadline
time
.
Time
,
ok
bool
)
{
return
c
.
deadline
,
true
}
func
(
c
*
timerCtx
)
String
()
string
{
return
fmt
.
Sprintf
(
"%v.WithDeadline(%s [%s])"
,
c
.
cancelCtx
.
Context
,
c
.
deadline
,
c
.
deadline
.
Sub
(
time
.
Now
()))
}
func
(
c
*
timerCtx
)
cancel
(
removeFromParent
bool
,
err
error
)
{
c
.
cancelCtx
.
cancel
(
false
,
err
)
if
removeFromParent
{
// Remove this timerCtx from its parent cancelCtx's children.
removeChild
(
c
.
cancelCtx
.
Context
,
c
)
}
c
.
mu
.
Lock
()
if
c
.
timer
!=
nil
{
c
.
timer
.
Stop
()
c
.
timer
=
nil
}
c
.
mu
.
Unlock
()
}
// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
//
// Canceling this context releases resources associated with it, so code should
// call cancel as soon as the operations running in this Context complete:
//
// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
// defer cancel() // releases resources if slowOperation completes before timeout elapses
// return slowOperation(ctx)
// }
func
WithTimeout
(
parent
Context
,
timeout
time
.
Duration
)
(
Context
,
CancelFunc
)
{
return
WithDeadline
(
parent
,
time
.
Now
()
.
Add
(
timeout
))
}
// WithValue returns a copy of parent in which the value associated with key is
// val.
//
// Use context Values only for request-scoped data that transits processes and
// APIs, not for passing optional parameters to functions.
func
WithValue
(
parent
Context
,
key
interface
{},
val
interface
{})
Context
{
return
&
valueCtx
{
parent
,
key
,
val
}
}
// A valueCtx carries a key-value pair. It implements Value for that key and
// delegates all other calls to the embedded Context.
type
valueCtx
struct
{
Context
key
,
val
interface
{}
}
func
(
c
*
valueCtx
)
String
()
string
{
return
fmt
.
Sprintf
(
"%v.WithValue(%#v, %#v)"
,
c
.
Context
,
c
.
key
,
c
.
val
)
}
func
(
c
*
valueCtx
)
Value
(
key
interface
{})
interface
{}
{
if
c
.
key
==
key
{
return
c
.
val
}
return
c
.
Context
.
Value
(
key
)
}
vendor/golang.org/x/net/context/ctxhttp/cancelreq.go
deleted
100644 → 0
View file @
6193335b
// Copyright 2015 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.
// +build go1.5
package
ctxhttp
import
"net/http"
func
canceler
(
client
*
http
.
Client
,
req
*
http
.
Request
)
func
()
{
// TODO(djd): Respect any existing value of req.Cancel.
ch
:=
make
(
chan
struct
{})
req
.
Cancel
=
ch
return
func
()
{
close
(
ch
)
}
}
vendor/golang.org/x/net/context/ctxhttp/cancelreq_go14.go
deleted
100644 → 0
View file @
6193335b
// Copyright 2015 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.
// +build !go1.5
package
ctxhttp
import
"net/http"
type
requestCanceler
interface
{
CancelRequest
(
*
http
.
Request
)
}
func
canceler
(
client
*
http
.
Client
,
req
*
http
.
Request
)
func
()
{
rc
,
ok
:=
client
.
Transport
.
(
requestCanceler
)
if
!
ok
{
return
func
()
{}
}
return
func
()
{
rc
.
CancelRequest
(
req
)
}
}
vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go
View file @
e5ed62e8
// Copyright 201
5
The Go Authors. All rights reserved.
// Copyright 201
6
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.
// +build go1.7
// Package ctxhttp provides helper functions for performing context-aware HTTP requests.
package
ctxhttp
...
...
@@ -14,71 +16,18 @@ import (
"golang.org/x/net/context"
)
func
nop
()
{}
var
(
testHookContextDoneBeforeHeaders
=
nop
testHookDoReturned
=
nop
testHookDidBodyClose
=
nop
)
// Do sends an HTTP request with the provided http.Client and returns an HTTP response.
// Do sends an HTTP request with the provided http.Client and returns
// an HTTP response.
//
// If the client is nil, http.DefaultClient is used.
// If the context is canceled or times out, ctx.Err() will be returned.
//
// The provided ctx must be non-nil. If it is canceled or times out,
// ctx.Err() will be returned.
func
Do
(
ctx
context
.
Context
,
client
*
http
.
Client
,
req
*
http
.
Request
)
(
*
http
.
Response
,
error
)
{
if
client
==
nil
{
client
=
http
.
DefaultClient
}
// Request cancelation changed in Go 1.5, see cancelreq.go and cancelreq_go14.go.
cancel
:=
canceler
(
client
,
req
)
type
responseAndError
struct
{
resp
*
http
.
Response
err
error
}
result
:=
make
(
chan
responseAndError
,
1
)
go
func
()
{
resp
,
err
:=
client
.
Do
(
req
)
testHookDoReturned
()
result
<-
responseAndError
{
resp
,
err
}
}()
var
resp
*
http
.
Response
select
{
case
<-
ctx
.
Done
()
:
testHookContextDoneBeforeHeaders
()
cancel
()
// Clean up after the goroutine calling client.Do:
go
func
()
{
if
r
:=
<-
result
;
r
.
resp
!=
nil
{
testHookDidBodyClose
()
r
.
resp
.
Body
.
Close
()
}
}()
return
nil
,
ctx
.
Err
()
case
r
:=
<-
result
:
var
err
error
resp
,
err
=
r
.
resp
,
r
.
err
if
err
!=
nil
{
return
resp
,
err
}
}
c
:=
make
(
chan
struct
{})
go
func
()
{
select
{
case
<-
ctx
.
Done
()
:
cancel
()
case
<-
c
:
// The response's Body is closed.
}
}()
resp
.
Body
=
&
notifyingReader
{
resp
.
Body
,
c
}
return
resp
,
nil
return
client
.
Do
(
req
.
WithContext
(
ctx
))
}
// Get issues a GET request via the Do function.
...
...
@@ -113,28 +62,3 @@ func Post(ctx context.Context, client *http.Client, url string, bodyType string,
func
PostForm
(
ctx
context
.
Context
,
client
*
http
.
Client
,
url
string
,
data
url
.
Values
)
(
*
http
.
Response
,
error
)
{
return
Post
(
ctx
,
client
,
url
,
"application/x-www-form-urlencoded"
,
strings
.
NewReader
(
data
.
Encode
()))
}
// notifyingReader is an io.ReadCloser that closes the notify channel after
// Close is called or a Read fails on the underlying ReadCloser.
type
notifyingReader
struct
{
io
.
ReadCloser
notify
chan
<-
struct
{}
}
func
(
r
*
notifyingReader
)
Read
(
p
[]
byte
)
(
int
,
error
)
{
n
,
err
:=
r
.
ReadCloser
.
Read
(
p
)
if
err
!=
nil
&&
r
.
notify
!=
nil
{
close
(
r
.
notify
)
r
.
notify
=
nil
}
return
n
,
err
}
func
(
r
*
notifyingReader
)
Close
()
error
{
err
:=
r
.
ReadCloser
.
Close
()
if
r
.
notify
!=
nil
{
close
(
r
.
notify
)
r
.
notify
=
nil
}
return
err
}
vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17.go
0 → 100644
View file @
e5ed62e8
// Copyright 2015 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.
// +build !go1.7
package
ctxhttp
import
(
"io"
"net/http"
"net/url"
"strings"
"golang.org/x/net/context"
)
func
nop
()
{}
var
(
testHookContextDoneBeforeHeaders
=
nop
testHookDoReturned
=
nop
testHookDidBodyClose
=
nop
)
// Do sends an HTTP request with the provided http.Client and returns an HTTP response.
// If the client is nil, http.DefaultClient is used.
// If the context is canceled or times out, ctx.Err() will be returned.
func
Do
(
ctx
context
.
Context
,
client
*
http
.
Client
,
req
*
http
.
Request
)
(
*
http
.
Response
,
error
)
{
if
client
==
nil
{
client
=
http
.
DefaultClient
}
// TODO(djd): Respect any existing value of req.Cancel.
cancel
:=
make
(
chan
struct
{})
req
.
Cancel
=
cancel
type
responseAndError
struct
{
resp
*
http
.
Response
err
error
}
result
:=
make
(
chan
responseAndError
,
1
)
// Make local copies of test hooks closed over by goroutines below.
// Prevents data races in tests.
testHookDoReturned
:=
testHookDoReturned
testHookDidBodyClose
:=
testHookDidBodyClose
go
func
()
{
resp
,
err
:=
client
.
Do
(
req
)
testHookDoReturned
()
result
<-
responseAndError
{
resp
,
err
}
}()
var
resp
*
http
.
Response
select
{
case
<-
ctx
.
Done
()
:
testHookContextDoneBeforeHeaders
()
close
(
cancel
)
// Clean up after the goroutine calling client.Do:
go
func
()
{
if
r
:=
<-
result
;
r
.
resp
!=
nil
{
testHookDidBodyClose
()
r
.
resp
.
Body
.
Close
()
}
}()
return
nil
,
ctx
.
Err
()
case
r
:=
<-
result
:
var
err
error
resp
,
err
=
r
.
resp
,
r
.
err
if
err
!=
nil
{
return
resp
,
err
}
}
c
:=
make
(
chan
struct
{})
go
func
()
{
select
{
case
<-
ctx
.
Done
()
:
close
(
cancel
)
case
<-
c
:
// The response's Body is closed.
}
}()
resp
.
Body
=
&
notifyingReader
{
resp
.
Body
,
c
}
return
resp
,
nil
}
// Get issues a GET request via the Do function.
func
Get
(
ctx
context
.
Context
,
client
*
http
.
Client
,
url
string
)
(
*
http
.
Response
,
error
)
{
req
,
err
:=
http
.
NewRequest
(
"GET"
,
url
,
nil
)
if
err
!=
nil
{
return
nil
,
err
}
return
Do
(
ctx
,
client
,
req
)
}
// Head issues a HEAD request via the Do function.
func
Head
(
ctx
context
.
Context
,
client
*
http
.
Client
,
url
string
)
(
*
http
.
Response
,
error
)
{
req
,
err
:=
http
.
NewRequest
(
"HEAD"
,
url
,
nil
)
if
err
!=
nil
{
return
nil
,
err
}
return
Do
(
ctx
,
client
,
req
)
}
// Post issues a POST request via the Do function.
func
Post
(
ctx
context
.
Context
,
client
*
http
.
Client
,
url
string
,
bodyType
string
,
body
io
.
Reader
)
(
*
http
.
Response
,
error
)
{
req
,
err
:=
http
.
NewRequest
(
"POST"
,
url
,
body
)
if
err
!=
nil
{
return
nil
,
err
}
req
.
Header
.
Set
(
"Content-Type"
,
bodyType
)
return
Do
(
ctx
,
client
,
req
)
}
// PostForm issues a POST request via the Do function.
func
PostForm
(
ctx
context
.
Context
,
client
*
http
.
Client
,
url
string
,
data
url
.
Values
)
(
*
http
.
Response
,
error
)
{
return
Post
(
ctx
,
client
,
url
,
"application/x-www-form-urlencoded"
,
strings
.
NewReader
(
data
.
Encode
()))
}
// notifyingReader is an io.ReadCloser that closes the notify channel after
// Close is called or a Read fails on the underlying ReadCloser.
type
notifyingReader
struct
{
io
.
ReadCloser
notify
chan
<-
struct
{}
}
func
(
r
*
notifyingReader
)
Read
(
p
[]
byte
)
(
int
,
error
)
{
n
,
err
:=
r
.
ReadCloser
.
Read
(
p
)
if
err
!=
nil
&&
r
.
notify
!=
nil
{
close
(
r
.
notify
)
r
.
notify
=
nil
}
return
n
,
err
}
func
(
r
*
notifyingReader
)
Close
()
error
{
err
:=
r
.
ReadCloser
.
Close
()
if
r
.
notify
!=
nil
{
close
(
r
.
notify
)
r
.
notify
=
nil
}
return
err
}
vendor/golang.org/x/net/context/go17.go
0 → 100644
View file @
e5ed62e8
// Copyright 2016 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.
// +build go1.7
package
context
import
(
"context"
// standard library's context, as of Go 1.7
"time"
)
var
(
todo
=
context
.
TODO
()
background
=
context
.
Background
()
)
// Canceled is the error returned by Context.Err when the context is canceled.
var
Canceled
=
context
.
Canceled
// DeadlineExceeded is the error returned by Context.Err when the context's
// deadline passes.
var
DeadlineExceeded
=
context
.
DeadlineExceeded
// WithCancel returns a copy of parent with a new Done channel. The returned
// context's Done channel is closed when the returned cancel function is called
// or when the parent context's Done channel is closed, whichever happens first.
//
// Canceling this context releases resources associated with it, so code should
// call cancel as soon as the operations running in this Context complete.
func
WithCancel
(
parent
Context
)
(
ctx
Context
,
cancel
CancelFunc
)
{
ctx
,
f
:=
context
.
WithCancel
(
parent
)
return
ctx
,
CancelFunc
(
f
)
}
// WithDeadline returns a copy of the parent context with the deadline adjusted
// to be no later than d. If the parent's deadline is already earlier than d,
// WithDeadline(parent, d) is semantically equivalent to parent. The returned
// context's Done channel is closed when the deadline expires, when the returned
// cancel function is called, or when the parent context's Done channel is
// closed, whichever happens first.
//
// Canceling this context releases resources associated with it, so code should
// call cancel as soon as the operations running in this Context complete.
func
WithDeadline
(
parent
Context
,
deadline
time
.
Time
)
(
Context
,
CancelFunc
)
{
ctx
,
f
:=
context
.
WithDeadline
(
parent
,
deadline
)
return
ctx
,
CancelFunc
(
f
)
}
// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
//
// Canceling this context releases resources associated with it, so code should
// call cancel as soon as the operations running in this Context complete:
//
// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
// defer cancel() // releases resources if slowOperation completes before timeout elapses
// return slowOperation(ctx)
// }
func
WithTimeout
(
parent
Context
,
timeout
time
.
Duration
)
(
Context
,
CancelFunc
)
{
return
WithDeadline
(
parent
,
time
.
Now
()
.
Add
(
timeout
))
}
// WithValue returns a copy of parent in which the value associated with key is
// val.
//
// Use context Values only for request-scoped data that transits processes and
// APIs, not for passing optional parameters to functions.
func
WithValue
(
parent
Context
,
key
interface
{},
val
interface
{})
Context
{
return
context
.
WithValue
(
parent
,
key
,
val
)
}
vendor/golang.org/x/net/context/pre_go17.go
0 → 100644
View file @
e5ed62e8
// 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.
// +build !go1.7
package
context
import
(
"errors"
"fmt"
"sync"
"time"
)
// An emptyCtx is never canceled, has no values, and has no deadline. It is not
// struct{}, since vars of this type must have distinct addresses.
type
emptyCtx
int
func
(
*
emptyCtx
)
Deadline
()
(
deadline
time
.
Time
,
ok
bool
)
{
return
}
func
(
*
emptyCtx
)
Done
()
<-
chan
struct
{}
{
return
nil
}
func
(
*
emptyCtx
)
Err
()
error
{
return
nil
}
func
(
*
emptyCtx
)
Value
(
key
interface
{})
interface
{}
{
return
nil
}
func
(
e
*
emptyCtx
)
String
()
string
{
switch
e
{
case
background
:
return
"context.Background"
case
todo
:
return
"context.TODO"
}
return
"unknown empty Context"
}
var
(
background
=
new
(
emptyCtx
)
todo
=
new
(
emptyCtx
)
)
// Canceled is the error returned by Context.Err when the context is canceled.
var
Canceled
=
errors
.
New
(
"context canceled"
)
// DeadlineExceeded is the error returned by Context.Err when the context's
// deadline passes.
var
DeadlineExceeded
=
errors
.
New
(
"context deadline exceeded"
)
// WithCancel returns a copy of parent with a new Done channel. The returned
// context's Done channel is closed when the returned cancel function is called
// or when the parent context's Done channel is closed, whichever happens first.
//
// Canceling this context releases resources associated with it, so code should
// call cancel as soon as the operations running in this Context complete.
func
WithCancel
(
parent
Context
)
(
ctx
Context
,
cancel
CancelFunc
)
{
c
:=
newCancelCtx
(
parent
)
propagateCancel
(
parent
,
c
)
return
c
,
func
()
{
c
.
cancel
(
true
,
Canceled
)
}
}
// newCancelCtx returns an initialized cancelCtx.
func
newCancelCtx
(
parent
Context
)
*
cancelCtx
{
return
&
cancelCtx
{
Context
:
parent
,
done
:
make
(
chan
struct
{}),
}
}
// propagateCancel arranges for child to be canceled when parent is.
func
propagateCancel
(
parent
Context
,
child
canceler
)
{
if
parent
.
Done
()
==
nil
{
return
// parent is never canceled
}
if
p
,
ok
:=
parentCancelCtx
(
parent
);
ok
{
p
.
mu
.
Lock
()
if
p
.
err
!=
nil
{
// parent has already been canceled
child
.
cancel
(
false
,
p
.
err
)
}
else
{
if
p
.
children
==
nil
{
p
.
children
=
make
(
map
[
canceler
]
bool
)
}
p
.
children
[
child
]
=
true
}
p
.
mu
.
Unlock
()
}
else
{
go
func
()
{
select
{
case
<-
parent
.
Done
()
:
child
.
cancel
(
false
,
parent
.
Err
())
case
<-
child
.
Done
()
:
}
}()
}
}
// parentCancelCtx follows a chain of parent references until it finds a
// *cancelCtx. This function understands how each of the concrete types in this
// package represents its parent.
func
parentCancelCtx
(
parent
Context
)
(
*
cancelCtx
,
bool
)
{
for
{
switch
c
:=
parent
.
(
type
)
{
case
*
cancelCtx
:
return
c
,
true
case
*
timerCtx
:
return
c
.
cancelCtx
,
true
case
*
valueCtx
:
parent
=
c
.
Context
default
:
return
nil
,
false
}
}
}
// removeChild removes a context from its parent.
func
removeChild
(
parent
Context
,
child
canceler
)
{
p
,
ok
:=
parentCancelCtx
(
parent
)
if
!
ok
{
return
}
p
.
mu
.
Lock
()
if
p
.
children
!=
nil
{
delete
(
p
.
children
,
child
)
}
p
.
mu
.
Unlock
()
}
// A canceler is a context type that can be canceled directly. The
// implementations are *cancelCtx and *timerCtx.
type
canceler
interface
{
cancel
(
removeFromParent
bool
,
err
error
)
Done
()
<-
chan
struct
{}
}
// A cancelCtx can be canceled. When canceled, it also cancels any children
// that implement canceler.
type
cancelCtx
struct
{
Context
done
chan
struct
{}
// closed by the first cancel call.
mu
sync
.
Mutex
children
map
[
canceler
]
bool
// set to nil by the first cancel call
err
error
// set to non-nil by the first cancel call
}
func
(
c
*
cancelCtx
)
Done
()
<-
chan
struct
{}
{
return
c
.
done
}
func
(
c
*
cancelCtx
)
Err
()
error
{
c
.
mu
.
Lock
()
defer
c
.
mu
.
Unlock
()
return
c
.
err
}
func
(
c
*
cancelCtx
)
String
()
string
{
return
fmt
.
Sprintf
(
"%v.WithCancel"
,
c
.
Context
)
}
// cancel closes c.done, cancels each of c's children, and, if
// removeFromParent is true, removes c from its parent's children.
func
(
c
*
cancelCtx
)
cancel
(
removeFromParent
bool
,
err
error
)
{
if
err
==
nil
{
panic
(
"context: internal error: missing cancel error"
)
}
c
.
mu
.
Lock
()
if
c
.
err
!=
nil
{
c
.
mu
.
Unlock
()
return
// already canceled
}
c
.
err
=
err
close
(
c
.
done
)
for
child
:=
range
c
.
children
{
// NOTE: acquiring the child's lock while holding parent's lock.
child
.
cancel
(
false
,
err
)
}
c
.
children
=
nil
c
.
mu
.
Unlock
()
if
removeFromParent
{
removeChild
(
c
.
Context
,
c
)
}
}
// WithDeadline returns a copy of the parent context with the deadline adjusted
// to be no later than d. If the parent's deadline is already earlier than d,
// WithDeadline(parent, d) is semantically equivalent to parent. The returned
// context's Done channel is closed when the deadline expires, when the returned
// cancel function is called, or when the parent context's Done channel is
// closed, whichever happens first.
//
// Canceling this context releases resources associated with it, so code should
// call cancel as soon as the operations running in this Context complete.
func
WithDeadline
(
parent
Context
,
deadline
time
.
Time
)
(
Context
,
CancelFunc
)
{
if
cur
,
ok
:=
parent
.
Deadline
();
ok
&&
cur
.
Before
(
deadline
)
{
// The current deadline is already sooner than the new one.
return
WithCancel
(
parent
)
}
c
:=
&
timerCtx
{
cancelCtx
:
newCancelCtx
(
parent
),
deadline
:
deadline
,
}
propagateCancel
(
parent
,
c
)
d
:=
deadline
.
Sub
(
time
.
Now
())
if
d
<=
0
{
c
.
cancel
(
true
,
DeadlineExceeded
)
// deadline has already passed
return
c
,
func
()
{
c
.
cancel
(
true
,
Canceled
)
}
}
c
.
mu
.
Lock
()
defer
c
.
mu
.
Unlock
()
if
c
.
err
==
nil
{
c
.
timer
=
time
.
AfterFunc
(
d
,
func
()
{
c
.
cancel
(
true
,
DeadlineExceeded
)
})
}
return
c
,
func
()
{
c
.
cancel
(
true
,
Canceled
)
}
}
// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to
// implement Done and Err. It implements cancel by stopping its timer then
// delegating to cancelCtx.cancel.
type
timerCtx
struct
{
*
cancelCtx
timer
*
time
.
Timer
// Under cancelCtx.mu.
deadline
time
.
Time
}
func
(
c
*
timerCtx
)
Deadline
()
(
deadline
time
.
Time
,
ok
bool
)
{
return
c
.
deadline
,
true
}
func
(
c
*
timerCtx
)
String
()
string
{
return
fmt
.
Sprintf
(
"%v.WithDeadline(%s [%s])"
,
c
.
cancelCtx
.
Context
,
c
.
deadline
,
c
.
deadline
.
Sub
(
time
.
Now
()))
}
func
(
c
*
timerCtx
)
cancel
(
removeFromParent
bool
,
err
error
)
{
c
.
cancelCtx
.
cancel
(
false
,
err
)
if
removeFromParent
{
// Remove this timerCtx from its parent cancelCtx's children.
removeChild
(
c
.
cancelCtx
.
Context
,
c
)
}
c
.
mu
.
Lock
()
if
c
.
timer
!=
nil
{
c
.
timer
.
Stop
()
c
.
timer
=
nil
}
c
.
mu
.
Unlock
()
}
// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
//
// Canceling this context releases resources associated with it, so code should
// call cancel as soon as the operations running in this Context complete:
//
// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
// defer cancel() // releases resources if slowOperation completes before timeout elapses
// return slowOperation(ctx)
// }
func
WithTimeout
(
parent
Context
,
timeout
time
.
Duration
)
(
Context
,
CancelFunc
)
{
return
WithDeadline
(
parent
,
time
.
Now
()
.
Add
(
timeout
))
}
// WithValue returns a copy of parent in which the value associated with key is
// val.
//
// Use context Values only for request-scoped data that transits processes and
// APIs, not for passing optional parameters to functions.
func
WithValue
(
parent
Context
,
key
interface
{},
val
interface
{})
Context
{
return
&
valueCtx
{
parent
,
key
,
val
}
}
// A valueCtx carries a key-value pair. It implements Value for that key and
// delegates all other calls to the embedded Context.
type
valueCtx
struct
{
Context
key
,
val
interface
{}
}
func
(
c
*
valueCtx
)
String
()
string
{
return
fmt
.
Sprintf
(
"%v.WithValue(%#v, %#v)"
,
c
.
Context
,
c
.
key
,
c
.
val
)
}
func
(
c
*
valueCtx
)
Value
(
key
interface
{})
interface
{}
{
if
c
.
key
==
key
{
return
c
.
val
}
return
c
.
Context
.
Value
(
key
)
}
vendor/golang.org/x/net/http2/client_conn_pool.go
View file @
e5ed62e8
...
...
@@ -18,6 +18,18 @@ type ClientConnPool interface {
MarkDead
(
*
ClientConn
)
}
// clientConnPoolIdleCloser is the interface implemented by ClientConnPool
// implementations which can close their idle connections.
type
clientConnPoolIdleCloser
interface
{
ClientConnPool
closeIdleConnections
()
}
var
(
_
clientConnPoolIdleCloser
=
(
*
clientConnPool
)(
nil
)
_
clientConnPoolIdleCloser
=
noDialClientConnPool
{}
)
// TODO: use singleflight for dialing and addConnCalls?
type
clientConnPool
struct
{
t
*
Transport
...
...
@@ -40,7 +52,16 @@ const (
noDialOnMiss
=
false
)
func
(
p
*
clientConnPool
)
getClientConn
(
_
*
http
.
Request
,
addr
string
,
dialOnMiss
bool
)
(
*
ClientConn
,
error
)
{
func
(
p
*
clientConnPool
)
getClientConn
(
req
*
http
.
Request
,
addr
string
,
dialOnMiss
bool
)
(
*
ClientConn
,
error
)
{
if
req
.
Close
&&
dialOnMiss
{
// It gets its own connection.
cc
,
err
:=
p
.
t
.
dialClientConn
(
addr
)
if
err
!=
nil
{
return
nil
,
err
}
cc
.
singleUse
=
true
return
cc
,
nil
}
p
.
mu
.
Lock
()
for
_
,
cc
:=
range
p
.
conns
[
addr
]
{
if
cc
.
CanTakeNewRequest
()
{
...
...
@@ -223,3 +244,12 @@ func filterOutClientConn(in []*ClientConn, exclude *ClientConn) []*ClientConn {
}
return
out
}
// noDialClientConnPool is an implementation of http2.ClientConnPool
// which never dials. We let the HTTP/1.1 client dial and use its TLS
// connection instead.
type
noDialClientConnPool
struct
{
*
clientConnPool
}
func
(
p
noDialClientConnPool
)
GetClientConn
(
req
*
http
.
Request
,
addr
string
)
(
*
ClientConn
,
error
)
{
return
p
.
getClientConn
(
req
,
addr
,
noDialOnMiss
)
}
vendor/golang.org/x/net/http2/configure_transport.go
View file @
e5ed62e8
...
...
@@ -32,7 +32,7 @@ func configureTransport(t1 *http.Transport) (*Transport, error) {
t1
.
TLSClientConfig
.
NextProtos
=
append
(
t1
.
TLSClientConfig
.
NextProtos
,
"http/1.1"
)
}
upgradeFn
:=
func
(
authority
string
,
c
*
tls
.
Conn
)
http
.
RoundTripper
{
addr
:=
authorityAddr
(
authority
)
addr
:=
authorityAddr
(
"https"
,
authority
)
if
used
,
err
:=
connPool
.
addConnIfNeeded
(
addr
,
t2
,
c
);
err
!=
nil
{
go
c
.
Close
()
return
erringRoundTripper
{
err
}
...
...
@@ -67,15 +67,6 @@ func registerHTTPSProtocol(t *http.Transport, rt http.RoundTripper) (err error)
return
nil
}
// noDialClientConnPool is an implementation of http2.ClientConnPool
// which never dials. We let the HTTP/1.1 client dial and use its TLS
// connection instead.
type
noDialClientConnPool
struct
{
*
clientConnPool
}
func
(
p
noDialClientConnPool
)
GetClientConn
(
req
*
http
.
Request
,
addr
string
)
(
*
ClientConn
,
error
)
{
return
p
.
getClientConn
(
req
,
addr
,
noDialOnMiss
)
}
// noDialH2RoundTripper is a RoundTripper which only tries to complete the request
// if there's already has a cached connection to the host.
type
noDialH2RoundTripper
struct
{
t
*
Transport
}
...
...
vendor/golang.org/x/net/http2/errors.go
View file @
e5ed62e8
...
...
@@ -4,7 +4,10 @@
package
http2
import
"fmt"
import
(
"errors"
"fmt"
)
// An ErrCode is an unsigned 32-bit error code as defined in the HTTP/2 spec.
type
ErrCode
uint32
...
...
@@ -88,3 +91,32 @@ type connError struct {
func
(
e
connError
)
Error
()
string
{
return
fmt
.
Sprintf
(
"http2: connection error: %v: %v"
,
e
.
Code
,
e
.
Reason
)
}
type
pseudoHeaderError
string
func
(
e
pseudoHeaderError
)
Error
()
string
{
return
fmt
.
Sprintf
(
"invalid pseudo-header %q"
,
string
(
e
))
}
type
duplicatePseudoHeaderError
string
func
(
e
duplicatePseudoHeaderError
)
Error
()
string
{
return
fmt
.
Sprintf
(
"duplicate pseudo-header %q"
,
string
(
e
))
}
type
headerFieldNameError
string
func
(
e
headerFieldNameError
)
Error
()
string
{
return
fmt
.
Sprintf
(
"invalid header field name %q"
,
string
(
e
))
}
type
headerFieldValueError
string
func
(
e
headerFieldValueError
)
Error
()
string
{
return
fmt
.
Sprintf
(
"invalid header field value %q"
,
string
(
e
))
}
var
(
errMixPseudoHeaderTypes
=
errors
.
New
(
"mix of request and response pseudo headers"
)
errPseudoAfterRegular
=
errors
.
New
(
"pseudo header field after regular"
)
)
vendor/golang.org/x/net/http2/frame.go
View file @
e5ed62e8
...
...
@@ -11,7 +11,11 @@ import (
"fmt"
"io"
"log"
"strings"
"sync"
"golang.org/x/net/http2/hpack"
"golang.org/x/net/lex/httplex"
)
const
frameHeaderLen
=
9
...
...
@@ -261,7 +265,7 @@ type Frame interface {
type
Framer
struct
{
r
io
.
Reader
lastFrame
Frame
err
Reason
string
err
Detail
error
// lastHeaderStream is non-zero if the last frame was an
// unfinished HEADERS/CONTINUATION.
...
...
@@ -293,8 +297,20 @@ type Framer struct {
// to return non-compliant frames or frame orders.
// This is for testing and permits using the Framer to test
// other HTTP/2 implementations' conformance to the spec.
// It is not compatible with ReadMetaHeaders.
AllowIllegalReads
bool
// ReadMetaHeaders if non-nil causes ReadFrame to merge
// HEADERS and CONTINUATION frames together and return
// MetaHeadersFrame instead.
ReadMetaHeaders
*
hpack
.
Decoder
// MaxHeaderListSize is the http2 MAX_HEADER_LIST_SIZE.
// It's used only if ReadMetaHeaders is set; 0 means a sane default
// (currently 16MB)
// If the limit is hit, MetaHeadersFrame.Truncated is set true.
MaxHeaderListSize
uint32
// TODO: track which type of frame & with which flags was sent
// last. Then return an error (unless AllowIllegalWrites) if
// we're in the middle of a header block and a
...
...
@@ -307,6 +323,13 @@ type Framer struct {
debugFramerBuf
*
bytes
.
Buffer
}
func
(
fr
*
Framer
)
maxHeaderListSize
()
uint32
{
if
fr
.
MaxHeaderListSize
==
0
{
return
16
<<
20
// sane default, per docs
}
return
fr
.
MaxHeaderListSize
}
func
(
f
*
Framer
)
startWrite
(
ftype
FrameType
,
flags
Flags
,
streamID
uint32
)
{
// Write the FrameHeader.
f
.
wbuf
=
append
(
f
.
wbuf
[
:
0
],
...
...
@@ -402,6 +425,17 @@ func (fr *Framer) SetMaxReadFrameSize(v uint32) {
fr
.
maxReadSize
=
v
}
// ErrorDetail returns a more detailed error of the last error
// returned by Framer.ReadFrame. For instance, if ReadFrame
// returns a StreamError with code PROTOCOL_ERROR, ErrorDetail
// will say exactly what was invalid. ErrorDetail is not guaranteed
// to return a non-nil value and like the rest of the http2 package,
// its return value is not protected by an API compatibility promise.
// ErrorDetail is reset after the next call to ReadFrame.
func
(
fr
*
Framer
)
ErrorDetail
()
error
{
return
fr
.
errDetail
}
// ErrFrameTooLarge is returned from Framer.ReadFrame when the peer
// sends a frame that is larger than declared with SetMaxReadFrameSize.
var
ErrFrameTooLarge
=
errors
.
New
(
"http2: frame too large"
)
...
...
@@ -420,9 +454,10 @@ func terminalReadFrameError(err error) bool {
//
// If the frame is larger than previously set with SetMaxReadFrameSize, the
// returned error is ErrFrameTooLarge. Other errors may be of type
// ConnectionError, StreamError, or anything else from
from
the underlying
// ConnectionError, StreamError, or anything else from the underlying
// reader.
func
(
fr
*
Framer
)
ReadFrame
()
(
Frame
,
error
)
{
fr
.
errDetail
=
nil
if
fr
.
lastFrame
!=
nil
{
fr
.
lastFrame
.
invalidate
()
}
...
...
@@ -450,6 +485,9 @@ func (fr *Framer) ReadFrame() (Frame, error) {
if
fr
.
logReads
{
log
.
Printf
(
"http2: Framer %p: read %v"
,
fr
,
summarizeFrame
(
f
))
}
if
fh
.
Type
==
FrameHeaders
&&
fr
.
ReadMetaHeaders
!=
nil
{
return
fr
.
readMetaFrame
(
f
.
(
*
HeadersFrame
))
}
return
f
,
nil
}
...
...
@@ -458,7 +496,7 @@ func (fr *Framer) ReadFrame() (Frame, error) {
// to the peer before hanging up on them. This might help others debug
// their implementations.
func
(
fr
*
Framer
)
connError
(
code
ErrCode
,
reason
string
)
error
{
fr
.
err
Reason
=
reason
fr
.
err
Detail
=
errors
.
New
(
reason
)
return
ConnectionError
(
code
)
}
...
...
@@ -553,7 +591,14 @@ func parseDataFrame(fh FrameHeader, payload []byte) (Frame, error) {
return
f
,
nil
}
var
errStreamID
=
errors
.
New
(
"invalid streamid"
)
var
(
errStreamID
=
errors
.
New
(
"invalid stream ID"
)
errDepStreamID
=
errors
.
New
(
"invalid dependent stream ID"
)
)
func
validStreamIDOrZero
(
streamID
uint32
)
bool
{
return
streamID
&
(
1
<<
31
)
==
0
}
func
validStreamID
(
streamID
uint32
)
bool
{
return
streamID
!=
0
&&
streamID
&
(
1
<<
31
)
==
0
...
...
@@ -940,8 +985,8 @@ func (f *Framer) WriteHeaders(p HeadersFrameParam) error {
}
if
!
p
.
Priority
.
IsZero
()
{
v
:=
p
.
Priority
.
StreamDep
if
!
validStreamID
(
v
)
&&
!
f
.
AllowIllegalWrites
{
return
err
ors
.
New
(
"invalid dependent stream id"
)
if
!
validStreamID
OrZero
(
v
)
&&
!
f
.
AllowIllegalWrites
{
return
err
DepStreamID
}
if
p
.
Priority
.
Exclusive
{
v
|=
1
<<
31
...
...
@@ -1009,6 +1054,9 @@ func (f *Framer) WritePriority(streamID uint32, p PriorityParam) error {
if
!
validStreamID
(
streamID
)
&&
!
f
.
AllowIllegalWrites
{
return
errStreamID
}
if
!
validStreamIDOrZero
(
p
.
StreamDep
)
{
return
errDepStreamID
}
f
.
startWrite
(
FramePriority
,
0
,
streamID
)
v
:=
p
.
StreamDep
if
p
.
Exclusive
{
...
...
@@ -1225,6 +1273,196 @@ type headersEnder interface {
HeadersEnded
()
bool
}
type
headersOrContinuation
interface
{
headersEnder
HeaderBlockFragment
()
[]
byte
}
// A MetaHeadersFrame is the representation of one HEADERS frame and
// zero or more contiguous CONTINUATION frames and the decoding of
// their HPACK-encoded contents.
//
// This type of frame does not appear on the wire and is only returned
// by the Framer when Framer.ReadMetaHeaders is set.
type
MetaHeadersFrame
struct
{
*
HeadersFrame
// Fields are the fields contained in the HEADERS and
// CONTINUATION frames. The underlying slice is owned by the
// Framer and must not be retained after the next call to
// ReadFrame.
//
// Fields are guaranteed to be in the correct http2 order and
// not have unknown pseudo header fields or invalid header
// field names or values. Required pseudo header fields may be
// missing, however. Use the MetaHeadersFrame.Pseudo accessor
// method access pseudo headers.
Fields
[]
hpack
.
HeaderField
// Truncated is whether the max header list size limit was hit
// and Fields is incomplete. The hpack decoder state is still
// valid, however.
Truncated
bool
}
// PseudoValue returns the given pseudo header field's value.
// The provided pseudo field should not contain the leading colon.
func
(
mh
*
MetaHeadersFrame
)
PseudoValue
(
pseudo
string
)
string
{
for
_
,
hf
:=
range
mh
.
Fields
{
if
!
hf
.
IsPseudo
()
{
return
""
}
if
hf
.
Name
[
1
:
]
==
pseudo
{
return
hf
.
Value
}
}
return
""
}
// RegularFields returns the regular (non-pseudo) header fields of mh.
// The caller does not own the returned slice.
func
(
mh
*
MetaHeadersFrame
)
RegularFields
()
[]
hpack
.
HeaderField
{
for
i
,
hf
:=
range
mh
.
Fields
{
if
!
hf
.
IsPseudo
()
{
return
mh
.
Fields
[
i
:
]
}
}
return
nil
}
// PseudoFields returns the pseudo header fields of mh.
// The caller does not own the returned slice.
func
(
mh
*
MetaHeadersFrame
)
PseudoFields
()
[]
hpack
.
HeaderField
{
for
i
,
hf
:=
range
mh
.
Fields
{
if
!
hf
.
IsPseudo
()
{
return
mh
.
Fields
[
:
i
]
}
}
return
mh
.
Fields
}
func
(
mh
*
MetaHeadersFrame
)
checkPseudos
()
error
{
var
isRequest
,
isResponse
bool
pf
:=
mh
.
PseudoFields
()
for
i
,
hf
:=
range
pf
{
switch
hf
.
Name
{
case
":method"
,
":path"
,
":scheme"
,
":authority"
:
isRequest
=
true
case
":status"
:
isResponse
=
true
default
:
return
pseudoHeaderError
(
hf
.
Name
)
}
// Check for duplicates.
// This would be a bad algorithm, but N is 4.
// And this doesn't allocate.
for
_
,
hf2
:=
range
pf
[
:
i
]
{
if
hf
.
Name
==
hf2
.
Name
{
return
duplicatePseudoHeaderError
(
hf
.
Name
)
}
}
}
if
isRequest
&&
isResponse
{
return
errMixPseudoHeaderTypes
}
return
nil
}
func
(
fr
*
Framer
)
maxHeaderStringLen
()
int
{
v
:=
fr
.
maxHeaderListSize
()
if
uint32
(
int
(
v
))
==
v
{
return
int
(
v
)
}
// They had a crazy big number for MaxHeaderBytes anyway,
// so give them unlimited header lengths:
return
0
}
// readMetaFrame returns 0 or more CONTINUATION frames from fr and
// merge them into into the provided hf and returns a MetaHeadersFrame
// with the decoded hpack values.
func
(
fr
*
Framer
)
readMetaFrame
(
hf
*
HeadersFrame
)
(
*
MetaHeadersFrame
,
error
)
{
if
fr
.
AllowIllegalReads
{
return
nil
,
errors
.
New
(
"illegal use of AllowIllegalReads with ReadMetaHeaders"
)
}
mh
:=
&
MetaHeadersFrame
{
HeadersFrame
:
hf
,
}
var
remainSize
=
fr
.
maxHeaderListSize
()
var
sawRegular
bool
var
invalid
error
// pseudo header field errors
hdec
:=
fr
.
ReadMetaHeaders
hdec
.
SetEmitEnabled
(
true
)
hdec
.
SetMaxStringLength
(
fr
.
maxHeaderStringLen
())
hdec
.
SetEmitFunc
(
func
(
hf
hpack
.
HeaderField
)
{
if
!
httplex
.
ValidHeaderFieldValue
(
hf
.
Value
)
{
invalid
=
headerFieldValueError
(
hf
.
Value
)
}
isPseudo
:=
strings
.
HasPrefix
(
hf
.
Name
,
":"
)
if
isPseudo
{
if
sawRegular
{
invalid
=
errPseudoAfterRegular
}
}
else
{
sawRegular
=
true
if
!
validWireHeaderFieldName
(
hf
.
Name
)
{
invalid
=
headerFieldNameError
(
hf
.
Name
)
}
}
if
invalid
!=
nil
{
hdec
.
SetEmitEnabled
(
false
)
return
}
size
:=
hf
.
Size
()
if
size
>
remainSize
{
hdec
.
SetEmitEnabled
(
false
)
mh
.
Truncated
=
true
return
}
remainSize
-=
size
mh
.
Fields
=
append
(
mh
.
Fields
,
hf
)
})
// Lose reference to MetaHeadersFrame:
defer
hdec
.
SetEmitFunc
(
func
(
hf
hpack
.
HeaderField
)
{})
var
hc
headersOrContinuation
=
hf
for
{
frag
:=
hc
.
HeaderBlockFragment
()
if
_
,
err
:=
hdec
.
Write
(
frag
);
err
!=
nil
{
return
nil
,
ConnectionError
(
ErrCodeCompression
)
}
if
hc
.
HeadersEnded
()
{
break
}
if
f
,
err
:=
fr
.
ReadFrame
();
err
!=
nil
{
return
nil
,
err
}
else
{
hc
=
f
.
(
*
ContinuationFrame
)
// guaranteed by checkFrameOrder
}
}
mh
.
HeadersFrame
.
headerFragBuf
=
nil
mh
.
HeadersFrame
.
invalidate
()
if
err
:=
hdec
.
Close
();
err
!=
nil
{
return
nil
,
ConnectionError
(
ErrCodeCompression
)
}
if
invalid
!=
nil
{
fr
.
errDetail
=
invalid
return
nil
,
StreamError
{
mh
.
StreamID
,
ErrCodeProtocol
}
}
if
err
:=
mh
.
checkPseudos
();
err
!=
nil
{
fr
.
errDetail
=
err
return
nil
,
StreamError
{
mh
.
StreamID
,
ErrCodeProtocol
}
}
return
mh
,
nil
}
func
summarizeFrame
(
f
Frame
)
string
{
var
buf
bytes
.
Buffer
f
.
Header
()
.
writeDebug
(
&
buf
)
...
...
vendor/golang.org/x/net/http2/go15.go
deleted
100644 → 0
View file @
6193335b
// Copyright 2015 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.
// +build go1.5
package
http2
import
"net/http"
func
requestCancel
(
req
*
http
.
Request
)
<-
chan
struct
{}
{
return
req
.
Cancel
}
vendor/golang.org/x/net/http2/go16.go
0 → 100644
View file @
e5ed62e8
// Copyright 2016 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.
// +build go1.6
package
http2
import
(
"crypto/tls"
"net/http"
"time"
)
func
transportExpectContinueTimeout
(
t1
*
http
.
Transport
)
time
.
Duration
{
return
t1
.
ExpectContinueTimeout
}
// isBadCipher reports whether the cipher is blacklisted by the HTTP/2 spec.
func
isBadCipher
(
cipher
uint16
)
bool
{
switch
cipher
{
case
tls
.
TLS_RSA_WITH_RC4_128_SHA
,
tls
.
TLS_RSA_WITH_3DES_EDE_CBC_SHA
,
tls
.
TLS_RSA_WITH_AES_128_CBC_SHA
,
tls
.
TLS_RSA_WITH_AES_256_CBC_SHA
,
tls
.
TLS_RSA_WITH_AES_128_GCM_SHA256
,
tls
.
TLS_RSA_WITH_AES_256_GCM_SHA384
,
tls
.
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
,
tls
.
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
,
tls
.
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
,
tls
.
TLS_ECDHE_RSA_WITH_RC4_128_SHA
,
tls
.
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
,
tls
.
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
,
tls
.
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
:
// Reject cipher suites from Appendix A.
// "This list includes those cipher suites that do not
// offer an ephemeral key exchange and those that are
// based on the TLS null, stream or block cipher type"
return
true
default
:
return
false
}
}
vendor/golang.org/x/net/http2/go17.go
0 → 100644
View file @
e5ed62e8
// Copyright 2016 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.
// +build go1.7
package
http2
import
(
"context"
"net"
"net/http"
"net/http/httptrace"
"time"
)
type
contextContext
interface
{
context
.
Context
}
func
serverConnBaseContext
(
c
net
.
Conn
,
opts
*
ServeConnOpts
)
(
ctx
contextContext
,
cancel
func
())
{
ctx
,
cancel
=
context
.
WithCancel
(
context
.
Background
())
ctx
=
context
.
WithValue
(
ctx
,
http
.
LocalAddrContextKey
,
c
.
LocalAddr
())
if
hs
:=
opts
.
baseConfig
();
hs
!=
nil
{
ctx
=
context
.
WithValue
(
ctx
,
http
.
ServerContextKey
,
hs
)
}
return
}
func
contextWithCancel
(
ctx
contextContext
)
(
_
contextContext
,
cancel
func
())
{
return
context
.
WithCancel
(
ctx
)
}
func
requestWithContext
(
req
*
http
.
Request
,
ctx
contextContext
)
*
http
.
Request
{
return
req
.
WithContext
(
ctx
)
}
type
clientTrace
httptrace
.
ClientTrace
func
reqContext
(
r
*
http
.
Request
)
context
.
Context
{
return
r
.
Context
()
}
func
setResponseUncompressed
(
res
*
http
.
Response
)
{
res
.
Uncompressed
=
true
}
func
traceGotConn
(
req
*
http
.
Request
,
cc
*
ClientConn
)
{
trace
:=
httptrace
.
ContextClientTrace
(
req
.
Context
())
if
trace
==
nil
||
trace
.
GotConn
==
nil
{
return
}
ci
:=
httptrace
.
GotConnInfo
{
Conn
:
cc
.
tconn
}
cc
.
mu
.
Lock
()
ci
.
Reused
=
cc
.
nextStreamID
>
1
ci
.
WasIdle
=
len
(
cc
.
streams
)
==
0
&&
ci
.
Reused
if
ci
.
WasIdle
&&
!
cc
.
lastActive
.
IsZero
()
{
ci
.
IdleTime
=
time
.
Now
()
.
Sub
(
cc
.
lastActive
)
}
cc
.
mu
.
Unlock
()
trace
.
GotConn
(
ci
)
}
func
traceWroteHeaders
(
trace
*
clientTrace
)
{
if
trace
!=
nil
&&
trace
.
WroteHeaders
!=
nil
{
trace
.
WroteHeaders
()
}
}
func
traceGot100Continue
(
trace
*
clientTrace
)
{
if
trace
!=
nil
&&
trace
.
Got100Continue
!=
nil
{
trace
.
Got100Continue
()
}
}
func
traceWait100Continue
(
trace
*
clientTrace
)
{
if
trace
!=
nil
&&
trace
.
Wait100Continue
!=
nil
{
trace
.
Wait100Continue
()
}
}
func
traceWroteRequest
(
trace
*
clientTrace
,
err
error
)
{
if
trace
!=
nil
&&
trace
.
WroteRequest
!=
nil
{
trace
.
WroteRequest
(
httptrace
.
WroteRequestInfo
{
Err
:
err
})
}
}
func
traceFirstResponseByte
(
trace
*
clientTrace
)
{
if
trace
!=
nil
&&
trace
.
GotFirstResponseByte
!=
nil
{
trace
.
GotFirstResponseByte
()
}
}
func
requestTrace
(
req
*
http
.
Request
)
*
clientTrace
{
trace
:=
httptrace
.
ContextClientTrace
(
req
.
Context
())
return
(
*
clientTrace
)(
trace
)
}
vendor/golang.org/x/net/http2/hpack/encode.go
View file @
e5ed62e8
...
...
@@ -144,7 +144,7 @@ func (e *Encoder) SetMaxDynamicTableSizeLimit(v uint32) {
// shouldIndex reports whether f should be indexed.
func
(
e
*
Encoder
)
shouldIndex
(
f
HeaderField
)
bool
{
return
!
f
.
Sensitive
&&
f
.
s
ize
()
<=
e
.
dynTab
.
maxSize
return
!
f
.
Sensitive
&&
f
.
S
ize
()
<=
e
.
dynTab
.
maxSize
}
// appendIndexed appends index i, as encoded in "Indexed Header Field"
...
...
vendor/golang.org/x/net/http2/hpack/hpack.go
View file @
e5ed62e8
...
...
@@ -41,6 +41,14 @@ type HeaderField struct {
Sensitive
bool
}
// IsPseudo reports whether the header field is an http2 pseudo header.
// That is, it reports whether it starts with a colon.
// It is not otherwise guaranteed to be a valid pseudo header field,
// though.
func
(
hf
HeaderField
)
IsPseudo
()
bool
{
return
len
(
hf
.
Name
)
!=
0
&&
hf
.
Name
[
0
]
==
':'
}
func
(
hf
HeaderField
)
String
()
string
{
var
suffix
string
if
hf
.
Sensitive
{
...
...
@@ -49,7 +57,8 @@ func (hf HeaderField) String() string {
return
fmt
.
Sprintf
(
"header field %q = %q%s"
,
hf
.
Name
,
hf
.
Value
,
suffix
)
}
func
(
hf
*
HeaderField
)
size
()
uint32
{
// Size returns the size of an entry per RFC 7540 section 5.2.
func
(
hf
HeaderField
)
Size
()
uint32
{
// http://http2.github.io/http2-spec/compression.html#rfc.section.4.1
// "The size of the dynamic table is the sum of the size of
// its entries. The size of an entry is the sum of its name's
...
...
@@ -171,7 +180,7 @@ func (dt *dynamicTable) setMaxSize(v uint32) {
func
(
dt
*
dynamicTable
)
add
(
f
HeaderField
)
{
dt
.
ents
=
append
(
dt
.
ents
,
f
)
dt
.
size
+=
f
.
s
ize
()
dt
.
size
+=
f
.
S
ize
()
dt
.
evict
()
}
...
...
@@ -179,7 +188,7 @@ func (dt *dynamicTable) add(f HeaderField) {
func
(
dt
*
dynamicTable
)
evict
()
{
base
:=
dt
.
ents
// keep base pointer of slice
for
dt
.
size
>
dt
.
maxSize
{
dt
.
size
-=
dt
.
ents
[
0
]
.
s
ize
()
dt
.
size
-=
dt
.
ents
[
0
]
.
S
ize
()
dt
.
ents
=
dt
.
ents
[
1
:
]
}
...
...
vendor/golang.org/x/net/http2/hpack/huffman.go
View file @
e5ed62e8
...
...
@@ -48,12 +48,16 @@ var ErrInvalidHuffman = errors.New("hpack: invalid Huffman-encoded data")
// maxLen bytes will return ErrStringLength.
func
huffmanDecode
(
buf
*
bytes
.
Buffer
,
maxLen
int
,
v
[]
byte
)
error
{
n
:=
rootHuffmanNode
cur
,
nbits
:=
uint
(
0
),
uint8
(
0
)
// cur is the bit buffer that has not been fed into n.
// cbits is the number of low order bits in cur that are valid.
// sbits is the number of bits of the symbol prefix being decoded.
cur
,
cbits
,
sbits
:=
uint
(
0
),
uint8
(
0
),
uint8
(
0
)
for
_
,
b
:=
range
v
{
cur
=
cur
<<
8
|
uint
(
b
)
nbits
+=
8
for
nbits
>=
8
{
idx
:=
byte
(
cur
>>
(
nbits
-
8
))
cbits
+=
8
sbits
+=
8
for
cbits
>=
8
{
idx
:=
byte
(
cur
>>
(
cbits
-
8
))
n
=
n
.
children
[
idx
]
if
n
==
nil
{
return
ErrInvalidHuffman
...
...
@@ -63,22 +67,40 @@ func huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error {
return
ErrStringLength
}
buf
.
WriteByte
(
n
.
sym
)
n
bits
-=
n
.
codeLen
c
bits
-=
n
.
codeLen
n
=
rootHuffmanNode
sbits
=
cbits
}
else
{
n
bits
-=
8
c
bits
-=
8
}
}
}
for
nbits
>
0
{
n
=
n
.
children
[
byte
(
cur
<<
(
8
-
nbits
))]
if
n
.
children
!=
nil
||
n
.
codeLen
>
nbits
{
for
cbits
>
0
{
n
=
n
.
children
[
byte
(
cur
<<
(
8
-
cbits
))]
if
n
==
nil
{
return
ErrInvalidHuffman
}
if
n
.
children
!=
nil
||
n
.
codeLen
>
cbits
{
break
}
if
maxLen
!=
0
&&
buf
.
Len
()
==
maxLen
{
return
ErrStringLength
}
buf
.
WriteByte
(
n
.
sym
)
n
bits
-=
n
.
codeLen
c
bits
-=
n
.
codeLen
n
=
rootHuffmanNode
sbits
=
cbits
}
if
sbits
>
7
{
// Either there was an incomplete symbol, or overlong padding.
// Both are decoding errors per RFC 7541 section 5.2.
return
ErrInvalidHuffman
}
if
mask
:=
uint
(
1
<<
cbits
-
1
);
cur
&
mask
!=
mask
{
// Trailing bits must be a prefix of EOS per RFC 7541 section 5.2.
return
ErrInvalidHuffman
}
return
nil
}
...
...
vendor/golang.org/x/net/http2/http2.go
View file @
e5ed62e8
...
...
@@ -23,9 +23,12 @@ import (
"io"
"net/http"
"os"
"sort"
"strconv"
"strings"
"sync"
"golang.org/x/net/lex/httplex"
)
var
(
...
...
@@ -165,57 +168,23 @@ var (
errInvalidHeaderFieldValue
=
errors
.
New
(
"http2: invalid header field value"
)
)
// validHeaderFieldName reports whether v is a valid header field name (key).
// RFC 7230 says:
// header-field = field-name ":" OWS field-value OWS
// field-name = token
// tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
// "^" / "_" / "
// validWireHeaderFieldName reports whether v is a valid header field
// name (key). See httplex.ValidHeaderName for the base rules.
//
// Further, http2 says:
// "Just as in HTTP/1.x, header field names are strings of ASCII
// characters that are compared in a case-insensitive
// fashion. However, header field names MUST be converted to
// lowercase prior to their encoding in HTTP/2. "
func
validHeaderFieldName
(
v
string
)
bool
{
func
valid
Wire
HeaderFieldName
(
v
string
)
bool
{
if
len
(
v
)
==
0
{
return
false
}
for
_
,
r
:=
range
v
{
if
int
(
r
)
>=
len
(
isTokenTable
)
||
(
'A'
<=
r
&&
r
<=
'Z'
)
{
return
false
}
if
!
isTokenTable
[
byte
(
r
)]
{
if
!
httplex
.
IsTokenRune
(
r
)
{
return
false
}
}
return
true
}
// validHeaderFieldValue reports whether v is a valid header field value.
//
// RFC 7230 says:
// field-value = *( field-content / obs-fold )
// obj-fold = N/A to http2, and deprecated
// field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
// field-vchar = VCHAR / obs-text
// obs-text = %x80-FF
// VCHAR = "any visible [USASCII] character"
//
// http2 further says: "Similarly, HTTP/2 allows header field values
// that are not valid. While most of the values that can be encoded
// will not alter header field parsing, carriage return (CR, ASCII
// 0xd), line feed (LF, ASCII 0xa), and the zero character (NUL, ASCII
// 0x0) might be exploited by an attacker if they are translated
// verbatim. Any request or response that contains a character not
// permitted in a header field value MUST be treated as malformed
// (Section 8.1.2.6). Valid characters are defined by the
// field-content ABNF rule in Section 3.2 of [RFC7230]."
//
// This function does not (yet?) properly handle the rejection of
// strings that begin or end with SP or HTAB.
func
validHeaderFieldValue
(
v
string
)
bool
{
for
i
:=
0
;
i
<
len
(
v
);
i
++
{
if
b
:=
v
[
i
];
b
<
' '
&&
b
!=
'\t'
||
b
==
0x7f
{
if
'A'
<=
r
&&
r
<=
'Z'
{
return
false
}
}
...
...
@@ -320,7 +289,7 @@ func mustUint31(v int32) uint32 {
}
// bodyAllowedForStatus reports whether a given response status code
// permits a body. See RFC2616, section 4.4.
// permits a body. See RFC
2616, section 4.4.
func
bodyAllowedForStatus
(
status
int
)
bool
{
switch
{
case
status
>=
100
&&
status
<=
199
:
...
...
@@ -344,86 +313,39 @@ func (e *httpError) Temporary() bool { return true }
var
errTimeout
error
=
&
httpError
{
msg
:
"http2: timeout awaiting response headers"
,
timeout
:
true
}
var
isTokenTable
=
[
127
]
bool
{
'!'
:
true
,
'#'
:
true
,
'$'
:
true
,
'%'
:
true
,
'&'
:
true
,
'\'
'
:
true
,
'*'
:
true
,
'+'
:
true
,
'-'
:
true
,
'.'
:
true
,
'0'
:
true
,
'1'
:
true
,
'2'
:
true
,
'3'
:
true
,
'4'
:
true
,
'5'
:
true
,
'6'
:
true
,
'7'
:
true
,
'8'
:
true
,
'9'
:
true
,
'A'
:
true
,
'B'
:
true
,
'C'
:
true
,
'D'
:
true
,
'E'
:
true
,
'F'
:
true
,
'G'
:
true
,
'H'
:
true
,
'I'
:
true
,
'J'
:
true
,
'K'
:
true
,
'L'
:
true
,
'M'
:
true
,
'N'
:
true
,
'O'
:
true
,
'P'
:
true
,
'Q'
:
true
,
'R'
:
true
,
'S'
:
true
,
'T'
:
true
,
'U'
:
true
,
'W'
:
true
,
'V'
:
true
,
'X'
:
true
,
'Y'
:
true
,
'Z'
:
true
,
'^'
:
true
,
'_'
:
true
,
'`'
:
true
,
'a'
:
true
,
'b'
:
true
,
'c'
:
true
,
'd'
:
true
,
'e'
:
true
,
'f'
:
true
,
'g'
:
true
,
'h'
:
true
,
'i'
:
true
,
'j'
:
true
,
'k'
:
true
,
'l'
:
true
,
'm'
:
true
,
'n'
:
true
,
'o'
:
true
,
'p'
:
true
,
'q'
:
true
,
'r'
:
true
,
's'
:
true
,
't'
:
true
,
'u'
:
true
,
'v'
:
true
,
'w'
:
true
,
'x'
:
true
,
'y'
:
true
,
'z'
:
true
,
'|'
:
true
,
'~'
:
true
,
}
type
connectionStater
interface
{
ConnectionState
()
tls
.
ConnectionState
}
var
sorterPool
=
sync
.
Pool
{
New
:
func
()
interface
{}
{
return
new
(
sorter
)
}}
type
sorter
struct
{
v
[]
string
// owned by sorter
}
func
(
s
*
sorter
)
Len
()
int
{
return
len
(
s
.
v
)
}
func
(
s
*
sorter
)
Swap
(
i
,
j
int
)
{
s
.
v
[
i
],
s
.
v
[
j
]
=
s
.
v
[
j
],
s
.
v
[
i
]
}
func
(
s
*
sorter
)
Less
(
i
,
j
int
)
bool
{
return
s
.
v
[
i
]
<
s
.
v
[
j
]
}
// Keys returns the sorted keys of h.
//
// The returned slice is only valid until s used again or returned to
// its pool.
func
(
s
*
sorter
)
Keys
(
h
http
.
Header
)
[]
string
{
keys
:=
s
.
v
[
:
0
]
for
k
:=
range
h
{
keys
=
append
(
keys
,
k
)
}
s
.
v
=
keys
sort
.
Sort
(
s
)
return
keys
}
func
(
s
*
sorter
)
SortStrings
(
ss
[]
string
)
{
// Our sorter works on s.v, which sorter owners, so
// stash it away while we sort the user's buffer.
save
:=
s
.
v
s
.
v
=
ss
sort
.
Sort
(
s
)
s
.
v
=
save
}
vendor/golang.org/x/net/http2/not_go15.go
deleted
100644 → 0
View file @
6193335b
// Copyright 2015 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.
// +build !go1.5
package
http2
import
"net/http"
func
requestCancel
(
req
*
http
.
Request
)
<-
chan
struct
{}
{
return
nil
}
vendor/golang.org/x/net/http2/not_go16.go
View file @
e5ed62e8
...
...
@@ -6,8 +6,41 @@
package
http2
import
"net/http"
import
(
"crypto/tls"
"net/http"
"time"
)
func
configureTransport
(
t1
*
http
.
Transport
)
(
*
Transport
,
error
)
{
return
nil
,
errTransportVersion
}
func
transportExpectContinueTimeout
(
t1
*
http
.
Transport
)
time
.
Duration
{
return
0
}
// isBadCipher reports whether the cipher is blacklisted by the HTTP/2 spec.
func
isBadCipher
(
cipher
uint16
)
bool
{
switch
cipher
{
case
tls
.
TLS_RSA_WITH_RC4_128_SHA
,
tls
.
TLS_RSA_WITH_3DES_EDE_CBC_SHA
,
tls
.
TLS_RSA_WITH_AES_128_CBC_SHA
,
tls
.
TLS_RSA_WITH_AES_256_CBC_SHA
,
tls
.
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
,
tls
.
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
,
tls
.
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
,
tls
.
TLS_ECDHE_RSA_WITH_RC4_128_SHA
,
tls
.
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
,
tls
.
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
,
tls
.
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
:
// Reject cipher suites from Appendix A.
// "This list includes those cipher suites that do not
// offer an ephemeral key exchange and those that are
// based on the TLS null, stream or block cipher type"
return
true
default
:
return
false
}
}
vendor/golang.org/x/net/http2/not_go17.go
0 → 100644
View file @
e5ed62e8
// Copyright 2016 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.
// +build !go1.7
package
http2
import
(
"net"
"net/http"
)
type
contextContext
interface
{}
type
fakeContext
struct
{}
func
(
fakeContext
)
Done
()
<-
chan
struct
{}
{
return
nil
}
func
(
fakeContext
)
Err
()
error
{
panic
(
"should not be called"
)
}
func
reqContext
(
r
*
http
.
Request
)
fakeContext
{
return
fakeContext
{}
}
func
setResponseUncompressed
(
res
*
http
.
Response
)
{
// Nothing.
}
type
clientTrace
struct
{}
func
requestTrace
(
*
http
.
Request
)
*
clientTrace
{
return
nil
}
func
traceGotConn
(
*
http
.
Request
,
*
ClientConn
)
{}
func
traceFirstResponseByte
(
*
clientTrace
)
{}
func
traceWroteHeaders
(
*
clientTrace
)
{}
func
traceWroteRequest
(
*
clientTrace
,
error
)
{}
func
traceGot100Continue
(
trace
*
clientTrace
)
{}
func
traceWait100Continue
(
trace
*
clientTrace
)
{}
func
nop
()
{}
func
serverConnBaseContext
(
c
net
.
Conn
,
opts
*
ServeConnOpts
)
(
ctx
contextContext
,
cancel
func
())
{
return
nil
,
nop
}
func
contextWithCancel
(
ctx
contextContext
)
(
_
contextContext
,
cancel
func
())
{
return
ctx
,
nop
}
func
requestWithContext
(
req
*
http
.
Request
,
ctx
contextContext
)
*
http
.
Request
{
return
req
}
vendor/golang.org/x/net/http2/pipe.go
View file @
e5ed62e8
...
...
@@ -29,6 +29,12 @@ type pipeBuffer interface {
io
.
Reader
}
func
(
p
*
pipe
)
Len
()
int
{
p
.
mu
.
Lock
()
defer
p
.
mu
.
Unlock
()
return
p
.
b
.
Len
()
}
// Read waits until data is available and copies bytes
// from the buffer into p.
func
(
p
*
pipe
)
Read
(
d
[]
byte
)
(
n
int
,
err
error
)
{
...
...
vendor/golang.org/x/net/http2/server.go
View file @
e5ed62e8
This diff is collapsed.
Click to expand it.
vendor/golang.org/x/net/http2/transport.go
View file @
e5ed62e8
This diff is collapsed.
Click to expand it.
vendor/golang.org/x/net/http2/write.go
View file @
e5ed62e8
...
...
@@ -9,10 +9,10 @@ import (
"fmt"
"log"
"net/http"
"sort"
"time"
"golang.org/x/net/http2/hpack"
"golang.org/x/net/lex/httplex"
)
// writeFramer is implemented by any type that is used to write frames.
...
...
@@ -230,25 +230,26 @@ func (wu writeWindowUpdate) writeFrame(ctx writeContext) error {
}
func
encodeHeaders
(
enc
*
hpack
.
Encoder
,
h
http
.
Header
,
keys
[]
string
)
{
// TODO: garbage. pool sorters like http1? hot path for 1 key?
if
keys
==
nil
{
keys
=
make
([]
string
,
0
,
len
(
h
))
for
k
:=
range
h
{
keys
=
append
(
keys
,
k
)
}
sort
.
Strings
(
keys
)
sorter
:=
sorterPool
.
Get
()
.
(
*
sorter
)
// Using defer here, since the returned keys from the
// sorter.Keys method is only valid until the sorter
// is returned:
defer
sorterPool
.
Put
(
sorter
)
keys
=
sorter
.
Keys
(
h
)
}
for
_
,
k
:=
range
keys
{
vv
:=
h
[
k
]
k
=
lowerHeader
(
k
)
if
!
validHeaderFieldName
(
k
)
{
// TODO: return an error? golang.org/issue/14048
// For now just omit it.
if
!
validWireHeaderFieldName
(
k
)
{
// Skip it as backup paranoia. Per
// golang.org/issue/14048, these should
// already be rejected at a higher level.
continue
}
isTE
:=
k
==
"transfer-encoding"
for
_
,
v
:=
range
vv
{
if
!
v
alidHeaderFieldValue
(
v
)
{
if
!
httplex
.
V
alidHeaderFieldValue
(
v
)
{
// TODO: return an error? golang.org/issue/14048
// For now just omit it.
continue
...
...
vendor/golang.org/x/net/lex/httplex/httplex.go
0 → 100644
View file @
e5ed62e8
// Copyright 2016 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 httplex contains rules around lexical matters of various
// HTTP-related specifications.
//
// This package is shared by the standard library (which vendors it)
// and x/net/http2. It comes with no API stability promise.
package
httplex
import
(
"strings"
"unicode/utf8"
)
var
isTokenTable
=
[
127
]
bool
{
'!'
:
true
,
'#'
:
true
,
'$'
:
true
,
'%'
:
true
,
'&'
:
true
,
'\'
'
:
true
,
'*'
:
true
,
'+'
:
true
,
'-'
:
true
,
'.'
:
true
,
'0'
:
true
,
'1'
:
true
,
'2'
:
true
,
'3'
:
true
,
'4'
:
true
,
'5'
:
true
,
'6'
:
true
,
'7'
:
true
,
'8'
:
true
,
'9'
:
true
,
'A'
:
true
,
'B'
:
true
,
'C'
:
true
,
'D'
:
true
,
'E'
:
true
,
'F'
:
true
,
'G'
:
true
,
'H'
:
true
,
'I'
:
true
,
'J'
:
true
,
'K'
:
true
,
'L'
:
true
,
'M'
:
true
,
'N'
:
true
,
'O'
:
true
,
'P'
:
true
,
'Q'
:
true
,
'R'
:
true
,
'S'
:
true
,
'T'
:
true
,
'U'
:
true
,
'W'
:
true
,
'V'
:
true
,
'X'
:
true
,
'Y'
:
true
,
'Z'
:
true
,
'^'
:
true
,
'_'
:
true
,
'`'
:
true
,
'a'
:
true
,
'b'
:
true
,
'c'
:
true
,
'd'
:
true
,
'e'
:
true
,
'f'
:
true
,
'g'
:
true
,
'h'
:
true
,
'i'
:
true
,
'j'
:
true
,
'k'
:
true
,
'l'
:
true
,
'm'
:
true
,
'n'
:
true
,
'o'
:
true
,
'p'
:
true
,
'q'
:
true
,
'r'
:
true
,
's'
:
true
,
't'
:
true
,
'u'
:
true
,
'v'
:
true
,
'w'
:
true
,
'x'
:
true
,
'y'
:
true
,
'z'
:
true
,
'|'
:
true
,
'~'
:
true
,
}
func
IsTokenRune
(
r
rune
)
bool
{
i
:=
int
(
r
)
return
i
<
len
(
isTokenTable
)
&&
isTokenTable
[
i
]
}
func
isNotToken
(
r
rune
)
bool
{
return
!
IsTokenRune
(
r
)
}
// HeaderValuesContainsToken reports whether any string in values
// contains the provided token, ASCII case-insensitively.
func
HeaderValuesContainsToken
(
values
[]
string
,
token
string
)
bool
{
for
_
,
v
:=
range
values
{
if
headerValueContainsToken
(
v
,
token
)
{
return
true
}
}
return
false
}
// isOWS reports whether b is an optional whitespace byte, as defined
// by RFC 7230 section 3.2.3.
func
isOWS
(
b
byte
)
bool
{
return
b
==
' '
||
b
==
'\t'
}
// trimOWS returns x with all optional whitespace removes from the
// beginning and end.
func
trimOWS
(
x
string
)
string
{
// TODO: consider using strings.Trim(x, " \t") instead,
// if and when it's fast enough. See issue 10292.
// But this ASCII-only code will probably always beat UTF-8
// aware code.
for
len
(
x
)
>
0
&&
isOWS
(
x
[
0
])
{
x
=
x
[
1
:
]
}
for
len
(
x
)
>
0
&&
isOWS
(
x
[
len
(
x
)
-
1
])
{
x
=
x
[
:
len
(
x
)
-
1
]
}
return
x
}
// headerValueContainsToken reports whether v (assumed to be a
// 0#element, in the ABNF extension described in RFC 7230 section 7)
// contains token amongst its comma-separated tokens, ASCII
// case-insensitively.
func
headerValueContainsToken
(
v
string
,
token
string
)
bool
{
v
=
trimOWS
(
v
)
if
comma
:=
strings
.
IndexByte
(
v
,
','
);
comma
!=
-
1
{
return
tokenEqual
(
trimOWS
(
v
[
:
comma
]),
token
)
||
headerValueContainsToken
(
v
[
comma
+
1
:
],
token
)
}
return
tokenEqual
(
v
,
token
)
}
// lowerASCII returns the ASCII lowercase version of b.
func
lowerASCII
(
b
byte
)
byte
{
if
'A'
<=
b
&&
b
<=
'Z'
{
return
b
+
(
'a'
-
'A'
)
}
return
b
}
// tokenEqual reports whether t1 and t2 are equal, ASCII case-insensitively.
func
tokenEqual
(
t1
,
t2
string
)
bool
{
if
len
(
t1
)
!=
len
(
t2
)
{
return
false
}
for
i
,
b
:=
range
t1
{
if
b
>=
utf8
.
RuneSelf
{
// No UTF-8 or non-ASCII allowed in tokens.
return
false
}
if
lowerASCII
(
byte
(
b
))
!=
lowerASCII
(
t2
[
i
])
{
return
false
}
}
return
true
}
// isLWS reports whether b is linear white space, according
// to http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2
// LWS = [CRLF] 1*( SP | HT )
func
isLWS
(
b
byte
)
bool
{
return
b
==
' '
||
b
==
'\t'
}
// isCTL reports whether b is a control byte, according
// to http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2
// CTL = <any US-ASCII control character
// (octets 0 - 31) and DEL (127)>
func
isCTL
(
b
byte
)
bool
{
const
del
=
0x7f
// a CTL
return
b
<
' '
||
b
==
del
}
// ValidHeaderFieldName reports whether v is a valid HTTP/1.x header name.
// HTTP/2 imposes the additional restriction that uppercase ASCII
// letters are not allowed.
//
// RFC 7230 says:
// header-field = field-name ":" OWS field-value OWS
// field-name = token
// token = 1*tchar
// tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
// "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
func
ValidHeaderFieldName
(
v
string
)
bool
{
if
len
(
v
)
==
0
{
return
false
}
for
_
,
r
:=
range
v
{
if
!
IsTokenRune
(
r
)
{
return
false
}
}
return
true
}
// ValidHostHeader reports whether h is a valid host header.
func
ValidHostHeader
(
h
string
)
bool
{
// The latest spec is actually this:
//
// http://tools.ietf.org/html/rfc7230#section-5.4
// Host = uri-host [ ":" port ]
//
// Where uri-host is:
// http://tools.ietf.org/html/rfc3986#section-3.2.2
//
// But we're going to be much more lenient for now and just
// search for any byte that's not a valid byte in any of those
// expressions.
for
i
:=
0
;
i
<
len
(
h
);
i
++
{
if
!
validHostByte
[
h
[
i
]]
{
return
false
}
}
return
true
}
// See the validHostHeader comment.
var
validHostByte
=
[
256
]
bool
{
'0'
:
true
,
'1'
:
true
,
'2'
:
true
,
'3'
:
true
,
'4'
:
true
,
'5'
:
true
,
'6'
:
true
,
'7'
:
true
,
'8'
:
true
,
'9'
:
true
,
'a'
:
true
,
'b'
:
true
,
'c'
:
true
,
'd'
:
true
,
'e'
:
true
,
'f'
:
true
,
'g'
:
true
,
'h'
:
true
,
'i'
:
true
,
'j'
:
true
,
'k'
:
true
,
'l'
:
true
,
'm'
:
true
,
'n'
:
true
,
'o'
:
true
,
'p'
:
true
,
'q'
:
true
,
'r'
:
true
,
's'
:
true
,
't'
:
true
,
'u'
:
true
,
'v'
:
true
,
'w'
:
true
,
'x'
:
true
,
'y'
:
true
,
'z'
:
true
,
'A'
:
true
,
'B'
:
true
,
'C'
:
true
,
'D'
:
true
,
'E'
:
true
,
'F'
:
true
,
'G'
:
true
,
'H'
:
true
,
'I'
:
true
,
'J'
:
true
,
'K'
:
true
,
'L'
:
true
,
'M'
:
true
,
'N'
:
true
,
'O'
:
true
,
'P'
:
true
,
'Q'
:
true
,
'R'
:
true
,
'S'
:
true
,
'T'
:
true
,
'U'
:
true
,
'V'
:
true
,
'W'
:
true
,
'X'
:
true
,
'Y'
:
true
,
'Z'
:
true
,
'!'
:
true
,
// sub-delims
'$'
:
true
,
// sub-delims
'%'
:
true
,
// pct-encoded (and used in IPv6 zones)
'&'
:
true
,
// sub-delims
'('
:
true
,
// sub-delims
')'
:
true
,
// sub-delims
'*'
:
true
,
// sub-delims
'+'
:
true
,
// sub-delims
','
:
true
,
// sub-delims
'-'
:
true
,
// unreserved
'.'
:
true
,
// unreserved
':'
:
true
,
// IPv6address + Host expression's optional port
';'
:
true
,
// sub-delims
'='
:
true
,
// sub-delims
'['
:
true
,
'\'
'
:
true
,
// sub-delims
']'
:
true
,
'_'
:
true
,
// unreserved
'~'
:
true
,
// unreserved
}
// ValidHeaderFieldValue reports whether v is a valid "field-value" according to
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 :
//
// message-header = field-name ":" [ field-value ]
// field-value = *( field-content | LWS )
// field-content = <the OCTETs making up the field-value
// and consisting of either *TEXT or combinations
// of token, separators, and quoted-string>
//
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2 :
//
// TEXT = <any OCTET except CTLs,
// but including LWS>
// LWS = [CRLF] 1*( SP | HT )
// CTL = <any US-ASCII control character
// (octets 0 - 31) and DEL (127)>
//
// RFC 7230 says:
// field-value = *( field-content / obs-fold )
// obj-fold = N/A to http2, and deprecated
// field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
// field-vchar = VCHAR / obs-text
// obs-text = %x80-FF
// VCHAR = "any visible [USASCII] character"
//
// http2 further says: "Similarly, HTTP/2 allows header field values
// that are not valid. While most of the values that can be encoded
// will not alter header field parsing, carriage return (CR, ASCII
// 0xd), line feed (LF, ASCII 0xa), and the zero character (NUL, ASCII
// 0x0) might be exploited by an attacker if they are translated
// verbatim. Any request or response that contains a character not
// permitted in a header field value MUST be treated as malformed
// (Section 8.1.2.6). Valid characters are defined by the
// field-content ABNF rule in Section 3.2 of [RFC7230]."
//
// This function does not (yet?) properly handle the rejection of
// strings that begin or end with SP or HTAB.
func
ValidHeaderFieldValue
(
v
string
)
bool
{
for
i
:=
0
;
i
<
len
(
v
);
i
++
{
b
:=
v
[
i
]
if
isCTL
(
b
)
&&
!
isLWS
(
b
)
{
return
false
}
}
return
true
}
vendor/golang.org/x/net/trace/trace.go
View file @
e5ed62e8
...
...
@@ -93,13 +93,17 @@ var DebugUseAfterFinish = false
//
// AuthRequest may be replaced by a program to customise its authorisation requirements.
//
// The default AuthRequest function returns (true, true) iff the request comes from localhost/127.0.0.1/[::1].
// The default AuthRequest function returns (true, true) if and only if the request
// comes from localhost/127.0.0.1/[::1].
var
AuthRequest
=
func
(
req
*
http
.
Request
)
(
any
,
sensitive
bool
)
{
// RemoteAddr is commonly in the form "IP" or "IP:port".
// If it is in the form "IP:port", split off the port.
host
,
_
,
err
:=
net
.
SplitHostPort
(
req
.
RemoteAddr
)
switch
{
case
err
!=
nil
:
// Badly formed address; fail closed.
return
false
,
false
case
host
==
"localhost"
||
host
==
"127.0.0.1"
||
host
==
"::1"
:
if
err
!=
nil
{
host
=
req
.
RemoteAddr
}
switch
host
{
case
"localhost"
,
"127.0.0.1"
,
"::1"
:
return
true
,
true
default
:
return
false
,
false
...
...
vendor/golang.org/x/net/websocket/hybi.go
View file @
e5ed62e8
...
...
@@ -81,9 +81,6 @@ type hybiFrameReader struct {
func
(
frame
*
hybiFrameReader
)
Read
(
msg
[]
byte
)
(
n
int
,
err
error
)
{
n
,
err
=
frame
.
reader
.
Read
(
msg
)
if
err
!=
nil
{
return
0
,
err
}
if
frame
.
header
.
MaskingKey
!=
nil
{
for
i
:=
0
;
i
<
n
;
i
++
{
msg
[
i
]
=
msg
[
i
]
^
frame
.
header
.
MaskingKey
[
frame
.
pos
%
4
]
...
...
vendor/golang.org/x/net/websocket/websocket.go
View file @
e5ed62e8
...
...
@@ -144,6 +144,8 @@ type frameHandler interface {
}
// Conn represents a WebSocket connection.
//
// Multiple goroutines may invoke methods on a Conn simultaneously.
type
Conn
struct
{
config
*
Config
request
*
http
.
Request
...
...
@@ -207,9 +209,6 @@ func (ws *Conn) Write(msg []byte) (n int, err error) {
}
n
,
err
=
w
.
Write
(
msg
)
w
.
Close
()
if
err
!=
nil
{
return
n
,
err
}
return
n
,
err
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment