Source file
src/net/http/http2server.go
1
2
3
4
5
6
7 package http
8
9 import (
10 "context"
11 "crypto/tls"
12 "io"
13 "log"
14 "net"
15 "net/http/internal/http2"
16 "time"
17 )
18
19
20
21
22
23 const omitHTTP2Server = false
24
25 type http2Server = http2.Server
26
27 func (s *Server) configureHTTP2() {
28 h2srv := &http2.Server{}
29
30
31
32 if s.IdleTimeout != 0 {
33 s.h2IdleTimeout = s.IdleTimeout
34 } else {
35 s.h2IdleTimeout = s.ReadTimeout
36 }
37
38 if s.TLSConfig == nil {
39 s.TLSConfig = &tls.Config{}
40 }
41 s.nextProtoErr = h2srv.Configure(http2ServerConfig{s}, s.TLSConfig)
42 if s.nextProtoErr != nil {
43 return
44 }
45
46 s.RegisterOnShutdown(h2srv.GracefulShutdown)
47
48 if s.TLSNextProto == nil {
49 s.TLSNextProto = make(map[string]func(*Server, *tls.Conn, Handler))
50 }
51
52
53 s.TLSNextProto["h2"] = func(hs *Server, c *tls.Conn, h Handler) {
54 c.Close()
55 }
56
57 s.h2 = h2srv
58 }
59
60 func (s *Server) setHTTP2Config(conf http2ExternalServerConfig) {
61 if s.h2Config != nil {
62 panic("http: HTTP/2 Server already registered")
63 }
64 s.h2Config = conf
65 s.h2Config.ServeConnFunc(func(ctx context.Context, nc net.Conn, h Handler, sawClientPreface bool, upgradeReq *Request, settings []byte) {
66 s.serveHTTP2Conn(ctx, nc, h, sawClientPreface, upgradeReq, settings, nil)
67 })
68 s.configureHTTP2()
69 }
70
71
72
73
74
75 func (s *Server) serveHTTP2Conn(ctx context.Context, nc net.Conn, h Handler, sawClientPreface bool, upgradeReq *Request, settings []byte, onClose func()) {
76 s.setupHTTP2_ServeTLS()
77 var serverUpgradeReq *http2.ServerRequest
78 if upgradeReq != nil {
79 serverUpgradeReq = http2ServerRequestFromRequest(upgradeReq)
80 }
81 nc.SetReadDeadline(time.Time{})
82 nc.SetWriteDeadline(time.Time{})
83 s.h2.ServeConn(nc, &http2.ServeConnOpts{
84 Context: ctx,
85 Handler: http2Handler{h},
86 BaseConfig: http2ServerConfig{s},
87 SawClientPreface: sawClientPreface,
88 UpgradeRequest: serverUpgradeReq,
89 Settings: settings,
90 OnClose: onClose,
91 })
92 }
93
94 func http2ServerRequestFromRequest(req *Request) *http2.ServerRequest {
95 return &http2.ServerRequest{
96 Context: req.Context(),
97 Proto: req.Proto,
98 ProtoMajor: req.ProtoMajor,
99 ProtoMinor: req.ProtoMinor,
100 Method: req.Method,
101 URL: req.URL,
102 Header: http2.Header(req.Header),
103 Trailer: http2.Header(req.Trailer),
104 Body: req.Body,
105 Host: req.Host,
106 ContentLength: req.ContentLength,
107 RemoteAddr: req.RemoteAddr,
108 RequestURI: req.RequestURI,
109 TLS: req.TLS,
110 }
111 }
112
113 type http2Handler struct {
114 h Handler
115 }
116
117 func (h http2Handler) ServeHTTP(w *http2.ResponseWriter, req *http2.ServerRequest) {
118 h.h.ServeHTTP(http2ResponseWriter{w}, &Request{
119 ctx: req.Context,
120 Proto: "HTTP/2.0",
121 ProtoMajor: 2,
122 ProtoMinor: 0,
123 Method: req.Method,
124 URL: req.URL,
125 Header: Header(req.Header),
126 RequestURI: req.RequestURI,
127 Trailer: Header(req.Trailer),
128 Body: req.Body,
129 Host: req.Host,
130 ContentLength: req.ContentLength,
131 RemoteAddr: req.RemoteAddr,
132 TLS: req.TLS,
133 })
134 }
135
136 type http2ResponseWriter struct {
137 *http2.ResponseWriter
138 }
139
140
141 var (
142 _ CloseNotifier = http2ResponseWriter{}
143 _ Flusher = http2ResponseWriter{}
144 _ io.StringWriter = http2ResponseWriter{}
145 )
146
147 func (w http2ResponseWriter) Flush() { w.ResponseWriter.FlushError() }
148 func (w http2ResponseWriter) FlushError() error { return w.ResponseWriter.FlushError() }
149
150 func (w http2ResponseWriter) Header() Header { return Header(w.ResponseWriter.Header()) }
151
152 func (w http2ResponseWriter) Push(target string, opts *PushOptions) error {
153 var (
154 method string
155 header http2.Header
156 )
157 if opts != nil {
158 method = opts.Method
159 header = http2.Header(opts.Header)
160 }
161 err := w.ResponseWriter.Push(target, method, header)
162 if err == http2.ErrNotSupported {
163 err = ErrNotSupported
164 }
165 return err
166 }
167
168 type http2ServerConfig struct {
169 s *Server
170 }
171
172 func (s http2ServerConfig) MaxHeaderBytes() int { return s.s.MaxHeaderBytes }
173 func (s http2ServerConfig) MaxHeaderValueCount() int { return s.s.maxHeaderValueCount() }
174 func (s http2ServerConfig) ConnState(c net.Conn, st http2.ConnState) {
175 if s.s.ConnState != nil {
176 s.s.ConnState(c, ConnState(st))
177 }
178 }
179 func (s http2ServerConfig) DoKeepAlives() bool { return s.s.doKeepAlives() }
180 func (s http2ServerConfig) WriteTimeout() time.Duration { return s.s.WriteTimeout }
181 func (s http2ServerConfig) SendPingTimeout() time.Duration { return s.s.ReadTimeout }
182 func (s http2ServerConfig) ErrorLog() *log.Logger { return s.s.ErrorLog }
183 func (s http2ServerConfig) ReadTimeout() time.Duration { return s.s.ReadTimeout }
184 func (s http2ServerConfig) DisableClientPriority() bool { return s.s.DisableClientPriority }
185
186 func (s http2ServerConfig) IdleTimeout() time.Duration {
187 if s.s.h2Config != nil {
188 return s.s.h2Config.IdleTimeout()
189 }
190 return s.s.h2IdleTimeout
191 }
192
193 func (s http2ServerConfig) HTTP2Config() http2.Config {
194 return mergeHTTP2Config(s.s.HTTP2, s.s.h2Config)
195 }
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211 type http2ExternalServerConfig interface {
212
213 HTTP2Config() HTTP2Config
214 IdleTimeout() time.Duration
215
216
217
218 ServeConnFunc(func(ctx context.Context, nc net.Conn, h Handler, sawClientPreface bool, upgradeReq *Request, settings []byte))
219 }
220
View as plain text