644724f58e6cc2d3388c4db86c704ea2725d2c8a
[platform/upstream/gcc.git] / libgo / go / http / server.go
1 // Copyright 2009 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 // HTTP server.  See RFC 2616.
6
7 // TODO(rsc):
8 //      logging
9 //      cgi support
10 //      post support
11
12 package http
13
14 import (
15         "bufio"
16         "crypto/rand"
17         "crypto/tls"
18         "fmt"
19         "io"
20         "log"
21         "net"
22         "os"
23         "path"
24         "strconv"
25         "strings"
26         "time"
27 )
28
29 // Errors introduced by the HTTP server.
30 var (
31         ErrWriteAfterFlush = os.NewError("Conn.Write called after Flush")
32         ErrBodyNotAllowed  = os.NewError("http: response status code does not allow body")
33         ErrHijacked        = os.NewError("Conn has been hijacked")
34 )
35
36 // Objects implementing the Handler interface can be
37 // registered to serve a particular path or subtree
38 // in the HTTP server.
39 //
40 // ServeHTTP should write reply headers and data to the ResponseWriter
41 // and then return.  Returning signals that the request is finished
42 // and that the HTTP server can move on to the next request on
43 // the connection.
44 type Handler interface {
45         ServeHTTP(ResponseWriter, *Request)
46 }
47
48 // A ResponseWriter interface is used by an HTTP handler to
49 // construct an HTTP response.
50 type ResponseWriter interface {
51         // RemoteAddr returns the address of the client that sent the current request
52         RemoteAddr() string
53
54         // UsingTLS returns true if the client is connected using TLS
55         UsingTLS() bool
56
57         // SetHeader sets a header line in the eventual response.
58         // For example, SetHeader("Content-Type", "text/html; charset=utf-8")
59         // will result in the header line
60         //
61         //      Content-Type: text/html; charset=utf-8
62         //
63         // being sent.  UTF-8 encoded HTML is the default setting for
64         // Content-Type in this library, so users need not make that
65         // particular call.  Calls to SetHeader after WriteHeader (or Write)
66         // are ignored.
67         SetHeader(string, string)
68
69         // Write writes the data to the connection as part of an HTTP reply.
70         // If WriteHeader has not yet been called, Write calls WriteHeader(http.StatusOK)
71         // before writing the data.
72         Write([]byte) (int, os.Error)
73
74         // WriteHeader sends an HTTP response header with status code.
75         // If WriteHeader is not called explicitly, the first call to Write
76         // will trigger an implicit WriteHeader(http.StatusOK).
77         // Thus explicit calls to WriteHeader are mainly used to
78         // send error codes.
79         WriteHeader(int)
80
81         // Flush sends any buffered data to the client.
82         Flush()
83
84         // Hijack lets the caller take over the connection.
85         // After a call to Hijack(), the HTTP server library
86         // will not do anything else with the connection.
87         // It becomes the caller's responsibility to manage
88         // and close the connection.
89         Hijack() (io.ReadWriteCloser, *bufio.ReadWriter, os.Error)
90 }
91
92 // A conn represents the server side of an HTTP connection.
93 type conn struct {
94         remoteAddr string             // network address of remote side
95         handler    Handler            // request handler
96         rwc        io.ReadWriteCloser // i/o connection
97         buf        *bufio.ReadWriter  // buffered rwc
98         hijacked   bool               // connection has been hijacked by handler
99         usingTLS   bool               // a flag indicating connection over TLS
100 }
101
102 // A response represents the server side of an HTTP response.
103 type response struct {
104         conn          *conn
105         req           *Request          // request for this response
106         chunking      bool              // using chunked transfer encoding for reply body
107         wroteHeader   bool              // reply header has been written
108         wroteContinue bool              // 100 Continue response was written
109         header        map[string]string // reply header parameters
110         written       int64             // number of bytes written in body
111         status        int               // status code passed to WriteHeader
112
113         // close connection after this reply.  set on request and
114         // updated after response from handler if there's a
115         // "Connection: keep-alive" response header and a
116         // Content-Length.
117         closeAfterReply bool
118 }
119
120 // Create new connection from rwc.
121 func newConn(rwc net.Conn, handler Handler) (c *conn, err os.Error) {
122         c = new(conn)
123         c.remoteAddr = rwc.RemoteAddr().String()
124         c.handler = handler
125         c.rwc = rwc
126         _, c.usingTLS = rwc.(*tls.Conn)
127         br := bufio.NewReader(rwc)
128         bw := bufio.NewWriter(rwc)
129         c.buf = bufio.NewReadWriter(br, bw)
130         return c, nil
131 }
132
133 // wrapper around io.ReaderCloser which on first read, sends an
134 // HTTP/1.1 100 Continue header
135 type expectContinueReader struct {
136         resp       *response
137         readCloser io.ReadCloser
138 }
139
140 func (ecr *expectContinueReader) Read(p []byte) (n int, err os.Error) {
141         if !ecr.resp.wroteContinue && !ecr.resp.conn.hijacked {
142                 ecr.resp.wroteContinue = true
143                 io.WriteString(ecr.resp.conn.buf, "HTTP/1.1 100 Continue\r\n\r\n")
144                 ecr.resp.conn.buf.Flush()
145         }
146         return ecr.readCloser.Read(p)
147 }
148
149 func (ecr *expectContinueReader) Close() os.Error {
150         return ecr.readCloser.Close()
151 }
152
153 // TimeFormat is the time format to use with
154 // time.Parse and time.Time.Format when parsing
155 // or generating times in HTTP headers.
156 // It is like time.RFC1123 but hard codes GMT as the time zone.
157 const TimeFormat = "Mon, 02 Jan 2006 15:04:05 GMT"
158
159 // Read next request from connection.
160 func (c *conn) readRequest() (w *response, err os.Error) {
161         if c.hijacked {
162                 return nil, ErrHijacked
163         }
164         var req *Request
165         if req, err = ReadRequest(c.buf.Reader); err != nil {
166                 return nil, err
167         }
168
169         w = new(response)
170         w.conn = c
171         w.req = req
172         w.header = make(map[string]string)
173
174         // Expect 100 Continue support
175         if req.expectsContinue() && req.ProtoAtLeast(1, 1) {
176                 // Wrap the Body reader with one that replies on the connection
177                 req.Body = &expectContinueReader{readCloser: req.Body, resp: w}
178         }
179
180         // Default output is HTML encoded in UTF-8.
181         w.SetHeader("Content-Type", "text/html; charset=utf-8")
182         w.SetHeader("Date", time.UTC().Format(TimeFormat))
183
184         if req.Method == "HEAD" {
185                 // do nothing
186         } else if req.ProtoAtLeast(1, 1) {
187                 // HTTP/1.1 or greater: use chunked transfer encoding
188                 // to avoid closing the connection at EOF.
189                 w.chunking = true
190                 w.SetHeader("Transfer-Encoding", "chunked")
191         } else {
192                 // HTTP version < 1.1: cannot do chunked transfer
193                 // encoding, so signal EOF by closing connection.
194                 // Will be overridden if the HTTP handler ends up
195                 // writing a Content-Length and the client requested
196                 // "Connection: keep-alive"
197                 w.closeAfterReply = true
198         }
199
200         return w, nil
201 }
202
203 // UsingTLS implements the ResponseWriter.UsingTLS
204 func (w *response) UsingTLS() bool {
205         return w.conn.usingTLS
206 }
207
208 // RemoteAddr implements the ResponseWriter.RemoteAddr method
209 func (w *response) RemoteAddr() string { return w.conn.remoteAddr }
210
211 // SetHeader implements the ResponseWriter.SetHeader method
212 func (w *response) SetHeader(hdr, val string) { w.header[CanonicalHeaderKey(hdr)] = val }
213
214 // WriteHeader implements the ResponseWriter.WriteHeader method
215 func (w *response) WriteHeader(code int) {
216         if w.conn.hijacked {
217                 log.Print("http: response.WriteHeader on hijacked connection")
218                 return
219         }
220         if w.wroteHeader {
221                 log.Print("http: multiple response.WriteHeader calls")
222                 return
223         }
224         w.wroteHeader = true
225         w.status = code
226         if code == StatusNotModified {
227                 // Must not have body.
228                 w.header["Content-Type"] = "", false
229                 w.header["Transfer-Encoding"] = "", false
230                 w.chunking = false
231         }
232         // Cannot use Content-Length with non-identity Transfer-Encoding.
233         if w.chunking {
234                 w.header["Content-Length"] = "", false
235         }
236         if !w.req.ProtoAtLeast(1, 0) {
237                 return
238         }
239         proto := "HTTP/1.0"
240         if w.req.ProtoAtLeast(1, 1) {
241                 proto = "HTTP/1.1"
242         }
243         codestring := strconv.Itoa(code)
244         text, ok := statusText[code]
245         if !ok {
246                 text = "status code " + codestring
247         }
248         io.WriteString(w.conn.buf, proto+" "+codestring+" "+text+"\r\n")
249         for k, v := range w.header {
250                 io.WriteString(w.conn.buf, k+": "+v+"\r\n")
251         }
252         io.WriteString(w.conn.buf, "\r\n")
253 }
254
255 // Write implements the ResponseWriter.Write method
256 func (w *response) Write(data []byte) (n int, err os.Error) {
257         if w.conn.hijacked {
258                 log.Print("http: response.Write on hijacked connection")
259                 return 0, ErrHijacked
260         }
261         if !w.wroteHeader {
262                 if w.req.wantsHttp10KeepAlive() {
263                         _, hasLength := w.header["Content-Length"]
264                         if hasLength {
265                                 _, connectionHeaderSet := w.header["Connection"]
266                                 if !connectionHeaderSet {
267                                         w.header["Connection"] = "keep-alive"
268                                 }
269                         }
270                 }
271                 w.WriteHeader(StatusOK)
272         }
273         if len(data) == 0 {
274                 return 0, nil
275         }
276
277         if w.status == StatusNotModified || w.req.Method == "HEAD" {
278                 // Must not have body.
279                 return 0, ErrBodyNotAllowed
280         }
281
282         w.written += int64(len(data)) // ignoring errors, for errorKludge
283
284         // TODO(rsc): if chunking happened after the buffering,
285         // then there would be fewer chunk headers.
286         // On the other hand, it would make hijacking more difficult.
287         if w.chunking {
288                 fmt.Fprintf(w.conn.buf, "%x\r\n", len(data)) // TODO(rsc): use strconv not fmt
289         }
290         n, err = w.conn.buf.Write(data)
291         if err == nil && w.chunking {
292                 if n != len(data) {
293                         err = io.ErrShortWrite
294                 }
295                 if err == nil {
296                         io.WriteString(w.conn.buf, "\r\n")
297                 }
298         }
299
300         return n, err
301 }
302
303 // If this is an error reply (4xx or 5xx)
304 // and the handler wrote some data explaining the error,
305 // some browsers (i.e., Chrome, Internet Explorer)
306 // will show their own error instead unless the error is
307 // long enough.  The minimum lengths used in those
308 // browsers are in the 256-512 range.
309 // Pad to 1024 bytes.
310 func errorKludge(w *response) {
311         const min = 1024
312
313         // Is this an error?
314         if kind := w.status / 100; kind != 4 && kind != 5 {
315                 return
316         }
317
318         // Did the handler supply any info?  Enough?
319         if w.written == 0 || w.written >= min {
320                 return
321         }
322
323         // Is it a broken browser?
324         var msg string
325         switch agent := w.req.UserAgent; {
326         case strings.Contains(agent, "MSIE"):
327                 msg = "Internet Explorer"
328         case strings.Contains(agent, "Chrome/"):
329                 msg = "Chrome"
330         default:
331                 return
332         }
333         msg += " would ignore this error page if this text weren't here.\n"
334
335         // Is it text?  ("Content-Type" is always in the map)
336         baseType := strings.Split(w.header["Content-Type"], ";", 2)[0]
337         switch baseType {
338         case "text/html":
339                 io.WriteString(w, "<!-- ")
340                 for w.written < min {
341                         io.WriteString(w, msg)
342                 }
343                 io.WriteString(w, " -->")
344         case "text/plain":
345                 io.WriteString(w, "\n")
346                 for w.written < min {
347                         io.WriteString(w, msg)
348                 }
349         }
350 }
351
352 func (w *response) finishRequest() {
353         // If this was an HTTP/1.0 request with keep-alive and we sent a Content-Length
354         // back, we can make this a keep-alive response ...
355         if w.req.wantsHttp10KeepAlive() {
356                 _, sentLength := w.header["Content-Length"]
357                 if sentLength && w.header["Connection"] == "keep-alive" {
358                         w.closeAfterReply = false
359                 }
360         }
361         if !w.wroteHeader {
362                 w.WriteHeader(StatusOK)
363         }
364         errorKludge(w)
365         if w.chunking {
366                 io.WriteString(w.conn.buf, "0\r\n")
367                 // trailer key/value pairs, followed by blank line
368                 io.WriteString(w.conn.buf, "\r\n")
369         }
370         w.conn.buf.Flush()
371         w.req.Body.Close()
372 }
373
374 // Flush implements the ResponseWriter.Flush method.
375 func (w *response) Flush() {
376         if !w.wroteHeader {
377                 w.WriteHeader(StatusOK)
378         }
379         w.conn.buf.Flush()
380 }
381
382 // Close the connection.
383 func (c *conn) close() {
384         if c.buf != nil {
385                 c.buf.Flush()
386                 c.buf = nil
387         }
388         if c.rwc != nil {
389                 c.rwc.Close()
390                 c.rwc = nil
391         }
392 }
393
394 // Serve a new connection.
395 func (c *conn) serve() {
396         for {
397                 w, err := c.readRequest()
398                 if err != nil {
399                         break
400                 }
401                 // HTTP cannot have multiple simultaneous active requests.[*]
402                 // Until the server replies to this request, it can't read another,
403                 // so we might as well run the handler in this goroutine.
404                 // [*] Not strictly true: HTTP pipelining.  We could let them all process
405                 // in parallel even if their responses need to be serialized.
406                 c.handler.ServeHTTP(w, w.req)
407                 if c.hijacked {
408                         return
409                 }
410                 w.finishRequest()
411                 if w.closeAfterReply {
412                         break
413                 }
414         }
415         c.close()
416 }
417
418 // Hijack impements the ResponseWriter.Hijack method.
419 func (w *response) Hijack() (rwc io.ReadWriteCloser, buf *bufio.ReadWriter, err os.Error) {
420         if w.conn.hijacked {
421                 return nil, nil, ErrHijacked
422         }
423         w.conn.hijacked = true
424         rwc = w.conn.rwc
425         buf = w.conn.buf
426         w.conn.rwc = nil
427         w.conn.buf = nil
428         return
429 }
430
431 // The HandlerFunc type is an adapter to allow the use of
432 // ordinary functions as HTTP handlers.  If f is a function
433 // with the appropriate signature, HandlerFunc(f) is a
434 // Handler object that calls f.
435 type HandlerFunc func(ResponseWriter, *Request)
436
437 // ServeHTTP calls f(w, req).
438 func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
439         f(w, r)
440 }
441
442 // Helper handlers
443
444 // Error replies to the request with the specified error message and HTTP code.
445 func Error(w ResponseWriter, error string, code int) {
446         w.SetHeader("Content-Type", "text/plain; charset=utf-8")
447         w.WriteHeader(code)
448         fmt.Fprintln(w, error)
449 }
450
451 // NotFound replies to the request with an HTTP 404 not found error.
452 func NotFound(w ResponseWriter, r *Request) { Error(w, "404 page not found", StatusNotFound) }
453
454 // NotFoundHandler returns a simple request handler
455 // that replies to each request with a ``404 page not found'' reply.
456 func NotFoundHandler() Handler { return HandlerFunc(NotFound) }
457
458 // Redirect replies to the request with a redirect to url,
459 // which may be a path relative to the request path.
460 func Redirect(w ResponseWriter, r *Request, url string, code int) {
461         if u, err := ParseURL(url); err == nil {
462                 // If url was relative, make absolute by
463                 // combining with request path.
464                 // The browser would probably do this for us,
465                 // but doing it ourselves is more reliable.
466
467                 // NOTE(rsc): RFC 2616 says that the Location
468                 // line must be an absolute URI, like
469                 // "http://www.google.com/redirect/",
470                 // not a path like "/redirect/".
471                 // Unfortunately, we don't know what to
472                 // put in the host name section to get the
473                 // client to connect to us again, so we can't
474                 // know the right absolute URI to send back.
475                 // Because of this problem, no one pays attention
476                 // to the RFC; they all send back just a new path.
477                 // So do we.
478                 oldpath := r.URL.Path
479                 if oldpath == "" { // should not happen, but avoid a crash if it does
480                         oldpath = "/"
481                 }
482                 if u.Scheme == "" {
483                         // no leading http://server
484                         if url == "" || url[0] != '/' {
485                                 // make relative path absolute
486                                 olddir, _ := path.Split(oldpath)
487                                 url = olddir + url
488                         }
489
490                         // clean up but preserve trailing slash
491                         trailing := url[len(url)-1] == '/'
492                         url = path.Clean(url)
493                         if trailing && url[len(url)-1] != '/' {
494                                 url += "/"
495                         }
496                 }
497         }
498
499         w.SetHeader("Location", url)
500         w.WriteHeader(code)
501
502         // RFC2616 recommends that a short note "SHOULD" be included in the
503         // response because older user agents may not understand 301/307.
504         // Shouldn't send the response for POST or HEAD; that leaves GET.
505         if r.Method == "GET" {
506                 note := "<a href=\"" + htmlEscape(url) + "\">" + statusText[code] + "</a>.\n"
507                 fmt.Fprintln(w, note)
508         }
509 }
510
511 func htmlEscape(s string) string {
512         s = strings.Replace(s, "&", "&amp;", -1)
513         s = strings.Replace(s, "<", "&lt;", -1)
514         s = strings.Replace(s, ">", "&gt;", -1)
515         s = strings.Replace(s, "\"", "&quot;", -1)
516         s = strings.Replace(s, "'", "&apos;", -1)
517         return s
518 }
519
520 // Redirect to a fixed URL
521 type redirectHandler struct {
522         url  string
523         code int
524 }
525
526 func (rh *redirectHandler) ServeHTTP(w ResponseWriter, r *Request) {
527         Redirect(w, r, rh.url, rh.code)
528 }
529
530 // RedirectHandler returns a request handler that redirects
531 // each request it receives to the given url using the given
532 // status code.
533 func RedirectHandler(url string, code int) Handler {
534         return &redirectHandler{url, code}
535 }
536
537 // ServeMux is an HTTP request multiplexer.
538 // It matches the URL of each incoming request against a list of registered
539 // patterns and calls the handler for the pattern that
540 // most closely matches the URL.
541 //
542 // Patterns named fixed paths, like "/favicon.ico",
543 // or subtrees, like "/images/" (note the trailing slash).
544 // Patterns must begin with /.
545 // Longer patterns take precedence over shorter ones, so that
546 // if there are handlers registered for both "/images/"
547 // and "/images/thumbnails/", the latter handler will be
548 // called for paths beginning "/images/thumbnails/" and the
549 // former will receiver requests for any other paths in the
550 // "/images/" subtree.
551 //
552 // In the future, the pattern syntax may be relaxed to allow
553 // an optional host-name at the beginning of the pattern,
554 // so that a handler might register for the two patterns
555 // "/codesearch" and "codesearch.google.com/"
556 // without taking over requests for http://www.google.com/.
557 //
558 // ServeMux also takes care of sanitizing the URL request path,
559 // redirecting any request containing . or .. elements to an
560 // equivalent .- and ..-free URL.
561 type ServeMux struct {
562         m map[string]Handler
563 }
564
565 // NewServeMux allocates and returns a new ServeMux.
566 func NewServeMux() *ServeMux { return &ServeMux{make(map[string]Handler)} }
567
568 // DefaultServeMux is the default ServeMux used by Serve.
569 var DefaultServeMux = NewServeMux()
570
571 // Does path match pattern?
572 func pathMatch(pattern, path string) bool {
573         if len(pattern) == 0 {
574                 // should not happen
575                 return false
576         }
577         n := len(pattern)
578         if pattern[n-1] != '/' {
579                 return pattern == path
580         }
581         return len(path) >= n && path[0:n] == pattern
582 }
583
584 // Return the canonical path for p, eliminating . and .. elements.
585 func cleanPath(p string) string {
586         if p == "" {
587                 return "/"
588         }
589         if p[0] != '/' {
590                 p = "/" + p
591         }
592         np := path.Clean(p)
593         // path.Clean removes trailing slash except for root;
594         // put the trailing slash back if necessary.
595         if p[len(p)-1] == '/' && np != "/" {
596                 np += "/"
597         }
598         return np
599 }
600
601 // ServeHTTP dispatches the request to the handler whose
602 // pattern most closely matches the request URL.
603 func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
604         // Clean path to canonical form and redirect.
605         if p := cleanPath(r.URL.Path); p != r.URL.Path {
606                 w.SetHeader("Location", p)
607                 w.WriteHeader(StatusMovedPermanently)
608                 return
609         }
610
611         // Most-specific (longest) pattern wins.
612         var h Handler
613         var n = 0
614         for k, v := range mux.m {
615                 if !pathMatch(k, r.URL.Path) {
616                         continue
617                 }
618                 if h == nil || len(k) > n {
619                         n = len(k)
620                         h = v
621                 }
622         }
623         if h == nil {
624                 h = NotFoundHandler()
625         }
626         h.ServeHTTP(w, r)
627 }
628
629 // Handle registers the handler for the given pattern.
630 func (mux *ServeMux) Handle(pattern string, handler Handler) {
631         if pattern == "" || pattern[0] != '/' {
632                 panic("http: invalid pattern " + pattern)
633         }
634
635         mux.m[pattern] = handler
636
637         // Helpful behavior:
638         // If pattern is /tree/, insert permanent redirect for /tree.
639         n := len(pattern)
640         if n > 0 && pattern[n-1] == '/' {
641                 mux.m[pattern[0:n-1]] = RedirectHandler(pattern, StatusMovedPermanently)
642         }
643 }
644
645 // HandleFunc registers the handler function for the given pattern.
646 func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
647         mux.Handle(pattern, HandlerFunc(handler))
648 }
649
650 // Handle registers the handler for the given pattern
651 // in the DefaultServeMux.
652 func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
653
654 // HandleFunc registers the handler function for the given pattern
655 // in the DefaultServeMux.
656 func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
657         DefaultServeMux.HandleFunc(pattern, handler)
658 }
659
660 // Serve accepts incoming HTTP connections on the listener l,
661 // creating a new service thread for each.  The service threads
662 // read requests and then call handler to reply to them.
663 // Handler is typically nil, in which case the DefaultServeMux is used.
664 func Serve(l net.Listener, handler Handler) os.Error {
665         if handler == nil {
666                 handler = DefaultServeMux
667         }
668         for {
669                 rw, e := l.Accept()
670                 if e != nil {
671                         return e
672                 }
673                 c, err := newConn(rw, handler)
674                 if err != nil {
675                         continue
676                 }
677                 go c.serve()
678         }
679         panic("not reached")
680 }
681
682 // ListenAndServe listens on the TCP network address addr
683 // and then calls Serve with handler to handle requests
684 // on incoming connections.  Handler is typically nil,
685 // in which case the DefaultServeMux is used.
686 //
687 // A trivial example server is:
688 //
689 //      package main
690 //
691 //      import (
692 //              "http"
693 //              "io"
694 //              "log"
695 //      )
696 //
697 //      // hello world, the web server
698 //      func HelloServer(w http.ResponseWriter, req *http.Request) {
699 //              io.WriteString(w, "hello, world!\n")
700 //      }
701 //
702 //      func main() {
703 //              http.HandleFunc("/hello", HelloServer)
704 //              err := http.ListenAndServe(":12345", nil)
705 //              if err != nil {
706 //                      log.Exit("ListenAndServe: ", err.String())
707 //              }
708 //      }
709 func ListenAndServe(addr string, handler Handler) os.Error {
710         l, e := net.Listen("tcp", addr)
711         if e != nil {
712                 return e
713         }
714         e = Serve(l, handler)
715         l.Close()
716         return e
717 }
718
719 // ListenAndServeTLS acts identically to ListenAndServe, except that it
720 // expects HTTPS connections. Additionally, files containing a certificate and
721 // matching private key for the server must be provided.
722 //
723 // A trivial example server is:
724 //
725 //      import (
726 //              "http"
727 //              "log"
728 //      )
729 //
730 //      func handler(w http.ResponseWriter, req *http.Request) {
731 //              w.SetHeader("Content-Type", "text/plain")
732 //              w.Write([]byte("This is an example server.\n"))
733 //      }
734 //
735 //      func main() {
736 //              http.HandleFunc("/", handler)
737 //              log.Printf("About to listen on 10443. Go to https://127.0.0.1:10443/")
738 //              err := http.ListenAndServeTLS(":10443", "cert.pem", "key.pem", nil)
739 //              if err != nil {
740 //                      log.Exit(err)
741 //              }
742 //      }
743 //
744 // One can use generate_cert.go in crypto/tls to generate cert.pem and key.pem.
745 func ListenAndServeTLS(addr string, certFile string, keyFile string, handler Handler) os.Error {
746         config := &tls.Config{
747                 Rand:       rand.Reader,
748                 Time:       time.Seconds,
749                 NextProtos: []string{"http/1.1"},
750         }
751
752         var err os.Error
753         config.Certificates = make([]tls.Certificate, 1)
754         config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
755         if err != nil {
756                 return err
757         }
758
759         conn, err := net.Listen("tcp", addr)
760         if err != nil {
761                 return err
762         }
763
764         tlsListener := tls.NewListener(conn, config)
765         return Serve(tlsListener, handler)
766 }