github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/net/http/httputil/dump_test.go (about)

     1  // Copyright 2011 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 httputil
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"io"
    11  	"io/ioutil"
    12  	"net/http"
    13  	"net/url"
    14  	"testing"
    15  )
    16  
    17  type dumpTest struct {
    18  	Req  http.Request
    19  	Body interface{} // optional []byte or func() io.ReadCloser to populate Req.Body
    20  
    21  	WantDump    string
    22  	WantDumpOut string
    23  }
    24  
    25  var dumpTests = []dumpTest{
    26  
    27  	// HTTP/1.1 => chunked coding; body; empty trailer
    28  	{
    29  		Req: http.Request{
    30  			Method: "GET",
    31  			URL: &url.URL{
    32  				Scheme: "http",
    33  				Host:   "www.google.com",
    34  				Path:   "/search",
    35  			},
    36  			ProtoMajor:       1,
    37  			ProtoMinor:       1,
    38  			TransferEncoding: []string{"chunked"},
    39  		},
    40  
    41  		Body: []byte("abcdef"),
    42  
    43  		WantDump: "GET /search HTTP/1.1\r\n" +
    44  			"Host: www.google.com\r\n" +
    45  			"Transfer-Encoding: chunked\r\n\r\n" +
    46  			chunk("abcdef") + chunk(""),
    47  	},
    48  
    49  	// Verify that DumpRequest preserves the HTTP version number, doesn't add a Host,
    50  	// and doesn't add a User-Agent.
    51  	{
    52  		Req: http.Request{
    53  			Method:     "GET",
    54  			URL:        mustParseURL("/foo"),
    55  			ProtoMajor: 1,
    56  			ProtoMinor: 0,
    57  			Header: http.Header{
    58  				"X-Foo": []string{"X-Bar"},
    59  			},
    60  		},
    61  
    62  		WantDump: "GET /foo HTTP/1.0\r\n" +
    63  			"X-Foo: X-Bar\r\n\r\n",
    64  	},
    65  
    66  	{
    67  		Req: *mustNewRequest("GET", "http://example.com/foo", nil),
    68  
    69  		WantDumpOut: "GET /foo HTTP/1.1\r\n" +
    70  			"Host: example.com\r\n" +
    71  			"User-Agent: Go 1.1 package http\r\n" +
    72  			"Accept-Encoding: gzip\r\n\r\n",
    73  	},
    74  
    75  	// Test that an https URL doesn't try to do an SSL negotiation
    76  	// with a bytes.Buffer and hang with all goroutines not
    77  	// runnable.
    78  	{
    79  		Req: *mustNewRequest("GET", "https://example.com/foo", nil),
    80  
    81  		WantDumpOut: "GET /foo HTTP/1.1\r\n" +
    82  			"Host: example.com\r\n" +
    83  			"User-Agent: Go 1.1 package http\r\n" +
    84  			"Accept-Encoding: gzip\r\n\r\n",
    85  	},
    86  }
    87  
    88  func TestDumpRequest(t *testing.T) {
    89  	for i, tt := range dumpTests {
    90  		setBody := func() {
    91  			if tt.Body == nil {
    92  				return
    93  			}
    94  			switch b := tt.Body.(type) {
    95  			case []byte:
    96  				tt.Req.Body = ioutil.NopCloser(bytes.NewBuffer(b))
    97  			case func() io.ReadCloser:
    98  				tt.Req.Body = b()
    99  			}
   100  		}
   101  		setBody()
   102  		if tt.Req.Header == nil {
   103  			tt.Req.Header = make(http.Header)
   104  		}
   105  
   106  		if tt.WantDump != "" {
   107  			setBody()
   108  			dump, err := DumpRequest(&tt.Req, true)
   109  			if err != nil {
   110  				t.Errorf("DumpRequest #%d: %s", i, err)
   111  				continue
   112  			}
   113  			if string(dump) != tt.WantDump {
   114  				t.Errorf("DumpRequest %d, expecting:\n%s\nGot:\n%s\n", i, tt.WantDump, string(dump))
   115  				continue
   116  			}
   117  		}
   118  
   119  		if tt.WantDumpOut != "" {
   120  			setBody()
   121  			dump, err := DumpRequestOut(&tt.Req, true)
   122  			if err != nil {
   123  				t.Errorf("DumpRequestOut #%d: %s", i, err)
   124  				continue
   125  			}
   126  			if string(dump) != tt.WantDumpOut {
   127  				t.Errorf("DumpRequestOut %d, expecting:\n%s\nGot:\n%s\n", i, tt.WantDumpOut, string(dump))
   128  				continue
   129  			}
   130  		}
   131  	}
   132  }
   133  
   134  func chunk(s string) string {
   135  	return fmt.Sprintf("%x\r\n%s\r\n", len(s), s)
   136  }
   137  
   138  func mustParseURL(s string) *url.URL {
   139  	u, err := url.Parse(s)
   140  	if err != nil {
   141  		panic(fmt.Sprintf("Error parsing URL %q: %v", s, err))
   142  	}
   143  	return u
   144  }
   145  
   146  func mustNewRequest(method, url string, body io.Reader) *http.Request {
   147  	req, err := http.NewRequest(method, url, body)
   148  	if err != nil {
   149  		panic(fmt.Sprintf("NewRequest(%q, %q, %p) err = %v", method, url, body, err))
   150  	}
   151  	return req
   152  }