Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(133)

Side by Side Diff: net/spdy/spdy_framer.h

Issue 2832973003: Split net/spdy into core and chromium subdirectories. (Closed)
Patch Set: Fix some more build rules. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/spdy/spdy_frame_reader_test.cc ('k') | net/spdy/spdy_framer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef NET_SPDY_SPDY_FRAMER_H_
6 #define NET_SPDY_SPDY_FRAMER_H_
7
8 #include <stddef.h>
9 #include <stdint.h>
10
11 #include <cstdint>
12 #include <map>
13 #include <memory>
14 #include <utility>
15
16 #include "base/sys_byteorder.h"
17 #include "net/base/net_export.h"
18 #include "net/spdy/hpack/hpack_decoder_interface.h"
19 #include "net/spdy/hpack/hpack_encoder.h"
20 #include "net/spdy/platform/api/spdy_string.h"
21 #include "net/spdy/platform/api/spdy_string_piece.h"
22 #include "net/spdy/spdy_alt_svc_wire_format.h"
23 #include "net/spdy/spdy_flags.h"
24 #include "net/spdy/spdy_header_block.h"
25 #include "net/spdy/spdy_headers_handler_interface.h"
26 #include "net/spdy/spdy_protocol.h"
27 #include "net/spdy/zero_copy_output_buffer.h"
28
29 namespace net {
30
31 class HttpProxyClientSocketPoolTest;
32 class HttpNetworkLayer;
33 class HttpNetworkTransactionTest;
34 class SpdyHttpStreamTest;
35 class SpdyNetworkTransactionTest;
36 class SpdyProxyClientSocketTest;
37 class SpdySessionTest;
38 class SpdyStreamTest;
39
40 class SpdyFramer;
41 class SpdyFrameBuilder;
42 class SpdyFramerDecoderAdapter;
43
44 namespace test {
45
46 class TestSpdyVisitor;
47 class SpdyFramerPeer;
48
49 } // namespace test
50
51 // SpdyFramerVisitorInterface is a set of callbacks for the SpdyFramer.
52 // Implement this interface to receive event callbacks as frames are
53 // decoded from the framer.
54 //
55 // Control frames that contain HTTP2 header blocks (HEADER, and PUSH_PROMISE)
56 // are processed in fashion that allows the decompressed header block to be
57 // delivered in chunks to the visitor.
58 // The following steps are followed:
59 // 1. OnHeaders, or OnPushPromise is called.
60 // 2. OnHeaderFrameStart is called; visitor is expected to return an instance
61 // of SpdyHeadersHandlerInterface that will receive the header key-value
62 // pairs.
63 // 3. OnHeaderFrameEnd is called, indicating that the full header block has
64 // been delivered for the control frame.
65 // During step 2, if the visitor is not interested in accepting the header data,
66 // it should return a no-op implementation of SpdyHeadersHandlerInterface.
67 class NET_EXPORT_PRIVATE SpdyFramerVisitorInterface {
68 public:
69 virtual ~SpdyFramerVisitorInterface() {}
70
71 // Called if an error is detected in the SpdySerializedFrame protocol.
72 virtual void OnError(SpdyFramer* framer) = 0;
73
74 // Called when the common header for a frame is received. Validating the
75 // common header occurs in later processing.
76 virtual void OnCommonHeader(SpdyStreamId stream_id,
77 size_t length,
78 uint8_t type,
79 uint8_t flags) {}
80
81 // Called when a data frame header is received. The frame's data
82 // payload will be provided via subsequent calls to
83 // OnStreamFrameData().
84 virtual void OnDataFrameHeader(SpdyStreamId stream_id,
85 size_t length,
86 bool fin) = 0;
87
88 // Called when data is received.
89 // |stream_id| The stream receiving data.
90 // |data| A buffer containing the data received.
91 // |len| The length of the data buffer.
92 virtual void OnStreamFrameData(SpdyStreamId stream_id,
93 const char* data,
94 size_t len) = 0;
95
96 // Called when the other side has finished sending data on this stream.
97 // |stream_id| The stream that was receivin data.
98 virtual void OnStreamEnd(SpdyStreamId stream_id) = 0;
99
100 // Called when padding is received (padding length field or padding octets).
101 // |stream_id| The stream receiving data.
102 // |len| The number of padding octets.
103 virtual void OnStreamPadding(SpdyStreamId stream_id, size_t len) = 0;
104
105 // Called just before processing the payload of a frame containing header
106 // data. Should return an implementation of SpdyHeadersHandlerInterface that
107 // will receive headers for stream |stream_id|. The caller will not take
108 // ownership of the headers handler. The same instance should remain live
109 // and be returned for all header frames comprising a logical header block
110 // (i.e. until OnHeaderFrameEnd() is called with end_headers == true).
111 virtual SpdyHeadersHandlerInterface* OnHeaderFrameStart(
112 SpdyStreamId stream_id) = 0;
113
114 // Called after processing the payload of a frame containing header data.
115 // |end_headers| is true if there will not be any subsequent CONTINUATION
116 // frames.
117 virtual void OnHeaderFrameEnd(SpdyStreamId stream_id, bool end_headers) = 0;
118
119 // Called when a RST_STREAM frame has been parsed.
120 virtual void OnRstStream(SpdyStreamId stream_id,
121 SpdyErrorCode error_code) = 0;
122
123 // Called when a SETTINGS frame is received.
124 // |clear_persisted| True if the respective flag is set on the SETTINGS frame.
125 virtual void OnSettings(bool clear_persisted) {}
126
127 // Called when a complete setting within a SETTINGS frame has been parsed and
128 // validated.
129 virtual void OnSetting(SpdySettingsIds id, uint32_t value) = 0;
130
131 // Called when a SETTINGS frame is received with the ACK flag set.
132 virtual void OnSettingsAck() {}
133
134 // Called before and after parsing SETTINGS id and value tuples.
135 virtual void OnSettingsEnd() = 0;
136
137 // Called when a PING frame has been parsed.
138 virtual void OnPing(SpdyPingId unique_id, bool is_ack) = 0;
139
140 // Called when a GOAWAY frame has been parsed.
141 virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
142 SpdyErrorCode error_code) = 0;
143
144 // Called when a HEADERS frame is received.
145 // Note that header block data is not included. See OnHeaderFrameStart().
146 // |stream_id| The stream receiving the header.
147 // |has_priority| Whether or not the headers frame included a priority value,
148 // and stream dependency info.
149 // |weight| If |has_priority| is true, then weight (in the range [1, 256])
150 // for the receiving stream, otherwise 0.
151 // |parent_stream_id| If |has_priority| is true the parent stream of the
152 // receiving stream, else 0.
153 // |exclusive| If |has_priority| is true the exclusivity of dependence on the
154 // parent stream, else false.
155 // |fin| Whether FIN flag is set in frame headers.
156 // |end| False if HEADERs frame is to be followed by a CONTINUATION frame,
157 // or true if not.
158 virtual void OnHeaders(SpdyStreamId stream_id,
159 bool has_priority,
160 int weight,
161 SpdyStreamId parent_stream_id,
162 bool exclusive,
163 bool fin,
164 bool end) = 0;
165
166 // Called when a WINDOW_UPDATE frame has been parsed.
167 virtual void OnWindowUpdate(SpdyStreamId stream_id,
168 int delta_window_size) = 0;
169
170 // Called when a goaway frame opaque data is available.
171 // |goaway_data| A buffer containing the opaque GOAWAY data chunk received.
172 // |len| The length of the header data buffer. A length of zero indicates
173 // that the header data block has been completely sent.
174 // When this function returns true the visitor indicates that it accepted
175 // all of the data. Returning false indicates that that an error has
176 // occurred while processing the data. Default implementation returns true.
177 virtual bool OnGoAwayFrameData(const char* goaway_data, size_t len);
178
179 // Called when a PUSH_PROMISE frame is received.
180 // Note that header block data is not included. See OnHeaderFrameStart().
181 virtual void OnPushPromise(SpdyStreamId stream_id,
182 SpdyStreamId promised_stream_id,
183 bool end) = 0;
184
185 // Called when a CONTINUATION frame is received.
186 // Note that header block data is not included. See OnHeaderFrameStart().
187 virtual void OnContinuation(SpdyStreamId stream_id, bool end) = 0;
188
189 // Called when an ALTSVC frame has been parsed.
190 virtual void OnAltSvc(
191 SpdyStreamId stream_id,
192 SpdyStringPiece origin,
193 const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector) {}
194
195 // Called when a PRIORITY frame is received.
196 // |stream_id| The stream to update the priority of.
197 // |parent_stream_id| The parent stream of |stream_id|.
198 // |weight| Stream weight, in the range [1, 256].
199 // |exclusive| Whether |stream_id| should be an only child of
200 // |parent_stream_id|.
201 virtual void OnPriority(SpdyStreamId stream_id,
202 SpdyStreamId parent_stream_id,
203 int weight,
204 bool exclusive) {}
205
206 // Called when a frame type we don't recognize is received.
207 // Return true if this appears to be a valid extension frame, false otherwise.
208 // We distinguish between extension frames and nonsense by checking
209 // whether the stream id is valid.
210 virtual bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) = 0;
211 };
212
213 class SpdyFrameSequence {
214 public:
215 virtual ~SpdyFrameSequence() {}
216
217 // Serializes the next frame in the sequence to |output|. Returns the number
218 // of bytes written to |output|.
219 virtual size_t NextFrame(ZeroCopyOutputBuffer* output) = 0;
220
221 // Returns true iff there is at least one more frame in the sequence.
222 virtual bool HasNextFrame() const = 0;
223 };
224
225 class ExtensionVisitorInterface {
226 public:
227 virtual ~ExtensionVisitorInterface() {}
228
229 // Called when non-standard SETTINGS are received.
230 virtual void OnSetting(uint16_t id, uint32_t value) = 0;
231
232 // Called when non-standard frames are received.
233 virtual bool OnFrameHeader(SpdyStreamId stream_id,
234 size_t length,
235 uint8_t type,
236 uint8_t flags) = 0;
237
238 // The payload for a single frame may be delivered as multiple calls to
239 // OnFramePayload. Since the length field is passed in OnFrameHeader, there is
240 // no explicit indication of the end of the frame payload.
241 virtual void OnFramePayload(const char* data, size_t len) = 0;
242 };
243
244 // Optionally, and in addition to SpdyFramerVisitorInterface, a class supporting
245 // SpdyFramerDebugVisitorInterface may be used in conjunction with SpdyFramer in
246 // order to extract debug/internal information about the SpdyFramer as it
247 // operates.
248 //
249 // Most HTTP2 implementations need not bother with this interface at all.
250 class NET_EXPORT_PRIVATE SpdyFramerDebugVisitorInterface {
251 public:
252 virtual ~SpdyFramerDebugVisitorInterface() {}
253
254 // Called after compressing a frame with a payload of
255 // a list of name-value pairs.
256 // |payload_len| is the uncompressed payload size.
257 // |frame_len| is the compressed frame size.
258 virtual void OnSendCompressedFrame(SpdyStreamId stream_id,
259 SpdyFrameType type,
260 size_t payload_len,
261 size_t frame_len) {}
262
263 // Called when a frame containing a compressed payload of
264 // name-value pairs is received.
265 // |frame_len| is the compressed frame size.
266 virtual void OnReceiveCompressedFrame(SpdyStreamId stream_id,
267 SpdyFrameType type,
268 size_t frame_len) {}
269 };
270
271 class NET_EXPORT_PRIVATE SpdyFramer {
272 public:
273 // HTTP2 states.
274 enum SpdyState {
275 SPDY_ERROR,
276 SPDY_READY_FOR_FRAME, // Framer is ready for reading the next frame.
277 SPDY_FRAME_COMPLETE, // Framer has finished reading a frame, need to reset.
278 SPDY_READING_COMMON_HEADER,
279 SPDY_CONTROL_FRAME_PAYLOAD,
280 SPDY_READ_DATA_FRAME_PADDING_LENGTH,
281 SPDY_CONSUME_PADDING,
282 SPDY_IGNORE_REMAINING_PAYLOAD,
283 SPDY_FORWARD_STREAM_FRAME,
284 SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK,
285 SPDY_CONTROL_FRAME_HEADER_BLOCK,
286 SPDY_GOAWAY_FRAME_PAYLOAD,
287 SPDY_SETTINGS_FRAME_HEADER,
288 SPDY_SETTINGS_FRAME_PAYLOAD,
289 SPDY_ALTSVC_FRAME_PAYLOAD,
290 SPDY_EXTENSION_FRAME_PAYLOAD,
291 };
292
293 // Framer error codes.
294 enum SpdyFramerError {
295 SPDY_NO_ERROR,
296 SPDY_INVALID_STREAM_ID, // Stream ID is invalid
297 SPDY_INVALID_CONTROL_FRAME, // Control frame is mal-formatted.
298 SPDY_CONTROL_PAYLOAD_TOO_LARGE, // Control frame payload was too large.
299 SPDY_ZLIB_INIT_FAILURE, // The Zlib library could not initialize.
300 SPDY_UNSUPPORTED_VERSION, // Control frame has unsupported version.
301 SPDY_DECOMPRESS_FAILURE, // There was an error decompressing.
302 SPDY_COMPRESS_FAILURE, // There was an error compressing.
303 SPDY_GOAWAY_FRAME_CORRUPT, // GOAWAY frame could not be parsed.
304 SPDY_RST_STREAM_FRAME_CORRUPT, // RST_STREAM frame could not be parsed.
305 SPDY_INVALID_PADDING, // HEADERS or DATA frame padding invalid
306 SPDY_INVALID_DATA_FRAME_FLAGS, // Data frame has invalid flags.
307 SPDY_INVALID_CONTROL_FRAME_FLAGS, // Control frame has invalid flags.
308 SPDY_UNEXPECTED_FRAME, // Frame received out of order.
309 SPDY_INTERNAL_FRAMER_ERROR, // SpdyFramer was used incorrectly.
310 SPDY_INVALID_CONTROL_FRAME_SIZE, // Control frame not sized to spec
311 SPDY_OVERSIZED_PAYLOAD, // Payload size was too large
312
313 LAST_ERROR, // Must be the last entry in the enum.
314 };
315
316 enum CompressionOption {
317 ENABLE_COMPRESSION,
318 DISABLE_COMPRESSION,
319 };
320
321 // Typedef for a function used to create SpdyFramerDecoderAdapter's.
322 // Defined in support of evaluating an alternate HTTP/2 decoder.
323 typedef std::unique_ptr<SpdyFramerDecoderAdapter> (*DecoderAdapterFactoryFn)(
324 SpdyFramer* outer);
325
326 // Constant for invalid (or unknown) stream IDs.
327 static const SpdyStreamId kInvalidStream;
328
329 // The maximum size of header data decompressed/delivered at once to the
330 // header block parser. (Exposed here for unit test purposes.)
331 static const size_t kHeaderDataChunkMaxSize;
332
333 void SerializeHeaderBlockWithoutCompression(
334 SpdyFrameBuilder* builder,
335 const SpdyHeaderBlock& header_block) const;
336
337 // Retrieve serialized length of SpdyHeaderBlock.
338 static size_t GetSerializedLength(const SpdyHeaderBlock* headers);
339
340 // Gets the serialized flags for the given |frame|.
341 static uint8_t GetSerializedFlags(const SpdyFrameIR& frame);
342
343 explicit SpdyFramer(CompressionOption option);
344
345 // Used recursively from the above constructor in order to support
346 // instantiating a SpdyFramerDecoderAdapter selected via flags or some other
347 // means.
348 SpdyFramer(DecoderAdapterFactoryFn adapter_factory, CompressionOption option);
349
350 virtual ~SpdyFramer();
351
352 // Set callbacks to be called from the framer. A visitor must be set, or
353 // else the framer will likely crash. It is acceptable for the visitor
354 // to do nothing. If this is called multiple times, only the last visitor
355 // will be used.
356 void set_visitor(SpdyFramerVisitorInterface* visitor);
357
358 // Set extension callbacks to be called from the framer. (Optional.)
359 void set_extension_visitor(ExtensionVisitorInterface* extension);
360
361 // Set debug callbacks to be called from the framer. The debug visitor is
362 // completely optional and need not be set in order for normal operation.
363 // If this is called multiple times, only the last visitor will be used.
364 void set_debug_visitor(SpdyFramerDebugVisitorInterface* debug_visitor);
365
366 // Sets whether or not ProcessInput returns after finishing a frame, or
367 // continues processing additional frames. Normally ProcessInput processes
368 // all input, but this method enables the caller (and visitor) to work with
369 // a single frame at a time (or that portion of the frame which is provided
370 // as input). Reset() does not change the value of this flag.
371 void set_process_single_input_frame(bool v);
372
373 // Pass data into the framer for parsing.
374 // Returns the number of bytes consumed. It is safe to pass more bytes in
375 // than may be consumed.
376 size_t ProcessInput(const char* data, size_t len);
377
378 // Resets the framer state after a frame has been successfully decoded.
379 // TODO(mbelshe): can we make this private?
380 void Reset();
381
382 // Check the state of the framer.
383 SpdyFramerError spdy_framer_error() const;
384 SpdyState state() const;
385 bool HasError() const { return state() == SPDY_ERROR; }
386
387 // Given a buffer containing a serialized header block parse out a
388 // SpdyHeaderBlock, putting the results in the given header block.
389 // Returns true if successfully parsed, false otherwise.
390 bool ParseHeaderBlockInBuffer(const char* header_data,
391 size_t header_length,
392 SpdyHeaderBlock* block) const;
393
394 // Iteratively converts a SpdyFrameWithHeaderBlockIR into an appropriate
395 // sequence of SpdySerializedFrames.
396 class NET_EXPORT_PRIVATE SpdyFrameIterator {
397 public:
398 // Creates an iterator with the provided framer.
399 // Does not take ownership of |framer|.
400 // |framer| must outlive this instance.
401 explicit SpdyFrameIterator(SpdyFramer* framer);
402 virtual ~SpdyFrameIterator();
403
404 // Serializes the next frame in the sequence to |output|. Returns the number
405 // of bytes written to |output|.
406 virtual bool NextFrame(ZeroCopyOutputBuffer* output);
407
408 // Returns true iff there is at least one more frame in the sequence.
409 virtual bool HasNextFrame() const;
410
411 // SpdyFrameIterator is neither copyable nor movable.
412 SpdyFrameIterator(const SpdyFrameIterator&) = delete;
413 SpdyFrameIterator& operator=(const SpdyFrameIterator&) = delete;
414
415 protected:
416 virtual SpdyFrameWithHeaderBlockIR* GetIR() const = 0;
417 virtual size_t GetFrameSizeSansBlock() const = 0;
418 virtual bool SerializeGivenEncoding(const SpdyString& encoding,
419 ZeroCopyOutputBuffer* output) const = 0;
420
421 SpdyFramer* GetFramer() const { return framer_; }
422 void SetEncoder(SpdyFrameWithHeaderBlockIR* ir) {
423 encoder_ =
424 framer_->GetHpackEncoder()->EncodeHeaderSet(ir->header_block());
425 }
426
427 private:
428 SpdyFramer* const framer_;
429 std::unique_ptr<HpackEncoder::ProgressiveEncoder> encoder_;
430 bool is_first_frame_;
431 bool has_next_frame_;
432
433 // Field for debug reporting.
434 size_t debug_total_size_;
435 };
436
437 // Iteratively converts a SpdyHeadersIR (with a possibly huge
438 // SpdyHeaderBlock) into an appropriate sequence of SpdySerializedFrames, and
439 // write to the output.
440 class NET_EXPORT_PRIVATE SpdyHeaderFrameIterator : public SpdyFrameIterator {
441 public:
442 // Does not take ownership of |framer|. Take ownership of |headers_ir|.
443 SpdyHeaderFrameIterator(SpdyFramer* framer,
444 std::unique_ptr<SpdyHeadersIR> headers_ir);
445
446 ~SpdyHeaderFrameIterator() override;
447
448 private:
449 SpdyFrameWithHeaderBlockIR* GetIR() const override;
450 size_t GetFrameSizeSansBlock() const override;
451 bool SerializeGivenEncoding(const SpdyString& encoding,
452 ZeroCopyOutputBuffer* output) const override;
453
454 const std::unique_ptr<SpdyHeadersIR> headers_ir_;
455 };
456
457 // Iteratively converts a SpdyPushPromiseIR (with a possibly huge
458 // SpdyHeaderBlock) into an appropriate sequence of SpdySerializedFrames, and
459 // write to the output.
460 class NET_EXPORT_PRIVATE SpdyPushPromiseFrameIterator
461 : public SpdyFrameIterator {
462 public:
463 // Does not take ownership of |framer|. Take ownership of |push_promise_ir|.
464 SpdyPushPromiseFrameIterator(
465 SpdyFramer* framer,
466 std::unique_ptr<SpdyPushPromiseIR> push_promise_ir);
467
468 ~SpdyPushPromiseFrameIterator() override;
469
470 private:
471 SpdyFrameWithHeaderBlockIR* GetIR() const override;
472 size_t GetFrameSizeSansBlock() const override;
473 bool SerializeGivenEncoding(const SpdyString& encoding,
474 ZeroCopyOutputBuffer* output) const override;
475
476 const std::unique_ptr<SpdyPushPromiseIR> push_promise_ir_;
477 };
478
479 // Serialize a data frame.
480 SpdySerializedFrame SerializeData(const SpdyDataIR& data) const;
481 // Serializes the data frame header and optionally padding length fields,
482 // excluding actual data payload and padding.
483 SpdySerializedFrame SerializeDataFrameHeaderWithPaddingLengthField(
484 const SpdyDataIR& data) const;
485
486 SpdySerializedFrame SerializeRstStream(
487 const SpdyRstStreamIR& rst_stream) const;
488
489 // Serializes a SETTINGS frame. The SETTINGS frame is
490 // used to communicate name/value pairs relevant to the communication channel.
491 SpdySerializedFrame SerializeSettings(const SpdySettingsIR& settings) const;
492
493 // Serializes a PING frame. The unique_id is used to
494 // identify the ping request/response.
495 SpdySerializedFrame SerializePing(const SpdyPingIR& ping) const;
496
497 // Serializes a GOAWAY frame. The GOAWAY frame is used
498 // prior to the shutting down of the TCP connection, and includes the
499 // stream_id of the last stream the sender of the frame is willing to process
500 // to completion.
501 SpdySerializedFrame SerializeGoAway(const SpdyGoAwayIR& goaway) const;
502
503 // Serializes a HEADERS frame. The HEADERS frame is used
504 // for sending headers.
505 SpdySerializedFrame SerializeHeaders(const SpdyHeadersIR& headers);
506
507 // Serializes a WINDOW_UPDATE frame. The WINDOW_UPDATE
508 // frame is used to implement per stream flow control.
509 SpdySerializedFrame SerializeWindowUpdate(
510 const SpdyWindowUpdateIR& window_update) const;
511
512 // Serializes a PUSH_PROMISE frame. The PUSH_PROMISE frame is used
513 // to inform the client that it will be receiving an additional stream
514 // in response to the original request. The frame includes synthesized
515 // headers to explain the upcoming data.
516 SpdySerializedFrame SerializePushPromise(
517 const SpdyPushPromiseIR& push_promise);
518
519 // Serializes a CONTINUATION frame. The CONTINUATION frame is used
520 // to continue a sequence of header block fragments.
521 SpdySerializedFrame SerializeContinuation(
522 const SpdyContinuationIR& continuation) const;
523
524 // Serializes an ALTSVC frame. The ALTSVC frame advertises the
525 // availability of an alternative service to the client.
526 SpdySerializedFrame SerializeAltSvc(const SpdyAltSvcIR& altsvc);
527
528 // Serializes a PRIORITY frame. The PRIORITY frame advises a change in
529 // the relative priority of the given stream.
530 SpdySerializedFrame SerializePriority(const SpdyPriorityIR& priority) const;
531
532 // Serialize a frame of unknown type.
533 SpdySerializedFrame SerializeFrame(const SpdyFrameIR& frame);
534
535 // Serialize a data frame.
536 bool SerializeData(const SpdyDataIR& data,
537 ZeroCopyOutputBuffer* output) const;
538
539 // Serializes the data frame header and optionally padding length fields,
540 // excluding actual data payload and padding.
541 bool SerializeDataFrameHeaderWithPaddingLengthField(
542 const SpdyDataIR& data,
543 ZeroCopyOutputBuffer* output) const;
544
545 bool SerializeRstStream(const SpdyRstStreamIR& rst_stream,
546 ZeroCopyOutputBuffer* output) const;
547
548 // Serializes a SETTINGS frame. The SETTINGS frame is
549 // used to communicate name/value pairs relevant to the communication channel.
550 bool SerializeSettings(const SpdySettingsIR& settings,
551 ZeroCopyOutputBuffer* output) const;
552
553 // Serializes a PING frame. The unique_id is used to
554 // identify the ping request/response.
555 bool SerializePing(const SpdyPingIR& ping,
556 ZeroCopyOutputBuffer* output) const;
557
558 // Serializes a GOAWAY frame. The GOAWAY frame is used
559 // prior to the shutting down of the TCP connection, and includes the
560 // stream_id of the last stream the sender of the frame is willing to process
561 // to completion.
562 bool SerializeGoAway(const SpdyGoAwayIR& goaway,
563 ZeroCopyOutputBuffer* output) const;
564
565 // Serializes a HEADERS frame. The HEADERS frame is used
566 // for sending headers.
567 bool SerializeHeaders(const SpdyHeadersIR& headers,
568 ZeroCopyOutputBuffer* output);
569
570 // Serializes a WINDOW_UPDATE frame. The WINDOW_UPDATE
571 // frame is used to implement per stream flow control.
572 bool SerializeWindowUpdate(const SpdyWindowUpdateIR& window_update,
573 ZeroCopyOutputBuffer* output) const;
574
575 // Serializes a PUSH_PROMISE frame. The PUSH_PROMISE frame is used
576 // to inform the client that it will be receiving an additional stream
577 // in response to the original request. The frame includes synthesized
578 // headers to explain the upcoming data.
579 bool SerializePushPromise(const SpdyPushPromiseIR& push_promise,
580 ZeroCopyOutputBuffer* output);
581
582 // Serializes a CONTINUATION frame. The CONTINUATION frame is used
583 // to continue a sequence of header block fragments.
584 bool SerializeContinuation(const SpdyContinuationIR& continuation,
585 ZeroCopyOutputBuffer* output) const;
586
587 // Serializes an ALTSVC frame. The ALTSVC frame advertises the
588 // availability of an alternative service to the client.
589 bool SerializeAltSvc(const SpdyAltSvcIR& altsvc,
590 ZeroCopyOutputBuffer* output);
591
592 // Serializes a PRIORITY frame. The PRIORITY frame advises a change in
593 // the relative priority of the given stream.
594 bool SerializePriority(const SpdyPriorityIR& priority,
595 ZeroCopyOutputBuffer* output) const;
596
597 // Serialize a frame of unknown type.
598 bool SerializeFrame(const SpdyFrameIR& frame, ZeroCopyOutputBuffer* output);
599
600 // Returns whether this SpdyFramer will compress header blocks using HPACK.
601 bool compression_enabled() const {
602 return compression_option_ == ENABLE_COMPRESSION;
603 }
604
605 void SetHpackIndexingPolicy(HpackEncoder::IndexingPolicy policy) {
606 GetHpackEncoder()->SetIndexingPolicy(std::move(policy));
607 }
608
609 // Returns the (minimum) size of frames (sans variable-length portions).
610 size_t GetDataFrameMinimumSize() const;
611 size_t GetFrameHeaderSize() const;
612 size_t GetRstStreamSize() const;
613 size_t GetSettingsMinimumSize() const;
614 size_t GetPingSize() const;
615 size_t GetGoAwayMinimumSize() const;
616 size_t GetHeadersMinimumSize() const;
617 size_t GetWindowUpdateSize() const;
618 size_t GetPushPromiseMinimumSize() const;
619 size_t GetContinuationMinimumSize() const;
620 size_t GetAltSvcMinimumSize() const;
621 size_t GetPrioritySize() const;
622
623 // Returns the minimum size a frame can be (data or control).
624 size_t GetFrameMinimumSize() const;
625
626 // Returns the maximum size a frame can be (data or control).
627 size_t GetFrameMaximumSize() const;
628
629 // Returns the maximum payload size of a DATA frame.
630 size_t GetDataFrameMaximumPayload() const;
631
632 // For debugging.
633 static const char* StateToString(int state);
634 static const char* SpdyFramerErrorToString(SpdyFramerError spdy_framer_error);
635
636 // Did the most recent frame header appear to be an HTTP/1.x (or earlier)
637 // response (i.e. start with "HTTP/")?
638 bool probable_http_response() const;
639
640 SpdyPriority GetLowestPriority() const { return kV3LowestPriority; }
641
642 SpdyPriority GetHighestPriority() const { return kV3HighestPriority; }
643
644 // Updates the maximum size of the header encoder compression table.
645 void UpdateHeaderEncoderTableSize(uint32_t value);
646
647 // Updates the maximum size of the header decoder compression table.
648 void UpdateHeaderDecoderTableSize(uint32_t value);
649
650 // Returns the maximum size of the header encoder compression table.
651 size_t header_encoder_table_size() const;
652
653 void set_max_decode_buffer_size_bytes(size_t max_decode_buffer_size_bytes) {
654 GetHpackDecoder()->set_max_decode_buffer_size_bytes(
655 max_decode_buffer_size_bytes);
656 }
657
658 size_t send_frame_size_limit() const { return send_frame_size_limit_; }
659 void set_send_frame_size_limit(size_t send_frame_size_limit) {
660 send_frame_size_limit_ = send_frame_size_limit;
661 }
662
663 size_t recv_frame_size_limit() const { return recv_frame_size_limit_; }
664 void set_recv_frame_size_limit(size_t recv_frame_size_limit) {
665 recv_frame_size_limit_ = recv_frame_size_limit;
666 }
667
668 void SetDecoderHeaderTableDebugVisitor(
669 std::unique_ptr<HpackHeaderTable::DebugVisitorInterface> visitor);
670
671 void SetEncoderHeaderTableDebugVisitor(
672 std::unique_ptr<HpackHeaderTable::DebugVisitorInterface> visitor);
673
674 // For use in SpdyFramerDecoderAdapter implementations; returns a HPACK
675 // decoder to be used.
676 HpackDecoderInterface* GetHpackDecoderForAdapter() {
677 return GetHpackDecoder();
678 }
679
680 // Returns the estimate of dynamically allocated memory in bytes.
681 size_t EstimateMemoryUsage() const;
682
683 protected:
684 friend class BufferedSpdyFramer;
685 friend class HttpNetworkLayer; // This is temporary for the server.
686 friend class HttpNetworkTransactionTest;
687 friend class HttpProxyClientSocketPoolTest;
688 friend class SpdyHttpStreamTest;
689 friend class SpdyNetworkTransactionTest;
690 friend class SpdyProxyClientSocketTest;
691 friend class SpdySessionTest;
692 friend class SpdyStreamTest;
693 friend class test::TestSpdyVisitor;
694 friend class test::SpdyFramerPeer;
695
696 private:
697 class CharBuffer {
698 public:
699 explicit CharBuffer(size_t capacity);
700 ~CharBuffer();
701
702 void CopyFrom(const char* data, size_t size);
703 void Rewind();
704
705 const char* data() const { return buffer_.get(); }
706 size_t len() const { return len_; }
707
708 size_t EstimateMemoryUsage() const;
709
710 private:
711 std::unique_ptr<char[]> buffer_;
712 size_t capacity_;
713 size_t len_;
714 };
715
716 // Scratch space necessary for processing SETTINGS frames.
717 struct SpdySettingsScratch {
718 SpdySettingsScratch();
719 void Reset();
720 size_t EstimateMemoryUsage() const;
721
722 // Buffer contains up to one complete key/value pair.
723 CharBuffer buffer;
724
725 // The ID of the last setting that was processed in the current SETTINGS
726 // frame. Used for detecting out-of-order or duplicate keys within a
727 // settings frame. Set to -1 before first key/value pair is processed.
728 int last_setting_id;
729 };
730
731 // Internal breakouts from ProcessInput. Each returns the number of bytes
732 // consumed from the data.
733 size_t ProcessCommonHeader(const char* data, size_t len);
734 size_t ProcessControlFramePayload(const char* data, size_t len);
735 size_t ProcessControlFrameBeforeHeaderBlock(const char* data, size_t len);
736 // HPACK data is re-encoded as SPDY3 and re-entrantly delivered through
737 // |ProcessControlFrameHeaderBlock()|. |is_hpack_header_block| controls
738 // whether data is treated as HPACK- vs SPDY3-encoded.
739 size_t ProcessControlFrameHeaderBlock(const char* data, size_t len);
740 size_t ProcessDataFramePaddingLength(const char* data, size_t len);
741 size_t ProcessFramePadding(const char* data, size_t len);
742 size_t ProcessDataFramePayload(const char* data, size_t len);
743 size_t ProcessGoAwayFramePayload(const char* data, size_t len);
744 size_t ProcessSettingsFrameHeader(const char* data, size_t len);
745 size_t ProcessSettingsFramePayload(const char* data, size_t len);
746 size_t ProcessAltSvcFramePayload(const char* data, size_t len);
747 size_t ProcessIgnoredControlFramePayload(/*const char* data,*/ size_t len);
748 size_t ProcessExtensionFramePayload(const char* data, size_t len);
749
750 // Validates the frame header against the current protocol, e.g.
751 // Frame type must be known, must specify a non-zero stream id.
752 //
753 // is_control_frame : the control bit
754 // frame_type_field : the unparsed frame type octet(s)
755 // payload_length_field: the stated length in octets of the frame payload
756 //
757 // For valid frames, returns the correct SpdyFrameType.
758 // Otherwise returns a best guess at invalid frame type,
759 // after setting the appropriate SpdyFramerError.
760 SpdyFrameType ValidateFrameHeader(bool is_control_frame,
761 uint8_t frame_type_field,
762 size_t payload_length_field);
763
764 // Helpers for above internal breakouts from ProcessInput.
765 void ProcessControlFrameHeader();
766 // Always passed exactly 1 setting's worth of data.
767 bool ProcessSetting(const char* data);
768
769 // Get (and lazily initialize) the HPACK state.
770 HpackEncoder* GetHpackEncoder();
771 HpackDecoderInterface* GetHpackDecoder();
772
773 size_t GetNumberRequiredContinuationFrames(size_t size);
774
775 bool WritePayloadWithContinuation(SpdyFrameBuilder* builder,
776 const SpdyString& hpack_encoding,
777 SpdyStreamId stream_id,
778 SpdyFrameType type,
779 int padding_payload_len);
780
781 // Utility to copy the given data block to the current frame buffer, up
782 // to the given maximum number of bytes, and update the buffer
783 // data (pointer and length). Returns the number of bytes
784 // read, and:
785 // *data is advanced the number of bytes read.
786 // *len is reduced by the number of bytes read.
787 size_t UpdateCurrentFrameBuffer(const char** data, size_t* len,
788 size_t max_bytes);
789
790 // Serializes a HEADERS frame from the given SpdyHeadersIR and encoded header
791 // block. Does not need or use the SpdyHeaderBlock inside SpdyHeadersIR.
792 // Return false if the serialization fails. |encoding| should not be empty.
793 bool SerializeHeadersGivenEncoding(const SpdyHeadersIR& headers,
794 const SpdyString& encoding,
795 ZeroCopyOutputBuffer* output) const;
796
797 // Serializes a PUSH_PROMISE frame from the given SpdyPushPromiseIR and
798 // encoded header block. Does not need or use the SpdyHeaderBlock inside
799 // SpdyHeadersIR.
800 bool SerializePushPromiseGivenEncoding(const SpdyPushPromiseIR& push_promise,
801 const SpdyString& encoding,
802 ZeroCopyOutputBuffer* output) const;
803
804 // Calculates the number of bytes required to serialize a SpdyHeadersIR, not
805 // including the bytes to be used for the encoded header set.
806 size_t GetHeaderFrameSizeSansBlock(const SpdyHeadersIR& header_ir) const;
807
808 // Calculates the number of bytes required to serialize a SpdyPushPromiseIR,
809 // not including the bytes to be used for the encoded header set.
810 size_t GetPushPromiseFrameSizeSansBlock(
811 const SpdyPushPromiseIR& push_promise_ir) const;
812
813 // Serializes the flags octet for a given SpdyHeadersIR.
814 uint8_t SerializeHeaderFrameFlags(const SpdyHeadersIR& header_ir) const;
815
816 // Serializes the flags octet for a given SpdyPushPromiseIR.
817 uint8_t SerializePushPromiseFrameFlags(
818 const SpdyPushPromiseIR& push_promise_ir) const;
819
820 // Set the error code and moves the framer into the error state.
821 void set_error(SpdyFramerError error);
822
823 // Helper functions to prepare the input for SpdyFrameBuilder.
824 void SerializeDataBuilderHelper(const SpdyDataIR& data_ir,
825 uint8_t* flags,
826 int* num_padding_fields,
827 size_t* size_with_padding) const;
828 void SerializeDataFrameHeaderWithPaddingLengthFieldBuilderHelper(
829 const SpdyDataIR& data_ir,
830 uint8_t* flags,
831 size_t* frame_size,
832 size_t* num_padding_fields) const;
833 void SerializeSettingsBuilderHelper(const SpdySettingsIR& settings,
834 uint8_t* flags,
835 const SettingsMap* values,
836 size_t* size) const;
837 void SerializeAltSvcBuilderHelper(const SpdyAltSvcIR& altsvc_ir,
838 SpdyString* value,
839 size_t* size) const;
840 void SerializeHeadersBuilderHelper(const SpdyHeadersIR& headers,
841 uint8_t* flags,
842 size_t* size,
843 SpdyString* hpack_encoding,
844 int* weight,
845 size_t* length_field);
846 void SerializePushPromiseBuilderHelper(const SpdyPushPromiseIR& push_promise,
847 uint8_t* flags,
848 SpdyString* hpack_encoding,
849 size_t* size);
850
851 // The size of the control frame buffer.
852 // Since this is only used for control frame headers, the maximum control
853 // frame header size is sufficient; all remaining control
854 // frame data is streamed to the visitor.
855 static const size_t kControlFrameBufferSize;
856
857 // The maximum size of the control frames that we send, including the size of
858 // the header. This limit is arbitrary. We can enforce it here or at the
859 // application layer. We chose the framing layer, but this can be changed (or
860 // removed) if necessary later down the line.
861 // TODO(diannahu): Rename to make it clear that this limit is for sending.
862 static const size_t kMaxControlFrameSize;
863 // The maximum size for the payload of DATA frames to send.
864 static const size_t kMaxDataPayloadSendSize;
865 // The size of one parameter in SETTINGS frame.
866 static const size_t kOneSettingParameterSize;
867
868 SpdyState state_;
869 SpdyState previous_state_;
870 SpdyFramerError spdy_framer_error_;
871
872 // Note that for DATA frame, remaining_data_length_ is sum of lengths of
873 // frame header, padding length field (optional), data payload (optional) and
874 // padding payload (optional).
875 size_t remaining_data_length_;
876
877 // The length (in bytes) of the padding payload to be processed.
878 size_t remaining_padding_payload_length_;
879
880 // The number of bytes remaining to read from the current control frame's
881 // headers. Note that header data blocks (for control types that have them)
882 // are part of the frame's payload, and not the frame's headers.
883 size_t remaining_control_header_;
884
885 // The limit on the size of sent HTTP/2 payloads as specified in the
886 // SETTINGS_MAX_FRAME_SIZE received from peer.
887 size_t send_frame_size_limit_ = kSpdyInitialFrameSizeLimit;
888
889 // The limit on the size of received HTTP/2 payloads as specified in the
890 // SETTINGS_MAX_FRAME_SIZE advertised to peer.
891 size_t recv_frame_size_limit_ = kSpdyInitialFrameSizeLimit;
892
893 CharBuffer current_frame_buffer_;
894
895 // The type of the frame currently being read.
896 SpdyFrameType current_frame_type_;
897
898 // The total length of the frame currently being read, including frame header.
899 uint32_t current_frame_length_;
900
901 // The stream ID field of the frame currently being read, if applicable.
902 SpdyStreamId current_frame_stream_id_;
903
904 // Set this to the current stream when we receive a HEADERS, PUSH_PROMISE, or
905 // CONTINUATION frame without the END_HEADERS(0x4) bit set. These frames must
906 // be followed by a CONTINUATION frame, or else we throw a PROTOCOL_ERROR.
907 // A value of 0 indicates that we are not expecting a CONTINUATION frame.
908 SpdyStreamId expect_continuation_;
909
910 // Scratch space for handling SETTINGS frames.
911 // TODO(hkhalil): Unify memory for this scratch space with
912 // current_frame_buffer_.
913 SpdySettingsScratch settings_scratch_;
914
915 std::unique_ptr<CharBuffer> altsvc_scratch_;
916
917 std::unique_ptr<HpackEncoder> hpack_encoder_;
918 std::unique_ptr<HpackDecoderInterface> hpack_decoder_;
919
920 SpdyFramerVisitorInterface* visitor_;
921 ExtensionVisitorInterface* extension_;
922 SpdyFramerDebugVisitorInterface* debug_visitor_;
923
924 SpdyHeadersHandlerInterface* header_handler_;
925
926 // Optional decoder to use instead of this instance.
927 std::unique_ptr<SpdyFramerDecoderAdapter> decoder_adapter_;
928
929 // The flags field of the frame currently being read.
930 uint8_t current_frame_flags_;
931
932 // Determines whether HPACK compression is used.
933 const CompressionOption compression_option_;
934
935 // On the first read, we check to see if the data starts with HTTP.
936 // If it does, we likely have an HTTP response. This isn't guaranteed
937 // though: we could have gotten a settings frame and then corrupt data that
938 // just looks like HTTP, but deterministic checking requires a lot more state.
939 bool probable_http_response_;
940
941 // If a HEADERS frame is followed by a CONTINUATION frame, the FIN/END_STREAM
942 // flag is still carried in the HEADERS frame. If it's set, flip this so that
943 // we know to terminate the stream when the entire header block has been
944 // processed.
945 bool end_stream_when_done_;
946
947 // If true, then ProcessInput returns after processing a full frame,
948 // rather than reading all available input.
949 bool process_single_input_frame_ = false;
950
951 // Latched value of FLAGS_chromium_http2_flag_remove_rewritelength.
952 bool skip_rewritelength_ = false;
953 };
954
955 } // namespace net
956
957 #endif // NET_SPDY_SPDY_FRAMER_H_
OLDNEW
« no previous file with comments | « net/spdy/spdy_frame_reader_test.cc ('k') | net/spdy/spdy_framer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698