server.go 35 KB
Newer Older
1 2 3 4
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

Russ Cox's avatar
Russ Cox committed
5
// HTTP server.  See RFC 2616.
6

Russ Cox's avatar
Russ Cox committed
7 8
// TODO(rsc):
//	logging
9 10 11 12

package http

import (
13
	"bufio"
Brad Fitzpatrick's avatar
Brad Fitzpatrick committed
14
	"bytes"
15
	"crypto/tls"
16
	"errors"
17 18
	"fmt"
	"io"
19
	"io/ioutil"
20 21
	"log"
	"net"
22
	"net/url"
23
	"path"
24
	"runtime/debug"
25 26
	"strconv"
	"strings"
27
	"sync"
28
	"time"
29 30
)

Russ Cox's avatar
Russ Cox committed
31 32
// Errors introduced by the HTTP server.
var (
33 34 35 36
	ErrWriteAfterFlush = errors.New("Conn.Write called after Flush")
	ErrBodyNotAllowed  = errors.New("http: response status code does not allow body")
	ErrHijacked        = errors.New("Conn has been hijacked")
	ErrContentLength   = errors.New("Conn.Write wrote more than the declared Content-Length")
Russ Cox's avatar
Russ Cox committed
37
)
Russ Cox's avatar
Russ Cox committed
38

Rob Pike's avatar
typo  
Rob Pike committed
39
// Objects implementing the Handler interface can be
Russ Cox's avatar
Russ Cox committed
40 41
// registered to serve a particular path or subtree
// in the HTTP server.
Russ Cox's avatar
Russ Cox committed
42
//
43
// ServeHTTP should write reply headers and data to the ResponseWriter
Russ Cox's avatar
Russ Cox committed
44 45 46
// and then return.  Returning signals that the request is finished
// and that the HTTP server can move on to the next request on
// the connection.
Russ Cox's avatar
Russ Cox committed
47
type Handler interface {
48 49 50 51 52 53
	ServeHTTP(ResponseWriter, *Request)
}

// A ResponseWriter interface is used by an HTTP handler to
// construct an HTTP response.
type ResponseWriter interface {
54 55 56 57
	// Header returns the header map that will be sent by WriteHeader.
	// Changing the header after a call to WriteHeader (or Write) has
	// no effect.
	Header() Header
58 59 60

	// Write writes the data to the connection as part of an HTTP reply.
	// If WriteHeader has not yet been called, Write calls WriteHeader(http.StatusOK)
61 62 63
	// before writing the data.  If the Header does not contain a
	// Content-Type line, Write adds a Content-Type set to the result of passing
	// the initial 512 bytes of written data to DetectContentType.
64
	Write([]byte) (int, error)
65 66 67 68 69 70 71

	// WriteHeader sends an HTTP response header with status code.
	// If WriteHeader is not called explicitly, the first call to Write
	// will trigger an implicit WriteHeader(http.StatusOK).
	// Thus explicit calls to WriteHeader are mainly used to
	// send error codes.
	WriteHeader(int)
72
}
73

74 75 76 77 78 79 80 81
// The Flusher interface is implemented by ResponseWriters that allow
// an HTTP handler to flush buffered data to the client.
//
// Note that even for ResponseWriters that support Flush,
// if the client is connected through an HTTP proxy,
// the buffered data may not reach the client until the response
// completes.
type Flusher interface {
82 83
	// Flush sends any buffered data to the client.
	Flush()
84
}
85

86 87
// The Hijacker interface is implemented by ResponseWriters that allow
// an HTTP handler to take over the connection.
88
type Hijacker interface {
89 90 91 92 93
	// Hijack lets the caller take over the connection.
	// After a call to Hijack(), the HTTP server library
	// will not do anything else with the connection.
	// It becomes the caller's responsibility to manage
	// and close the connection.
94
	Hijack() (net.Conn, *bufio.ReadWriter, error)
95 96 97 98
}

// A conn represents the server side of an HTTP connection.
type conn struct {
99
	remoteAddr string               // network address of remote side
100
	server     *Server              // the Server on which the connection arrived
101
	rwc        net.Conn             // i/o connection
102 103
	lr         *io.LimitedReader    // io.LimitReader(rwc)
	buf        *bufio.ReadWriter    // buffered(lr,rwc), reading from bufio->limitReader->rwc
104
	hijacked   bool                 // connection has been hijacked by handler
Russ Cox's avatar
Russ Cox committed
105 106
	tlsState   *tls.ConnectionState // or nil when not using TLS
	body       []byte
107 108 109 110 111
}

// A response represents the server side of an HTTP response.
type response struct {
	conn          *conn
112 113 114 115 116 117 118 119
	req           *Request // request for this response
	chunking      bool     // using chunked transfer encoding for reply body
	wroteHeader   bool     // reply header has been written
	wroteContinue bool     // 100 Continue response was written
	header        Header   // reply header parameters
	written       int64    // number of bytes written in body
	contentLength int64    // explicitly-declared Content-Length; or -1
	status        int      // status code passed to WriteHeader
Russ Cox's avatar
Russ Cox committed
120
	needSniff     bool     // need to sniff to find Content-Type
121 122 123 124 125 126

	// close connection after this reply.  set on request and
	// updated after response from handler if there's a
	// "Connection: keep-alive" response header and a
	// Content-Length.
	closeAfterReply bool
127 128 129 130 131 132 133 134 135 136 137 138 139

	// requestBodyLimitHit is set by requestTooLarge when
	// maxBytesReader hits its max size. It is checked in
	// WriteHeader, to make sure we don't consume the the
	// remaining request body to try to advance to the next HTTP
	// request. Instead, when this is set, we stop doing
	// subsequent requests on this connection and stop reading
	// input from it.
	requestBodyLimitHit bool
}

// requestTooLarge is called by maxBytesReader when too much input has
// been read from the client.
140 141 142 143 144
func (w *response) requestTooLarge() {
	w.closeAfterReply = true
	w.requestBodyLimitHit = true
	if !w.wroteHeader {
		w.Header().Set("Connection", "close")
145
	}
Russ Cox's avatar
Russ Cox committed
146 147
}

148 149 150 151
type writerOnly struct {
	io.Writer
}

152
func (w *response) ReadFrom(src io.Reader) (n int64, err error) {
153 154 155 156 157
	// Call WriteHeader before checking w.chunking if it hasn't
	// been called yet, since WriteHeader is what sets w.chunking.
	if !w.wroteHeader {
		w.WriteHeader(StatusOK)
	}
158
	if !w.chunking && w.bodyAllowed() && !w.needSniff {
159
		w.Flush()
160
		if rf, ok := w.conn.rwc.(io.ReaderFrom); ok {
161
			n, err = rf.ReadFrom(src)
162
			w.written += n
163 164 165 166
			return
		}
	}
	// Fall back to default io.Copy implementation.
167 168
	// Use wrapper to hide w.ReadFrom from io.Copy.
	return io.Copy(writerOnly{w}, src)
169 170
}

171 172 173
// noLimit is an effective infinite upper bound for io.LimitedReader
const noLimit int64 = (1 << 63) - 1

Russ Cox's avatar
Russ Cox committed
174
// Create new connection from rwc.
175
func (srv *Server) newConn(rwc net.Conn) (c *conn, err error) {
176 177
	c = new(conn)
	c.remoteAddr = rwc.RemoteAddr().String()
178
	c.server = srv
179
	c.rwc = rwc
Russ Cox's avatar
Russ Cox committed
180
	c.body = make([]byte, sniffLen)
181 182
	c.lr = io.LimitReader(rwc, noLimit).(*io.LimitedReader)
	br := bufio.NewReader(c.lr)
183 184 185
	bw := bufio.NewWriter(rwc)
	c.buf = bufio.NewReadWriter(br, bw)
	return c, nil
Russ Cox's avatar
Russ Cox committed
186 187
}

188 189 190 191 192 193 194 195 196 197 198 199
// DefaultMaxHeaderBytes is the maximum permitted size of the headers
// in an HTTP request.
// This can be overridden by setting Server.MaxHeaderBytes.
const DefaultMaxHeaderBytes = 1 << 20 // 1 MB

func (srv *Server) maxHeaderBytes() int {
	if srv.MaxHeaderBytes > 0 {
		return srv.MaxHeaderBytes
	}
	return DefaultMaxHeaderBytes
}

200 201 202
// wrapper around io.ReaderCloser which on first read, sends an
// HTTP/1.1 100 Continue header
type expectContinueReader struct {
203
	resp       *response
204
	readCloser io.ReadCloser
205
	closed     bool
206 207
}

208
func (ecr *expectContinueReader) Read(p []byte) (n int, err error) {
209
	if ecr.closed {
210
		return 0, errors.New("http: Read after Close on request Body")
211
	}
212 213 214 215
	if !ecr.resp.wroteContinue && !ecr.resp.conn.hijacked {
		ecr.resp.wroteContinue = true
		io.WriteString(ecr.resp.conn.buf, "HTTP/1.1 100 Continue\r\n\r\n")
		ecr.resp.conn.buf.Flush()
216 217 218 219
	}
	return ecr.readCloser.Read(p)
}

220
func (ecr *expectContinueReader) Close() error {
221
	ecr.closed = true
222 223 224
	return ecr.readCloser.Close()
}

225 226 227 228 229 230
// TimeFormat is the time format to use with
// time.Parse and time.Time.Format when parsing
// or generating times in HTTP headers.
// It is like time.RFC1123 but hard codes GMT as the time zone.
const TimeFormat = "Mon, 02 Jan 2006 15:04:05 GMT"

231
var errTooLarge = errors.New("http: request too large")
232

Russ Cox's avatar
Russ Cox committed
233
// Read next request from connection.
234
func (c *conn) readRequest() (w *response, err error) {
Russ Cox's avatar
Russ Cox committed
235
	if c.hijacked {
236
		return nil, ErrHijacked
Russ Cox's avatar
Russ Cox committed
237
	}
238
	c.lr.N = int64(c.server.maxHeaderBytes()) + 4096 /* bufio slop */
239
	var req *Request
240
	if req, err = ReadRequest(c.buf.Reader); err != nil {
241 242 243
		if c.lr.N == 0 {
			return nil, errTooLarge
		}
244
		return nil, err
Russ Cox's avatar
Russ Cox committed
245
	}
246
	c.lr.N = noLimit
Russ Cox's avatar
Russ Cox committed
247

248 249 250
	req.RemoteAddr = c.remoteAddr
	req.TLS = c.tlsState

251 252 253
	w = new(response)
	w.conn = c
	w.req = req
254
	w.header = make(Header)
255
	w.contentLength = -1
Russ Cox's avatar
Russ Cox committed
256
	c.body = c.body[:0]
257
	return w, nil
Russ Cox's avatar
Russ Cox committed
258 259
}

260 261
func (w *response) Header() Header {
	return w.header
262
}
263

264
// maxPostHandlerReadBytes is the max number of Request.Body bytes not
265
// consumed by a handler that the server will read from the client
266 267 268 269 270 271 272 273 274
// in order to keep a connection alive.  If there are more bytes than
// this then the server to be paranoid instead sends a "Connection:
// close" response.
//
// This number is approximately what a typical machine's TCP buffer
// size is anyway.  (if we have the bytes on the machine, we might as
// well read them)
const maxPostHandlerReadBytes = 256 << 10

