1 |
747 |
jeremybenn |
// 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 |
|
|
|
10 |
|
|
package http
|
11 |
|
|
|
12 |
|
|
import (
|
13 |
|
|
"bufio"
|
14 |
|
|
"bytes"
|
15 |
|
|
"crypto/rand"
|
16 |
|
|
"crypto/tls"
|
17 |
|
|
"errors"
|
18 |
|
|
"fmt"
|
19 |
|
|
"io"
|
20 |
|
|
"io/ioutil"
|
21 |
|
|
"log"
|
22 |
|
|
"net"
|
23 |
|
|
"net/url"
|
24 |
|
|
"path"
|
25 |
|
|
"runtime/debug"
|
26 |
|
|
"strconv"
|
27 |
|
|
"strings"
|
28 |
|
|
"sync"
|
29 |
|
|
"time"
|
30 |
|
|
)
|
31 |
|
|
|
32 |
|
|
// Errors introduced by the HTTP server.
|
33 |
|
|
var (
|
34 |
|
|
ErrWriteAfterFlush = errors.New("Conn.Write called after Flush")
|
35 |
|
|
ErrBodyNotAllowed = errors.New("http: response status code does not allow body")
|
36 |
|
|
ErrHijacked = errors.New("Conn has been hijacked")
|
37 |
|
|
ErrContentLength = errors.New("Conn.Write wrote more than the declared Content-Length")
|
38 |
|
|
)
|
39 |
|
|
|
40 |
|
|
// Objects implementing the Handler interface can be
|
41 |
|
|
// registered to serve a particular path or subtree
|
42 |
|
|
// in the HTTP server.
|
43 |
|
|
//
|
44 |
|
|
// ServeHTTP should write reply headers and data to the ResponseWriter
|
45 |
|
|
// and then return. Returning signals that the request is finished
|
46 |
|
|
// and that the HTTP server can move on to the next request on
|
47 |
|
|
// the connection.
|
48 |
|
|
type Handler interface {
|
49 |
|
|
ServeHTTP(ResponseWriter, *Request)
|
50 |
|
|
}
|
51 |
|
|
|
52 |
|
|
// A ResponseWriter interface is used by an HTTP handler to
|
53 |
|
|
// construct an HTTP response.
|
54 |
|
|
type ResponseWriter interface {
|
55 |
|
|
// Header returns the header map that will be sent by WriteHeader.
|
56 |
|
|
// Changing the header after a call to WriteHeader (or Write) has
|
57 |
|
|
// no effect.
|
58 |
|
|
Header() Header
|
59 |
|
|
|
60 |
|
|
// Write writes the data to the connection as part of an HTTP reply.
|
61 |
|
|
// If WriteHeader has not yet been called, Write calls WriteHeader(http.StatusOK)
|
62 |
|
|
// before writing the data.
|
63 |
|
|
Write([]byte) (int, error)
|
64 |
|
|
|
65 |
|
|
// WriteHeader sends an HTTP response header with status code.
|
66 |
|
|
// If WriteHeader is not called explicitly, the first call to Write
|
67 |
|
|
// will trigger an implicit WriteHeader(http.StatusOK).
|
68 |
|
|
// Thus explicit calls to WriteHeader are mainly used to
|
69 |
|
|
// send error codes.
|
70 |
|
|
WriteHeader(int)
|
71 |
|
|
}
|
72 |
|
|
|
73 |
|
|
// The Flusher interface is implemented by ResponseWriters that allow
|
74 |
|
|
// an HTTP handler to flush buffered data to the client.
|
75 |
|
|
//
|
76 |
|
|
// Note that even for ResponseWriters that support Flush,
|
77 |
|
|
// if the client is connected through an HTTP proxy,
|
78 |
|
|
// the buffered data may not reach the client until the response
|
79 |
|
|
// completes.
|
80 |
|
|
type Flusher interface {
|
81 |
|
|
// Flush sends any buffered data to the client.
|
82 |
|
|
Flush()
|
83 |
|
|
}
|
84 |
|
|
|
85 |
|
|
// The Hijacker interface is implemented by ResponseWriters that allow
|
86 |
|
|
// an HTTP handler to take over the connection.
|
87 |
|
|
type Hijacker interface {
|
88 |
|
|
// Hijack lets the caller take over the connection.
|
89 |
|
|
// After a call to Hijack(), the HTTP server library
|
90 |
|
|
// will not do anything else with the connection.
|
91 |
|
|
// It becomes the caller's responsibility to manage
|
92 |
|
|
// and close the connection.
|
93 |
|
|
Hijack() (net.Conn, *bufio.ReadWriter, error)
|
94 |
|
|
}
|
95 |
|
|
|
96 |
|
|
// A conn represents the server side of an HTTP connection.
|
97 |
|
|
type conn struct {
|
98 |
|
|
remoteAddr string // network address of remote side
|
99 |
|
|
server *Server // the Server on which the connection arrived
|
100 |
|
|
rwc net.Conn // i/o connection
|
101 |
|
|
lr *io.LimitedReader // io.LimitReader(rwc)
|
102 |
|
|
buf *bufio.ReadWriter // buffered(lr,rwc), reading from bufio->limitReader->rwc
|
103 |
|
|
hijacked bool // connection has been hijacked by handler
|
104 |
|
|
tlsState *tls.ConnectionState // or nil when not using TLS
|
105 |
|
|
body []byte
|
106 |
|
|
}
|
107 |
|
|
|
108 |
|
|
// A response represents the server side of an HTTP response.
|
109 |
|
|
type response struct {
|
110 |
|
|
conn *conn
|
111 |
|
|
req *Request // request for this response
|
112 |
|
|
chunking bool // using chunked transfer encoding for reply body
|
113 |
|
|
wroteHeader bool // reply header has been written
|
114 |
|
|
wroteContinue bool // 100 Continue response was written
|
115 |
|
|
header Header // reply header parameters
|
116 |
|
|
written int64 // number of bytes written in body
|
117 |
|
|
contentLength int64 // explicitly-declared Content-Length; or -1
|
118 |
|
|
status int // status code passed to WriteHeader
|
119 |
|
|
needSniff bool // need to sniff to find Content-Type
|
120 |
|
|
|
121 |
|
|
// close connection after this reply. set on request and
|
122 |
|
|
// updated after response from handler if there's a
|
123 |
|
|
// "Connection: keep-alive" response header and a
|
124 |
|
|
// Content-Length.
|
125 |
|
|
closeAfterReply bool
|
126 |
|
|
|
127 |
|
|
// requestBodyLimitHit is set by requestTooLarge when
|
128 |
|
|
// maxBytesReader hits its max size. It is checked in
|
129 |
|
|
// WriteHeader, to make sure we don't consume the the
|
130 |
|
|
// remaining request body to try to advance to the next HTTP
|
131 |
|
|
// request. Instead, when this is set, we stop doing
|
132 |
|
|
// subsequent requests on this connection and stop reading
|
133 |
|
|
// input from it.
|
134 |
|
|
requestBodyLimitHit bool
|
135 |
|
|
}
|
136 |
|
|
|
137 |
|
|
// requestTooLarge is called by maxBytesReader when too much input has
|
138 |
|
|
// been read from the client.
|
139 |
|
|
func (w *response) requestTooLarge() {
|
140 |
|
|
w.closeAfterReply = true
|
141 |
|
|
w.requestBodyLimitHit = true
|
142 |
|
|
if !w.wroteHeader {
|
143 |
|
|
w.Header().Set("Connection", "close")
|
144 |
|
|
}
|
145 |
|
|
}
|
146 |
|
|
|
147 |
|
|
type writerOnly struct {
|
148 |
|
|
io.Writer
|
149 |
|
|
}
|
150 |
|
|
|
151 |
|
|
func (w *response) ReadFrom(src io.Reader) (n int64, err error) {
|
152 |
|
|
// Call WriteHeader before checking w.chunking if it hasn't
|
153 |
|
|
// been called yet, since WriteHeader is what sets w.chunking.
|
154 |
|
|
if !w.wroteHeader {
|
155 |
|
|
w.WriteHeader(StatusOK)
|
156 |
|
|
}
|
157 |
|
|
if !w.chunking && w.bodyAllowed() && !w.needSniff {
|
158 |
|
|
w.Flush()
|
159 |
|
|
if rf, ok := w.conn.rwc.(io.ReaderFrom); ok {
|
160 |
|
|
n, err = rf.ReadFrom(src)
|
161 |
|
|
w.written += n
|
162 |
|
|
return
|
163 |
|
|
}
|
164 |
|
|
}
|
165 |
|
|
// Fall back to default io.Copy implementation.
|
166 |
|
|
// Use wrapper to hide w.ReadFrom from io.Copy.
|
167 |
|
|
return io.Copy(writerOnly{w}, src)
|
168 |
|
|
}
|
169 |
|
|
|
170 |
|
|
// noLimit is an effective infinite upper bound for io.LimitedReader
|
171 |
|
|
const noLimit int64 = (1 << 63) - 1
|
172 |
|
|
|
173 |
|
|
// Create new connection from rwc.
|
174 |
|
|
func (srv *Server) newConn(rwc net.Conn) (c *conn, err error) {
|
175 |
|
|
c = new(conn)
|
176 |
|
|
c.remoteAddr = rwc.RemoteAddr().String()
|
177 |
|
|
c.server = srv
|
178 |
|
|
c.rwc = rwc
|
179 |
|
|
c.body = make([]byte, sniffLen)
|
180 |
|
|
c.lr = io.LimitReader(rwc, noLimit).(*io.LimitedReader)
|
181 |
|
|
br := bufio.NewReader(c.lr)
|
182 |
|
|
bw := bufio.NewWriter(rwc)
|
183 |
|
|
c.buf = bufio.NewReadWriter(br, bw)
|
184 |
|
|
return c, nil
|
185 |
|
|
}
|
186 |
|
|
|
187 |
|
|
// DefaultMaxHeaderBytes is the maximum permitted size of the headers
|
188 |
|
|
// in an HTTP request.
|
189 |
|
|
// This can be overridden by setting Server.MaxHeaderBytes.
|
190 |
|
|
const DefaultMaxHeaderBytes = 1 << 20 // 1 MB
|
191 |
|
|
|
192 |
|
|
func (srv *Server) maxHeaderBytes() int {
|
193 |
|
|
if srv.MaxHeaderBytes > 0 {
|
194 |
|
|
return srv.MaxHeaderBytes
|
195 |
|
|
}
|
196 |
|
|
return DefaultMaxHeaderBytes
|
197 |
|
|
}
|
198 |
|
|
|
199 |
|
|
// wrapper around io.ReaderCloser which on first read, sends an
|
200 |
|
|
// HTTP/1.1 100 Continue header
|
201 |
|
|
type expectContinueReader struct {
|
202 |
|
|
resp *response
|
203 |
|
|
readCloser io.ReadCloser
|
204 |
|
|
closed bool
|
205 |
|
|
}
|
206 |
|
|
|
207 |
|
|
func (ecr *expectContinueReader) Read(p []byte) (n int, err error) {
|
208 |
|
|
if ecr.closed {
|
209 |
|
|
return 0, errors.New("http: Read after Close on request Body")
|
210 |
|
|
}
|
211 |
|
|
if !ecr.resp.wroteContinue && !ecr.resp.conn.hijacked {
|
212 |
|
|
ecr.resp.wroteContinue = true
|
213 |
|
|
io.WriteString(ecr.resp.conn.buf, "HTTP/1.1 100 Continue\r\n\r\n")
|
214 |
|
|
ecr.resp.conn.buf.Flush()
|
215 |
|
|
}
|
216 |
|
|
return ecr.readCloser.Read(p)
|
217 |
|
|
}
|
218 |
|
|
|
219 |
|
|
func (ecr *expectContinueReader) Close() error {
|
220 |
|
|
ecr.closed = true
|
221 |
|
|
return ecr.readCloser.Close()
|
222 |
|
|
}
|
223 |
|
|
|
224 |
|
|
// TimeFormat is the time format to use with
|
225 |
|
|
// time.Parse and time.Time.Format when parsing
|
226 |
|
|
// or generating times in HTTP headers.
|
227 |
|
|
// It is like time.RFC1123 but hard codes GMT as the time zone.
|
228 |
|
|
const TimeFormat = "Mon, 02 Jan 2006 15:04:05 GMT"
|
229 |
|
|
|
230 |
|
|
var errTooLarge = errors.New("http: request too large")
|
231 |
|
|
|
232 |
|
|
// Read next request from connection.
|
233 |
|
|
func (c *conn) readRequest() (w *response, err error) {
|
234 |
|
|
if c.hijacked {
|
235 |
|
|
return nil, ErrHijacked
|
236 |
|
|
}
|
237 |
|
|
c.lr.N = int64(c.server.maxHeaderBytes()) + 4096 /* bufio slop */
|
238 |
|
|
var req *Request
|
239 |
|
|
if req, err = ReadRequest(c.buf.Reader); err != nil {
|
240 |
|
|
if c.lr.N == 0 {
|
241 |
|
|
return nil, errTooLarge
|
242 |
|
|
}
|
243 |
|
|
return nil, err
|
244 |
|
|
}
|
245 |
|
|
c.lr.N = noLimit
|
246 |
|
|
|
247 |
|
|
req.RemoteAddr = c.remoteAddr
|
248 |
|
|
req.TLS = c.tlsState
|
249 |
|
|
|
250 |
|
|
w = new(response)
|
251 |
|
|
w.conn = c
|
252 |
|
|
w.req = req
|
253 |
|
|
w.header = make(Header)
|
254 |
|
|
w.contentLength = -1
|
255 |
|
|
c.body = c.body[:0]
|
256 |
|
|
return w, nil
|
257 |
|
|
}
|
258 |
|
|
|
259 |
|
|
func (w *response) Header() Header {
|
260 |
|
|
return w.header
|
261 |
|
|
}
|
262 |
|
|
|
263 |
|
|
// maxPostHandlerReadBytes is the max number of Request.Body bytes not
|
264 |
|
|
// consumed by a handler that the server will read from the client
|
265 |
|
|
// in order to keep a connection alive. If there are more bytes than
|
266 |
|
|
// this then the server to be paranoid instead sends a "Connection:
|
267 |
|
|
// close" response.
|
268 |
|
|
//
|
269 |
|
|
// This number is approximately what a typical machine's TCP buffer
|
270 |
|
|
// size is anyway. (if we have the bytes on the machine, we might as
|
271 |
|
|
// well read them)
|
272 |
|
|
const maxPostHandlerReadBytes = 256 << 10
|
273 |
|
|
|
274 |
|
|
func (w *response) WriteHeader(code int) {
|
275 |
|
|
if w.conn.hijacked {
|
276 |
|
|
log.Print("http: response.WriteHeader on hijacked connection")
|
277 |
|
|
return
|
278 |
|
|
}
|
279 |
|
|
if w.wroteHeader {
|
280 |
|
|
log.Print("http: multiple response.WriteHeader calls")
|
281 |
|
|
return
|
282 |
|
|
}
|
283 |
|
|
w.wroteHeader = true
|
284 |
|
|
w.status = code
|
285 |
|
|
|
286 |
|
|
// Check for a explicit (and valid) Content-Length header.
|
287 |
|
|
var hasCL bool
|
288 |
|
|
var contentLength int64
|
289 |
|
|
if clenStr := w.header.Get("Content-Length"); clenStr != "" {
|
290 |
|
|
var err error
|
291 |
|
|
contentLength, err = strconv.ParseInt(clenStr, 10, 64)
|
292 |
|
|
if err == nil {
|
293 |
|
|
hasCL = true
|
294 |
|
|
} else {
|
295 |
|
|
log.Printf("http: invalid Content-Length of %q sent", clenStr)
|
296 |
|
|
w.header.Del("Content-Length")
|
297 |
|
|
}
|
298 |
|
|
}
|
299 |
|
|
|
300 |
|
|
if w.req.wantsHttp10KeepAlive() && (w.req.Method == "HEAD" || hasCL) {
|
301 |
|
|
_, connectionHeaderSet := w.header["Connection"]
|
302 |
|
|
if !connectionHeaderSet {
|
303 |
|
|
w.header.Set("Connection", "keep-alive")
|
304 |
|
|
}
|
305 |
|
|
} else if !w.req.ProtoAtLeast(1, 1) {
|
306 |
|
|
// Client did not ask to keep connection alive.
|
307 |
|
|
w.closeAfterReply = true
|
308 |
|
|
}
|
309 |
|
|
|
310 |
|
|
if w.header.Get("Connection") == "close" {
|
311 |
|
|
w.closeAfterReply = true
|
312 |
|
|
}
|
313 |
|
|
|
314 |
|
|
// Per RFC 2616, we should consume the request body before
|
315 |
|
|
// replying, if the handler hasn't already done so. But we
|
316 |
|
|
// don't want to do an unbounded amount of reading here for
|
317 |
|
|
// DoS reasons, so we only try up to a threshold.
|
318 |
|
|
if w.req.ContentLength != 0 && !w.closeAfterReply {
|
319 |
|
|
ecr, isExpecter := w.req.Body.(*expectContinueReader)
|
320 |
|
|
if !isExpecter || ecr.resp.wroteContinue {
|
321 |
|
|
n, _ := io.CopyN(ioutil.Discard, w.req.Body, maxPostHandlerReadBytes+1)
|
322 |
|
|
if n >= maxPostHandlerReadBytes {
|
323 |
|
|
w.requestTooLarge()
|
324 |
|
|
w.header.Set("Connection", "close")
|
325 |
|
|
} else {
|
326 |
|
|
w.req.Body.Close()
|
327 |
|
|
}
|
328 |
|
|
}
|
329 |
|
|
}
|
330 |
|
|
|
331 |
|
|
if code == StatusNotModified {
|
332 |
|
|
// Must not have body.
|
333 |
|
|
for _, header := range []string{"Content-Type", "Content-Length", "Transfer-Encoding"} {
|
334 |
|
|
if w.header.Get(header) != "" {
|
335 |
|
|
// TODO: return an error if WriteHeader gets a return parameter
|
336 |
|
|
// or set a flag on w to make future Writes() write an error page?
|
337 |
|
|
// for now just log and drop the header.
|
338 |
|
|
log.Printf("http: StatusNotModified response with header %q defined", header)
|
339 |
|
|
w.header.Del(header)
|
340 |
|
|
}
|
341 |
|
|
}
|
342 |
|
|
} else {
|
343 |
|
|
// If no content type, apply sniffing algorithm to body.
|
344 |
|
|
if w.header.Get("Content-Type") == "" && w.req.Method != "HEAD" {
|
345 |
|
|
w.needSniff = true
|
346 |
|
|
}
|
347 |
|
|
}
|
348 |
|
|
|
349 |
|
|
if _, ok := w.header["Date"]; !ok {
|
350 |
|
|
w.Header().Set("Date", time.Now().UTC().Format(TimeFormat))
|
351 |
|
|
}
|
352 |
|
|
|
353 |
|
|
te := w.header.Get("Transfer-Encoding")
|
354 |
|
|
hasTE := te != ""
|
355 |
|
|
if hasCL && hasTE && te != "identity" {
|
356 |
|
|
// TODO: return an error if WriteHeader gets a return parameter
|
357 |
|
|
// For now just ignore the Content-Length.
|
358 |
|
|
log.Printf("http: WriteHeader called with both Transfer-Encoding of %q and a Content-Length of %d",
|
359 |
|
|
te, contentLength)
|
360 |
|
|
w.header.Del("Content-Length")
|
361 |
|
|
hasCL = false
|
362 |
|
|
}
|
363 |
|
|
|
364 |
|
|
if w.req.Method == "HEAD" || code == StatusNotModified {
|
365 |
|
|
// do nothing
|
366 |
|
|
} else if hasCL {
|
367 |
|
|
w.contentLength = contentLength
|
368 |
|
|
w.header.Del("Transfer-Encoding")
|
369 |
|
|
} else if w.req.ProtoAtLeast(1, 1) {
|
370 |
|
|
// HTTP/1.1 or greater: use chunked transfer encoding
|
371 |
|
|
// to avoid closing the connection at EOF.
|
372 |
|
|
// TODO: this blows away any custom or stacked Transfer-Encoding they
|
373 |
|
|
// might have set. Deal with that as need arises once we have a valid
|
374 |
|
|
// use case.
|
375 |
|
|
w.chunking = true
|
376 |
|
|
w.header.Set("Transfer-Encoding", "chunked")
|
377 |
|
|
} else {
|
378 |
|
|
// HTTP version < 1.1: cannot do chunked transfer
|
379 |
|
|
// encoding and we don't know the Content-Length so
|
380 |
|
|
// signal EOF by closing connection.
|
381 |
|
|
w.closeAfterReply = true
|
382 |
|
|
w.header.Del("Transfer-Encoding") // in case already set
|
383 |
|
|
}
|
384 |
|
|
|
385 |
|
|
// Cannot use Content-Length with non-identity Transfer-Encoding.
|
386 |
|
|
if w.chunking {
|
387 |
|
|
w.header.Del("Content-Length")
|
388 |
|
|
}
|
389 |
|
|
if !w.req.ProtoAtLeast(1, 0) {
|
390 |
|
|
return
|
391 |
|
|
}
|
392 |
|
|
proto := "HTTP/1.0"
|
393 |
|
|
if w.req.ProtoAtLeast(1, 1) {
|
394 |
|
|
proto = "HTTP/1.1"
|
395 |
|
|
}
|
396 |
|
|
codestring := strconv.Itoa(code)
|
397 |
|
|
text, ok := statusText[code]
|
398 |
|
|
if !ok {
|
399 |
|
|
text = "status code " + codestring
|
400 |
|
|
}
|
401 |
|
|
io.WriteString(w.conn.buf, proto+" "+codestring+" "+text+"\r\n")
|
402 |
|
|
w.header.Write(w.conn.buf)
|
403 |
|
|
|
404 |
|
|
// If we need to sniff the body, leave the header open.
|
405 |
|
|
// Otherwise, end it here.
|
406 |
|
|
if !w.needSniff {
|
407 |
|
|
io.WriteString(w.conn.buf, "\r\n")
|
408 |
|
|
}
|
409 |
|
|
}
|
410 |
|
|
|
411 |
|
|
// sniff uses the first block of written data,
|
412 |
|
|
// stored in w.conn.body, to decide the Content-Type
|
413 |
|
|
// for the HTTP body.
|
414 |
|
|
func (w *response) sniff() {
|
415 |
|
|
if !w.needSniff {
|
416 |
|
|
return
|
417 |
|
|
}
|
418 |
|
|
w.needSniff = false
|
419 |
|
|
|
420 |
|
|
data := w.conn.body
|
421 |
|
|
fmt.Fprintf(w.conn.buf, "Content-Type: %s\r\n\r\n", DetectContentType(data))
|
422 |
|
|
|
423 |
|
|
if len(data) == 0 {
|
424 |
|
|
return
|
425 |
|
|
}
|
426 |
|
|
if w.chunking {
|
427 |
|
|
fmt.Fprintf(w.conn.buf, "%x\r\n", len(data))
|
428 |
|
|
}
|
429 |
|
|
_, err := w.conn.buf.Write(data)
|
430 |
|
|
if w.chunking && err == nil {
|
431 |
|
|
io.WriteString(w.conn.buf, "\r\n")
|
432 |
|
|
}
|
433 |
|
|
}
|
434 |
|
|
|
435 |
|
|
// bodyAllowed returns true if a Write is allowed for this response type.
|
436 |
|
|
// It's illegal to call this before the header has been flushed.
|
437 |
|
|
func (w *response) bodyAllowed() bool {
|
438 |
|
|
if !w.wroteHeader {
|
439 |
|
|
panic("")
|
440 |
|
|
}
|
441 |
|
|
return w.status != StatusNotModified && w.req.Method != "HEAD"
|
442 |
|
|
}
|
443 |
|
|
|
444 |
|
|
func (w *response) Write(data []byte) (n int, err error) {
|
445 |
|
|
if w.conn.hijacked {
|
446 |
|
|
log.Print("http: response.Write on hijacked connection")
|
447 |
|
|
return 0, ErrHijacked
|
448 |
|
|
}
|
449 |
|
|
if !w.wroteHeader {
|
450 |
|
|
w.WriteHeader(StatusOK)
|
451 |
|
|
}
|
452 |
|
|
if len(data) == 0 {
|
453 |
|
|
return 0, nil
|
454 |
|
|
}
|
455 |
|
|
if !w.bodyAllowed() {
|
456 |
|
|
return 0, ErrBodyNotAllowed
|
457 |
|
|
}
|
458 |
|
|
|
459 |
|
|
w.written += int64(len(data)) // ignoring errors, for errorKludge
|
460 |
|
|
if w.contentLength != -1 && w.written > w.contentLength {
|
461 |
|
|
return 0, ErrContentLength
|
462 |
|
|
}
|
463 |
|
|
|
464 |
|
|
var m int
|
465 |
|
|
if w.needSniff {
|
466 |
|
|
// We need to sniff the beginning of the output to
|
467 |
|
|
// determine the content type. Accumulate the
|
468 |
|
|
// initial writes in w.conn.body.
|
469 |
|
|
// Cap m so that append won't allocate.
|
470 |
|
|
m = cap(w.conn.body) - len(w.conn.body)
|
471 |
|
|
if m > len(data) {
|
472 |
|
|
m = len(data)
|
473 |
|
|
}
|
474 |
|
|
w.conn.body = append(w.conn.body, data[:m]...)
|
475 |
|
|
data = data[m:]
|
476 |
|
|
if len(data) == 0 {
|
477 |
|
|
// Copied everything into the buffer.
|
478 |
|
|
// Wait for next write.
|
479 |
|
|
return m, nil
|
480 |
|
|
}
|
481 |
|
|
|
482 |
|
|
// Filled the buffer; more data remains.
|
483 |
|
|
// Sniff the content (flushes the buffer)
|
484 |
|
|
// and then proceed with the remainder
|
485 |
|
|
// of the data as a normal Write.
|
486 |
|
|
// Calling sniff clears needSniff.
|
487 |
|
|
w.sniff()
|
488 |
|
|
}
|
489 |
|
|
|
490 |
|
|
// TODO(rsc): if chunking happened after the buffering,
|
491 |
|
|
// then there would be fewer chunk headers.
|
492 |
|
|
// On the other hand, it would make hijacking more difficult.
|
493 |
|
|
if w.chunking {
|
494 |
|
|
fmt.Fprintf(w.conn.buf, "%x\r\n", len(data)) // TODO(rsc): use strconv not fmt
|
495 |
|
|
}
|
496 |
|
|
n, err = w.conn.buf.Write(data)
|
497 |
|
|
if err == nil && w.chunking {
|
498 |
|
|
if n != len(data) {
|
499 |
|
|
err = io.ErrShortWrite
|
500 |
|
|
}
|
501 |
|
|
if err == nil {
|
502 |
|
|
io.WriteString(w.conn.buf, "\r\n")
|
503 |
|
|
}
|
504 |
|
|
}
|
505 |
|
|
|
506 |
|
|
return m + n, err
|
507 |
|
|
}
|
508 |
|
|
|
509 |
|
|
func (w *response) finishRequest() {
|
510 |
|
|
// If this was an HTTP/1.0 request with keep-alive and we sent a Content-Length
|
511 |
|
|
// back, we can make this a keep-alive response ...
|
512 |
|
|
if w.req.wantsHttp10KeepAlive() {
|
513 |
|
|
sentLength := w.header.Get("Content-Length") != ""
|
514 |
|
|
if sentLength && w.header.Get("Connection") == "keep-alive" {
|
515 |
|
|
w.closeAfterReply = false
|
516 |
|
|
}
|
517 |
|
|
}
|
518 |
|
|
if !w.wroteHeader {
|
519 |
|
|
w.WriteHeader(StatusOK)
|
520 |
|
|
}
|
521 |
|
|
if w.needSniff {
|
522 |
|
|
w.sniff()
|
523 |
|
|
}
|
524 |
|
|
if w.chunking {
|
525 |
|
|
io.WriteString(w.conn.buf, "0\r\n")
|
526 |
|
|
// trailer key/value pairs, followed by blank line
|
527 |
|
|
io.WriteString(w.conn.buf, "\r\n")
|
528 |
|
|
}
|
529 |
|
|
w.conn.buf.Flush()
|
530 |
|
|
// Close the body, unless we're about to close the whole TCP connection
|
531 |
|
|
// anyway.
|
532 |
|
|
if !w.closeAfterReply {
|
533 |
|
|
w.req.Body.Close()
|
534 |
|
|
}
|
535 |
|
|
if w.req.MultipartForm != nil {
|
536 |
|
|
w.req.MultipartForm.RemoveAll()
|
537 |
|
|
}
|
538 |
|
|
|
539 |
|
|
if w.contentLength != -1 && w.contentLength != w.written {
|
540 |
|
|
// Did not write enough. Avoid getting out of sync.
|
541 |
|
|
w.closeAfterReply = true
|
542 |
|
|
}
|
543 |
|
|
}
|
544 |
|
|
|
545 |
|
|
func (w *response) Flush() {
|
546 |
|
|
if !w.wroteHeader {
|
547 |
|
|
w.WriteHeader(StatusOK)
|
548 |
|
|
}
|
549 |
|
|
w.sniff()
|
550 |
|
|
w.conn.buf.Flush()
|
551 |
|
|
}
|
552 |
|
|
|
553 |
|
|
// Close the connection.
|
554 |
|
|
func (c *conn) close() {
|
555 |
|
|
if c.buf != nil {
|
556 |
|
|
c.buf.Flush()
|
557 |
|
|
c.buf = nil
|
558 |
|
|
}
|
559 |
|
|
if c.rwc != nil {
|
560 |
|
|
c.rwc.Close()
|
561 |
|
|
c.rwc = nil
|
562 |
|
|
}
|
563 |
|
|
}
|
564 |
|
|
|
565 |
|
|
// Serve a new connection.
|
566 |
|
|
func (c *conn) serve() {
|
567 |
|
|
defer func() {
|
568 |
|
|
err := recover()
|
569 |
|
|
if err == nil {
|
570 |
|
|
return
|
571 |
|
|
}
|
572 |
|
|
|
573 |
|
|
var buf bytes.Buffer
|
574 |
|
|
fmt.Fprintf(&buf, "http: panic serving %v: %v\n", c.remoteAddr, err)
|
575 |
|
|
buf.Write(debug.Stack())
|
576 |
|
|
log.Print(buf.String())
|
577 |
|
|
|
578 |
|
|
if c.rwc != nil { // may be nil if connection hijacked
|
579 |
|
|
c.rwc.Close()
|
580 |
|
|
}
|
581 |
|
|
}()
|
582 |
|
|
|
583 |
|
|
if tlsConn, ok := c.rwc.(*tls.Conn); ok {
|
584 |
|
|
if err := tlsConn.Handshake(); err != nil {
|
585 |
|
|
c.close()
|
586 |
|
|
return
|
587 |
|
|
}
|
588 |
|
|
c.tlsState = new(tls.ConnectionState)
|
589 |
|
|
*c.tlsState = tlsConn.ConnectionState()
|
590 |
|
|
}
|
591 |
|
|
|
592 |
|
|
for {
|
593 |
|
|
w, err := c.readRequest()
|
594 |
|
|
if err != nil {
|
595 |
|
|
msg := "400 Bad Request"
|
596 |
|
|
if err == errTooLarge {
|
597 |
|
|
// Their HTTP client may or may not be
|
598 |
|
|
// able to read this if we're
|
599 |
|
|
// responding to them and hanging up
|
600 |
|
|
// while they're still writing their
|
601 |
|
|
// request. Undefined behavior.
|
602 |
|
|
msg = "413 Request Entity Too Large"
|
603 |
|
|
} else if err == io.ErrUnexpectedEOF {
|
604 |
|
|
break // Don't reply
|
605 |
|
|
} else if neterr, ok := err.(net.Error); ok && neterr.Timeout() {
|
606 |
|
|
break // Don't reply
|
607 |
|
|
}
|
608 |
|
|
fmt.Fprintf(c.rwc, "HTTP/1.1 %s\r\n\r\n", msg)
|
609 |
|
|
break
|
610 |
|
|
}
|
611 |
|
|
|
612 |
|
|
// Expect 100 Continue support
|
613 |
|
|
req := w.req
|
614 |
|
|
if req.expectsContinue() {
|
615 |
|
|
if req.ProtoAtLeast(1, 1) {
|
616 |
|
|
// Wrap the Body reader with one that replies on the connection
|
617 |
|
|
req.Body = &expectContinueReader{readCloser: req.Body, resp: w}
|
618 |
|
|
}
|
619 |
|
|
if req.ContentLength == 0 {
|
620 |
|
|
w.Header().Set("Connection", "close")
|
621 |
|
|
w.WriteHeader(StatusBadRequest)
|
622 |
|
|
w.finishRequest()
|
623 |
|
|
break
|
624 |
|
|
}
|
625 |
|
|
req.Header.Del("Expect")
|
626 |
|
|
} else if req.Header.Get("Expect") != "" {
|
627 |
|
|
// TODO(bradfitz): let ServeHTTP handlers handle
|
628 |
|
|
// requests with non-standard expectation[s]? Seems
|
629 |
|
|
// theoretical at best, and doesn't fit into the
|
630 |
|
|
// current ServeHTTP model anyway. We'd need to
|
631 |
|
|
// make the ResponseWriter an optional
|
632 |
|
|
// "ExpectReplier" interface or something.
|
633 |
|
|
//
|
634 |
|
|
// For now we'll just obey RFC 2616 14.20 which says
|
635 |
|
|
// "If a server receives a request containing an
|
636 |
|
|
// Expect field that includes an expectation-
|
637 |
|
|
// extension that it does not support, it MUST
|
638 |
|
|
// respond with a 417 (Expectation Failed) status."
|
639 |
|
|
w.Header().Set("Connection", "close")
|
640 |
|
|
w.WriteHeader(StatusExpectationFailed)
|
641 |
|
|
w.finishRequest()
|
642 |
|
|
break
|
643 |
|
|
}
|
644 |
|
|
|
645 |
|
|
handler := c.server.Handler
|
646 |
|
|
if handler == nil {
|
647 |
|
|
handler = DefaultServeMux
|
648 |
|
|
}
|
649 |
|
|
|
650 |
|
|
// HTTP cannot have multiple simultaneous active requests.[*]
|
651 |
|
|
// Until the server replies to this request, it can't read another,
|
652 |
|
|
// so we might as well run the handler in this goroutine.
|
653 |
|
|
// [*] Not strictly true: HTTP pipelining. We could let them all process
|
654 |
|
|
// in parallel even if their responses need to be serialized.
|
655 |
|
|
handler.ServeHTTP(w, w.req)
|
656 |
|
|
if c.hijacked {
|
657 |
|
|
return
|
658 |
|
|
}
|
659 |
|
|
w.finishRequest()
|
660 |
|
|
if w.closeAfterReply {
|
661 |
|
|
break
|
662 |
|
|
}
|
663 |
|
|
}
|
664 |
|
|
c.close()
|
665 |
|
|
}
|
666 |
|
|
|
667 |
|
|
// Hijack implements the Hijacker.Hijack method. Our response is both a ResponseWriter
|
668 |
|
|
// and a Hijacker.
|
669 |
|
|
func (w *response) Hijack() (rwc net.Conn, buf *bufio.ReadWriter, err error) {
|
670 |
|
|
if w.conn.hijacked {
|
671 |
|
|
return nil, nil, ErrHijacked
|
672 |
|
|
}
|
673 |
|
|
w.conn.hijacked = true
|
674 |
|
|
rwc = w.conn.rwc
|
675 |
|
|
buf = w.conn.buf
|
676 |
|
|
w.conn.rwc = nil
|
677 |
|
|
w.conn.buf = nil
|
678 |
|
|
return
|
679 |
|
|
}
|
680 |
|
|
|
681 |
|
|
// The HandlerFunc type is an adapter to allow the use of
|
682 |
|
|
// ordinary functions as HTTP handlers. If f is a function
|
683 |
|
|
// with the appropriate signature, HandlerFunc(f) is a
|
684 |
|
|
// Handler object that calls f.
|
685 |
|
|
type HandlerFunc func(ResponseWriter, *Request)
|
686 |
|
|
|
687 |
|
|
// ServeHTTP calls f(w, r).
|
688 |
|
|
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
|
689 |
|
|
f(w, r)
|
690 |
|
|
}
|
691 |
|
|
|
692 |
|
|
// Helper handlers
|
693 |
|
|
|
694 |
|
|
// Error replies to the request with the specified error message and HTTP code.
|
695 |
|
|
func Error(w ResponseWriter, error string, code int) {
|
696 |
|
|
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
697 |
|
|
w.WriteHeader(code)
|
698 |
|
|
fmt.Fprintln(w, error)
|
699 |
|
|
}
|
700 |
|
|
|
701 |
|
|
// NotFound replies to the request with an HTTP 404 not found error.
|
702 |
|
|
func NotFound(w ResponseWriter, r *Request) { Error(w, "404 page not found", StatusNotFound) }
|
703 |
|
|
|
704 |
|
|
// NotFoundHandler returns a simple request handler
|
705 |
|
|
// that replies to each request with a ``404 page not found'' reply.
|
706 |
|
|
func NotFoundHandler() Handler { return HandlerFunc(NotFound) }
|
707 |
|
|
|
708 |
|
|
// StripPrefix returns a handler that serves HTTP requests
|
709 |
|
|
// by removing the given prefix from the request URL's Path
|
710 |
|
|
// and invoking the handler h. StripPrefix handles a
|
711 |
|
|
// request for a path that doesn't begin with prefix by
|
712 |
|
|
// replying with an HTTP 404 not found error.
|
713 |
|
|
func StripPrefix(prefix string, h Handler) Handler {
|
714 |
|
|
return HandlerFunc(func(w ResponseWriter, r *Request) {
|
715 |
|
|
if !strings.HasPrefix(r.URL.Path, prefix) {
|
716 |
|
|
NotFound(w, r)
|
717 |
|
|
return
|
718 |
|
|
}
|
719 |
|
|
r.URL.Path = r.URL.Path[len(prefix):]
|
720 |
|
|
h.ServeHTTP(w, r)
|
721 |
|
|
})
|
722 |
|
|
}
|
723 |
|
|
|
724 |
|
|
// Redirect replies to the request with a redirect to url,
|
725 |
|
|
// which may be a path relative to the request path.
|
726 |
|
|
func Redirect(w ResponseWriter, r *Request, urlStr string, code int) {
|
727 |
|
|
if u, err := url.Parse(urlStr); err == nil {
|
728 |
|
|
// If url was relative, make absolute by
|
729 |
|
|
// combining with request path.
|
730 |
|
|
// The browser would probably do this for us,
|
731 |
|
|
// but doing it ourselves is more reliable.
|
732 |
|
|
|
733 |
|
|
// NOTE(rsc): RFC 2616 says that the Location
|
734 |
|
|
// line must be an absolute URI, like
|
735 |
|
|
// "http://www.google.com/redirect/",
|
736 |
|
|
// not a path like "/redirect/".
|
737 |
|
|
// Unfortunately, we don't know what to
|
738 |
|
|
// put in the host name section to get the
|
739 |
|
|
// client to connect to us again, so we can't
|
740 |
|
|
// know the right absolute URI to send back.
|
741 |
|
|
// Because of this problem, no one pays attention
|
742 |
|
|
// to the RFC; they all send back just a new path.
|
743 |
|
|
// So do we.
|
744 |
|
|
oldpath := r.URL.Path
|
745 |
|
|
if oldpath == "" { // should not happen, but avoid a crash if it does
|
746 |
|
|
oldpath = "/"
|
747 |
|
|
}
|
748 |
|
|
if u.Scheme == "" {
|
749 |
|
|
// no leading http://server
|
750 |
|
|
if urlStr == "" || urlStr[0] != '/' {
|
751 |
|
|
// make relative path absolute
|
752 |
|
|
olddir, _ := path.Split(oldpath)
|
753 |
|
|
urlStr = olddir + urlStr
|
754 |
|
|
}
|
755 |
|
|
|
756 |
|
|
var query string
|
757 |
|
|
if i := strings.Index(urlStr, "?"); i != -1 {
|
758 |
|
|
urlStr, query = urlStr[:i], urlStr[i:]
|
759 |
|
|
}
|
760 |
|
|
|
761 |
|
|
// clean up but preserve trailing slash
|
762 |
|
|
trailing := urlStr[len(urlStr)-1] == '/'
|
763 |
|
|
urlStr = path.Clean(urlStr)
|
764 |
|
|
if trailing && urlStr[len(urlStr)-1] != '/' {
|
765 |
|
|
urlStr += "/"
|
766 |
|
|
}
|
767 |
|
|
urlStr += query
|
768 |
|
|
}
|
769 |
|
|
}
|
770 |
|
|
|
771 |
|
|
w.Header().Set("Location", urlStr)
|
772 |
|
|
w.WriteHeader(code)
|
773 |
|
|
|
774 |
|
|
// RFC2616 recommends that a short note "SHOULD" be included in the
|
775 |
|
|
// response because older user agents may not understand 301/307.
|
776 |
|
|
// Shouldn't send the response for POST or HEAD; that leaves GET.
|
777 |
|
|
if r.Method == "GET" {
|
778 |
|
|
note := "" + statusText[code] + ".\n"
|
779 |
|
|
fmt.Fprintln(w, note)
|
780 |
|
|
}
|
781 |
|
|
}
|
782 |
|
|
|
783 |
|
|
var htmlReplacer = strings.NewReplacer(
|
784 |
|
|
"&", "&",
|
785 |
|
|
"<", "<",
|
786 |
|
|
">", ">",
|
787 |
|
|
`"`, """,
|
788 |
|
|
"'", "'",
|
789 |
|
|
)
|
790 |
|
|
|
791 |
|
|
func htmlEscape(s string) string {
|
792 |
|
|
return htmlReplacer.Replace(s)
|
793 |
|
|
}
|
794 |
|
|
|
795 |
|
|
// Redirect to a fixed URL
|
796 |
|
|
type redirectHandler struct {
|
797 |
|
|
url string
|
798 |
|
|
code int
|
799 |
|
|
}
|
800 |
|
|
|
801 |
|
|
func (rh *redirectHandler) ServeHTTP(w ResponseWriter, r *Request) {
|
802 |
|
|
Redirect(w, r, rh.url, rh.code)
|
803 |
|
|
}
|
804 |
|
|
|
805 |
|
|
// RedirectHandler returns a request handler that redirects
|
806 |
|
|
// each request it receives to the given url using the given
|
807 |
|
|
// status code.
|
808 |
|
|
func RedirectHandler(url string, code int) Handler {
|
809 |
|
|
return &redirectHandler{url, code}
|
810 |
|
|
}
|
811 |
|
|
|
812 |
|
|
// ServeMux is an HTTP request multiplexer.
|
813 |
|
|
// It matches the URL of each incoming request against a list of registered
|
814 |
|
|
// patterns and calls the handler for the pattern that
|
815 |
|
|
// most closely matches the URL.
|
816 |
|
|
//
|
817 |
|
|
// Patterns named fixed, rooted paths, like "/favicon.ico",
|
818 |
|
|
// or rooted subtrees, like "/images/" (note the trailing slash).
|
819 |
|
|
// Longer patterns take precedence over shorter ones, so that
|
820 |
|
|
// if there are handlers registered for both "/images/"
|
821 |
|
|
// and "/images/thumbnails/", the latter handler will be
|
822 |
|
|
// called for paths beginning "/images/thumbnails/" and the
|
823 |
|
|
// former will receiver requests for any other paths in the
|
824 |
|
|
// "/images/" subtree.
|
825 |
|
|
//
|
826 |
|
|
// Patterns may optionally begin with a host name, restricting matches to
|
827 |
|
|
// URLs on that host only. Host-specific patterns take precedence over
|
828 |
|
|
// general patterns, so that a handler might register for the two patterns
|
829 |
|
|
// "/codesearch" and "codesearch.google.com/" without also taking over
|
830 |
|
|
// requests for "http://www.google.com/".
|
831 |
|
|
//
|
832 |
|
|
// ServeMux also takes care of sanitizing the URL request path,
|
833 |
|
|
// redirecting any request containing . or .. elements to an
|
834 |
|
|
// equivalent .- and ..-free URL.
|
835 |
|
|
type ServeMux struct {
|
836 |
|
|
m map[string]Handler
|
837 |
|
|
}
|
838 |
|
|
|
839 |
|
|
// NewServeMux allocates and returns a new ServeMux.
|
840 |
|
|
func NewServeMux() *ServeMux { return &ServeMux{make(map[string]Handler)} }
|
841 |
|
|
|
842 |
|
|
// DefaultServeMux is the default ServeMux used by Serve.
|
843 |
|
|
var DefaultServeMux = NewServeMux()
|
844 |
|
|
|
845 |
|
|
// Does path match pattern?
|
846 |
|
|
func pathMatch(pattern, path string) bool {
|
847 |
|
|
if len(pattern) == 0 {
|
848 |
|
|
// should not happen
|
849 |
|
|
return false
|
850 |
|
|
}
|
851 |
|
|
n := len(pattern)
|
852 |
|
|
if pattern[n-1] != '/' {
|
853 |
|
|
return pattern == path
|
854 |
|
|
}
|
855 |
|
|
return len(path) >= n && path[0:n] == pattern
|
856 |
|
|
}
|
857 |
|
|
|
858 |
|
|
// Return the canonical path for p, eliminating . and .. elements.
|
859 |
|
|
func cleanPath(p string) string {
|
860 |
|
|
if p == "" {
|
861 |
|
|
return "/"
|
862 |
|
|
}
|
863 |
|
|
if p[0] != '/' {
|
864 |
|
|
p = "/" + p
|
865 |
|
|
}
|
866 |
|
|
np := path.Clean(p)
|
867 |
|
|
// path.Clean removes trailing slash except for root;
|
868 |
|
|
// put the trailing slash back if necessary.
|
869 |
|
|
if p[len(p)-1] == '/' && np != "/" {
|
870 |
|
|
np += "/"
|
871 |
|
|
}
|
872 |
|
|
return np
|
873 |
|
|
}
|
874 |
|
|
|
875 |
|
|
// Find a handler on a handler map given a path string
|
876 |
|
|
// Most-specific (longest) pattern wins
|
877 |
|
|
func (mux *ServeMux) match(path string) Handler {
|
878 |
|
|
var h Handler
|
879 |
|
|
var n = 0
|
880 |
|
|
for k, v := range mux.m {
|
881 |
|
|
if !pathMatch(k, path) {
|
882 |
|
|
continue
|
883 |
|
|
}
|
884 |
|
|
if h == nil || len(k) > n {
|
885 |
|
|
n = len(k)
|
886 |
|
|
h = v
|
887 |
|
|
}
|
888 |
|
|
}
|
889 |
|
|
return h
|
890 |
|
|
}
|
891 |
|
|
|
892 |
|
|
// ServeHTTP dispatches the request to the handler whose
|
893 |
|
|
// pattern most closely matches the request URL.
|
894 |
|
|
func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
|
895 |
|
|
// Clean path to canonical form and redirect.
|
896 |
|
|
if p := cleanPath(r.URL.Path); p != r.URL.Path {
|
897 |
|
|
w.Header().Set("Location", p)
|
898 |
|
|
w.WriteHeader(StatusMovedPermanently)
|
899 |
|
|
return
|
900 |
|
|
}
|
901 |
|
|
// Host-specific pattern takes precedence over generic ones
|
902 |
|
|
h := mux.match(r.Host + r.URL.Path)
|
903 |
|
|
if h == nil {
|
904 |
|
|
h = mux.match(r.URL.Path)
|
905 |
|
|
}
|
906 |
|
|
if h == nil {
|
907 |
|
|
h = NotFoundHandler()
|
908 |
|
|
}
|
909 |
|
|
h.ServeHTTP(w, r)
|
910 |
|
|
}
|
911 |
|
|
|
912 |
|
|
// Handle registers the handler for the given pattern.
|
913 |
|
|
func (mux *ServeMux) Handle(pattern string, handler Handler) {
|
914 |
|
|
if pattern == "" {
|
915 |
|
|
panic("http: invalid pattern " + pattern)
|
916 |
|
|
}
|
917 |
|
|
|
918 |
|
|
mux.m[pattern] = handler
|
919 |
|
|
|
920 |
|
|
// Helpful behavior:
|
921 |
|
|
// If pattern is /tree/, insert permanent redirect for /tree.
|
922 |
|
|
n := len(pattern)
|
923 |
|
|
if n > 0 && pattern[n-1] == '/' {
|
924 |
|
|
mux.m[pattern[0:n-1]] = RedirectHandler(pattern, StatusMovedPermanently)
|
925 |
|
|
}
|
926 |
|
|
}
|
927 |
|
|
|
928 |
|
|
// HandleFunc registers the handler function for the given pattern.
|
929 |
|
|
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
|
930 |
|
|
mux.Handle(pattern, HandlerFunc(handler))
|
931 |
|
|
}
|
932 |
|
|
|
933 |
|
|
// Handle registers the handler for the given pattern
|
934 |
|
|
// in the DefaultServeMux.
|
935 |
|
|
// The documentation for ServeMux explains how patterns are matched.
|
936 |
|
|
func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
|
937 |
|
|
|
938 |
|
|
// HandleFunc registers the handler function for the given pattern
|
939 |
|
|
// in the DefaultServeMux.
|
940 |
|
|
// The documentation for ServeMux explains how patterns are matched.
|
941 |
|
|
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
|
942 |
|
|
DefaultServeMux.HandleFunc(pattern, handler)
|
943 |
|
|
}
|
944 |
|
|
|
945 |
|
|
// Serve accepts incoming HTTP connections on the listener l,
|
946 |
|
|
// creating a new service thread for each. The service threads
|
947 |
|
|
// read requests and then call handler to reply to them.
|
948 |
|
|
// Handler is typically nil, in which case the DefaultServeMux is used.
|
949 |
|
|
func Serve(l net.Listener, handler Handler) error {
|
950 |
|
|
srv := &Server{Handler: handler}
|
951 |
|
|
return srv.Serve(l)
|
952 |
|
|
}
|
953 |
|
|
|
954 |
|
|
// A Server defines parameters for running an HTTP server.
|
955 |
|
|
type Server struct {
|
956 |
|
|
Addr string // TCP address to listen on, ":http" if empty
|
957 |
|
|
Handler Handler // handler to invoke, http.DefaultServeMux if nil
|
958 |
|
|
ReadTimeout time.Duration // maximum duration before timing out read of the request
|
959 |
|
|
WriteTimeout time.Duration // maximum duration before timing out write of the response
|
960 |
|
|
MaxHeaderBytes int // maximum size of request headers, DefaultMaxHeaderBytes if 0
|
961 |
|
|
}
|
962 |
|
|
|
963 |
|
|
// ListenAndServe listens on the TCP network address srv.Addr and then
|
964 |
|
|
// calls Serve to handle requests on incoming connections. If
|
965 |
|
|
// srv.Addr is blank, ":http" is used.
|
966 |
|
|
func (srv *Server) ListenAndServe() error {
|
967 |
|
|
addr := srv.Addr
|
968 |
|
|
if addr == "" {
|
969 |
|
|
addr = ":http"
|
970 |
|
|
}
|
971 |
|
|
l, e := net.Listen("tcp", addr)
|
972 |
|
|
if e != nil {
|
973 |
|
|
return e
|
974 |
|
|
}
|
975 |
|
|
return srv.Serve(l)
|
976 |
|
|
}
|
977 |
|
|
|
978 |
|
|
// Serve accepts incoming connections on the Listener l, creating a
|
979 |
|
|
// new service thread for each. The service threads read requests and
|
980 |
|
|
// then call srv.Handler to reply to them.
|
981 |
|
|
func (srv *Server) Serve(l net.Listener) error {
|
982 |
|
|
defer l.Close()
|
983 |
|
|
for {
|
984 |
|
|
rw, e := l.Accept()
|
985 |
|
|
if e != nil {
|
986 |
|
|
if ne, ok := e.(net.Error); ok && ne.Temporary() {
|
987 |
|
|
log.Printf("http: Accept error: %v", e)
|
988 |
|
|
continue
|
989 |
|
|
}
|
990 |
|
|
return e
|
991 |
|
|
}
|
992 |
|
|
if srv.ReadTimeout != 0 {
|
993 |
|
|
rw.SetReadDeadline(time.Now().Add(srv.ReadTimeout))
|
994 |
|
|
}
|
995 |
|
|
if srv.WriteTimeout != 0 {
|
996 |
|
|
rw.SetWriteDeadline(time.Now().Add(srv.WriteTimeout))
|
997 |
|
|
}
|
998 |
|
|
c, err := srv.newConn(rw)
|
999 |
|
|
if err != nil {
|
1000 |
|
|
continue
|
1001 |
|
|
}
|
1002 |
|
|
go c.serve()
|
1003 |
|
|
}
|
1004 |
|
|
panic("not reached")
|
1005 |
|
|
}
|
1006 |
|
|
|
1007 |
|
|
// ListenAndServe listens on the TCP network address addr
|
1008 |
|
|
// and then calls Serve with handler to handle requests
|
1009 |
|
|
// on incoming connections. Handler is typically nil,
|
1010 |
|
|
// in which case the DefaultServeMux is used.
|
1011 |
|
|
//
|
1012 |
|
|
// A trivial example server is:
|
1013 |
|
|
//
|
1014 |
|
|
// package main
|
1015 |
|
|
//
|
1016 |
|
|
// import (
|
1017 |
|
|
// "io"
|
1018 |
|
|
// "net/http"
|
1019 |
|
|
// "log"
|
1020 |
|
|
// )
|
1021 |
|
|
//
|
1022 |
|
|
// // hello world, the web server
|
1023 |
|
|
// func HelloServer(w http.ResponseWriter, req *http.Request) {
|
1024 |
|
|
// io.WriteString(w, "hello, world!\n")
|
1025 |
|
|
// }
|
1026 |
|
|
//
|
1027 |
|
|
// func main() {
|
1028 |
|
|
// http.HandleFunc("/hello", HelloServer)
|
1029 |
|
|
// err := http.ListenAndServe(":12345", nil)
|
1030 |
|
|
// if err != nil {
|
1031 |
|
|
// log.Fatal("ListenAndServe: ", err)
|
1032 |
|
|
// }
|
1033 |
|
|
// }
|
1034 |
|
|
func ListenAndServe(addr string, handler Handler) error {
|
1035 |
|
|
server := &Server{Addr: addr, Handler: handler}
|
1036 |
|
|
return server.ListenAndServe()
|
1037 |
|
|
}
|
1038 |
|
|
|
1039 |
|
|
// ListenAndServeTLS acts identically to ListenAndServe, except that it
|
1040 |
|
|
// expects HTTPS connections. Additionally, files containing a certificate and
|
1041 |
|
|
// matching private key for the server must be provided. If the certificate
|
1042 |
|
|
// is signed by a certificate authority, the certFile should be the concatenation
|
1043 |
|
|
// of the server's certificate followed by the CA's certificate.
|
1044 |
|
|
//
|
1045 |
|
|
// A trivial example server is:
|
1046 |
|
|
//
|
1047 |
|
|
// import (
|
1048 |
|
|
// "log"
|
1049 |
|
|
// "net/http"
|
1050 |
|
|
// )
|
1051 |
|
|
//
|
1052 |
|
|
// func handler(w http.ResponseWriter, req *http.Request) {
|
1053 |
|
|
// w.Header().Set("Content-Type", "text/plain")
|
1054 |
|
|
// w.Write([]byte("This is an example server.\n"))
|
1055 |
|
|
// }
|
1056 |
|
|
//
|
1057 |
|
|
// func main() {
|
1058 |
|
|
// http.HandleFunc("/", handler)
|
1059 |
|
|
// log.Printf("About to listen on 10443. Go to https://127.0.0.1:10443/")
|
1060 |
|
|
// err := http.ListenAndServeTLS(":10443", "cert.pem", "key.pem", nil)
|
1061 |
|
|
// if err != nil {
|
1062 |
|
|
// log.Fatal(err)
|
1063 |
|
|
// }
|
1064 |
|
|
// }
|
1065 |
|
|
//
|
1066 |
|
|
// One can use generate_cert.go in crypto/tls to generate cert.pem and key.pem.
|
1067 |
|
|
func ListenAndServeTLS(addr string, certFile string, keyFile string, handler Handler) error {
|
1068 |
|
|
server := &Server{Addr: addr, Handler: handler}
|
1069 |
|
|
return server.ListenAndServeTLS(certFile, keyFile)
|
1070 |
|
|
}
|
1071 |
|
|
|
1072 |
|
|
// ListenAndServeTLS listens on the TCP network address srv.Addr and
|
1073 |
|
|
// then calls Serve to handle requests on incoming TLS connections.
|
1074 |
|
|
//
|
1075 |
|
|
// Filenames containing a certificate and matching private key for
|
1076 |
|
|
// the server must be provided. If the certificate is signed by a
|
1077 |
|
|
// certificate authority, the certFile should be the concatenation
|
1078 |
|
|
// of the server's certificate followed by the CA's certificate.
|
1079 |
|
|
//
|
1080 |
|
|
// If srv.Addr is blank, ":https" is used.
|
1081 |
|
|
func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error {
|
1082 |
|
|
addr := srv.Addr
|
1083 |
|
|
if addr == "" {
|
1084 |
|
|
addr = ":https"
|
1085 |
|
|
}
|
1086 |
|
|
config := &tls.Config{
|
1087 |
|
|
Rand: rand.Reader,
|
1088 |
|
|
NextProtos: []string{"http/1.1"},
|
1089 |
|
|
}
|
1090 |
|
|
|
1091 |
|
|
var err error
|
1092 |
|
|
config.Certificates = make([]tls.Certificate, 1)
|
1093 |
|
|
config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
|
1094 |
|
|
if err != nil {
|
1095 |
|
|
return err
|
1096 |
|
|
}
|
1097 |
|
|
|
1098 |
|
|
conn, err := net.Listen("tcp", addr)
|
1099 |
|
|
if err != nil {
|
1100 |
|
|
return err
|
1101 |
|
|
}
|
1102 |
|
|
|
1103 |
|
|
tlsListener := tls.NewListener(conn, config)
|
1104 |
|
|
return srv.Serve(tlsListener)
|
1105 |
|
|
}
|
1106 |
|
|
|
1107 |
|
|
// TimeoutHandler returns a Handler that runs h with the given time limit.
|
1108 |
|
|
//
|
1109 |
|
|
// The new Handler calls h.ServeHTTP to handle each request, but if a
|
1110 |
|
|
// call runs for more than ns nanoseconds, the handler responds with
|
1111 |
|
|
// a 503 Service Unavailable error and the given message in its body.
|
1112 |
|
|
// (If msg is empty, a suitable default message will be sent.)
|
1113 |
|
|
// After such a timeout, writes by h to its ResponseWriter will return
|
1114 |
|
|
// ErrHandlerTimeout.
|
1115 |
|
|
func TimeoutHandler(h Handler, dt time.Duration, msg string) Handler {
|
1116 |
|
|
f := func() <-chan time.Time {
|
1117 |
|
|
return time.After(dt)
|
1118 |
|
|
}
|
1119 |
|
|
return &timeoutHandler{h, f, msg}
|
1120 |
|
|
}
|
1121 |
|
|
|
1122 |
|
|
// ErrHandlerTimeout is returned on ResponseWriter Write calls
|
1123 |
|
|
// in handlers which have timed out.
|
1124 |
|
|
var ErrHandlerTimeout = errors.New("http: Handler timeout")
|
1125 |
|
|
|
1126 |
|
|
type timeoutHandler struct {
|
1127 |
|
|
handler Handler
|
1128 |
|
|
timeout func() <-chan time.Time // returns channel producing a timeout
|
1129 |
|
|
body string
|
1130 |
|
|
}
|
1131 |
|
|
|
1132 |
|
|
func (h *timeoutHandler) errorBody() string {
|
1133 |
|
|
if h.body != "" {
|
1134 |
|
|
return h.body
|
1135 |
|
|
}
|
1136 |
|
|
return "TimeoutTimeout"
|
1137 |
|
|
}
|
1138 |
|
|
|
1139 |
|
|
func (h *timeoutHandler) ServeHTTP(w ResponseWriter, r *Request) {
|
1140 |
|
|
done := make(chan bool)
|
1141 |
|
|
tw := &timeoutWriter{w: w}
|
1142 |
|
|
go func() {
|
1143 |
|
|
h.handler.ServeHTTP(tw, r)
|
1144 |
|
|
done <- true
|
1145 |
|
|
}()
|
1146 |
|
|
select {
|
1147 |
|
|
case <-done:
|
1148 |
|
|
return
|
1149 |
|
|
case <-h.timeout():
|
1150 |
|
|
tw.mu.Lock()
|
1151 |
|
|
defer tw.mu.Unlock()
|
1152 |
|
|
if !tw.wroteHeader {
|
1153 |
|
|
tw.w.WriteHeader(StatusServiceUnavailable)
|
1154 |
|
|
tw.w.Write([]byte(h.errorBody()))
|
1155 |
|
|
}
|
1156 |
|
|
tw.timedOut = true
|
1157 |
|
|
}
|
1158 |
|
|
}
|
1159 |
|
|
|
1160 |
|
|
type timeoutWriter struct {
|
1161 |
|
|
w ResponseWriter
|
1162 |
|
|
|
1163 |
|
|
mu sync.Mutex
|
1164 |
|
|
timedOut bool
|
1165 |
|
|
wroteHeader bool
|
1166 |
|
|
}
|
1167 |
|
|
|
1168 |
|
|
func (tw *timeoutWriter) Header() Header {
|
1169 |
|
|
return tw.w.Header()
|
1170 |
|
|
}
|
1171 |
|
|
|
1172 |
|
|
func (tw *timeoutWriter) Write(p []byte) (int, error) {
|
1173 |
|
|
tw.mu.Lock()
|
1174 |
|
|
timedOut := tw.timedOut
|
1175 |
|
|
tw.mu.Unlock()
|
1176 |
|
|
if timedOut {
|
1177 |
|
|
return 0, ErrHandlerTimeout
|
1178 |
|
|
}
|
1179 |
|
|
return tw.w.Write(p)
|
1180 |
|
|
}
|
1181 |
|
|
|
1182 |
|
|
func (tw *timeoutWriter) WriteHeader(code int) {
|
1183 |
|
|
tw.mu.Lock()
|
1184 |
|
|
if tw.timedOut || tw.wroteHeader {
|
1185 |
|
|
tw.mu.Unlock()
|
1186 |
|
|
return
|
1187 |
|
|
}
|
1188 |
|
|
tw.wroteHeader = true
|
1189 |
|
|
tw.mu.Unlock()
|
1190 |
|
|
tw.w.WriteHeader(code)
|
1191 |
|
|
}
|