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