275 276
func (w *response) WriteHeader(code int) {
	if w.conn.hijacked {
Rob Pike's avatar
Rob Pike committed
277
		log.Print("http: response.WriteHeader on hijacked connection")
278
		return
Russ Cox's avatar
Russ Cox committed
279
	}
280
	if w.wroteHeader {
Rob Pike's avatar
Rob Pike committed
281
		log.Print("http: multiple response.WriteHeader calls")
282
		return
Russ Cox's avatar
Russ Cox committed
283
	}
284 285 286 287 288 289 290
	w.wroteHeader = true
	w.status = code

	// Check for a explicit (and valid) Content-Length header.
	var hasCL bool
	var contentLength int64
	if clenStr := w.header.Get("Content-Length"); clenStr != "" {
291
		var err error
Russ Cox's avatar
Russ Cox committed
292
		contentLength, err = strconv.ParseInt(clenStr, 10, 64)
293 294 295 296 297 298 299 300 301 302 303 304 305
		if err == nil {
			hasCL = true
		} else {
			log.Printf("http: invalid Content-Length of %q sent", clenStr)
			w.header.Del("Content-Length")
		}
	}

	if w.req.wantsHttp10KeepAlive() && (w.req.Method == "HEAD" || hasCL) {
		_, connectionHeaderSet := w.header["Connection"]
		if !connectionHeaderSet {
			w.header.Set("Connection", "keep-alive")
		}
Russ Cox's avatar
Russ Cox committed
306
	} else if !w.req.ProtoAtLeast(1, 1) || w.req.wantsClose() {
307 308 309 310 311 312
		w.closeAfterReply = true
	}

	if w.header.Get("Connection") == "close" {
		w.closeAfterReply = true
	}
313 314

	// Per RFC 2616, we should consume the request body before
315 316 317 318
	// replying, if the handler hasn't already done so.  But we
	// don't want to do an unbounded amount of reading here for
	// DoS reasons, so we only try up to a threshold.
	if w.req.ContentLength != 0 && !w.closeAfterReply {
319 320
		ecr, isExpecter := w.req.Body.(*expectContinueReader)
		if !isExpecter || ecr.resp.wroteContinue {
321 322 323 324 325 326 327
			n, _ := io.CopyN(ioutil.Discard, w.req.Body, maxPostHandlerReadBytes+1)
			if n >= maxPostHandlerReadBytes {
				w.requestTooLarge()
				w.header.Set("Connection", "close")
			} else {
				w.req.Body.Close()
			}
328 329 330
		}
	}

Russ Cox's avatar
Russ Cox committed
331 332
	if code == StatusNotModified {
		// Must not have body.
333
		for _, header := range []string{"Content-Type", "Content-Length", "Transfer-Encoding"} {
334
			if w.header.Get(header) != "" {
335 336 337 338
				// TODO: return an error if WriteHeader gets a return parameter
				// or set a flag on w to make future Writes() write an error page?
				// for now just log and drop the header.
				log.Printf("http: StatusNotModified response with header %q defined", header)
339
				w.header.Del(header)
340 341 342
			}
		}
	} else {
Russ Cox's avatar
Russ Cox committed
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 {
Russ Cox's avatar
Russ Cox committed
350
		w.Header().Set("Date", time.Now().UTC().Format(TimeFormat))
351 352
	}

353 354
	te := w.header.Get("Transfer-Encoding")
	hasTE := te != ""
355 356 357 358 359
	if hasCL && hasTE && te != "identity" {
		// TODO: return an error if WriteHeader gets a return parameter
		// For now just ignore the Content-Length.
		log.Printf("http: WriteHeader called with both Transfer-Encoding of %q and a Content-Length of %d",
			te, contentLength)
360
		w.header.Del("Content-Length")
361 362 363
		hasCL = false
	}

364
	if w.req.Method == "HEAD" || code == StatusNotModified {
365 366 367
		// do nothing
	} else if hasCL {
		w.contentLength = contentLength
368
		w.header.Del("Transfer-Encoding")
369 370 371 372 373 374 375
	} else if w.req.ProtoAtLeast(1, 1) {
		// HTTP/1.1 or greater: use chunked transfer encoding
		// to avoid closing the connection at EOF.
		// TODO: this blows away any custom or stacked Transfer-Encoding they
		// might have set.  Deal with that as need arises once we have a valid
		// use case.
		w.chunking = true
376
		w.header.Set("Transfer-Encoding", "chunked")
377 378 379 380 381
	} else {
		// HTTP version < 1.1: cannot do chunked transfer
		// encoding and we don't know the Content-Length so
		// signal EOF by closing connection.
		w.closeAfterReply = true
382
		w.header.Del("Transfer-Encoding") // in case already set
383 384
	}

385 386
	// Cannot use Content-Length with non-identity Transfer-Encoding.
	if w.chunking {
387
		w.header.Del("Content-Length")
388
	}
389
	if !w.req.ProtoAtLeast(1, 0) {
390
		return
Russ Cox's avatar
Russ Cox committed
391
	}
392
	proto := "HTTP/1.0"
393
	if w.req.ProtoAtLeast(1, 1) {
394
		proto = "HTTP/1.1"
Russ Cox's avatar
Russ Cox committed
395
	}
396 397
	codestring := strconv.Itoa(code)
	text, ok := statusText[code]
Russ Cox's avatar
Russ Cox committed
398
	if !ok {
399
		text = "status code " + codestring
Russ Cox's avatar
Russ Cox committed
400
	}
401
	io.WriteString(w.conn.buf, proto+" "+codestring+" "+text+"\r\n")
Evan Shaw's avatar
Evan Shaw committed
402
	w.header.Write(w.conn.buf)
Russ Cox's avatar
Russ Cox committed
403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420

	// If we need to sniff the body, leave the header open.
	// Otherwise, end it here.
	if !w.needSniff {
		io.WriteString(w.conn.buf, "\r\n")
	}
}

// sniff uses the first block of written data,
// stored in w.conn.body, to decide the Content-Type
// for the HTTP body.
func (w *response) sniff() {
	if !w.needSniff {
		return
	}
	w.needSniff = false

	data := w.conn.body
421
	fmt.Fprintf(w.conn.buf, "Content-Type: %s\r\n\r\n", DetectContentType(data))
Russ Cox's avatar
Russ Cox committed
422

423 424 425 426
	if len(data) == 0 {
		return
	}
	if w.chunking {
Russ Cox's avatar
Russ Cox committed
427 428
		fmt.Fprintf(w.conn.buf, "%x\r\n", len(data))
	}
429 430 431 432
	_, err := w.conn.buf.Write(data)
	if w.chunking && err == nil {
		io.WriteString(w.conn.buf, "\r\n")
	}
Russ Cox's avatar
Russ Cox committed
433 434
}

435 436 437 438 439 440 441 442 443
// bodyAllowed returns true if a Write is allowed for this response type.
// It's illegal to call this before the header has been flushed.
func (w *response) bodyAllowed() bool {
	if !w.wroteHeader {
		panic("")
	}
	return w.status != StatusNotModified && w.req.Method != "HEAD"
}

444
func (w *response) Write(data []byte) (n int, err error) {
445
	if w.conn.hijacked {
Rob Pike's avatar
Rob Pike committed
446
		log.Print("http: response.Write on hijacked connection")
447
		return 0, ErrHijacked
Russ Cox's avatar
Russ Cox committed
448
	}
449 450
	if !w.wroteHeader {
		w.WriteHeader(StatusOK)
Russ Cox's avatar
Russ Cox committed
451 452
	}
	if len(data) == 0 {
453
		return 0, nil
Russ Cox's avatar
Russ Cox committed
454
	}
455
	if !w.bodyAllowed() {
Russ Cox's avatar
Russ Cox committed
456 457 458
		return 0, ErrBodyNotAllowed
	}

459
	w.written += int64(len(data)) // ignoring errors, for errorKludge
460 461 462
	if w.contentLength != -1 && w.written > w.contentLength {
		return 0, ErrContentLength
	}
463

Russ Cox's avatar
Russ Cox committed
464 465
	var m int
	if w.needSniff {
466 467 468
		// We need to sniff the beginning of the output to
		// determine the content type.  Accumulate the
		// 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 472 473 474 475 476
		if m > len(data) {
			m = len(data)
		}
		w.conn.body = append(w.conn.body, data[:m]...)
		data = data[m:]
		if len(data) == 0 {
477 478
			// Copied everything into the buffer.
			// Wait for next write.
Russ Cox's avatar
Russ Cox committed
479 480
			return m, nil
		}
481 482 483 484 485 486

		// Filled the buffer; more data remains.
		// Sniff the content (flushes the buffer)
		// and then proceed with the remainder
		// of the data as a normal Write.
		// Calling sniff clears needSniff.
Russ Cox's avatar
Russ Cox committed
487 488 489
		w.sniff()
	}

Russ Cox's avatar
Russ Cox committed
490
	// TODO(rsc): if chunking happened after the buffering,
Russ Cox's avatar
Russ Cox committed
491 492
	// then there would be fewer chunk headers.
	// On the other hand, it would make hijacking more difficult.
493 494
	if w.chunking {
		fmt.Fprintf(w.conn.buf, "%x\r\n", len(data)) // TODO(rsc): use strconv not fmt
Russ Cox's avatar
Russ Cox committed
495
	}
496 497
	n, err = w.conn.buf.Write(data)
	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
		}
	}

