Commit 36036781 authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

http: remove Request.RawURL

Its purpose is not only undocumented, it's also unknown (to me
and Russ, at least) and leads to complexity, bugs and
confusion.

R=golang-dev, adg, rsc
CC=golang-dev
https://golang.org/cl/5213043
parent fefadcf5
...@@ -93,20 +93,20 @@ func RequestFromMap(params map[string]string) (*http.Request, os.Error) { ...@@ -93,20 +93,20 @@ func RequestFromMap(params map[string]string) (*http.Request, os.Error) {
if r.Host != "" { if r.Host != "" {
// Hostname is provided, so we can reasonably construct a URL, // Hostname is provided, so we can reasonably construct a URL,
// even if we have to assume 'http' for the scheme. // even if we have to assume 'http' for the scheme.
r.RawURL = "http://" + r.Host + params["REQUEST_URI"] rawurl := "http://" + r.Host + params["REQUEST_URI"]
url, err := url.Parse(r.RawURL) url, err := url.Parse(rawurl)
if err != nil { if err != nil {
return nil, os.NewError("cgi: failed to parse host and REQUEST_URI into a URL: " + r.RawURL) return nil, os.NewError("cgi: failed to parse host and REQUEST_URI into a URL: " + rawurl)
} }
r.URL = url r.URL = url
} }
// Fallback logic if we don't have a Host header or the URL // Fallback logic if we don't have a Host header or the URL
// failed to parse // failed to parse
if r.URL == nil { if r.URL == nil {
r.RawURL = params["REQUEST_URI"] uriStr := params["REQUEST_URI"]
url, err := url.Parse(r.RawURL) url, err := url.Parse(uriStr)
if err != nil { if err != nil {
return nil, os.NewError("cgi: failed to parse REQUEST_URI into a URL: " + r.RawURL) return nil, os.NewError("cgi: failed to parse REQUEST_URI into a URL: " + uriStr)
} }
r.URL = url r.URL = url
} }
......
...@@ -49,9 +49,6 @@ func TestRequest(t *testing.T) { ...@@ -49,9 +49,6 @@ func TestRequest(t *testing.T) {
if g, e := req.Header.Get("Foo-Bar"), "baz"; e != g { if g, e := req.Header.Get("Foo-Bar"), "baz"; e != g {
t.Errorf("expected Foo-Bar %q; got %q", e, g) t.Errorf("expected Foo-Bar %q; got %q", e, g)
} }
if g, e := req.RawURL, "http://example.com/path?a=b"; e != g {
t.Errorf("expected RawURL %q; got %q", e, g)
}
if g, e := req.URL.String(), "http://example.com/path?a=b"; e != g { if g, e := req.URL.String(), "http://example.com/path?a=b"; e != g {
t.Errorf("expected URL %q; got %q", e, g) t.Errorf("expected URL %q; got %q", e, g)
} }
...@@ -81,9 +78,6 @@ func TestRequestWithoutHost(t *testing.T) { ...@@ -81,9 +78,6 @@ func TestRequestWithoutHost(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("RequestFromMap: %v", err) t.Fatalf("RequestFromMap: %v", err)
} }
if g, e := req.RawURL, "/path?a=b"; e != g {
t.Errorf("expected RawURL %q; got %q", e, g)
}
if req.URL == nil { if req.URL == nil {
t.Fatalf("unexpected nil URL") t.Fatalf("unexpected nil URL")
} }
......
...@@ -322,7 +322,6 @@ func (h *Handler) handleInternalRedirect(rw http.ResponseWriter, req *http.Reque ...@@ -322,7 +322,6 @@ func (h *Handler) handleInternalRedirect(rw http.ResponseWriter, req *http.Reque
newReq := &http.Request{ newReq := &http.Request{
Method: "GET", Method: "GET",
URL: url, URL: url,
RawURL: path,
Proto: "HTTP/1.1", Proto: "HTTP/1.1",
ProtoMajor: 1, ProtoMajor: 1,
ProtoMinor: 1, ProtoMinor: 1,
......
...@@ -40,7 +40,6 @@ var reqTests = []reqTest{ ...@@ -40,7 +40,6 @@ var reqTests = []reqTest{
&Request{ &Request{
Method: "GET", Method: "GET",
RawURL: "http://www.techcrunch.com/",
URL: &url.URL{ URL: &url.URL{
Raw: "http://www.techcrunch.com/", Raw: "http://www.techcrunch.com/",
Scheme: "http", Scheme: "http",
...@@ -83,7 +82,6 @@ var reqTests = []reqTest{ ...@@ -83,7 +82,6 @@ var reqTests = []reqTest{
&Request{ &Request{
Method: "GET", Method: "GET",
RawURL: "/",
URL: &url.URL{ URL: &url.URL{
Raw: "/", Raw: "/",
Path: "/", Path: "/",
...@@ -110,7 +108,6 @@ var reqTests = []reqTest{ ...@@ -110,7 +108,6 @@ var reqTests = []reqTest{
&Request{ &Request{
Method: "GET", Method: "GET",
RawURL: "//user@host/is/actually/a/path/",
URL: &url.URL{ URL: &url.URL{
Raw: "//user@host/is/actually/a/path/", Raw: "//user@host/is/actually/a/path/",
Scheme: "", Scheme: "",
......
...@@ -80,9 +80,8 @@ var reqWriteExcludeHeaderDump = map[string]bool{ ...@@ -80,9 +80,8 @@ var reqWriteExcludeHeaderDump = map[string]bool{
// A Request represents a parsed HTTP request header. // A Request represents a parsed HTTP request header.
type Request struct { type Request struct {
Method string // GET, POST, PUT, etc. Method string // GET, POST, PUT, etc.
RawURL string // The raw URL given in the request. URL *url.URL
URL *url.URL // Parsed URL.
// The protocol version for incoming requests. // The protocol version for incoming requests.
// Outgoing requests always use HTTP/1.1. // Outgoing requests always use HTTP/1.1.
...@@ -265,7 +264,7 @@ const defaultUserAgent = "Go http package" ...@@ -265,7 +264,7 @@ const defaultUserAgent = "Go http package"
// Write writes an HTTP/1.1 request -- header and body -- in wire format. // Write writes an HTTP/1.1 request -- header and body -- in wire format.
// This method consults the following fields of req: // This method consults the following fields of req:
// Host // Host
// RawURL, if non-empty, or else URL // URL
// Method (defaults to "GET") // Method (defaults to "GET")
// Header // Header
// ContentLength // ContentLength
...@@ -282,21 +281,18 @@ func (req *Request) Write(w io.Writer) os.Error { ...@@ -282,21 +281,18 @@ 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. In particular, WriteProxy writes the // expected by an HTTP proxy. In particular, WriteProxy writes the
// initial Request-URI line of the request with an absolute URI, per // initial Request-URI line of the request with an absolute URI, per
// section 5.1.2 of RFC 2616, including the scheme and host. If // section 5.1.2 of RFC 2616, including the scheme and host. In
// req.RawURL is non-empty, WriteProxy uses it unchanged. In either // either case, WriteProxy also writes a Host header, using either
// case, WriteProxy also writes a Host header, using either req.Host // req.Host or req.URL.Host.
// or req.URL.Host.
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)
} }
func (req *Request) dumpWrite(w io.Writer) os.Error { func (req *Request) dumpWrite(w io.Writer) os.Error {
urlStr := req.RawURL // TODO(bradfitz): RawPath here?
if urlStr == "" { urlStr := valueOrDefault(req.URL.EncodedPath(), "/")
urlStr = valueOrDefault(req.URL.EncodedPath(), "/") if req.URL.RawQuery != "" {
if req.URL.RawQuery != "" { urlStr += "?" + req.URL.RawQuery
urlStr += "?" + req.URL.RawQuery
}
} }
bw := bufio.NewWriter(w) bw := bufio.NewWriter(w)
...@@ -346,9 +342,12 @@ func (req *Request) write(w io.Writer, usingProxy bool) os.Error { ...@@ -346,9 +342,12 @@ func (req *Request) write(w io.Writer, usingProxy bool) os.Error {
host = req.URL.Host host = req.URL.Host
} }
urlStr := req.RawURL urlStr := req.URL.RawPath
if strings.HasPrefix(urlStr, "?") {
urlStr = "/" + urlStr // Issue 2344
}
if urlStr == "" { if urlStr == "" {
urlStr = valueOrDefault(req.URL.EncodedPath(), "/") urlStr = valueOrDefault(req.URL.RawPath, valueOrDefault(req.URL.EncodedPath(), "/"))
if req.URL.RawQuery != "" { if req.URL.RawQuery != "" {
urlStr += "?" + req.URL.RawQuery urlStr += "?" + req.URL.RawQuery
} }
...@@ -359,6 +358,7 @@ func (req *Request) write(w io.Writer, usingProxy bool) os.Error { ...@@ -359,6 +358,7 @@ func (req *Request) write(w io.Writer, usingProxy bool) os.Error {
urlStr = req.URL.Scheme + "://" + host + urlStr urlStr = req.URL.Scheme + "://" + host + urlStr
} }
} }
// TODO(bradfitz): escape at least newlines in urlStr?
bw := bufio.NewWriter(w) bw := bufio.NewWriter(w)
fmt.Fprintf(bw, "%s %s HTTP/1.1\r\n", valueOrDefault(req.Method, "GET"), urlStr) fmt.Fprintf(bw, "%s %s HTTP/1.1\r\n", valueOrDefault(req.Method, "GET"), urlStr)
...@@ -598,13 +598,14 @@ func ReadRequest(b *bufio.Reader) (req *Request, err os.Error) { ...@@ -598,13 +598,14 @@ func ReadRequest(b *bufio.Reader) (req *Request, err os.Error) {
if f = strings.SplitN(s, " ", 3); len(f) < 3 { if f = strings.SplitN(s, " ", 3); len(f) < 3 {
return nil, &badStringError{"malformed HTTP request", s} return nil, &badStringError{"malformed HTTP request", s}
} }
req.Method, req.RawURL, req.Proto = f[0], f[1], f[2] var rawurl string
req.Method, rawurl, req.Proto = f[0], f[1], f[2]
var ok bool var ok bool
if req.ProtoMajor, req.ProtoMinor, ok = ParseHTTPVersion(req.Proto); !ok { if req.ProtoMajor, req.ProtoMinor, ok = ParseHTTPVersion(req.Proto); !ok {
return nil, &badStringError{"malformed HTTP version", req.Proto} return nil, &badStringError{"malformed HTTP version", req.Proto}
} }
if req.URL, err = url.ParseRequest(req.RawURL); err != nil { if req.URL, err = url.ParseRequest(rawurl); err != nil {
return nil, err return nil, err
} }
......
...@@ -32,7 +32,6 @@ var reqWriteTests = []reqWriteTest{ ...@@ -32,7 +32,6 @@ var reqWriteTests = []reqWriteTest{
{ {
Req: Request{ Req: Request{
Method: "GET", Method: "GET",
RawURL: "http://www.techcrunch.com/",
URL: &url.URL{ URL: &url.URL{
Raw: "http://www.techcrunch.com/", Raw: "http://www.techcrunch.com/",
Scheme: "http", Scheme: "http",
...@@ -188,7 +187,7 @@ var reqWriteTests = []reqWriteTest{ ...@@ -188,7 +187,7 @@ var reqWriteTests = []reqWriteTest{
{ {
Req: Request{ Req: Request{
Method: "POST", Method: "POST",
RawURL: "http://example.com/", URL: mustParseURL("http://example.com/"),
Host: "example.com", Host: "example.com",
Header: Header{ Header: Header{
"Content-Length": []string{"10"}, // ignored "Content-Length": []string{"10"}, // ignored
...@@ -198,14 +197,14 @@ var reqWriteTests = []reqWriteTest{ ...@@ -198,14 +197,14 @@ var reqWriteTests = []reqWriteTest{
Body: []byte("abcdef"), Body: []byte("abcdef"),
WantWrite: "POST http://example.com/ HTTP/1.1\r\n" + WantWrite: "POST / HTTP/1.1\r\n" +
"Host: example.com\r\n" + "Host: example.com\r\n" +
"User-Agent: Go http package\r\n" + "User-Agent: Go http package\r\n" +
"Content-Length: 6\r\n" + "Content-Length: 6\r\n" +
"\r\n" + "\r\n" +
"abcdef", "abcdef",
WantProxy: "POST http://example.com/ HTTP/1.1\r\n" + WantProxy: "POST / HTTP/1.1\r\n" +
"Host: example.com\r\n" + "Host: example.com\r\n" +
"User-Agent: Go http package\r\n" + "User-Agent: Go http package\r\n" +
"Content-Length: 6\r\n" + "Content-Length: 6\r\n" +
...@@ -217,7 +216,7 @@ var reqWriteTests = []reqWriteTest{ ...@@ -217,7 +216,7 @@ var reqWriteTests = []reqWriteTest{
{ {
Req: Request{ Req: Request{
Method: "GET", Method: "GET",
RawURL: "/search", URL: mustParseURL("/search"),
Host: "www.google.com", Host: "www.google.com",
}, },
...@@ -225,19 +224,13 @@ var reqWriteTests = []reqWriteTest{ ...@@ -225,19 +224,13 @@ var reqWriteTests = []reqWriteTest{
"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.
WantProxy: "GET /search HTTP/1.1\r\n" +
"Host: www.google.com\r\n" +
"User-Agent: Go http package\r\n" +
"\r\n",
}, },
// Request with a 0 ContentLength and a 0 byte body. // Request with a 0 ContentLength and a 0 byte body.
{ {
Req: Request{ Req: Request{
Method: "POST", Method: "POST",
RawURL: "/", URL: mustParseURL("/"),
Host: "example.com", Host: "example.com",
ProtoMajor: 1, ProtoMajor: 1,
ProtoMinor: 1, ProtoMinor: 1,
...@@ -266,7 +259,7 @@ var reqWriteTests = []reqWriteTest{ ...@@ -266,7 +259,7 @@ var reqWriteTests = []reqWriteTest{
{ {
Req: Request{ Req: Request{
Method: "POST", Method: "POST",
RawURL: "/", URL: mustParseURL("/"),
Host: "example.com", Host: "example.com",
ProtoMajor: 1, ProtoMajor: 1,
ProtoMinor: 1, ProtoMinor: 1,
...@@ -292,7 +285,7 @@ var reqWriteTests = []reqWriteTest{ ...@@ -292,7 +285,7 @@ var reqWriteTests = []reqWriteTest{
{ {
Req: Request{ Req: Request{
Method: "POST", Method: "POST",
RawURL: "/", URL: mustParseURL("/"),
Host: "example.com", Host: "example.com",
ProtoMajor: 1, ProtoMajor: 1,
ProtoMinor: 1, ProtoMinor: 1,
...@@ -306,7 +299,7 @@ var reqWriteTests = []reqWriteTest{ ...@@ -306,7 +299,7 @@ var reqWriteTests = []reqWriteTest{
{ {
Req: Request{ Req: Request{
Method: "POST", Method: "POST",
RawURL: "/", URL: mustParseURL("/"),
Host: "example.com", Host: "example.com",
ProtoMajor: 1, ProtoMajor: 1,
ProtoMinor: 1, ProtoMinor: 1,
...@@ -320,7 +313,7 @@ var reqWriteTests = []reqWriteTest{ ...@@ -320,7 +313,7 @@ var reqWriteTests = []reqWriteTest{
{ {
Req: Request{ Req: Request{
Method: "POST", Method: "POST",
RawURL: "/", URL: mustParseURL("/"),
Host: "example.com", Host: "example.com",
ProtoMajor: 1, ProtoMajor: 1,
ProtoMinor: 1, ProtoMinor: 1,
...@@ -334,7 +327,7 @@ var reqWriteTests = []reqWriteTest{ ...@@ -334,7 +327,7 @@ var reqWriteTests = []reqWriteTest{
{ {
Req: Request{ Req: Request{
Method: "GET", Method: "GET",
RawURL: "/foo", URL: mustParseURL("/foo"),
ProtoMajor: 1, ProtoMajor: 1,
ProtoMinor: 0, ProtoMinor: 0,
Header: Header{ Header: Header{
...@@ -349,7 +342,10 @@ var reqWriteTests = []reqWriteTest{ ...@@ -349,7 +342,10 @@ var reqWriteTests = []reqWriteTest{
// .. but we can't call Request.Write on it, due to its lack of Host header. // .. but we can't call Request.Write on it, due to its lack of Host header.
// TODO(bradfitz): there might be an argument to allow this, but for now I'd // TODO(bradfitz): there might be an argument to allow this, but for now I'd
// rather let HTTP/1.0 continue to die. // rather let HTTP/1.0 continue to die.
WantError: os.NewError("http: Request.Write on Request with no Host or URL set"), WantWrite: "GET /foo HTTP/1.1\r\n" +
"Host: \r\n" +
"User-Agent: Go http package\r\n" +
"X-Foo: X-Bar\r\n\r\n",
}, },
} }
...@@ -464,3 +460,11 @@ func TestRequestWriteClosesBody(t *testing.T) { ...@@ -464,3 +460,11 @@ func TestRequestWriteClosesBody(t *testing.T) {
func chunk(s string) string { func chunk(s string) string {
return fmt.Sprintf("%x\r\n%s\r\n", len(s), s) return fmt.Sprintf("%x\r\n%s\r\n", len(s), s)
} }
func mustParseURL(s string) *url.URL {
u, err := url.Parse(s)
if err != nil {
panic(fmt.Sprintf("Error parsing URL %q: %v", s, err))
}
return u
}
...@@ -103,9 +103,7 @@ func ProxyURL(fixedURL *url.URL) func(*Request) (*url.URL, os.Error) { ...@@ -103,9 +103,7 @@ func ProxyURL(fixedURL *url.URL) func(*Request) (*url.URL, os.Error) {
// RoundTrip implements the RoundTripper interface. // RoundTrip implements the RoundTripper interface.
func (t *Transport) RoundTrip(req *Request) (resp *Response, err os.Error) { func (t *Transport) RoundTrip(req *Request) (resp *Response, err os.Error) {
if req.URL == nil { if req.URL == nil {
if req.URL, err = url.Parse(req.RawURL); err != nil { return nil, os.NewError("http: nil Request.URL")
return
}
} }
if req.URL.Scheme != "http" && req.URL.Scheme != "https" { if req.URL.Scheme != "http" && req.URL.Scheme != "https" {
t.lk.Lock() t.lk.Lock()
...@@ -315,7 +313,7 @@ func (t *Transport) getConn(cm *connectMethod) (*persistConn, os.Error) { ...@@ -315,7 +313,7 @@ func (t *Transport) getConn(cm *connectMethod) (*persistConn, os.Error) {
case cm.targetScheme == "https": case cm.targetScheme == "https":
connectReq := &Request{ connectReq := &Request{
Method: "CONNECT", Method: "CONNECT",
RawURL: cm.targetAddr, URL: &url.URL{RawPath: cm.targetAddr},
Host: cm.targetAddr, Host: cm.targetAddr,
Header: make(Header), Header: make(Header),
} }
......
...@@ -78,7 +78,7 @@ func TestTransportConnectionCloseOnResponse(t *testing.T) { ...@@ -78,7 +78,7 @@ func TestTransportConnectionCloseOnResponse(t *testing.T) {
fetch := func(n int) string { fetch := func(n int) string {
req := new(Request) req := new(Request)
var err os.Error var err os.Error
req.URL, err = url.Parse(ts.URL + fmt.Sprintf("?close=%v", connectionClose)) req.URL, err = url.Parse(ts.URL + fmt.Sprintf("/?close=%v", connectionClose))
if err != nil { if err != nil {
t.Fatalf("URL parse error: %v", err) t.Fatalf("URL parse error: %v", err)
} }
...@@ -362,32 +362,6 @@ func TestTransportHeadChunkedResponse(t *testing.T) { ...@@ -362,32 +362,6 @@ func TestTransportHeadChunkedResponse(t *testing.T) {
} }
} }
func TestTransportNilURL(t *testing.T) {
ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
fmt.Fprintf(w, "Hi")
}))
defer ts.Close()
req := new(Request)
req.URL = nil // what we're actually testing
req.Method = "GET"
req.RawURL = ts.URL
req.Proto = "HTTP/1.1"
req.ProtoMajor = 1
req.ProtoMinor = 1
req.Header = make(Header)
tr := &Transport{}
res, err := tr.RoundTrip(req)
if err != nil {
t.Fatalf("unexpected RoundTrip error: %v", err)
}
body, err := ioutil.ReadAll(res.Body)
if g, e := string(body), "Hi"; g != e {
t.Fatalf("Expected response body of %q; got %q", e, g)
}
}
var roundTripTests = []struct { var roundTripTests = []struct {
accept string accept string
expectAccept string expectAccept string
...@@ -484,7 +458,7 @@ func TestTransportGzip(t *testing.T) { ...@@ -484,7 +458,7 @@ func TestTransportGzip(t *testing.T) {
c := &Client{Transport: &Transport{}} c := &Client{Transport: &Transport{}}
// First fetch something large, but only read some of it. // First fetch something large, but only read some of it.
res, err := c.Get(ts.URL + "?body=large&chunked=" + chunked) res, err := c.Get(ts.URL + "/?body=large&chunked=" + chunked)
if err != nil { if err != nil {
t.Fatalf("large get: %v", err) t.Fatalf("large get: %v", err)
} }
...@@ -504,7 +478,7 @@ func TestTransportGzip(t *testing.T) { ...@@ -504,7 +478,7 @@ func TestTransportGzip(t *testing.T) {
} }
// Then something small. // Then something small.
res, err = c.Get(ts.URL + "?chunked=" + chunked) res, err = c.Get(ts.URL + "/?chunked=" + chunked)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
......
...@@ -72,13 +72,13 @@ Sec-WebSocket-Protocol: sample ...@@ -72,13 +72,13 @@ Sec-WebSocket-Protocol: sample
} }
req, err := http.ReadRequest(bufio.NewReader(b)) req, err := http.ReadRequest(bufio.NewReader(b))
if err != nil { if err != nil {
t.Errorf("read request: %v", err) t.Fatalf("read request: %v", err)
} }
if req.Method != "GET" { if req.Method != "GET" {
t.Errorf("request method expected GET, but got %q", req.Method) t.Errorf("request method expected GET, but got %q", req.Method)
} }
if req.RawURL != "/demo" { if req.URL.Path != "/demo" {
t.Errorf("request path expected /demo, but got %q", req.RawURL) t.Errorf("request path expected /demo, but got %q", req.URL.Path)
} }
if req.Proto != "HTTP/1.1" { if req.Proto != "HTTP/1.1" {
t.Errorf("request proto expected HTTP/1.1, but got %q", req.Proto) t.Errorf("request proto expected HTTP/1.1, but got %q", req.Proto)
......
...@@ -63,13 +63,13 @@ Sec-WebSocket-Protocol: chat ...@@ -63,13 +63,13 @@ Sec-WebSocket-Protocol: chat
} }
req, err := http.ReadRequest(bufio.NewReader(b)) req, err := http.ReadRequest(bufio.NewReader(b))
if err != nil { if err != nil {
t.Errorf("read request: %v", err) t.Fatalf("read request: %v", err)
} }
if req.Method != "GET" { if req.Method != "GET" {
t.Errorf("request method expected GET, but got %q", req.Method) t.Errorf("request method expected GET, but got %q", req.Method)
} }
if req.RawURL != "/chat" { if req.URL.Path != "/chat" {
t.Errorf("request path expected /chat, but got %q", req.RawURL) t.Errorf("request path expected /chat, but got %q", req.URL.Path)
} }
if req.Proto != "HTTP/1.1" { if req.Proto != "HTTP/1.1" {
t.Errorf("request proto expected HTTP/1.1, but got %q", req.Proto) t.Errorf("request proto expected HTTP/1.1, but got %q", req.Proto)
...@@ -125,13 +125,13 @@ Sec-WebSocket-Protocol: chat ...@@ -125,13 +125,13 @@ Sec-WebSocket-Protocol: chat
} }
req, err := http.ReadRequest(bufio.NewReader(b)) req, err := http.ReadRequest(bufio.NewReader(b))
if err != nil { if err != nil {
t.Errorf("read request: %v", err) t.Fatalf("read request: %v", err)
} }
if req.Method != "GET" { if req.Method != "GET" {
t.Errorf("request method expected GET, but got %q", req.Method) t.Errorf("request method expected GET, but got %q", req.Method)
} }
if req.RawURL != "/chat" { if req.URL.Path != "/chat" {
t.Errorf("request path expected /demo, but got %q", req.RawURL) t.Errorf("request path expected /demo, but got %q", req.URL.Path)
} }
if req.Proto != "HTTP/1.1" { if req.Proto != "HTTP/1.1" {
t.Errorf("request proto expected HTTP/1.1, but got %q", req.Proto) t.Errorf("request proto expected HTTP/1.1, but got %q", req.Proto)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment