Files
weave/proxy/proxy_intercept_test.go
T
Paul Bellamy 11663dd29f [proxy] rewrote chunked response handler
1) We cannot send "Connection: close", because the fsouza docker client
   expects the tcp socket to stay open between requests.

2) Because we cannot force-close the connection, we can't hijack the
   connection (because go's net/http doesn't let use un-hijack it).

3) Because we need to maintain the individual chunking of messages (for
   docker-py), we can't just copy the response body, as Go will remove and
   re-add the chunking willy-nilly.

Therefore, we have to read each chunk one-by-one, and flush the
ResponseWriter after each one.
2015-07-20 14:43:16 +01:00

137 lines
3.0 KiB
Go

// Based on net/http/internal
package proxy
import (
"bufio"
"bytes"
"strconv"
"strings"
"testing"
)
func TestChunk(t *testing.T) {
r := bufio.NewScanner(bytes.NewBufferString(
"7\r\nhello, \r\n17\r\nworld! 0123456789abcdef\r\n0\r\n",
))
r.Split(splitChunks)
assertNextChunk(t, r, "hello, ")
assertNextChunk(t, r, "world! 0123456789abcdef")
assertNoMoreChunks(t, r)
}
func TestMalformedChunks(t *testing.T) {
r := bufio.NewScanner(bytes.NewBufferString(
"7\r\nhello, GARBAGEBYTES17\r\nworld! 0123456789abcdef\r\n0\r\n",
))
r.Split(splitChunks)
// First chunk fails
{
if r.Scan() {
t.Errorf("Expected failure when reading chunks, but got one")
}
e := "malformed chunked encoding"
if r.Err() == nil || r.Err().Error() != e {
t.Errorf("chunk reader errored %q; want %q", r.Err(), e)
}
data := r.Bytes()
if len(data) != 0 {
t.Errorf("chunk should have been empty. got %q", data)
}
}
if r.Scan() {
t.Errorf("Expected no more chunks, but found too many")
}
}
func TestChunkTooLarge(t *testing.T) {
data := make([]byte, maxChunkSize+1)
r := bufio.NewScanner(bytes.NewBufferString(strings.Join(
[]string{
strconv.FormatInt(maxChunkSize+1, 16), string(data),
"0", "",
},
"\r\n",
)))
r.Split(splitChunks)
// First chunk fails
{
if r.Scan() {
t.Errorf("Expected failure when reading chunks, but got one")
}
e := "chunk too long"
if r.Err() == nil || r.Err().Error() != e {
t.Errorf("chunk reader errored %q; want %q", r.Err(), e)
}
data := r.Bytes()
if len(data) != 0 {
t.Errorf("chunk should have been empty. got %q", data)
}
}
if r.Scan() {
t.Errorf("Expected no more chunks, but found too many")
}
}
func TestInvalidChunkSize(t *testing.T) {
r := bufio.NewScanner(bytes.NewBufferString(
"foobar\r\nhello, \r\n0\r\n",
))
r.Split(splitChunks)
// First chunk fails
{
if r.Scan() {
t.Errorf("Expected failure when reading chunks, but got one")
}
e := "invalid byte in chunk length"
if r.Err() == nil || r.Err().Error() != e {
t.Errorf("chunk reader errored %q; want %q", r.Err(), e)
}
data := r.Bytes()
if len(data) != 0 {
t.Errorf("chunk should have been empty. got %q", data)
}
}
if r.Scan() {
t.Errorf("Expected no more chunks, but found too many")
}
}
func TestBytesAfterLastChunkAreIgnored(t *testing.T) {
r := bufio.NewScanner(bytes.NewBufferString(
"7\r\nhello, \r\n0\r\nGARBAGEBYTES",
))
r.Split(splitChunks)
assertNextChunk(t, r, "hello, ")
assertNoMoreChunks(t, r)
}
func assertNextChunk(t *testing.T, r *bufio.Scanner, expected string) {
if !r.Scan() {
t.Fatalf("Expected chunk, but ran out early: %v", r.Err())
}
if r.Err() != nil {
t.Fatalf("Error reading chunk: %q", r.Err())
}
data := r.Bytes()
if string(data) != expected {
t.Errorf("chunk reader read %q; want %q", data, expected)
}
}
func assertNoMoreChunks(t *testing.T, r *bufio.Scanner) {
if r.Scan() {
t.Errorf("Expected no more chunks, but found too many")
}
if r.Err() != nil {
t.Errorf("Expected no error, but found: %q", r.Err())
}
}