mirror of
https://github.com/golang/go
synced 2024-11-19 12:44:51 -07:00
http: buffer Request.Write
Fixes #1996 R=golang-dev, r CC=golang-dev https://golang.org/cl/4639068
This commit is contained in:
parent
65b036c381
commit
89873e60e2
@ -12,6 +12,7 @@ import (
|
||||
"http/httptest"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -243,3 +244,48 @@ func TestStreamingGet(t *testing.T) {
|
||||
t.Fatalf("at end expected EOF, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
type writeCountingConn struct {
|
||||
net.Conn
|
||||
count *int
|
||||
}
|
||||
|
||||
func (c *writeCountingConn) Write(p []byte) (int, os.Error) {
|
||||
*c.count++
|
||||
return c.Conn.Write(p)
|
||||
}
|
||||
|
||||
// TestClientWrites verifies that client requests are buffered and we
|
||||
// don't send a TCP packet per line of the http request + body.
|
||||
func TestClientWrites(t *testing.T) {
|
||||
ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
writes := 0
|
||||
dialer := func(netz string, addr string) (net.Conn, os.Error) {
|
||||
c, err := net.Dial(netz, addr)
|
||||
if err == nil {
|
||||
c = &writeCountingConn{c, &writes}
|
||||
}
|
||||
return c, err
|
||||
}
|
||||
c := &Client{Transport: &Transport{Dial: dialer}}
|
||||
|
||||
_, err := c.Get(ts.URL)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if writes != 1 {
|
||||
t.Errorf("Get request did %d Write calls, want 1", writes)
|
||||
}
|
||||
|
||||
writes = 0
|
||||
_, err = c.PostForm(ts.URL, Values{"foo": {"bar"}})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if writes != 1 {
|
||||
t.Errorf("Post request did %d Write calls, want 1", writes)
|
||||
}
|
||||
}
|
||||
|
@ -304,10 +304,11 @@ func (req *Request) write(w io.Writer, usingProxy bool) os.Error {
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, "%s %s HTTP/1.1\r\n", valueOrDefault(req.Method, "GET"), uri)
|
||||
bw := bufio.NewWriter(w)
|
||||
fmt.Fprintf(bw, "%s %s HTTP/1.1\r\n", valueOrDefault(req.Method, "GET"), uri)
|
||||
|
||||
// Header lines
|
||||
fmt.Fprintf(w, "Host: %s\r\n", host)
|
||||
fmt.Fprintf(bw, "Host: %s\r\n", host)
|
||||
|
||||
// Use the defaultUserAgent unless the Header contains one, which
|
||||
// may be blank to not send the header.
|
||||
@ -318,7 +319,7 @@ func (req *Request) write(w io.Writer, usingProxy bool) os.Error {
|
||||
}
|
||||
}
|
||||
if userAgent != "" {
|
||||
fmt.Fprintf(w, "User-Agent: %s\r\n", userAgent)
|
||||
fmt.Fprintf(bw, "User-Agent: %s\r\n", userAgent)
|
||||
}
|
||||
|
||||
// Process Body,ContentLength,Close,Trailer
|
||||
@ -326,25 +327,25 @@ func (req *Request) write(w io.Writer, usingProxy bool) os.Error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = tw.WriteHeader(w)
|
||||
err = tw.WriteHeader(bw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: split long values? (If so, should share code with Conn.Write)
|
||||
err = req.Header.WriteSubset(w, reqWriteExcludeHeader)
|
||||
err = req.Header.WriteSubset(bw, reqWriteExcludeHeader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
io.WriteString(w, "\r\n")
|
||||
io.WriteString(bw, "\r\n")
|
||||
|
||||
// Write body and trailer
|
||||
err = tw.WriteBody(w)
|
||||
err = tw.WriteBody(bw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bw.Flush()
|
||||
return nil
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user