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.
5 // HTTP server. See RFC 2616.
29 // Errors introduced by the HTTP server.
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 ErrContentLength = os.NewError("Conn.Write wrote more than the declared Content-Length")
37 // Objects implementing the Handler interface can be
38 // registered to serve a particular path or subtree
39 // in the HTTP server.
41 // ServeHTTP should write reply headers and data to the ResponseWriter
42 // and then return. Returning signals that the request is finished
43 // and that the HTTP server can move on to the next request on
45 type Handler interface {
46 ServeHTTP(ResponseWriter, *Request)
49 // A ResponseWriter interface is used by an HTTP handler to
50 // construct an HTTP response.
51 type ResponseWriter interface {
52 // RemoteAddr returns the address of the client that sent the current request
55 // UsingTLS returns true if the client is connected using TLS
58 // SetHeader sets a header line in the eventual response.
59 // For example, SetHeader("Content-Type", "text/html; charset=utf-8")
60 // will result in the header line
62 // Content-Type: text/html; charset=utf-8
64 // being sent. UTF-8 encoded HTML is the default setting for
65 // Content-Type in this library, so users need not make that
66 // particular call. Calls to SetHeader after WriteHeader (or Write)
67 // are ignored. An empty value removes the header if previously set.
68 SetHeader(string, string)
70 // Write writes the data to the connection as part of an HTTP reply.
71 // If WriteHeader has not yet been called, Write calls WriteHeader(http.StatusOK)
72 // before writing the data.
73 Write([]byte) (int, os.Error)
75 // WriteHeader sends an HTTP response header with status code.
76 // If WriteHeader is not called explicitly, the first call to Write
77 // will trigger an implicit WriteHeader(http.StatusOK).
78 // Thus explicit calls to WriteHeader are mainly used to
82 // Flush sends any buffered data to the client.
85 // Hijack lets the caller take over the connection.
86 // After a call to Hijack(), the HTTP server library
87 // will not do anything else with the connection.
88 // It becomes the caller's responsibility to manage
89 // and close the connection.
90 Hijack() (io.ReadWriteCloser, *bufio.ReadWriter, os.Error)
93 // A conn represents the server side of an HTTP connection.
95 remoteAddr string // network address of remote side
96 handler Handler // request handler
97 rwc io.ReadWriteCloser // i/o connection
98 buf *bufio.ReadWriter // buffered rwc
99 hijacked bool // connection has been hijacked by handler
100 usingTLS bool // a flag indicating connection over TLS
103 // A response represents the server side of an HTTP response.
104 type response struct {
106 req *Request // request for this response
107 chunking bool // using chunked transfer encoding for reply body
108 wroteHeader bool // reply header has been written
109 wroteContinue bool // 100 Continue response was written
110 header map[string]string // reply header parameters
111 written int64 // number of bytes written in body
112 contentLength int64 // explicitly-declared Content-Length; or -1
113 status int // status code passed to WriteHeader
115 // close connection after this reply. set on request and
116 // updated after response from handler if there's a
117 // "Connection: keep-alive" response header and a
122 // Create new connection from rwc.
123 func newConn(rwc net.Conn, handler Handler) (c *conn, err os.Error) {
125 c.remoteAddr = rwc.RemoteAddr().String()
128 _, c.usingTLS = rwc.(*tls.Conn)
129 br := bufio.NewReader(rwc)
130 bw := bufio.NewWriter(rwc)
131 c.buf = bufio.NewReadWriter(br, bw)
135 // wrapper around io.ReaderCloser which on first read, sends an
136 // HTTP/1.1 100 Continue header
137 type expectContinueReader struct {
139 readCloser io.ReadCloser
142 func (ecr *expectContinueReader) Read(p []byte) (n int, err os.Error) {
143 if !ecr.resp.wroteContinue && !ecr.resp.conn.hijacked {
144 ecr.resp.wroteContinue = true
145 io.WriteString(ecr.resp.conn.buf, "HTTP/1.1 100 Continue\r\n\r\n")
146 ecr.resp.conn.buf.Flush()
148 return ecr.readCloser.Read(p)
151 func (ecr *expectContinueReader) Close() os.Error {
152 return ecr.readCloser.Close()
155 // TimeFormat is the time format to use with
156 // time.Parse and time.Time.Format when parsing
157 // or generating times in HTTP headers.
158 // It is like time.RFC1123 but hard codes GMT as the time zone.
159 const TimeFormat = "Mon, 02 Jan 2006 15:04:05 GMT"
161 // Read next request from connection.
162 func (c *conn) readRequest() (w *response, err os.Error) {
164 return nil, ErrHijacked
167 if req, err = ReadRequest(c.buf.Reader); err != nil {
174 w.header = make(map[string]string)
177 // Expect 100 Continue support
178 if req.expectsContinue() && req.ProtoAtLeast(1, 1) {
179 // Wrap the Body reader with one that replies on the connection
180 req.Body = &expectContinueReader{readCloser: req.Body, resp: w}
185 // UsingTLS implements the ResponseWriter.UsingTLS
186 func (w *response) UsingTLS() bool {
187 return w.conn.usingTLS
190 // RemoteAddr implements the ResponseWriter.RemoteAddr method
191 func (w *response) RemoteAddr() string { return w.conn.remoteAddr }
193 // SetHeader implements the ResponseWriter.SetHeader method
194 // An empty value removes the header from the map.
195 func (w *response) SetHeader(hdr, val string) {
196 w.header[CanonicalHeaderKey(hdr)] = val, val != ""
199 // WriteHeader implements the ResponseWriter.WriteHeader method
200 func (w *response) WriteHeader(code int) {
202 log.Print("http: response.WriteHeader on hijacked connection")
206 log.Print("http: multiple response.WriteHeader calls")
211 if code == StatusNotModified {
212 // Must not have body.
213 for _, header := range []string{"Content-Type", "Content-Length", "Transfer-Encoding"} {
214 if w.header[header] != "" {
215 // TODO: return an error if WriteHeader gets a return parameter
216 // or set a flag on w to make future Writes() write an error page?
217 // for now just log and drop the header.
218 log.Printf("http: StatusNotModified response with header %q defined", header)
219 w.header[header] = "", false
223 // Default output is HTML encoded in UTF-8.
224 if w.header["Content-Type"] == "" {
225 w.SetHeader("Content-Type", "text/html; charset=utf-8")
229 if w.header["Date"] == "" {
230 w.SetHeader("Date", time.UTC().Format(TimeFormat))
233 // Check for a explicit (and valid) Content-Length header.
235 var contentLength int64
236 if clenStr, ok := w.header["Content-Length"]; ok {
238 contentLength, err = strconv.Atoi64(clenStr)
242 log.Printf("http: invalid Content-Length of %q sent", clenStr)
243 w.SetHeader("Content-Length", "")
247 te, hasTE := w.header["Transfer-Encoding"]
248 if hasCL && hasTE && te != "identity" {
249 // TODO: return an error if WriteHeader gets a return parameter
250 // For now just ignore the Content-Length.
251 log.Printf("http: WriteHeader called with both Transfer-Encoding of %q and a Content-Length of %d",
253 w.SetHeader("Content-Length", "")
257 if w.req.Method == "HEAD" {
261 w.contentLength = contentLength
262 w.SetHeader("Transfer-Encoding", "")
263 } else if w.req.ProtoAtLeast(1, 1) {
264 // HTTP/1.1 or greater: use chunked transfer encoding
265 // to avoid closing the connection at EOF.
266 // TODO: this blows away any custom or stacked Transfer-Encoding they
267 // might have set. Deal with that as need arises once we have a valid
270 w.SetHeader("Transfer-Encoding", "chunked")
272 // HTTP version < 1.1: cannot do chunked transfer
273 // encoding and we don't know the Content-Length so
274 // signal EOF by closing connection.
275 w.closeAfterReply = true
276 w.chunking = false // redundant
277 w.SetHeader("Transfer-Encoding", "") // in case already set
280 if w.req.wantsHttp10KeepAlive() && (w.req.Method == "HEAD" || hasCL) {
281 _, connectionHeaderSet := w.header["Connection"]
282 if !connectionHeaderSet {
283 w.SetHeader("Connection", "keep-alive")
287 // Cannot use Content-Length with non-identity Transfer-Encoding.
289 w.SetHeader("Content-Length", "")
291 if !w.req.ProtoAtLeast(1, 0) {
295 if w.req.ProtoAtLeast(1, 1) {
298 codestring := strconv.Itoa(code)
299 text, ok := statusText[code]
301 text = "status code " + codestring
303 io.WriteString(w.conn.buf, proto+" "+codestring+" "+text+"\r\n")
304 for k, v := range w.header {
305 io.WriteString(w.conn.buf, k+": "+v+"\r\n")
307 io.WriteString(w.conn.buf, "\r\n")
310 // Write implements the ResponseWriter.Write method
311 func (w *response) Write(data []byte) (n int, err os.Error) {
313 log.Print("http: response.Write on hijacked connection")
314 return 0, ErrHijacked
317 w.WriteHeader(StatusOK)
323 if w.status == StatusNotModified || w.req.Method == "HEAD" {
324 // Must not have body.
325 return 0, ErrBodyNotAllowed
328 w.written += int64(len(data)) // ignoring errors, for errorKludge
329 if w.contentLength != -1 && w.written > w.contentLength {
330 return 0, ErrContentLength
333 // TODO(rsc): if chunking happened after the buffering,
334 // then there would be fewer chunk headers.
335 // On the other hand, it would make hijacking more difficult.
337 fmt.Fprintf(w.conn.buf, "%x\r\n", len(data)) // TODO(rsc): use strconv not fmt
339 n, err = w.conn.buf.Write(data)
340 if err == nil && w.chunking {
342 err = io.ErrShortWrite
345 io.WriteString(w.conn.buf, "\r\n")
352 // If this is an error reply (4xx or 5xx)
353 // and the handler wrote some data explaining the error,
354 // some browsers (i.e., Chrome, Internet Explorer)
355 // will show their own error instead unless the error is
356 // long enough. The minimum lengths used in those
357 // browsers are in the 256-512 range.
358 // Pad to 1024 bytes.
359 func errorKludge(w *response) {
363 if kind := w.status / 100; kind != 4 && kind != 5 {
367 // Did the handler supply any info? Enough?
368 if w.written == 0 || w.written >= min {
372 // Is it a broken browser?
374 switch agent := w.req.UserAgent; {
375 case strings.Contains(agent, "MSIE"):
376 msg = "Internet Explorer"
377 case strings.Contains(agent, "Chrome/"):
382 msg += " would ignore this error page if this text weren't here.\n"
384 // Is it text? ("Content-Type" is always in the map)
385 baseType := strings.Split(w.header["Content-Type"], ";", 2)[0]
388 io.WriteString(w, "<!-- ")
389 for w.written < min {
390 io.WriteString(w, msg)
392 io.WriteString(w, " -->")
394 io.WriteString(w, "\n")
395 for w.written < min {
396 io.WriteString(w, msg)
401 func (w *response) finishRequest() {
402 // If this was an HTTP/1.0 request with keep-alive and we sent a Content-Length
403 // back, we can make this a keep-alive response ...
404 if w.req.wantsHttp10KeepAlive() {
405 _, sentLength := w.header["Content-Length"]
406 if sentLength && w.header["Connection"] == "keep-alive" {
407 w.closeAfterReply = false
411 w.WriteHeader(StatusOK)
415 io.WriteString(w.conn.buf, "0\r\n")
416 // trailer key/value pairs, followed by blank line
417 io.WriteString(w.conn.buf, "\r\n")
422 if w.contentLength != -1 && w.contentLength != w.written {
423 // Did not write enough. Avoid getting out of sync.
424 w.closeAfterReply = true
428 // Flush implements the ResponseWriter.Flush method.
429 func (w *response) Flush() {
431 w.WriteHeader(StatusOK)
436 // Close the connection.
437 func (c *conn) close() {
448 // Serve a new connection.
449 func (c *conn) serve() {
451 w, err := c.readRequest()
455 // HTTP cannot have multiple simultaneous active requests.[*]
456 // Until the server replies to this request, it can't read another,
457 // so we might as well run the handler in this goroutine.
458 // [*] Not strictly true: HTTP pipelining. We could let them all process
459 // in parallel even if their responses need to be serialized.
460 c.handler.ServeHTTP(w, w.req)
465 if w.closeAfterReply {
472 // Hijack impements the ResponseWriter.Hijack method.
473 func (w *response) Hijack() (rwc io.ReadWriteCloser, buf *bufio.ReadWriter, err os.Error) {
475 return nil, nil, ErrHijacked
477 w.conn.hijacked = true
485 // The HandlerFunc type is an adapter to allow the use of
486 // ordinary functions as HTTP handlers. If f is a function
487 // with the appropriate signature, HandlerFunc(f) is a
488 // Handler object that calls f.
489 type HandlerFunc func(ResponseWriter, *Request)
491 // ServeHTTP calls f(w, req).
492 func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
498 // Error replies to the request with the specified error message and HTTP code.
499 func Error(w ResponseWriter, error string, code int) {
500 w.SetHeader("Content-Type", "text/plain; charset=utf-8")
502 fmt.Fprintln(w, error)
505 // NotFound replies to the request with an HTTP 404 not found error.
506 func NotFound(w ResponseWriter, r *Request) { Error(w, "404 page not found", StatusNotFound) }
508 // NotFoundHandler returns a simple request handler
509 // that replies to each request with a ``404 page not found'' reply.
510 func NotFoundHandler() Handler { return HandlerFunc(NotFound) }
512 // Redirect replies to the request with a redirect to url,
513 // which may be a path relative to the request path.
514 func Redirect(w ResponseWriter, r *Request, url string, code int) {
515 if u, err := ParseURL(url); err == nil {
516 // If url was relative, make absolute by
517 // combining with request path.
518 // The browser would probably do this for us,
519 // but doing it ourselves is more reliable.
521 // NOTE(rsc): RFC 2616 says that the Location
522 // line must be an absolute URI, like
523 // "http://www.google.com/redirect/",
524 // not a path like "/redirect/".
525 // Unfortunately, we don't know what to
526 // put in the host name section to get the
527 // client to connect to us again, so we can't
528 // know the right absolute URI to send back.
529 // Because of this problem, no one pays attention
530 // to the RFC; they all send back just a new path.
532 oldpath := r.URL.Path
533 if oldpath == "" { // should not happen, but avoid a crash if it does
537 // no leading http://server
538 if url == "" || url[0] != '/' {
539 // make relative path absolute
540 olddir, _ := path.Split(oldpath)
544 // clean up but preserve trailing slash
545 trailing := url[len(url)-1] == '/'
546 url = path.Clean(url)
547 if trailing && url[len(url)-1] != '/' {
553 w.SetHeader("Location", url)
556 // RFC2616 recommends that a short note "SHOULD" be included in the
557 // response because older user agents may not understand 301/307.
558 // Shouldn't send the response for POST or HEAD; that leaves GET.
559 if r.Method == "GET" {
560 note := "<a href=\"" + htmlEscape(url) + "\">" + statusText[code] + "</a>.\n"
561 fmt.Fprintln(w, note)
565 func htmlEscape(s string) string {
566 s = strings.Replace(s, "&", "&", -1)
567 s = strings.Replace(s, "<", "<", -1)
568 s = strings.Replace(s, ">", ">", -1)
569 s = strings.Replace(s, "\"", """, -1)
570 s = strings.Replace(s, "'", "'", -1)
574 // Redirect to a fixed URL
575 type redirectHandler struct {
580 func (rh *redirectHandler) ServeHTTP(w ResponseWriter, r *Request) {
581 Redirect(w, r, rh.url, rh.code)
584 // RedirectHandler returns a request handler that redirects
585 // each request it receives to the given url using the given
587 func RedirectHandler(url string, code int) Handler {
588 return &redirectHandler{url, code}
591 // ServeMux is an HTTP request multiplexer.
592 // It matches the URL of each incoming request against a list of registered
593 // patterns and calls the handler for the pattern that
594 // most closely matches the URL.
596 // Patterns named fixed, rooted paths, like "/favicon.ico",
597 // or rooted subtrees, like "/images/" (note the trailing slash).
598 // Longer patterns take precedence over shorter ones, so that
599 // if there are handlers registered for both "/images/"
600 // and "/images/thumbnails/", the latter handler will be
601 // called for paths beginning "/images/thumbnails/" and the
602 // former will receiver requests for any other paths in the
603 // "/images/" subtree.
605 // Patterns may optionally begin with a host name, restricting matches to
606 // URLs on that host only. Host-specific patterns take precedence over
607 // general patterns, so that a handler might register for the two patterns
608 // "/codesearch" and "codesearch.google.com/" without also taking over
609 // requests for "http://www.google.com/".
611 // ServeMux also takes care of sanitizing the URL request path,
612 // redirecting any request containing . or .. elements to an
613 // equivalent .- and ..-free URL.
614 type ServeMux struct {
618 // NewServeMux allocates and returns a new ServeMux.
619 func NewServeMux() *ServeMux { return &ServeMux{make(map[string]Handler)} }
621 // DefaultServeMux is the default ServeMux used by Serve.
622 var DefaultServeMux = NewServeMux()
624 // Does path match pattern?
625 func pathMatch(pattern, path string) bool {
626 if len(pattern) == 0 {
631 if pattern[n-1] != '/' {
632 return pattern == path
634 return len(path) >= n && path[0:n] == pattern
637 // Return the canonical path for p, eliminating . and .. elements.
638 func cleanPath(p string) string {
646 // path.Clean removes trailing slash except for root;
647 // put the trailing slash back if necessary.
648 if p[len(p)-1] == '/' && np != "/" {
654 // Find a handler on a handler map given a path string
655 // Most-specific (longest) pattern wins
656 func (mux *ServeMux) match(path string) Handler {
659 for k, v := range mux.m {
660 if !pathMatch(k, path) {
663 if h == nil || len(k) > n {
671 // ServeHTTP dispatches the request to the handler whose
672 // pattern most closely matches the request URL.
673 func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
674 // Clean path to canonical form and redirect.
675 if p := cleanPath(r.URL.Path); p != r.URL.Path {
676 w.SetHeader("Location", p)
677 w.WriteHeader(StatusMovedPermanently)
680 // Host-specific pattern takes precedence over generic ones
681 h := mux.match(r.Host + r.URL.Path)
683 h = mux.match(r.URL.Path)
686 h = NotFoundHandler()
691 // Handle registers the handler for the given pattern.
692 func (mux *ServeMux) Handle(pattern string, handler Handler) {
694 panic("http: invalid pattern " + pattern)
697 mux.m[pattern] = handler
700 // If pattern is /tree/, insert permanent redirect for /tree.
702 if n > 0 && pattern[n-1] == '/' {
703 mux.m[pattern[0:n-1]] = RedirectHandler(pattern, StatusMovedPermanently)
707 // HandleFunc registers the handler function for the given pattern.
708 func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
709 mux.Handle(pattern, HandlerFunc(handler))
712 // Handle registers the handler for the given pattern
713 // in the DefaultServeMux.
714 // The documentation for ServeMux explains how patterns are matched.
715 func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
717 // HandleFunc registers the handler function for the given pattern
718 // in the DefaultServeMux.
719 // The documentation for ServeMux explains how patterns are matched.
720 func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
721 DefaultServeMux.HandleFunc(pattern, handler)
724 // Serve accepts incoming HTTP connections on the listener l,
725 // creating a new service thread for each. The service threads
726 // read requests and then call handler to reply to them.
727 // Handler is typically nil, in which case the DefaultServeMux is used.
728 func Serve(l net.Listener, handler Handler) os.Error {
729 srv := &Server{Handler: handler}
733 // A Server defines parameters for running an HTTP server.
735 Addr string // TCP address to listen on, ":http" if empty
736 Handler Handler // handler to invoke, http.DefaultServeMux if nil
737 ReadTimeout int64 // the net.Conn.SetReadTimeout value for new connections
738 WriteTimeout int64 // the net.Conn.SetWriteTimeout value for new connections
741 // ListenAndServe listens on the TCP network address srv.Addr and then
742 // calls Serve to handle requests on incoming connections. If
743 // srv.Addr is blank, ":http" is used.
744 func (srv *Server) ListenAndServe() os.Error {
749 l, e := net.Listen("tcp", addr)
756 // Serve accepts incoming connections on the Listener l, creating a
757 // new service thread for each. The service threads read requests and
758 // then call srv.Handler to reply to them.
759 func (srv *Server) Serve(l net.Listener) os.Error {
761 handler := srv.Handler
763 handler = DefaultServeMux
770 if srv.ReadTimeout != 0 {
771 rw.SetReadTimeout(srv.ReadTimeout)
773 if srv.WriteTimeout != 0 {
774 rw.SetWriteTimeout(srv.WriteTimeout)
776 c, err := newConn(rw, handler)
785 // ListenAndServe listens on the TCP network address addr
786 // and then calls Serve with handler to handle requests
787 // on incoming connections. Handler is typically nil,
788 // in which case the DefaultServeMux is used.
790 // A trivial example server is:
800 // // hello world, the web server
801 // func HelloServer(w http.ResponseWriter, req *http.Request) {
802 // io.WriteString(w, "hello, world!\n")
806 // http.HandleFunc("/hello", HelloServer)
807 // err := http.ListenAndServe(":12345", nil)
809 // log.Fatal("ListenAndServe: ", err.String())
812 func ListenAndServe(addr string, handler Handler) os.Error {
813 server := &Server{Addr: addr, Handler: handler}
814 return server.ListenAndServe()
817 // ListenAndServeTLS acts identically to ListenAndServe, except that it
818 // expects HTTPS connections. Additionally, files containing a certificate and
819 // matching private key for the server must be provided.
821 // A trivial example server is:
828 // func handler(w http.ResponseWriter, req *http.Request) {
829 // w.SetHeader("Content-Type", "text/plain")
830 // w.Write([]byte("This is an example server.\n"))
834 // http.HandleFunc("/", handler)
835 // log.Printf("About to listen on 10443. Go to https://127.0.0.1:10443/")
836 // err := http.ListenAndServeTLS(":10443", "cert.pem", "key.pem", nil)
842 // One can use generate_cert.go in crypto/tls to generate cert.pem and key.pem.
843 func ListenAndServeTLS(addr string, certFile string, keyFile string, handler Handler) os.Error {
844 config := &tls.Config{
847 NextProtos: []string{"http/1.1"},
851 config.Certificates = make([]tls.Certificate, 1)
852 config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
857 conn, err := net.Listen("tcp", addr)
862 tlsListener := tls.NewListener(conn, config)
863 return Serve(tlsListener, handler)