1
0
mirror of https://github.com/golang/go synced 2024-11-22 04:44:39 -07:00

http: fix, use WriteProxy

Fixes #53.

R=bradfitzgo, bradfitzwork
CC=golang-dev
https://golang.org/cl/4240075
This commit is contained in:
Russ Cox 2011-03-05 14:35:15 -05:00
parent d044674a0d
commit 7bc90eda69
3 changed files with 66 additions and 11 deletions

View File

@ -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,14 +208,13 @@ 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 usingProxy {
if uri == "" || uri[0] != '/' { if uri == "" || uri[0] != '/' {
uri = "/" + uri 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)

View File

@ -11,7 +11,9 @@ import (
type reqWriteTest struct { type reqWriteTest struct {
Req Request Req Request
Body []byte
Raw string 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
}
} }
} }

View File

@ -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