github.com/ssdev-go/moby@v17.12.1-ce-rc2+incompatible/cmd/dockerd/hack/malformed_host_override_test.go (about) 1 // +build !windows 2 3 package hack 4 5 import ( 6 "bytes" 7 "io" 8 "net" 9 "strings" 10 "testing" 11 ) 12 13 type bufConn struct { 14 net.Conn 15 buf *bytes.Buffer 16 } 17 18 func (bc *bufConn) Read(b []byte) (int, error) { 19 return bc.buf.Read(b) 20 } 21 22 func TestHeaderOverrideHack(t *testing.T) { 23 tests := [][2][]byte{ 24 { 25 []byte("GET /foo\nHost: /var/run/docker.sock\nUser-Agent: Docker\r\n\r\n"), 26 []byte("GET /foo\nHost: \r\nConnection: close\r\nUser-Agent: Docker\r\n\r\n"), 27 }, 28 { 29 []byte("GET /foo\nHost: /var/run/docker.sock\nUser-Agent: Docker\nFoo: Bar\r\n"), 30 []byte("GET /foo\nHost: \r\nConnection: close\r\nUser-Agent: Docker\nFoo: Bar\r\n"), 31 }, 32 { 33 []byte("GET /foo\nHost: /var/run/docker.sock\nUser-Agent: Docker\r\n\r\ntest something!"), 34 []byte("GET /foo\nHost: \r\nConnection: close\r\nUser-Agent: Docker\r\n\r\ntest something!"), 35 }, 36 { 37 []byte("GET /foo\nHost: /var/run/docker.sock\nUser-Agent: Docker\r\n\r\ntest something! " + strings.Repeat("test", 15000)), 38 []byte("GET /foo\nHost: \r\nConnection: close\r\nUser-Agent: Docker\r\n\r\ntest something! " + strings.Repeat("test", 15000)), 39 }, 40 { 41 []byte("GET /foo\nFoo: Bar\nHost: /var/run/docker.sock\nUser-Agent: Docker\r\n\r\n"), 42 []byte("GET /foo\nFoo: Bar\nHost: /var/run/docker.sock\nUser-Agent: Docker\r\n\r\n"), 43 }, 44 } 45 46 // Test for https://github.com/docker/docker/issues/23045 47 h0 := "GET /foo\nUser-Agent: Docker\r\n\r\n" 48 h0 = h0 + strings.Repeat("a", 4096-len(h0)-1) + "\n" 49 tests = append(tests, [2][]byte{[]byte(h0), []byte(h0)}) 50 51 for _, pair := range tests { 52 read := make([]byte, 4096) 53 client := &bufConn{ 54 buf: bytes.NewBuffer(pair[0]), 55 } 56 l := MalformedHostHeaderOverrideConn{client, true} 57 58 n, err := l.Read(read) 59 if err != nil && err != io.EOF { 60 t.Fatalf("read: %d - %d, err: %v\n%s", n, len(pair[0]), err, string(read[:n])) 61 } 62 if !bytes.Equal(read[:n], pair[1][:n]) { 63 t.Fatalf("\n%s\n%s\n", read[:n], pair[1][:n]) 64 } 65 } 66 } 67 68 func BenchmarkWithHack(b *testing.B) { 69 client, srv := net.Pipe() 70 done := make(chan struct{}) 71 req := []byte("GET /foo\nHost: /var/run/docker.sock\nUser-Agent: Docker\n") 72 read := make([]byte, 4096) 73 b.SetBytes(int64(len(req) * 30)) 74 75 l := MalformedHostHeaderOverrideConn{client, true} 76 go func() { 77 for { 78 if _, err := srv.Write(req); err != nil { 79 srv.Close() 80 break 81 } 82 l.first = true // make sure each subsequent run uses the hack parsing 83 } 84 close(done) 85 }() 86 87 for i := 0; i < b.N; i++ { 88 for i := 0; i < 30; i++ { 89 if n, err := l.Read(read); err != nil && err != io.EOF { 90 b.Fatalf("read: %d - %d, err: %v\n%s", n, len(req), err, string(read[:n])) 91 } 92 } 93 } 94 l.Close() 95 <-done 96 } 97 98 func BenchmarkNoHack(b *testing.B) { 99 client, srv := net.Pipe() 100 done := make(chan struct{}) 101 req := []byte("GET /foo\nHost: /var/run/docker.sock\nUser-Agent: Docker\n") 102 read := make([]byte, 4096) 103 b.SetBytes(int64(len(req) * 30)) 104 105 go func() { 106 for { 107 if _, err := srv.Write(req); err != nil { 108 srv.Close() 109 break 110 } 111 } 112 close(done) 113 }() 114 115 for i := 0; i < b.N; i++ { 116 for i := 0; i < 30; i++ { 117 if _, err := client.Read(read); err != nil && err != io.EOF { 118 b.Fatal(err) 119 } 120 } 121 } 122 client.Close() 123 <-done 124 }