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 var (
1043 wholeReqDeadline time.Time
1044 hdrDeadline time.Time
1045 )
1046 t0 := time.Now()
1047 if d := c.server.readHeaderTimeout(); d > 0 {
1048 hdrDeadline = t0.Add(d)
1049 }
1050 if d := c.server.ReadTimeout; d > 0 {
1051 wholeReqDeadline = t0.Add(d)
1052 }
1053 c.rwc.SetReadDeadline(hdrDeadline)
1054 if d := c.server.WriteTimeout; d > 0 {
1055 defer func() {
1056 c.rwc.SetWriteDeadline(time.Now().Add(d))
1057 }()
1058 }
1059
1060 c.r.setReadLimit(c.server.initialReadLimitSize())
1061 if c.lastMethod == "POST" {
1062
1063 peek, _ := c.bufr.Peek(4)
1064 c.bufr.Discard(numLeadingCRorLF(peek))
1065 }
1066 req, err := readRequestLimit(c.bufr, int64(c.server.maxHeaderValueCount()))
1067 if err != nil {
1068 if c.r.hitReadLimit() {
1069 return nil, errTooLarge
1070 }
1071 return nil, err
1072 }
1073
1074 if !http1ServerSupportsRequest(req) {
1075 return nil, statusError{StatusHTTPVersionNotSupported, "unsupported protocol version"}
1076 }
1077
1078 c.lastMethod = req.Method
1079 c.r.setInfiniteReadLimit()
1080
1081 hosts, haveHost := req.Header["Host"]
1082 isH2Upgrade := req.isH2Upgrade()
1083 if req.ProtoAtLeast(1, 1) && (!haveHost || len(hosts) == 0) && !isH2Upgrade && req.Method != "CONNECT" {
1084 return nil, badRequestError("missing required Host header")
1085 }
1086 if len(hosts) == 1 && !httpguts.ValidHostHeader(hosts[0]) {
1087 return nil, badRequestError("malformed Host header")
1088 }
1089 for k, vv := range req.Header {
1090 if !httpguts.ValidHeaderFieldName(k) {
1091 return nil, badRequestError("invalid header name")
1092 }
1093 for _, v := range vv {
1094 if !httpguts.ValidHeaderFieldValue(v) {
1095 return nil, badRequestError("invalid header value")
1096 }
1097 }
1098 }
1099 delete(req.Header, "Host")
1100
1101 ctx, cancelCtx := context.WithCancel(ctx)
1102 req.ctx = ctx
1103 req.RemoteAddr = c.remoteAddr
1104 req.TLS = c.tlsState
1105 if body, ok := req.Body.(*body); ok {
1106 body.doEarlyClose = true
1107 }
1108
1109
1110 if !hdrDeadline.Equal(wholeReqDeadline) {
1111 c.rwc.SetReadDeadline(wholeReqDeadline)
1112 }
1113
1114 w = &response{
1115 conn: c,
1116 cancelCtx: cancelCtx,
1117 req: req,
1118 reqBody: req.Body,
1119 handlerHeader: make(Header),
1120 contentLength: -1,
1121
1122
1123
1124
1125 wants10KeepAlive: req.wantsHttp10KeepAlive(),
1126 wantsClose: req.wantsClose(),
1127 }
1128 if isH2Upgrade {
1129 w.closeAfterReply = true
1130 }
1131 w.cw.res = w
1132 w.w = newBufioWriterSize(&w.cw, bufferBeforeChunkingSize)
1133 return w, nil
1134 }
1135
1136
1137
1138 func http1ServerSupportsRequest(req *Request) bool {
1139 if req.ProtoMajor == 1 {
1140 return true
1141 }
1142
1143
1144 if req.ProtoMajor == 2 && req.ProtoMinor == 0 &&
1145 req.Method == "PRI" && req.RequestURI == "*" {
1146 return true
1147 }
1148
1149
1150 return false
1151 }
1152
1153 func (w *response) Header() Header {
1154 if w.cw.header == nil && w.wroteHeader && !w.cw.wroteHeader {
1155
1156
1157
1158 w.cw.header = w.handlerHeader.Clone()
1159 }
1160 w.calledHeader = true
1161 return w.handlerHeader
1162 }
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173 const maxPostHandlerReadBytes = 256 << 10
1174
1175 func checkWriteHeaderCode(code int) {
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186 if code < 100 || code > 999 {
1187 panic(fmt.Sprintf("invalid WriteHeader code %v", code))
1188 }
1189 }
1190
1191
1192
1193 func relevantCaller() runtime.Frame {
1194 pc := make([]uintptr, 16)
1195 n := runtime.Callers(1, pc)
1196 frames := runtime.CallersFrames(pc[:n])
1197 var frame runtime.Frame
1198 for {
1199 var more bool
1200 frame, more = frames.Next()
1201 if !strings.HasPrefix(frame.Function, "net/http.") {
1202 return frame
1203 }
1204 if !more {
1205 break
1206 }
1207 }
1208 return frame
1209 }
1210
1211 func (w *response) WriteHeader(code int) {
1212 if w.conn.hijacked() {
1213 caller := relevantCaller()
1214 w.conn.server.logf("http: response.WriteHeader on hijacked connection from %s (%s:%d)", caller.Function, path.Base(caller.File), caller.Line)
1215 return
1216 }
1217 if w.wroteHeader {
1218 caller := relevantCaller()
1219 w.conn.server.logf("http: superfluous response.WriteHeader call from %s (%s:%d)", caller.Function, path.Base(caller.File), caller.Line)
1220 return
1221 }
1222 checkWriteHeaderCode(code)
1223
1224
1225
1226
1227
1228 if code == 100 || code >= 200 {
1229 w.disableWriteContinue(code >= 200)
1230 }
1231
1232
1233
1234
1235
1236 if code >= 100 && code <= 199 && code != StatusSwitchingProtocols {
1237 writeStatusLine(w.conn.bufw, w.req.ProtoAtLeast(1, 1), code, w.statusBuf[:])
1238
1239
1240 w.handlerHeader.WriteSubset(w.conn.bufw, excludedHeadersNoBody)
1241 w.conn.bufw.Write(crlf)
1242 w.conn.bufw.Flush()
1243
1244 return
1245 }
1246
1247 w.wroteHeader = true
1248 w.status = code
1249
1250 if w.calledHeader && w.cw.header == nil {
1251 w.cw.header = w.handlerHeader.Clone()
1252 }
1253
1254 if cl := w.handlerHeader.get("Content-Length"); cl != "" {
1255 v, err := strconv.ParseInt(cl, 10, 64)
1256 if err == nil && v >= 0 {
1257 w.contentLength = v
1258 } else {
1259 w.conn.server.logf("http: invalid Content-Length of %q", cl)
1260 w.handlerHeader.Del("Content-Length")
1261 }
1262 }
1263 }
1264
1265
1266
1267
1268 type extraHeader struct {
1269 contentType string
1270 connection string
1271 transferEncoding string
1272 date []byte
1273 contentLength []byte
1274 }
1275
1276
1277 var extraHeaderKeys = [][]byte{
1278 []byte("Content-Type"),
1279 []byte("Connection"),
1280 []byte("Transfer-Encoding"),
1281 }
1282
1283 var (
1284 headerContentLength = []byte("Content-Length: ")
1285 headerDate = []byte("Date: ")
1286 )
1287
1288
1289
1290
1291
1292
1293 func (h extraHeader) Write(w *bufio.Writer) {
1294 if h.date != nil {
1295 w.Write(headerDate)
1296 w.Write(h.date)
1297 w.Write(crlf)
1298 }
1299 if h.contentLength != nil {
1300 w.Write(headerContentLength)
1301 w.Write(h.contentLength)
1302 w.Write(crlf)
1303 }
1304 for i, v := range []string{h.contentType, h.connection, h.transferEncoding} {
1305 if v != "" {
1306 w.Write(extraHeaderKeys[i])
1307 w.Write(colonSpace)
1308 w.WriteString(v)
1309 w.Write(crlf)
1310 }
1311 }
1312 }
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322 func (cw *chunkWriter) writeHeader(p []byte) {
1323 if cw.wroteHeader {
1324 return
1325 }
1326 cw.wroteHeader = true
1327
1328 w := cw.res
1329 keepAlivesEnabled := w.conn.server.doKeepAlives()
1330 isHEAD := w.req.Method == "HEAD"
1331
1332
1333
1334
1335
1336
1337 header := cw.header
1338 owned := header != nil
1339 if !owned {
1340 header = w.handlerHeader
1341 }
1342 var excludeHeader map[string]bool
1343 delHeader := func(key string) {
1344 if owned {
1345 header.Del(key)
1346 return
1347 }
1348 if _, ok := header[key]; !ok {
1349 return
1350 }
1351 if excludeHeader == nil {
1352 excludeHeader = make(map[string]bool)
1353 }
1354 excludeHeader[key] = true
1355 }
1356 var setHeader extraHeader
1357
1358
1359 trailers := false
1360 for k := range cw.header {
1361 if strings.HasPrefix(k, TrailerPrefix) {
1362 if excludeHeader == nil {
1363 excludeHeader = make(map[string]bool)
1364 }
1365 excludeHeader[k] = true
1366 trailers = true
1367 }
1368 }
1369 for _, v := range cw.header["Trailer"] {
1370 trailers = true
1371 foreachHeaderElement(v, cw.res.declareTrailer)
1372 }
1373
1374 te := header.get("Transfer-Encoding")
1375 hasTE := te != ""
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391 if w.handlerDone.Load() && !trailers && !hasTE && bodyAllowedForStatus(w.status) && !header.has("Content-Length") && (!isHEAD || len(p) > 0) {
1392 w.contentLength = int64(len(p))
1393 setHeader.contentLength = strconv.AppendInt(cw.res.clenBuf[:0], int64(len(p)), 10)
1394 }
1395
1396
1397
1398 if w.wants10KeepAlive && keepAlivesEnabled {
1399 sentLength := header.get("Content-Length") != ""
1400 if sentLength && header.get("Connection") == "keep-alive" {
1401 w.closeAfterReply = false
1402 }
1403 }
1404
1405
1406 hasCL := w.contentLength != -1
1407
1408 if w.wants10KeepAlive && (isHEAD || hasCL || !bodyAllowedForStatus(w.status)) {
1409 _, connectionHeaderSet := header["Connection"]
1410 if !connectionHeaderSet {
1411 setHeader.connection = "keep-alive"
1412 }
1413 } else if !w.req.ProtoAtLeast(1, 1) || w.wantsClose {
1414 w.closeAfterReply = true
1415 }
1416
1417 if header.get("Connection") == "close" || !keepAlivesEnabled {
1418 w.closeAfterReply = true
1419 }
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438 if ecr, ok := w.req.Body.(*expectContinueReader); ok && !ecr.sawEOF.Load() {
1439 w.closeAfterReply = true
1440 }
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456 if w.req.ContentLength != 0 && !w.closeAfterReply && !w.fullDuplex {
1457 var discard, tooBig bool
1458
1459 switch bdy := w.req.Body.(type) {
1460 case *expectContinueReader:
1461
1462
1463 case *body:
1464 bdy.mu.Lock()
1465 switch {
1466 case bdy.closed:
1467 if !bdy.sawEOF {
1468
1469 w.closeAfterReply = true
1470 }
1471 case bdy.unreadDataSizeLocked() >= maxPostHandlerReadBytes:
1472 tooBig = true
1473 default:
1474 discard = true
1475 }
1476 bdy.mu.Unlock()
1477 default:
1478 discard = true
1479 }
1480
1481 if discard {
1482 _, err := io.CopyN(io.Discard, w.reqBody, maxPostHandlerReadBytes+1)
1483 switch err {
1484 case nil:
1485
1486 tooBig = true
1487 case ErrBodyReadAfterClose:
1488
1489 case io.EOF:
1490
1491 err = w.reqBody.Close()
1492 if err != nil {
1493 w.closeAfterReply = true
1494 }
1495 default:
1496
1497
1498
1499 w.closeAfterReply = true
1500 }
1501 }
1502
1503 if tooBig {
1504 w.requestTooLarge()
1505 delHeader("Connection")
1506 setHeader.connection = "close"
1507 }
1508 }
1509
1510 code := w.status
1511 if bodyAllowedForStatus(code) {
1512
1513 _, haveType := header["Content-Type"]
1514
1515
1516
1517 ce := header.Get("Content-Encoding")
1518 hasCE := len(ce) > 0
1519 if !hasCE && !haveType && !hasTE && len(p) > 0 {
1520 setHeader.contentType = DetectContentType(p)
1521 }
1522 } else {
1523 for _, k := range suppressedHeaders(code) {
1524 delHeader(k)
1525 }
1526 }
1527
1528 if !header.has("Date") {
1529 setHeader.date = time.Now().UTC().AppendFormat(cw.res.dateBuf[:0], TimeFormat)
1530 }
1531
1532 if hasCL && hasTE && te != "identity" {
1533
1534
1535 w.conn.server.logf("http: WriteHeader called with both Transfer-Encoding of %q and a Content-Length of %d",
1536 te, w.contentLength)
1537 delHeader("Content-Length")
1538 hasCL = false
1539 }
1540
1541 if w.req.Method == "HEAD" || !bodyAllowedForStatus(code) || code == StatusNoContent {
1542
1543 delHeader("Transfer-Encoding")
1544 } else if hasCL {
1545
1546 delHeader("Transfer-Encoding")
1547 } else if w.req.ProtoAtLeast(1, 1) {
1548
1549
1550
1551
1552
1553 if hasTE && te == "identity" {
1554 cw.chunking = false
1555 w.closeAfterReply = true
1556 delHeader("Transfer-Encoding")
1557 } else {
1558
1559
1560 cw.chunking = true
1561 setHeader.transferEncoding = "chunked"
1562 if hasTE && te == "chunked" {
1563
1564 delHeader("Transfer-Encoding")
1565 }
1566 }
1567 } else {
1568
1569
1570
1571 w.closeAfterReply = true
1572 delHeader("Transfer-Encoding")
1573 }
1574
1575
1576 if cw.chunking {
1577 delHeader("Content-Length")
1578 }
1579 if !w.req.ProtoAtLeast(1, 0) {
1580 return
1581 }
1582
1583
1584
1585
1586 delConnectionHeader := w.closeAfterReply &&
1587 (!keepAlivesEnabled || !hasToken(cw.header.get("Connection"), "close")) &&
1588 !isProtocolSwitchResponse(w.status, header)
1589 if delConnectionHeader {
1590 delHeader("Connection")
1591 if w.req.ProtoAtLeast(1, 1) {
1592 setHeader.connection = "close"
1593 }
1594 }
1595
1596 writeStatusLine(w.conn.bufw, w.req.ProtoAtLeast(1, 1), code, w.statusBuf[:])
1597 cw.header.WriteSubset(w.conn.bufw, excludeHeader)
1598 setHeader.Write(w.conn.bufw)
1599 w.conn.bufw.Write(crlf)
1600 }
1601
1602
1603
1604 func foreachHeaderElement(v string, fn func(string)) {
1605 v = textproto.TrimString(v)
1606 if v == "" {
1607 return
1608 }
1609 if !strings.Contains(v, ",") {
1610 fn(v)
1611 return
1612 }
1613 for f := range strings.SplitSeq(v, ",") {
1614 if f = textproto.TrimString(f); f != "" {
1615 fn(f)
1616 }
1617 }
1618 }
1619
1620
1621
1622
1623
1624 func writeStatusLine(bw *bufio.Writer, is11 bool, code int, scratch []byte) {
1625 if is11 {
1626 bw.WriteString("HTTP/1.1 ")
1627 } else {
1628 bw.WriteString("HTTP/1.0 ")
1629 }
1630 if text := StatusText(code); text != "" {
1631 bw.Write(strconv.AppendInt(scratch[:0], int64(code), 10))
1632 bw.WriteByte(' ')
1633 bw.WriteString(text)
1634 bw.WriteString("\r\n")
1635 } else {
1636
1637 fmt.Fprintf(bw, "%03d status code %d\r\n", code, code)
1638 }
1639 }
1640
1641
1642
1643 func (w *response) bodyAllowed() bool {
1644 if !w.wroteHeader {
1645 panic("net/http: bodyAllowed called before the header was written")
1646 }
1647 return bodyAllowedForStatus(w.status)
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
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684 func (w *response) Write(data []byte) (n int, err error) {
1685 return w.write(len(data), data, "")
1686 }
1687
1688 func (w *response) WriteString(data string) (n int, err error) {
1689 return w.write(len(data), nil, data)
1690 }
1691
1692
1693 func (w *response) write(lenData int, dataB []byte, dataS string) (n int, err error) {
1694 if w.conn.hijacked() {
1695 if lenData > 0 {
1696 caller := relevantCaller()
1697 w.conn.server.logf("http: response.Write on hijacked connection from %s (%s:%d)", caller.Function, path.Base(caller.File), caller.Line)
1698 }
1699 return 0, ErrHijacked
1700 }
1701
1702 if w.canWriteContinue.Load() {
1703
1704 w.disableWriteContinue(true)
1705 }
1706
1707 if !w.wroteHeader {
1708 w.WriteHeader(StatusOK)
1709 }
1710 if lenData == 0 {
1711 return 0, nil
1712 }
1713 if !w.bodyAllowed() {
1714 return 0, ErrBodyNotAllowed
1715 }
1716
1717 w.written += int64(lenData)
1718 if w.contentLength != -1 && w.written > w.contentLength {
1719 return 0, ErrContentLength
1720 }
1721 if dataB != nil {
1722 return w.w.Write(dataB)
1723 } else {
1724 return w.w.WriteString(dataS)
1725 }
1726 }
1727
1728 func (w *response) finishRequest() {
1729 w.handlerDone.Store(true)
1730
1731 if !w.wroteHeader {
1732 w.WriteHeader(StatusOK)
1733 }
1734
1735 w.w.Flush()
1736 putBufioWriter(w.w)
1737 w.cw.close()
1738 w.conn.bufw.Flush()
1739
1740 w.conn.r.abortPendingRead()
1741
1742 if w.canWriteContinue.Load() {
1743 w.disableWriteContinue(true)
1744 }
1745
1746
1747
1748 w.reqBody.Close()
1749
1750 if w.req.MultipartForm != nil {
1751 w.req.MultipartForm.RemoveAll()
1752 }
1753 }
1754
1755
1756
1757 func (w *response) shouldReuseConnection() bool {
1758 if w.closeAfterReply {
1759
1760
1761
1762 return false
1763 }
1764
1765 if w.req.Method != "HEAD" && w.contentLength != -1 && w.bodyAllowed() && w.contentLength != w.written {
1766
1767 return false
1768 }
1769
1770
1771
1772 if w.conn.werr != nil {
1773 return false
1774 }
1775
1776 if w.closedRequestBodyEarly() {
1777 return false
1778 }
1779
1780 return true
1781 }
1782
1783 func (w *response) closedRequestBodyEarly() bool {
1784 body, ok := w.req.Body.(*body)
1785 return ok && body.didEarlyClose()
1786 }
1787
1788 func (w *response) Flush() {
1789 w.FlushError()
1790 }
1791
1792 func (w *response) FlushError() error {
1793 if !w.wroteHeader {
1794 w.WriteHeader(StatusOK)
1795 }
1796 err := w.w.Flush()
1797 e2 := w.cw.flush()
1798 if err == nil {
1799 err = e2
1800 }
1801 return err
1802 }
1803
1804 func (c *conn) finalFlush() {
1805 if c.bufr != nil {
1806
1807
1808 putBufioReader(c.bufr)
1809 c.bufr = nil
1810 }
1811
1812 if c.bufw != nil {
1813 c.bufw.Flush()
1814
1815
1816 putBufioWriter(c.bufw)
1817 c.bufw = nil
1818 }
1819 }
1820
1821
1822 func (c *conn) close() {
1823 c.finalFlush()
1824 c.rwc.Close()
1825 }
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838 var rstAvoidanceDelay = 500 * time.Millisecond
1839
1840 type closeWriter interface {
1841 CloseWrite() error
1842 }
1843
1844 var _ closeWriter = (*net.TCPConn)(nil)
1845
1846
1847
1848
1849
1850
1851
1852 func (c *conn) closeWriteAndWait() {
1853 c.finalFlush()
1854 if tcp, ok := c.rwc.(closeWriter); ok {
1855 tcp.CloseWrite()
1856 }
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878 time.Sleep(rstAvoidanceDelay)
1879 }
1880
1881
1882
1883
1884 func validNextProto(proto string) bool {
1885 switch proto {
1886 case "", "http/1.1", "http/1.0":
1887 return false
1888 }
1889 return true
1890 }
1891
1892 const (
1893 runHooks = true
1894 skipHooks = false
1895 )
1896
1897 func (c *conn) setState(nc net.Conn, state ConnState, runHook bool) {
1898 srv := c.server
1899 switch state {
1900 case StateNew:
1901 srv.trackConn(c, true)
1902 case StateHijacked, StateClosed:
1903 srv.trackConn(c, false)
1904 }
1905 if state > 0xff || state < 0 {
1906 panic("internal error")
1907 }
1908 packedState := uint64(time.Now().Unix()<<8) | uint64(state)
1909 c.curState.Store(packedState)
1910 if !runHook {
1911 return
1912 }
1913 if hook := srv.ConnState; hook != nil {
1914 hook(nc, state)
1915 }
1916 }
1917
1918 func (c *conn) getState() (state ConnState, unixSec int64) {
1919 packedState := c.curState.Load()
1920 return ConnState(packedState & 0xff), int64(packedState >> 8)
1921 }
1922
1923
1924
1925
1926 func badRequestError(e string) error { return statusError{StatusBadRequest, e} }
1927
1928
1929
1930 type statusError struct {
1931 code int
1932 text string
1933 }
1934
1935 func (e statusError) Error() string { return StatusText(e.code) + ": " + e.text }
1936
1937
1938
1939
1940
1941 var ErrAbortHandler = internal.ErrAbortHandler
1942
1943
1944
1945
1946
1947 func isCommonNetReadError(err error) bool {
1948 if err == io.EOF {
1949 return true
1950 }
1951 if neterr, ok := err.(net.Error); ok && neterr.Timeout() {
1952 return true
1953 }
1954 if oe, ok := err.(*net.OpError); ok && oe.Op == "read" {
1955 return true
1956 }
1957 return false
1958 }
1959
1960
1961 func (c *conn) serve(ctx context.Context) {
1962 if ra := c.rwc.RemoteAddr(); ra != nil {
1963 c.remoteAddr = ra.String()
1964 }
1965 ctx = context.WithValue(ctx, LocalAddrContextKey, c.rwc.LocalAddr())
1966 var inFlightResponse *response
1967 defer func() {
1968 if err := recover(); err != nil && err != ErrAbortHandler {
1969 const size = 64 << 10
1970 buf := make([]byte, size)
1971 buf = buf[:runtime.Stack(buf, false)]
1972 c.server.logf("http: panic serving %v: %v\n%s", c.remoteAddr, err, buf)
1973 }
1974 if inFlightResponse != nil {
1975 inFlightResponse.cancelCtx()
1976 inFlightResponse.disableWriteContinue(true)
1977 }
1978 if !c.hijacked() {
1979 if inFlightResponse != nil {
1980 inFlightResponse.conn.r.abortPendingRead()
1981 inFlightResponse.reqBody.Close()
1982 }
1983 c.close()
1984 c.setState(c.rwc, StateClosed, runHooks)
1985 }
1986 }()
1987
1988 type connectionStater interface {
1989 ConnectionState() tls.ConnectionState
1990 }
1991 type handshakeContexter interface {
1992 HandshakeContext(ctx context.Context) error
1993 }
1994 if connStater, ok := c.rwc.(connectionStater); ok {
1995 tlsTO := c.server.tlsHandshakeTimeout()
1996 if tlsTO > 0 {
1997 dl := time.Now().Add(tlsTO)
1998 c.rwc.SetReadDeadline(dl)
1999 c.rwc.SetWriteDeadline(dl)
2000 }
2001 var err error
2002 if handshaker, ok := c.rwc.(handshakeContexter); ok {
2003 err = handshaker.HandshakeContext(ctx)
2004 }
2005 if err != nil {
2006
2007
2008
2009 var reason string
2010 if re, ok := err.(tls.RecordHeaderError); ok && re.Conn != nil && tlsRecordHeaderLooksLikeHTTP(re.RecordHeader) {
2011 io.WriteString(re.Conn, "HTTP/1.0 400 Bad Request\r\n\r\nClient sent an HTTP request to an HTTPS server.\n")
2012 re.Conn.Close()
2013 reason = "client sent an HTTP request to an HTTPS server"
2014 } else {
2015 reason = err.Error()
2016 }
2017 c.server.logf("http: TLS handshake error from %s: %v", c.rwc.RemoteAddr(), reason)
2018 return
2019 }
2020
2021 if tlsTO > 0 {
2022 c.rwc.SetReadDeadline(time.Time{})
2023 c.rwc.SetWriteDeadline(time.Time{})
2024 }
2025 c.tlsState = new(tls.ConnectionState)
2026 *c.tlsState = connStater.ConnectionState()
2027 proto := c.tlsState.NegotiatedProtocol
2028 if proto == "h2" && c.server.h2 != nil {
2029
2030
2031
2032
2033
2034 c.setState(c.rwc, StateActive, skipHooks)
2035 const sawClientPreface = false
2036 c.server.serveHTTP2Conn(ctx, c.rwc, serverHandler{c.server}, sawClientPreface, nil, nil)
2037 return
2038 }
2039 tlsConn, tlsConnOK := c.rwc.(*tls.Conn)
2040 if validNextProto(proto) && tlsConnOK {
2041
2042 if fn := c.server.TLSNextProto[proto]; fn != nil {
2043 h := initALPNRequest{ctx, tlsConn, serverHandler{c.server}}
2044
2045 c.setState(c.rwc, StateActive, skipHooks)
2046 fn(c.server, tlsConn, h)
2047 }
2048 return
2049 }
2050 }
2051
2052
2053
2054
2055 if c.tlsState == nil {
2056 if tc, ok := c.rwc.(connectionStater); ok {
2057 c.tlsState = new(tls.ConnectionState)
2058 *c.tlsState = tc.ConnectionState()
2059 }
2060 }
2061
2062 ctx, cancelCtx := context.WithCancel(ctx)
2063 c.cancelCtx = cancelCtx
2064 defer cancelCtx()
2065
2066 c.r = &connReader{conn: c, rwc: c.rwc}
2067 c.bufr = newBufioReader(c.r)
2068 c.bufw = newBufioWriterSize(checkConnErrorWriter{c}, 4<<10)
2069
2070 protos := c.server.protocols()
2071 if c.tlsState == nil && protos.UnencryptedHTTP2() {
2072 if c.maybeServeUnencryptedHTTP2(ctx) {
2073 return
2074 }
2075 }
2076 if !protos.HTTP1() {
2077 return
2078 }
2079
2080
2081
2082 for {
2083 w, err := c.readRequest(ctx)
2084 if c.r.remain != c.server.initialReadLimitSize() {
2085
2086 c.setState(c.rwc, StateActive, runHooks)
2087 }
2088 if c.server.shuttingDown() {
2089 return
2090 }
2091 if err != nil {
2092 const errorHeaders = "\r\nContent-Type: text/plain; charset=utf-8\r\nConnection: close\r\n\r\n"
2093
2094 switch {
2095 case err == errTooLarge:
2096
2097
2098
2099
2100
2101 const publicErr = "431 Request Header Fields Too Large"
2102 fmt.Fprintf(c.rwc, "HTTP/1.1 "+publicErr+errorHeaders+publicErr)
2103 c.closeWriteAndWait()
2104 return
2105
2106 case isUnsupportedTEError(err):
2107
2108
2109
2110
2111 code := StatusNotImplemented
2112
2113
2114
2115 fmt.Fprintf(c.rwc, "HTTP/1.1 %d %s%sUnsupported transfer encoding", code, StatusText(code), errorHeaders)
2116 return
2117
2118 case isCommonNetReadError(err):
2119 return
2120
2121 default:
2122 if v, ok := err.(statusError); ok {
2123 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)
2124 return
2125 }
2126 const publicErr = "400 Bad Request"
2127 fmt.Fprintf(c.rwc, "HTTP/1.1 "+publicErr+errorHeaders+publicErr)
2128 return
2129 }
2130 }
2131
2132
2133 req := w.req
2134 if req.expectsContinue() {
2135 if req.ProtoAtLeast(1, 1) && req.ContentLength != 0 {
2136
2137 req.Body = &expectContinueReader{readCloser: req.Body, resp: w}
2138 w.canWriteContinue.Store(true)
2139 w.reqBody = req.Body
2140 }
2141 } else if req.Header.get("Expect") != "" {
2142 w.sendExpectationFailed()
2143 return
2144 }
2145
2146 c.curReq.Store(w)
2147
2148 if requestBodyRemains(req.Body) {
2149 registerOnHitEOF(req.Body, w.conn.r.startBackgroundRead)
2150 } else {
2151 w.conn.r.startBackgroundRead()
2152 }
2153
2154
2155
2156
2157
2158
2159
2160
2161 inFlightResponse = w
2162 serverHandler{c.server}.ServeHTTP(w, w.req)
2163 inFlightResponse = nil
2164 w.cancelCtx()
2165 if c.hijacked() {
2166 c.r.releaseConn()
2167 return
2168 }
2169 w.finishRequest()
2170 c.rwc.SetWriteDeadline(time.Time{})
2171 if !w.shouldReuseConnection() {
2172 if w.requestBodyLimitHit || w.closedRequestBodyEarly() {
2173 c.closeWriteAndWait()
2174 }
2175 return
2176 }
2177 c.setState(c.rwc, StateIdle, runHooks)
2178 c.curReq.Store(nil)
2179
2180 if !w.conn.server.doKeepAlives() {
2181
2182
2183
2184
2185 return
2186 }
2187
2188 if d := c.server.idleTimeout(); d > 0 {
2189 c.rwc.SetReadDeadline(time.Now().Add(d))
2190 } else {
2191 c.rwc.SetReadDeadline(time.Time{})
2192 }
2193
2194
2195
2196
2197
2198 if _, err := c.bufr.Peek(4); err != nil {
2199 return
2200 }
2201
2202 c.rwc.SetReadDeadline(time.Time{})
2203 }
2204 }
2205
2206
2207
2208
2209
2210 type unencryptedHTTP2Request struct {
2211 ctx context.Context
2212 c net.Conn
2213 h serverHandler
2214 }
2215
2216 func (h unencryptedHTTP2Request) BaseContext() context.Context { return h.ctx }
2217
2218 func (h unencryptedHTTP2Request) ServeHTTP(rw ResponseWriter, req *Request) {
2219 if req.Body == nil {
2220 req.Body = NoBody
2221 }
2222 if req.RemoteAddr == "" {
2223 req.RemoteAddr = h.c.RemoteAddr().String()
2224 }
2225 h.h.ServeHTTP(rw, req)
2226 }
2227
2228
2229
2230 type unencryptedNetConnInTLSConn struct {
2231 net.Conn
2232 conn net.Conn
2233 }
2234
2235 func (c unencryptedNetConnInTLSConn) UnencryptedNetConn() net.Conn {
2236 return c.conn
2237 }
2238
2239 func unencryptedTLSConn(c net.Conn) *tls.Conn {
2240 return tls.Client(unencryptedNetConnInTLSConn{conn: c}, nil)
2241 }
2242
2243
2244
2245 const nextProtoUnencryptedHTTP2 = "unencrypted_http2"
2246
2247 func (c *conn) maybeServeUnencryptedHTTP2(ctx context.Context) bool {
2248 var nextFunc func(*Server, *tls.Conn, Handler)
2249 if c.server.h2 == nil {
2250 var ok bool
2251 nextFunc, ok = c.server.TLSNextProto[nextProtoUnencryptedHTTP2]
2252 if !ok {
2253 return false
2254 }
2255 }
2256 hasPreface := func(c *conn, preface []byte) bool {
2257 c.r.setReadLimit(int64(len(preface)) - int64(c.bufr.Buffered()))
2258 got, err := c.bufr.Peek(len(preface))
2259 c.r.setInfiniteReadLimit()
2260 return err == nil && bytes.Equal(got, preface)
2261 }
2262 if !hasPreface(c, []byte("PRI * HTTP/2.0")) {
2263 return false
2264 }
2265 if !hasPreface(c, []byte("PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n")) {
2266 return false
2267 }
2268 c.setState(c.rwc, StateActive, skipHooks)
2269 if c.server.h2 != nil {
2270 const sawClientPreface = true
2271 c.server.serveHTTP2Conn(ctx, c.rwc, serverHandler{c.server}, sawClientPreface, nil, nil)
2272 } else {
2273 h := unencryptedHTTP2Request{ctx, c.rwc, serverHandler{c.server}}
2274 nextFunc(c.server, unencryptedTLSConn(c.rwc), h)
2275 }
2276 return true
2277 }
2278
2279 func (w *response) sendExpectationFailed() {
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292 w.Header().Set("Connection", "close")
2293 w.WriteHeader(StatusExpectationFailed)
2294 w.finishRequest()
2295 }
2296
2297
2298
2299 func (w *response) Hijack() (rwc net.Conn, buf *bufio.ReadWriter, err error) {
2300 if w.handlerDone.Load() {
2301 panic("net/http: Hijack called after ServeHTTP finished")
2302 }
2303 w.disableWriteContinue(false)
2304 if w.wroteHeader {
2305 w.cw.flush()
2306 }
2307
2308 c := w.conn
2309 c.mu.Lock()
2310 defer c.mu.Unlock()
2311
2312
2313
2314 rwc, buf, err = c.hijackLocked()
2315 if err == nil {
2316 putBufioWriter(w.w)
2317 w.w = nil
2318 }
2319 return rwc, buf, err
2320 }
2321
2322 func (w *response) CloseNotify() <-chan bool {
2323 w.lazyCloseNotifyMu.Lock()
2324 defer w.lazyCloseNotifyMu.Unlock()
2325 if w.handlerDone.Load() {
2326 panic("net/http: CloseNotify called after ServeHTTP finished")
2327 }
2328 if w.closeNotifyCh == nil {
2329 w.closeNotifyCh = make(chan bool, 1)
2330 if w.closeNotifyTriggered {
2331 w.closeNotifyCh <- true
2332 }
2333 }
2334 return w.closeNotifyCh
2335 }
2336
2337 func (w *response) closeNotify() {
2338 w.lazyCloseNotifyMu.Lock()
2339 defer w.lazyCloseNotifyMu.Unlock()
2340 if w.closeNotifyTriggered {
2341 return
2342 }
2343 w.closeNotifyTriggered = true
2344 if w.closeNotifyCh != nil {
2345 w.closeNotifyCh <- true
2346 }
2347 }
2348
2349 func registerOnHitEOF(rc io.ReadCloser, fn func()) {
2350 switch v := rc.(type) {
2351 case *expectContinueReader:
2352 registerOnHitEOF(v.readCloser, fn)
2353 case *body:
2354 v.registerOnHitEOF(fn)
2355 default:
2356 panic("unexpected type " + fmt.Sprintf("%T", rc))
2357 }
2358 }
2359
2360
2361
2362 func requestBodyRemains(rc io.ReadCloser) bool {
2363 if rc == NoBody {
2364 return false
2365 }
2366 switch v := rc.(type) {
2367 case *expectContinueReader:
2368 return requestBodyRemains(v.readCloser)
2369 case *body:
2370 return v.bodyRemains()
2371 default:
2372 panic("unexpected type " + fmt.Sprintf("%T", rc))
2373 }
2374 }
2375
2376
2377
2378
2379
2380 type HandlerFunc func(ResponseWriter, *Request)
2381
2382
2383 func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
2384 f(w, r)
2385 }
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399 func Error(w ResponseWriter, error string, code int) {
2400 h := w.Header()
2401
2402
2403
2404
2405
2406
2407
2408
2409 h.Del("Content-Length")
2410
2411
2412
2413 h.Set("Content-Type", "text/plain; charset=utf-8")
2414 h.Set("X-Content-Type-Options", "nosniff")
2415 w.WriteHeader(code)
2416 fmt.Fprintln(w, error)
2417 }
2418
2419
2420 func NotFound(w ResponseWriter, r *Request) { Error(w, "404 page not found", StatusNotFound) }
2421
2422
2423
2424 func NotFoundHandler() Handler { return HandlerFunc(NotFound) }
2425
2426
2427
2428
2429
2430
2431
2432 func StripPrefix(prefix string, h Handler) Handler {
2433 if prefix == "" {
2434 return h
2435 }
2436 return HandlerFunc(func(w ResponseWriter, r *Request) {
2437 p := strings.TrimPrefix(r.URL.Path, prefix)
2438 rp := strings.TrimPrefix(r.URL.RawPath, prefix)
2439 if len(p) < len(r.URL.Path) && (r.URL.RawPath == "" || len(rp) < len(r.URL.RawPath)) {
2440 r2 := new(Request)
2441 *r2 = *r
2442 r2.URL = new(url.URL)
2443 *r2.URL = *r.URL
2444 r2.URL.Path = p
2445 r2.URL.RawPath = rp
2446 h.ServeHTTP(w, r2)
2447 } else {
2448 NotFound(w, r)
2449 }
2450 })
2451 }
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465 func Redirect(w ResponseWriter, r *Request, url string, code int) {
2466 if u, err := urlpkg.Parse(url); err == nil {
2467
2468
2469
2470
2471
2472 if u.Scheme == "" && u.Host == "" {
2473 oldpath := r.URL.EscapedPath()
2474 if oldpath == "" {
2475 oldpath = "/"
2476 }
2477
2478
2479 if url == "" || url[0] != '/' {
2480
2481 olddir, _ := path.Split(oldpath)
2482 url = olddir + url
2483 }
2484
2485 var query string
2486 if i := strings.Index(url, "?"); i != -1 {
2487 url, query = url[:i], url[i:]
2488 }
2489
2490
2491 trailing := strings.HasSuffix(url, "/")
2492 url = path.Clean(url)
2493 if trailing && !strings.HasSuffix(url, "/") {
2494 url += "/"
2495 }
2496 url += query
2497 }
2498 }
2499
2500 h := w.Header()
2501
2502
2503
2504
2505 _, hadCT := h["Content-Type"]
2506
2507 h.Set("Location", hexEscapeNonASCII(url))
2508 if !hadCT && (r.Method == "GET" || r.Method == "HEAD") {
2509 h.Set("Content-Type", "text/html; charset=utf-8")
2510 }
2511 w.WriteHeader(code)
2512
2513
2514 if !hadCT && r.Method == "GET" {
2515 body := "<a href=\"" + htmlEscape(url) + "\">" + StatusText(code) + "</a>.\n"
2516 fmt.Fprintln(w, body)
2517 }
2518 }
2519
2520 var htmlReplacer = strings.NewReplacer(
2521 "&", "&",
2522 "<", "<",
2523 ">", ">",
2524
2525 `"`, """,
2526
2527 "'", "'",
2528 )
2529
2530 func htmlEscape(s string) string {
2531 return htmlReplacer.Replace(s)
2532 }
2533
2534
2535 type redirectHandler struct {
2536 url string
2537 code int
2538 }
2539
2540 func (rh *redirectHandler) ServeHTTP(w ResponseWriter, r *Request) {
2541 Redirect(w, r, rh.url, rh.code)
2542 }
2543
2544
2545
2546
2547
2548
2549
2550 func RedirectHandler(url string, code int) Handler {
2551 return &redirectHandler{url, code}
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
2672
2673 type ServeMux struct {
2674 mu sync.RWMutex
2675 tree routingNode
2676 index routingIndex
2677 mux121 serveMux121
2678 }
2679
2680
2681 func NewServeMux() *ServeMux {
2682 return &ServeMux{}
2683 }
2684
2685
2686 var DefaultServeMux = &defaultServeMux
2687
2688 var defaultServeMux ServeMux
2689
2690
2691 func cleanPath(p string) string {
2692 if p == "" {
2693 return "/"
2694 }
2695 if p[0] != '/' {
2696 p = "/" + p
2697 }
2698 np := path.Clean(p)
2699
2700
2701 if p[len(p)-1] == '/' && np != "/" {
2702
2703 if len(p) == len(np)+1 && strings.HasPrefix(p, np) {
2704 np = p
2705 } else {
2706 np += "/"
2707 }
2708 }
2709 return np
2710 }
2711
2712
2713 func stripHostPort(h string) string {
2714
2715 if !strings.Contains(h, ":") {
2716 return h
2717 }
2718 host, _, err := net.SplitHostPort(h)
2719 if err != nil {
2720 return h
2721 }
2722 return host
2723 }
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745 func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string) {
2746 if use121 {
2747 return mux.mux121.findHandler(r)
2748 }
2749 h, p, _, _ := mux.findHandler(r)
2750 return h, p
2751 }
2752
2753
2754
2755
2756
2757 func (mux *ServeMux) findHandler(r *Request) (h Handler, patStr string, _ *pattern, matches []string) {
2758 var n *routingNode
2759 host := r.URL.Host
2760 escapedPath := r.URL.EscapedPath()
2761 path := escapedPath
2762
2763 if r.Method == "CONNECT" {
2764
2765
2766
2767 _, _, u := mux.matchOrRedirect(host, r.Method, path, r.URL)
2768 if u != nil {
2769 return RedirectHandler(u.String(), StatusTemporaryRedirect), u.Path, nil, nil
2770 }
2771
2772
2773 n, matches, _ = mux.matchOrRedirect(r.Host, r.Method, path, nil)
2774 } else {
2775
2776
2777 host = stripHostPort(r.Host)
2778 path = cleanPath(path)
2779
2780
2781
2782 var u *url.URL
2783 n, matches, u = mux.matchOrRedirect(host, r.Method, path, r.URL)
2784 if u != nil {
2785 return RedirectHandler(u.String(), StatusTemporaryRedirect), n.pattern.String(), nil, nil
2786 }
2787 if path != escapedPath {
2788
2789 patStr := ""
2790 if n != nil {
2791 patStr = n.pattern.String()
2792 }
2793 u := urlFromEscaped(path, r.URL.RawQuery)
2794 return RedirectHandler(u.String(), StatusTemporaryRedirect), patStr, nil, nil
2795 }
2796 }
2797 if n == nil {
2798
2799
2800
2801 allowedMethods := mux.matchingMethods(host, path)
2802 if len(allowedMethods) > 0 {
2803 return HandlerFunc(func(w ResponseWriter, r *Request) {
2804 w.Header().Set("Allow", strings.Join(allowedMethods, ", "))
2805 Error(w, StatusText(StatusMethodNotAllowed), StatusMethodNotAllowed)
2806 }), "", nil, nil
2807 }
2808 return NotFoundHandler(), "", nil, nil
2809 }
2810 return n.handler, n.pattern.String(), n.pattern, matches
2811 }
2812
2813
2814
2815
2816
2817
2818
2819 func (mux *ServeMux) matchOrRedirect(host, method, path string, u *url.URL) (_ *routingNode, matches []string, redirectTo *url.URL) {
2820 mux.mu.RLock()
2821 defer mux.mu.RUnlock()
2822
2823 n, matches := mux.tree.match(host, method, path)
2824
2825
2826
2827
2828
2829 if !exactMatch(n, path) && u != nil && !strings.HasSuffix(path, "/") && path != "" {
2830
2831 path += "/"
2832 n2, _ := mux.tree.match(host, method, path)
2833 if exactMatch(n2, path) {
2834
2835
2836
2837
2838 return n2, nil, urlFromEscaped(path, u.RawQuery)
2839 }
2840 }
2841 return n, matches, nil
2842 }
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853 func urlFromEscaped(escaped, rawQuery string) *url.URL {
2854 unescaped, err := url.PathUnescape(escaped)
2855
2856
2857 if err != nil {
2858 unescaped = escaped
2859 }
2860 return &url.URL{
2861 Path: unescaped,
2862 RawPath: escaped,
2863 RawQuery: rawQuery,
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
2892
2893 func exactMatch(n *routingNode, path string) bool {
2894 if n == nil {
2895 return false
2896 }
2897
2898
2899
2900
2901 if !n.pattern.lastSegment().multi {
2902 return true
2903 }
2904
2905
2906
2907 if len(path) > 0 && path[len(path)-1] != '/' {
2908 return false
2909 }
2910
2911
2912
2913
2914
2915 return len(n.pattern.segments) == strings.Count(path, "/")
2916 }
2917
2918
2919 func (mux *ServeMux) matchingMethods(host, path string) []string {
2920
2921
2922 mux.mu.RLock()
2923 defer mux.mu.RUnlock()
2924 ms := map[string]bool{}
2925 mux.tree.matchingMethods(host, path, ms)
2926
2927 if !strings.HasSuffix(path, "/") {
2928 mux.tree.matchingMethods(host, path+"/", ms)
2929 }
2930 return slices.Sorted(maps.Keys(ms))
2931 }
2932
2933
2934
2935 func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
2936 if r.RequestURI == "*" {
2937 if r.ProtoAtLeast(1, 1) {
2938 w.Header().Set("Connection", "close")
2939 }
2940 w.WriteHeader(StatusBadRequest)
2941 return
2942 }
2943 var h Handler
2944 if use121 {
2945 h, _ = mux.mux121.findHandler(r)
2946 } else {
2947 h, r.Pattern, r.pat, r.matches = mux.findHandler(r)
2948 }
2949 h.ServeHTTP(w, r)
2950 }
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960 func (mux *ServeMux) Handle(pattern string, handler Handler) {
2961 if use121 {
2962 mux.mux121.handle(pattern, handler)
2963 } else {
2964 mux.register(pattern, handler)
2965 }
2966 }
2967
2968
2969
2970
2971
2972
2973 func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
2974 if use121 {
2975 mux.mux121.handleFunc(pattern, handler)
2976 } else {
2977 mux.register(pattern, HandlerFunc(handler))
2978 }
2979 }
2980
2981
2982
2983 func Handle(pattern string, handler Handler) {
2984 if use121 {
2985 DefaultServeMux.mux121.handle(pattern, handler)
2986 } else {
2987 DefaultServeMux.register(pattern, handler)
2988 }
2989 }
2990
2991
2992
2993 func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
2994 if use121 {
2995 DefaultServeMux.mux121.handleFunc(pattern, handler)
2996 } else {
2997 DefaultServeMux.register(pattern, HandlerFunc(handler))
2998 }
2999 }
3000
3001 func (mux *ServeMux) register(pattern string, handler Handler) {
3002 if err := mux.registerErr(pattern, handler); err != nil {
3003 panic(err)
3004 }
3005 }
3006
3007 func (mux *ServeMux) registerErr(patstr string, handler Handler) error {
3008 if patstr == "" {
3009 return errors.New("http: invalid pattern")
3010 }
3011 if handler == nil {
3012 return errors.New("http: nil handler")
3013 }
3014 if f, ok := handler.(HandlerFunc); ok && f == nil {
3015 return errors.New("http: nil handler")
3016 }
3017
3018 pat, err := parsePattern(patstr)
3019 if err != nil {
3020 return fmt.Errorf("parsing %q: %w", patstr, err)
3021 }
3022
3023
3024
3025 _, file, line, ok := runtime.Caller(3)
3026 if !ok {
3027 pat.loc = "unknown location"
3028 } else {
3029 pat.loc = fmt.Sprintf("%s:%d", file, line)
3030 }
3031
3032 mux.mu.Lock()
3033 defer mux.mu.Unlock()
3034
3035 if err := mux.index.possiblyConflictingPatterns(pat, func(pat2 *pattern) error {
3036 if pat.conflictsWith(pat2) {
3037 d := describeConflict(pat, pat2)
3038 return fmt.Errorf("pattern %q (registered at %s) conflicts with pattern %q (registered at %s):\n%s",
3039 pat, pat.loc, pat2, pat2.loc, d)
3040 }
3041 return nil
3042 }); err != nil {
3043 return err
3044 }
3045 mux.tree.addPattern(pat, handler)
3046 mux.index.addPattern(pat)
3047 return nil
3048 }
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062 func Serve(l net.Listener, handler Handler) error {
3063 srv := &Server{Handler: handler}
3064 return srv.Serve(l)
3065 }
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079 func ServeTLS(l net.Listener, handler Handler, certFile, keyFile string) error {
3080 srv := &Server{Handler: handler}
3081 return srv.ServeTLS(l, certFile, keyFile)
3082 }
3083
3084
3085
3086 type Server struct {
3087
3088
3089
3090
3091 Addr string
3092
3093 Handler Handler
3094
3095
3096
3097 DisableGeneralOptionsHandler bool
3098
3099
3100
3101
3102
3103
3104
3105
3106 TLSConfig *tls.Config
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116 ReadTimeout time.Duration
3117
3118
3119
3120
3121
3122
3123
3124 ReadHeaderTimeout time.Duration
3125
3126
3127
3128
3129
3130
3131 WriteTimeout time.Duration
3132
3133
3134
3135
3136
3137 IdleTimeout time.Duration
3138
3139
3140
3141
3142
3143
3144 MaxHeaderBytes int
3145
3146
3147
3148
3149
3150
3151
3152 MaxHeaderValueCount int
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166 TLSNextProto map[string]func(*Server, *tls.Conn, Handler)
3167
3168
3169
3170
3171 ConnState func(net.Conn, ConnState)
3172
3173
3174
3175
3176
3177 ErrorLog *log.Logger
3178
3179
3180
3181
3182
3183
3184
3185 BaseContext func(net.Listener) context.Context
3186
3187
3188
3189
3190
3191 ConnContext func(ctx context.Context, c net.Conn) context.Context
3192
3193
3194 HTTP2 *HTTP2Config
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205 Protocols *Protocols
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216 DisableClientPriority bool
3217
3218 inShutdown atomic.Bool
3219
3220 disableKeepAlives atomic.Bool
3221 nextProtoOnce sync.Once
3222 nextProtoErr error
3223
3224 mu sync.Mutex
3225 listeners map[*net.Listener]struct{}
3226 activeConn map[*conn]struct{}
3227 onShutdown []func()
3228 h2 *http2Server
3229 h2Config http2ExternalServerConfig
3230 h2IdleTimeout time.Duration
3231 h3 *http3ServerHandler
3232
3233 listenerGroup sync.WaitGroup
3234 }
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245 func (s *Server) Close() error {
3246 s.inShutdown.Store(true)
3247 s.mu.Lock()
3248 defer s.mu.Unlock()
3249 err := s.closeListenersLocked()
3250
3251
3252
3253
3254
3255 s.mu.Unlock()
3256 s.listenerGroup.Wait()
3257 s.mu.Lock()
3258
3259 for c := range s.activeConn {
3260 c.rwc.Close()
3261 delete(s.activeConn, c)
3262 }
3263 return err
3264 }
3265
3266
3267
3268
3269
3270
3271
3272
3273 const shutdownPollIntervalMax = 500 * time.Millisecond
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295 func (s *Server) Shutdown(ctx context.Context) error {
3296 s.inShutdown.Store(true)
3297
3298 s.mu.Lock()
3299 if s.h3 != nil {
3300 s.h3.shutdownCtx = ctx
3301 }
3302 lnerr := s.closeListenersLocked()
3303 for _, f := range s.onShutdown {
3304 go f()
3305 }
3306 s.mu.Unlock()
3307 s.listenerGroup.Wait()
3308
3309 pollIntervalBase := time.Millisecond
3310 nextPollInterval := func() time.Duration {
3311
3312 interval := pollIntervalBase + time.Duration(rand.IntN(int(pollIntervalBase/10)))
3313
3314 pollIntervalBase *= 2
3315 if pollIntervalBase > shutdownPollIntervalMax {
3316 pollIntervalBase = shutdownPollIntervalMax
3317 }
3318 return interval
3319 }
3320
3321 timer := time.NewTimer(nextPollInterval())
3322 defer timer.Stop()
3323 for {
3324 if s.closeIdleConns() {
3325 return lnerr
3326 }
3327 select {
3328 case <-ctx.Done():
3329 return ctx.Err()
3330 case <-timer.C:
3331 timer.Reset(nextPollInterval())
3332 }
3333 }
3334 }
3335
3336
3337
3338
3339
3340
3341 func (s *Server) RegisterOnShutdown(f func()) {
3342 s.mu.Lock()
3343 s.onShutdown = append(s.onShutdown, f)
3344 s.mu.Unlock()
3345 }
3346
3347
3348
3349 func (s *Server) closeIdleConns() bool {
3350 s.mu.Lock()
3351 defer s.mu.Unlock()
3352 quiescent := true
3353 for c := range s.activeConn {
3354 st, unixSec := c.getState()
3355
3356
3357
3358 if st == StateNew && unixSec < time.Now().Unix()-5 {
3359 st = StateIdle
3360 }
3361 if st != StateIdle || unixSec == 0 {
3362
3363
3364 quiescent = false
3365 continue
3366 }
3367 c.rwc.Close()
3368 delete(s.activeConn, c)
3369 }
3370 return quiescent
3371 }
3372
3373 func (s *Server) closeListenersLocked() error {
3374 var err error
3375 for ln := range s.listeners {
3376 if cerr := (*ln).Close(); cerr != nil && err == nil {
3377 err = cerr
3378 }
3379 }
3380 return err
3381 }
3382
3383
3384
3385 type ConnState int
3386
3387 const (
3388
3389
3390
3391
3392 StateNew ConnState = iota
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405 StateActive
3406
3407
3408
3409
3410
3411 StateIdle
3412
3413
3414
3415 StateHijacked
3416
3417
3418
3419
3420 StateClosed
3421 )
3422
3423 var stateName = map[ConnState]string{
3424 StateNew: "new",
3425 StateActive: "active",
3426 StateIdle: "idle",
3427 StateHijacked: "hijacked",
3428 StateClosed: "closed",
3429 }
3430
3431 func (c ConnState) String() string {
3432 return stateName[c]
3433 }
3434
3435
3436
3437 type serverHandler struct {
3438 srv *Server
3439 }
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450 func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
3451 handler := sh.srv.Handler
3452 if handler == nil {
3453 handler = DefaultServeMux
3454 }
3455 if !sh.srv.DisableGeneralOptionsHandler && req.RequestURI == "*" && req.Method == "OPTIONS" {
3456 handler = globalOptionsHandler{}
3457 }
3458
3459 handler.ServeHTTP(rw, req)
3460 }
3461
3462 func badServeHTTP(serverHandler, ResponseWriter, *Request)
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473 func AllowQuerySemicolons(h Handler) Handler {
3474 return HandlerFunc(func(w ResponseWriter, r *Request) {
3475 if strings.Contains(r.URL.RawQuery, ";") {
3476 r2 := new(Request)
3477 *r2 = *r
3478 r2.URL = new(url.URL)
3479 *r2.URL = *r.URL
3480 r2.URL.RawQuery = strings.ReplaceAll(r.URL.RawQuery, ";", "&")
3481 h.ServeHTTP(w, r2)
3482 } else {
3483 h.ServeHTTP(w, r)
3484 }
3485 })
3486 }
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496 func (s *Server) ListenAndServe() error {
3497 if s.shuttingDown() {
3498 return ErrServerClosed
3499 }
3500 addr := s.Addr
3501 if addr == "" {
3502 addr = ":http"
3503 }
3504 ln, err := net.Listen("tcp", addr)
3505 if err != nil {
3506 return err
3507 }
3508 return s.Serve(ln)
3509 }
3510
3511 var testHookServerServe func(*Server, net.Listener)
3512
3513
3514
3515 func (s *Server) shouldConfigureHTTP2ForServe() bool {
3516 if s.TLSConfig == nil {
3517
3518
3519
3520
3521
3522
3523 return true
3524 }
3525 if s.protocols().UnencryptedHTTP2() {
3526 return true
3527 }
3528
3529
3530
3531
3532
3533
3534
3535 return slices.Contains(s.TLSConfig.NextProtos, "h2")
3536 }
3537
3538
3539
3540 var ErrServerClosed = errors.New("http: Server closed")
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552 func (s *Server) Serve(l net.Listener) error {
3553 if conf, ok := l.(http2ExternalServerConfig); ok {
3554
3555
3556
3557
3558
3559
3560
3561 s.setHTTP2Config(conf)
3562
3563
3564
3565 return nil
3566 }
3567
3568 if fn := testHookServerServe; fn != nil {
3569 fn(s, l)
3570 }
3571
3572 origListener := l
3573 l = &onceCloseListener{Listener: l}
3574 defer l.Close()
3575
3576 if err := s.setupHTTP2_Serve(); err != nil {
3577 return err
3578 }
3579
3580 if !s.trackListener(&l, true) {
3581 return ErrServerClosed
3582 }
3583 defer s.trackListener(&l, false)
3584
3585 baseCtx := context.Background()
3586 if s.BaseContext != nil {
3587 baseCtx = s.BaseContext(origListener)
3588 if baseCtx == nil {
3589 panic("BaseContext returned a nil context")
3590 }
3591 }
3592
3593 var tempDelay time.Duration
3594
3595 ctx := context.WithValue(baseCtx, ServerContextKey, s)
3596 for {
3597 rw, err := l.Accept()
3598 if err != nil {
3599 if s.shuttingDown() {
3600 return ErrServerClosed
3601 }
3602 if ne, ok := err.(net.Error); ok && ne.Temporary() {
3603 if tempDelay == 0 {
3604 tempDelay = 5 * time.Millisecond
3605 } else {
3606 tempDelay *= 2
3607 }
3608 if max := 1 * time.Second; tempDelay > max {
3609 tempDelay = max
3610 }
3611 s.logf("http: Accept error: %v; retrying in %v", err, tempDelay)
3612 time.Sleep(tempDelay)
3613 continue
3614 }
3615 return err
3616 }
3617 connCtx := ctx
3618 if cc := s.ConnContext; cc != nil {
3619 connCtx = cc(connCtx, rw)
3620 if connCtx == nil {
3621 panic("ConnContext returned nil")
3622 }
3623 }
3624 tempDelay = 0
3625 c := s.newConn(rw)
3626 c.setState(c.rwc, StateNew, runHooks)
3627 go c.serve(connCtx)
3628 }
3629 }
3630
3631 func (s *Server) setupTLSConfig(certFile, keyFile string, nextProtos []string) (*tls.Config, error) {
3632 config := cloneTLSConfig(s.TLSConfig)
3633 config.NextProtos = nextProtos
3634
3635 configHasCert := len(config.Certificates) > 0 || config.GetCertificate != nil || config.GetConfigForClient != nil
3636 if !configHasCert || certFile != "" || keyFile != "" {
3637 var err error
3638 config.Certificates = make([]tls.Certificate, 1)
3639 config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
3640 if err != nil {
3641 return nil, err
3642 }
3643 }
3644 return config, nil
3645 }
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661 func (s *Server) ServeTLS(l net.Listener, certFile, keyFile string) error {
3662
3663
3664 if err := s.setupHTTP2_ServeTLS(); err != nil {
3665 return err
3666 }
3667
3668 var nextProtos []string
3669 if s.TLSConfig != nil {
3670 nextProtos = s.TLSConfig.NextProtos
3671 }
3672 config, err := s.setupTLSConfig(certFile, keyFile, adjustNextProtos(nextProtos, s.protocols()))
3673 if err != nil {
3674 return err
3675 }
3676
3677 tlsListener := tls.NewListener(l, config)
3678 return s.Serve(tlsListener)
3679 }
3680
3681 func (s *Server) protocols() Protocols {
3682 if s.Protocols != nil {
3683
3684
3685
3686
3687 if s.Protocols.empty() {
3688 var p Protocols
3689 p.SetHTTP1(true)
3690 return p
3691 }
3692 return *s.Protocols
3693 }
3694
3695
3696
3697 _, hasH2 := s.TLSNextProto["h2"]
3698 http2Disabled := s.TLSNextProto != nil && !hasH2
3699
3700
3701
3702
3703 if http2server.Value() == "0" && !hasH2 {
3704 http2Disabled = true
3705 }
3706
3707 var p Protocols
3708 p.SetHTTP1(true)
3709 if !http2Disabled {
3710 p.SetHTTP2(true)
3711 }
3712 return p
3713 }
3714
3715
3716
3717 func adjustNextProtos(nextProtos []string, protos Protocols) []string {
3718
3719
3720
3721
3722
3723 nextProtos = slices.Clone(nextProtos)
3724 var have Protocols
3725 nextProtos = slices.DeleteFunc(nextProtos, func(s string) bool {
3726 switch s {
3727 case "http/1.1":
3728 if !protos.HTTP1() {
3729 return true
3730 }
3731 have.SetHTTP1(true)
3732 case "h2":
3733 if !protos.HTTP2() {
3734 return true
3735 }
3736 have.SetHTTP2(true)
3737 }
3738 return false
3739 })
3740 if protos.HTTP2() && !have.HTTP2() {
3741 nextProtos = append(nextProtos, "h2")
3742 }
3743 if protos.HTTP1() && !have.HTTP1() {
3744 nextProtos = append(nextProtos, "http/1.1")
3745 }
3746 return nextProtos
3747 }
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759 func (s *Server) trackListener(ln *net.Listener, add bool) bool {
3760 s.mu.Lock()
3761 defer s.mu.Unlock()
3762 if s.listeners == nil {
3763 s.listeners = make(map[*net.Listener]struct{})
3764 }
3765 if add {
3766 if s.shuttingDown() {
3767 return false
3768 }
3769 s.listeners[ln] = struct{}{}
3770 s.listenerGroup.Add(1)
3771 } else {
3772 delete(s.listeners, ln)
3773 s.listenerGroup.Done()
3774 }
3775 return true
3776 }
3777
3778 func (s *Server) trackConn(c *conn, add bool) {
3779 s.mu.Lock()
3780 defer s.mu.Unlock()
3781 if s.activeConn == nil {
3782 s.activeConn = make(map[*conn]struct{})
3783 }
3784 if add {
3785 s.activeConn[c] = struct{}{}
3786 } else {
3787 delete(s.activeConn, c)
3788 }
3789 }
3790
3791 func (s *Server) idleTimeout() time.Duration {
3792 if s.IdleTimeout != 0 {
3793 return s.IdleTimeout
3794 }
3795 return s.ReadTimeout
3796 }
3797
3798 func (s *Server) readHeaderTimeout() time.Duration {
3799 if s.ReadHeaderTimeout != 0 {
3800 return s.ReadHeaderTimeout
3801 }
3802 return s.ReadTimeout
3803 }
3804
3805 func (s *Server) doKeepAlives() bool {
3806 return !s.disableKeepAlives.Load() && !s.shuttingDown()
3807 }
3808
3809 func (s *Server) shuttingDown() bool {
3810 return s.inShutdown.Load()
3811 }
3812
3813
3814
3815
3816
3817 func (s *Server) SetKeepAlivesEnabled(v bool) {
3818 if v {
3819 s.disableKeepAlives.Store(false)
3820 return
3821 }
3822 s.disableKeepAlives.Store(true)
3823
3824
3825 s.closeIdleConns()
3826
3827
3828 }
3829
3830 func (s *Server) logf(format string, args ...any) {
3831 if s.ErrorLog != nil {
3832 s.ErrorLog.Printf(format, args...)
3833 } else {
3834 log.Printf(format, args...)
3835 }
3836 }
3837
3838
3839
3840
3841 func logf(r *Request, format string, args ...any) {
3842 s, _ := r.Context().Value(ServerContextKey).(*Server)
3843 if s != nil && s.ErrorLog != nil {
3844 s.ErrorLog.Printf(format, args...)
3845 } else {
3846 log.Printf(format, args...)
3847 }
3848 }
3849
3850
3851
3852
3853
3854
3855
3856
3857 func ListenAndServe(addr string, handler Handler) error {
3858 server := &Server{Addr: addr, Handler: handler}
3859 return server.ListenAndServe()
3860 }
3861
3862
3863
3864
3865
3866
3867 func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error {
3868 server := &Server{Addr: addr, Handler: handler}
3869 return server.ListenAndServeTLS(certFile, keyFile)
3870 }
3871
3872
3873
3874
3875
3876
3877
3878
3879 type http3ServerHandler struct {
3880 handler serverHandler
3881 tlsConfig *tls.Config
3882 baseCtx context.Context
3883 errc chan error
3884 shutdownCtx context.Context
3885 }
3886
3887
3888
3889 func (h *http3ServerHandler) ServeHTTP(w ResponseWriter, r *Request) {
3890 h.handler.ServeHTTP(w, r)
3891 }
3892
3893
3894
3895 func (h *http3ServerHandler) Addr() string {
3896 return h.handler.srv.Addr
3897 }
3898
3899
3900
3901 func (h *http3ServerHandler) TLSConfig() *tls.Config {
3902 return h.tlsConfig
3903 }
3904
3905
3906
3907 func (h *http3ServerHandler) BaseContext() context.Context {
3908 return h.baseCtx
3909 }
3910
3911
3912
3913
3914 func (h *http3ServerHandler) ListenErrHook(err error) {
3915 h.errc <- err
3916 }
3917
3918
3919
3920
3921
3922
3923 func (h *http3ServerHandler) ShutdownContext() context.Context {
3924 return h.shutdownCtx
3925 }
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942 func (s *Server) ListenAndServeTLS(certFile, keyFile string) error {
3943 if s.shuttingDown() {
3944 return ErrServerClosed
3945 }
3946 addr := s.Addr
3947 if addr == "" {
3948 addr = ":https"
3949 }
3950
3951 p := s.protocols()
3952 if p.http3() {
3953 fn, ok := s.TLSNextProto["http/3"]
3954 if !ok {
3955 return errors.New("http: Server.Protocols contains HTTP3, but Server does not support HTTP/3")
3956 }
3957 config, err := s.setupTLSConfig(certFile, keyFile, []string{"h3"})
3958 if err != nil {
3959 return err
3960 }
3961 errc := make(chan error, 1)
3962 s.mu.Lock()
3963 s.h3 = &http3ServerHandler{
3964 handler: serverHandler{s},
3965 tlsConfig: config,
3966 baseCtx: context.WithValue(context.Background(), ServerContextKey, s),
3967 errc: errc,
3968 }
3969 s.mu.Unlock()
3970 go fn(s, nil, s.h3)
3971 if err := <-errc; err != nil {
3972 return err
3973 }
3974 }
3975
3976
3977 if !p.HTTP1() && !p.HTTP2() && !p.UnencryptedHTTP2() {
3978 return nil
3979 }
3980 ln, err := net.Listen("tcp", addr)
3981 if err != nil {
3982 return err
3983 }
3984 defer ln.Close()
3985 return s.ServeTLS(ln, certFile, keyFile)
3986 }
3987
3988
3989
3990
3991 func (s *Server) setupHTTP2_ServeTLS() error {
3992 s.nextProtoOnce.Do(s.onceSetNextProtoDefaults)
3993 return s.nextProtoErr
3994 }
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004 func (s *Server) setupHTTP2_Serve() error {
4005 s.nextProtoOnce.Do(s.onceSetNextProtoDefaults_Serve)
4006 return s.nextProtoErr
4007 }
4008
4009 func (s *Server) onceSetNextProtoDefaults_Serve() {
4010 if s.shouldConfigureHTTP2ForServe() {
4011 s.onceSetNextProtoDefaults()
4012 }
4013 }
4014
4015 var http2server = godebug.New("http2server")
4016
4017
4018
4019
4020 func (s *Server) onceSetNextProtoDefaults() {
4021 if omitBundledHTTP2 {
4022 return
4023 }
4024 p := s.protocols()
4025 if !p.HTTP2() && !p.UnencryptedHTTP2() {
4026 return
4027 }
4028 if http2server.Value() == "0" {
4029 http2server.IncNonDefault()
4030 return
4031 }
4032 if _, ok := s.TLSNextProto["h2"]; ok {
4033
4034
4035
4036 return
4037 }
4038 s.configureHTTP2()
4039 }
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052 func TimeoutHandler(h Handler, dt time.Duration, msg string) Handler {
4053 return &timeoutHandler{
4054 handler: h,
4055 body: msg,
4056 dt: dt,
4057 }
4058 }
4059
4060
4061
4062 var ErrHandlerTimeout = errors.New("http: Handler timeout")
4063
4064 type timeoutHandler struct {
4065 handler Handler
4066 body string
4067 dt time.Duration
4068
4069
4070
4071 testContext context.Context
4072 }
4073
4074 func (h *timeoutHandler) errorBody() string {
4075 if h.body != "" {
4076 return h.body
4077 }
4078 return "<html><head><title>Timeout</title></head><body><h1>Timeout</h1></body></html>"
4079 }
4080
4081 func (h *timeoutHandler) ServeHTTP(w ResponseWriter, r *Request) {
4082 ctx := h.testContext
4083 if ctx == nil {
4084 var cancelCtx context.CancelFunc
4085 ctx, cancelCtx = context.WithTimeout(r.Context(), h.dt)
4086 defer cancelCtx()
4087 }
4088 r = r.WithContext(ctx)
4089 done := make(chan struct{})
4090 tw := &timeoutWriter{
4091 w: w,
4092 h: make(Header),
4093 req: r,
4094 }
4095 panicChan := make(chan any, 1)
4096 go func() {
4097 defer func() {
4098 if p := recover(); p != nil {
4099 panicChan <- p
4100 }
4101 }()
4102 h.handler.ServeHTTP(tw, r)
4103 close(done)
4104 }()
4105 select {
4106 case p := <-panicChan:
4107 panic(p)
4108 case <-done:
4109 tw.mu.Lock()
4110 defer tw.mu.Unlock()
4111 dst := w.Header()
4112 maps.Copy(dst, tw.h)
4113 if !tw.wroteHeader {
4114 tw.code = StatusOK
4115 }
4116 w.WriteHeader(tw.code)
4117 w.Write(tw.wbuf.Bytes())
4118 case <-ctx.Done():
4119 tw.mu.Lock()
4120 defer tw.mu.Unlock()
4121 switch err := ctx.Err(); err {
4122 case context.DeadlineExceeded:
4123 w.WriteHeader(StatusServiceUnavailable)
4124 io.WriteString(w, h.errorBody())
4125 tw.err = ErrHandlerTimeout
4126 default:
4127 w.WriteHeader(StatusServiceUnavailable)
4128 tw.err = err
4129 }
4130 }
4131 }
4132
4133 type timeoutWriter struct {
4134 w ResponseWriter
4135 h Header
4136 wbuf bytes.Buffer
4137 req *Request
4138
4139 mu sync.Mutex
4140 err error
4141 wroteHeader bool
4142 code int
4143 }
4144
4145 var _ Pusher = (*timeoutWriter)(nil)
4146
4147
4148 func (tw *timeoutWriter) Push(target string, opts *PushOptions) error {
4149 if pusher, ok := tw.w.(Pusher); ok {
4150 return pusher.Push(target, opts)
4151 }
4152 return ErrNotSupported
4153 }
4154
4155 func (tw *timeoutWriter) Header() Header { return tw.h }
4156
4157 func (tw *timeoutWriter) Write(p []byte) (int, error) {
4158 tw.mu.Lock()
4159 defer tw.mu.Unlock()
4160 if tw.err != nil {
4161 return 0, tw.err
4162 }
4163 if !tw.wroteHeader {
4164 tw.writeHeaderLocked(StatusOK)
4165 }
4166 return tw.wbuf.Write(p)
4167 }
4168
4169 func (tw *timeoutWriter) writeHeaderLocked(code int) {
4170 checkWriteHeaderCode(code)
4171
4172 switch {
4173 case tw.err != nil:
4174 return
4175 case tw.wroteHeader:
4176 if tw.req != nil {
4177 caller := relevantCaller()
4178 logf(tw.req, "http: superfluous response.WriteHeader call from %s (%s:%d)", caller.Function, path.Base(caller.File), caller.Line)
4179 }
4180 default:
4181 tw.wroteHeader = true
4182 tw.code = code
4183 }
4184 }
4185
4186 func (tw *timeoutWriter) WriteHeader(code int) {
4187 tw.mu.Lock()
4188 defer tw.mu.Unlock()
4189 tw.writeHeaderLocked(code)
4190 }
4191
4192
4193
4194 type onceCloseListener struct {
4195 net.Listener
4196 once sync.Once
4197 closeErr error
4198 }
4199
4200 func (oc *onceCloseListener) Close() error {
4201 oc.once.Do(oc.close)
4202 return oc.closeErr
4203 }
4204
4205 func (oc *onceCloseListener) close() { oc.closeErr = oc.Listener.Close() }
4206
4207
4208 type globalOptionsHandler struct{}
4209
4210 func (globalOptionsHandler) ServeHTTP(w ResponseWriter, r *Request) {
4211 w.Header().Set("Content-Length", "0")
4212 if r.ContentLength != 0 {
4213
4214
4215
4216
4217
4218 mb := MaxBytesReader(w, r.Body, 4<<10)
4219 io.Copy(io.Discard, mb)
4220 }
4221 }
4222
4223
4224
4225
4226 type initALPNRequest struct {
4227 ctx context.Context
4228 c *tls.Conn
4229 h serverHandler
4230 }
4231
4232
4233
4234
4235
4236 func (h initALPNRequest) BaseContext() context.Context { return h.ctx }
4237
4238 func (h initALPNRequest) ServeHTTP(rw ResponseWriter, req *Request) {
4239 if req.TLS == nil {
4240 req.TLS = &tls.ConnectionState{}
4241 *req.TLS = h.c.ConnectionState()
4242 }
4243 if req.Body == nil {
4244 req.Body = NoBody
4245 }
4246 if req.RemoteAddr == "" {
4247 req.RemoteAddr = h.c.RemoteAddr().String()
4248 }
4249 h.h.ServeHTTP(rw, req)
4250 }
4251
4252
4253 type loggingConn struct {
4254 name string
4255 net.Conn
4256 }
4257
4258 var (
4259 uniqNameMu sync.Mutex
4260 uniqNameNext = make(map[string]int)
4261 )
4262
4263 func newLoggingConn(baseName string, c net.Conn) net.Conn {
4264 uniqNameMu.Lock()
4265 defer uniqNameMu.Unlock()
4266 uniqNameNext[baseName]++
4267 return &loggingConn{
4268 name: fmt.Sprintf("%s-%d", baseName, uniqNameNext[baseName]),
4269 Conn: c,
4270 }
4271 }
4272
4273 func (c *loggingConn) Write(p []byte) (n int, err error) {
4274 log.Printf("%s.Write(%d) = ....", c.name, len(p))
4275 n, err = c.Conn.Write(p)
4276 log.Printf("%s.Write(%d) = %d, %v", c.name, len(p), n, err)
4277 return
4278 }
4279
4280 func (c *loggingConn) Read(p []byte) (n int, err error) {
4281 log.Printf("%s.Read(%d) = ....", c.name, len(p))
4282 n, err = c.Conn.Read(p)
4283 log.Printf("%s.Read(%d) = %d, %v", c.name, len(p), n, err)
4284 return
4285 }
4286
4287 func (c *loggingConn) Close() (err error) {
4288 log.Printf("%s.Close() = ...", c.name)
4289 err = c.Conn.Close()
4290 log.Printf("%s.Close() = %v", c.name, err)
4291 return
4292 }
4293
4294
4295
4296
4297 type checkConnErrorWriter struct {
4298 c *conn
4299 }
4300
4301 func (w checkConnErrorWriter) Write(p []byte) (n int, err error) {
4302 n, err = w.c.rwc.Write(p)
4303 if err != nil && w.c.werr == nil {
4304 w.c.werr = err
4305 w.c.cancelCtx()
4306 }
4307 return
4308 }
4309
4310 func numLeadingCRorLF(v []byte) (n int) {
4311 for _, b := range v {
4312 if b == '\r' || b == '\n' {
4313 n++
4314 continue
4315 }
4316 break
4317 }
4318 return
4319 }
4320
4321
4322
4323 func tlsRecordHeaderLooksLikeHTTP(hdr [5]byte) bool {
4324 switch string(hdr[:]) {
4325 case "GET /", "HEAD ", "POST ", "PUT /", "OPTIO":
4326 return true
4327 }
4328 return false
4329 }
4330
4331
4332 func MaxBytesHandler(h Handler, n int64) Handler {
4333 return HandlerFunc(func(w ResponseWriter, r *Request) {
4334 r2 := *r
4335 r2.Body = MaxBytesReader(w, r.Body, n)
4336 h.ServeHTTP(w, &r2)
4337 })
4338 }
4339
View as plain text