Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(663)

Delta Between Two Patch Sets: src/pkg/net/http/httptest/server.go

Issue 6845077: code review 6845077: net/http/httptest: fix possible race on historyListener... (Closed)
Left Patch Set: Created 11 years, 3 months ago
Right Patch Set: diff -r 74b1ad92a812 https://code.google.com/p/go Created 11 years, 3 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(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
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
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
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
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 `)
LEFTRIGHT
« no previous file | no next file » | Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Toggle Comments ('s')

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b