Pass CreateDirectory errors up to IndexedDB.
[chromium-blink-merge.git] / net / spdy / buffered_spdy_framer.cc
blobe62316c643de6658128b3a42d9844d1ba322ed52
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.
5 #include "net/spdy/buffered_spdy_framer.h"
7 #include "base/logging.h"
9 namespace net {
11 BufferedSpdyFramer::BufferedSpdyFramer(SpdyMajorVersion version,
12 bool enable_compression)
13 : spdy_framer_(version),
14 visitor_(NULL),
15 header_buffer_used_(0),
16 header_buffer_valid_(false),
17 header_stream_id_(SpdyFramer::kInvalidStream),
18 frames_received_(0) {
19 spdy_framer_.set_enable_compression(enable_compression);
20 memset(header_buffer_, 0, sizeof(header_buffer_));
23 BufferedSpdyFramer::~BufferedSpdyFramer() {
26 void BufferedSpdyFramer::set_visitor(
27 BufferedSpdyFramerVisitorInterface* visitor) {
28 visitor_ = visitor;
29 spdy_framer_.set_visitor(this);
32 void BufferedSpdyFramer::OnError(SpdyFramer* spdy_framer) {
33 DCHECK(spdy_framer);
34 visitor_->OnError(spdy_framer->error_code());
37 void BufferedSpdyFramer::OnSynStream(SpdyStreamId stream_id,
38 SpdyStreamId associated_stream_id,
39 SpdyPriority priority,
40 uint8 credential_slot,
41 bool fin,
42 bool unidirectional) {
43 frames_received_++;
44 DCHECK(!control_frame_fields_.get());
45 control_frame_fields_.reset(new ControlFrameFields());
46 control_frame_fields_->type = SYN_STREAM;
47 control_frame_fields_->stream_id = stream_id;
48 control_frame_fields_->associated_stream_id = associated_stream_id;
49 control_frame_fields_->priority = priority;
50 control_frame_fields_->credential_slot = credential_slot;
51 control_frame_fields_->fin = fin;
52 control_frame_fields_->unidirectional = unidirectional;
54 InitHeaderStreaming(stream_id);
57 void BufferedSpdyFramer::OnHeaders(SpdyStreamId stream_id,
58 bool fin) {
59 frames_received_++;
60 DCHECK(!control_frame_fields_.get());
61 control_frame_fields_.reset(new ControlFrameFields());
62 control_frame_fields_->type = HEADERS;
63 control_frame_fields_->stream_id = stream_id;
64 control_frame_fields_->fin = fin;
66 InitHeaderStreaming(stream_id);
69 void BufferedSpdyFramer::OnSynReply(SpdyStreamId stream_id,
70 bool fin) {
71 frames_received_++;
72 DCHECK(!control_frame_fields_.get());
73 control_frame_fields_.reset(new ControlFrameFields());
74 control_frame_fields_->type = SYN_REPLY;
75 control_frame_fields_->stream_id = stream_id;
76 control_frame_fields_->fin = fin;
78 InitHeaderStreaming(stream_id);
81 bool BufferedSpdyFramer::OnCredentialFrameData(const char* frame_data,
82 size_t len) {
83 DCHECK(false);
84 return false;
87 bool BufferedSpdyFramer::OnControlFrameHeaderData(SpdyStreamId stream_id,
88 const char* header_data,
89 size_t len) {
90 CHECK_EQ(header_stream_id_, stream_id);
92 if (len == 0) {
93 // Indicates end-of-header-block.
94 CHECK(header_buffer_valid_);
96 SpdyHeaderBlock headers;
97 size_t parsed_len = spdy_framer_.ParseHeaderBlockInBuffer(
98 header_buffer_, header_buffer_used_, &headers);
99 // TODO(rch): this really should be checking parsed_len != len,
100 // but a bunch of tests fail. Need to figure out why.
101 if (parsed_len == 0) {
102 visitor_->OnStreamError(
103 stream_id, "Could not parse Spdy Control Frame Header.");
104 return false;
106 DCHECK(control_frame_fields_.get());
107 switch (control_frame_fields_->type) {
108 case SYN_STREAM:
109 visitor_->OnSynStream(control_frame_fields_->stream_id,
110 control_frame_fields_->associated_stream_id,
111 control_frame_fields_->priority,
112 control_frame_fields_->credential_slot,
113 control_frame_fields_->fin,
114 control_frame_fields_->unidirectional,
115 headers);
116 break;
117 case SYN_REPLY:
118 visitor_->OnSynReply(control_frame_fields_->stream_id,
119 control_frame_fields_->fin,
120 headers);
121 break;
122 case HEADERS:
123 visitor_->OnHeaders(control_frame_fields_->stream_id,
124 control_frame_fields_->fin,
125 headers);
126 break;
127 default:
128 DCHECK(false) << "Unexpect control frame type: "
129 << control_frame_fields_->type;
130 break;
132 control_frame_fields_.reset(NULL);
133 return true;
136 const size_t available = kHeaderBufferSize - header_buffer_used_;
137 if (len > available) {
138 header_buffer_valid_ = false;
139 visitor_->OnStreamError(
140 stream_id, "Received more data than the allocated size.");
141 return false;
143 memcpy(header_buffer_ + header_buffer_used_, header_data, len);
144 header_buffer_used_ += len;
145 return true;
148 void BufferedSpdyFramer::OnDataFrameHeader(SpdyStreamId stream_id,
149 size_t length,
150 bool fin) {
151 frames_received_++;
152 header_stream_id_ = stream_id;
155 void BufferedSpdyFramer::OnStreamFrameData(SpdyStreamId stream_id,
156 const char* data,
157 size_t len,
158 bool fin) {
159 visitor_->OnStreamFrameData(stream_id, data, len, fin);
162 void BufferedSpdyFramer::OnSettings(bool clear_persisted) {
163 visitor_->OnSettings(clear_persisted);
166 void BufferedSpdyFramer::OnSetting(SpdySettingsIds id,
167 uint8 flags,
168 uint32 value) {
169 visitor_->OnSetting(id, flags, value);
172 void BufferedSpdyFramer::OnPing(uint32 unique_id) {
173 visitor_->OnPing(unique_id);
176 void BufferedSpdyFramer::OnRstStream(SpdyStreamId stream_id,
177 SpdyRstStreamStatus status) {
178 visitor_->OnRstStream(stream_id, status);
180 void BufferedSpdyFramer::OnGoAway(SpdyStreamId last_accepted_stream_id,
181 SpdyGoAwayStatus status) {
182 visitor_->OnGoAway(last_accepted_stream_id, status);
185 void BufferedSpdyFramer::OnWindowUpdate(SpdyStreamId stream_id,
186 uint32 delta_window_size) {
187 visitor_->OnWindowUpdate(stream_id, delta_window_size);
190 void BufferedSpdyFramer::OnSynStreamCompressed(
191 size_t uncompressed_size,
192 size_t compressed_size) {
193 visitor_->OnSynStreamCompressed(uncompressed_size, compressed_size);
196 int BufferedSpdyFramer::protocol_version() {
197 return spdy_framer_.protocol_version();
200 size_t BufferedSpdyFramer::ProcessInput(const char* data, size_t len) {
201 return spdy_framer_.ProcessInput(data, len);
204 void BufferedSpdyFramer::Reset() {
205 spdy_framer_.Reset();
208 SpdyFramer::SpdyError BufferedSpdyFramer::error_code() const {
209 return spdy_framer_.error_code();
212 SpdyFramer::SpdyState BufferedSpdyFramer::state() const {
213 return spdy_framer_.state();
216 bool BufferedSpdyFramer::MessageFullyRead() {
217 return state() == SpdyFramer::SPDY_AUTO_RESET;
220 bool BufferedSpdyFramer::HasError() {
221 return spdy_framer_.HasError();
224 SpdyFrame* BufferedSpdyFramer::CreateSynStream(
225 SpdyStreamId stream_id,
226 SpdyStreamId associated_stream_id,
227 SpdyPriority priority,
228 uint8 credential_slot,
229 SpdyControlFlags flags,
230 bool compressed,
231 const SpdyHeaderBlock* headers) {
232 return spdy_framer_.CreateSynStream(stream_id, associated_stream_id, priority,
233 credential_slot, flags, compressed,
234 headers);
237 SpdyFrame* BufferedSpdyFramer::CreateSynReply(
238 SpdyStreamId stream_id,
239 SpdyControlFlags flags,
240 bool compressed,
241 const SpdyHeaderBlock* headers) {
242 return spdy_framer_.CreateSynReply(stream_id, flags, compressed, headers);
245 SpdyFrame* BufferedSpdyFramer::CreateRstStream(
246 SpdyStreamId stream_id,
247 SpdyRstStreamStatus status) const {
248 return spdy_framer_.CreateRstStream(stream_id, status);
251 SpdyFrame* BufferedSpdyFramer::CreateSettings(
252 const SettingsMap& values) const {
253 return spdy_framer_.CreateSettings(values);
256 SpdyFrame* BufferedSpdyFramer::CreatePingFrame(
257 uint32 unique_id) const {
258 return spdy_framer_.CreatePingFrame(unique_id);
261 SpdyFrame* BufferedSpdyFramer::CreateGoAway(
262 SpdyStreamId last_accepted_stream_id,
263 SpdyGoAwayStatus status) const {
264 return spdy_framer_.CreateGoAway(last_accepted_stream_id, status);
267 SpdyFrame* BufferedSpdyFramer::CreateHeaders(
268 SpdyStreamId stream_id,
269 SpdyControlFlags flags,
270 bool compressed,
271 const SpdyHeaderBlock* headers) {
272 return spdy_framer_.CreateHeaders(stream_id, flags, compressed, headers);
275 SpdyFrame* BufferedSpdyFramer::CreateWindowUpdate(
276 SpdyStreamId stream_id,
277 uint32 delta_window_size) const {
278 return spdy_framer_.CreateWindowUpdate(stream_id, delta_window_size);
281 SpdyFrame* BufferedSpdyFramer::CreateCredentialFrame(
282 const SpdyCredential& credential) const {
283 return spdy_framer_.CreateCredentialFrame(credential);
286 SpdyFrame* BufferedSpdyFramer::CreateDataFrame(SpdyStreamId stream_id,
287 const char* data,
288 uint32 len,
289 SpdyDataFlags flags) {
290 return spdy_framer_.CreateDataFrame(stream_id, data, len, flags);
293 SpdyPriority BufferedSpdyFramer::GetHighestPriority() const {
294 return spdy_framer_.GetHighestPriority();
297 void BufferedSpdyFramer::InitHeaderStreaming(SpdyStreamId stream_id) {
298 memset(header_buffer_, 0, kHeaderBufferSize);
299 header_buffer_used_ = 0;
300 header_buffer_valid_ = true;
301 header_stream_id_ = stream_id;
302 DCHECK_NE(header_stream_id_, SpdyFramer::kInvalidStream);
305 } // namespace net