Commit 33d531df authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

net/http: support WriteString on the ResponseWriter

Fixes #5377

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/12991046
parent 94b42fb1
...@@ -1994,6 +1994,21 @@ func TestNoContentTypeOnNotModified(t *testing.T) { ...@@ -1994,6 +1994,21 @@ func TestNoContentTypeOnNotModified(t *testing.T) {
} }
} }
func TestResponseWriterWriteStringAllocs(t *testing.T) {
ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) {
if r.URL.Path == "/s" {
io.WriteString(w, "Hello world")
} else {
w.Write([]byte("Hello world"))
}
}))
before := testing.AllocsPerRun(25, func() { ht.rawResponse("GET / HTTP/1.0") })
after := testing.AllocsPerRun(25, func() { ht.rawResponse("GET /s HTTP/1.0") })
if int(after) >= int(before) {
t.Errorf("WriteString allocs of %v >= Write allocs of %v", after, before)
}
}
func BenchmarkClientServer(b *testing.B) { func BenchmarkClientServer(b *testing.B) {
b.ReportAllocs() b.ReportAllocs()
b.StopTimer() b.StopTimer()
......
...@@ -953,6 +953,15 @@ func (w *response) bodyAllowed() bool { ...@@ -953,6 +953,15 @@ func (w *response) bodyAllowed() bool {
// bufferBeforeChunkingSize smaller and having bufio's fast-paths deal // bufferBeforeChunkingSize smaller and having bufio's fast-paths deal
// with this instead. // with this instead.
func (w *response) Write(data []byte) (n int, err error) { func (w *response) Write(data []byte) (n int, err error) {
return w.write(len(data), data, "")
}
func (w *response) WriteString(data string) (n int, err error) {
return w.write(len(data), nil, data)
}
// either dataB or dataS is non-zero.
func (w *response) write(lenData int, dataB []byte, dataS string) (n int, err error) {
if w.conn.hijacked() { if w.conn.hijacked() {
log.Print("http: response.Write on hijacked connection") log.Print("http: response.Write on hijacked connection")
return 0, ErrHijacked return 0, ErrHijacked
...@@ -960,18 +969,22 @@ func (w *response) Write(data []byte) (n int, err error) { ...@@ -960,18 +969,22 @@ func (w *response) Write(data []byte) (n int, err error) {
if !w.wroteHeader { if !w.wroteHeader {
w.WriteHeader(StatusOK) w.WriteHeader(StatusOK)
} }
if len(data) == 0 { if lenData == 0 {
return 0, nil return 0, nil
} }
if !w.bodyAllowed() { if !w.bodyAllowed() {
return 0, ErrBodyNotAllowed return 0, ErrBodyNotAllowed
} }
w.written += int64(len(data)) // ignoring errors, for errorKludge w.written += int64(lenData) // ignoring errors, for errorKludge
if w.contentLength != -1 && w.written > w.contentLength { if w.contentLength != -1 && w.written > w.contentLength {
return 0, ErrContentLength return 0, ErrContentLength
} }
return w.w.Write(data) if dataB != nil {
return w.w.Write(dataB)
} else {
return w.w.WriteString(dataS)
}
} }
func (w *response) finishRequest() { func (w *response) finishRequest() {
......
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