LEFT | RIGHT |
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/rand" | 15 "crypto/rand" |
16 "crypto/tls" | 16 "crypto/tls" |
17 "fmt" | 17 "fmt" |
18 "io" | 18 "io" |
19 "log" | 19 "log" |
20 "net" | 20 "net" |
21 "os" | 21 "os" |
22 "path" | 22 "path" |
23 "runtime" | 23 "runtime" |
24 "strconv" | 24 "strconv" |
25 "strings" | 25 "strings" |
26 "sync" | 26 "sync" |
27 "syscall" | |
28 "time" | 27 "time" |
29 ) | 28 ) |
30 | 29 |
31 // Errors introduced by the HTTP server. | 30 // Errors introduced by the HTTP server. |
32 var ( | 31 var ( |
33 ErrWriteAfterFlush = os.NewError("Conn.Write called after Flush") | 32 ErrWriteAfterFlush = os.NewError("Conn.Write called after Flush") |
34 ErrBodyNotAllowed = os.NewError("http: response status code does not al
low body") | 33 ErrBodyNotAllowed = os.NewError("http: response status code does not al
low body") |
35 ErrHijacked = os.NewError("Conn has been hijacked") | 34 ErrHijacked = os.NewError("Conn has been hijacked") |
36 ErrContentLength = os.NewError("Conn.Write wrote more than the declare
d Content-Length") | 35 ErrContentLength = os.NewError("Conn.Write wrote more than the declare
d Content-Length") |
37 ) | 36 ) |
(...skipping 804 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
842 if addr == "" { | 841 if addr == "" { |
843 addr = ":http" | 842 addr = ":http" |
844 } | 843 } |
845 l, e := net.Listen("tcp", addr) | 844 l, e := net.Listen("tcp", addr) |
846 if e != nil { | 845 if e != nil { |
847 return e | 846 return e |
848 } | 847 } |
849 return srv.Serve(l) | 848 return srv.Serve(l) |
850 } | 849 } |
851 | 850 |
852 func errorIsAcceptMaxFiles(err os.Error) bool { | |
853 ne, ok := err.(*net.OpError) | |
854 if !ok || ne.Op != "accept" { | |
855 return false | |
856 } | |
857 errno, ok := ne.Error.(os.Errno) | |
858 return ok && errno == os.Errno(syscall.EMFILE) | |
859 } | |
860 | |
861 // Serve accepts incoming connections on the Listener l, creating a | 851 // Serve accepts incoming connections on the Listener l, creating a |
862 // new service thread for each. The service threads read requests and | 852 // new service thread for each. The service threads read requests and |
863 // then call srv.Handler to reply to them. | 853 // then call srv.Handler to reply to them. |
864 func (srv *Server) Serve(l net.Listener) os.Error { | 854 func (srv *Server) Serve(l net.Listener) os.Error { |
865 defer l.Close() | 855 defer l.Close() |
866 handler := srv.Handler | 856 handler := srv.Handler |
867 if handler == nil { | 857 if handler == nil { |
868 handler = DefaultServeMux | 858 handler = DefaultServeMux |
869 } | 859 } |
870 for { | 860 for { |
871 rw, e := l.Accept() | 861 rw, e := l.Accept() |
872 if e != nil { | 862 if e != nil { |
873 » » » if errorIsAcceptMaxFiles(e) { | 863 » » » if ne, ok := e.(net.Error); ok && ne.Temporary() { |
874 log.Printf("http: Accept error: %v", e) | 864 log.Printf("http: Accept error: %v", e) |
875 continue | 865 continue |
876 } | 866 } |
877 return e | 867 return e |
878 } | 868 } |
879 if srv.ReadTimeout != 0 { | 869 if srv.ReadTimeout != 0 { |
880 rw.SetReadTimeout(srv.ReadTimeout) | 870 rw.SetReadTimeout(srv.ReadTimeout) |
881 } | 871 } |
882 if srv.WriteTimeout != 0 { | 872 if srv.WriteTimeout != 0 { |
883 rw.SetWriteTimeout(srv.WriteTimeout) | 873 rw.SetWriteTimeout(srv.WriteTimeout) |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1050 func (tw *timeoutWriter) WriteHeader(code int) { | 1040 func (tw *timeoutWriter) WriteHeader(code int) { |
1051 tw.mu.Lock() | 1041 tw.mu.Lock() |
1052 if tw.timedOut || tw.wroteHeader { | 1042 if tw.timedOut || tw.wroteHeader { |
1053 tw.mu.Unlock() | 1043 tw.mu.Unlock() |
1054 return | 1044 return |
1055 } | 1045 } |
1056 tw.wroteHeader = true | 1046 tw.wroteHeader = true |
1057 tw.mu.Unlock() | 1047 tw.mu.Unlock() |
1058 tw.w.WriteHeader(code) | 1048 tw.w.WriteHeader(code) |
1059 } | 1049 } |
LEFT | RIGHT |