OLD | NEW |
| (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/frame_decoder_state.h" | |
6 | |
7 namespace net { | |
8 | |
9 DecodeStatus FrameDecoderState::ReadPadLength(DecodeBuffer* db, | |
10 bool report_pad_length) { | |
11 DVLOG(2) << "ReadPadLength db->Remaining=" << db->Remaining() | |
12 << "; payload_length=" << frame_header().payload_length; | |
13 DCHECK(IsPaddable()); | |
14 DCHECK(frame_header().IsPadded()); | |
15 | |
16 // Pad Length is always at the start of the frame, so remaining_payload_ | |
17 // should equal payload_length at this point. | |
18 const uint32_t total_payload = frame_header().payload_length; | |
19 DCHECK_EQ(total_payload, remaining_payload_); | |
20 DCHECK_EQ(0u, remaining_padding_); | |
21 | |
22 if (db->HasData()) { | |
23 const uint32_t pad_length = db->DecodeUInt8(); | |
24 const uint32_t total_padding = pad_length + 1; | |
25 if (total_padding <= total_payload) { | |
26 remaining_padding_ = pad_length; | |
27 remaining_payload_ = total_payload - total_padding; | |
28 if (report_pad_length) { | |
29 listener()->OnPadLength(pad_length); | |
30 } | |
31 return DecodeStatus::kDecodeDone; | |
32 } | |
33 const uint32_t missing_length = total_padding - total_payload; | |
34 // To allow for the possibility of recovery, record the number of | |
35 // remaining bytes of the frame's payload (invalid though it is) | |
36 // in remaining_payload_. | |
37 remaining_payload_ = total_payload - 1; // 1 for sizeof(Pad Length). | |
38 remaining_padding_ = 0; | |
39 listener()->OnPaddingTooLong(frame_header(), missing_length); | |
40 return DecodeStatus::kDecodeError; | |
41 } | |
42 | |
43 if (total_payload == 0) { | |
44 remaining_payload_ = 0; | |
45 remaining_padding_ = 0; | |
46 listener()->OnPaddingTooLong(frame_header(), 1); | |
47 return DecodeStatus::kDecodeError; | |
48 } | |
49 // Need to wait for another buffer. | |
50 return DecodeStatus::kDecodeInProgress; | |
51 } | |
52 | |
53 bool FrameDecoderState::SkipPadding(DecodeBuffer* db) { | |
54 DVLOG(2) << "SkipPadding remaining_padding_=" << remaining_padding_ | |
55 << ", db->Remaining=" << db->Remaining() | |
56 << ", header: " << frame_header(); | |
57 DCHECK_EQ(remaining_payload_, 0u); | |
58 DCHECK(IsPaddable()) << "header: " << frame_header(); | |
59 DCHECK_GE(remaining_padding_, 0u); | |
60 DCHECK(remaining_padding_ == 0 || frame_header().IsPadded()) | |
61 << "remaining_padding_=" << remaining_padding_ | |
62 << ", header: " << frame_header(); | |
63 const size_t avail = AvailablePadding(db); | |
64 if (avail > 0) { | |
65 listener()->OnPadding(db->cursor(), avail); | |
66 db->AdvanceCursor(avail); | |
67 remaining_padding_ -= avail; | |
68 } | |
69 return remaining_padding_ == 0; | |
70 } | |
71 | |
72 DecodeStatus FrameDecoderState::ReportFrameSizeError() { | |
73 DVLOG(2) << "FrameDecoderState::ReportFrameSizeError: " | |
74 << " remaining_payload_=" << remaining_payload_ | |
75 << "; remaining_padding_=" << remaining_padding_ | |
76 << ", header: " << frame_header(); | |
77 listener()->OnFrameSizeError(frame_header()); | |
78 return DecodeStatus::kDecodeError; | |
79 } | |
80 | |
81 } // namespace net | |
OLD | NEW |