aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/http/server.go
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@golang.org>2011-05-25 10:15:26 -0700
committerBrad Fitzpatrick <bradfitz@golang.org>2011-05-25 10:15:26 -0700
commitb0f39cc27cb3bcd0c9a53b158d8ea04d6f5c2e28 (patch)
tree682b003c35555606404aeea124fe0a1d34f57061 /src/pkg/http/server.go
parente94eb38975ecdb3d4ed0a200671b6470c0b791a3 (diff)
downloadgo-b0f39cc27cb3bcd0c9a53b158d8ea04d6f5c2e28.tar.xz
io, net, http: sendfile support
Speeds up static fileserver, avoiding kernel/userspace copies. Numbers: downloading 14 MB AppEngine Go SDK with ab (Apache Bench) with 5 threads: Before/after numbers: CPU: user 0m3.910s sys 0m23.650s -> user 0m0.720s sys 0m4.890s Time taken for tests: 8.906 seconds -> Time taken for tests: 8.545 seconds Percentage of the requests served within a certain time (ms) 50% 44 66% 45 75% 46 80% 46 90% 48 95% 51 98% 59 99% 71 100 74 (longest request) -> 50% 42 66% 43 75% 43 80% 44 90% 46 95% 57 98% 62 99% 63 100% 64 (longest request) R=iant, gary.burd, rsc, bradfitz CC=golang-dev https://golang.org/cl/4543071
Diffstat (limited to 'src/pkg/http/server.go')
-rw-r--r--src/pkg/http/server.go21
1 files changed, 21 insertions, 0 deletions
diff --git a/src/pkg/http/server.go b/src/pkg/http/server.go
index eb5a3a365e..ffeac034ef 100644
--- a/src/pkg/http/server.go
+++ b/src/pkg/http/server.go
@@ -119,6 +119,27 @@ type response struct {
closeAfterReply bool
}
+type writerOnly struct {
+ io.Writer
+}
+
+func (r *response) ReadFrom(src io.Reader) (n int64, err os.Error) {
+ // Flush before checking r.chunking, as Flush will call
+ // WriteHeader if it hasn't been called yet, and WriteHeader
+ // is what sets r.chunking.
+ r.Flush()
+ if !r.chunking {
+ if rf, ok := r.conn.rwc.(io.ReaderFrom); ok {
+ n, err = rf.ReadFrom(src)
+ r.written += n
+ return
+ }
+ }
+ // Fall back to default io.Copy implementation.
+ // Use wrapper to hide r.ReadFrom from io.Copy.
+ return io.Copy(writerOnly{r}, src)
+}
+
// Create new connection from rwc.
func newConn(rwc net.Conn, handler Handler) (c *conn, err os.Error) {
c = new(conn)