Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
G
golang
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
golang
Commits
48ff4a84
Commit
48ff4a84
authored
Sep 19, 2011
by
Brad Fitzpatrick
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
http: check explicit wrong Request.ContentLength values
R=golang-dev, rsc CC=golang-dev
https://golang.org/cl/5070041
parent
5edf5197
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
112 additions
and
8 deletions
+112
-8
requestwrite_test.go
src/pkg/http/requestwrite_test.go
+92
-5
transfer.go
src/pkg/http/transfer.go
+20
-3
No files found.
src/pkg/http/requestwrite_test.go
View file @
48ff4a84
...
...
@@ -16,10 +16,11 @@ import (
)
type
reqWriteTest
struct
{
Req
Request
Body
interface
{}
// optional []byte or func() io.ReadCloser to populate Req.Body
Raw
string
RawProxy
string
Req
Request
Body
interface
{}
// optional []byte or func() io.ReadCloser to populate Req.Body
Raw
string
RawProxy
string
WantError
os
.
Error
}
var
reqWriteTests
=
[]
reqWriteTest
{
...
...
@@ -78,6 +79,8 @@ var reqWriteTests = []reqWriteTest{
"Accept-Language: en-us,en;q=0.5
\r\n
"
+
"Keep-Alive: 300
\r\n
"
+
"Proxy-Connection: keep-alive
\r\n\r\n
"
,
nil
,
},
// HTTP/1.1 => chunked coding; body; empty trailer
{
...
...
@@ -107,6 +110,8 @@ var reqWriteTests = []reqWriteTest{
"User-Agent: Go http package
\r\n
"
+
"Transfer-Encoding: chunked
\r\n\r\n
"
+
chunk
(
"abcdef"
)
+
chunk
(
""
),
nil
,
},
// HTTP/1.1 POST => chunked coding; body; empty trailer
{
...
...
@@ -139,6 +144,8 @@ var reqWriteTests = []reqWriteTest{
"Connection: close
\r\n
"
+
"Transfer-Encoding: chunked
\r\n\r\n
"
+
chunk
(
"abcdef"
)
+
chunk
(
""
),
nil
,
},
// HTTP/1.1 POST with Content-Length, no chunking
...
...
@@ -174,6 +181,8 @@ var reqWriteTests = []reqWriteTest{
"Content-Length: 6
\r\n
"
+
"
\r\n
"
+
"abcdef"
,
nil
,
},
// HTTP/1.1 POST with Content-Length in headers
...
...
@@ -203,6 +212,8 @@ var reqWriteTests = []reqWriteTest{
"Content-Length: 6
\r\n
"
+
"
\r\n
"
+
"abcdef"
,
nil
,
},
// default to HTTP/1.1
...
...
@@ -225,6 +236,8 @@ var reqWriteTests = []reqWriteTest{
"Host: www.google.com
\r\n
"
+
"User-Agent: Go http package
\r\n
"
+
"
\r\n
"
,
nil
,
},
// Request with a 0 ContentLength and a 0 byte body.
...
...
@@ -249,6 +262,8 @@ var reqWriteTests = []reqWriteTest{
"Host: example.com
\r\n
"
+
"User-Agent: Go http package
\r\n
"
+
"
\r\n
"
,
nil
,
},
// Request with a 0 ContentLength and a 1 byte body.
...
...
@@ -275,6 +290,74 @@ var reqWriteTests = []reqWriteTest{
"User-Agent: Go http package
\r\n
"
+
"Transfer-Encoding: chunked
\r\n\r\n
"
+
chunk
(
"x"
)
+
chunk
(
""
),
nil
,
},
// Request with a ContentLength of 10 but a 5 byte body.
{
Request
{
Method
:
"POST"
,
RawURL
:
"/"
,
Host
:
"example.com"
,
ProtoMajor
:
1
,
ProtoMinor
:
1
,
ContentLength
:
10
,
// but we're going to send only 5 bytes
},
[]
byte
(
"12345"
),
""
,
// ignored
""
,
// ignored
os
.
NewError
(
"http: Request.ContentLength=10 with Body length 5"
),
},
// Request with a ContentLength of 4 but an 8 byte body.
{
Request
{
Method
:
"POST"
,
RawURL
:
"/"
,
Host
:
"example.com"
,
ProtoMajor
:
1
,
ProtoMinor
:
1
,
ContentLength
:
4
,
// but we're going to try to send 8 bytes
},
[]
byte
(
"12345678"
),
""
,
// ignored
""
,
// ignored
os
.
NewError
(
"http: Request.ContentLength=4 with Body length 8"
),
},
// Request with a 5 ContentLength and nil body.
{
Request
{
Method
:
"POST"
,
RawURL
:
"/"
,
Host
:
"example.com"
,
ProtoMajor
:
1
,
ProtoMinor
:
1
,
ContentLength
:
5
,
// but we'll omit the body
},
nil
,
// missing body
"POST / HTTP/1.1
\r\n
"
+
"Host: example.com
\r\n
"
+
"User-Agent: Go http package
\r\n
"
+
"Content-Length: 5
\r\n\r\n
"
+
""
,
"POST / HTTP/1.1
\r\n
"
+
"Host: example.com
\r\n
"
+
"User-Agent: Go http package
\r\n
"
+
"Content-Length: 5
\r\n\r\n
"
+
""
,
os
.
NewError
(
"http: Request.ContentLength=5 with nil Body"
),
},
}
...
...
@@ -298,10 +381,14 @@ func TestRequestWrite(t *testing.T) {
}
var
braw
bytes
.
Buffer
err
:=
tt
.
Req
.
Write
(
&
braw
)
if
g
,
e
:=
fmt
.
Sprintf
(
"%v"
,
err
),
fmt
.
Sprintf
(
"%v"
,
tt
.
WantError
);
g
!=
e
{
t
.
Errorf
(
"writing #%d, err = %q, want %q"
,
i
,
g
,
e
)
continue
}
if
err
!=
nil
{
t
.
Errorf
(
"error writing #%d: %s"
,
i
,
err
)
continue
}
sraw
:=
braw
.
String
()
if
sraw
!=
tt
.
Raw
{
t
.
Errorf
(
"Test %d, expecting:
\n
%s
\n
Got:
\n
%s
\n
"
,
i
,
tt
.
Raw
,
sraw
)
...
...
src/pkg/http/transfer.go
View file @
48ff4a84
...
...
@@ -7,6 +7,7 @@ package http
import
(
"bytes"
"bufio"
"fmt"
"io"
"io/ioutil"
"os"
...
...
@@ -21,7 +22,7 @@ type transferWriter struct {
Body
io
.
Reader
BodyCloser
io
.
Closer
ResponseToHEAD
bool
ContentLength
int64
ContentLength
int64
// -1 means unknown, 0 means exactly none
Close
bool
TransferEncoding
[]
string
Trailer
Header
...
...
@@ -34,6 +35,10 @@ func newTransferWriter(r interface{}) (t *transferWriter, err os.Error) {
atLeastHTTP11
:=
false
switch
rr
:=
r
.
(
type
)
{
case
*
Request
:
if
rr
.
ContentLength
!=
0
&&
rr
.
Body
==
nil
{
return
nil
,
fmt
.
Errorf
(
"http: Request.ContentLength=%d with nil Body"
,
rr
.
ContentLength
)
}
t
.
Body
=
rr
.
Body
t
.
BodyCloser
=
rr
.
Body
t
.
ContentLength
=
rr
.
ContentLength
...
...
@@ -154,6 +159,8 @@ func (t *transferWriter) WriteHeader(w io.Writer) (err os.Error) {
}
func
(
t
*
transferWriter
)
WriteBody
(
w
io
.
Writer
)
(
err
os
.
Error
)
{
var
ncopy
int64
// Write body
if
t
.
Body
!=
nil
{
if
chunked
(
t
.
TransferEncoding
)
{
...
...
@@ -163,9 +170,14 @@ func (t *transferWriter) WriteBody(w io.Writer) (err os.Error) {
err
=
cw
.
Close
()
}
}
else
if
t
.
ContentLength
==
-
1
{
_
,
err
=
io
.
Copy
(
w
,
t
.
Body
)
ncopy
,
err
=
io
.
Copy
(
w
,
t
.
Body
)
}
else
{
_
,
err
=
io
.
Copy
(
w
,
io
.
LimitReader
(
t
.
Body
,
t
.
ContentLength
))
ncopy
,
err
=
io
.
Copy
(
w
,
io
.
LimitReader
(
t
.
Body
,
t
.
ContentLength
))
nextra
,
err
:=
io
.
Copy
(
ioutil
.
Discard
,
t
.
Body
)
if
err
!=
nil
{
return
err
}
ncopy
+=
nextra
}
if
err
!=
nil
{
return
err
...
...
@@ -175,6 +187,11 @@ func (t *transferWriter) WriteBody(w io.Writer) (err os.Error) {
}
}
if
t
.
ContentLength
!=
-
1
&&
t
.
ContentLength
!=
ncopy
{
return
fmt
.
Errorf
(
"http: Request.ContentLength=%d with Body length %d"
,
t
.
ContentLength
,
ncopy
)
}
// TODO(petar): Place trailer writer code here.
if
chunked
(
t
.
TransferEncoding
)
{
// Last chunk, empty trailer
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment