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.
5 // Implementation of Server
20 // A Server is an HTTP server listening on a system-chosen port on the
21 // local loopback interface, for use in end-to-end HTTP tests.
23 URL string // base URL of form http://ipaddr:port with no trailing slash
25 TLS *tls.Config // nil if not using using TLS
27 // Config may be changed after calling NewUnstartedServer and
28 // before Start or StartTLS.
32 // historyListener keeps track of all connections that it's ever
34 type historyListener struct {
39 func (hs *historyListener) Accept() (c net.Conn, err error) {
40 c, err = hs.Listener.Accept()
42 hs.history = append(hs.history, c)
47 func newLocalListener() net.Listener {
49 l, err := net.Listen("tcp", *serve)
51 panic(fmt.Sprintf("httptest: failed to listen on %v: %v", *serve, err))
55 l, err := net.Listen("tcp", "127.0.0.1:0")
57 if l, err = net.Listen("tcp6", "[::1]:0"); err != nil {
58 panic(fmt.Sprintf("httptest: failed to listen on a port: %v", err))
64 // When debugging a particular http server-based test,
65 // this flag lets you run
66 // gotest -run=BrokenTest -httptest.serve=127.0.0.1:8000
67 // to start the broken server so you can interact with it manually.
68 var serve = flag.String("httptest.serve", "", "if non-empty, httptest.NewServer serves on this address and blocks")
70 // NewServer starts and returns a new Server.
71 // The caller should call Close when finished, to shut it down.
72 func NewServer(handler http.Handler) *Server {
73 ts := NewUnstartedServer(handler)
78 // NewUnstartedServer returns a new Server but doesn't start it.
80 // After changing its configuration, the caller should call Start or
83 // The caller should call Close when finished, to shut it down.
84 func NewUnstartedServer(handler http.Handler) *Server {
86 Listener: newLocalListener(),
87 Config: &http.Server{Handler: handler},
91 // Start starts a server from NewUnstartedServer.
92 func (s *Server) Start() {
94 panic("Server already started")
96 s.Listener = &historyListener{s.Listener, make([]net.Conn, 0)}
97 s.URL = "http://" + s.Listener.Addr().String()
98 go s.Config.Serve(s.Listener)
100 fmt.Println(os.Stderr, "httptest: serving on", s.URL)
105 // StartTLS starts TLS on a server from NewUnstartedServer.
106 func (s *Server) StartTLS() {
108 panic("Server already started")
110 cert, err := tls.X509KeyPair(localhostCert, localhostKey)
112 panic(fmt.Sprintf("httptest: NewTLSServer: %v", err))
118 NextProtos: []string{"http/1.1"},
119 Certificates: []tls.Certificate{cert},
121 tlsListener := tls.NewListener(s.Listener, s.TLS)
123 s.Listener = &historyListener{tlsListener, make([]net.Conn, 0)}
124 s.URL = "https://" + s.Listener.Addr().String()
125 go s.Config.Serve(s.Listener)
128 // NewTLSServer starts and returns a new Server using TLS.
129 // The caller should call Close when finished, to shut it down.
130 func NewTLSServer(handler http.Handler) *Server {
131 ts := NewUnstartedServer(handler)
136 // Close shuts down the server.
137 func (s *Server) Close() {
141 // CloseClientConnections closes any currently open HTTP connections
142 // to the test Server.
143 func (s *Server) CloseClientConnections() {
144 hl, ok := s.Listener.(*historyListener)
148 for _, conn := range hl.history {
153 // localhostCert is a PEM-encoded TLS cert with SAN DNS names
154 // "127.0.0.1" and "[::1]", expiring at the last second of 2049 (the end
156 var localhostCert = []byte(`-----BEGIN CERTIFICATE-----
157 MIIBOTCB5qADAgECAgEAMAsGCSqGSIb3DQEBBTAAMB4XDTcwMDEwMTAwMDAwMFoX
158 DTQ5MTIzMTIzNTk1OVowADBaMAsGCSqGSIb3DQEBAQNLADBIAkEAsuA5mAFMj6Q7
159 qoBzcvKzIq4kzuT5epSp2AkcQfyBHm7K13Ws7u+0b5Vb9gqTf5cAiIKcrtrXVqkL
160 8i1UQF6AzwIDAQABo08wTTAOBgNVHQ8BAf8EBAMCACQwDQYDVR0OBAYEBAECAwQw
161 DwYDVR0jBAgwBoAEAQIDBDAbBgNVHREEFDASggkxMjcuMC4wLjGCBVs6OjFdMAsG
162 CSqGSIb3DQEBBQNBAJH30zjLWRztrWpOCgJL8RQWLaKzhK79pVhAx6q/3NrF16C7
163 +l1BRZstTwIGdoGId8BRpErK1TXkniFb95ZMynM=
164 -----END CERTIFICATE-----
167 // localhostKey is the private key for localhostCert.
168 var localhostKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
169 MIIBPQIBAAJBALLgOZgBTI+kO6qAc3LysyKuJM7k+XqUqdgJHEH8gR5uytd1rO7v
170 tG+VW/YKk3+XAIiCnK7a11apC/ItVEBegM8CAwEAAQJBAI5sxq7naeR9ahyqRkJi
171 SIv2iMxLuPEHaezf5CYOPWjSjBPyVhyRevkhtqEjF/WkgL7C2nWpYHsUcBDBQVF0
172 3KECIQDtEGB2ulnkZAahl3WuJziXGLB+p8Wgx7wzSM6bHu1c6QIhAMEp++CaS+SJ
173 /TrU0zwY/fW4SvQeb49BPZUF3oqR8Xz3AiEA1rAJHBzBgdOQKdE3ksMUPcnvNJSN
174 poCcELmz2clVXtkCIQCLytuLV38XHToTipR4yMl6O+6arzAjZ56uq7m7ZRV0TwIh
175 AM65XAOw8Dsg9Kq78aYXiOEDc5DL0sbFUu/SlmRcCg93
176 -----END RSA PRIVATE KEY-----