Source file src/net/http/httptest/httptest.go
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 provides utilities for HTTP testing. 6 package httptest 7 8 import ( 9 "bufio" 10 "bytes" 11 "crypto/tls" 12 "io" 13 "net/http" 14 "strings" 15 ) 16 17 // NewRequest returns a new incoming server Request, suitable 18 // for passing to an http.Handler for testing. 19 // 20 // The target is the RFC 7230 "request-target": it may be either a 21 // path or an absolute URL. If target is an absolute URL, the host name 22 // from the URL is used. Otherwise, "example.com" is used. 23 // 24 // The TLS field is set to a non-nil dummy value if target has scheme 25 // "https". 26 // 27 // The Request.Proto is always HTTP/1.1. 28 // 29 // An empty method means "GET". 30 // 31 // The provided body may be nil. If the body is of type *bytes.Reader, 32 // *strings.Reader, or *bytes.Buffer, the Request.ContentLength is 33 // set. 34 // 35 // NewRequest panics on error for ease of use in testing, where a 36 // panic is acceptable. 37 // 38 // To generate a client HTTP request instead of a server request, see 39 // the NewRequest function in the net/http package. 40 func NewRequest(method, target string, body io.Reader) *http.Request { 41 if method == "" { 42 method = "GET" 43 } 44 req, err := http.ReadRequest(bufio.NewReader(strings.NewReader(method + " " + target + " HTTP/1.0\r\n\r\n"))) 45 if err != nil { 46 panic("invalid NewRequest arguments; " + err.Error()) 47 } 48 49 // HTTP/1.0 was used above to avoid needing a Host field. Change it to 1.1 here. 50 req.Proto = "HTTP/1.1" 51 req.ProtoMinor = 1 52 req.Close = false 53 54 if body != nil { 55 switch v := body.(type) { 56 case *bytes.Buffer: 57 req.ContentLength = int64(v.Len()) 58 case *bytes.Reader: 59 req.ContentLength = int64(v.Len()) 60 case *strings.Reader: 61 req.ContentLength = int64(v.Len()) 62 default: 63 req.ContentLength = -1 64 } 65 if rc, ok := body.(io.ReadCloser); ok { 66 req.Body = rc 67 } else { 68 req.Body = io.NopCloser(body) 69 } 70 } 71 72 // 192.0.2.0/24 is "TEST-NET" in RFC 5737 for use solely in 73 // documentation and example source code and should not be 74 // used publicly. 75 req.RemoteAddr = "192.0.2.1:1234" 76 77 if req.Host == "" { 78 req.Host = "example.com" 79 } 80 81 if strings.HasPrefix(target, "https://") { 82 req.TLS = &tls.ConnectionState{ 83 Version: tls.VersionTLS12, 84 HandshakeComplete: true, 85 ServerName: req.Host, 86 } 87 } 88 89 return req 90 } 91