LEFT | RIGHT |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package http_test | 5 package http_test |
6 | 6 |
7 import ( | 7 import ( |
8 "bufio" | 8 "bufio" |
9 "bytes" | 9 "bytes" |
10 "encoding/base64" | 10 "encoding/base64" |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 Body: ioutil.NopCloser(new(bytes.Buffer)), | 148 Body: ioutil.NopCloser(new(bytes.Buffer)), |
149 } | 149 } |
150 multipart, err := req.MultipartReader() | 150 multipart, err := req.MultipartReader() |
151 if multipart == nil { | 151 if multipart == nil { |
152 t.Errorf("expected multipart; error: %v", err) | 152 t.Errorf("expected multipart; error: %v", err) |
153 } | 153 } |
154 | 154 |
155 req.Header = Header{"Content-Type": {"text/plain"}} | 155 req.Header = Header{"Content-Type": {"text/plain"}} |
156 multipart, err = req.MultipartReader() | 156 multipart, err = req.MultipartReader() |
157 if multipart != nil { | 157 if multipart != nil { |
158 » » t.Errorf("unexpected multipart for text/plain") | 158 » » t.Error("unexpected multipart for text/plain") |
| 159 » } |
| 160 } |
| 161 |
| 162 func TestParseMultipartForm(t *testing.T) { |
| 163 » req := &Request{ |
| 164 » » Method: "POST", |
| 165 » » Header: Header{"Content-Type": {`multipart/form-data; boundary="
foo123"`}}, |
| 166 » » Body: ioutil.NopCloser(new(bytes.Buffer)), |
| 167 » } |
| 168 » err := req.ParseMultipartForm(25) |
| 169 » if err == nil { |
| 170 » » t.Error("expected multipart EOF, got nil") |
| 171 » } |
| 172 |
| 173 » req.Header = Header{"Content-Type": {"text/plain"}} |
| 174 » err = req.ParseMultipartForm(25) |
| 175 » if err != ErrNotMultipart { |
| 176 » » t.Error("expected ErrNotMultipart for text/plain") |
159 } | 177 } |
160 } | 178 } |
161 | 179 |
162 func TestRedirect(t *testing.T) { | 180 func TestRedirect(t *testing.T) { |
163 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request)
{ | 181 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request)
{ |
164 switch r.URL.Path { | 182 switch r.URL.Path { |
165 case "/": | 183 case "/": |
166 w.Header().Set("Location", "/foo/") | 184 w.Header().Set("Location", "/foo/") |
167 w.WriteHeader(StatusSeeOther) | 185 w.WriteHeader(StatusSeeOther) |
168 case "/foo/": | 186 case "/foo/": |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 // ParseMultipartForm and return the right values. | 232 // ParseMultipartForm and return the right values. |
215 req := newTestMultipartRequest(t) | 233 req := newTestMultipartRequest(t) |
216 defer func() { | 234 defer func() { |
217 if req.MultipartForm != nil { | 235 if req.MultipartForm != nil { |
218 req.MultipartForm.RemoveAll() | 236 req.MultipartForm.RemoveAll() |
219 } | 237 } |
220 }() | 238 }() |
221 validateTestMultipartContents(t, req, true) | 239 validateTestMultipartContents(t, req, true) |
222 } | 240 } |
223 | 241 |
224 func TestEmptyMultipartRequest(t *testing.T) { | 242 func TestMissingFileMultipartRequest(t *testing.T) { |
225 » // Test that FormValue and FormFile automatically invoke | 243 » // Test that FormFile returns an error if |
226 » // ParseMultipartForm and return the right values. | 244 » // the named file is missing. |
227 » req, err := NewRequest("GET", "/", nil) | 245 » req := newTestMultipartRequest(t) |
228 » if err != nil { | |
229 » » t.Errorf("NewRequest err = %q", err) | |
230 » } | |
231 testMissingFile(t, req) | 246 testMissingFile(t, req) |
| 247 } |
| 248 |
| 249 // Test that FormValue invokes ParseMultipartForm. |
| 250 func TestFormValueCallsParseMultipartForm(t *testing.T) { |
| 251 req, _ := NewRequest("POST", "http://www.google.com/", strings.NewReader
("z=post")) |
| 252 req.Header.Set("Content-Type", "application/x-www-form-urlencoded; param
=value") |
| 253 if req.Form != nil { |
| 254 t.Fatal("Unexpected request Form, want nil") |
| 255 } |
| 256 req.FormValue("z") |
| 257 if req.Form == nil { |
| 258 t.Fatal("ParseMultipartForm not called by FormValue") |
| 259 } |
| 260 } |
| 261 |
| 262 // Test that FormFile invokes ParseMultipartForm. |
| 263 func TestFormFileCallsParseMultipartForm(t *testing.T) { |
| 264 req := newTestMultipartRequest(t) |
| 265 if req.Form != nil { |
| 266 t.Fatal("Unexpected request Form, want nil") |
| 267 } |
| 268 req.FormFile("") |
| 269 if req.Form == nil { |
| 270 t.Fatal("ParseMultipartForm not called by FormFile") |
| 271 } |
232 } | 272 } |
233 | 273 |
234 // Test that ParseMultipartForm errors if called | 274 // Test that ParseMultipartForm errors if called |
235 // after MultipartReader on the same request. | 275 // after MultipartReader on the same request. |
236 func TestParseMultipartFormOrder(t *testing.T) { | 276 func TestParseMultipartFormOrder(t *testing.T) { |
237 req := newTestMultipartRequest(t) | 277 req := newTestMultipartRequest(t) |
238 if _, err := req.MultipartReader(); err != nil { | 278 if _, err := req.MultipartReader(); err != nil { |
239 t.Fatalf("MultipartReader: %v", err) | 279 t.Fatalf("MultipartReader: %v", err) |
240 } | 280 } |
241 if err := req.ParseMultipartForm(1024); err == nil { | 281 if err := req.ParseMultipartForm(1024); err == nil { |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 major, minor int | 392 major, minor int |
353 ok bool | 393 ok bool |
354 } | 394 } |
355 t.Errorf("failed to parse %q, expected: %#v, got %#v", t
t.vers, version{tt.major, tt.minor, tt.ok}, version{major, minor, ok}) | 395 t.Errorf("failed to parse %q, expected: %#v, got %#v", t
t.vers, version{tt.major, tt.minor, tt.ok}, version{major, minor, ok}) |
356 } | 396 } |
357 } | 397 } |
358 } | 398 } |
359 | 399 |
360 type getBasicAuthTest struct { | 400 type getBasicAuthTest struct { |
361 username, password string | 401 username, password string |
362 » err error | 402 » ok bool |
363 } | 403 } |
364 | 404 |
365 type parseBasicAuthTest getBasicAuthTest | 405 type parseBasicAuthTest getBasicAuthTest |
366 | 406 |
367 type basicAuthCredentialsTest struct { | 407 type basicAuthCredentialsTest struct { |
368 username, password string | 408 username, password string |
369 } | 409 } |
370 | 410 |
371 var getBasicAuthTests = []struct { | 411 var getBasicAuthTests = []struct { |
372 username, password string | 412 username, password string |
373 » err error | 413 » ok bool |
374 }{ | 414 }{ |
375 » {"Aladdin", "open sesame", nil}, | 415 » {"Aladdin", "open sesame", true}, |
376 » {"Aladdin", "open:sesame", nil}, | 416 » {"Aladdin", "open:sesame", true}, |
377 » {"", "", nil}, | 417 » {"", "", true}, |
378 } | 418 } |
379 | 419 |
380 func TestGetBasicAuth(t *testing.T) { | 420 func TestGetBasicAuth(t *testing.T) { |
381 for _, tt := range getBasicAuthTests { | 421 for _, tt := range getBasicAuthTests { |
382 r, _ := NewRequest("GET", "http://example.com/", nil) | 422 r, _ := NewRequest("GET", "http://example.com/", nil) |
383 r.SetBasicAuth(tt.username, tt.password) | 423 r.SetBasicAuth(tt.username, tt.password) |
384 » » username, password, err := r.BasicAuth() | 424 » » username, password, ok := r.BasicAuth() |
385 » » if err != tt.err || username != tt.username || password != tt.pa
ssword { | 425 » » if ok != tt.ok || username != tt.username || password != tt.pass
word { |
386 » » » t.Errorf("BasicAuth() = %#v, want %#v", getBasicAuthTest
{username, password, err}, | 426 » » » t.Errorf("BasicAuth() = %#v, want %#v", getBasicAuthTest
{username, password, ok}, |
387 » » » » getBasicAuthTest{tt.username, tt.password, tt.er
r}) | 427 » » » » getBasicAuthTest{tt.username, tt.password, tt.ok
}) |
388 } | 428 } |
389 } | 429 } |
390 // Unauthenticated request. | 430 // Unauthenticated request. |
391 r, _ := NewRequest("GET", "http://example.com/", nil) | 431 r, _ := NewRequest("GET", "http://example.com/", nil) |
392 » username, password, err := r.BasicAuth() | 432 » username, password, ok := r.BasicAuth() |
393 » if err == nil { | 433 » if ok { |
394 » » t.Errorf("expected an error from BasicAuth when the request is u
nauthenticated") | 434 » » t.Errorf("expected false from BasicAuth when the request is unau
thenticated") |
395 } | 435 } |
396 want := basicAuthCredentialsTest{"", ""} | 436 want := basicAuthCredentialsTest{"", ""} |
397 if username != want.username || password != want.password { | 437 if username != want.username || password != want.password { |
398 t.Errorf("expected credentials: %#v when the request is unauthen
ticated, got %#v", | 438 t.Errorf("expected credentials: %#v when the request is unauthen
ticated, got %#v", |
399 want, basicAuthCredentialsTest{username, password}) | 439 want, basicAuthCredentialsTest{username, password}) |
400 } | 440 } |
401 } | 441 } |
402 | 442 |
403 var parseBasicAuthTests = []struct { | 443 var parseBasicAuthTests = []struct { |
404 header, username, password string | 444 header, username, password string |
405 » err error | 445 » ok bool |
406 }{ | 446 }{ |
407 » {"Basic " + base64.StdEncoding.EncodeToString([]byte("Aladdin:open sesam
e")), "Aladdin", "open sesame", nil}, | 447 » {"Basic " + base64.StdEncoding.EncodeToString([]byte("Aladdin:open sesam
e")), "Aladdin", "open sesame", true}, |
408 » {"Basic " + base64.StdEncoding.EncodeToString([]byte("Aladdin:open:sesam
e")), "Aladdin", "open:sesame", nil}, | 448 » {"Basic " + base64.StdEncoding.EncodeToString([]byte("Aladdin:open:sesam
e")), "Aladdin", "open:sesame", true}, |
409 » {"Basic " + base64.StdEncoding.EncodeToString([]byte(":")), "", "", nil}
, | 449 » {"Basic " + base64.StdEncoding.EncodeToString([]byte(":")), "", "", true
}, |
| 450 » {"Basic" + base64.StdEncoding.EncodeToString([]byte("Aladdin:open sesame
")), "", "", false}, |
| 451 » {base64.StdEncoding.EncodeToString([]byte("Aladdin:open sesame")), "", "
", false}, |
| 452 » {"Basic ", "", "", false}, |
| 453 » {"Basic Aladdin:open sesame", "", "", false}, |
| 454 » {`Digest username="Aladdin"`, "", "", false}, |
410 } | 455 } |
411 | 456 |
412 func TestParseBasicAuth(t *testing.T) { | 457 func TestParseBasicAuth(t *testing.T) { |
413 for _, tt := range parseBasicAuthTests { | 458 for _, tt := range parseBasicAuthTests { |
414 » » username, password, err := ParseBasicAuth(tt.header) | 459 » » r, _ := NewRequest("GET", "http://example.com/", nil) |
415 » » if err != tt.err || username != tt.username || password != tt.pa
ssword { | 460 » » r.Header.Set("Authorization", tt.header) |
416 » » » t.Errorf("ParseBasicAuth(%s) = %#v, want %#v", tt.header
, parseBasicAuthTest{username, password, err}, | 461 » » username, password, ok := r.BasicAuth() |
417 » » » » parseBasicAuthTest{tt.username, tt.password, tt.
err}) | 462 » » if ok != tt.ok || username != tt.username || password != tt.pass
word { |
418 » » } | 463 » » » t.Errorf("BasicAuth() = %#v, want %#v", getBasicAuthTest
{username, password, ok}, |
419 » } | 464 » » » » getBasicAuthTest{tt.username, tt.password, tt.ok
}) |
420 } | |
421 | |
422 var parseBasicAuthErrorTests = []struct { | |
423 » header, username, password, message string | |
424 }{ | |
425 » {"Basic" + base64.StdEncoding.EncodeToString([]byte("Aladdin:open sesame
")), "", "", "header malformed"}, | |
426 » {base64.StdEncoding.EncodeToString([]byte("Aladdin:open sesame")), "", "
", "missing authentication scheme"}, | |
427 » {"Basic ", "", "", "missing basic credentials"}, | |
428 » {"Basic Aladdin:open sesame", "", "", "basic credentials malformed base6
4"}, | |
429 » {`Digest username="Aladdin"`, "", "", "non Basic authentication scheme"}
, | |
430 } | |
431 | |
432 func TestParseBasicAuthErrors(t *testing.T) { | |
433 » for _, tt := range parseBasicAuthErrorTests { | |
434 » » username, password, err := ParseBasicAuth(tt.header) | |
435 » » if err == nil { | |
436 » » » t.Errorf("expected an error from ParseBasicAuth when %s"
, tt.message) | |
437 » » } | |
438 » » want := basicAuthCredentialsTest{"", ""} | |
439 » » if username != want.username || password != want.password { | |
440 » » » t.Errorf("expected credentials: %#v when %s, got %#v", w
ant, tt.message, | |
441 » » » » basicAuthCredentialsTest{username, password}) | |
442 } | 465 } |
443 } | 466 } |
444 } | 467 } |
445 | 468 |
446 type logWrites struct { | 469 type logWrites struct { |
447 t *testing.T | 470 t *testing.T |
448 dst *[]string | 471 dst *[]string |
449 } | 472 } |
450 | 473 |
451 func (l logWrites) WriteByte(c byte) error { | 474 func (l logWrites) WriteByte(c byte) error { |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
648 Connection: keep-alive | 671 Connection: keep-alive |
649 `) | 672 `) |
650 } | 673 } |
651 | 674 |
652 func BenchmarkReadRequestWrk(b *testing.B) { | 675 func BenchmarkReadRequestWrk(b *testing.B) { |
653 // wrk -t 1 -r 1 -c 1 http://localhost:8080/ | 676 // wrk -t 1 -r 1 -c 1 http://localhost:8080/ |
654 benchmarkReadRequest(b, `GET / HTTP/1.1 | 677 benchmarkReadRequest(b, `GET / HTTP/1.1 |
655 Host: localhost:8080 | 678 Host: localhost:8080 |
656 `) | 679 `) |
657 } | 680 } |
LEFT | RIGHT |