Russ Cox's avatar
Russ Cox committed
506
	return m + n, err
Russ Cox's avatar
Russ Cox committed
507 508
}

509
func (w *response) finishRequest() {
510 511
	// If this was an HTTP/1.0 request with keep-alive and we sent a Content-Length
	// back, we can make this a keep-alive response ...
512
	if w.req.wantsHttp10KeepAlive() {
513 514
		sentLength := w.header.Get("Content-Length") != ""
		if sentLength && w.header.Get("Connection") == "keep-alive" {
515
			w.closeAfterReply = false
516 517
		}
	}
518 519
	if !w.wroteHeader {
		w.WriteHeader(StatusOK)
Russ Cox's avatar
Russ Cox committed
520
	}
Russ Cox's avatar
Russ Cox committed
521 522 523
	if w.needSniff {
		w.sniff()
	}
524 525
	if w.chunking {
		io.WriteString(w.conn.buf, "0\r\n")
Russ Cox's avatar
Russ Cox committed
526
		// trailer key/value pairs, followed by blank line
527
		io.WriteString(w.conn.buf, "\r\n")
Russ Cox's avatar
Russ Cox committed
528
	}
529
	w.conn.buf.Flush()
530 531 532 533 534
	// Close the body, unless we're about to close the whole TCP connection
	// anyway.
	if !w.closeAfterReply {
		w.req.Body.Close()
	}
535 536 537
	if w.req.MultipartForm != nil {
		w.req.MultipartForm.RemoveAll()
	}
538 539 540 541 542

	if w.contentLength != -1 && w.contentLength != w.written {
		// Did not write enough. Avoid getting out of sync.
		w.closeAfterReply = true
	}
Russ Cox's avatar
Russ Cox committed
543 544
}

545 546 547
func (w *response) Flush() {
	if !w.wroteHeader {
		w.WriteHeader(StatusOK)
548
	}
Russ Cox's avatar
Russ Cox committed
549
	w.sniff()
550
	w.conn.buf.Flush()
551 552
}

Russ Cox's avatar
Russ Cox committed
553
// Close the connection.
554
func (c *conn) close() {
Russ Cox's avatar
Russ Cox committed
555
	if c.buf != nil {
556 557
		c.buf.Flush()
		c.buf = nil
Russ Cox's avatar
Russ Cox committed
558
	}
Russ Cox's avatar
Russ Cox committed
559
	if c.rwc != nil {
560 561
		c.rwc.Close()
		c.rwc = nil
Russ Cox's avatar
Russ Cox committed
562 563 564 565
	}
}

