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 HandleRequest: func(w *http2.ResponseWriter, req *http2.ServerRequest) error {
86 return s.handleRequest(http2ResponseWriter{w}, &Request{
87 ctx: req.Context,
88 Proto: "HTTP/2.0",
89 ProtoMajor: 2,
90 ProtoMinor: 0,
91 Method: req.Method,
92 URL: req.URL,
93 Header: Header(req.Header),
94 RequestURI: req.RequestURI,
95 Trailer: Header(req.Trailer),
96 Body: req.Body,
97 Host: req.Host,
98 ContentLength: req.ContentLength,
99 RemoteAddr: req.RemoteAddr,
100 TLS: req.TLS,
101 }, h)
102 },
103 BaseConfig: http2ServerConfig{s},
104 SawClientPreface: sawClientPreface,
105 UpgradeRequest: serverUpgradeReq,
106 Settings: settings,
107 OnClose: onClose,
108 })
109 }
110
111 func http2ServerRequestFromRequest(req *Request) *http2.ServerRequest {
112 return &http2.ServerRequest{
113 Context: req.Context(),
114 Proto: req.Proto,
115 ProtoMajor: req.ProtoMajor,
116 ProtoMinor: req.ProtoMinor,
117 Method: req.Method,
118 URL: req.URL,
119 Header: http2.Header(req.Header),
120 Trailer: http2.Header(req.Trailer),
121 Body: req.Body,
122 Host: req.Host,
123 ContentLength: req.ContentLength,
124 RemoteAddr: req.RemoteAddr,
125 RequestURI: req.RequestURI,
126 TLS: req.TLS,
127 }
128 }
129
130 type http2ResponseWriter struct {
131 *http2.ResponseWriter
132 }
133
134
135 var (
136 _ CloseNotifier = http2ResponseWriter{}
137 _ Flusher = http2ResponseWriter{}
138 _ io.StringWriter = http2ResponseWriter{}
139 )
140
141 func (w http2ResponseWriter) Flush() { w.ResponseWriter.FlushError() }
142 func (w http2ResponseWriter) FlushError() error { return w.ResponseWriter.FlushError() }
143
144 func (w http2ResponseWriter) Header() Header { return Header(w.ResponseWriter.Header()) }
145
146 func (w http2ResponseWriter) Push(target string, opts *PushOptions) error {
147 var (
148 method string
149 header http2.Header
150 )
151 if opts != nil {
152 method = opts.Method
153 header = http2.Header(opts.Header)
154 }
155 err := w.ResponseWriter.Push(target, method, header)
156 if err == http2.ErrNotSupported {
157 err = ErrNotSupported
158 }
159 return err
160 }
161
162 type http2ServerConfig struct {
163 s *Server
164 }
165
166 func (s http2ServerConfig) MaxHeaderBytes() int { return s.s.MaxHeaderBytes }
167 func (s http2ServerConfig) MaxHeaderValueCount() int { return s.s.maxHeaderValueCount() }
168 func (s http2ServerConfig) ConnState(c net.Conn, st http2.ConnState) {
169 if s.s.ConnState != nil {
170 s.s.ConnState(c, ConnState(st))
171 }
172 }
173 func (s http2ServerConfig) DoKeepAlives() bool { return s.s.doKeepAlives() }
174 func (s http2ServerConfig) WriteTimeout() time.Duration { return s.s.WriteTimeout }
175 func (s http2ServerConfig) SendPingTimeout() time.Duration { return s.s.ReadTimeout }
176 func (s http2ServerConfig) ErrorLog() *log.Logger { return s.s.ErrorLog }
177 func (s http2ServerConfig) ReadTimeout() time.Duration { return s.s.ReadTimeout }
178 func (s http2ServerConfig) DisableClientPriority() bool { return s.s.DisableClientPriority }
179
180 func (s http2ServerConfig) IdleTimeout() time.Duration {
181 if s.s.h2Config != nil {
182 return s.s.h2Config.IdleTimeout()
183 }
184 return s.s.h2IdleTimeout
185 }
186
187 func (s http2ServerConfig) HTTP2Config() http2.Config {
188 return mergeHTTP2Config(s.s.HTTP2, s.s.h2Config)
189 }
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205 type http2ExternalServerConfig interface {
206
207 HTTP2Config() HTTP2Config
208 IdleTimeout() time.Duration
209
210
211
212 ServeConnFunc(func(ctx context.Context, nc net.Conn, h Handler, sawClientPreface bool, upgradeReq *Request, settings []byte))
213 }
214
View as plain text