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 := &url.URL{Path: path, RawQuery: 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, &url.URL{Path: cleanPath(u.Path) + "/", RawQuery: u.RawQuery}
2796 }
2797 }
2798 return n, matches, nil
2799 }
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827 func exactMatch(n *routingNode, path string) bool {
2828 if n == nil {
2829 return false
2830 }
2831
2832
2833
2834
2835 if !n.pattern.lastSegment().multi {
2836 return true
2837 }
2838
2839
2840
2841 if len(path) > 0 && path[len(path)-1] != '/' {
2842 return false
2843 }
2844
2845
2846
2847
2848
2849 return len(n.pattern.segments) == strings.Count(path, "/")
2850 }
2851
2852
2853 func (mux *ServeMux) matchingMethods(host, path string) []string {
2854
2855
2856 mux.mu.RLock()
2857 defer mux.mu.RUnlock()
2858 ms := map[string]bool{}
2859 mux.tree.matchingMethods(host, path, ms)
2860
2861 if !strings.HasSuffix(path, "/") {
2862 mux.tree.matchingMethods(host, path+"/", ms)
2863 }
2864 return slices.Sorted(maps.Keys(ms))
2865 }
2866
2867
2868
2869 func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
2870 if r.RequestURI == "*" {
2871 if r.ProtoAtLeast(1, 1) {
2872 w.Header().Set("Connection", "close")
2873 }
2874 w.WriteHeader(StatusBadRequest)
2875 return
2876 }
2877 var h Handler
2878 if use121 {
2879 h, _ = mux.mux121.findHandler(r)
2880 } else {
2881 h, r.Pattern, r.pat, r.matches = mux.findHandler(r)
2882 }
2883 h.ServeHTTP(w, r)
2884 }
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894 func (mux *ServeMux) Handle(pattern string, handler Handler) {
2895 if use121 {
2896 mux.mux121.handle(pattern, handler)
2897 } else {
2898 mux.register(pattern, handler)
2899 }
2900 }
2901
2902
2903
2904
2905
2906
2907 func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
2908 if use121 {
2909 mux.mux121.handleFunc(pattern, handler)
2910 } else {
2911 mux.register(pattern, HandlerFunc(handler))
2912 }
2913 }
2914
2915
2916
2917 func Handle(pattern string, handler Handler) {
2918 if use121 {
2919 DefaultServeMux.mux121.handle(pattern, handler)
2920 } else {
2921 DefaultServeMux.register(pattern, handler)
2922 }
2923 }
2924
2925
2926
2927 func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
2928 if use121 {
2929 DefaultServeMux.mux121.handleFunc(pattern, handler)
2930 } else {
2931 DefaultServeMux.register(pattern, HandlerFunc(handler))
2932 }
2933 }
2934
2935 func (mux *ServeMux) register(pattern string, handler Handler) {
2936 if err := mux.registerErr(pattern, handler); err != nil {
2937 panic(err)
2938 }
2939 }
2940
2941 func (mux *ServeMux) registerErr(patstr string, handler Handler) error {
2942 if patstr == "" {
2943 return errors.New("http: invalid pattern")
2944 }
2945 if handler == nil {
2946 return errors.New("http: nil handler")
2947 }
2948 if f, ok := handler.(HandlerFunc); ok && f == nil {
2949 return errors.New("http: nil handler")
2950 }
2951
2952 pat, err := parsePattern(patstr)
2953 if err != nil {
2954 return fmt.Errorf("parsing %q: %w", patstr, err)
2955 }
2956
2957
2958
2959 _, file, line, ok := runtime.Caller(3)
2960 if !ok {
2961 pat.loc = "unknown location"
2962 } else {
2963 pat.loc = fmt.Sprintf("%s:%d", file, line)
2964 }
2965
2966 mux.mu.Lock()
2967 defer mux.mu.Unlock()
2968
2969 if err := mux.index.possiblyConflictingPatterns(pat, func(pat2 *pattern) error {
2970 if pat.conflictsWith(pat2) {
2971 d := describeConflict(pat, pat2)
2972 return fmt.Errorf("pattern %q (registered at %s) conflicts with pattern %q (registered at %s):\n%s",
2973 pat, pat.loc, pat2, pat2.loc, d)
2974 }
2975 return nil
2976 }); err != nil {
2977 return err
2978 }
2979 mux.tree.addPattern(pat, handler)
2980 mux.index.addPattern(pat)
2981 return nil
2982 }
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996 func Serve(l net.Listener, handler Handler) error {
2997 srv := &Server{Handler: handler}
2998 return srv.Serve(l)
2999 }
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013 func ServeTLS(l net.Listener, handler Handler, certFile, keyFile string) error {
3014 srv := &Server{Handler: handler}
3015 return srv.ServeTLS(l, certFile, keyFile)
3016 }
3017
3018
3019
3020 type Server struct {
3021
3022
3023
3024
3025 Addr string
3026
3027 Handler Handler
3028
3029
3030
3031 DisableGeneralOptionsHandler bool
3032
3033
3034
3035
3036
3037
3038
3039
3040 TLSConfig *tls.Config
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050 ReadTimeout time.Duration
3051
3052
3053
3054
3055
3056
3057
3058 ReadHeaderTimeout time.Duration
3059
3060
3061
3062
3063
3064
3065 WriteTimeout time.Duration
3066
3067
3068
3069
3070
3071 IdleTimeout time.Duration
3072
3073
3074
3075
3076
3077
3078 MaxHeaderBytes int
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092 TLSNextProto map[string]func(*Server, *tls.Conn, Handler)
3093
3094
3095
3096
3097 ConnState func(net.Conn, ConnState)
3098
3099
3100
3101
3102
3103 ErrorLog *log.Logger
3104
3105
3106
3107
3108
3109
3110
3111 BaseContext func(net.Listener) context.Context
3112
3113
3114
3115
3116
3117 ConnContext func(ctx context.Context, c net.Conn) context.Context
3118
3119
3120 HTTP2 *HTTP2Config
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131 Protocols *Protocols
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142 DisableClientPriority bool
3143
3144 inShutdown atomic.Bool
3145
3146 disableKeepAlives atomic.Bool
3147 nextProtoOnce sync.Once
3148 nextProtoErr error
3149
3150 mu sync.Mutex
3151 listeners map[*net.Listener]struct{}
3152 activeConn map[*conn]struct{}
3153 onShutdown []func()
3154 h2 *http2Server
3155 h2Config http2ExternalServerConfig
3156 h2IdleTimeout time.Duration
3157 h3 *http3ServerHandler
3158
3159 listenerGroup sync.WaitGroup
3160 }
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171 func (s *Server) Close() error {
3172 s.inShutdown.Store(true)
3173 s.mu.Lock()
3174 defer s.mu.Unlock()
3175 err := s.closeListenersLocked()
3176
3177
3178
3179
3180
3181 s.mu.Unlock()
3182 s.listenerGroup.Wait()
3183 s.mu.Lock()
3184
3185 for c := range s.activeConn {
3186 c.rwc.Close()
3187 delete(s.activeConn, c)
3188 }
3189 return err
3190 }
3191
3192
3193
3194
3195
3196
3197
3198
3199 const shutdownPollIntervalMax = 500 * time.Millisecond
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221 func (s *Server) Shutdown(ctx context.Context) error {
3222 s.inShutdown.Store(true)
3223
3224 s.mu.Lock()
3225 if s.h3 != nil {
3226 s.h3.shutdownCtx = ctx
3227 }
3228 lnerr := s.closeListenersLocked()
3229 for _, f := range s.onShutdown {
3230 go f()
3231 }
3232 s.mu.Unlock()
3233 s.listenerGroup.Wait()
3234
3235 pollIntervalBase := time.Millisecond
3236 nextPollInterval := func() time.Duration {
3237
3238 interval := pollIntervalBase + time.Duration(rand.IntN(int(pollIntervalBase/10)))
3239
3240 pollIntervalBase *= 2
3241 if pollIntervalBase > shutdownPollIntervalMax {
3242 pollIntervalBase = shutdownPollIntervalMax
3243 }
3244 return interval
3245 }
3246
3247 timer := time.NewTimer(nextPollInterval())
3248 defer timer.Stop()
3249 for {
3250 if s.closeIdleConns() {
3251 return lnerr
3252 }
3253 select {
3254 case <-ctx.Done():
3255 return ctx.Err()
3256 case <-timer.C:
3257 timer.Reset(nextPollInterval())
3258 }
3259 }
3260 }
3261
3262
3263
3264
3265
3266
3267 func (s *Server) RegisterOnShutdown(f func()) {
3268 s.mu.Lock()
3269 s.onShutdown = append(s.onShutdown, f)
3270 s.mu.Unlock()
3271 }
3272
3273
3274
3275 func (s *Server) closeIdleConns() bool {
3276 s.mu.Lock()
3277 defer s.mu.Unlock()
3278 quiescent := true
3279 for c := range s.activeConn {
3280 st, unixSec := c.getState()
3281
3282
3283
3284 if st == StateNew && unixSec < time.Now().Unix()-5 {
3285 st = StateIdle
3286 }
3287 if st != StateIdle || unixSec == 0 {
3288
3289
3290 quiescent = false
3291 continue
3292 }
3293 c.rwc.Close()
3294 delete(s.activeConn, c)
3295 }
3296 return quiescent
3297 }
3298
3299 func (s *Server) closeListenersLocked() error {
3300 var err error
3301 for ln := range s.listeners {
3302 if cerr := (*ln).Close(); cerr != nil && err == nil {
3303 err = cerr
3304 }
3305 }
3306 return err
3307 }
3308
3309
3310
3311 type ConnState int
3312
3313 const (
3314
3315
3316
3317
3318 StateNew ConnState = iota
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331 StateActive
3332
3333
3334
3335
3336
3337 StateIdle
3338
3339
3340
3341 StateHijacked
3342
3343
3344
3345
3346 StateClosed
3347 )
3348
3349 var stateName = map[ConnState]string{
3350 StateNew: "new",
3351 StateActive: "active",
3352 StateIdle: "idle",
3353 StateHijacked: "hijacked",
3354 StateClosed: "closed",
3355 }
3356
3357 func (c ConnState) String() string {
3358 return stateName[c]
3359 }
3360
3361
3362
3363 type serverHandler struct {
3364 srv *Server
3365 }
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376 func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
3377 handler := sh.srv.Handler
3378 if handler == nil {
3379 handler = DefaultServeMux
3380 }
3381 if !sh.srv.DisableGeneralOptionsHandler && req.RequestURI == "*" && req.Method == "OPTIONS" {
3382 handler = globalOptionsHandler{}
3383 }
3384
3385 handler.ServeHTTP(rw, req)
3386 }
3387
3388 func badServeHTTP(serverHandler, ResponseWriter, *Request)
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399 func AllowQuerySemicolons(h Handler) Handler {
3400 return HandlerFunc(func(w ResponseWriter, r *Request) {
3401 if strings.Contains(r.URL.RawQuery, ";") {
3402 r2 := new(Request)
3403 *r2 = *r
3404 r2.URL = new(url.URL)
3405 *r2.URL = *r.URL
3406 r2.URL.RawQuery = strings.ReplaceAll(r.URL.RawQuery, ";", "&")
3407 h.ServeHTTP(w, r2)
3408 } else {
3409 h.ServeHTTP(w, r)
3410 }
3411 })
3412 }
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422 func (s *Server) ListenAndServe() error {
3423 if s.shuttingDown() {
3424 return ErrServerClosed
3425 }
3426 addr := s.Addr
3427 if addr == "" {
3428 addr = ":http"
3429 }
3430 ln, err := net.Listen("tcp", addr)
3431 if err != nil {
3432 return err
3433 }
3434 return s.Serve(ln)
3435 }
3436
3437 var testHookServerServe func(*Server, net.Listener)
3438
3439
3440
3441 func (s *Server) shouldConfigureHTTP2ForServe() bool {
3442 if s.TLSConfig == nil {
3443
3444
3445
3446
3447
3448
3449 return true
3450 }
3451 if s.protocols().UnencryptedHTTP2() {
3452 return true
3453 }
3454
3455
3456
3457
3458
3459
3460
3461 return slices.Contains(s.TLSConfig.NextProtos, "h2")
3462 }
3463
3464
3465
3466 var ErrServerClosed = errors.New("http: Server closed")
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478 func (s *Server) Serve(l net.Listener) error {
3479 if conf, ok := l.(http2ExternalServerConfig); ok {
3480
3481
3482
3483
3484
3485
3486
3487 s.setHTTP2Config(conf)
3488
3489
3490
3491 return nil
3492 }
3493
3494 if fn := testHookServerServe; fn != nil {
3495 fn(s, l)
3496 }
3497
3498 origListener := l
3499 l = &onceCloseListener{Listener: l}
3500 defer l.Close()
3501
3502 if err := s.setupHTTP2_Serve(); err != nil {
3503 return err
3504 }
3505
3506 if !s.trackListener(&l, true) {
3507 return ErrServerClosed
3508 }
3509 defer s.trackListener(&l, false)
3510
3511 baseCtx := context.Background()
3512 if s.BaseContext != nil {
3513 baseCtx = s.BaseContext(origListener)
3514 if baseCtx == nil {
3515 panic("BaseContext returned a nil context")
3516 }
3517 }
3518
3519 var tempDelay time.Duration
3520
3521 ctx := context.WithValue(baseCtx, ServerContextKey, s)
3522 for {
3523 rw, err := l.Accept()
3524 if err != nil {
3525 if s.shuttingDown() {
3526 return ErrServerClosed
3527 }
3528 if ne, ok := err.(net.Error); ok && ne.Temporary() {
3529 if tempDelay == 0 {
3530 tempDelay = 5 * time.Millisecond
3531 } else {
3532 tempDelay *= 2
3533 }
3534 if max := 1 * time.Second; tempDelay > max {
3535 tempDelay = max
3536 }
3537 s.logf("http: Accept error: %v; retrying in %v", err, tempDelay)
3538 time.Sleep(tempDelay)
3539 continue
3540 }
3541 return err
3542 }
3543 connCtx := ctx
3544 if cc := s.ConnContext; cc != nil {
3545 connCtx = cc(connCtx, rw)
3546 if connCtx == nil {
3547 panic("ConnContext returned nil")
3548 }
3549 }
3550 tempDelay = 0
3551 c := s.newConn(rw)
3552 c.setState(c.rwc, StateNew, runHooks)
3553 go c.serve(connCtx)
3554 }
3555 }
3556
3557 func (s *Server) setupTLSConfig(certFile, keyFile string, nextProtos []string) (*tls.Config, error) {
3558 config := cloneTLSConfig(s.TLSConfig)
3559 config.NextProtos = nextProtos
3560
3561 configHasCert := len(config.Certificates) > 0 || config.GetCertificate != nil || config.GetConfigForClient != nil
3562 if !configHasCert || certFile != "" || keyFile != "" {
3563 var err error
3564 config.Certificates = make([]tls.Certificate, 1)
3565 config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
3566 if err != nil {
3567 return nil, err
3568 }
3569 }
3570 return config, nil
3571 }
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587 func (s *Server) ServeTLS(l net.Listener, certFile, keyFile string) error {
3588
3589
3590 if err := s.setupHTTP2_ServeTLS(); err != nil {
3591 return err
3592 }
3593
3594 var nextProtos []string
3595 if s.TLSConfig != nil {
3596 nextProtos = s.TLSConfig.NextProtos
3597 }
3598 config, err := s.setupTLSConfig(certFile, keyFile, adjustNextProtos(nextProtos, s.protocols()))
3599 if err != nil {
3600 return err
3601 }
3602
3603 tlsListener := tls.NewListener(l, config)
3604 return s.Serve(tlsListener)
3605 }
3606
3607 func (s *Server) protocols() Protocols {
3608 if s.Protocols != nil {
3609
3610
3611
3612
3613 if s.Protocols.empty() {
3614 var p Protocols
3615 p.SetHTTP1(true)
3616 return p
3617 }
3618 return *s.Protocols
3619 }
3620
3621
3622
3623 _, hasH2 := s.TLSNextProto["h2"]
3624 http2Disabled := s.TLSNextProto != nil && !hasH2
3625
3626
3627
3628
3629 if http2server.Value() == "0" && !hasH2 {
3630 http2Disabled = true
3631 }
3632
3633 var p Protocols
3634 p.SetHTTP1(true)
3635 if !http2Disabled {
3636 p.SetHTTP2(true)
3637 }
3638 return p
3639 }
3640
3641
3642
3643 func adjustNextProtos(nextProtos []string, protos Protocols) []string {
3644
3645
3646
3647
3648
3649 nextProtos = slices.Clone(nextProtos)
3650 var have Protocols
3651 nextProtos = slices.DeleteFunc(nextProtos, func(s string) bool {
3652 switch s {
3653 case "http/1.1":
3654 if !protos.HTTP1() {
3655 return true
3656 }
3657 have.SetHTTP1(true)
3658 case "h2":
3659 if !protos.HTTP2() {
3660 return true
3661 }
3662 have.SetHTTP2(true)
3663 }
3664 return false
3665 })
3666 if protos.HTTP2() && !have.HTTP2() {
3667 nextProtos = append(nextProtos, "h2")
3668 }
3669 if protos.HTTP1() && !have.HTTP1() {
3670 nextProtos = append(nextProtos, "http/1.1")
3671 }
3672 return nextProtos
3673 }
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685 func (s *Server) trackListener(ln *net.Listener, add bool) bool {
3686 s.mu.Lock()
3687 defer s.mu.Unlock()
3688 if s.listeners == nil {
3689 s.listeners = make(map[*net.Listener]struct{})
3690 }
3691 if add {
3692 if s.shuttingDown() {
3693 return false
3694 }
3695 s.listeners[ln] = struct{}{}
3696 s.listenerGroup.Add(1)
3697 } else {
3698 delete(s.listeners, ln)
3699 s.listenerGroup.Done()
3700 }
3701 return true
3702 }
3703
3704 func (s *Server) trackConn(c *conn, add bool) {
3705 s.mu.Lock()
3706 defer s.mu.Unlock()
3707 if s.activeConn == nil {
3708 s.activeConn = make(map[*conn]struct{})
3709 }
3710 if add {
3711 s.activeConn[c] = struct{}{}
3712 } else {
3713 delete(s.activeConn, c)
3714 }
3715 }
3716
3717 func (s *Server) idleTimeout() time.Duration {
3718 if s.IdleTimeout != 0 {
3719 return s.IdleTimeout
3720 }
3721 return s.ReadTimeout
3722 }
3723
3724 func (s *Server) readHeaderTimeout() time.Duration {
3725 if s.ReadHeaderTimeout != 0 {
3726 return s.ReadHeaderTimeout
3727 }
3728 return s.ReadTimeout
3729 }
3730
3731 func (s *Server) doKeepAlives() bool {
3732 return !s.disableKeepAlives.Load() && !s.shuttingDown()
3733 }
3734
3735 func (s *Server) shuttingDown() bool {
3736 return s.inShutdown.Load()
3737 }
3738
3739
3740
3741
3742
3743 func (s *Server) SetKeepAlivesEnabled(v bool) {
3744 if v {
3745 s.disableKeepAlives.Store(false)
3746 return
3747 }
3748 s.disableKeepAlives.Store(true)
3749
3750
3751 s.closeIdleConns()
3752
3753
3754 }
3755
3756 func (s *Server) logf(format string, args ...any) {
3757 if s.ErrorLog != nil {
3758 s.ErrorLog.Printf(format, args...)
3759 } else {
3760 log.Printf(format, args...)
3761 }
3762 }
3763
3764
3765
3766
3767 func logf(r *Request, format string, args ...any) {
3768 s, _ := r.Context().Value(ServerContextKey).(*Server)
3769 if s != nil && s.ErrorLog != nil {
3770 s.ErrorLog.Printf(format, args...)
3771 } else {
3772 log.Printf(format, args...)
3773 }
3774 }
3775
3776
3777
3778
3779
3780
3781
3782
3783 func ListenAndServe(addr string, handler Handler) error {
3784 server := &Server{Addr: addr, Handler: handler}
3785 return server.ListenAndServe()
3786 }
3787
3788
3789
3790
3791
3792
3793 func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error {
3794 server := &Server{Addr: addr, Handler: handler}
3795 return server.ListenAndServeTLS(certFile, keyFile)
3796 }
3797
3798
3799
3800
3801
3802
3803
3804
3805 type http3ServerHandler struct {
3806 handler serverHandler
3807 tlsConfig *tls.Config
3808 baseCtx context.Context
3809 errc chan error
3810 shutdownCtx context.Context
3811 }
3812
3813
3814
3815 func (h *http3ServerHandler) ServeHTTP(w ResponseWriter, r *Request) {
3816 h.handler.ServeHTTP(w, r)
3817 }
3818
3819
3820
3821 func (h *http3ServerHandler) Addr() string {
3822 return h.handler.srv.Addr
3823 }
3824
3825
3826
3827 func (h *http3ServerHandler) TLSConfig() *tls.Config {
3828 return h.tlsConfig
3829 }
3830
3831
3832
3833 func (h *http3ServerHandler) BaseContext() context.Context {
3834 return h.baseCtx
3835 }
3836
3837
3838
3839
3840 func (h *http3ServerHandler) ListenErrHook(err error) {
3841 h.errc <- err
3842 }
3843
3844
3845
3846
3847
3848
3849 func (h *http3ServerHandler) ShutdownContext() context.Context {
3850 return h.shutdownCtx
3851 }
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868 func (s *Server) ListenAndServeTLS(certFile, keyFile string) error {
3869 if s.shuttingDown() {
3870 return ErrServerClosed
3871 }
3872 addr := s.Addr
3873 if addr == "" {
3874 addr = ":https"
3875 }
3876
3877 p := s.protocols()
3878 if p.http3() {
3879 fn, ok := s.TLSNextProto["http/3"]
3880 if !ok {
3881 return errors.New("http: Server.Protocols contains HTTP3, but Server does not support HTTP/3")
3882 }
3883 config, err := s.setupTLSConfig(certFile, keyFile, []string{"h3"})
3884 if err != nil {
3885 return err
3886 }
3887 errc := make(chan error, 1)
3888 s.mu.Lock()
3889 s.h3 = &http3ServerHandler{
3890 handler: serverHandler{s},
3891 tlsConfig: config,
3892 baseCtx: context.WithValue(context.Background(), ServerContextKey, s),
3893 errc: errc,
3894 }
3895 s.mu.Unlock()
3896 go fn(s, nil, s.h3)
3897 if err := <-errc; err != nil {
3898 return err
3899 }
3900 }
3901
3902
3903 if !p.HTTP1() && !p.HTTP2() && !p.UnencryptedHTTP2() {
3904 return nil
3905 }
3906 ln, err := net.Listen("tcp", addr)
3907 if err != nil {
3908 return err
3909 }
3910 defer ln.Close()
3911 return s.ServeTLS(ln, certFile, keyFile)
3912 }
3913
3914
3915
3916
3917 func (s *Server) setupHTTP2_ServeTLS() error {
3918 s.nextProtoOnce.Do(s.onceSetNextProtoDefaults)
3919 return s.nextProtoErr
3920 }
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930 func (s *Server) setupHTTP2_Serve() error {
3931 s.nextProtoOnce.Do(s.onceSetNextProtoDefaults_Serve)
3932 return s.nextProtoErr
3933 }
3934
3935 func (s *Server) onceSetNextProtoDefaults_Serve() {
3936 if s.shouldConfigureHTTP2ForServe() {
3937 s.onceSetNextProtoDefaults()
3938 }
3939 }
3940
3941 var http2server = godebug.New("http2server")
3942
3943
3944
3945
3946 func (s *Server) onceSetNextProtoDefaults() {
3947 if omitBundledHTTP2 {
3948 return
3949 }
3950 p := s.protocols()
3951 if !p.HTTP2() && !p.UnencryptedHTTP2() {
3952 return
3953 }
3954 if http2server.Value() == "0" {
3955 http2server.IncNonDefault()
3956 return
3957 }
3958 if _, ok := s.TLSNextProto["h2"]; ok {
3959
3960
3961
3962 return
3963 }
3964 s.configureHTTP2()
3965 }
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978 func TimeoutHandler(h Handler, dt time.Duration, msg string) Handler {
3979 return &timeoutHandler{
3980 handler: h,
3981 body: msg,
3982 dt: dt,
3983 }
3984 }
3985
3986
3987
3988 var ErrHandlerTimeout = errors.New("http: Handler timeout")
3989
3990 type timeoutHandler struct {
3991 handler Handler
3992 body string
3993 dt time.Duration
3994
3995
3996
3997 testContext context.Context
3998 }
3999
4000 func (h *timeoutHandler) errorBody() string {
4001 if h.body != "" {
4002 return h.body
4003 }
4004 return "<html><head><title>Timeout</title></head><body><h1>Timeout</h1></body></html>"
4005 }
4006
4007 func (h *timeoutHandler) ServeHTTP(w ResponseWriter, r *Request) {
4008 ctx := h.testContext
4009 if ctx == nil {
4010 var cancelCtx context.CancelFunc
4011 ctx, cancelCtx = context.WithTimeout(r.Context(), h.dt)
4012 defer cancelCtx()
4013 }
4014 r = r.WithContext(ctx)
4015 done := make(chan struct{})
4016 tw := &timeoutWriter{
4017 w: w,
4018 h: make(Header),
4019 req: r,
4020 }
4021 panicChan := make(chan any, 1)
4022 go func() {
4023 defer func() {
4024 if p := recover(); p != nil {
4025 panicChan <- p
4026 }
4027 }()
4028 h.handler.ServeHTTP(tw, r)
4029 close(done)
4030 }()
4031 select {
4032 case p := <-panicChan:
4033 panic(p)
4034 case <-done:
4035 tw.mu.Lock()
4036 defer tw.mu.Unlock()
4037 dst := w.Header()
4038 maps.Copy(dst, tw.h)
4039 if !tw.wroteHeader {
4040 tw.code = StatusOK
4041 }
4042 w.WriteHeader(tw.code)
4043 w.Write(tw.wbuf.Bytes())
4044 case <-ctx.Done():
4045 tw.mu.Lock()
4046 defer tw.mu.Unlock()
4047 switch err := ctx.Err(); err {
4048 case context.DeadlineExceeded:
4049 w.WriteHeader(StatusServiceUnavailable)
4050 io.WriteString(w, h.errorBody())
4051 tw.err = ErrHandlerTimeout
4052 default:
4053 w.WriteHeader(StatusServiceUnavailable)
4054 tw.err = err
4055 }
4056 }
4057 }
4058
4059 type timeoutWriter struct {
4060 w ResponseWriter
4061 h Header
4062 wbuf bytes.Buffer
4063 req *Request
4064
4065 mu sync.Mutex
4066 err error
4067 wroteHeader bool
4068 code int
4069 }
4070
4071 var _ Pusher = (*timeoutWriter)(nil)
4072
4073
4074 func (tw *timeoutWriter) Push(target string, opts *PushOptions) error {
4075 if pusher, ok := tw.w.(Pusher); ok {
4076 return pusher.Push(target, opts)
4077 }
4078 return ErrNotSupported
4079 }
4080
4081 func (tw *timeoutWriter) Header() Header { return tw.h }
4082
4083 func (tw *timeoutWriter) Write(p []byte) (int, error) {
4084 tw.mu.Lock()
4085 defer tw.mu.Unlock()
4086 if tw.err != nil {
4087 return 0, tw.err
4088 }
4089 if !tw.wroteHeader {
4090 tw.writeHeaderLocked(StatusOK)
4091 }
4092 return tw.wbuf.Write(p)
4093 }
4094
4095 func (tw *timeoutWriter) writeHeaderLocked(code int) {
4096 checkWriteHeaderCode(code)
4097
4098 switch {
4099 case tw.err != nil:
4100 return
4101 case tw.wroteHeader:
4102 if tw.req != nil {
4103 caller := relevantCaller()
4104 logf(tw.req, "http: superfluous response.WriteHeader call from %s (%s:%d)", caller.Function, path.Base(caller.File), caller.Line)
4105 }
4106 default:
4107 tw.wroteHeader = true
4108 tw.code = code
4109 }
4110 }
4111
4112 func (tw *timeoutWriter) WriteHeader(code int) {
4113 tw.mu.Lock()
4114 defer tw.mu.Unlock()
4115 tw.writeHeaderLocked(code)
4116 }
4117
4118
4119
4120 type onceCloseListener struct {
4121 net.Listener
4122 once sync.Once
4123 closeErr error
4124 }
4125
4126 func (oc *onceCloseListener) Close() error {
4127 oc.once.Do(oc.close)
4128 return oc.closeErr
4129 }
4130
4131 func (oc *onceCloseListener) close() { oc.closeErr = oc.Listener.Close() }
4132
4133
4134 type globalOptionsHandler struct{}
4135
4136 func (globalOptionsHandler) ServeHTTP(w ResponseWriter, r *Request) {
4137 w.Header().Set("Content-Length", "0")
4138 if r.ContentLength != 0 {
4139
4140
4141
4142
4143
4144 mb := MaxBytesReader(w, r.Body, 4<<10)
4145 io.Copy(io.Discard, mb)
4146 }
4147 }
4148
4149
4150
4151
4152 type initALPNRequest struct {
4153 ctx context.Context
4154 c *tls.Conn
4155 h serverHandler
4156 }
4157
4158
4159
4160
4161
4162 func (h initALPNRequest) BaseContext() context.Context { return h.ctx }
4163
4164 func (h initALPNRequest) ServeHTTP(rw ResponseWriter, req *Request) {
4165 if req.TLS == nil {
4166 req.TLS = &tls.ConnectionState{}
4167 *req.TLS = h.c.ConnectionState()
4168 }
4169 if req.Body == nil {
4170 req.Body = NoBody
4171 }
4172 if req.RemoteAddr == "" {
4173 req.RemoteAddr = h.c.RemoteAddr().String()
4174 }
4175 h.h.ServeHTTP(rw, req)
4176 }
4177
4178
4179 type loggingConn struct {
4180 name string
4181 net.Conn
4182 }
4183
4184 var (
4185 uniqNameMu sync.Mutex
4186 uniqNameNext = make(map[string]int)
4187 )
4188
4189 func newLoggingConn(baseName string, c net.Conn) net.Conn {
4190 uniqNameMu.Lock()
4191 defer uniqNameMu.Unlock()
4192 uniqNameNext[baseName]++
4193 return &loggingConn{
4194 name: fmt.Sprintf("%s-%d", baseName, uniqNameNext[baseName]),
4195 Conn: c,
4196 }
4197 }
4198
4199 func (c *loggingConn) Write(p []byte) (n int, err error) {
4200 log.Printf("%s.Write(%d) = ....", c.name, len(p))
4201 n, err = c.Conn.Write(p)
4202 log.Printf("%s.Write(%d) = %d, %v", c.name, len(p), n, err)
4203 return
4204 }
4205
4206 func (c *loggingConn) Read(p []byte) (n int, err error) {
4207 log.Printf("%s.Read(%d) = ....", c.name, len(p))
4208 n, err = c.Conn.Read(p)
4209 log.Printf("%s.Read(%d) = %d, %v", c.name, len(p), n, err)
4210 return
4211 }
4212
4213 func (c *loggingConn) Close() (err error) {
4214 log.Printf("%s.Close() = ...", c.name)
4215 err = c.Conn.Close()
4216 log.Printf("%s.Close() = %v", c.name, err)
4217 return
4218 }
4219
4220
4221
4222
4223 type checkConnErrorWriter struct {
4224 c *conn
4225 }
4226
4227 func (w checkConnErrorWriter) Write(p []byte) (n int, err error) {
4228 n, err = w.c.rwc.Write(p)
4229 if err != nil && w.c.werr == nil {
4230 w.c.werr = err
4231 w.c.cancelCtx()
4232 }
4233 return
4234 }
4235
4236 func numLeadingCRorLF(v []byte) (n int) {
4237 for _, b := range v {
4238 if b == '\r' || b == '\n' {
4239 n++
4240 continue
4241 }
4242 break
4243 }
4244 return
4245 }
4246
4247
4248
4249 func tlsRecordHeaderLooksLikeHTTP(hdr [5]byte) bool {
4250 switch string(hdr[:]) {
4251 case "GET /", "HEAD ", "POST ", "PUT /", "OPTIO":
4252 return true
4253 }
4254 return false
4255 }
4256
4257
4258 func MaxBytesHandler(h Handler, n int64) Handler {
4259 return HandlerFunc(func(w ResponseWriter, r *Request) {
4260 r2 := *r
4261 r2.Body = MaxBytesReader(w, r.Body, n)
4262 h.ServeHTTP(w, &r2)
4263 })
4264 }
4265
View as plain text