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

Side by Side Diff: net/http2/decoder/http2_frame_decoder.cc

Issue 2554683003: Revert of Add new HTTP/2 and HPACK decoder in net/http2/. (Closed)
Patch Set: Created 4 years 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
OLDNEW
(Empty)
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 "net/http2/decoder/http2_frame_decoder.h"
6
7 #include "net/http2/http2_constants.h"
8
9 namespace net {
10
11 std::ostream& operator<<(std::ostream& out, Http2FrameDecoder::State v) {
12 switch (v) {
13 case Http2FrameDecoder::State::kStartDecodingHeader:
14 return out << "kStartDecodingHeader";
15 case Http2FrameDecoder::State::kResumeDecodingHeader:
16 return out << "kResumeDecodingHeader";
17 case Http2FrameDecoder::State::kResumeDecodingPayload:
18 return out << "kResumeDecodingPayload";
19 case Http2FrameDecoder::State::kDiscardPayload:
20 return out << "kDiscardPayload";
21 }
22 return out << static_cast<int>(v);
23 }
24
25 Http2FrameDecoder::Http2FrameDecoder(Http2FrameDecoderListener* listener)
26 : state_(State::kStartDecodingHeader),
27 maximum_payload_size_(Http2SettingsInfo::DefaultMaxFrameSize()) {
28 set_listener(listener);
29 }
30
31 void Http2FrameDecoder::set_listener(Http2FrameDecoderListener* listener) {
32 if (listener == nullptr) {
33 listener = &no_op_listener_;
34 }
35 frame_decoder_state_.set_listener(listener);
36 }
37
38 Http2FrameDecoderListener* Http2FrameDecoder::listener() const {
39 return frame_decoder_state_.listener();
40 }
41
42 DecodeStatus Http2FrameDecoder::DecodeFrame(DecodeBuffer* db) {
43 DVLOG(2) << "Http2FrameDecoder::DecodeFrame state=" << state_;
44 switch (state_) {
45 case State::kStartDecodingHeader:
46 if (frame_decoder_state_.StartDecodingFrameHeader(db)) {
47 return StartDecodingPayload(db);
48 }
49 state_ = State::kResumeDecodingHeader;
50 return DecodeStatus::kDecodeInProgress;
51
52 case State::kResumeDecodingHeader:
53 if (frame_decoder_state_.ResumeDecodingFrameHeader(db)) {
54 return StartDecodingPayload(db);
55 }
56 return DecodeStatus::kDecodeInProgress;
57
58 case State::kResumeDecodingPayload:
59 return ResumeDecodingPayload(db);
60
61 case State::kDiscardPayload:
62 return DiscardPayload(db);
63 }
64
65 NOTREACHED();
66 return DecodeStatus::kDecodeError;
67 }
68
69 size_t Http2FrameDecoder::remaining_payload() const {
70 return frame_decoder_state_.remaining_payload();
71 }
72
73 uint32_t Http2FrameDecoder::remaining_padding() const {
74 return frame_decoder_state_.remaining_padding();
75 }
76
77 DecodeStatus Http2FrameDecoder::StartDecodingPayload(DecodeBuffer* db) {
78 const Http2FrameHeader& header = frame_header();
79
80 // TODO(jamessynge): Remove OnFrameHeader once done with supporting
81 // SpdyFramer's exact states.
82 if (!listener()->OnFrameHeader(header)) {
83 DVLOG(2) << "OnFrameHeader rejected the frame, will discard; header: "
84 << header;
85 state_ = State::kDiscardPayload;
86 frame_decoder_state_.InitializeRemainders();
87 return DecodeStatus::kDecodeError;
88 }
89
90 if (header.payload_length > maximum_payload_size_) {
91 DVLOG(2) << "Payload length is greater than allowed: "
92 << header.payload_length << " > " << maximum_payload_size_
93 << "\n header: " << header;
94 state_ = State::kDiscardPayload;
95 frame_decoder_state_.InitializeRemainders();
96 listener()->OnFrameSizeError(header);
97 return DecodeStatus::kDecodeError;
98 }
99
100 // The decode buffer can extend across many frames. Make sure that the
101 // buffer we pass to the start method that is specific to the frame type
102 // does not exend beyond this frame.
103 DecodeBufferSubset subset(db, header.payload_length);
104 DecodeStatus status;
105 switch (header.type) {
106 case Http2FrameType::DATA:
107 status = StartDecodingDataPayload(&subset);
108 break;
109
110 case Http2FrameType::HEADERS:
111 status = StartDecodingHeadersPayload(&subset);
112 break;
113
114 case Http2FrameType::PRIORITY:
115 status = StartDecodingPriorityPayload(&subset);
116 break;
117
118 case Http2FrameType::RST_STREAM:
119 status = StartDecodingRstStreamPayload(&subset);
120 break;
121
122 case Http2FrameType::SETTINGS:
123 status = StartDecodingSettingsPayload(&subset);
124 break;
125
126 case Http2FrameType::PUSH_PROMISE:
127 status = StartDecodingPushPromisePayload(&subset);
128 break;
129
130 case Http2FrameType::PING:
131 status = StartDecodingPingPayload(&subset);
132 break;
133
134 case Http2FrameType::GOAWAY:
135 status = StartDecodingGoAwayPayload(&subset);
136 break;
137
138 case Http2FrameType::WINDOW_UPDATE:
139 status = StartDecodingWindowUpdatePayload(&subset);
140 break;
141
142 case Http2FrameType::CONTINUATION:
143 status = StartDecodingContinuationPayload(&subset);
144 break;
145
146 case Http2FrameType::ALTSVC:
147 status = StartDecodingAltSvcPayload(&subset);
148 break;
149
150 default:
151 status = StartDecodingUnknownPayload(&subset);
152 break;
153 }
154
155 if (status == DecodeStatus::kDecodeDone) {
156 state_ = State::kStartDecodingHeader;
157 return status;
158 } else if (status == DecodeStatus::kDecodeInProgress) {
159 state_ = State::kResumeDecodingPayload;
160 return status;
161 } else {
162 state_ = State::kDiscardPayload;
163 return status;
164 }
165 }
166
167 DecodeStatus Http2FrameDecoder::ResumeDecodingPayload(DecodeBuffer* db) {
168 // The decode buffer can extend across many frames. Make sure that the
169 // buffer we pass to the start method that is specific to the frame type
170 // does not exend beyond this frame.
171 size_t remaining = frame_decoder_state_.remaining_total_payload();
172 DCHECK_LE(remaining, frame_header().payload_length);
173 DecodeBufferSubset subset(db, remaining);
174 DecodeStatus status;
175 switch (frame_header().type) {
176 case Http2FrameType::DATA:
177 status = ResumeDecodingDataPayload(&subset);
178 break;
179
180 case Http2FrameType::HEADERS:
181 status = ResumeDecodingHeadersPayload(&subset);
182 break;
183
184 case Http2FrameType::PRIORITY:
185 status = ResumeDecodingPriorityPayload(&subset);
186 break;
187
188 case Http2FrameType::RST_STREAM:
189 status = ResumeDecodingRstStreamPayload(&subset);
190 break;
191
192 case Http2FrameType::SETTINGS:
193 status = ResumeDecodingSettingsPayload(&subset);
194 break;
195
196 case Http2FrameType::PUSH_PROMISE:
197 status = ResumeDecodingPushPromisePayload(&subset);
198 break;
199
200 case Http2FrameType::PING:
201 status = ResumeDecodingPingPayload(&subset);
202 break;
203
204 case Http2FrameType::GOAWAY:
205 status = ResumeDecodingGoAwayPayload(&subset);
206 break;
207
208 case Http2FrameType::WINDOW_UPDATE:
209 status = ResumeDecodingWindowUpdatePayload(&subset);
210 break;
211
212 case Http2FrameType::CONTINUATION:
213 status = ResumeDecodingContinuationPayload(&subset);
214 break;
215
216 case Http2FrameType::ALTSVC:
217 status = ResumeDecodingAltSvcPayload(&subset);
218 break;
219
220 default:
221 status = ResumeDecodingUnknownPayload(&subset);
222 break;
223 }
224
225 if (status == DecodeStatus::kDecodeDone) {
226 state_ = State::kStartDecodingHeader;
227 return status;
228 } else if (status == DecodeStatus::kDecodeInProgress) {
229 return status;
230 } else {
231 state_ = State::kDiscardPayload;
232 return status;
233 }
234 }
235
236 // Clear any of the flags in the frame header that aren't set in valid_flags.
237 void Http2FrameDecoder::RetainFlags(uint8_t valid_flags) {
238 frame_decoder_state_.RetainFlags(valid_flags);
239 }
240
241 // Clear all of the flags in the frame header; for use with frame types that
242 // don't define any flags, such as WINDOW_UPDATE.
243 void Http2FrameDecoder::ClearFlags() {
244 frame_decoder_state_.ClearFlags();
245 }
246
247 DecodeStatus Http2FrameDecoder::StartDecodingAltSvcPayload(DecodeBuffer* db) {
248 ClearFlags();
249 return altsvc_payload_decoder_.StartDecodingPayload(&frame_decoder_state_,
250 db);
251 }
252 DecodeStatus Http2FrameDecoder::ResumeDecodingAltSvcPayload(DecodeBuffer* db) {
253 // The frame is not paddable.
254 DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
255 frame_decoder_state_.remaining_payload());
256 return altsvc_payload_decoder_.ResumeDecodingPayload(&frame_decoder_state_,
257 db);
258 }
259
260 DecodeStatus Http2FrameDecoder::StartDecodingContinuationPayload(
261 DecodeBuffer* db) {
262 RetainFlags(Http2FrameFlag::FLAG_END_HEADERS);
263 return continuation_payload_decoder_.StartDecodingPayload(
264 &frame_decoder_state_, db);
265 }
266 DecodeStatus Http2FrameDecoder::ResumeDecodingContinuationPayload(
267 DecodeBuffer* db) {
268 // The frame is not paddable.
269 DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
270 frame_decoder_state_.remaining_payload());
271 return continuation_payload_decoder_.ResumeDecodingPayload(
272 &frame_decoder_state_, db);
273 }
274
275 DecodeStatus Http2FrameDecoder::StartDecodingDataPayload(DecodeBuffer* db) {
276 RetainFlags(Http2FrameFlag::FLAG_END_STREAM | Http2FrameFlag::FLAG_PADDED);
277 return data_payload_decoder_.StartDecodingPayload(&frame_decoder_state_, db);
278 }
279 DecodeStatus Http2FrameDecoder::ResumeDecodingDataPayload(DecodeBuffer* db) {
280 return data_payload_decoder_.ResumeDecodingPayload(&frame_decoder_state_, db);
281 }
282
283 DecodeStatus Http2FrameDecoder::StartDecodingGoAwayPayload(DecodeBuffer* db) {
284 ClearFlags();
285 return goaway_payload_decoder_.StartDecodingPayload(&frame_decoder_state_,
286 db);
287 }
288 DecodeStatus Http2FrameDecoder::ResumeDecodingGoAwayPayload(DecodeBuffer* db) {
289 // The frame is not paddable.
290 DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
291 frame_decoder_state_.remaining_payload());
292 return goaway_payload_decoder_.ResumeDecodingPayload(&frame_decoder_state_,
293 db);
294 }
295
296 DecodeStatus Http2FrameDecoder::StartDecodingHeadersPayload(DecodeBuffer* db) {
297 RetainFlags(Http2FrameFlag::FLAG_END_STREAM |
298 Http2FrameFlag::FLAG_END_HEADERS | Http2FrameFlag::FLAG_PADDED |
299 Http2FrameFlag::FLAG_PRIORITY);
300 return headers_payload_decoder_.StartDecodingPayload(&frame_decoder_state_,
301 db);
302 }
303 DecodeStatus Http2FrameDecoder::ResumeDecodingHeadersPayload(DecodeBuffer* db) {
304 DCHECK_LE(frame_decoder_state_.remaining_payload_and_padding(),
305 frame_header().payload_length);
306 return headers_payload_decoder_.ResumeDecodingPayload(&frame_decoder_state_,
307 db);
308 }
309
310 DecodeStatus Http2FrameDecoder::StartDecodingPingPayload(DecodeBuffer* db) {
311 RetainFlags(Http2FrameFlag::FLAG_ACK);
312 return ping_payload_decoder_.StartDecodingPayload(&frame_decoder_state_, db);
313 }
314 DecodeStatus Http2FrameDecoder::ResumeDecodingPingPayload(DecodeBuffer* db) {
315 // The frame is not paddable.
316 DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
317 frame_decoder_state_.remaining_payload());
318 return ping_payload_decoder_.ResumeDecodingPayload(&frame_decoder_state_, db);
319 }
320
321 DecodeStatus Http2FrameDecoder::StartDecodingPriorityPayload(DecodeBuffer* db) {
322 ClearFlags();
323 return priority_payload_decoder_.StartDecodingPayload(&frame_decoder_state_,
324 db);
325 }
326 DecodeStatus Http2FrameDecoder::ResumeDecodingPriorityPayload(
327 DecodeBuffer* db) {
328 // The frame is not paddable.
329 DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
330 frame_decoder_state_.remaining_payload());
331 return priority_payload_decoder_.ResumeDecodingPayload(&frame_decoder_state_,
332 db);
333 }
334
335 DecodeStatus Http2FrameDecoder::StartDecodingPushPromisePayload(
336 DecodeBuffer* db) {
337 RetainFlags(Http2FrameFlag::FLAG_END_HEADERS | Http2FrameFlag::FLAG_PADDED);
338 return push_promise_payload_decoder_.StartDecodingPayload(
339 &frame_decoder_state_, db);
340 }
341 DecodeStatus Http2FrameDecoder::ResumeDecodingPushPromisePayload(
342 DecodeBuffer* db) {
343 DCHECK_LE(frame_decoder_state_.remaining_payload_and_padding(),
344 frame_header().payload_length);
345 return push_promise_payload_decoder_.ResumeDecodingPayload(
346 &frame_decoder_state_, db);
347 }
348
349 DecodeStatus Http2FrameDecoder::StartDecodingRstStreamPayload(
350 DecodeBuffer* db) {
351 ClearFlags();
352 return rst_stream_payload_decoder_.StartDecodingPayload(&frame_decoder_state_,
353 db);
354 }
355 DecodeStatus Http2FrameDecoder::ResumeDecodingRstStreamPayload(
356 DecodeBuffer* db) {
357 // The frame is not paddable.
358 DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
359 frame_decoder_state_.remaining_payload());
360 return rst_stream_payload_decoder_.ResumeDecodingPayload(
361 &frame_decoder_state_, db);
362 }
363
364 DecodeStatus Http2FrameDecoder::StartDecodingSettingsPayload(DecodeBuffer* db) {
365 RetainFlags(Http2FrameFlag::FLAG_ACK);
366 return settings_payload_decoder_.StartDecodingPayload(&frame_decoder_state_,
367 db);
368 }
369 DecodeStatus Http2FrameDecoder::ResumeDecodingSettingsPayload(
370 DecodeBuffer* db) {
371 // The frame is not paddable.
372 DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
373 frame_decoder_state_.remaining_payload());
374 return settings_payload_decoder_.ResumeDecodingPayload(&frame_decoder_state_,
375 db);
376 }
377
378 DecodeStatus Http2FrameDecoder::StartDecodingUnknownPayload(DecodeBuffer* db) {
379 // We don't known what type of frame this is, so we don't know which flags
380 // are valid, so we don't touch them.
381 return unknown_payload_decoder_.StartDecodingPayload(&frame_decoder_state_,
382 db);
383 }
384 DecodeStatus Http2FrameDecoder::ResumeDecodingUnknownPayload(DecodeBuffer* db) {
385 // We don't known what type of frame this is, so we treat it as not paddable.
386 DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
387 frame_decoder_state_.remaining_payload());
388 return unknown_payload_decoder_.ResumeDecodingPayload(&frame_decoder_state_,
389 db);
390 }
391
392 DecodeStatus Http2FrameDecoder::StartDecodingWindowUpdatePayload(
393 DecodeBuffer* db) {
394 ClearFlags();
395 return window_update_payload_decoder_.StartDecodingPayload(
396 &frame_decoder_state_, db);
397 }
398 DecodeStatus Http2FrameDecoder::ResumeDecodingWindowUpdatePayload(
399 DecodeBuffer* db) {
400 // The frame is not paddable.
401 DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
402 frame_decoder_state_.remaining_payload());
403 return window_update_payload_decoder_.ResumeDecodingPayload(
404 &frame_decoder_state_, db);
405 }
406
407 DecodeStatus Http2FrameDecoder::DiscardPayload(DecodeBuffer* db) {
408 DVLOG(2) << "remaining_payload=" << frame_decoder_state_.remaining_payload_
409 << "; remaining_padding=" << frame_decoder_state_.remaining_padding_;
410 frame_decoder_state_.remaining_payload_ +=
411 frame_decoder_state_.remaining_padding_;
412 frame_decoder_state_.remaining_padding_ = 0;
413 const size_t avail = frame_decoder_state_.AvailablePayload(db);
414 DVLOG(2) << "avail=" << avail;
415 if (avail > 0) {
416 frame_decoder_state_.ConsumePayload(avail);
417 db->AdvanceCursor(avail);
418 }
419 if (frame_decoder_state_.remaining_payload_ == 0) {
420 state_ = State::kStartDecodingHeader;
421 return DecodeStatus::kDecodeDone;
422 }
423 return DecodeStatus::kDecodeInProgress;
424 }
425
426 } // namespace net
OLDNEW
« no previous file with comments | « net/http2/decoder/http2_frame_decoder.h ('k') | net/http2/decoder/http2_frame_decoder_listener.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698