mirror of
https://github.com/golang/go
synced 2024-11-02 11:50:30 +00:00
net/http: zero pad Response status codes to three digits
Go 1.6's HTTP/1.x Transport started enforcing that responses have 3 status digits, per the spec, but we could still write out invalid status codes ourselves if the called ResponseWriter.WriteHeader(0). That is bogus anyway, since the minimum status code is 1xx, but be a little bit less bogus (and consistent) and zero pad our responses. Change-Id: I6883901fd95073cb72f6b74035cabf1a79c35e1c Reviewed-on: https://go-review.googlesource.com/19130 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Andrew Gerrand <adg@golang.org>
This commit is contained in:
parent
7208a2cd78
commit
3bbede0c51
4 changed files with 62 additions and 5 deletions
|
@ -1102,6 +1102,27 @@ func testTransportRejectsInvalidHeaders(t *testing.T, h2 bool) {
|
|||
}
|
||||
}
|
||||
|
||||
// Tests that we support bogus under-100 HTTP statuses, because we historically
|
||||
// have. This might change at some point, but not yet in Go 1.6.
|
||||
func TestBogusStatusWorks_h1(t *testing.T) { testBogusStatusWorks(t, h1Mode) }
|
||||
func TestBogusStatusWorks_h2(t *testing.T) { testBogusStatusWorks(t, h2Mode) }
|
||||
func testBogusStatusWorks(t *testing.T, h2 bool) {
|
||||
defer afterTest(t)
|
||||
const code = 7
|
||||
cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
|
||||
w.WriteHeader(code)
|
||||
}))
|
||||
defer cst.close()
|
||||
|
||||
res, err := cst.c.Get(cst.ts.URL)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if res.StatusCode != code {
|
||||
t.Errorf("StatusCode = %d; want %d", res.StatusCode, code)
|
||||
}
|
||||
}
|
||||
|
||||
type noteCloseConn struct {
|
||||
net.Conn
|
||||
closeFunc func()
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"bytes"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/textproto"
|
||||
"net/url"
|
||||
|
@ -228,11 +229,13 @@ func (r *Response) Write(w io.Writer) error {
|
|||
if !ok {
|
||||
text = "status code " + strconv.Itoa(r.StatusCode)
|
||||
}
|
||||
} else {
|
||||
// Just to reduce stutter, if user set r.Status to "200 OK" and StatusCode to 200.
|
||||
// Not important.
|
||||
text = strings.TrimPrefix(text, strconv.Itoa(r.StatusCode)+" ")
|
||||
}
|
||||
protoMajor, protoMinor := strconv.Itoa(r.ProtoMajor), strconv.Itoa(r.ProtoMinor)
|
||||
statusCode := strconv.Itoa(r.StatusCode) + " "
|
||||
text = strings.TrimPrefix(text, statusCode)
|
||||
if _, err := io.WriteString(w, "HTTP/"+protoMajor+"."+protoMinor+" "+statusCode+text+"\r\n"); err != nil {
|
||||
|
||||
if _, err := fmt.Fprintf(w, "HTTP/%d.%d %03d %s\r\n", r.ProtoMajor, r.ProtoMinor, r.StatusCode, text); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -222,6 +222,39 @@ func TestResponseWrite(t *testing.T) {
|
|||
},
|
||||
"HTTP/1.1 200 OK\r\nConnection: close\r\n\r\nabcdef",
|
||||
},
|
||||
|
||||
// Status code under 100 should be zero-padded to
|
||||
// three digits. Still bogus, but less bogus. (be
|
||||
// consistent with generating three digits, since the
|
||||
// Transport requires it)
|
||||
{
|
||||
Response{
|
||||
StatusCode: 7,
|
||||
Status: "license to violate specs",
|
||||
ProtoMajor: 1,
|
||||
ProtoMinor: 0,
|
||||
Request: dummyReq("GET"),
|
||||
Header: Header{},
|
||||
Body: nil,
|
||||
},
|
||||
|
||||
"HTTP/1.0 007 license to violate specs\r\nContent-Length: 0\r\n\r\n",
|
||||
},
|
||||
|
||||
// No stutter.
|
||||
{
|
||||
Response{
|
||||
StatusCode: 123,
|
||||
Status: "123 Sesame Street",
|
||||
ProtoMajor: 1,
|
||||
ProtoMinor: 0,
|
||||
Request: dummyReq("GET"),
|
||||
Header: Header{},
|
||||
Body: nil,
|
||||
},
|
||||
|
||||
"HTTP/1.0 123 Sesame Street\r\nContent-Length: 0\r\n\r\n",
|
||||
},
|
||||
}
|
||||
|
||||
for i := range respWriteTests {
|
||||
|
|
|
@ -1152,7 +1152,7 @@ func statusLine(req *Request, code int) string {
|
|||
if proto11 {
|
||||
proto = "HTTP/1.1"
|
||||
}
|
||||
codestring := strconv.Itoa(code)
|
||||
codestring := fmt.Sprintf("%03d", code)
|
||||
text, ok := statusText[code]
|
||||
if !ok {
|
||||
text = "status code " + codestring
|
||||
|
|
Loading…
Reference in a new issue