mirror of
https://github.com/golang/go
synced 2024-11-21 22:34:48 -07:00
http: fix, use WriteProxy
Fixes #53. R=bradfitzgo, bradfitzwork CC=golang-dev https://golang.org/cl/4240075
This commit is contained in:
parent
d044674a0d
commit
7bc90eda69
@ -190,6 +190,8 @@ func (req *Request) Write(w io.Writer) os.Error {
|
|||||||
// WriteProxy is like Write but writes the request in the form
|
// WriteProxy is like Write but writes the request in the form
|
||||||
// expected by an HTTP proxy. It includes the scheme and host
|
// expected by an HTTP proxy. It includes the scheme and host
|
||||||
// name in the URI instead of using a separate Host: header line.
|
// name in the URI instead of using a separate Host: header line.
|
||||||
|
// If req.RawURL is non-empty, WriteProxy uses it unchanged
|
||||||
|
// instead of URL but still omits the Host: header.
|
||||||
func (req *Request) WriteProxy(w io.Writer) os.Error {
|
func (req *Request) WriteProxy(w io.Writer) os.Error {
|
||||||
return req.write(w, true)
|
return req.write(w, true)
|
||||||
}
|
}
|
||||||
@ -206,13 +208,12 @@ func (req *Request) write(w io.Writer, usingProxy bool) os.Error {
|
|||||||
if req.URL.RawQuery != "" {
|
if req.URL.RawQuery != "" {
|
||||||
uri += "?" + req.URL.RawQuery
|
uri += "?" + req.URL.RawQuery
|
||||||
}
|
}
|
||||||
}
|
if usingProxy {
|
||||||
|
if uri == "" || uri[0] != '/' {
|
||||||
if usingProxy {
|
uri = "/" + uri
|
||||||
if uri == "" || uri[0] != '/' {
|
}
|
||||||
uri = "/" + uri
|
uri = req.URL.Scheme + "://" + host + uri
|
||||||
}
|
}
|
||||||
uri = req.URL.Scheme + "://" + host + uri
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintf(w, "%s %s HTTP/1.1\r\n", valueOrDefault(req.Method, "GET"), uri)
|
fmt.Fprintf(w, "%s %s HTTP/1.1\r\n", valueOrDefault(req.Method, "GET"), uri)
|
||||||
|
@ -10,8 +10,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type reqWriteTest struct {
|
type reqWriteTest struct {
|
||||||
Req Request
|
Req Request
|
||||||
Raw string
|
Body []byte
|
||||||
|
Raw string
|
||||||
|
RawProxy string
|
||||||
}
|
}
|
||||||
|
|
||||||
var reqWriteTests = []reqWriteTest{
|
var reqWriteTests = []reqWriteTest{
|
||||||
@ -50,6 +52,8 @@ var reqWriteTests = []reqWriteTest{
|
|||||||
Form: map[string][]string{},
|
Form: map[string][]string{},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
nil,
|
||||||
|
|
||||||
"GET http://www.techcrunch.com/ HTTP/1.1\r\n" +
|
"GET http://www.techcrunch.com/ HTTP/1.1\r\n" +
|
||||||
"Host: www.techcrunch.com\r\n" +
|
"Host: www.techcrunch.com\r\n" +
|
||||||
"User-Agent: Fake\r\n" +
|
"User-Agent: Fake\r\n" +
|
||||||
@ -59,6 +63,15 @@ var reqWriteTests = []reqWriteTest{
|
|||||||
"Accept-Language: en-us,en;q=0.5\r\n" +
|
"Accept-Language: en-us,en;q=0.5\r\n" +
|
||||||
"Keep-Alive: 300\r\n" +
|
"Keep-Alive: 300\r\n" +
|
||||||
"Proxy-Connection: keep-alive\r\n\r\n",
|
"Proxy-Connection: keep-alive\r\n\r\n",
|
||||||
|
|
||||||
|
"GET http://www.techcrunch.com/ HTTP/1.1\r\n" +
|
||||||
|
"User-Agent: Fake\r\n" +
|
||||||
|
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" +
|
||||||
|
"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" +
|
||||||
|
"Accept-Encoding: gzip,deflate\r\n" +
|
||||||
|
"Accept-Language: en-us,en;q=0.5\r\n" +
|
||||||
|
"Keep-Alive: 300\r\n" +
|
||||||
|
"Proxy-Connection: keep-alive\r\n\r\n",
|
||||||
},
|
},
|
||||||
// HTTP/1.1 => chunked coding; body; empty trailer
|
// HTTP/1.1 => chunked coding; body; empty trailer
|
||||||
{
|
{
|
||||||
@ -72,15 +85,21 @@ var reqWriteTests = []reqWriteTest{
|
|||||||
ProtoMajor: 1,
|
ProtoMajor: 1,
|
||||||
ProtoMinor: 1,
|
ProtoMinor: 1,
|
||||||
Header: map[string][]string{},
|
Header: map[string][]string{},
|
||||||
Body: nopCloser{bytes.NewBufferString("abcdef")},
|
|
||||||
TransferEncoding: []string{"chunked"},
|
TransferEncoding: []string{"chunked"},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
[]byte("abcdef"),
|
||||||
|
|
||||||
"GET /search HTTP/1.1\r\n" +
|
"GET /search HTTP/1.1\r\n" +
|
||||||
"Host: www.google.com\r\n" +
|
"Host: www.google.com\r\n" +
|
||||||
"User-Agent: Go http package\r\n" +
|
"User-Agent: Go http package\r\n" +
|
||||||
"Transfer-Encoding: chunked\r\n\r\n" +
|
"Transfer-Encoding: chunked\r\n\r\n" +
|
||||||
"6\r\nabcdef\r\n0\r\n\r\n",
|
"6\r\nabcdef\r\n0\r\n\r\n",
|
||||||
|
|
||||||
|
"GET http://www.google.com/search HTTP/1.1\r\n" +
|
||||||
|
"User-Agent: Go http package\r\n" +
|
||||||
|
"Transfer-Encoding: chunked\r\n\r\n" +
|
||||||
|
"6\r\nabcdef\r\n0\r\n\r\n",
|
||||||
},
|
},
|
||||||
// HTTP/1.1 POST => chunked coding; body; empty trailer
|
// HTTP/1.1 POST => chunked coding; body; empty trailer
|
||||||
{
|
{
|
||||||
@ -95,16 +114,23 @@ var reqWriteTests = []reqWriteTest{
|
|||||||
ProtoMinor: 1,
|
ProtoMinor: 1,
|
||||||
Header: map[string][]string{},
|
Header: map[string][]string{},
|
||||||
Close: true,
|
Close: true,
|
||||||
Body: nopCloser{bytes.NewBufferString("abcdef")},
|
|
||||||
TransferEncoding: []string{"chunked"},
|
TransferEncoding: []string{"chunked"},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
[]byte("abcdef"),
|
||||||
|
|
||||||
"POST /search HTTP/1.1\r\n" +
|
"POST /search HTTP/1.1\r\n" +
|
||||||
"Host: www.google.com\r\n" +
|
"Host: www.google.com\r\n" +
|
||||||
"User-Agent: Go http package\r\n" +
|
"User-Agent: Go http package\r\n" +
|
||||||
"Connection: close\r\n" +
|
"Connection: close\r\n" +
|
||||||
"Transfer-Encoding: chunked\r\n\r\n" +
|
"Transfer-Encoding: chunked\r\n\r\n" +
|
||||||
"6\r\nabcdef\r\n0\r\n\r\n",
|
"6\r\nabcdef\r\n0\r\n\r\n",
|
||||||
|
|
||||||
|
"POST http://www.google.com/search HTTP/1.1\r\n" +
|
||||||
|
"User-Agent: Go http package\r\n" +
|
||||||
|
"Connection: close\r\n" +
|
||||||
|
"Transfer-Encoding: chunked\r\n\r\n" +
|
||||||
|
"6\r\nabcdef\r\n0\r\n\r\n",
|
||||||
},
|
},
|
||||||
// default to HTTP/1.1
|
// default to HTTP/1.1
|
||||||
{
|
{
|
||||||
@ -114,16 +140,26 @@ var reqWriteTests = []reqWriteTest{
|
|||||||
Host: "www.google.com",
|
Host: "www.google.com",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
nil,
|
||||||
|
|
||||||
"GET /search HTTP/1.1\r\n" +
|
"GET /search HTTP/1.1\r\n" +
|
||||||
"Host: www.google.com\r\n" +
|
"Host: www.google.com\r\n" +
|
||||||
"User-Agent: Go http package\r\n" +
|
"User-Agent: Go http package\r\n" +
|
||||||
"\r\n",
|
"\r\n",
|
||||||
|
|
||||||
|
// Looks weird but RawURL overrides what WriteProxy would choose.
|
||||||
|
"GET /search HTTP/1.1\r\n" +
|
||||||
|
"User-Agent: Go http package\r\n" +
|
||||||
|
"\r\n",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRequestWrite(t *testing.T) {
|
func TestRequestWrite(t *testing.T) {
|
||||||
for i := range reqWriteTests {
|
for i := range reqWriteTests {
|
||||||
tt := &reqWriteTests[i]
|
tt := &reqWriteTests[i]
|
||||||
|
if tt.Body != nil {
|
||||||
|
tt.Req.Body = nopCloser{bytes.NewBuffer(tt.Body)}
|
||||||
|
}
|
||||||
var braw bytes.Buffer
|
var braw bytes.Buffer
|
||||||
err := tt.Req.Write(&braw)
|
err := tt.Req.Write(&braw)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -135,5 +171,20 @@ func TestRequestWrite(t *testing.T) {
|
|||||||
t.Errorf("Test %d, expecting:\n%s\nGot:\n%s\n", i, tt.Raw, sraw)
|
t.Errorf("Test %d, expecting:\n%s\nGot:\n%s\n", i, tt.Raw, sraw)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if tt.Body != nil {
|
||||||
|
tt.Req.Body = nopCloser{bytes.NewBuffer(tt.Body)}
|
||||||
|
}
|
||||||
|
var praw bytes.Buffer
|
||||||
|
err = tt.Req.WriteProxy(&praw)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error writing #%d: %s", i, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
sraw = praw.String()
|
||||||
|
if sraw != tt.RawProxy {
|
||||||
|
t.Errorf("Test Proxy %d, expecting:\n%s\nGot:\n%s\n", i, tt.RawProxy, sraw)
|
||||||
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,10 @@ func (ct *transport) Do(req *Request) (resp *Response, err os.Error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var write = (*Request).Write
|
||||||
|
|
||||||
if proxy != "" {
|
if proxy != "" {
|
||||||
|
write = (*Request).WriteProxy
|
||||||
proxyURL, err = ParseRequestURL(proxy)
|
proxyURL, err = ParseRequestURL(proxy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, os.ErrorString("invalid proxy address")
|
return nil, os.ErrorString("invalid proxy address")
|
||||||
@ -130,7 +133,7 @@ func (ct *transport) Do(req *Request) (resp *Response, err os.Error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = req.Write(conn)
|
err = write(req, conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
|
Loading…
Reference in New Issue
Block a user