Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(575)

Delta Between Two Patch Sets: src/pkg/net/http/server.go

Issue 12708046: code review 12708046: net/http: simplify server, use bufio Reader.Reset and W... (Closed)
Left Patch Set: Created 10 years, 7 months ago
Right Patch Set: diff -r b302ea285b42 https://go.googlecode.com/hg/ Created 10 years, 7 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(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
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
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
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
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
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
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 }
LEFTRIGHT
« no previous file | no next file » | Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Toggle Comments ('s')

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b