// Serve a new connection.
566
func (c *conn) serve() {
Brad Fitzpatrick's avatar
Brad Fitzpatrick committed
567 568 569 570 571
	defer func() {
		err := recover()
		if err == nil {
			return
		}
Russ Cox's avatar
Russ Cox committed
572

Brad Fitzpatrick's avatar
Brad Fitzpatrick committed
573 574
		var buf bytes.Buffer
		fmt.Fprintf(&buf, "http: panic serving %v: %v\n", c.remoteAddr, err)
575
		buf.Write(debug.Stack())
Brad Fitzpatrick's avatar
Brad Fitzpatrick committed
576
		log.Print(buf.String())
577 578 579 580

		if c.rwc != nil { // may be nil if connection hijacked
			c.rwc.Close()
		}
Brad Fitzpatrick's avatar
Brad Fitzpatrick committed
581 582
	}()

583
	if tlsConn, ok := c.rwc.(*tls.Conn); ok {
584 585 586 587
		if err := tlsConn.Handshake(); err != nil {
			c.close()
			return
		}
588 589 590 591
		c.tlsState = new(tls.ConnectionState)
		*c.tlsState = tlsConn.ConnectionState()
	}

592
	for {
593
		w, err := c.readRequest()
594
		if err != nil {
595
			msg := "400 Bad Request"
596 597 598 599 600 601
			if err == errTooLarge {
				// Their HTTP client may or may not be
				// able to read this if we're
				// responding to them and hanging up
				// while they're still writing their
				// request.  Undefined behavior.
602
				msg = "413 Request Entity Too Large"
603
			} else if err == io.EOF {
604
				break // Don't reply
605 606
			} else if neterr, ok := err.(net.Error); ok && neterr.Timeout() {
				break // Don't reply
607
			}
608
			fmt.Fprintf(c.rwc, "HTTP/1.1 %s\r\n\r\n", msg)
609
			break
610
		}
611 612 613 614 615 616 617 618 619 620 621

		// Expect 100 Continue support
		req := w.req
		if req.expectsContinue() {
			if req.ProtoAtLeast(1, 1) {
				// Wrap the Body reader with one that replies on the connection
				req.Body = &expectContinueReader{readCloser: req.Body, resp: w}
			}
			if req.ContentLength == 0 {
				w.Header().Set("Connection", "close")
				w.WriteHeader(StatusBadRequest)
Russ Cox's avatar
Russ Cox committed
622
				w.finishRequest()
623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640
				break
			}
			req.Header.Del("Expect")
		} else if req.Header.Get("Expect") != "" {
			// TODO(bradfitz): let ServeHTTP handlers handle
			// requests with non-standard expectation[s]? Seems
			// theoretical at best, and doesn't fit into the
			// current ServeHTTP model anyway.  We'd need to
			// make the ResponseWriter an optional
			// "ExpectReplier" interface or something.
			//
			// For now we'll just obey RFC 2616 14.20 which says
			// "If a server receives a request containing an
			// Expect field that includes an expectation-
			// extension that it does not support, it MUST
			// respond with a 417 (Expectation Failed) status."
			w.Header().Set("Connection", "close")
			w.WriteHeader(StatusExpectationFailed)
Russ Cox's avatar
Russ Cox committed
641
			w.finishRequest()
642 643 644
			break
		}

645 646 647 648 649
		handler := c.server.Handler
		if handler == nil {
			handler = DefaultServeMux
		}

650
		// HTTP cannot have multiple simultaneous active requests.[*]
Russ Cox's avatar
Russ Cox committed
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 654
		// [*] Not strictly true: HTTP pipelining.  We could let them all process
		// in parallel even if their responses need to be serialized.
655
		handler.ServeHTTP(w, w.req)
Russ Cox's avatar
Russ Cox committed
656
		if c.hijacked {
657
			return
Russ Cox's avatar
Russ Cox committed
658
		}
659 660
		w.finishRequest()
		if w.closeAfterReply {
661
			break
662 663
		}
	}
664
	c.close()
Russ Cox's avatar
Russ Cox committed
665 666
}

667 668
// Hijack implements the Hijacker.Hijack method. Our response is both a ResponseWriter
// 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
Russ Cox's avatar
Russ Cox committed
672
	}
673 674 675 676 677
	w.conn.hijacked = true
	rwc = w.conn.rwc
	buf = w.conn.buf
	w.conn.rwc = nil
	w.conn.buf = nil
678
	return
679 680
}

Russ Cox's avatar
Russ Cox committed
681 682 683 684
// The HandlerFunc type is an adapter to allow the use of
// ordinary functions as HTTP handlers.  If f is a function
// with the appropriate signature, HandlerFunc(f) is a
// Handler object that calls f.
685
type HandlerFunc func(ResponseWriter, *Request)
Russ Cox's avatar
Russ Cox committed
686

687
// ServeHTTP calls f(w, r).
688 689
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
	f(w, r)
Russ Cox's avatar
Russ Cox committed
690 691 692 693
}

// Helper handlers

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 698
	w.WriteHeader(code)
	fmt.Fprintln(w, error)
Russ Cox's avatar
Russ Cox committed
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

Russ Cox's avatar
Russ Cox committed
704 705
// NotFoundHandler returns a simple request handler
// that replies to each request with a ``404 page not found'' reply.
706
func NotFoundHandler() Handler { return HandlerFunc(NotFound) }
Russ Cox's avatar
Russ Cox committed
707

708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723
// StripPrefix returns a handler that serves HTTP requests
// by removing the given prefix from the request URL's Path
// and invoking the handler h. StripPrefix handles a
// request for a path that doesn't begin with prefix by
// replying with an HTTP 404 not found error.
func StripPrefix(prefix string, h Handler) Handler {
	return HandlerFunc(func(w ResponseWriter, r *Request) {
		if !strings.HasPrefix(r.URL.Path, prefix) {
			NotFound(w, r)
			return
		}
		r.URL.Path = r.URL.Path[len(prefix):]
		h.ServeHTTP(w, r)
	})
}

Russ Cox's avatar
Russ Cox committed
724 725
// Redirect replies to the request with a redirect to url,
// which may be a path relative to the request path.
Rob Pike's avatar
Rob Pike committed
726 727
func Redirect(w ResponseWriter, r *Request, urlStr string, code int) {
	if u, err := url.Parse(urlStr); err == nil {
728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746
		// If url was relative, make absolute by
		// combining with request path.
		// The browser would probably do this for us,
		// but doing it ourselves is more reliable.

		// NOTE(rsc): RFC 2616 says that the Location
		// line must be an absolute URI, like
		// "http://www.google.com/redirect/",
		// not a path like "/redirect/".
		// Unfortunately, we don't know what to
		// put in the host name section to get the
		// client to connect to us again, so we can't
		// know the right absolute URI to send back.
		// Because of this problem, no one pays attention
		// to the RFC; they all send back just a new path.
		// So do we.
		oldpath := r.URL.Path
		if oldpath == "" { // should not happen, but avoid a crash if it does
			oldpath = "/"
747
		}
748 749
		if u.Scheme == "" {
			// no leading http://server
Rob Pike's avatar
Rob Pike committed
750
			if urlStr == "" || urlStr[0] != '/' {
751 752
				// make relative path absolute
				olddir, _ := path.Split(oldpath)
Rob Pike's avatar
Rob Pike committed
753
				urlStr = olddir + urlStr
754
			}
755

756
			var query string
Rob Pike's avatar
Rob Pike committed
757 758
			if i := strings.Index(urlStr, "?"); i != -1 {
				urlStr, query = urlStr[:i], urlStr[i:]
759 760
			}

761
			// clean up but preserve trailing slash
Rob Pike's avatar
Rob Pike committed
762 763 764 765
			trailing := urlStr[len(urlStr)-1] == '/'
			urlStr = path.Clean(urlStr)
			if trailing && urlStr[len(urlStr)-1] != '/' {
				urlStr += "/"
766
			}
Rob Pike's avatar
Rob Pike committed
767
			urlStr += query
768 769 770
		}
	}

Rob Pike's avatar
Rob Pike committed
771
	w.Header().Set("Location", urlStr)
772
	w.WriteHeader(code)
773 774 775

	// RFC2616 recommends that a short note "SHOULD" be included in the
	// response because older user agents may not understand 301/307.
776 777
	// Shouldn't send the response for POST or HEAD; that leaves GET.
	if r.Method == "GET" {
Rob Pike's avatar
Rob Pike committed
778
		note := "<a href=\"" + htmlEscape(urlStr) + "\">" + statusText[code] + "</a>.\n"
779
		fmt.Fprintln(w, note)
780 781 782
	}
}

