LEFT | RIGHT |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 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 // HTTP server. See RFC 2616. | 5 // HTTP server. See RFC 2616. |
6 | 6 |
7 // TODO(rsc): | 7 // TODO(rsc): |
8 // logging | 8 // logging |
9 | 9 |
10 package http | 10 package http |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 func newConn(rwc net.Conn, handler Handler) (c *conn, err os.Error) { | 145 func newConn(rwc net.Conn, handler Handler) (c *conn, err os.Error) { |
146 c = new(conn) | 146 c = new(conn) |
147 c.remoteAddr = rwc.RemoteAddr().String() | 147 c.remoteAddr = rwc.RemoteAddr().String() |
148 c.handler = handler | 148 c.handler = handler |
149 c.rwc = rwc | 149 c.rwc = rwc |
150 br := bufio.NewReader(rwc) | 150 br := bufio.NewReader(rwc) |
151 bw := bufio.NewWriter(rwc) | 151 bw := bufio.NewWriter(rwc) |
152 c.buf = bufio.NewReadWriter(br, bw) | 152 c.buf = bufio.NewReadWriter(br, bw) |
153 | 153 |
154 if tlsConn, ok := rwc.(*tls.Conn); ok { | 154 if tlsConn, ok := rwc.(*tls.Conn); ok { |
| 155 tlsConn.Handshake() |
155 c.tlsState = new(tls.ConnectionState) | 156 c.tlsState = new(tls.ConnectionState) |
156 *c.tlsState = tlsConn.ConnectionState() | 157 *c.tlsState = tlsConn.ConnectionState() |
157 } | 158 } |
158 | 159 |
159 return c, nil | 160 return c, nil |
160 } | 161 } |
161 | 162 |
162 // wrapper around io.ReaderCloser which on first read, sends an | 163 // wrapper around io.ReaderCloser which on first read, sends an |
163 // HTTP/1.1 100 Continue header | 164 // HTTP/1.1 100 Continue header |
164 type expectContinueReader struct { | 165 type expectContinueReader struct { |
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
584 fmt.Fprintln(w, error) | 585 fmt.Fprintln(w, error) |
585 } | 586 } |
586 | 587 |
587 // NotFound replies to the request with an HTTP 404 not found error. | 588 // NotFound replies to the request with an HTTP 404 not found error. |
588 func NotFound(w ResponseWriter, r *Request) { Error(w, "404 page not found", Sta
tusNotFound) } | 589 func NotFound(w ResponseWriter, r *Request) { Error(w, "404 page not found", Sta
tusNotFound) } |
589 | 590 |
590 // NotFoundHandler returns a simple request handler | 591 // NotFoundHandler returns a simple request handler |
591 // that replies to each request with a ``404 page not found'' reply. | 592 // that replies to each request with a ``404 page not found'' reply. |
592 func NotFoundHandler() Handler { return HandlerFunc(NotFound) } | 593 func NotFoundHandler() Handler { return HandlerFunc(NotFound) } |
593 | 594 |
594 // StripHandler returns a Handler that strips a given prefix | 595 // StripPrefix returns a handler that serves HTTP requests |
595 // from the request URL path and calls the provided Handler | 596 // by removing the given prefix from the request URL's Path |
596 // with the modified Request. If a request doesn't start | 597 // and invoking the handler h. StripPrefix handles a |
597 // with the prefix, an HTTP 404 not found error is returned. | 598 // request for a path that doesn't begin with prefix by |
598 func StripHandler(h Handler, prefix string) Handler { | 599 // replying with an HTTP 404 not found error. |
| 600 func StripPrefix(prefix string, h Handler) Handler { |
599 return HandlerFunc(func(w ResponseWriter, r *Request) { | 601 return HandlerFunc(func(w ResponseWriter, r *Request) { |
600 if !strings.HasPrefix(r.URL.Path, prefix) { | 602 if !strings.HasPrefix(r.URL.Path, prefix) { |
601 » » » Error(w, "404 page not found", StatusNotFound) | 603 » » » NotFound(w, r) |
602 return | 604 return |
603 } | 605 } |
604 r.URL.Path = r.URL.Path[len(prefix):] | 606 r.URL.Path = r.URL.Path[len(prefix):] |
605 r.URL.RawPath = r.URL.RawPath[len(prefix):] | |
606 h.ServeHTTP(w, r) | 607 h.ServeHTTP(w, r) |
607 }) | 608 }) |
608 } | 609 } |
609 | 610 |
610 // Redirect replies to the request with a redirect to url, | 611 // Redirect replies to the request with a redirect to url, |
611 // which may be a path relative to the request path. | 612 // which may be a path relative to the request path. |
612 func Redirect(w ResponseWriter, r *Request, url string, code int) { | 613 func Redirect(w ResponseWriter, r *Request, url string, code int) { |
613 if u, err := ParseURL(url); err == nil { | 614 if u, err := ParseURL(url); err == nil { |
614 // If url was relative, make absolute by | 615 // If url was relative, make absolute by |
615 // combining with request path. | 616 // combining with request path. |
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1069 func (tw *timeoutWriter) WriteHeader(code int) { | 1070 func (tw *timeoutWriter) WriteHeader(code int) { |
1070 tw.mu.Lock() | 1071 tw.mu.Lock() |
1071 if tw.timedOut || tw.wroteHeader { | 1072 if tw.timedOut || tw.wroteHeader { |
1072 tw.mu.Unlock() | 1073 tw.mu.Unlock() |
1073 return | 1074 return |
1074 } | 1075 } |
1075 tw.wroteHeader = true | 1076 tw.wroteHeader = true |
1076 tw.mu.Unlock() | 1077 tw.mu.Unlock() |
1077 tw.w.WriteHeader(code) | 1078 tw.w.WriteHeader(code) |
1078 } | 1079 } |
LEFT | RIGHT |