Home | History | Annotate | Download | only in httptest
      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 
      5 package httptest
      6 
      7 import (
      8 	"crypto/tls"
      9 	"io"
     10 	"io/ioutil"
     11 	"net/http"
     12 	"net/url"
     13 	"reflect"
     14 	"strings"
     15 	"testing"
     16 )
     17 
     18 func TestNewRequest(t *testing.T) {
     19 	tests := [...]struct {
     20 		method, uri string
     21 		body        io.Reader
     22 
     23 		want     *http.Request
     24 		wantBody string
     25 	}{
     26 		// Empty method means GET:
     27 		0: {
     28 			method: "",
     29 			uri:    "/",
     30 			body:   nil,
     31 			want: &http.Request{
     32 				Method:     "GET",
     33 				Host:       "example.com",
     34 				URL:        &url.URL{Path: "/"},
     35 				Header:     http.Header{},
     36 				Proto:      "HTTP/1.1",
     37 				ProtoMajor: 1,
     38 				ProtoMinor: 1,
     39 				RemoteAddr: "192.0.2.1:1234",
     40 				RequestURI: "/",
     41 			},
     42 			wantBody: "",
     43 		},
     44 
     45 		// GET with full URL:
     46 		1: {
     47 			method: "GET",
     48 			uri:    "http://foo.com/path/%2f/bar/",
     49 			body:   nil,
     50 			want: &http.Request{
     51 				Method: "GET",
     52 				Host:   "foo.com",
     53 				URL: &url.URL{
     54 					Scheme:  "http",
     55 					Path:    "/path///bar/",
     56 					RawPath: "/path/%2f/bar/",
     57 					Host:    "foo.com",
     58 				},
     59 				Header:     http.Header{},
     60 				Proto:      "HTTP/1.1",
     61 				ProtoMajor: 1,
     62 				ProtoMinor: 1,
     63 				RemoteAddr: "192.0.2.1:1234",
     64 				RequestURI: "http://foo.com/path/%2f/bar/",
     65 			},
     66 			wantBody: "",
     67 		},
     68 
     69 		// GET with full https URL:
     70 		2: {
     71 			method: "GET",
     72 			uri:    "https://foo.com/path/",
     73 			body:   nil,
     74 			want: &http.Request{
     75 				Method: "GET",
     76 				Host:   "foo.com",
     77 				URL: &url.URL{
     78 					Scheme: "https",
     79 					Path:   "/path/",
     80 					Host:   "foo.com",
     81 				},
     82 				Header:     http.Header{},
     83 				Proto:      "HTTP/1.1",
     84 				ProtoMajor: 1,
     85 				ProtoMinor: 1,
     86 				RemoteAddr: "192.0.2.1:1234",
     87 				RequestURI: "https://foo.com/path/",
     88 				TLS: &tls.ConnectionState{
     89 					Version:           tls.VersionTLS12,
     90 					HandshakeComplete: true,
     91 					ServerName:        "foo.com",
     92 				},
     93 			},
     94 			wantBody: "",
     95 		},
     96 
     97 		// Post with known length
     98 		3: {
     99 			method: "POST",
    100 			uri:    "/",
    101 			body:   strings.NewReader("foo"),
    102 			want: &http.Request{
    103 				Method:        "POST",
    104 				Host:          "example.com",
    105 				URL:           &url.URL{Path: "/"},
    106 				Header:        http.Header{},
    107 				Proto:         "HTTP/1.1",
    108 				ContentLength: 3,
    109 				ProtoMajor:    1,
    110 				ProtoMinor:    1,
    111 				RemoteAddr:    "192.0.2.1:1234",
    112 				RequestURI:    "/",
    113 			},
    114 			wantBody: "foo",
    115 		},
    116 
    117 		// Post with unknown length
    118 		4: {
    119 			method: "POST",
    120 			uri:    "/",
    121 			body:   struct{ io.Reader }{strings.NewReader("foo")},
    122 			want: &http.Request{
    123 				Method:        "POST",
    124 				Host:          "example.com",
    125 				URL:           &url.URL{Path: "/"},
    126 				Header:        http.Header{},
    127 				Proto:         "HTTP/1.1",
    128 				ContentLength: -1,
    129 				ProtoMajor:    1,
    130 				ProtoMinor:    1,
    131 				RemoteAddr:    "192.0.2.1:1234",
    132 				RequestURI:    "/",
    133 			},
    134 			wantBody: "foo",
    135 		},
    136 
    137 		// OPTIONS *
    138 		5: {
    139 			method: "OPTIONS",
    140 			uri:    "*",
    141 			want: &http.Request{
    142 				Method:     "OPTIONS",
    143 				Host:       "example.com",
    144 				URL:        &url.URL{Path: "*"},
    145 				Header:     http.Header{},
    146 				Proto:      "HTTP/1.1",
    147 				ProtoMajor: 1,
    148 				ProtoMinor: 1,
    149 				RemoteAddr: "192.0.2.1:1234",
    150 				RequestURI: "*",
    151 			},
    152 		},
    153 	}
    154 	for i, tt := range tests {
    155 		got := NewRequest(tt.method, tt.uri, tt.body)
    156 		slurp, err := ioutil.ReadAll(got.Body)
    157 		if err != nil {
    158 			t.Errorf("%d. ReadAll: %v", i, err)
    159 		}
    160 		if string(slurp) != tt.wantBody {
    161 			t.Errorf("%d. Body = %q; want %q", i, slurp, tt.wantBody)
    162 		}
    163 		got.Body = nil // before DeepEqual
    164 		if !reflect.DeepEqual(got.URL, tt.want.URL) {
    165 			t.Errorf("%d. Request.URL mismatch:\n got: %#v\nwant: %#v", i, got.URL, tt.want.URL)
    166 		}
    167 		if !reflect.DeepEqual(got.Header, tt.want.Header) {
    168 			t.Errorf("%d. Request.Header mismatch:\n got: %#v\nwant: %#v", i, got.Header, tt.want.Header)
    169 		}
    170 		if !reflect.DeepEqual(got.TLS, tt.want.TLS) {
    171 			t.Errorf("%d. Request.TLS mismatch:\n got: %#v\nwant: %#v", i, got.TLS, tt.want.TLS)
    172 		}
    173 		if !reflect.DeepEqual(got, tt.want) {
    174 			t.Errorf("%d. Request mismatch:\n got: %#v\nwant: %#v", i, got, tt.want)
    175 		}
    176 	}
    177 }
    178