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 // TODO(rsc): | 7 // TODO(rsc): |
8 // logging | 8 // logging |
9 | 9 |
10 package http | 10 package http |
11 | 11 |
12 import ( | 12 import ( |
13 "bufio" | 13 "bufio" |
14 "bytes" | 14 "bytes" |
15 "crypto/tls" | 15 "crypto/tls" |
16 "errors" | 16 "errors" |
17 "fmt" | 17 "fmt" |
18 "io" | 18 "io" |
19 "io/ioutil" | 19 "io/ioutil" |
20 "log" | 20 "log" |
21 "net" | 21 "net" |
| 22 "net/textproto" |
22 "net/url" | 23 "net/url" |
23 "path" | 24 "path" |
24 "runtime/debug" | 25 "runtime/debug" |
25 "strconv" | 26 "strconv" |
26 "strings" | 27 "strings" |
27 "sync" | 28 "sync" |
28 "time" | 29 "time" |
29 ) | 30 ) |
30 | 31 |
31 // Errors introduced by the HTTP server. | 32 // Errors introduced by the HTTP server. |
(...skipping 1271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1303 func (tw *timeoutWriter) WriteHeader(code int) { | 1304 func (tw *timeoutWriter) WriteHeader(code int) { |
1304 tw.mu.Lock() | 1305 tw.mu.Lock() |
1305 if tw.timedOut || tw.wroteHeader { | 1306 if tw.timedOut || tw.wroteHeader { |
1306 tw.mu.Unlock() | 1307 tw.mu.Unlock() |
1307 return | 1308 return |
1308 } | 1309 } |
1309 tw.wroteHeader = true | 1310 tw.wroteHeader = true |
1310 tw.mu.Unlock() | 1311 tw.mu.Unlock() |
1311 tw.w.WriteHeader(code) | 1312 tw.w.WriteHeader(code) |
1312 } | 1313 } |
| 1314 |
| 1315 // A cache holds a set of reusable textproto.Readers. |
| 1316 // The slice is a stack (LIFO). |
| 1317 type cache struct { |
| 1318 mu sync.Mutex |
| 1319 saved []*textproto.Reader |
| 1320 } |
| 1321 |
| 1322 func (c *cache) put(x *textproto.Reader) { |
| 1323 c.mu.Lock() |
| 1324 if len(c.saved) < cap(c.saved) { |
| 1325 c.saved = append(c.saved, x) |
| 1326 } |
| 1327 c.mu.Unlock() |
| 1328 } |
| 1329 |
| 1330 func (c *cache) get() *textproto.Reader { |
| 1331 c.mu.Lock() |
| 1332 // lazy initialization |
| 1333 if cap(c.saved) == 0 { |
| 1334 c.saved = make([]*textproto.Reader, 0, 100) |
| 1335 } |
| 1336 n := len(c.saved) |
| 1337 if n == 0 { |
| 1338 c.mu.Unlock() |
| 1339 return new(textproto.Reader) |
| 1340 } |
| 1341 x := c.saved[n-1] |
| 1342 c.saved = c.saved[0 : n-1] |
| 1343 c.mu.Unlock() |
| 1344 return x |
| 1345 } |
| 1346 |
| 1347 // A cache of reusable textproto.Readers. Reusing them is important |
| 1348 // because each of them has a value cache inside it, which should be |
| 1349 // used during many transactions. |
| 1350 var tpFree cache |
LEFT | RIGHT |