1 // Copyright 2016 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 #include "quiche/http2/decoder/decode_http2_structures.h"
6
7 #include <cstdint>
8 #include <cstring>
9
10 #include "quiche/http2/decoder/decode_buffer.h"
11 #include "quiche/http2/http2_constants.h"
12 #include "quiche/common/platform/api/quiche_logging.h"
13
14 namespace http2 {
15
16 // Http2FrameHeader decoding:
17
DoDecode(Http2FrameHeader * out,DecodeBuffer * b)18 void DoDecode(Http2FrameHeader* out, DecodeBuffer* b) {
19 QUICHE_DCHECK_NE(nullptr, out);
20 QUICHE_DCHECK_NE(nullptr, b);
21 QUICHE_DCHECK_LE(Http2FrameHeader::EncodedSize(), b->Remaining());
22 out->payload_length = b->DecodeUInt24();
23 out->type = static_cast<Http2FrameType>(b->DecodeUInt8());
24 out->flags = static_cast<Http2FrameFlag>(b->DecodeUInt8());
25 out->stream_id = b->DecodeUInt31();
26 }
27
28 // Http2PriorityFields decoding:
29
DoDecode(Http2PriorityFields * out,DecodeBuffer * b)30 void DoDecode(Http2PriorityFields* out, DecodeBuffer* b) {
31 QUICHE_DCHECK_NE(nullptr, out);
32 QUICHE_DCHECK_NE(nullptr, b);
33 QUICHE_DCHECK_LE(Http2PriorityFields::EncodedSize(), b->Remaining());
34 uint32_t stream_id_and_flag = b->DecodeUInt32();
35 out->stream_dependency = stream_id_and_flag & StreamIdMask();
36 if (out->stream_dependency == stream_id_and_flag) {
37 out->is_exclusive = false;
38 } else {
39 out->is_exclusive = true;
40 }
41 // Note that chars are automatically promoted to ints during arithmetic,
42 // so 255 + 1 doesn't end up as zero.
43 out->weight = b->DecodeUInt8() + 1;
44 }
45
46 // Http2RstStreamFields decoding:
47
DoDecode(Http2RstStreamFields * out,DecodeBuffer * b)48 void DoDecode(Http2RstStreamFields* out, DecodeBuffer* b) {
49 QUICHE_DCHECK_NE(nullptr, out);
50 QUICHE_DCHECK_NE(nullptr, b);
51 QUICHE_DCHECK_LE(Http2RstStreamFields::EncodedSize(), b->Remaining());
52 out->error_code = static_cast<Http2ErrorCode>(b->DecodeUInt32());
53 }
54
55 // Http2SettingFields decoding:
56
DoDecode(Http2SettingFields * out,DecodeBuffer * b)57 void DoDecode(Http2SettingFields* out, DecodeBuffer* b) {
58 QUICHE_DCHECK_NE(nullptr, out);
59 QUICHE_DCHECK_NE(nullptr, b);
60 QUICHE_DCHECK_LE(Http2SettingFields::EncodedSize(), b->Remaining());
61 out->parameter = static_cast<Http2SettingsParameter>(b->DecodeUInt16());
62 out->value = b->DecodeUInt32();
63 }
64
65 // Http2PushPromiseFields decoding:
66
DoDecode(Http2PushPromiseFields * out,DecodeBuffer * b)67 void DoDecode(Http2PushPromiseFields* out, DecodeBuffer* b) {
68 QUICHE_DCHECK_NE(nullptr, out);
69 QUICHE_DCHECK_NE(nullptr, b);
70 QUICHE_DCHECK_LE(Http2PushPromiseFields::EncodedSize(), b->Remaining());
71 out->promised_stream_id = b->DecodeUInt31();
72 }
73
74 // Http2PingFields decoding:
75
DoDecode(Http2PingFields * out,DecodeBuffer * b)76 void DoDecode(Http2PingFields* out, DecodeBuffer* b) {
77 QUICHE_DCHECK_NE(nullptr, out);
78 QUICHE_DCHECK_NE(nullptr, b);
79 QUICHE_DCHECK_LE(Http2PingFields::EncodedSize(), b->Remaining());
80 memcpy(out->opaque_bytes, b->cursor(), Http2PingFields::EncodedSize());
81 b->AdvanceCursor(Http2PingFields::EncodedSize());
82 }
83
84 // Http2GoAwayFields decoding:
85
DoDecode(Http2GoAwayFields * out,DecodeBuffer * b)86 void DoDecode(Http2GoAwayFields* out, DecodeBuffer* b) {
87 QUICHE_DCHECK_NE(nullptr, out);
88 QUICHE_DCHECK_NE(nullptr, b);
89 QUICHE_DCHECK_LE(Http2GoAwayFields::EncodedSize(), b->Remaining());
90 out->last_stream_id = b->DecodeUInt31();
91 out->error_code = static_cast<Http2ErrorCode>(b->DecodeUInt32());
92 }
93
94 // Http2WindowUpdateFields decoding:
95
DoDecode(Http2WindowUpdateFields * out,DecodeBuffer * b)96 void DoDecode(Http2WindowUpdateFields* out, DecodeBuffer* b) {
97 QUICHE_DCHECK_NE(nullptr, out);
98 QUICHE_DCHECK_NE(nullptr, b);
99 QUICHE_DCHECK_LE(Http2WindowUpdateFields::EncodedSize(), b->Remaining());
100 out->window_size_increment = b->DecodeUInt31();
101 }
102
103 // Http2PriorityUpdateFields decoding:
104
DoDecode(Http2PriorityUpdateFields * out,DecodeBuffer * b)105 void DoDecode(Http2PriorityUpdateFields* out, DecodeBuffer* b) {
106 QUICHE_DCHECK_NE(nullptr, out);
107 QUICHE_DCHECK_NE(nullptr, b);
108 QUICHE_DCHECK_LE(Http2PriorityUpdateFields::EncodedSize(), b->Remaining());
109 out->prioritized_stream_id = b->DecodeUInt31();
110 }
111
112 // Http2AltSvcFields decoding:
113
DoDecode(Http2AltSvcFields * out,DecodeBuffer * b)114 void DoDecode(Http2AltSvcFields* out, DecodeBuffer* b) {
115 QUICHE_DCHECK_NE(nullptr, out);
116 QUICHE_DCHECK_NE(nullptr, b);
117 QUICHE_DCHECK_LE(Http2AltSvcFields::EncodedSize(), b->Remaining());
118 out->origin_length = b->DecodeUInt16();
119 }
120
121 } // namespace http2
122