783 784 785 786
var htmlReplacer = strings.NewReplacer(
	"&", "&amp;",
	"<", "&lt;",
	">", "&gt;",
787 788 789 790
	// "&#34;" is shorter than "&quot;".
	`"`, "&#34;",
	// "&#39;" is shorter than "&apos;" and apos was not in HTML until HTML5.
	"'", "&#39;",
791 792
)

793
func htmlEscape(s string) string {
794
	return htmlReplacer.Replace(s)
Russ Cox's avatar
Russ Cox committed
795 796
}

Russ Cox's avatar
Russ Cox committed
797
// Redirect to a fixed URL
798
type redirectHandler struct {
799 800
	url  string
	code int
801
}
802

803 804
func (rh *redirectHandler) ServeHTTP(w ResponseWriter, r *Request) {
	Redirect(w, r, rh.url, rh.code)
Russ Cox's avatar
Russ Cox committed
805 806
}

Russ Cox's avatar
Russ Cox committed
807
// RedirectHandler returns a request handler that redirects
808 809 810
// each request it receives to the given url using the given
// status code.
func RedirectHandler(url string, code int) Handler {
811
	return &redirectHandler{url, code}
Russ Cox's avatar
Russ Cox committed
812 813
}

Russ Cox's avatar
Russ Cox committed
814 815 816 817 818
// ServeMux is an HTTP request multiplexer.
// It matches the URL of each incoming request against a list of registered
// patterns and calls the handler for the pattern that
// most closely matches the URL.
//
819 820
// Patterns named fixed, rooted paths, like "/favicon.ico",
// or rooted subtrees, like "/images/" (note the trailing slash).
Russ Cox's avatar
Russ Cox committed
821 822 823 824 825 826 827
// Longer patterns take precedence over shorter ones, so that
// if there are handlers registered for both "/images/"
// and "/images/thumbnails/", the latter handler will be
// called for paths beginning "/images/thumbnails/" and the
// former will receiver requests for any other paths in the
// "/images/" subtree.
//
828 829 830 831 832
// Patterns may optionally begin with a host name, restricting matches to
// URLs on that host only.  Host-specific patterns take precedence over
// general patterns, so that a handler might register for the two patterns
// "/codesearch" and "codesearch.google.com/" without also taking over
// requests for "http://www.google.com/".
833 834 835 836
//
// ServeMux also takes care of sanitizing the URL request path,
// redirecting any request containing . or .. elements to an
// equivalent .- and ..-free URL.
Russ Cox's avatar
Russ Cox committed
837
type ServeMux struct {
838 839 840 841 842 843 844
	mu sync.RWMutex
	m  map[string]muxEntry
}

type muxEntry struct {
	explicit bool
	h        Handler
Russ Cox's avatar
Russ Cox committed
845 846
}

Russ Cox's avatar
Russ Cox committed
847
// NewServeMux allocates and returns a new ServeMux.
848
func NewServeMux() *ServeMux { return &ServeMux{m: make(map[string]muxEntry)} }
Russ Cox's avatar
Russ Cox committed
849

Russ Cox's avatar
Russ Cox committed
850
// DefaultServeMux is the default ServeMux used by Serve.
851
var DefaultServeMux = NewServeMux()
Russ Cox's avatar
Russ Cox committed
852 853 854 855 856

// Does path match pattern?
func pathMatch(pattern, path string) bool {
	if len(pattern) == 0 {
		// should not happen
857
		return false
Russ Cox's avatar
Russ Cox committed
858
	}
859
	n := len(pattern)
Russ Cox's avatar
Russ Cox committed
860
	if pattern[n-1] != '/' {
861
		return pattern == path
862
	}
863
	return len(path) >= n && path[0:n] == pattern
Russ Cox's avatar
Russ Cox committed
864 865
}

866 867 868
// Return the canonical path for p, eliminating . and .. elements.
func cleanPath(p string) string {
	if p == "" {
869
		return "/"
870 871
	}
	if p[0] != '/' {
872
		p = "/" + p
873
	}
874
	np := path.Clean(p)
875 876 877
	// path.Clean removes trailing slash except for root;
	// put the trailing slash back if necessary.
	if p[len(p)-1] == '/' && np != "/" {
878
		np += "/"
879
	}
880
	return np
881 882
}

883 884 885
// Find a handler on a handler map given a path string
// Most-specific (longest) pattern wins
func (mux *ServeMux) match(path string) Handler {
886 887
	var h Handler
	var n = 0
Russ Cox's avatar
Russ Cox committed
888
	for k, v := range mux.m {
889
		if !pathMatch(k, path) {
890
			continue
Russ Cox's avatar
Russ Cox committed
891 892
		}
		if h == nil || len(k) > n {
893
			n = len(k)
894
			h = v.h
Russ Cox's avatar
Russ Cox committed
895 896
		}
	}
897 898 899
	return h
}

900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915
// handler returns the handler to use for the request r.
func (mux *ServeMux) handler(r *Request) Handler {
	mux.mu.RLock()
	defer mux.mu.RUnlock()

	// Host-specific pattern takes precedence over generic ones
	h := mux.match(r.Host + r.URL.Path)
	if h == nil {
		h = mux.match(r.URL.Path)
	}
	if h == nil {
		h = NotFoundHandler()
	}
	return h
}

