mirror of
https://github.com/golang/go
synced 2024-11-25 02:57:57 -07:00
net/http: parse CONNECT requests
Fixes #2755 R=dsymonds, rsc CC=golang-dev https://golang.org/cl/5571052
This commit is contained in:
parent
03ea8b1c81
commit
c3b9650caa
@ -171,6 +171,75 @@ var reqTests = []reqTest{
|
|||||||
},
|
},
|
||||||
noError,
|
noError,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// CONNECT request with domain name:
|
||||||
|
{
|
||||||
|
"CONNECT www.google.com:443 HTTP/1.1\r\n\r\n",
|
||||||
|
|
||||||
|
&Request{
|
||||||
|
Method: "CONNECT",
|
||||||
|
URL: &url.URL{
|
||||||
|
Host: "www.google.com:443",
|
||||||
|
},
|
||||||
|
Proto: "HTTP/1.1",
|
||||||
|
ProtoMajor: 1,
|
||||||
|
ProtoMinor: 1,
|
||||||
|
Header: Header{},
|
||||||
|
Close: false,
|
||||||
|
ContentLength: 0,
|
||||||
|
Host: "www.google.com:443",
|
||||||
|
},
|
||||||
|
|
||||||
|
noBody,
|
||||||
|
noTrailer,
|
||||||
|
noError,
|
||||||
|
},
|
||||||
|
|
||||||
|
// CONNECT request with IP address:
|
||||||
|
{
|
||||||
|
"CONNECT 127.0.0.1:6060 HTTP/1.1\r\n\r\n",
|
||||||
|
|
||||||
|
&Request{
|
||||||
|
Method: "CONNECT",
|
||||||
|
URL: &url.URL{
|
||||||
|
Host: "127.0.0.1:6060",
|
||||||
|
},
|
||||||
|
Proto: "HTTP/1.1",
|
||||||
|
ProtoMajor: 1,
|
||||||
|
ProtoMinor: 1,
|
||||||
|
Header: Header{},
|
||||||
|
Close: false,
|
||||||
|
ContentLength: 0,
|
||||||
|
Host: "127.0.0.1:6060",
|
||||||
|
},
|
||||||
|
|
||||||
|
noBody,
|
||||||
|
noTrailer,
|
||||||
|
noError,
|
||||||
|
},
|
||||||
|
|
||||||
|
// CONNECT request for RPC:
|
||||||
|
{
|
||||||
|
"CONNECT /_goRPC_ HTTP/1.1\r\n\r\n",
|
||||||
|
|
||||||
|
&Request{
|
||||||
|
Method: "CONNECT",
|
||||||
|
URL: &url.URL{
|
||||||
|
Path: "/_goRPC_",
|
||||||
|
},
|
||||||
|
Proto: "HTTP/1.1",
|
||||||
|
ProtoMajor: 1,
|
||||||
|
ProtoMinor: 1,
|
||||||
|
Header: Header{},
|
||||||
|
Close: false,
|
||||||
|
ContentLength: 0,
|
||||||
|
Host: "",
|
||||||
|
},
|
||||||
|
|
||||||
|
noBody,
|
||||||
|
noTrailer,
|
||||||
|
noError,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReadRequest(t *testing.T) {
|
func TestReadRequest(t *testing.T) {
|
||||||
|
@ -305,6 +305,9 @@ func (req *Request) write(w io.Writer, usingProxy bool, extraHeaders Header) err
|
|||||||
ruri := req.URL.RequestURI()
|
ruri := req.URL.RequestURI()
|
||||||
if usingProxy && req.URL.Scheme != "" && req.URL.Opaque == "" {
|
if usingProxy && req.URL.Scheme != "" && req.URL.Opaque == "" {
|
||||||
ruri = req.URL.Scheme + "://" + host + ruri
|
ruri = req.URL.Scheme + "://" + host + ruri
|
||||||
|
} else if req.Method == "CONNECT" && req.URL.Path == "" {
|
||||||
|
// CONNECT requests normally give just the host and port, not a full URL.
|
||||||
|
ruri = host
|
||||||
}
|
}
|
||||||
// TODO(bradfitz): escape at least newlines in ruri?
|
// TODO(bradfitz): escape at least newlines in ruri?
|
||||||
|
|
||||||
@ -463,10 +466,29 @@ func ReadRequest(b *bufio.Reader) (req *Request, err error) {
|
|||||||
return nil, &badStringError{"malformed HTTP version", req.Proto}
|
return nil, &badStringError{"malformed HTTP version", req.Proto}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CONNECT requests are used two different ways, and neither uses a full URL:
|
||||||
|
// The standard use is to tunnel HTTPS through an HTTP proxy.
|
||||||
|
// It looks like "CONNECT www.google.com:443 HTTP/1.1", and the parameter is
|
||||||
|
// just the authority section of a URL. This information should go in req.URL.Host.
|
||||||
|
//
|
||||||
|
// The net/rpc package also uses CONNECT, but there the parameter is a path
|
||||||
|
// that starts with a slash. It can be parsed with the regular URL parser,
|
||||||
|
// and the path will end up in req.URL.Path, where it needs to be in order for
|
||||||
|
// RPC to work.
|
||||||
|
justAuthority := req.Method == "CONNECT" && !strings.HasPrefix(rawurl, "/")
|
||||||
|
if justAuthority {
|
||||||
|
rawurl = "http://" + rawurl
|
||||||
|
}
|
||||||
|
|
||||||
if req.URL, err = url.ParseRequest(rawurl); err != nil {
|
if req.URL, err = url.ParseRequest(rawurl); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if justAuthority {
|
||||||
|
// Strip the bogus "http://" back off.
|
||||||
|
req.URL.Scheme = ""
|
||||||
|
}
|
||||||
|
|
||||||
// Subsequent lines: Key: value.
|
// Subsequent lines: Key: value.
|
||||||
mimeHeader, err := tp.ReadMIMEHeader()
|
mimeHeader, err := tp.ReadMIMEHeader()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user