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

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

Issue 12632043: code review 12632043: net/http: fix early side effects in the ResponseWriter'... (Closed)
Left Patch Set: Created 11 years, 7 months ago
Right Patch Set: diff -r c6b37ee14a9f https://go.googlecode.com/hg/ Created 11 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 | « src/pkg/net/http/serve_test.go ('k') | 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"
11 "crypto/tls" 11 "crypto/tls"
12 "errors" 12 "errors"
13 "fmt" 13 "fmt"
14 "io" 14 "io"
15 "io/ioutil" 15 "io/ioutil"
16 "log" 16 "log"
17 "net" 17 "net"
18 "net/url" 18 "net/url"
19 "os"
19 "path" 20 "path"
20 "runtime" 21 "runtime"
21 "strconv" 22 "strconv"
22 "strings" 23 "strings"
23 "sync" 24 "sync"
24 "time" 25 "time"
25 ) 26 )
26 27
27 // Errors introduced by the HTTP server. 28 // Errors introduced by the HTTP server.
28 var ( 29 var (
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 if !w.wroteHeader { 339 if !w.wroteHeader {
339 w.Header().Set("Connection", "close") 340 w.Header().Set("Connection", "close")
340 } 341 }
341 } 342 }
342 343
343 // needsSniff reports whether a Content-Type still needs to be sniffed. 344 // needsSniff reports whether a Content-Type still needs to be sniffed.
344 func (w *response) needsSniff() bool { 345 func (w *response) needsSniff() bool {
345 return !w.cw.wroteHeader && w.handlerHeader.Get("Content-Type") == "" && w.written < sniffLen 346 return !w.cw.wroteHeader && w.handlerHeader.Get("Content-Type") == "" && w.written < sniffLen
346 } 347 }
347 348
349 // writerOnly hides an io.Writer value's optional ReadFrom method
350 // from io.Copy.
348 type writerOnly struct { 351 type writerOnly struct {
349 io.Writer 352 io.Writer
350 } 353 }
351 354
355 func srcIsRegularFile(src io.Reader) (isRegular bool, err error) {
356 switch v := src.(type) {
357 case *os.File:
358 fi, err := v.Stat()
359 if err != nil {
360 return false, err
361 }
362 return fi.Mode().IsRegular(), nil
363 case *io.LimitedReader:
364 return srcIsRegularFile(v.R)
365 default:
366 return
367 }
368 }
369
370 // ReadFrom is here to optimize copying from an *os.File regular file
371 // to a *net.TCPConn with sendfile.
352 func (w *response) ReadFrom(src io.Reader) (n int64, err error) { 372 func (w *response) ReadFrom(src io.Reader) (n int64, err error) {
373 // Our underlying w.conn.rwc is usually a *TCPConn (with its
374 // own ReadFrom method). If not, or if our src isn't a regular
375 // file, just fall back to the normal copy method.
376 rf, ok := w.conn.rwc.(io.ReaderFrom)
377 regFile, err := srcIsRegularFile(src)
378 if err != nil {
379 return 0, err
380 }
381 if !ok || !regFile {
382 return io.Copy(writerOnly{w}, src)
383 }
384
385 // sendfile path:
386
353 if !w.wroteHeader { 387 if !w.wroteHeader {
354 w.WriteHeader(StatusOK) 388 w.WriteHeader(StatusOK)
355 } 389 }
356 390
357 if w.needsSniff() { 391 if w.needsSniff() {
358 n0, err := io.Copy(writerOnly{w}, io.LimitReader(src, sniffLen)) 392 n0, err := io.Copy(writerOnly{w}, io.LimitReader(src, sniffLen))
359 n += n0 393 n += n0
360 if err != nil { 394 if err != nil {
361 return n, err 395 return n, err
362 } 396 }
363 } 397 }
364 398
365 w.w.Flush() // get rid of any previous writes 399 w.w.Flush() // get rid of any previous writes
366 w.cw.flush() // make sure Header is written; flush data to rwc 400 w.cw.flush() // make sure Header is written; flush data to rwc
367 401
368 // Now that cw has been flushed, its chunking field is guaranteed initia lized. 402 // Now that cw has been flushed, its chunking field is guaranteed initia lized.
369 if !w.cw.chunking && w.bodyAllowed() { 403 if !w.cw.chunking && w.bodyAllowed() {
370 » » if rf, ok := w.conn.rwc.(io.ReaderFrom); ok { 404 » » n0, err := rf.ReadFrom(src)
371 » » » n0, err := rf.ReadFrom(src) 405 » » n += n0
372 » » » n += n0 406 » » w.written += n0
373 » » » w.written += n0 407 » » return n, err
374 » » » return n, err 408 » }
375 » » } 409
376 » }
377
378 » // Fall back to default io.Copy implementation.
379 » // Use wrapper to hide w.ReadFrom from io.Copy.
380 n0, err := io.Copy(writerOnly{w}, src) 410 n0, err := io.Copy(writerOnly{w}, src)
381 n += n0 411 n += n0
382 return n, err 412 return n, err
383 } 413 }
384 414
385 // noLimit is an effective infinite upper bound for io.LimitedReader 415 // noLimit is an effective infinite upper bound for io.LimitedReader
386 const noLimit int64 = (1 << 63) - 1 416 const noLimit int64 = (1 << 63) - 1
387 417
388 // debugServerConnections controls whether all server connections are wrapped 418 // debugServerConnections controls whether all server connections are wrapped
389 // with a verbose logging wrapper. 419 // with a verbose logging wrapper.
(...skipping 1501 matching lines...) Expand 10 before | Expand all | Expand 10 after
1891 log.Printf("%s.Read(%d) = %d, %v", c.name, len(p), n, err) 1921 log.Printf("%s.Read(%d) = %d, %v", c.name, len(p), n, err)
1892 return 1922 return
1893 } 1923 }
1894 1924
1895 func (c *loggingConn) Close() (err error) { 1925 func (c *loggingConn) Close() (err error) {
1896 log.Printf("%s.Close() = ...", c.name) 1926 log.Printf("%s.Close() = ...", c.name)
1897 err = c.Conn.Close() 1927 err = c.Conn.Close()
1898 log.Printf("%s.Close() = %v", c.name, err) 1928 log.Printf("%s.Close() = %v", c.name, err)
1899 return 1929 return
1900 } 1930 }
LEFTRIGHT

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