916 917 918
// ServeHTTP dispatches the request to the handler whose
// pattern most closely matches the request URL.
func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
919 920 921 922 923 924 925
	if r.Method != "CONNECT" {
		// Clean path to canonical form and redirect.
		if p := cleanPath(r.URL.Path); p != r.URL.Path {
			w.Header().Set("Location", p)
			w.WriteHeader(StatusMovedPermanently)
			return
		}
926
	}
927
	mux.handler(r).ServeHTTP(w, r)
Russ Cox's avatar
Russ Cox committed
928
}
929

Russ Cox's avatar
Russ Cox committed
930
// Handle registers the handler for the given pattern.
931
// If a handler already exists for pattern, Handle panics.
Russ Cox's avatar
Russ Cox committed
932
func (mux *ServeMux) Handle(pattern string, handler Handler) {
933 934 935
	mux.mu.Lock()
	defer mux.mu.Unlock()

936
	if pattern == "" {
937
		panic("http: invalid pattern " + pattern)
Russ Cox's avatar
Russ Cox committed
938
	}
939 940 941 942 943 944
	if handler == nil {
		panic("http: nil handler")
	}
	if mux.m[pattern].explicit {
		panic("http: multiple registrations for " + pattern)
	}
Russ Cox's avatar
Russ Cox committed
945

946
	mux.m[pattern] = muxEntry{explicit: true, h: handler}
Russ Cox's avatar
Russ Cox committed
947 948

	// Helpful behavior:
949 950
	// If pattern is /tree/, insert an implicit permanent redirect for /tree.
	// It can be overridden by an explicit registration.
951
	n := len(pattern)
952 953
	if n > 0 && pattern[n-1] == '/' && !mux.m[pattern[0:n-1]].explicit {
		mux.m[pattern[0:n-1]] = muxEntry{h: RedirectHandler(pattern, StatusMovedPermanently)}
Russ Cox's avatar
Russ Cox committed
954 955 956
	}
}

957
// HandleFunc registers the handler function for the given pattern.
958
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
959 960 961
	mux.Handle(pattern, HandlerFunc(handler))
}

Russ Cox's avatar
Russ Cox committed
962 963
// Handle registers the handler for the given pattern
// in the DefaultServeMux.
964
// The documentation for ServeMux explains how patterns are matched.
965
func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
Russ Cox's avatar
Russ Cox committed
966

967 968
// HandleFunc registers the handler function for the given pattern
// in the DefaultServeMux.
969
// The documentation for ServeMux explains how patterns are matched.
970
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
971 972 973
	DefaultServeMux.HandleFunc(pattern, handler)
}

Russ Cox's avatar
Russ Cox committed
974 975 976 977
// Serve accepts incoming HTTP connections on the listener l,
// creating a new service thread for each.  The service threads
// read requests and then call handler to reply to them.
// Handler is typically nil, in which case the DefaultServeMux is used.
978
func Serve(l net.Listener, handler Handler) error {
979 980 981 982 983 984
	srv := &Server{Handler: handler}
	return srv.Serve(l)
}

// A Server defines parameters for running an HTTP server.
type Server struct {
985 986
	Addr           string        // TCP address to listen on, ":http" if empty
	Handler        Handler       // handler to invoke, http.DefaultServeMux if nil
987 988
	ReadTimeout    time.Duration // maximum duration before timing out read of the request
	WriteTimeout   time.Duration // maximum duration before timing out write of the response
989
	MaxHeaderBytes int           // maximum size of request headers, DefaultMaxHeaderBytes if 0
990
	TLSConfig      *tls.Config   // optional TLS config, used by ListenAndServeTLS
991 992 993 994 995
}

// ListenAndServe listens on the TCP network address srv.Addr and then
// calls Serve to handle requests on incoming connections.  If
// srv.Addr is blank, ":http" is used.
996
func (srv *Server) ListenAndServe() error {
997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010
	addr := srv.Addr
	if addr == "" {
		addr = ":http"
	}
	l, e := net.Listen("tcp", addr)
	if e != nil {
		return e
	}
	return srv.Serve(l)
}

// Serve accepts incoming connections on the Listener l, creating a
// new service thread for each.  The service threads read requests and
// then call srv.Handler to reply to them.
1011
func (srv *Server) Serve(l net.Listener) error {
1012
	defer l.Close()
1013
	var tempDelay time.Duration // how long to sleep on accept failure
1014
	for {
1015
		rw, e := l.Accept()
1016
		if e != nil {
1017
			if ne, ok := e.(net.Error); ok && ne.Temporary() {
1018 1019 1020 1021 1022 1023 1024 1025 1026 1027
				if tempDelay == 0 {
					tempDelay = 5 * time.Millisecond
				} else {
					tempDelay *= 2
				}
				if max := 1 * time.Second; tempDelay > max {
					tempDelay = max
				}
				log.Printf("http: Accept error: %v; retrying in %v", e, tempDelay)
				time.Sleep(tempDelay)
1028 1029
				continue
			}
1030
			return e
1031
		}
1032
		tempDelay = 0
1033
		if srv.ReadTimeout != 0 {
1034
			rw.SetReadDeadline(time.Now().Add(srv.ReadTimeout))
1035 1036
		}
		if srv.WriteTimeout != 0 {
1037
			rw.SetWriteDeadline(time.Now().Add(srv.WriteTimeout))
1038
		}
1039
		c, err := srv.newConn(rw)
Russ Cox's avatar
Russ Cox committed
1040
		if err != nil {
1041
			continue
Russ Cox's avatar
Russ Cox committed
1042
		}
1043
		go c.serve()
1044
	}
1045
	panic("not reached")
1046 1047
}

