OSDN Git Service

libgo: Update to weekly 2011-11-09.
[pf3gnuchains/gcc-fork.git] / libgo / go / net / http / httptest / server.go
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 // Implementation of Server
6
7 package httptest
8
9 import (
10         "crypto/rand"
11         "crypto/tls"
12         "flag"
13         "fmt"
14         "net"
15         "net/http"
16         "os"
17         "time"
18 )
19
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.
22 type Server struct {
23         URL      string // base URL of form http://ipaddr:port with no trailing slash
24         Listener net.Listener
25         TLS      *tls.Config // nil if not using using TLS
26
27         // Config may be changed after calling NewUnstartedServer and
28         // before Start or StartTLS.
29         Config *http.Server
30 }
31
32 // historyListener keeps track of all connections that it's ever
33 // accepted.
34 type historyListener struct {
35         net.Listener
36         history []net.Conn
37 }
38
39 func (hs *historyListener) Accept() (c net.Conn, err error) {
40         c, err = hs.Listener.Accept()
41         if err == nil {
42                 hs.history = append(hs.history, c)
43         }
44         return
45 }
46
47 func newLocalListener() net.Listener {
48         if *serve != "" {
49                 l, err := net.Listen("tcp", *serve)
50                 if err != nil {
51                         panic(fmt.Sprintf("httptest: failed to listen on %v: %v", *serve, err))
52                 }
53                 return l
54         }
55         l, err := net.Listen("tcp", "127.0.0.1:0")
56         if err != nil {
57                 if l, err = net.Listen("tcp6", "[::1]:0"); err != nil {
58                         panic(fmt.Sprintf("httptest: failed to listen on a port: %v", err))
59                 }
60         }
61         return l
62 }
63
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")
69
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)
74         ts.Start()
75         return ts
76 }
77
78 // NewUnstartedServer returns a new Server but doesn't start it.
79 //
80 // After changing its configuration, the caller should call Start or
81 // StartTLS.
82 //
83 // The caller should call Close when finished, to shut it down.
84 func NewUnstartedServer(handler http.Handler) *Server {
85         return &Server{
86                 Listener: newLocalListener(),
87                 Config:   &http.Server{Handler: handler},
88         }
89 }
90
91 // Start starts a server from NewUnstartedServer.
92 func (s *Server) Start() {
93         if s.URL != "" {
94                 panic("Server already started")
95         }
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)
99         if *serve != "" {
100                 fmt.Println(os.Stderr, "httptest: serving on", s.URL)
101                 select {}
102         }
103 }
104
105 // StartTLS starts TLS on a server from NewUnstartedServer.
106 func (s *Server) StartTLS() {
107         if s.URL != "" {
108                 panic("Server already started")
109         }
110         cert, err := tls.X509KeyPair(localhostCert, localhostKey)
111         if err != nil {
112                 panic(fmt.Sprintf("httptest: NewTLSServer: %v", err))
113         }
114
115         s.TLS = &tls.Config{
116                 Rand:         rand.Reader,
117                 Time:         time.Seconds,
118                 NextProtos:   []string{"http/1.1"},
119                 Certificates: []tls.Certificate{cert},
120         }
121         tlsListener := tls.NewListener(s.Listener, s.TLS)
122
123         s.Listener = &historyListener{tlsListener, make([]net.Conn, 0)}
124         s.URL = "https://" + s.Listener.Addr().String()
125         go s.Config.Serve(s.Listener)
126 }
127
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)
132         ts.StartTLS()
133         return ts
134 }
135
136 // Close shuts down the server.
137 func (s *Server) Close() {
138         s.Listener.Close()
139 }
140
141 // CloseClientConnections closes any currently open HTTP connections
142 // to the test Server.
143 func (s *Server) CloseClientConnections() {
144         hl, ok := s.Listener.(*historyListener)
145         if !ok {
146                 return
147         }
148         for _, conn := range hl.history {
149                 conn.Close()
150         }
151 }
152
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
155 // of ASN.1 time).
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-----
165 `)
166
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-----
177 `)