LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // HTTP server. See RFC 2616. | 5 // HTTP server. See RFC 2616. |
6 | 6 |
7 package http | 7 package http |
8 | 8 |
9 import ( | 9 import ( |
10 "bufio" | 10 "bufio" |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 } | 103 } |
104 | 104 |
105 // A conn represents the server side of an HTTP connection. | 105 // A conn represents the server side of an HTTP connection. |
106 type conn struct { | 106 type conn struct { |
107 remoteAddr string // network address of remote side | 107 remoteAddr string // network address of remote side |
108 server *Server // the Server on which the connection ar
rived | 108 server *Server // the Server on which the connection ar
rived |
109 rwc net.Conn // i/o connection | 109 rwc net.Conn // i/o connection |
110 sr liveSwitchReader // where the LimitReader reads from; usu
ally the rwc | 110 sr liveSwitchReader // where the LimitReader reads from; usu
ally the rwc |
111 lr *io.LimitedReader // io.LimitReader(sr) | 111 lr *io.LimitedReader // io.LimitReader(sr) |
112 buf *bufio.ReadWriter // buffered(lr,rwc), reading from bufio-
>limitReader->sr->rwc | 112 buf *bufio.ReadWriter // buffered(lr,rwc), reading from bufio-
>limitReader->sr->rwc |
113 bufswr *switchReader // the *switchReader io.Reader source of
buf | |
114 bufsww *switchWriter // the *switchWriter io.Writer dest of b
uf | |
115 tlsState *tls.ConnectionState // or nil when not using TLS | 113 tlsState *tls.ConnectionState // or nil when not using TLS |
116 | 114 |
117 mu sync.Mutex // guards the following | 115 mu sync.Mutex // guards the following |
118 clientGone bool // if client has disconnected mid-request | 116 clientGone bool // if client has disconnected mid-request |
119 closeNotifyc chan bool // made lazily | 117 closeNotifyc chan bool // made lazily |
120 hijackedv bool // connection has been hijacked by handler | 118 hijackedv bool // connection has been hijacked by handler |
121 } | 119 } |
122 | 120 |
123 func (c *conn) hijacked() bool { | 121 func (c *conn) hijacked() bool { |
124 c.mu.Lock() | 122 c.mu.Lock() |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 func (srv *Server) newConn(rwc net.Conn) (c *conn, err error) { | 421 func (srv *Server) newConn(rwc net.Conn) (c *conn, err error) { |
424 c = new(conn) | 422 c = new(conn) |
425 c.remoteAddr = rwc.RemoteAddr().String() | 423 c.remoteAddr = rwc.RemoteAddr().String() |
426 c.server = srv | 424 c.server = srv |
427 c.rwc = rwc | 425 c.rwc = rwc |
428 if debugServerConnections { | 426 if debugServerConnections { |
429 c.rwc = newLoggingConn("server", c.rwc) | 427 c.rwc = newLoggingConn("server", c.rwc) |
430 } | 428 } |
431 c.sr = liveSwitchReader{r: c.rwc} | 429 c.sr = liveSwitchReader{r: c.rwc} |
432 c.lr = io.LimitReader(&c.sr, noLimit).(*io.LimitedReader) | 430 c.lr = io.LimitReader(&c.sr, noLimit).(*io.LimitedReader) |
433 » br, sr := newBufioReader(c.lr) | 431 » br := newBufioReader(c.lr) |
434 » bw, sw := newBufioWriterSize(c.rwc, 4<<10) | 432 » bw := newBufioWriterSize(c.rwc, 4<<10) |
435 c.buf = bufio.NewReadWriter(br, bw) | 433 c.buf = bufio.NewReadWriter(br, bw) |
436 c.bufswr = sr | |
437 c.bufsww = sw | |
438 return c, nil | 434 return c, nil |
439 } | |
440 | |
441 // TODO: remove this, if issue 5100 is fixed | |
442 type bufioReaderPair struct { | |
443 br *bufio.Reader | |
444 sr *switchReader // from which the bufio.Reader is reading | |
445 } | |
446 | |
447 // TODO: remove this, if issue 5100 is fixed | |
448 type bufioWriterPair struct { | |
449 bw *bufio.Writer | |
450 sw *switchWriter // to which the bufio.Writer is writing | |
451 } | 435 } |
452 | 436 |
453 // TODO: use a sync.Cache instead | 437 // TODO: use a sync.Cache instead |
454 var ( | 438 var ( |
455 » bufioReaderCache = make(chan bufioReaderPair, 4) | 439 » bufioReaderCache = make(chan *bufio.Reader, 4) |
456 » bufioWriterCache2k = make(chan bufioWriterPair, 4) | 440 » bufioWriterCache2k = make(chan *bufio.Writer, 4) |
457 » bufioWriterCache4k = make(chan bufioWriterPair, 4) | 441 » bufioWriterCache4k = make(chan *bufio.Writer, 4) |
458 ) | 442 ) |
459 | 443 |
460 func bufioWriterCache(size int) chan bufioWriterPair { | 444 func bufioWriterCache(size int) chan *bufio.Writer { |
461 switch size { | 445 switch size { |
462 case 2 << 10: | 446 case 2 << 10: |
463 return bufioWriterCache2k | 447 return bufioWriterCache2k |
464 case 4 << 10: | 448 case 4 << 10: |
465 return bufioWriterCache4k | 449 return bufioWriterCache4k |
466 } | 450 } |
467 return nil | 451 return nil |
468 } | 452 } |
469 | 453 |
470 func newBufioReader(r io.Reader) (*bufio.Reader, *switchReader) { | 454 func newBufioReader(r io.Reader) *bufio.Reader { |
471 select { | 455 select { |
472 case p := <-bufioReaderCache: | 456 case p := <-bufioReaderCache: |
473 » » p.sr.Reader = r | 457 » » p.Reset(r) |
474 » » return p.br, p.sr | 458 » » return p |
475 default: | 459 default: |
476 » » sr := &switchReader{r} | 460 » » return bufio.NewReader(r) |
477 » » return bufio.NewReader(sr), sr | 461 » } |
478 » } | 462 } |
479 } | 463 |
480 | 464 func putBufioReader(br *bufio.Reader) { |
481 func putBufioReader(br *bufio.Reader, sr *switchReader) { | 465 » br.Reset(nil) |
482 » if n := br.Buffered(); n > 0 { | |
483 » » io.CopyN(ioutil.Discard, br, int64(n)) | |
484 » } | |
485 » br.Read(nil) // clears br.err | |
486 » sr.Reader = nil | |
487 select { | 466 select { |
488 » case bufioReaderCache <- bufioReaderPair{br, sr}: | 467 » case bufioReaderCache <- br: |
489 default: | 468 default: |
490 } | 469 } |
491 } | 470 } |
492 | 471 |
493 func newBufioWriterSize(w io.Writer, size int) (*bufio.Writer, *switchWriter) { | 472 func newBufioWriterSize(w io.Writer, size int) *bufio.Writer { |
494 select { | 473 select { |
495 case p := <-bufioWriterCache(size): | 474 case p := <-bufioWriterCache(size): |
496 » » p.sw.Writer = w | 475 » » p.Reset(w) |
497 » » return p.bw, p.sw | 476 » » return p |
498 default: | 477 default: |
499 » » sw := &switchWriter{w} | 478 » » return bufio.NewWriterSize(w, size) |
500 » » return bufio.NewWriterSize(sw, size), sw | 479 » } |
501 » } | 480 } |
502 } | 481 |
503 | 482 func putBufioWriter(bw *bufio.Writer) { |
504 func putBufioWriter(bw *bufio.Writer, sw *switchWriter) { | 483 » bw.Reset(nil) |
505 » if bw.Buffered() > 0 { | |
506 » » // It must have failed to flush to its target | |
507 » » // earlier. We can't reuse this bufio.Writer. | |
508 » » return | |
509 » } | |
510 » if err := bw.Flush(); err != nil { | |
511 » » // Its sticky error field is set, which is returned by | |
512 » » // Flush even when there's no data buffered. This | |
513 » » // bufio Writer is dead to us. Don't reuse it. | |
514 » » return | |
515 » } | |
516 » sw.Writer = nil | |
517 select { | 484 select { |
518 » case bufioWriterCache(bw.Available()) <- bufioWriterPair{bw, sw}: | 485 » case bufioWriterCache(bw.Available()) <- bw: |
519 default: | 486 default: |
520 } | 487 } |
521 } | 488 } |
522 | 489 |
523 // DefaultMaxHeaderBytes is the maximum permitted size of the headers | 490 // DefaultMaxHeaderBytes is the maximum permitted size of the headers |
524 // in an HTTP request. | 491 // in an HTTP request. |
525 // This can be overridden by setting Server.MaxHeaderBytes. | 492 // This can be overridden by setting Server.MaxHeaderBytes. |
526 const DefaultMaxHeaderBytes = 1 << 20 // 1 MB | 493 const DefaultMaxHeaderBytes = 1 << 20 // 1 MB |
527 | 494 |
528 func (srv *Server) maxHeaderBytes() int { | 495 func (srv *Server) maxHeaderBytes() int { |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 req.RemoteAddr = c.remoteAddr | 581 req.RemoteAddr = c.remoteAddr |
615 req.TLS = c.tlsState | 582 req.TLS = c.tlsState |
616 | 583 |
617 w = &response{ | 584 w = &response{ |
618 conn: c, | 585 conn: c, |
619 req: req, | 586 req: req, |
620 handlerHeader: make(Header), | 587 handlerHeader: make(Header), |
621 contentLength: -1, | 588 contentLength: -1, |
622 } | 589 } |
623 w.cw.res = w | 590 w.cw.res = w |
624 » w.w, w.sw = newBufioWriterSize(&w.cw, bufferBeforeChunkingSize) | 591 » w.w = newBufioWriterSize(&w.cw, bufferBeforeChunkingSize) |
625 return w, nil | 592 return w, nil |
626 } | 593 } |
627 | 594 |
628 func (w *response) Header() Header { | 595 func (w *response) Header() Header { |
629 if w.cw.header == nil && w.wroteHeader && !w.cw.wroteHeader { | 596 if w.cw.header == nil && w.wroteHeader && !w.cw.wroteHeader { |
630 // Accessing the header between logically writing it | 597 // Accessing the header between logically writing it |
631 // and physically writing it means we need to allocate | 598 // and physically writing it means we need to allocate |
632 // a clone to snapshot the logically written state. | 599 // a clone to snapshot the logically written state. |
633 w.cw.header = w.handlerHeader.clone() | 600 w.cw.header = w.handlerHeader.clone() |
634 } | 601 } |
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1000 } | 967 } |
1001 | 968 |
1002 func (w *response) finishRequest() { | 969 func (w *response) finishRequest() { |
1003 w.handlerDone = true | 970 w.handlerDone = true |
1004 | 971 |
1005 if !w.wroteHeader { | 972 if !w.wroteHeader { |
1006 w.WriteHeader(StatusOK) | 973 w.WriteHeader(StatusOK) |
1007 } | 974 } |
1008 | 975 |
1009 w.w.Flush() | 976 w.w.Flush() |
1010 » putBufioWriter(w.w, w.sw) | 977 » putBufioWriter(w.w) |
1011 w.cw.close() | 978 w.cw.close() |
1012 w.conn.buf.Flush() | 979 w.conn.buf.Flush() |
1013 | 980 |
1014 // Close the body, unless we're about to close the whole TCP connection | 981 // Close the body, unless we're about to close the whole TCP connection |
1015 // anyway. | 982 // anyway. |
1016 if !w.closeAfterReply { | 983 if !w.closeAfterReply { |
1017 w.req.Body.Close() | 984 w.req.Body.Close() |
1018 } | 985 } |
1019 if w.req.MultipartForm != nil { | 986 if w.req.MultipartForm != nil { |
1020 w.req.MultipartForm.RemoveAll() | 987 w.req.MultipartForm.RemoveAll() |
(...skipping 12 matching lines...) Expand all Loading... |
1033 w.w.Flush() | 1000 w.w.Flush() |
1034 w.cw.flush() | 1001 w.cw.flush() |
1035 } | 1002 } |
1036 | 1003 |
1037 func (c *conn) finalFlush() { | 1004 func (c *conn) finalFlush() { |
1038 if c.buf != nil { | 1005 if c.buf != nil { |
1039 c.buf.Flush() | 1006 c.buf.Flush() |
1040 | 1007 |
1041 // Steal the bufio.Reader (~4KB worth of memory) and its associa
ted | 1008 // Steal the bufio.Reader (~4KB worth of memory) and its associa
ted |
1042 // reader for a future connection. | 1009 // reader for a future connection. |
1043 » » putBufioReader(c.buf.Reader, c.bufswr) | 1010 » » putBufioReader(c.buf.Reader) |
1044 | 1011 |
1045 // Steal the bufio.Writer (~4KB worth of memory) and its associa
ted | 1012 // Steal the bufio.Writer (~4KB worth of memory) and its associa
ted |
1046 // writer for a future connection. | 1013 // writer for a future connection. |
1047 » » putBufioWriter(c.buf.Writer, c.bufsww) | 1014 » » putBufioWriter(c.buf.Writer) |
1048 | 1015 |
1049 c.buf = nil | 1016 c.buf = nil |
1050 } | 1017 } |
1051 } | 1018 } |
1052 | 1019 |
1053 // Close the connection. | 1020 // Close the connection. |
1054 func (c *conn) close() { | 1021 func (c *conn) close() { |
1055 c.finalFlush() | 1022 c.finalFlush() |
1056 if c.rwc != nil { | 1023 if c.rwc != nil { |
1057 c.rwc.Close() | 1024 c.rwc.Close() |
(...skipping 863 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1921 log.Printf("%s.Read(%d) = %d, %v", c.name, len(p), n, err) | 1888 log.Printf("%s.Read(%d) = %d, %v", c.name, len(p), n, err) |
1922 return | 1889 return |
1923 } | 1890 } |
1924 | 1891 |
1925 func (c *loggingConn) Close() (err error) { | 1892 func (c *loggingConn) Close() (err error) { |
1926 log.Printf("%s.Close() = ...", c.name) | 1893 log.Printf("%s.Close() = ...", c.name) |
1927 err = c.Conn.Close() | 1894 err = c.Conn.Close() |
1928 log.Printf("%s.Close() = %v", c.name, err) | 1895 log.Printf("%s.Close() = %v", c.name, err) |
1929 return | 1896 return |
1930 } | 1897 } |
LEFT | RIGHT |