Russ Cox's avatar
Russ Cox committed
1048 1049 1050 1051 1052 1053 1054 1055 1056 1057
// ListenAndServe listens on the TCP network address addr
// and then calls Serve with handler to handle requests
// on incoming connections.  Handler is typically nil,
// in which case the DefaultServeMux is used.
//
// A trivial example server is:
//
//	package main
//
//	import (
Russ Cox's avatar
Russ Cox committed
1058
//		"io"
1059
//		"net/http"
Russ Cox's avatar
Russ Cox committed
1060
//		"log"
Russ Cox's avatar
Russ Cox committed
1061 1062 1063
//	)
//
//	// hello world, the web server
1064 1065
//	func HelloServer(w http.ResponseWriter, req *http.Request) {
//		io.WriteString(w, "hello, world!\n")
Russ Cox's avatar
Russ Cox committed
1066 1067 1068
//	}
//
//	func main() {
Russ Cox's avatar
Russ Cox committed
1069 1070
//		http.HandleFunc("/hello", HelloServer)
//		err := http.ListenAndServe(":12345", nil)
Russ Cox's avatar
Russ Cox committed
1071
//		if err != nil {
1072
//			log.Fatal("ListenAndServe: ", err)
Russ Cox's avatar
Russ Cox committed
1073 1074
//		}
//	}
1075
func ListenAndServe(addr string, handler Handler) error {
1076 1077
	server := &Server{Addr: addr, Handler: handler}
	return server.ListenAndServe()
1078
}
1079

1080 1081
// ListenAndServeTLS acts identically to ListenAndServe, except that it
// expects HTTPS connections. Additionally, files containing a certificate and
1082 1083 1084
// matching private key for the server must be provided. If the certificate
// is signed by a certificate authority, the certFile should be the concatenation
// of the server's certificate followed by the CA's certificate.
1085 1086 1087 1088 1089
//
// A trivial example server is:
//
//	import (
//		"log"
1090
//		"net/http"
1091 1092
//	)
//
1093
//	func handler(w http.ResponseWriter, req *http.Request) {
1094
//		w.Header().Set("Content-Type", "text/plain")
1095
//		w.Write([]byte("This is an example server.\n"))
1096 1097 1098 1099
//	}
//
//	func main() {
//		http.HandleFunc("/", handler)
Rob Pike's avatar
Rob Pike committed
1100
//		log.Printf("About to listen on 10443. Go to https://127.0.0.1:10443/")
1101
//		err := http.ListenAndServeTLS(":10443", "cert.pem", "key.pem", nil)
1102
//		if err != nil {
Rob Pike's avatar
Rob Pike committed
1103
//			log.Fatal(err)
1104 1105 1106 1107
//		}
//	}
//
// One can use generate_cert.go in crypto/tls to generate cert.pem and key.pem.
1108
func ListenAndServeTLS(addr string, certFile string, keyFile string, handler Handler) error {
1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121
	server := &Server{Addr: addr, Handler: handler}
	return server.ListenAndServeTLS(certFile, keyFile)
}

// ListenAndServeTLS listens on the TCP network address srv.Addr and
// then calls Serve to handle requests on incoming TLS connections.
//
// Filenames containing a certificate and matching private key for
// the server must be provided. If the certificate is signed by a
// certificate authority, the certFile should be the concatenation
// of the server's certificate followed by the CA's certificate.
//
// If srv.Addr is blank, ":https" is used.
1122 1123
func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error {
	addr := srv.Addr
1124 1125 1126
	if addr == "" {
		addr = ":https"
	}
1127 1128 1129 1130 1131 1132
	config := &tls.Config{}
	if srv.TLSConfig != nil {
		*config = *srv.TLSConfig
	}
	if config.NextProtos == nil {
		config.NextProtos = []string{"http/1.1"}
1133 1134
	}

1135
	var err error
1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147
	config.Certificates = make([]tls.Certificate, 1)
	config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
	if err != nil {
		return err
	}

	conn, err := net.Listen("tcp", addr)
	if err != nil {
		return err
	}

	tlsListener := tls.NewListener(conn, config)
1148
	return srv.Serve(tlsListener)
1149
}
1150 1151 1152 1153 1154 1155 1156 1157 1158

// TimeoutHandler returns a Handler that runs h with the given time limit.
//
// The new Handler calls h.ServeHTTP to handle each request, but if a
// call runs for more than ns nanoseconds, the handler responds with
// a 503 Service Unavailable error and the given message in its body.
// (If msg is empty, a suitable default message will be sent.)
// After such a timeout, writes by h to its ResponseWriter will return
// ErrHandlerTimeout.
Russ Cox's avatar
Russ Cox committed
1159 1160 1161
func TimeoutHandler(h Handler, dt time.Duration, msg string) Handler {
	f := func() <-chan time.Time {
		return time.After(dt)
1162 1163 1164 1165 1166 1167
	}
	return &timeoutHandler{h, f, msg}
}

// ErrHandlerTimeout is returned on ResponseWriter Write calls
// in handlers which have timed out.
1168
var ErrHandlerTimeout = errors.New("http: Handler timeout")
1169 1170 1171

type timeoutHandler struct {
	handler Handler
Russ Cox's avatar
Russ Cox committed
1172
	timeout func() <-chan time.Time // returns channel producing a timeout
1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215
	body    string
}

func (h *timeoutHandler) errorBody() string {
	if h.body != "" {
		return h.body
	}
	return "<html><head><title>Timeout</title></head><body><h1>Timeout</h1></body></html>"
}

func (h *timeoutHandler) ServeHTTP(w ResponseWriter, r *Request) {
	done := make(chan bool)
	tw := &timeoutWriter{w: w}
	go func() {
		h.handler.ServeHTTP(tw, r)
		done <- true
	}()
	select {
	case <-done:
		return
	case <-h.timeout():
		tw.mu.Lock()
		defer tw.mu.Unlock()
		if !tw.wroteHeader {
			tw.w.WriteHeader(StatusServiceUnavailable)
			tw.w.Write([]byte(h.errorBody()))
		}
		tw.timedOut = true
	}
}

type timeoutWriter struct {
	w ResponseWriter

	mu          sync.Mutex
	timedOut    bool
	wroteHeader bool
}

func (tw *timeoutWriter) Header() Header {
	return tw.w.Header()
}

1216
func (tw *timeoutWriter) Write(p []byte) (int, error) {
1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235
	tw.mu.Lock()
	timedOut := tw.timedOut
	tw.mu.Unlock()
	if timedOut {
		return 0, ErrHandlerTimeout
	}
	return tw.w.Write(p)
}

func (tw *timeoutWriter) WriteHeader(code int) {
	tw.mu.Lock()
	if tw.timedOut || tw.wroteHeader {
		tw.mu.Unlock()
		return
	}
	tw.wroteHeader = true
	tw.mu.Unlock()
	tw.w.WriteHeader(code)
}