1919// Package grpchttp2 defines HTTP/2 types and a framer API and implementation.
2020package grpchttp2
2121
22- import "golang.org/x/net/http2/hpack"
22+ import (
23+ "golang.org/x/net/http2/hpack"
24+ "google.golang.org/grpc/mem"
25+ )
2326
2427// FrameType represents the type of an HTTP/2 Frame.
2528// See [Frame Type].
@@ -106,60 +109,41 @@ type FrameHeader struct {
106109// Each concrete Frame type defined below implements the Frame interface.
107110type Frame interface {
108111 Header () * FrameHeader
109- // Free frees the underlying buffer if present so it can be reused by the
110- // framer.
111- //
112- // TODO: Remove method from the interface once the mem package gets merged.
113- // Free will be called on each mem.Buffer individually.
114- Free ()
115112}
116113
117114// DataFrame is the representation of a [DATA frame]. DATA frames convey
118- // arbitrary, variable-length sequences of octets associated with a stream.
115+ // arbitrary, variable-length sequences of octets associated with a stream. It
116+ // is the user's responsibility to call Data.Free() when it is no longer
117+ // needed.
119118//
120119// [DATA frame]: https://httpwg.org/specs/rfc7540.html#DATA
121120type DataFrame struct {
122121 hdr * FrameHeader
123- free func ()
124- Data []byte
122+ Data * mem.Buffer
125123}
126124
127125// Header returns the 9 byte HTTP/2 header for this frame.
128126func (f * DataFrame ) Header () * FrameHeader {
129127 return f .hdr
130128}
131129
132- // Free frees the buffer containing the data in this frame.
133- func (f * DataFrame ) Free () {
134- if f .free != nil {
135- f .free ()
136- }
137- }
138-
139130// HeadersFrame is the representation of a [HEADERS Frame]. The HEADERS frame
140131// is used to open a stream, and additionally carries a header block fragment.
132+ // It is the user's responsibility to call HdrBlock.Free() when it is no longer
133+ // needed.
141134//
142135// [HEADERS Frame]: https://httpwg.org/specs/rfc7540.html#HEADERS
143136type HeadersFrame struct {
144137 hdr * FrameHeader
145- free func ()
146- HdrBlock []byte
138+ HdrBlock * mem.Buffer
147139}
148140
149141// Header returns the 9 byte HTTP/2 header for this frame.
150142func (f * HeadersFrame ) Header () * FrameHeader {
151143 return f .hdr
152144}
153145
154- // Free frees the buffer containing the header block in this frame.
155- func (f * HeadersFrame ) Free () {
156- if f .free != nil {
157- f .free ()
158- }
159- }
160-
161- // RSTStreamFrame is the representation of a [RST_STREAM Frame]. There is no
162- // underlying byte array in this frame, so Free() is a no-op. The RST_STREAM
146+ // RSTStreamFrame is the representation of a [RST_STREAM Frame]. The RST_STREAM
163147// frame allows for immediate termination of a stream
164148//
165149// [RST_STREAM Frame]: https://httpwg.org/specs/rfc7540.html#RST_STREAM
@@ -173,14 +157,9 @@ func (f *RSTStreamFrame) Header() *FrameHeader {
173157 return f .hdr
174158}
175159
176- // Free is a no-op for RSTStreamFrame.
177- func (f * RSTStreamFrame ) Free () {}
178-
179- // SettingsFrame is the representation of a [SETTINGS Frame]. There is no
180- // underlying byte array in this frame, so Free() is a no-op.
181- //
182- // The SETTINGS frame conveys configuration parameters that affect how
183- // endpoints communicate, such as preferences and constraints on peer behavior.
160+ // SettingsFrame is the representation of a [SETTINGS Frame]. The SETTINGS frame
161+ // conveys configuration parameters that affect how endpoints communicate, such
162+ // as preferences and constraints on peer behavior.
184163//
185164// [SETTINGS Frame]: https://httpwg.org/specs/rfc7540.html#SETTINGS
186165type SettingsFrame struct {
@@ -193,57 +172,44 @@ func (f *SettingsFrame) Header() *FrameHeader {
193172 return f .hdr
194173}
195174
196- // Free is a no-op for SettingsFrame.
197- func (f * SettingsFrame ) Free () {}
198-
199175// PingFrame is the representation of a [PING Frame]. The PING frame is a
200176// mechanism for measuring a minimal round-trip time from the sender, as well
201177// as determining whether an idle connection is still functional.
202178//
179+ // It is the user's responsibility to call Data.Free() when it is no longer
180+ // needed.
181+ //
203182// [PING Frame]: https://httpwg.org/specs/rfc7540.html#PING
204183type PingFrame struct {
205184 hdr * FrameHeader
206- free func ()
207- Data []byte
185+ Data * mem.Buffer
208186}
209187
210188// Header returns the 9 byte HTTP/2 header for this frame.
211189func (f * PingFrame ) Header () * FrameHeader {
212190 return f .hdr
213191}
214192
215- // Free frees the buffer containing the data in this frame.
216- func (f * PingFrame ) Free () {
217- if f .free != nil {
218- f .free ()
219- }
220- }
221-
222193// GoAwayFrame is the representation of a [GOAWAY Frame]. The GOAWAY frame is
223194// used to initiate shutdown of a connection or to signal serious error
224195// conditions.
225196//
197+ // It is the user's responsibility to call DebugData.Free() when it is no longer
198+ // needed.
199+ //
226200// [GOAWAY Frame]: https://httpwg.org/specs/rfc7540.html#GOAWAY
227201type GoAwayFrame struct {
228202 hdr * FrameHeader
229- free func ()
230203 LastStreamID uint32
231204 Code ErrCode
232- DebugData [] byte
205+ DebugData * mem. Buffer
233206}
234207
235208// Header returns the 9 byte HTTP/2 header for this frame.
236209func (f * GoAwayFrame ) Header () * FrameHeader {
237210 return f .hdr
238211}
239212
240- // Free frees the buffer containing the debug data in this frame.
241- func (f * GoAwayFrame ) Free () {
242- if f .free != nil {
243- f .free ()
244- }
245- }
246-
247213// WindowUpdateFrame is the representation of a [WINDOW_UPDATE Frame]. The
248214// WINDOW_UPDATE frame is used to implement flow control.
249215//
@@ -261,31 +227,24 @@ func (f *WindowUpdateFrame) Header() *FrameHeader {
261227// ContinuationFrame is the representation of a [CONTINUATION Frame]. The
262228// CONTINUATION frame is used to continue a sequence of header block fragments.
263229//
230+ // It is the user's responsibility to call HdrBlock.Free() when it is no longer
231+ // needed.
232+ //
264233// [CONTINUATION Frame]: https://httpwg.org/specs/rfc7540.html#CONTINUATION
265234type ContinuationFrame struct {
266235 hdr * FrameHeader
267- free func ()
268- HdrBlock []byte
236+ HdrBlock * mem.Buffer
269237}
270238
271239// Header returns the 9 byte HTTP/2 header for this frame.
272240func (f * ContinuationFrame ) Header () * FrameHeader {
273241 return f .hdr
274242}
275243
276- // Free frees the buffer containing the header block in this frame.
277- func (f * ContinuationFrame ) Free () {
278- if f .free != nil {
279- f .free ()
280- }
281- }
282-
283244// MetaHeadersFrame is the representation of one HEADERS frame and zero or more
284245// contiguous CONTINUATION frames and the decoding of their HPACK-encoded
285246// contents. This frame type is not transmitted over the network and is only
286247// generated by the ReadFrame() function.
287- //
288- // Since there is no underlying buffer in this Frame, Free() is a no-op.
289248type MetaHeadersFrame struct {
290249 hdr * FrameHeader
291250 Fields []hpack.HeaderField
@@ -299,24 +258,17 @@ func (f *MetaHeadersFrame) Header() *FrameHeader {
299258 return f .hdr
300259}
301260
302- // Free is a no-op for MetaHeadersFrame.
303- func (f * MetaHeadersFrame ) Free () {}
304-
305261// Framer encapsulates the functionality to read and write HTTP/2 frames.
306262type Framer interface {
307263 // ReadFrame returns grpchttp2.Frame. It is the caller's responsibility to
308- // call Frame.Free() once it is done using it. Note that once the mem
309- // package gets merged, this API will change in favor of Buffer.Free().
264+ // free the underlying buffer when done using the Frame.
310265 ReadFrame () (Frame , error )
311- // WriteData writes an HTTP/2 DATA frame to the stream.
312- // TODO: Once the mem package gets merged, data will change type to
313- // mem.BufferSlice.
314- WriteData (streamID uint32 , endStream bool , data ... []byte ) error
315- // WriteData writes an HTTP/2 HEADERS frame to the stream.
316- // TODO: Once the mem package gets merged, headerBlock will change type to
317- // mem.Buffer.
318- WriteHeaders (streamID uint32 , endStream , endHeaders bool , headerBlocks []byte ) error
319- // WriteData writes an HTTP/2 RST_STREAM frame to the stream.
266+ // WriteData writes an HTTP/2 DATA frame to the stream. The data is expected
267+ // to be freed by the caller.
268+ WriteData (streamID uint32 , endStream bool , data mem.BufferSlice ) error
269+ // WriteHeaders writes an HTTP/2 HEADERS frame to the stream.
270+ WriteHeaders (streamID uint32 , endStream , endHeaders bool , headerBlock []byte ) error
271+ // WriteRSTStream writes an HTTP/2 RST_STREAM frame to the stream.
320272 WriteRSTStream (streamID uint32 , code ErrCode ) error
321273 // WriteSettings writes an HTTP/2 SETTINGS frame to the connection.
322274 WriteSettings (settings ... Setting ) error
@@ -325,13 +277,9 @@ type Framer interface {
325277 // WritePing writes an HTTP/2 PING frame to the connection.
326278 WritePing (ack bool , data [8 ]byte ) error
327279 // WriteGoAway writes an HTTP/2 GOAWAY frame to the connection.
328- // TODO: Once the mem package gets merged, debugData will change type to
329- // mem.Buffer.
330280 WriteGoAway (maxStreamID uint32 , code ErrCode , debugData []byte ) error
331281 // WriteWindowUpdate writes an HTTP/2 WINDOW_UPDATE frame to the stream.
332282 WriteWindowUpdate (streamID , inc uint32 ) error
333283 // WriteContinuation writes an HTTP/2 CONTINUATION frame to the stream.
334- // TODO: Once the mem package gets merged, data will change type to
335- // mem.Buffer.
336284 WriteContinuation (streamID uint32 , endHeaders bool , headerBlock []byte ) error
337285}
0 commit comments