LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 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 // Implementation of Server | 5 // Implementation of Server |
6 | 6 |
7 package httptest | 7 package httptest |
8 | 8 |
9 import ( | 9 import ( |
10 "crypto/tls" | 10 "crypto/tls" |
(...skipping 18 matching lines...) Expand all Loading... |
29 | 29 |
30 // wg counts the number of outstanding HTTP requests on this server. | 30 // wg counts the number of outstanding HTTP requests on this server. |
31 // Close blocks until all requests are finished. | 31 // Close blocks until all requests are finished. |
32 wg sync.WaitGroup | 32 wg sync.WaitGroup |
33 } | 33 } |
34 | 34 |
35 // historyListener keeps track of all connections that it's ever | 35 // historyListener keeps track of all connections that it's ever |
36 // accepted. | 36 // accepted. |
37 type historyListener struct { | 37 type historyListener struct { |
38 net.Listener | 38 net.Listener |
39 » history []net.Conn | 39 » sync.Mutex // protects history |
| 40 » history []net.Conn |
40 } | 41 } |
41 | 42 |
42 func (hs *historyListener) Accept() (c net.Conn, err error) { | 43 func (hs *historyListener) Accept() (c net.Conn, err error) { |
43 c, err = hs.Listener.Accept() | 44 c, err = hs.Listener.Accept() |
44 if err == nil { | 45 if err == nil { |
| 46 hs.Lock() |
45 hs.history = append(hs.history, c) | 47 hs.history = append(hs.history, c) |
| 48 hs.Unlock() |
46 } | 49 } |
47 return | 50 return |
48 } | 51 } |
49 | 52 |
50 func newLocalListener() net.Listener { | 53 func newLocalListener() net.Listener { |
51 if *serve != "" { | 54 if *serve != "" { |
52 l, err := net.Listen("tcp", *serve) | 55 l, err := net.Listen("tcp", *serve) |
53 if err != nil { | 56 if err != nil { |
54 panic(fmt.Sprintf("httptest: failed to listen on %v: %v"
, *serve, err)) | 57 panic(fmt.Sprintf("httptest: failed to listen on %v: %v"
, *serve, err)) |
55 } | 58 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 Listener: newLocalListener(), | 92 Listener: newLocalListener(), |
90 Config: &http.Server{Handler: handler}, | 93 Config: &http.Server{Handler: handler}, |
91 } | 94 } |
92 } | 95 } |
93 | 96 |
94 // Start starts a server from NewUnstartedServer. | 97 // Start starts a server from NewUnstartedServer. |
95 func (s *Server) Start() { | 98 func (s *Server) Start() { |
96 if s.URL != "" { | 99 if s.URL != "" { |
97 panic("Server already started") | 100 panic("Server already started") |
98 } | 101 } |
99 » s.Listener = &historyListener{s.Listener, make([]net.Conn, 0)} | 102 » s.Listener = &historyListener{Listener: s.Listener} |
100 s.URL = "http://" + s.Listener.Addr().String() | 103 s.URL = "http://" + s.Listener.Addr().String() |
101 s.wrapHandler() | 104 s.wrapHandler() |
102 go s.Config.Serve(s.Listener) | 105 go s.Config.Serve(s.Listener) |
103 if *serve != "" { | 106 if *serve != "" { |
104 fmt.Fprintln(os.Stderr, "httptest: serving on", s.URL) | 107 fmt.Fprintln(os.Stderr, "httptest: serving on", s.URL) |
105 select {} | 108 select {} |
106 } | 109 } |
107 } | 110 } |
108 | 111 |
109 // StartTLS starts TLS on a server from NewUnstartedServer. | 112 // StartTLS starts TLS on a server from NewUnstartedServer. |
110 func (s *Server) StartTLS() { | 113 func (s *Server) StartTLS() { |
111 if s.URL != "" { | 114 if s.URL != "" { |
112 panic("Server already started") | 115 panic("Server already started") |
113 } | 116 } |
114 cert, err := tls.X509KeyPair(localhostCert, localhostKey) | 117 cert, err := tls.X509KeyPair(localhostCert, localhostKey) |
115 if err != nil { | 118 if err != nil { |
116 panic(fmt.Sprintf("httptest: NewTLSServer: %v", err)) | 119 panic(fmt.Sprintf("httptest: NewTLSServer: %v", err)) |
117 } | 120 } |
118 | 121 |
119 s.TLS = &tls.Config{ | 122 s.TLS = &tls.Config{ |
120 NextProtos: []string{"http/1.1"}, | 123 NextProtos: []string{"http/1.1"}, |
121 Certificates: []tls.Certificate{cert}, | 124 Certificates: []tls.Certificate{cert}, |
122 } | 125 } |
123 tlsListener := tls.NewListener(s.Listener, s.TLS) | 126 tlsListener := tls.NewListener(s.Listener, s.TLS) |
124 | 127 |
125 » s.Listener = &historyListener{tlsListener, make([]net.Conn, 0)} | 128 » s.Listener = &historyListener{Listener: tlsListener} |
126 s.URL = "https://" + s.Listener.Addr().String() | 129 s.URL = "https://" + s.Listener.Addr().String() |
127 s.wrapHandler() | 130 s.wrapHandler() |
128 go s.Config.Serve(s.Listener) | 131 go s.Config.Serve(s.Listener) |
129 } | 132 } |
130 | 133 |
131 func (s *Server) wrapHandler() { | 134 func (s *Server) wrapHandler() { |
132 h := s.Config.Handler | 135 h := s.Config.Handler |
133 if h == nil { | 136 if h == nil { |
134 h = http.DefaultServeMux | 137 h = http.DefaultServeMux |
135 } | 138 } |
(...skipping 18 matching lines...) Expand all Loading... |
154 s.wg.Wait() | 157 s.wg.Wait() |
155 } | 158 } |
156 | 159 |
157 // CloseClientConnections closes any currently open HTTP connections | 160 // CloseClientConnections closes any currently open HTTP connections |
158 // to the test Server. | 161 // to the test Server. |
159 func (s *Server) CloseClientConnections() { | 162 func (s *Server) CloseClientConnections() { |
160 hl, ok := s.Listener.(*historyListener) | 163 hl, ok := s.Listener.(*historyListener) |
161 if !ok { | 164 if !ok { |
162 return | 165 return |
163 } | 166 } |
| 167 hl.Lock() |
164 for _, conn := range hl.history { | 168 for _, conn := range hl.history { |
165 conn.Close() | 169 conn.Close() |
166 } | 170 } |
| 171 hl.Unlock() |
167 } | 172 } |
168 | 173 |
169 // waitGroupHandler wraps a handler, incrementing and decrementing a | 174 // waitGroupHandler wraps a handler, incrementing and decrementing a |
170 // sync.WaitGroup on each request, to enable Server.Close to block | 175 // sync.WaitGroup on each request, to enable Server.Close to block |
171 // until outstanding requests are finished. | 176 // until outstanding requests are finished. |
172 type waitGroupHandler struct { | 177 type waitGroupHandler struct { |
173 s *Server | 178 s *Server |
174 h http.Handler // non-nil | 179 h http.Handler // non-nil |
175 } | 180 } |
176 | 181 |
(...skipping 21 matching lines...) Expand all Loading... |
198 var localhostKey = []byte(`-----BEGIN RSA PRIVATE KEY----- | 203 var localhostKey = []byte(`-----BEGIN RSA PRIVATE KEY----- |
199 MIIBPQIBAAJBALLgOZgBTI+kO6qAc3LysyKuJM7k+XqUqdgJHEH8gR5uytd1rO7v | 204 MIIBPQIBAAJBALLgOZgBTI+kO6qAc3LysyKuJM7k+XqUqdgJHEH8gR5uytd1rO7v |
200 tG+VW/YKk3+XAIiCnK7a11apC/ItVEBegM8CAwEAAQJBAI5sxq7naeR9ahyqRkJi | 205 tG+VW/YKk3+XAIiCnK7a11apC/ItVEBegM8CAwEAAQJBAI5sxq7naeR9ahyqRkJi |
201 SIv2iMxLuPEHaezf5CYOPWjSjBPyVhyRevkhtqEjF/WkgL7C2nWpYHsUcBDBQVF0 | 206 SIv2iMxLuPEHaezf5CYOPWjSjBPyVhyRevkhtqEjF/WkgL7C2nWpYHsUcBDBQVF0 |
202 3KECIQDtEGB2ulnkZAahl3WuJziXGLB+p8Wgx7wzSM6bHu1c6QIhAMEp++CaS+SJ | 207 3KECIQDtEGB2ulnkZAahl3WuJziXGLB+p8Wgx7wzSM6bHu1c6QIhAMEp++CaS+SJ |
203 /TrU0zwY/fW4SvQeb49BPZUF3oqR8Xz3AiEA1rAJHBzBgdOQKdE3ksMUPcnvNJSN | 208 /TrU0zwY/fW4SvQeb49BPZUF3oqR8Xz3AiEA1rAJHBzBgdOQKdE3ksMUPcnvNJSN |
204 poCcELmz2clVXtkCIQCLytuLV38XHToTipR4yMl6O+6arzAjZ56uq7m7ZRV0TwIh | 209 poCcELmz2clVXtkCIQCLytuLV38XHToTipR4yMl6O+6arzAjZ56uq7m7ZRV0TwIh |
205 AM65XAOw8Dsg9Kq78aYXiOEDc5DL0sbFUu/SlmRcCg93 | 210 AM65XAOw8Dsg9Kq78aYXiOEDc5DL0sbFUu/SlmRcCg93 |
206 -----END RSA PRIVATE KEY----- | 211 -----END RSA PRIVATE KEY----- |
207 `) | 212 `) |
LEFT | RIGHT |