1// Copyright 2016 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package httptest 6 7import ( 8 "context" 9 "crypto/tls" 10 "io" 11 "net/http" 12 "net/url" 13 "reflect" 14 "strings" 15 "testing" 16) 17 18func TestNewRequest(t *testing.T) { 19 got := NewRequest("GET", "/", nil) 20 want := &http.Request{ 21 Method: "GET", 22 Host: "example.com", 23 URL: &url.URL{Path: "/"}, 24 Header: http.Header{}, 25 Proto: "HTTP/1.1", 26 ProtoMajor: 1, 27 ProtoMinor: 1, 28 RemoteAddr: "192.0.2.1:1234", 29 RequestURI: "/", 30 } 31 got.Body = nil // before DeepEqual 32 want = want.WithContext(context.Background()) 33 if !reflect.DeepEqual(got, want) { 34 t.Errorf("Request mismatch:\n got: %#v\nwant: %#v", got, want) 35 } 36} 37 38func TestNewRequestWithContext(t *testing.T) { 39 for _, tt := range [...]struct { 40 name string 41 42 method, uri string 43 body io.Reader 44 45 want *http.Request 46 wantBody string 47 }{ 48 { 49 name: "Empty method means GET", 50 method: "", 51 uri: "/", 52 body: nil, 53 want: &http.Request{ 54 Method: "GET", 55 Host: "example.com", 56 URL: &url.URL{Path: "/"}, 57 Header: http.Header{}, 58 Proto: "HTTP/1.1", 59 ProtoMajor: 1, 60 ProtoMinor: 1, 61 RemoteAddr: "192.0.2.1:1234", 62 RequestURI: "/", 63 }, 64 wantBody: "", 65 }, 66 67 { 68 name: "GET with full URL", 69 method: "GET", 70 uri: "http://foo.com/path/%2f/bar/", 71 body: nil, 72 want: &http.Request{ 73 Method: "GET", 74 Host: "foo.com", 75 URL: &url.URL{ 76 Scheme: "http", 77 Path: "/path///bar/", 78 RawPath: "/path/%2f/bar/", 79 Host: "foo.com", 80 }, 81 Header: http.Header{}, 82 Proto: "HTTP/1.1", 83 ProtoMajor: 1, 84 ProtoMinor: 1, 85 RemoteAddr: "192.0.2.1:1234", 86 RequestURI: "http://foo.com/path/%2f/bar/", 87 }, 88 wantBody: "", 89 }, 90 91 { 92 name: "GET with full https URL", 93 method: "GET", 94 uri: "https://foo.com/path/", 95 body: nil, 96 want: &http.Request{ 97 Method: "GET", 98 Host: "foo.com", 99 URL: &url.URL{ 100 Scheme: "https", 101 Path: "/path/", 102 Host: "foo.com", 103 }, 104 Header: http.Header{}, 105 Proto: "HTTP/1.1", 106 ProtoMajor: 1, 107 ProtoMinor: 1, 108 RemoteAddr: "192.0.2.1:1234", 109 RequestURI: "https://foo.com/path/", 110 TLS: &tls.ConnectionState{ 111 Version: tls.VersionTLS12, 112 HandshakeComplete: true, 113 ServerName: "foo.com", 114 }, 115 }, 116 wantBody: "", 117 }, 118 119 { 120 name: "Post with known length", 121 method: "POST", 122 uri: "/", 123 body: strings.NewReader("foo"), 124 want: &http.Request{ 125 Method: "POST", 126 Host: "example.com", 127 URL: &url.URL{Path: "/"}, 128 Header: http.Header{}, 129 Proto: "HTTP/1.1", 130 ContentLength: 3, 131 ProtoMajor: 1, 132 ProtoMinor: 1, 133 RemoteAddr: "192.0.2.1:1234", 134 RequestURI: "/", 135 }, 136 wantBody: "foo", 137 }, 138 139 { 140 name: "Post with unknown length", 141 method: "POST", 142 uri: "/", 143 body: struct{ io.Reader }{strings.NewReader("foo")}, 144 want: &http.Request{ 145 Method: "POST", 146 Host: "example.com", 147 URL: &url.URL{Path: "/"}, 148 Header: http.Header{}, 149 Proto: "HTTP/1.1", 150 ContentLength: -1, 151 ProtoMajor: 1, 152 ProtoMinor: 1, 153 RemoteAddr: "192.0.2.1:1234", 154 RequestURI: "/", 155 }, 156 wantBody: "foo", 157 }, 158 159 { 160 name: "OPTIONS *", 161 method: "OPTIONS", 162 uri: "*", 163 want: &http.Request{ 164 Method: "OPTIONS", 165 Host: "example.com", 166 URL: &url.URL{Path: "*"}, 167 Header: http.Header{}, 168 Proto: "HTTP/1.1", 169 ProtoMajor: 1, 170 ProtoMinor: 1, 171 RemoteAddr: "192.0.2.1:1234", 172 RequestURI: "*", 173 }, 174 }, 175 } { 176 t.Run(tt.name, func(t *testing.T) { 177 got := NewRequestWithContext(context.Background(), tt.method, tt.uri, tt.body) 178 slurp, err := io.ReadAll(got.Body) 179 if err != nil { 180 t.Errorf("ReadAll: %v", err) 181 } 182 if string(slurp) != tt.wantBody { 183 t.Errorf("Body = %q; want %q", slurp, tt.wantBody) 184 } 185 tt.want = tt.want.WithContext(context.Background()) 186 got.Body = nil // before DeepEqual 187 if !reflect.DeepEqual(got.URL, tt.want.URL) { 188 t.Errorf("Request.URL mismatch:\n got: %#v\nwant: %#v", got.URL, tt.want.URL) 189 } 190 if !reflect.DeepEqual(got.Header, tt.want.Header) { 191 t.Errorf("Request.Header mismatch:\n got: %#v\nwant: %#v", got.Header, tt.want.Header) 192 } 193 if !reflect.DeepEqual(got.TLS, tt.want.TLS) { 194 t.Errorf("Request.TLS mismatch:\n got: %#v\nwant: %#v", got.TLS, tt.want.TLS) 195 } 196 if !reflect.DeepEqual(got, tt.want) { 197 t.Errorf("Request mismatch:\n got: %#v\nwant: %#v", got, tt.want) 198 } 199 }) 200 } 201} 202