Source file
src/net/http/server.go
1
2
3
4
5
6
7 package http
8
9 import (
10 "bufio"
11 "bytes"
12 "context"
13 "crypto/tls"
14 "errors"
15 "fmt"
16 "internal/godebug"
17 "io"
18 "log"
19 "maps"
20 "math/rand/v2"
21 "net"
22 "net/http/internal"
23 "net/textproto"
24 "net/url"
25 urlpkg "net/url"
26 "path"
27 "runtime"
28 "slices"
29 "strconv"
30 "strings"
31 "sync"
32 "sync/atomic"
33 "time"
34 _ "unsafe"
35
36 "golang.org/x/net/http/httpguts"
37 )
38
39
40 var (
41
42
43
44 ErrBodyNotAllowed = internal.ErrBodyNotAllowed
45
46
47
48
49
50
51 ErrHijacked = errors.New("http: connection has been hijacked")
52
53
54
55
56
57 ErrContentLength = errors.New("http: wrote more than the declared Content-Length")
58
59
60
61
62 ErrWriteAfterFlush = errors.New("unused")
63 )
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89 type Handler interface {
90 ServeHTTP(ResponseWriter, *Request)
91 }
92
93
94
95
96
97 type ResponseWriter interface {
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118 Header() Header
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141 Write([]byte) (int, error)
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161 WriteHeader(statusCode int)
162 }
163
164
165
166
167
168
169
170
171
172
173
174
175 type Flusher interface {
176
177 Flush()
178 }
179
180
181
182
183
184
185
186
187 type Hijacker interface {
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207 Hijack() (net.Conn, *bufio.ReadWriter, error)
208 }
209
210
211
212
213
214
215
216
217
218 type CloseNotifier interface {
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237 CloseNotify() <-chan bool
238 }
239
240 var (
241
242
243
244
245 ServerContextKey = &contextKey{"http-server"}
246
247
248
249
250
251 LocalAddrContextKey = &contextKey{"local-addr"}
252 )
253
254
255 type conn struct {
256
257
258 server *Server
259
260
261 cancelCtx context.CancelFunc
262
263
264
265
266
267 rwc net.Conn
268
269
270
271
272
273 remoteAddr string
274
275
276
277 tlsState *tls.ConnectionState
278
279
280
281 werr error
282
283
284
285
286 r *connReader
287
288
289 bufr *bufio.Reader
290
291
292 bufw *bufio.Writer
293
294
295
296 lastMethod string
297
298 curReq atomic.Pointer[response]
299
300 curState atomic.Uint64
301
302
303 mu sync.Mutex
304
305
306
307
308 hijackedv bool
309 }
310
311 func (c *conn) hijacked() bool {
312 c.mu.Lock()
313 defer c.mu.Unlock()
314 return c.hijackedv
315 }
316
317
318 func (c *conn) hijackLocked() (rwc net.Conn, buf *bufio.ReadWriter, err error) {
319 if c.hijackedv {
320 return nil, nil, ErrHijacked
321 }
322 c.r.abortPendingRead()
323
324 c.hijackedv = true
325 rwc = c.rwc
326 rwc.SetDeadline(time.Time{})
327
328 if c.r.hasByte {
329 if _, err := c.bufr.Peek(c.bufr.Buffered() + 1); err != nil {
330 return nil, nil, fmt.Errorf("unexpected Peek failure reading buffered byte: %v", err)
331 }
332 }
333 c.bufw.Reset(rwc)
334 buf = bufio.NewReadWriter(c.bufr, c.bufw)
335
336 c.setState(rwc, StateHijacked, runHooks)
337 return
338 }
339
340
341
342 const bufferBeforeChunkingSize = 2048
343
344
345
346
347
348
349
350
351
352
353 type chunkWriter struct {
354 res *response
355
356
357
358
359
360 header Header
361
362
363
364
365
366 wroteHeader bool
367
368
369 chunking bool
370 }
371
372 var (
373 crlf = []byte("\r\n")
374 colonSpace = []byte(": ")
375 )
376
377 func (cw *chunkWriter) Write(p []byte) (n int, err error) {
378 if !cw.wroteHeader {
379 cw.writeHeader(p)
380 }
381 if cw.res.req.Method == "HEAD" {
382
383 return len(p), nil
384 }
385 if cw.chunking {
386 _, err = fmt.Fprintf(cw.res.conn.bufw, "%x\r\n", len(p))
387 if err != nil {
388 cw.res.conn.rwc.Close()
389 return
390 }
391 }
392 n, err = cw.res.conn.bufw.Write(p)
393 if cw.chunking && err == nil {
394 _, err = cw.res.conn.bufw.Write(crlf)
395 }
396 if err != nil {
397 cw.res.conn.rwc.Close()
398 }
399 return
400 }
401
402 func (cw *chunkWriter) flush() error {
403 if !cw.wroteHeader {
404 cw.writeHeader(nil)
405 }
406 return cw.res.conn.bufw.Flush()
407 }
408
409 func (cw *chunkWriter) close() {
410 if !cw.wroteHeader {
411 cw.writeHeader(nil)
412 }
413 if cw.chunking {
414 bw := cw.res.conn.bufw
415
416 bw.WriteString("0\r\n")
417 if trailers := cw.res.finalTrailers(); trailers != nil {
418 trailers.Write(bw)
419 }
420
421
422 bw.WriteString("\r\n")
423 }
424 }
425
426
427 type response struct {
428 conn *conn
429 req *Request
430 reqBody io.ReadCloser
431 cancelCtx context.CancelFunc
432 wroteHeader bool
433 wants10KeepAlive bool
434 wantsClose bool
435
436
437
438
439
440
441
442
443 writeContinueMu sync.Mutex
444 canWriteContinue atomic.Bool
445
446 w *bufio.Writer
447 cw chunkWriter
448
449
450
451
452
453 handlerHeader Header
454 calledHeader bool
455
456 written int64
457 contentLength int64
458 status int
459
460
461
462
463
464 closeAfterReply bool
465
466
467
468 fullDuplex bool
469
470
471
472
473
474
475
476
477 requestBodyLimitHit bool
478
479
480
481
482
483 trailers []string
484
485 handlerDone atomic.Bool
486
487
488 dateBuf [len(TimeFormat)]byte
489 clenBuf [10]byte
490 statusBuf [3]byte
491
492
493 lazyCloseNotifyMu sync.Mutex
494
495 closeNotifyCh chan bool
496
497 closeNotifyTriggered bool
498 }
499
500 func (c *response) SetReadDeadline(deadline time.Time) error {
501 return c.conn.rwc.SetReadDeadline(deadline)
502 }
503
504 func (c *response) SetWriteDeadline(deadline time.Time) error {
505 return c.conn.rwc.SetWriteDeadline(deadline)
506 }
507
508 func (c *response) EnableFullDuplex() error {
509 c.fullDuplex = true
510 return nil
511 }
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526 const TrailerPrefix = "Trailer:"
527
528
529
530 func (w *response) finalTrailers() Header {
531 var t Header
532 for k, vv := range w.handlerHeader {
533 if kk, found := strings.CutPrefix(k, TrailerPrefix); found {
534 if t == nil {
535 t = make(Header)
536 }
537 t[kk] = vv
538 }
539 }
540 for _, k := range w.trailers {
541 if t == nil {
542 t = make(Header)
543 }
544 for _, v := range w.handlerHeader[k] {
545 t.Add(k, v)
546 }
547 }
548 return t
549 }
550
551
552
553
554 func (w *response) declareTrailer(k string) {
555 k = CanonicalHeaderKey(k)
556 if !httpguts.ValidTrailerHeader(k) {
557
558 return
559 }
560 w.trailers = append(w.trailers, k)
561 }
562
563
564
565 func (w *response) requestTooLarge() {
566 w.closeAfterReply = true
567 w.requestBodyLimitHit = true
568 if !w.wroteHeader {
569 w.Header().Set("Connection", "close")
570 }
571 }
572
573
574
575
576
577
578
579
580
581 func (w *response) disableWriteContinue(skipDrain bool) {
582 ecr, ok := w.reqBody.(*expectContinueReader)
583 if !ok {
584 return
585 }
586 w.writeContinueMu.Lock()
587 if w.canWriteContinue.Load() {
588 w.canWriteContinue.Store(false)
589 if skipDrain {
590
591
592 w.closeAfterReply = true
593
594 ecr.closed.Store(true)
595 }
596 }
597 w.writeContinueMu.Unlock()
598 }
599
600
601
602 type writerOnly struct {
603 io.Writer
604 }
605
606
607
608
609 func (w *response) ReadFrom(src io.Reader) (n int64, err error) {
610 buf := getCopyBuf()
611 defer putCopyBuf(buf)
612
613
614
615
616 rf, ok := w.conn.rwc.(io.ReaderFrom)
617 if !ok {
618 return io.CopyBuffer(writerOnly{w}, src, buf)
619 }
620
621
622
623
624
625 if !w.cw.wroteHeader {
626 n0, err := io.CopyBuffer(writerOnly{w}, io.LimitReader(src, internal.SniffLen), buf)
627 n += n0
628 if err != nil || n0 < internal.SniffLen {
629 return n, err
630 }
631 }
632
633 w.w.Flush()
634 w.cw.flush()
635
636
637 if !w.cw.chunking && w.bodyAllowed() && w.req.Method != "HEAD" {
638
639
640
641 if w.contentLength != -1 {
642 defer func(originalReader io.Reader) {
643 if w.written != w.contentLength {
644 return
645 }
646 if n, _ := originalReader.Read([]byte{0}); err == nil && n != 0 {
647 err = ErrContentLength
648 }
649 }(src)
650
651
652
653 if lr, ok := src.(*io.LimitedReader); ok {
654 if lenDiff := lr.N - (w.contentLength - w.written); lenDiff > 0 {
655 defer func() { lr.N += lenDiff }()
656 lr.N -= lenDiff
657 }
658 } else {
659 src = io.LimitReader(src, w.contentLength-w.written)
660 }
661 }
662 n0, err := rf.ReadFrom(src)
663 n += n0
664 w.written += n0
665 return n, err
666 }
667
668 n0, err := io.CopyBuffer(writerOnly{w}, src, buf)
669 n += n0
670 return n, err
671 }
672
673
674
675 const debugServerConnections = false
676
677
678 func (s *Server) newConn(rwc net.Conn) *conn {
679 c := &conn{
680 server: s,
681 rwc: rwc,
682 }
683 if debugServerConnections {
684 c.rwc = newLoggingConn("server", c.rwc)
685 }
686 return c
687 }
688
689 type readResult struct {
690 _ incomparable
691 n int
692 err error
693 b byte
694 }
695
696
697
698
699
700
701
702
703 type connReader struct {
704 rwc net.Conn
705
706 mu sync.Mutex
707 conn *conn
708 hasByte bool
709 byteBuf [1]byte
710 cond *sync.Cond
711 inRead bool
712 aborted bool
713 remain int64
714 }
715
716 func (cr *connReader) lock() {
717 cr.mu.Lock()
718 if cr.cond == nil {
719 cr.cond = sync.NewCond(&cr.mu)
720 }
721 }
722
723 func (cr *connReader) unlock() { cr.mu.Unlock() }
724
725 func (cr *connReader) releaseConn() {
726 cr.lock()
727 defer cr.unlock()
728 cr.conn = nil
729 }
730
731 func (cr *connReader) startBackgroundRead() {
732 cr.lock()
733 defer cr.unlock()
734 if cr.inRead {
735 panic("invalid concurrent Body.Read call")
736 }
737 if cr.hasByte {
738 return
739 }
740 cr.inRead = true
741 cr.rwc.SetReadDeadline(time.Time{})
742 go cr.backgroundRead()
743 }
744
745 func (cr *connReader) backgroundRead() {
746 n, err := cr.rwc.Read(cr.byteBuf[:])
747 cr.lock()
748 if n == 1 {
749 cr.hasByte = true
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772 }
773 if ne, ok := err.(net.Error); ok && cr.aborted && ne.Timeout() {
774
775
776 } else if err != nil {
777 cr.handleReadErrorLocked(err)
778 }
779 cr.aborted = false
780 cr.inRead = false
781 cr.unlock()
782 cr.cond.Broadcast()
783 }
784
785 func (cr *connReader) abortPendingRead() {
786 cr.lock()
787 defer cr.unlock()
788 if !cr.inRead {
789 return
790 }
791 cr.aborted = true
792 cr.rwc.SetReadDeadline(aLongTimeAgo)
793 for cr.inRead {
794 cr.cond.Wait()
795 }
796 cr.rwc.SetReadDeadline(time.Time{})
797 }
798
799 func (cr *connReader) setReadLimit(remain int64) { cr.remain = remain }
800 func (cr *connReader) setInfiniteReadLimit() { cr.remain = maxInt64 }
801 func (cr *connReader) hitReadLimit() bool { return cr.remain <= 0 }
802
803
804
805
806
807
808
809
810
811
812
813 func (cr *connReader) handleReadErrorLocked(_ error) {
814 if cr.conn == nil {
815 return
816 }
817 cr.conn.cancelCtx()
818 if res := cr.conn.curReq.Load(); res != nil {
819 res.closeNotify()
820 }
821 }
822
823 func (cr *connReader) Read(p []byte) (n int, err error) {
824 cr.lock()
825 if cr.conn == nil {
826 cr.unlock()
827 return cr.rwc.Read(p)
828 }
829 if cr.inRead {
830 hijacked := cr.conn.hijacked()
831 cr.unlock()
832 if hijacked {
833 panic("invalid Body.Read call. After hijacked, the original Request must not be used")
834 }
835 panic("invalid concurrent Body.Read call")
836 }
837 if cr.hitReadLimit() {
838 cr.unlock()
839 return 0, io.EOF
840 }
841 if len(p) == 0 {
842 cr.unlock()
843 return 0, nil
844 }
845 if int64(len(p)) > cr.remain {
846 p = p[:cr.remain]
847 }
848 if cr.hasByte {
849 p[0] = cr.byteBuf[0]
850 cr.hasByte = false
851 cr.unlock()
852 return 1, nil
853 }
854 cr.inRead = true
855 cr.unlock()
856 n, err = cr.rwc.Read(p)
857
858 cr.lock()
859 cr.inRead = false
860 if err != nil {
861 cr.handleReadErrorLocked(err)
862 }
863 cr.remain -= int64(n)
864 cr.unlock()
865
866 cr.cond.Broadcast()
867 return n, err
868 }
869
870 var (
871 bufioReaderPool sync.Pool
872 bufioWriter2kPool sync.Pool
873 bufioWriter4kPool sync.Pool
874 )
875
876 const copyBufPoolSize = 32 * 1024
877
878 var copyBufPool = sync.Pool{New: func() any { return new([copyBufPoolSize]byte) }}
879
880 func getCopyBuf() []byte {
881 return copyBufPool.Get().(*[copyBufPoolSize]byte)[:]
882 }
883
884 func putCopyBuf(b []byte) {
885 if len(b) != copyBufPoolSize {
886 panic("trying to put back buffer of the wrong size in the copyBufPool")
887 }
888 copyBufPool.Put((*[copyBufPoolSize]byte)(b))
889 }
890
891 func bufioWriterPool(size int) *sync.Pool {
892 switch size {
893 case 2 << 10:
894 return &bufioWriter2kPool
895 case 4 << 10:
896 return &bufioWriter4kPool
897 }
898 return nil
899 }
900
901 func newBufioReader(r io.Reader) *bufio.Reader {
902 if v := bufioReaderPool.Get(); v != nil {
903 br := v.(*bufio.Reader)
904 br.Reset(r)
905 return br
906 }
907
908
909 return bufio.NewReader(r)
910 }
911
912 func putBufioReader(br *bufio.Reader) {
913 br.Reset(nil)
914 bufioReaderPool.Put(br)
915 }
916
917 func newBufioWriterSize(w io.Writer, size int) *bufio.Writer {
918 pool := bufioWriterPool(size)
919 if pool != nil {
920 if v := pool.Get(); v != nil {
921 bw := v.(*bufio.Writer)
922 bw.Reset(w)
923 return bw
924 }
925 }
926 return bufio.NewWriterSize(w, size)
927 }
928
929 func putBufioWriter(bw *bufio.Writer) {
930 bw.Reset(nil)
931 if pool := bufioWriterPool(bw.Available()); pool != nil {
932 pool.Put(bw)
933 }
934 }
935
936
937
938
939 const DefaultMaxHeaderBytes = 1 << 20
940
941
942
943
944 const DefaultMaxHeaderValueCount = 500
945
946 func (s *Server) maxHeaderBytes() int {
947 if s.MaxHeaderBytes > 0 {
948 return s.MaxHeaderBytes
949 }
950 return DefaultMaxHeaderBytes
951 }
952
953 func (s *Server) maxHeaderValueCount() int {
954 if s.MaxHeaderValueCount > 0 {
955 return s.MaxHeaderValueCount
956 }
957 return DefaultMaxHeaderValueCount
958 }
959
960 func (s *Server) initialReadLimitSize() int64 {
961 return int64(s.maxHeaderBytes()) + 4096
962 }
963
964
965
966
967
968
969 func (s *Server) tlsHandshakeTimeout() time.Duration {
970 var ret time.Duration
971 for _, v := range [...]time.Duration{
972 s.ReadHeaderTimeout,
973 s.ReadTimeout,
974 s.WriteTimeout,
975 } {
976 if v <= 0 {
977 continue
978 }
979 if ret == 0 || v < ret {
980 ret = v
981 }
982 }
983 return ret
984 }
985
986
987
988 type expectContinueReader struct {
989 resp *response
990 readCloser io.ReadCloser
991 closed atomic.Bool
992 sawEOF atomic.Bool
993 }
994
995 func (ecr *expectContinueReader) Read(p []byte) (n int, err error) {
996 if ecr.closed.Load() {
997 return 0, ErrBodyReadAfterClose
998 }
999 w := ecr.resp
1000 if w.canWriteContinue.Load() {
1001 w.writeContinueMu.Lock()
1002 if w.canWriteContinue.Load() {
1003 w.conn.bufw.WriteString("HTTP/1.1 100 Continue\r\n\r\n")
1004 w.conn.bufw.Flush()
1005 w.canWriteContinue.Store(false)
1006 }
1007 w.writeContinueMu.Unlock()
1008 }
1009 n, err = ecr.readCloser.Read(p)
1010 if err == io.EOF {
1011 ecr.sawEOF.Store(true)
1012 }
1013 return
1014 }
1015
1016 func (ecr *expectContinueReader) Close() error {
1017 if ecr.resp.canWriteContinue.Load() {
1018 ecr.resp.disableWriteContinue(true)
1019 }
1020 if ecr.closed.Swap(true) {
1021 return nil
1022 }
1023 return ecr.readCloser.Close()
1024 }
1025
1026
1027
1028
1029
1030
1031
1032 const TimeFormat = "Mon, 02 Jan 2006 15:04:05 GMT"
1033
1034 var errTooLarge = errors.New("http: request too large")
1035
1036
1037 func (c *conn) readRequest(ctx context.Context) (w *response, err error) {
1038 if c.hijacked() {
1039 return nil, ErrHijacked
1040 }
1041
1042 t0 := time.Now()
1043 var wholeReqDeadline time.Time
1044 if d := c.server.ReadTimeout; d > 0 {
1045 wholeReqDeadline = t0.Add(d)
1046 }
1047 if d := c.server.WriteTimeout; d > 0 {
1048 defer func() {
1049 c.rwc.SetWriteDeadline(time.Now().Add(d))
1050 }()
1051 }
1052
1053 c.r.setReadLimit(c.server.initialReadLimitSize())
1054 if c.lastMethod == "POST" {
1055
1056 peek, _ := c.bufr.Peek(4)
1057 c.bufr.Discard(numLeadingCRorLF(peek))
1058 }
1059 req, err := readRequestLimit(c.bufr, int64(c.server.maxHeaderValueCount()))
1060 if err != nil {
1061 if c.r.hitReadLimit() {
1062 return nil, errTooLarge
1063 }
1064 return nil, err
1065 }
1066
1067 if !http1ServerSupportsRequest(req) {
1068 return nil, statusError{StatusHTTPVersionNotSupported, "unsupported protocol version"}
1069 }
1070
1071 c.lastMethod = req.Method
1072 c.r.setInfiniteReadLimit()
1073
1074 hosts, haveHost := req.Header["Host"]
1075 isH2Upgrade := req.isH2Upgrade()
1076 if req.ProtoAtLeast(1, 1) && (!haveHost || len(hosts) == 0) && !isH2Upgrade && req.Method != "CONNECT" {
1077 return nil, badRequestError("missing required Host header")
1078 }
1079 if len(hosts) == 1 && !httpguts.ValidHostHeader(hosts[0]) {
1080 return nil, badRequestError("malformed Host header")
1081 }
1082 for k, vv := range req.Header {
1083 if !httpguts.ValidHeaderFieldName(k) {
1084 return nil, badRequestError("invalid header name")
1085 }
1086 for _, v := range vv {
1087 if !httpguts.ValidHeaderFieldValue(v) {
1088 return nil, badRequestError("invalid header value")
1089 }
1090 }
1091 }
1092 delete(req.Header, "Host")
1093
1094 ctx, cancelCtx := context.WithCancel(ctx)
1095 req.ctx = ctx
1096 req.RemoteAddr = c.remoteAddr
1097 req.TLS = c.tlsState
1098 if body, ok := req.Body.(*body); ok {
1099 body.doEarlyClose = true
1100 }
1101
1102 c.rwc.SetReadDeadline(wholeReqDeadline)
1103
1104 w = &response{
1105 conn: c,
1106 cancelCtx: cancelCtx,
1107 req: req,
1108 reqBody: req.Body,
1109 handlerHeader: make(Header),
1110 contentLength: -1,
1111
1112
1113
1114
1115 wants10KeepAlive: req.wantsHttp10KeepAlive(),
1116 wantsClose: req.wantsClose(),
1117 }
1118 if isH2Upgrade {
1119 w.closeAfterReply = true
1120 }
1121 w.cw.res = w
1122 w.w = newBufioWriterSize(&w.cw, bufferBeforeChunkingSize)
1123 return w, nil
1124 }
1125
1126
1127
1128 func http1ServerSupportsRequest(req *Request) bool {
1129 if req.ProtoMajor == 1 {
1130 return true
1131 }
1132
1133
1134 if req.ProtoMajor == 2 && req.ProtoMinor == 0 &&
1135 req.Method == "PRI" && req.RequestURI == "*" {
1136 return true
1137 }
1138
1139
1140 return false
1141 }
1142
1143 func (w *response) Header() Header {
1144 if w.cw.header == nil && w.wroteHeader && !w.cw.wroteHeader {
1145
1146
1147
1148 w.cw.header = w.handlerHeader.Clone()
1149 }
1150 w.calledHeader = true
1151 return w.handlerHeader
1152 }
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163 const maxPostHandlerReadBytes = 256 << 10
1164
1165 func checkWriteHeaderCode(code int) {
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176 if code < 100 || code > 999 {
1177 panic(fmt.Sprintf("invalid WriteHeader code %v", code))
1178 }
1179 }
1180
1181
1182
1183 func relevantCaller() runtime.Frame {
1184 pc := make([]uintptr, 16)
1185 n := runtime.Callers(1, pc)
1186 frames := runtime.CallersFrames(pc[:n])
1187 var frame runtime.Frame
1188 for {
1189 var more bool
1190 frame, more = frames.Next()
1191 if !strings.HasPrefix(frame.Function, "net/http.") {
1192 return frame
1193 }
1194 if !more {
1195 break
1196 }
1197 }
1198 return frame
1199 }
1200
1201 func (w *response) WriteHeader(code int) {
1202 if w.conn.hijacked() {
1203 caller := relevantCaller()
1204 w.conn.server.logf("http: response.WriteHeader on hijacked connection from %s (%s:%d)", caller.Function, path.Base(caller.File), caller.Line)
1205 return
1206 }
1207 if w.wroteHeader {
1208 caller := relevantCaller()
1209 w.conn.server.logf("http: superfluous response.WriteHeader call from %s (%s:%d)", caller.Function, path.Base(caller.File), caller.Line)
1210 return
1211 }
1212 checkWriteHeaderCode(code)
1213
1214
1215
1216
1217
1218 if code == 100 || code >= 200 {
1219 w.disableWriteContinue(code >= 200)
1220 }
1221
1222
1223
1224
1225
1226 if code >= 100 && code <= 199 && code != StatusSwitchingProtocols {
1227 writeStatusLine(w.conn.bufw, w.req.ProtoAtLeast(1, 1), code, w.statusBuf[:])
1228
1229
1230 w.handlerHeader.WriteSubset(w.conn.bufw, excludedHeadersNoBody)
1231 w.conn.bufw.Write(crlf)
1232 w.conn.bufw.Flush()
1233
1234 return
1235 }
1236
1237 w.wroteHeader = true
1238 w.status = code
1239
1240 if w.calledHeader && w.cw.header == nil {
1241 w.cw.header = w.handlerHeader.Clone()
1242 }
1243
1244 if cl := w.handlerHeader.get("Content-Length"); cl != "" {
1245 v, err := strconv.ParseInt(cl, 10, 64)
1246 if err == nil && v >= 0 {
1247 w.contentLength = v
1248 } else {
1249 w.conn.server.logf("http: invalid Content-Length of %q", cl)
1250 w.handlerHeader.Del("Content-Length")
1251 }
1252 }
1253 }
1254
1255
1256
1257
1258 type extraHeader struct {
1259 contentType string
1260 connection string
1261 transferEncoding string
1262 date []byte
1263 contentLength []byte
1264 }
1265
1266
1267 var extraHeaderKeys = [][]byte{
1268 []byte("Content-Type"),
1269 []byte("Connection"),
1270 []byte("Transfer-Encoding"),
1271 }
1272
1273 var (
1274 headerContentLength = []byte("Content-Length: ")
1275 headerDate = []byte("Date: ")
1276 )
1277
1278
1279
1280
1281
1282
1283 func (h extraHeader) Write(w *bufio.Writer) {
1284 if h.date != nil {
1285 w.Write(headerDate)
1286 w.Write(h.date)
1287 w.Write(crlf)
1288 }
1289 if h.contentLength != nil {
1290 w.Write(headerContentLength)
1291 w.Write(h.contentLength)
1292 w.Write(crlf)
1293 }
1294 for i, v := range []string{h.contentType, h.connection, h.transferEncoding} {
1295 if v != "" {
1296 w.Write(extraHeaderKeys[i])
1297 w.Write(colonSpace)
1298 w.WriteString(v)
1299 w.Write(crlf)
1300 }
1301 }
1302 }
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312 func (cw *chunkWriter) writeHeader(p []byte) {
1313 if cw.wroteHeader {
1314 return
1315 }
1316 cw.wroteHeader = true
1317
1318 w := cw.res
1319 keepAlivesEnabled := w.conn.server.doKeepAlives()
1320 isHEAD := w.req.Method == "HEAD"
1321
1322
1323
1324
1325
1326
1327 header := cw.header
1328 owned := header != nil
1329 if !owned {
1330 header = w.handlerHeader
1331 }
1332 var excludeHeader map[string]bool
1333 delHeader := func(key string) {
1334 if owned {
1335 header.Del(key)
1336 return
1337 }
1338 if _, ok := header[key]; !ok {
1339 return
1340 }
1341 if excludeHeader == nil {
1342 excludeHeader = make(map[string]bool)
1343 }
1344 excludeHeader[key] = true
1345 }
1346 var setHeader extraHeader
1347
1348
1349 trailers := false
1350 for k := range cw.header {
1351 if strings.HasPrefix(k, TrailerPrefix) {
1352 if excludeHeader == nil {
1353 excludeHeader = make(map[string]bool)
1354 }
1355 excludeHeader[k] = true
1356 trailers = true
1357 }
1358 }
1359 for _, v := range cw.header["Trailer"] {
1360 trailers = true
1361 foreachHeaderElement(v, cw.res.declareTrailer)
1362 }
1363
1364 te := header.get("Transfer-Encoding")
1365 hasTE := te != ""
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381 if w.handlerDone.Load() && !trailers && !hasTE && bodyAllowedForStatus(w.status) && !header.has("Content-Length") && (!isHEAD || len(p) > 0) {
1382 w.contentLength = int64(len(p))
1383 setHeader.contentLength = strconv.AppendInt(cw.res.clenBuf[:0], int64(len(p)), 10)
1384 }
1385
1386
1387
1388 if w.wants10KeepAlive && keepAlivesEnabled {
1389 sentLength := header.get("Content-Length") != ""
1390 if sentLength && header.get("Connection") == "keep-alive" {
1391 w.closeAfterReply = false
1392 }
1393 }
1394
1395
1396 hasCL := w.contentLength != -1
1397
1398 if w.wants10KeepAlive && (isHEAD || hasCL || !bodyAllowedForStatus(w.status)) {
1399 _, connectionHeaderSet := header["Connection"]
1400 if !connectionHeaderSet {
1401 setHeader.connection = "keep-alive"
1402 }
1403 } else if !w.req.ProtoAtLeast(1, 1) || w.wantsClose {
1404 w.closeAfterReply = true
1405 }
1406
1407 if header.get("Connection") == "close" || !keepAlivesEnabled {
1408 w.closeAfterReply = true
1409 }
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428 if ecr, ok := w.req.Body.(*expectContinueReader); ok && !ecr.sawEOF.Load() {
1429 w.closeAfterReply = true
1430 }
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446 if w.req.ContentLength != 0 && !w.closeAfterReply && !w.fullDuplex {
1447 var discard, tooBig bool
1448
1449 switch bdy := w.req.Body.(type) {
1450 case *expectContinueReader:
1451
1452
1453 case *body:
1454 bdy.mu.Lock()
1455 switch {
1456 case bdy.closed:
1457 if !bdy.sawEOF {
1458
1459 w.closeAfterReply = true
1460 }
1461 case bdy.unreadDataSizeLocked() >= maxPostHandlerReadBytes:
1462 tooBig = true
1463 default:
1464 discard = true
1465 }
1466 bdy.mu.Unlock()
1467 default:
1468 discard = true
1469 }
1470
1471 if discard {
1472 _, err := io.CopyN(io.Discard, w.reqBody, maxPostHandlerReadBytes+1)
1473 switch err {
1474 case nil:
1475
1476 tooBig = true
1477 case ErrBodyReadAfterClose:
1478
1479 case io.EOF:
1480
1481 err = w.reqBody.Close()
1482 if err != nil {
1483 w.closeAfterReply = true
1484 }
1485 default:
1486
1487
1488
1489 w.closeAfterReply = true
1490 }
1491 }
1492
1493 if tooBig {
1494 w.requestTooLarge()
1495 delHeader("Connection")
1496 setHeader.connection = "close"
1497 }
1498 }
1499
1500 code := w.status
1501 if bodyAllowedForStatus(code) {
1502
1503 _, haveType := header["Content-Type"]
1504
1505
1506
1507 ce := header.Get("Content-Encoding")
1508 hasCE := len(ce) > 0
1509 if !hasCE && !haveType && !hasTE && len(p) > 0 {
1510 setHeader.contentType = DetectContentType(p)
1511 }
1512 } else {
1513 for _, k := range suppressedHeaders(code) {
1514 delHeader(k)
1515 }
1516 }
1517
1518 if !header.has("Date") {
1519 setHeader.date = time.Now().UTC().AppendFormat(cw.res.dateBuf[:0], TimeFormat)
1520 }
1521
1522 if hasCL && hasTE && te != "identity" {
1523
1524
1525 w.conn.server.logf("http: WriteHeader called with both Transfer-Encoding of %q and a Content-Length of %d",
1526 te, w.contentLength)
1527 delHeader("Content-Length")
1528 hasCL = false
1529 }
1530
1531 if w.req.Method == "HEAD" || !bodyAllowedForStatus(code) || code == StatusNoContent {
1532
1533 delHeader("Transfer-Encoding")
1534 } else if hasCL {
1535
1536 delHeader("Transfer-Encoding")
1537 } else if w.req.ProtoAtLeast(1, 1) {
1538
1539
1540
1541
1542
1543 if hasTE && te == "identity" {
1544 cw.chunking = false
1545 w.closeAfterReply = true
1546 delHeader("Transfer-Encoding")
1547 } else {
1548
1549
1550 cw.chunking = true
1551 setHeader.transferEncoding = "chunked"
1552 if hasTE && te == "chunked" {
1553
1554 delHeader("Transfer-Encoding")
1555 }
1556 }
1557 } else {
1558
1559
1560
1561 w.closeAfterReply = true
1562 delHeader("Transfer-Encoding")
1563 }
1564
1565
1566 if cw.chunking {
1567 delHeader("Content-Length")
1568 }
1569 if !w.req.ProtoAtLeast(1, 0) {
1570 return
1571 }
1572
1573
1574
1575
1576 delConnectionHeader := w.closeAfterReply &&
1577 (!keepAlivesEnabled || !hasToken(cw.header.get("Connection"), "close")) &&
1578 !isProtocolSwitchResponse(w.status, header)
1579 if delConnectionHeader {
1580 delHeader("Connection")
1581 if w.req.ProtoAtLeast(1, 1) {
1582 setHeader.connection = "close"
1583 }
1584 }
1585
1586 writeStatusLine(w.conn.bufw, w.req.ProtoAtLeast(1, 1), code, w.statusBuf[:])
1587 cw.header.WriteSubset(w.conn.bufw, excludeHeader)
1588 setHeader.Write(w.conn.bufw)
1589 w.conn.bufw.Write(crlf)
1590 }
1591
1592
1593
1594 func foreachHeaderElement(v string, fn func(string)) {
1595 v = textproto.TrimString(v)
1596 if v == "" {
1597 return
1598 }
1599 if !strings.Contains(v, ",") {
1600 fn(v)
1601 return
1602 }
1603 for f := range strings.SplitSeq(v, ",") {
1604 if f = textproto.TrimString(f); f != "" {
1605 fn(f)
1606 }
1607 }
1608 }
1609
1610
1611
1612
1613
1614 func writeStatusLine(bw *bufio.Writer, is11 bool, code int, scratch []byte) {
1615 if is11 {
1616 bw.WriteString("HTTP/1.1 ")
1617 } else {
1618 bw.WriteString("HTTP/1.0 ")
1619 }
1620 if text := StatusText(code); text != "" {
1621 bw.Write(strconv.AppendInt(scratch[:0], int64(code), 10))
1622 bw.WriteByte(' ')
1623 bw.WriteString(text)
1624 bw.WriteString("\r\n")
1625 } else {
1626
1627 fmt.Fprintf(bw, "%03d status code %d\r\n", code, code)
1628 }
1629 }
1630
1631
1632
1633 func (w *response) bodyAllowed() bool {
1634 if !w.wroteHeader {
1635 panic("net/http: bodyAllowed called before the header was written")
1636 }
1637 return bodyAllowedForStatus(w.status)
1638 }
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674 func (w *response) Write(data []byte) (n int, err error) {
1675 return w.write(len(data), data, "")
1676 }
1677
1678 func (w *response) WriteString(data string) (n int, err error) {
1679 return w.write(len(data), nil, data)
1680 }
1681
1682
1683 func (w *response) write(lenData int, dataB []byte, dataS string) (n int, err error) {
1684 if w.conn.hijacked() {
1685 if lenData > 0 {
1686 caller := relevantCaller()
1687 w.conn.server.logf("http: response.Write on hijacked connection from %s (%s:%d)", caller.Function, path.Base(caller.File), caller.Line)
1688 }
1689 return 0, ErrHijacked
1690 }
1691
1692 if w.canWriteContinue.Load() {
1693
1694 w.disableWriteContinue(true)
1695 }
1696
1697 if !w.wroteHeader {
1698 w.WriteHeader(StatusOK)
1699 }
1700 if lenData == 0 {
1701 return 0, nil
1702 }
1703 if !w.bodyAllowed() {
1704 return 0, ErrBodyNotAllowed
1705 }
1706
1707 w.written += int64(lenData)
1708 if w.contentLength != -1 && w.written > w.contentLength {
1709 return 0, ErrContentLength
1710 }
1711 if dataB != nil {
1712 return w.w.Write(dataB)
1713 } else {
1714 return w.w.WriteString(dataS)
1715 }
1716 }
1717
1718 func (w *response) finishRequest() {
1719 w.handlerDone.Store(true)
1720
1721 if !w.wroteHeader {
1722 w.WriteHeader(StatusOK)
1723 }
1724
1725 w.w.Flush()
1726 putBufioWriter(w.w)
1727 w.cw.close()
1728 w.conn.bufw.Flush()
1729
1730 w.conn.r.abortPendingRead()
1731
1732 if w.canWriteContinue.Load() {
1733 w.disableWriteContinue(true)
1734 }
1735
1736
1737
1738 w.reqBody.Close()
1739
1740 if w.req.MultipartForm != nil {
1741 w.req.MultipartForm.RemoveAll()
1742 }
1743 }
1744
1745
1746
1747 func (w *response) shouldReuseConnection() bool {
1748 if w.closeAfterReply {
1749
1750
1751
1752 return false
1753 }
1754
1755 if w.req.Method != "HEAD" && w.contentLength != -1 && w.bodyAllowed() && w.contentLength != w.written {
1756
1757 return false
1758 }
1759
1760
1761
1762 if w.conn.werr != nil {
1763 return false
1764 }
1765
1766 if w.closedRequestBodyEarly() {
1767 return false
1768 }
1769
1770 return true
1771 }
1772
1773 func (w *response) closedRequestBodyEarly() bool {
1774 body, ok := w.req.Body.(*body)
1775 return ok && body.didEarlyClose()
1776 }
1777
1778 func (w *response) Flush() {
1779 w.FlushError()
1780 }
1781
1782 func (w *response) FlushError() error {
1783 if !w.wroteHeader {
1784 w.WriteHeader(StatusOK)
1785 }
1786 err := w.w.Flush()
1787 e2 := w.cw.flush()
1788 if err == nil {
1789 err = e2
1790 }
1791 return err
1792 }
1793
1794 func (c *conn) finalFlush() {
1795 if c.bufr != nil {
1796
1797
1798 putBufioReader(c.bufr)
1799 c.bufr = nil
1800 }
1801
1802 if c.bufw != nil {
1803 c.bufw.Flush()
1804
1805
1806 putBufioWriter(c.bufw)
1807 c.bufw = nil
1808 }
1809 }
1810
1811
1812 func (c *conn) close() {
1813 c.finalFlush()
1814 c.rwc.Close()
1815 }
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828 var rstAvoidanceDelay = 500 * time.Millisecond
1829
1830 type closeWriter interface {
1831 CloseWrite() error
1832 }
1833
1834 var _ closeWriter = (*net.TCPConn)(nil)
1835
1836
1837
1838
1839
1840
1841
1842 func (c *conn) closeWriteAndWait() {
1843 c.finalFlush()
1844 if tcp, ok := c.rwc.(closeWriter); ok {
1845 tcp.CloseWrite()
1846 }
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868 time.Sleep(rstAvoidanceDelay)
1869 }
1870
1871
1872
1873
1874 func validNextProto(proto string) bool {
1875 switch proto {
1876 case "", "http/1.1", "http/1.0":
1877 return false
1878 }
1879 return true
1880 }
1881
1882 const (
1883 runHooks = true
1884 skipHooks = false
1885 )
1886
1887 func (c *conn) setState(nc net.Conn, state ConnState, runHook bool) {
1888 srv := c.server
1889 switch state {
1890 case StateNew:
1891 srv.trackConn(c, true)
1892 case StateHijacked, StateClosed:
1893 srv.trackConn(c, false)
1894 }
1895 if state > 0xff || state < 0 {
1896 panic("internal error")
1897 }
1898 packedState := uint64(time.Now().Unix()<<8) | uint64(state)
1899 c.curState.Store(packedState)
1900 if !runHook {
1901 return
1902 }
1903 if hook := srv.ConnState; hook != nil {
1904 hook(nc, state)
1905 }
1906 }
1907
1908 func (c *conn) getState() (state ConnState, unixSec int64) {
1909 packedState := c.curState.Load()
1910 return ConnState(packedState & 0xff), int64(packedState >> 8)
1911 }
1912
1913
1914
1915
1916 func badRequestError(e string) error { return statusError{StatusBadRequest, e} }
1917
1918
1919
1920 type statusError struct {
1921 code int
1922 text string
1923 }
1924
1925 func (e statusError) Error() string { return StatusText(e.code) + ": " + e.text }
1926
1927
1928
1929
1930
1931 var ErrAbortHandler = internal.ErrAbortHandler
1932
1933
1934
1935
1936
1937 func isCommonNetReadError(err error) bool {
1938 if err == io.EOF {
1939 return true
1940 }
1941 if neterr, ok := err.(net.Error); ok && neterr.Timeout() {
1942 return true
1943 }
1944 if oe, ok := err.(*net.OpError); ok && oe.Op == "read" {
1945 return true
1946 }
1947 return false
1948 }
1949
1950
1951 func (c *conn) serve(ctx context.Context) {
1952 if ra := c.rwc.RemoteAddr(); ra != nil {
1953 c.remoteAddr = ra.String()
1954 }
1955 ctx = context.WithValue(ctx, LocalAddrContextKey, c.rwc.LocalAddr())
1956 var inFlightResponse *response
1957 defer func() {
1958 if err := recover(); err != nil && err != ErrAbortHandler {
1959 const size = 64 << 10
1960 buf := make([]byte, size)
1961 buf = buf[:runtime.Stack(buf, false)]
1962 c.server.logf("http: panic serving %v: %v\n%s", c.remoteAddr, err, buf)
1963 }
1964 if inFlightResponse != nil {
1965 inFlightResponse.cancelCtx()
1966 inFlightResponse.disableWriteContinue(true)
1967 }
1968 if !c.hijacked() {
1969 if inFlightResponse != nil {
1970 inFlightResponse.conn.r.abortPendingRead()
1971 inFlightResponse.reqBody.Close()
1972 }
1973 c.close()
1974 c.setState(c.rwc, StateClosed, runHooks)
1975 }
1976 }()
1977
1978 type connectionStater interface {
1979 ConnectionState() tls.ConnectionState
1980 }
1981 type handshakeContexter interface {
1982 HandshakeContext(ctx context.Context) error
1983 }
1984 if connStater, ok := c.rwc.(connectionStater); ok {
1985 tlsTO := c.server.tlsHandshakeTimeout()
1986 if tlsTO > 0 {
1987 dl := time.Now().Add(tlsTO)
1988 c.rwc.SetReadDeadline(dl)
1989 c.rwc.SetWriteDeadline(dl)
1990 }
1991 var err error
1992 if handshaker, ok := c.rwc.(handshakeContexter); ok {
1993 err = handshaker.HandshakeContext(ctx)
1994 }
1995 if err != nil {
1996
1997
1998
1999 var reason string
2000 if re, ok := err.(tls.RecordHeaderError); ok && re.Conn != nil && tlsRecordHeaderLooksLikeHTTP(re.RecordHeader) {
2001 io.WriteString(re.Conn, "HTTP/1.0 400 Bad Request\r\n\r\nClient sent an HTTP request to an HTTPS server.\n")
2002 re.Conn.Close()
2003 reason = "client sent an HTTP request to an HTTPS server"
2004 } else {
2005 reason = err.Error()
2006 }
2007 c.server.logf("http: TLS handshake error from %s: %v", c.rwc.RemoteAddr(), reason)
2008 return
2009 }
2010
2011 if tlsTO > 0 {
2012 c.rwc.SetReadDeadline(time.Time{})
2013 c.rwc.SetWriteDeadline(time.Time{})
2014 }
2015 c.tlsState = new(tls.ConnectionState)
2016 *c.tlsState = connStater.ConnectionState()
2017 proto := c.tlsState.NegotiatedProtocol
2018 if proto == "h2" && c.server.h2 != nil {
2019
2020
2021
2022
2023
2024 c.setState(c.rwc, StateActive, skipHooks)
2025 const sawClientPreface = false
2026 c.server.serveHTTP2Conn(ctx, c.rwc, serverHandler{c.server}, sawClientPreface, nil, nil)
2027 return
2028 }
2029 tlsConn, tlsConnOK := c.rwc.(*tls.Conn)
2030 if validNextProto(proto) && tlsConnOK {
2031
2032 if fn := c.server.TLSNextProto[proto]; fn != nil {
2033 h := initALPNRequest{ctx, tlsConn, serverHandler{c.server}}
2034
2035 c.setState(c.rwc, StateActive, skipHooks)
2036 fn(c.server, tlsConn, h)
2037 }
2038 return
2039 }
2040 }
2041
2042
2043
2044
2045 if c.tlsState == nil {
2046 if tc, ok := c.rwc.(connectionStater); ok {
2047 c.tlsState = new(tls.ConnectionState)
2048 *c.tlsState = tc.ConnectionState()
2049 }
2050 }
2051
2052 ctx, cancelCtx := context.WithCancel(ctx)
2053 c.cancelCtx = cancelCtx
2054 defer cancelCtx()
2055
2056 c.r = &connReader{conn: c, rwc: c.rwc}
2057 c.bufr = newBufioReader(c.r)
2058 c.bufw = newBufioWriterSize(checkConnErrorWriter{c}, 4<<10)
2059
2060 if d := c.server.readHeaderTimeout(); d > 0 {
2061 c.rwc.SetReadDeadline(time.Now().Add(d))
2062 }
2063
2064 protos := c.server.protocols()
2065 if c.tlsState == nil && protos.UnencryptedHTTP2() {
2066 if c.maybeServeUnencryptedHTTP2(ctx) {
2067 return
2068 }
2069 }
2070 if !protos.HTTP1() {
2071 return
2072 }
2073
2074
2075
2076 for {
2077 w, err := c.readRequest(ctx)
2078 if c.r.remain != c.server.initialReadLimitSize() {
2079
2080 c.setState(c.rwc, StateActive, runHooks)
2081 }
2082 if c.server.shuttingDown() {
2083 return
2084 }
2085 if err != nil {
2086 const errorHeaders = "\r\nContent-Type: text/plain; charset=utf-8\r\nConnection: close\r\n\r\n"
2087
2088 switch {
2089 case err == errTooLarge:
2090
2091
2092
2093
2094
2095 const publicErr = "431 Request Header Fields Too Large"
2096 fmt.Fprintf(c.rwc, "HTTP/1.1 "+publicErr+errorHeaders+publicErr)
2097 c.closeWriteAndWait()
2098 return
2099
2100 case isUnsupportedTEError(err):
2101
2102
2103
2104
2105 code := StatusNotImplemented
2106
2107
2108
2109 fmt.Fprintf(c.rwc, "HTTP/1.1 %d %s%sUnsupported transfer encoding", code, StatusText(code), errorHeaders)
2110 return
2111
2112 case isCommonNetReadError(err):
2113 return
2114
2115 default:
2116 if v, ok := err.(statusError); ok {
2117 fmt.Fprintf(c.rwc, "HTTP/1.1 %d %s: %s%s%d %s: %s", v.code, StatusText(v.code), v.text, errorHeaders, v.code, StatusText(v.code), v.text)
2118 return
2119 }
2120 const publicErr = "400 Bad Request"
2121 fmt.Fprintf(c.rwc, "HTTP/1.1 "+publicErr+errorHeaders+publicErr)
2122 return
2123 }
2124 }
2125
2126
2127 req := w.req
2128 if req.expectsContinue() {
2129 if req.ProtoAtLeast(1, 1) && req.ContentLength != 0 {
2130
2131 req.Body = &expectContinueReader{readCloser: req.Body, resp: w}
2132 w.canWriteContinue.Store(true)
2133 w.reqBody = req.Body
2134 }
2135 } else if req.Header.get("Expect") != "" {
2136 w.sendExpectationFailed()
2137 return
2138 }
2139
2140 c.curReq.Store(w)
2141
2142 if requestBodyRemains(req.Body) {
2143 registerOnHitEOF(req.Body, w.conn.r.startBackgroundRead)
2144 } else {
2145 w.conn.r.startBackgroundRead()
2146 }
2147
2148
2149
2150
2151
2152
2153
2154
2155 inFlightResponse = w
2156 serverHandler{c.server}.ServeHTTP(w, w.req)
2157 inFlightResponse = nil
2158 w.cancelCtx()
2159 if c.hijacked() {
2160 c.r.releaseConn()
2161 return
2162 }
2163 w.finishRequest()
2164 c.rwc.SetWriteDeadline(time.Time{})
2165 if !w.shouldReuseConnection() {
2166 if w.requestBodyLimitHit || w.closedRequestBodyEarly() {
2167 c.closeWriteAndWait()
2168 }
2169 return
2170 }
2171 c.setState(c.rwc, StateIdle, runHooks)
2172 c.curReq.Store(nil)
2173
2174 if !w.conn.server.doKeepAlives() {
2175
2176
2177
2178
2179 return
2180 }
2181
2182 if d := c.server.idleTimeout(); d > 0 {
2183 c.rwc.SetReadDeadline(time.Now().Add(d))
2184 } else {
2185 c.rwc.SetReadDeadline(time.Time{})
2186 }
2187
2188
2189
2190
2191
2192 if _, err := c.bufr.Peek(4); err != nil {
2193 return
2194 }
2195
2196 if d := c.server.readHeaderTimeout(); d > 0 {
2197 c.rwc.SetReadDeadline(time.Now().Add(d))
2198 } else {
2199 c.rwc.SetReadDeadline(time.Time{})
2200 }
2201 }
2202 }
2203
2204
2205
2206
2207
2208 type unencryptedHTTP2Request struct {
2209 ctx context.Context
2210 c net.Conn
2211 h serverHandler
2212 }
2213
2214 func (h unencryptedHTTP2Request) BaseContext() context.Context { return h.ctx }
2215
2216 func (h unencryptedHTTP2Request) ServeHTTP(rw ResponseWriter, req *Request) {
2217 if req.Body == nil {
2218 req.Body = NoBody
2219 }
2220 if req.RemoteAddr == "" {
2221 req.RemoteAddr = h.c.RemoteAddr().String()
2222 }
2223 h.h.ServeHTTP(rw, req)
2224 }
2225
2226
2227
2228 type unencryptedNetConnInTLSConn struct {
2229 net.Conn
2230 conn net.Conn
2231 }
2232
2233 func (c unencryptedNetConnInTLSConn) UnencryptedNetConn() net.Conn {
2234 return c.conn
2235 }
2236
2237 func unencryptedTLSConn(c net.Conn) *tls.Conn {
2238 return tls.Client(unencryptedNetConnInTLSConn{conn: c}, nil)
2239 }
2240
2241
2242
2243 const nextProtoUnencryptedHTTP2 = "unencrypted_http2"
2244
2245 func (c *conn) maybeServeUnencryptedHTTP2(ctx context.Context) bool {
2246 var nextFunc func(*Server, *tls.Conn, Handler)
2247 if c.server.h2 == nil {
2248 var ok bool
2249 nextFunc, ok = c.server.TLSNextProto[nextProtoUnencryptedHTTP2]
2250 if !ok {
2251 return false
2252 }
2253 }
2254 hasPreface := func(c *conn, preface []byte) bool {
2255 c.r.setReadLimit(int64(len(preface)) - int64(c.bufr.Buffered()))
2256 got, err := c.bufr.Peek(len(preface))
2257 c.r.setInfiniteReadLimit()
2258 return err == nil && bytes.Equal(got, preface)
2259 }
2260 if !hasPreface(c, []byte("PRI * HTTP/2.0")) {
2261 return false
2262 }
2263 if !hasPreface(c, []byte("PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n")) {
2264 return false
2265 }
2266 c.setState(c.rwc, StateActive, skipHooks)
2267 if c.server.h2 != nil {
2268 const sawClientPreface = true
2269 c.server.serveHTTP2Conn(ctx, c.rwc, serverHandler{c.server}, sawClientPreface, nil, nil)
2270 } else {
2271 h := unencryptedHTTP2Request{ctx, c.rwc, serverHandler{c.server}}
2272 nextFunc(c.server, unencryptedTLSConn(c.rwc), h)
2273 }
2274 return true
2275 }
2276
2277 func (w *response) sendExpectationFailed() {
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290 w.Header().Set("Connection", "close")
2291 w.WriteHeader(StatusExpectationFailed)
2292 w.finishRequest()
2293 }
2294
2295
2296
2297 func (w *response) Hijack() (rwc net.Conn, buf *bufio.ReadWriter, err error) {
2298 if w.handlerDone.Load() {
2299 panic("net/http: Hijack called after ServeHTTP finished")
2300 }
2301 w.disableWriteContinue(false)
2302 if w.wroteHeader {
2303 w.cw.flush()
2304 }
2305
2306 c := w.conn
2307 c.mu.Lock()
2308 defer c.mu.Unlock()
2309
2310
2311
2312 rwc, buf, err = c.hijackLocked()
2313 if err == nil {
2314 putBufioWriter(w.w)
2315 w.w = nil
2316 }
2317 return rwc, buf, err
2318 }
2319
2320 func (w *response) CloseNotify() <-chan bool {
2321 w.lazyCloseNotifyMu.Lock()
2322 defer w.lazyCloseNotifyMu.Unlock()
2323 if w.handlerDone.Load() {
2324 panic("net/http: CloseNotify called after ServeHTTP finished")
2325 }
2326 if w.closeNotifyCh == nil {
2327 w.closeNotifyCh = make(chan bool, 1)
2328 if w.closeNotifyTriggered {
2329 w.closeNotifyCh <- true
2330 }
2331 }
2332 return w.closeNotifyCh
2333 }
2334
2335 func (w *response) closeNotify() {
2336 w.lazyCloseNotifyMu.Lock()
2337 defer w.lazyCloseNotifyMu.Unlock()
2338 if w.closeNotifyTriggered {
2339 return
2340 }
2341 w.closeNotifyTriggered = true
2342 if w.closeNotifyCh != nil {
2343 w.closeNotifyCh <- true
2344 }
2345 }
2346
2347 func registerOnHitEOF(rc io.ReadCloser, fn func()) {
2348 switch v := rc.(type) {
2349 case *expectContinueReader:
2350 registerOnHitEOF(v.readCloser, fn)
2351 case *body:
2352 v.registerOnHitEOF(fn)
2353 default:
2354 panic("unexpected type " + fmt.Sprintf("%T", rc))
2355 }
2356 }
2357
2358
2359
2360 func requestBodyRemains(rc io.ReadCloser) bool {
2361 if rc == NoBody {
2362 return false
2363 }
2364 switch v := rc.(type) {
2365 case *expectContinueReader:
2366 return requestBodyRemains(v.readCloser)
2367 case *body:
2368 return v.bodyRemains()
2369 default:
2370 panic("unexpected type " + fmt.Sprintf("%T", rc))
2371 }
2372 }
2373
2374
2375
2376
2377
2378 type HandlerFunc func(ResponseWriter, *Request)
2379
2380
2381 func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
2382 f(w, r)
2383 }
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397 func Error(w ResponseWriter, error string, code int) {
2398 h := w.Header()
2399
2400
2401
2402
2403
2404
2405
2406
2407 h.Del("Content-Length")
2408
2409
2410
2411 h.Set("Content-Type", "text/plain; charset=utf-8")
2412 h.Set("X-Content-Type-Options", "nosniff")
2413 w.WriteHeader(code)
2414 fmt.Fprintln(w, error)
2415 }
2416
2417
2418 func NotFound(w ResponseWriter, r *Request) { Error(w, "404 page not found", StatusNotFound) }
2419
2420
2421
2422 func NotFoundHandler() Handler { return HandlerFunc(NotFound) }
2423
2424
2425
2426
2427
2428
2429
2430 func StripPrefix(prefix string, h Handler) Handler {
2431 if prefix == "" {
2432 return h
2433 }
2434 return HandlerFunc(func(w ResponseWriter, r *Request) {
2435 p := strings.TrimPrefix(r.URL.Path, prefix)
2436 rp := strings.TrimPrefix(r.URL.RawPath, prefix)
2437 if len(p) < len(r.URL.Path) && (r.URL.RawPath == "" || len(rp) < len(r.URL.RawPath)) {
2438 r2 := new(Request)
2439 *r2 = *r
2440 r2.URL = new(url.URL)
2441 *r2.URL = *r.URL
2442 r2.URL.Path = p
2443 r2.URL.RawPath = rp
2444 h.ServeHTTP(w, r2)
2445 } else {
2446 NotFound(w, r)
2447 }
2448 })
2449 }
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463 func Redirect(w ResponseWriter, r *Request, url string, code int) {
2464 if u, err := urlpkg.Parse(url); err == nil {
2465
2466
2467
2468
2469
2470 if u.Scheme == "" && u.Host == "" {
2471 oldpath := r.URL.EscapedPath()
2472 if oldpath == "" {
2473 oldpath = "/"
2474 }
2475
2476
2477 if url == "" || url[0] != '/' {
2478
2479 olddir, _ := path.Split(oldpath)
2480 url = olddir + url
2481 }
2482
2483 var query string
2484 if i := strings.Index(url, "?"); i != -1 {
2485 url, query = url[:i], url[i:]
2486 }
2487
2488
2489 trailing := strings.HasSuffix(url, "/")
2490 url = path.Clean(url)
2491 if trailing && !strings.HasSuffix(url, "/") {
2492 url += "/"
2493 }
2494 url += query
2495 }
2496 }
2497
2498 h := w.Header()
2499
2500
2501
2502
2503 _, hadCT := h["Content-Type"]
2504
2505 h.Set("Location", hexEscapeNonASCII(url))
2506 if !hadCT && (r.Method == "GET" || r.Method == "HEAD") {
2507 h.Set("Content-Type", "text/html; charset=utf-8")
2508 }
2509 w.WriteHeader(code)
2510
2511
2512 if !hadCT && r.Method == "GET" {
2513 body := "<a href=\"" + htmlEscape(url) + "\">" + StatusText(code) + "</a>.\n"
2514 fmt.Fprintln(w, body)
2515 }
2516 }
2517
2518 var htmlReplacer = strings.NewReplacer(
2519 "&", "&",
2520 "<", "<",
2521 ">", ">",
2522
2523 `"`, """,
2524
2525 "'", "'",
2526 )
2527
2528 func htmlEscape(s string) string {
2529 return htmlReplacer.Replace(s)
2530 }
2531
2532
2533 type redirectHandler struct {
2534 url string
2535 code int
2536 }
2537
2538 func (rh *redirectHandler) ServeHTTP(w ResponseWriter, r *Request) {
2539 Redirect(w, r, rh.url, rh.code)
2540 }
2541
2542
2543
2544
2545
2546
2547
2548 func RedirectHandler(url string, code int) Handler {
2549 return &redirectHandler{url, code}
2550 }
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671 type ServeMux struct {
2672 mu sync.RWMutex
2673 tree routingNode
2674 index routingIndex
2675 mux121 serveMux121
2676 }
2677
2678
2679 func NewServeMux() *ServeMux {
2680 return &ServeMux{}
2681 }
2682
2683
2684 var DefaultServeMux = &defaultServeMux
2685
2686 var defaultServeMux ServeMux
2687
2688
2689 func cleanPath(p string) string {
2690 if p == "" {
2691 return "/"
2692 }
2693 if p[0] != '/' {
2694 p = "/" + p
2695 }
2696 np := path.Clean(p)
2697
2698
2699 if p[len(p)-1] == '/' && np != "/" {
2700
2701 if len(p) == len(np)+1 && strings.HasPrefix(p, np) {
2702 np = p
2703 } else {
2704 np += "/"
2705 }
2706 }
2707 return np
2708 }
2709
2710
2711 func stripHostPort(h string) string {
2712
2713 if !strings.Contains(h, ":") {
2714 return h
2715 }
2716 host, _, err := net.SplitHostPort(h)
2717 if err != nil {
2718 return h
2719 }
2720 return host
2721 }
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743 func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string) {
2744 if use121 {
2745 return mux.mux121.findHandler(r)
2746 }
2747 h, p, _, _ := mux.findHandler(r)
2748 return h, p
2749 }
2750
2751
2752
2753
2754
2755 func (mux *ServeMux) findHandler(r *Request) (h Handler, patStr string, _ *pattern, matches []string) {
2756 var n *routingNode
2757 host := r.URL.Host
2758 escapedPath := r.URL.EscapedPath()
2759 path := escapedPath
2760
2761 if r.Method == "CONNECT" {
2762
2763
2764
2765 _, _, u := mux.matchOrRedirect(host, r.Method, path, r.URL)
2766 if u != nil {
2767 return RedirectHandler(u.String(), StatusTemporaryRedirect), u.Path, nil, nil
2768 }
2769
2770
2771 n, matches, _ = mux.matchOrRedirect(r.Host, r.Method, path, nil)
2772 } else {
2773
2774
2775 host = stripHostPort(r.Host)
2776 path = cleanPath(path)
2777
2778
2779
2780 var u *url.URL
2781 n, matches, u = mux.matchOrRedirect(host, r.Method, path, r.URL)
2782 if u != nil {
2783 return RedirectHandler(u.String(), StatusTemporaryRedirect), n.pattern.String(), nil, nil
2784 }
2785 if path != escapedPath {
2786
2787 patStr := ""
2788 if n != nil {
2789 patStr = n.pattern.String()
2790 }
2791 u := urlFromEscaped(path, r.URL.RawQuery)
2792 return RedirectHandler(u.String(), StatusTemporaryRedirect), patStr, nil, nil
2793 }
2794 }
2795 if n == nil {
2796
2797
2798
2799 allowedMethods := mux.matchingMethods(host, path)
2800 if len(allowedMethods) > 0 {
2801 return HandlerFunc(func(w ResponseWriter, r *Request) {
2802 w.Header().Set("Allow", strings.Join(allowedMethods, ", "))
2803 Error(w, StatusText(StatusMethodNotAllowed), StatusMethodNotAllowed)
2804 }), "", nil, nil
2805 }
2806 return NotFoundHandler(), "", nil, nil
2807 }
2808 return n.handler, n.pattern.String(), n.pattern, matches
2809 }
2810
2811
2812
2813
2814
2815
2816
2817 func (mux *ServeMux) matchOrRedirect(host, method, path string, u *url.URL) (_ *routingNode, matches []string, redirectTo *url.URL) {
2818 mux.mu.RLock()
2819 defer mux.mu.RUnlock()
2820
2821 n, matches := mux.tree.match(host, method, path)
2822
2823
2824
2825
2826
2827 if !exactMatch(n, path) && u != nil && !strings.HasSuffix(path, "/") && path != "" {
2828
2829 path += "/"
2830 n2, _ := mux.tree.match(host, method, path)
2831 if exactMatch(n2, path) {
2832
2833
2834
2835
2836 return n2, nil, urlFromEscaped(path, u.RawQuery)
2837 }
2838 }
2839 return n, matches, nil
2840 }
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851 func urlFromEscaped(escaped, rawQuery string) *url.URL {
2852 unescaped, err := url.PathUnescape(escaped)
2853
2854
2855 if err != nil {
2856 unescaped = escaped
2857 }
2858 return &url.URL{
2859 Path: unescaped,
2860 RawPath: escaped,
2861 RawQuery: rawQuery,
2862 }
2863 }
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891 func exactMatch(n *routingNode, path string) bool {
2892 if n == nil {
2893 return false
2894 }
2895
2896
2897
2898
2899 if !n.pattern.lastSegment().multi {
2900 return true
2901 }
2902
2903
2904
2905 if len(path) > 0 && path[len(path)-1] != '/' {
2906 return false
2907 }
2908
2909
2910
2911
2912
2913 return len(n.pattern.segments) == strings.Count(path, "/")
2914 }
2915
2916
2917 func (mux *ServeMux) matchingMethods(host, path string) []string {
2918
2919
2920 mux.mu.RLock()
2921 defer mux.mu.RUnlock()
2922 ms := map[string]bool{}
2923 mux.tree.matchingMethods(host, path, ms)
2924
2925 if !strings.HasSuffix(path, "/") {
2926 mux.tree.matchingMethods(host, path+"/", ms)
2927 }
2928 return slices.Sorted(maps.Keys(ms))
2929 }
2930
2931
2932
2933 func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
2934 if r.RequestURI == "*" {
2935 if r.ProtoAtLeast(1, 1) {
2936 w.Header().Set("Connection", "close")
2937 }
2938 w.WriteHeader(StatusBadRequest)
2939 return
2940 }
2941 var h Handler
2942 if use121 {
2943 h, _ = mux.mux121.findHandler(r)
2944 } else {
2945 h, r.Pattern, r.pat, r.matches = mux.findHandler(r)
2946 }
2947 h.ServeHTTP(w, r)
2948 }
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958 func (mux *ServeMux) Handle(pattern string, handler Handler) {
2959 if use121 {
2960 mux.mux121.handle(pattern, handler)
2961 } else {
2962 mux.register(pattern, handler)
2963 }
2964 }
2965
2966
2967
2968
2969
2970
2971 func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
2972 if use121 {
2973 mux.mux121.handleFunc(pattern, handler)
2974 } else {
2975 mux.register(pattern, HandlerFunc(handler))
2976 }
2977 }
2978
2979
2980
2981 func Handle(pattern string, handler Handler) {
2982 if use121 {
2983 DefaultServeMux.mux121.handle(pattern, handler)
2984 } else {
2985 DefaultServeMux.register(pattern, handler)
2986 }
2987 }
2988
2989
2990
2991 func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
2992 if use121 {
2993 DefaultServeMux.mux121.handleFunc(pattern, handler)
2994 } else {
2995 DefaultServeMux.register(pattern, HandlerFunc(handler))
2996 }
2997 }
2998
2999 func (mux *ServeMux) register(pattern string, handler Handler) {
3000 if err := mux.registerErr(pattern, handler); err != nil {
3001 panic(err)
3002 }
3003 }
3004
3005 func (mux *ServeMux) registerErr(patstr string, handler Handler) error {
3006 if patstr == "" {
3007 return errors.New("http: invalid pattern")
3008 }
3009 if handler == nil {
3010 return errors.New("http: nil handler")
3011 }
3012 if f, ok := handler.(HandlerFunc); ok && f == nil {
3013 return errors.New("http: nil handler")
3014 }
3015
3016 pat, err := parsePattern(patstr)
3017 if err != nil {
3018 return fmt.Errorf("parsing %q: %w", patstr, err)
3019 }
3020
3021
3022
3023 _, file, line, ok := runtime.Caller(3)
3024 if !ok {
3025 pat.loc = "unknown location"
3026 } else {
3027 pat.loc = fmt.Sprintf("%s:%d", file, line)
3028 }
3029
3030 mux.mu.Lock()
3031 defer mux.mu.Unlock()
3032
3033 if err := mux.index.possiblyConflictingPatterns(pat, func(pat2 *pattern) error {
3034 if pat.conflictsWith(pat2) {
3035 d := describeConflict(pat, pat2)
3036 return fmt.Errorf("pattern %q (registered at %s) conflicts with pattern %q (registered at %s):\n%s",
3037 pat, pat.loc, pat2, pat2.loc, d)
3038 }
3039 return nil
3040 }); err != nil {
3041 return err
3042 }
3043 mux.tree.addPattern(pat, handler)
3044 mux.index.addPattern(pat)
3045 return nil
3046 }
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060 func Serve(l net.Listener, handler Handler) error {
3061 srv := &Server{Handler: handler}
3062 return srv.Serve(l)
3063 }
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077 func ServeTLS(l net.Listener, handler Handler, certFile, keyFile string) error {
3078 srv := &Server{Handler: handler}
3079 return srv.ServeTLS(l, certFile, keyFile)
3080 }
3081
3082
3083
3084 type Server struct {
3085
3086
3087
3088
3089 Addr string
3090
3091 Handler Handler
3092
3093
3094
3095 DisableGeneralOptionsHandler bool
3096
3097
3098
3099
3100
3101
3102
3103
3104 TLSConfig *tls.Config
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114 ReadTimeout time.Duration
3115
3116
3117
3118
3119
3120
3121
3122 ReadHeaderTimeout time.Duration
3123
3124
3125
3126
3127
3128
3129 WriteTimeout time.Duration
3130
3131
3132
3133
3134
3135 IdleTimeout time.Duration
3136
3137
3138
3139
3140
3141
3142 MaxHeaderBytes int
3143
3144
3145
3146
3147
3148
3149
3150 MaxHeaderValueCount int
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164 TLSNextProto map[string]func(*Server, *tls.Conn, Handler)
3165
3166
3167
3168
3169 ConnState func(net.Conn, ConnState)
3170
3171
3172
3173
3174
3175 ErrorLog *log.Logger
3176
3177
3178
3179
3180
3181
3182
3183 BaseContext func(net.Listener) context.Context
3184
3185
3186
3187
3188
3189 ConnContext func(ctx context.Context, c net.Conn) context.Context
3190
3191
3192 HTTP2 *HTTP2Config
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203 Protocols *Protocols
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214 DisableClientPriority bool
3215
3216 inShutdown atomic.Bool
3217
3218 disableKeepAlives atomic.Bool
3219 nextProtoOnce sync.Once
3220 nextProtoErr error
3221
3222 mu sync.Mutex
3223 listeners map[*net.Listener]struct{}
3224 activeConn map[*conn]struct{}
3225 onShutdown []func()
3226 h2 *http2Server
3227 h2Config http2ExternalServerConfig
3228 h2IdleTimeout time.Duration
3229 h3 *http3ServerHandler
3230
3231 listenerGroup sync.WaitGroup
3232 }
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243 func (s *Server) Close() error {
3244 s.inShutdown.Store(true)
3245 s.mu.Lock()
3246 defer s.mu.Unlock()
3247 err := s.closeListenersLocked()
3248
3249
3250
3251
3252
3253 s.mu.Unlock()
3254 s.listenerGroup.Wait()
3255 s.mu.Lock()
3256
3257 for c := range s.activeConn {
3258 c.rwc.Close()
3259 delete(s.activeConn, c)
3260 }
3261 return err
3262 }
3263
3264
3265
3266
3267
3268
3269
3270
3271 const shutdownPollIntervalMax = 500 * time.Millisecond
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293 func (s *Server) Shutdown(ctx context.Context) error {
3294 s.inShutdown.Store(true)
3295
3296 s.mu.Lock()
3297 if s.h3 != nil {
3298 s.h3.shutdownCtx = ctx
3299 }
3300 lnerr := s.closeListenersLocked()
3301 for _, f := range s.onShutdown {
3302 go f()
3303 }
3304 s.mu.Unlock()
3305 s.listenerGroup.Wait()
3306
3307 pollIntervalBase := time.Millisecond
3308 nextPollInterval := func() time.Duration {
3309
3310 interval := pollIntervalBase + time.Duration(rand.IntN(int(pollIntervalBase/10)))
3311
3312 pollIntervalBase *= 2
3313 if pollIntervalBase > shutdownPollIntervalMax {
3314 pollIntervalBase = shutdownPollIntervalMax
3315 }
3316 return interval
3317 }
3318
3319 timer := time.NewTimer(nextPollInterval())
3320 defer timer.Stop()
3321 for {
3322 if s.closeIdleConns() {
3323 return lnerr
3324 }
3325 select {
3326 case <-ctx.Done():
3327 return ctx.Err()
3328 case <-timer.C:
3329 timer.Reset(nextPollInterval())
3330 }
3331 }
3332 }
3333
3334
3335
3336
3337
3338
3339 func (s *Server) RegisterOnShutdown(f func()) {
3340 s.mu.Lock()
3341 s.onShutdown = append(s.onShutdown, f)
3342 s.mu.Unlock()
3343 }
3344
3345
3346
3347 func (s *Server) closeIdleConns() bool {
3348 s.mu.Lock()
3349 defer s.mu.Unlock()
3350 quiescent := true
3351 for c := range s.activeConn {
3352 st, unixSec := c.getState()
3353
3354
3355
3356 if st == StateNew && unixSec < time.Now().Unix()-5 {
3357 st = StateIdle
3358 }
3359 if st != StateIdle || unixSec == 0 {
3360
3361
3362 quiescent = false
3363 continue
3364 }
3365 c.rwc.Close()
3366 delete(s.activeConn, c)
3367 }
3368 return quiescent
3369 }
3370
3371 func (s *Server) closeListenersLocked() error {
3372 var err error
3373 for ln := range s.listeners {
3374 if cerr := (*ln).Close(); cerr != nil && err == nil {
3375 err = cerr
3376 }
3377 }
3378 return err
3379 }
3380
3381
3382
3383 type ConnState int
3384
3385 const (
3386
3387
3388
3389
3390 StateNew ConnState = iota
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403 StateActive
3404
3405
3406
3407
3408
3409 StateIdle
3410
3411
3412
3413 StateHijacked
3414
3415
3416
3417
3418 StateClosed
3419 )
3420
3421 var stateName = map[ConnState]string{
3422 StateNew: "new",
3423 StateActive: "active",
3424 StateIdle: "idle",
3425 StateHijacked: "hijacked",
3426 StateClosed: "closed",
3427 }
3428
3429 func (c ConnState) String() string {
3430 return stateName[c]
3431 }
3432
3433
3434
3435 type serverHandler struct {
3436 srv *Server
3437 }
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448 func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
3449 handler := sh.srv.Handler
3450 if handler == nil {
3451 handler = DefaultServeMux
3452 }
3453 if !sh.srv.DisableGeneralOptionsHandler && req.RequestURI == "*" && req.Method == "OPTIONS" {
3454 handler = globalOptionsHandler{}
3455 }
3456
3457 handler.ServeHTTP(rw, req)
3458 }
3459
3460 func badServeHTTP(serverHandler, ResponseWriter, *Request)
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471 func AllowQuerySemicolons(h Handler) Handler {
3472 return HandlerFunc(func(w ResponseWriter, r *Request) {
3473 if strings.Contains(r.URL.RawQuery, ";") {
3474 r2 := new(Request)
3475 *r2 = *r
3476 r2.URL = new(url.URL)
3477 *r2.URL = *r.URL
3478 r2.URL.RawQuery = strings.ReplaceAll(r.URL.RawQuery, ";", "&")
3479 h.ServeHTTP(w, r2)
3480 } else {
3481 h.ServeHTTP(w, r)
3482 }
3483 })
3484 }
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494 func (s *Server) ListenAndServe() error {
3495 if s.shuttingDown() {
3496 return ErrServerClosed
3497 }
3498 addr := s.Addr
3499 if addr == "" {
3500 addr = ":http"
3501 }
3502 ln, err := net.Listen("tcp", addr)
3503 if err != nil {
3504 return err
3505 }
3506 return s.Serve(ln)
3507 }
3508
3509 var testHookServerServe func(*Server, net.Listener)
3510
3511
3512
3513 func (s *Server) shouldConfigureHTTP2ForServe() bool {
3514 if s.TLSConfig == nil {
3515
3516
3517
3518
3519
3520
3521 return true
3522 }
3523 if s.protocols().UnencryptedHTTP2() {
3524 return true
3525 }
3526
3527
3528
3529
3530
3531
3532
3533 return slices.Contains(s.TLSConfig.NextProtos, "h2")
3534 }
3535
3536
3537
3538 var ErrServerClosed = errors.New("http: Server closed")
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550 func (s *Server) Serve(l net.Listener) error {
3551 if conf, ok := l.(http2ExternalServerConfig); ok {
3552
3553
3554
3555
3556
3557
3558
3559 s.setHTTP2Config(conf)
3560
3561
3562
3563 return nil
3564 }
3565
3566 if fn := testHookServerServe; fn != nil {
3567 fn(s, l)
3568 }
3569
3570 origListener := l
3571 l = &onceCloseListener{Listener: l}
3572 defer l.Close()
3573
3574 if err := s.setupHTTP2_Serve(); err != nil {
3575 return err
3576 }
3577
3578 if !s.trackListener(&l, true) {
3579 return ErrServerClosed
3580 }
3581 defer s.trackListener(&l, false)
3582
3583 baseCtx := context.Background()
3584 if s.BaseContext != nil {
3585 baseCtx = s.BaseContext(origListener)
3586 if baseCtx == nil {
3587 panic("BaseContext returned a nil context")
3588 }
3589 }
3590
3591 var tempDelay time.Duration
3592
3593 ctx := context.WithValue(baseCtx, ServerContextKey, s)
3594 for {
3595 rw, err := l.Accept()
3596 if err != nil {
3597 if s.shuttingDown() {
3598 return ErrServerClosed
3599 }
3600 if ne, ok := err.(net.Error); ok && ne.Temporary() {
3601 if tempDelay == 0 {
3602 tempDelay = 5 * time.Millisecond
3603 } else {
3604 tempDelay *= 2
3605 }
3606 if max := 1 * time.Second; tempDelay > max {
3607 tempDelay = max
3608 }
3609 s.logf("http: Accept error: %v; retrying in %v", err, tempDelay)
3610 time.Sleep(tempDelay)
3611 continue
3612 }
3613 return err
3614 }
3615 connCtx := ctx
3616 if cc := s.ConnContext; cc != nil {
3617 connCtx = cc(connCtx, rw)
3618 if connCtx == nil {
3619 panic("ConnContext returned nil")
3620 }
3621 }
3622 tempDelay = 0
3623 c := s.newConn(rw)
3624 c.setState(c.rwc, StateNew, runHooks)
3625 go c.serve(connCtx)
3626 }
3627 }
3628
3629 func (s *Server) setupTLSConfig(certFile, keyFile string, nextProtos []string) (*tls.Config, error) {
3630 config := cloneTLSConfig(s.TLSConfig)
3631 config.NextProtos = nextProtos
3632
3633 configHasCert := len(config.Certificates) > 0 || config.GetCertificate != nil || config.GetConfigForClient != nil
3634 if !configHasCert || certFile != "" || keyFile != "" {
3635 var err error
3636 config.Certificates = make([]tls.Certificate, 1)
3637 config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
3638 if err != nil {
3639 return nil, err
3640 }
3641 }
3642 return config, nil
3643 }
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659 func (s *Server) ServeTLS(l net.Listener, certFile, keyFile string) error {
3660
3661
3662 if err := s.setupHTTP2_ServeTLS(); err != nil {
3663 return err
3664 }
3665
3666 var nextProtos []string
3667 if s.TLSConfig != nil {
3668 nextProtos = s.TLSConfig.NextProtos
3669 }
3670 config, err := s.setupTLSConfig(certFile, keyFile, adjustNextProtos(nextProtos, s.protocols()))
3671 if err != nil {
3672 return err
3673 }
3674
3675 tlsListener := tls.NewListener(l, config)
3676 return s.Serve(tlsListener)
3677 }
3678
3679 func (s *Server) protocols() Protocols {
3680 if s.Protocols != nil {
3681
3682
3683
3684
3685 if s.Protocols.empty() {
3686 var p Protocols
3687 p.SetHTTP1(true)
3688 return p
3689 }
3690 return *s.Protocols
3691 }
3692
3693
3694
3695 _, hasH2 := s.TLSNextProto["h2"]
3696 http2Disabled := s.TLSNextProto != nil && !hasH2
3697
3698
3699
3700
3701 if http2server.Value() == "0" && !hasH2 {
3702 http2Disabled = true
3703 }
3704
3705 var p Protocols
3706 p.SetHTTP1(true)
3707 if !http2Disabled {
3708 p.SetHTTP2(true)
3709 }
3710 return p
3711 }
3712
3713
3714
3715 func adjustNextProtos(nextProtos []string, protos Protocols) []string {
3716
3717
3718
3719
3720
3721 nextProtos = slices.Clone(nextProtos)
3722 var have Protocols
3723 nextProtos = slices.DeleteFunc(nextProtos, func(s string) bool {
3724 switch s {
3725 case "http/1.1":
3726 if !protos.HTTP1() {
3727 return true
3728 }
3729 have.SetHTTP1(true)
3730 case "h2":
3731 if !protos.HTTP2() {
3732 return true
3733 }
3734 have.SetHTTP2(true)
3735 }
3736 return false
3737 })
3738 if protos.HTTP2() && !have.HTTP2() {
3739 nextProtos = append(nextProtos, "h2")
3740 }
3741 if protos.HTTP1() && !have.HTTP1() {
3742 nextProtos = append(nextProtos, "http/1.1")
3743 }
3744 return nextProtos
3745 }
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757 func (s *Server) trackListener(ln *net.Listener, add bool) bool {
3758 s.mu.Lock()
3759 defer s.mu.Unlock()
3760 if s.listeners == nil {
3761 s.listeners = make(map[*net.Listener]struct{})
3762 }
3763 if add {
3764 if s.shuttingDown() {
3765 return false
3766 }
3767 s.listeners[ln] = struct{}{}
3768 s.listenerGroup.Add(1)
3769 } else {
3770 delete(s.listeners, ln)
3771 s.listenerGroup.Done()
3772 }
3773 return true
3774 }
3775
3776 func (s *Server) trackConn(c *conn, add bool) {
3777 s.mu.Lock()
3778 defer s.mu.Unlock()
3779 if s.activeConn == nil {
3780 s.activeConn = make(map[*conn]struct{})
3781 }
3782 if add {
3783 s.activeConn[c] = struct{}{}
3784 } else {
3785 delete(s.activeConn, c)
3786 }
3787 }
3788
3789 func (s *Server) idleTimeout() time.Duration {
3790 if s.IdleTimeout != 0 {
3791 return s.IdleTimeout
3792 }
3793 return s.ReadTimeout
3794 }
3795
3796 func (s *Server) readHeaderTimeout() time.Duration {
3797 if s.ReadHeaderTimeout != 0 {
3798 return s.ReadHeaderTimeout
3799 }
3800 return s.ReadTimeout
3801 }
3802
3803 func (s *Server) doKeepAlives() bool {
3804 return !s.disableKeepAlives.Load() && !s.shuttingDown()
3805 }
3806
3807 func (s *Server) shuttingDown() bool {
3808 return s.inShutdown.Load()
3809 }
3810
3811
3812
3813
3814
3815 func (s *Server) SetKeepAlivesEnabled(v bool) {
3816 if v {
3817 s.disableKeepAlives.Store(false)
3818 return
3819 }
3820 s.disableKeepAlives.Store(true)
3821
3822
3823 s.closeIdleConns()
3824
3825
3826 }
3827
3828 func (s *Server) logf(format string, args ...any) {
3829 if s.ErrorLog != nil {
3830 s.ErrorLog.Printf(format, args...)
3831 } else {
3832 log.Printf(format, args...)
3833 }
3834 }
3835
3836
3837
3838
3839 func logf(r *Request, format string, args ...any) {
3840 s, _ := r.Context().Value(ServerContextKey).(*Server)
3841 if s != nil && s.ErrorLog != nil {
3842 s.ErrorLog.Printf(format, args...)
3843 } else {
3844 log.Printf(format, args...)
3845 }
3846 }
3847
3848
3849
3850
3851
3852
3853
3854
3855 func ListenAndServe(addr string, handler Handler) error {
3856 server := &Server{Addr: addr, Handler: handler}
3857 return server.ListenAndServe()
3858 }
3859
3860
3861
3862
3863
3864
3865 func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error {
3866 server := &Server{Addr: addr, Handler: handler}
3867 return server.ListenAndServeTLS(certFile, keyFile)
3868 }
3869
3870
3871
3872
3873
3874
3875
3876
3877 type http3ServerHandler struct {
3878 handler serverHandler
3879 tlsConfig *tls.Config
3880 baseCtx context.Context
3881 errc chan error
3882 shutdownCtx context.Context
3883 }
3884
3885
3886
3887 func (h *http3ServerHandler) ServeHTTP(w ResponseWriter, r *Request) {
3888 h.handler.ServeHTTP(w, r)
3889 }
3890
3891
3892
3893 func (h *http3ServerHandler) Addr() string {
3894 return h.handler.srv.Addr
3895 }
3896
3897
3898
3899 func (h *http3ServerHandler) TLSConfig() *tls.Config {
3900 return h.tlsConfig
3901 }
3902
3903
3904
3905 func (h *http3ServerHandler) BaseContext() context.Context {
3906 return h.baseCtx
3907 }
3908
3909
3910
3911
3912 func (h *http3ServerHandler) ListenErrHook(err error) {
3913 h.errc <- err
3914 }
3915
3916
3917
3918
3919
3920
3921 func (h *http3ServerHandler) ShutdownContext() context.Context {
3922 return h.shutdownCtx
3923 }
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940 func (s *Server) ListenAndServeTLS(certFile, keyFile string) error {
3941 if s.shuttingDown() {
3942 return ErrServerClosed
3943 }
3944 addr := s.Addr
3945 if addr == "" {
3946 addr = ":https"
3947 }
3948
3949 p := s.protocols()
3950 if p.http3() {
3951 fn, ok := s.TLSNextProto["http/3"]
3952 if !ok {
3953 return errors.New("http: Server.Protocols contains HTTP3, but Server does not support HTTP/3")
3954 }
3955 config, err := s.setupTLSConfig(certFile, keyFile, []string{"h3"})
3956 if err != nil {
3957 return err
3958 }
3959 errc := make(chan error, 1)
3960 s.mu.Lock()
3961 s.h3 = &http3ServerHandler{
3962 handler: serverHandler{s},
3963 tlsConfig: config,
3964 baseCtx: context.WithValue(context.Background(), ServerContextKey, s),
3965 errc: errc,
3966 }
3967 s.mu.Unlock()
3968 go fn(s, nil, s.h3)
3969 if err := <-errc; err != nil {
3970 return err
3971 }
3972 }
3973
3974
3975 if !p.HTTP1() && !p.HTTP2() && !p.UnencryptedHTTP2() {
3976 return nil
3977 }
3978 ln, err := net.Listen("tcp", addr)
3979 if err != nil {
3980 return err
3981 }
3982 defer ln.Close()
3983 return s.ServeTLS(ln, certFile, keyFile)
3984 }
3985
3986
3987
3988
3989 func (s *Server) setupHTTP2_ServeTLS() error {
3990 s.nextProtoOnce.Do(s.onceSetNextProtoDefaults)
3991 return s.nextProtoErr
3992 }
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002 func (s *Server) setupHTTP2_Serve() error {
4003 s.nextProtoOnce.Do(s.onceSetNextProtoDefaults_Serve)
4004 return s.nextProtoErr
4005 }
4006
4007 func (s *Server) onceSetNextProtoDefaults_Serve() {
4008 if s.shouldConfigureHTTP2ForServe() {
4009 s.onceSetNextProtoDefaults()
4010 }
4011 }
4012
4013 var http2server = godebug.New("http2server")
4014
4015
4016
4017
4018 func (s *Server) onceSetNextProtoDefaults() {
4019 if omitBundledHTTP2 {
4020 return
4021 }
4022 p := s.protocols()
4023 if !p.HTTP2() && !p.UnencryptedHTTP2() {
4024 return
4025 }
4026 if http2server.Value() == "0" {
4027 http2server.IncNonDefault()
4028 return
4029 }
4030 if _, ok := s.TLSNextProto["h2"]; ok {
4031
4032
4033
4034 return
4035 }
4036 s.configureHTTP2()
4037 }
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050 func TimeoutHandler(h Handler, dt time.Duration, msg string) Handler {
4051 return &timeoutHandler{
4052 handler: h,
4053 body: msg,
4054 dt: dt,
4055 }
4056 }
4057
4058
4059
4060 var ErrHandlerTimeout = errors.New("http: Handler timeout")
4061
4062 type timeoutHandler struct {
4063 handler Handler
4064 body string
4065 dt time.Duration
4066
4067
4068
4069 testContext context.Context
4070 }
4071
4072 func (h *timeoutHandler) errorBody() string {
4073 if h.body != "" {
4074 return h.body
4075 }
4076 return "<html><head><title>Timeout</title></head><body><h1>Timeout</h1></body></html>"
4077 }
4078
4079 func (h *timeoutHandler) ServeHTTP(w ResponseWriter, r *Request) {
4080 ctx := h.testContext
4081 if ctx == nil {
4082 var cancelCtx context.CancelFunc
4083 ctx, cancelCtx = context.WithTimeout(r.Context(), h.dt)
4084 defer cancelCtx()
4085 }
4086 r = r.WithContext(ctx)
4087 done := make(chan struct{})
4088 tw := &timeoutWriter{
4089 w: w,
4090 h: make(Header),
4091 req: r,
4092 }
4093 panicChan := make(chan any, 1)
4094 go func() {
4095 defer func() {
4096 if p := recover(); p != nil {
4097 panicChan <- p
4098 }
4099 }()
4100 h.handler.ServeHTTP(tw, r)
4101 close(done)
4102 }()
4103 select {
4104 case p := <-panicChan:
4105 panic(p)
4106 case <-done:
4107 tw.mu.Lock()
4108 defer tw.mu.Unlock()
4109 dst := w.Header()
4110 maps.Copy(dst, tw.h)
4111 if !tw.wroteHeader {
4112 tw.code = StatusOK
4113 }
4114 w.WriteHeader(tw.code)
4115 w.Write(tw.wbuf.Bytes())
4116 case <-ctx.Done():
4117 tw.mu.Lock()
4118 defer tw.mu.Unlock()
4119 switch err := ctx.Err(); err {
4120 case context.DeadlineExceeded:
4121 w.WriteHeader(StatusServiceUnavailable)
4122 io.WriteString(w, h.errorBody())
4123 tw.err = ErrHandlerTimeout
4124 default:
4125 w.WriteHeader(StatusServiceUnavailable)
4126 tw.err = err
4127 }
4128 }
4129 }
4130
4131 type timeoutWriter struct {
4132 w ResponseWriter
4133 h Header
4134 wbuf bytes.Buffer
4135 req *Request
4136
4137 mu sync.Mutex
4138 err error
4139 wroteHeader bool
4140 code int
4141 }
4142
4143 var _ Pusher = (*timeoutWriter)(nil)
4144
4145
4146 func (tw *timeoutWriter) Push(target string, opts *PushOptions) error {
4147 if pusher, ok := tw.w.(Pusher); ok {
4148 return pusher.Push(target, opts)
4149 }
4150 return ErrNotSupported
4151 }
4152
4153 func (tw *timeoutWriter) Header() Header { return tw.h }
4154
4155 func (tw *timeoutWriter) Write(p []byte) (int, error) {
4156 tw.mu.Lock()
4157 defer tw.mu.Unlock()
4158 if tw.err != nil {
4159 return 0, tw.err
4160 }
4161 if !tw.wroteHeader {
4162 tw.writeHeaderLocked(StatusOK)
4163 }
4164 return tw.wbuf.Write(p)
4165 }
4166
4167 func (tw *timeoutWriter) writeHeaderLocked(code int) {
4168 checkWriteHeaderCode(code)
4169
4170 switch {
4171 case tw.err != nil:
4172 return
4173 case tw.wroteHeader:
4174 if tw.req != nil {
4175 caller := relevantCaller()
4176 logf(tw.req, "http: superfluous response.WriteHeader call from %s (%s:%d)", caller.Function, path.Base(caller.File), caller.Line)
4177 }
4178 default:
4179 tw.wroteHeader = true
4180 tw.code = code
4181 }
4182 }
4183
4184 func (tw *timeoutWriter) WriteHeader(code int) {
4185 tw.mu.Lock()
4186 defer tw.mu.Unlock()
4187 tw.writeHeaderLocked(code)
4188 }
4189
4190
4191
4192 type onceCloseListener struct {
4193 net.Listener
4194 once sync.Once
4195 closeErr error
4196 }
4197
4198 func (oc *onceCloseListener) Close() error {
4199 oc.once.Do(oc.close)
4200 return oc.closeErr
4201 }
4202
4203 func (oc *onceCloseListener) close() { oc.closeErr = oc.Listener.Close() }
4204
4205
4206 type globalOptionsHandler struct{}
4207
4208 func (globalOptionsHandler) ServeHTTP(w ResponseWriter, r *Request) {
4209 w.Header().Set("Content-Length", "0")
4210 if r.ContentLength != 0 {
4211
4212
4213
4214
4215
4216 mb := MaxBytesReader(w, r.Body, 4<<10)
4217 io.Copy(io.Discard, mb)
4218 }
4219 }
4220
4221
4222
4223
4224 type initALPNRequest struct {
4225 ctx context.Context
4226 c *tls.Conn
4227 h serverHandler
4228 }
4229
4230
4231
4232
4233
4234 func (h initALPNRequest) BaseContext() context.Context { return h.ctx }
4235
4236 func (h initALPNRequest) ServeHTTP(rw ResponseWriter, req *Request) {
4237 if req.TLS == nil {
4238 req.TLS = &tls.ConnectionState{}
4239 *req.TLS = h.c.ConnectionState()
4240 }
4241 if req.Body == nil {
4242 req.Body = NoBody
4243 }
4244 if req.RemoteAddr == "" {
4245 req.RemoteAddr = h.c.RemoteAddr().String()
4246 }
4247 h.h.ServeHTTP(rw, req)
4248 }
4249
4250
4251 type loggingConn struct {
4252 name string
4253 net.Conn
4254 }
4255
4256 var (
4257 uniqNameMu sync.Mutex
4258 uniqNameNext = make(map[string]int)
4259 )
4260
4261 func newLoggingConn(baseName string, c net.Conn) net.Conn {
4262 uniqNameMu.Lock()
4263 defer uniqNameMu.Unlock()
4264 uniqNameNext[baseName]++
4265 return &loggingConn{
4266 name: fmt.Sprintf("%s-%d", baseName, uniqNameNext[baseName]),
4267 Conn: c,
4268 }
4269 }
4270
4271 func (c *loggingConn) Write(p []byte) (n int, err error) {
4272 log.Printf("%s.Write(%d) = ....", c.name, len(p))
4273 n, err = c.Conn.Write(p)
4274 log.Printf("%s.Write(%d) = %d, %v", c.name, len(p), n, err)
4275 return
4276 }
4277
4278 func (c *loggingConn) Read(p []byte) (n int, err error) {
4279 log.Printf("%s.Read(%d) = ....", c.name, len(p))
4280 n, err = c.Conn.Read(p)
4281 log.Printf("%s.Read(%d) = %d, %v", c.name, len(p), n, err)
4282 return
4283 }
4284
4285 func (c *loggingConn) Close() (err error) {
4286 log.Printf("%s.Close() = ...", c.name)
4287 err = c.Conn.Close()
4288 log.Printf("%s.Close() = %v", c.name, err)
4289 return
4290 }
4291
4292
4293
4294
4295 type checkConnErrorWriter struct {
4296 c *conn
4297 }
4298
4299 func (w checkConnErrorWriter) Write(p []byte) (n int, err error) {
4300 n, err = w.c.rwc.Write(p)
4301 if err != nil && w.c.werr == nil {
4302 w.c.werr = err
4303 w.c.cancelCtx()
4304 }
4305 return
4306 }
4307
4308 func numLeadingCRorLF(v []byte) (n int) {
4309 for _, b := range v {
4310 if b == '\r' || b == '\n' {
4311 n++
4312 continue
4313 }
4314 break
4315 }
4316 return
4317 }
4318
4319
4320
4321 func tlsRecordHeaderLooksLikeHTTP(hdr [5]byte) bool {
4322 switch string(hdr[:]) {
4323 case "GET /", "HEAD ", "POST ", "PUT /", "OPTIO":
4324 return true
4325 }
4326 return false
4327 }
4328
4329
4330 func MaxBytesHandler(h Handler, n int64) Handler {
4331 return HandlerFunc(func(w ResponseWriter, r *Request) {
4332 r2 := *r
4333 r2.Body = MaxBytesReader(w, r.Body, n)
4334 h.ServeHTTP(w, &r2)
4335 })
4336 }
4337
View as plain text