Make certificate viewer a tab-modal dialog.
[chromium-blink-merge.git] / net / spdy / buffered_spdy_framer.cc
blobfb1dcd7d06ad6a0ca8c52fc4600469c92961809a
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(int version, bool enable_compression)
12 : spdy_framer_(version),
13 visitor_(NULL),
14 header_buffer_used_(0),
15 header_buffer_valid_(false),
16 header_stream_id_(SpdyFramer::kInvalidStream),
17 frames_received_(0) {
18 spdy_framer_.set_enable_compression(enable_compression);
19 memset(header_buffer_, 0, sizeof(header_buffer_));
22 BufferedSpdyFramer::~BufferedSpdyFramer() {
25 void BufferedSpdyFramer::set_visitor(
26 BufferedSpdyFramerVisitorInterface* visitor) {
27 visitor_ = visitor;
28 spdy_framer_.set_visitor(this);
31 void BufferedSpdyFramer::OnError(SpdyFramer* spdy_framer) {
32 DCHECK(spdy_framer);
33 visitor_->OnError(spdy_framer->error_code());
36 void BufferedSpdyFramer::OnSynStream(SpdyStreamId stream_id,
37 SpdyStreamId associated_stream_id,
38 SpdyPriority priority,
39 uint8 credential_slot,
40 bool fin,
41 bool unidirectional) {
42 frames_received_++;
43 DCHECK(!control_frame_fields_.get());
44 control_frame_fields_.reset(new ControlFrameFields());
45 control_frame_fields_->type = SYN_STREAM;
46 control_frame_fields_->stream_id = stream_id;
47 control_frame_fields_->associated_stream_id = associated_stream_id;
48 control_frame_fields_->priority = priority;
49 control_frame_fields_->credential_slot = credential_slot;
50 control_frame_fields_->fin = fin;
51 control_frame_fields_->unidirectional = unidirectional;
53 InitHeaderStreaming(stream_id);
56 void BufferedSpdyFramer::OnHeaders(SpdyStreamId stream_id,
57 bool fin) {
58 frames_received_++;
59 DCHECK(!control_frame_fields_.get());
60 control_frame_fields_.reset(new ControlFrameFields());
61 control_frame_fields_->type = HEADERS;
62 control_frame_fields_->stream_id = stream_id;
63 control_frame_fields_->fin = fin;
65 InitHeaderStreaming(stream_id);
68 void BufferedSpdyFramer::OnSynReply(SpdyStreamId stream_id,
69 bool fin) {
70 frames_received_++;
71 DCHECK(!control_frame_fields_.get());
72 control_frame_fields_.reset(new ControlFrameFields());
73 control_frame_fields_->type = SYN_REPLY;
74 control_frame_fields_->stream_id = stream_id;
75 control_frame_fields_->fin = fin;
77 InitHeaderStreaming(stream_id);
80 bool BufferedSpdyFramer::OnCredentialFrameData(const char* frame_data,
81 size_t len) {
82 DCHECK(false);
83 return false;
86 bool BufferedSpdyFramer::OnControlFrameHeaderData(SpdyStreamId stream_id,
87 const char* header_data,
88 size_t len) {
89 CHECK_EQ(header_stream_id_, stream_id);
91 if (len == 0) {
92 // Indicates end-of-header-block.
93 CHECK(header_buffer_valid_);
95 SpdyHeaderBlock headers;
96 size_t parsed_len = spdy_framer_.ParseHeaderBlockInBuffer(
97 header_buffer_, header_buffer_used_, &headers);
98 // TODO(rch): this really should be checking parsed_len != len,
99 // but a bunch of tests fail. Need to figure out why.
100 if (parsed_len == 0) {
101 visitor_->OnStreamError(
102 stream_id, "Could not parse Spdy Control Frame Header.");
103 return false;
105 DCHECK(control_frame_fields_.get());
106 switch (control_frame_fields_->type) {
107 case SYN_STREAM:
108 visitor_->OnSynStream(control_frame_fields_->stream_id,
109 control_frame_fields_->associated_stream_id,
110 control_frame_fields_->priority,
111 control_frame_fields_->credential_slot,
112 control_frame_fields_->fin,
113 control_frame_fields_->unidirectional,
114 headers);
115 break;
116 case SYN_REPLY:
117 visitor_->OnSynReply(control_frame_fields_->stream_id,
118 control_frame_fields_->fin,
119 headers);
120 break;
121 case HEADERS:
122 visitor_->OnHeaders(control_frame_fields_->stream_id,
123 control_frame_fields_->fin,
124 headers);
125 break;
126 default:
127 DCHECK(false) << "Unexpect control frame type: "
128 << control_frame_fields_->type;
129 break;
131 control_frame_fields_.reset(NULL);
132 return true;
135 const size_t available = kHeaderBufferSize - header_buffer_used_;
136 if (len > available) {
137 header_buffer_valid_ = false;
138 visitor_->OnStreamError(
139 stream_id, "Received more data than the allocated size.");
140 return false;
142 memcpy(header_buffer_ + header_buffer_used_, header_data, len);
143 header_buffer_used_ += len;
144 return true;
147 void BufferedSpdyFramer::OnDataFrameHeader(SpdyStreamId stream_id,
148 size_t length,
149 bool fin) {
150 frames_received_++;
151 header_stream_id_ = stream_id;
154 void BufferedSpdyFramer::OnStreamFrameData(SpdyStreamId stream_id,
155 const char* data,
156 size_t len,
157 bool fin) {
158 visitor_->OnStreamFrameData(stream_id, data, len, fin);
161 void BufferedSpdyFramer::OnSetting(SpdySettingsIds id,
162 uint8 flags,
163 uint32 value) {
164 visitor_->OnSetting(id, flags, value);
167 void BufferedSpdyFramer::OnPing(uint32 unique_id) {
168 visitor_->OnPing(unique_id);
171 void BufferedSpdyFramer::OnRstStream(SpdyStreamId stream_id,
172 SpdyRstStreamStatus status) {
173 visitor_->OnRstStream(stream_id, status);
175 void BufferedSpdyFramer::OnGoAway(SpdyStreamId last_accepted_stream_id,
176 SpdyGoAwayStatus status) {
177 visitor_->OnGoAway(last_accepted_stream_id, status);
180 void BufferedSpdyFramer::OnWindowUpdate(SpdyStreamId stream_id,
181 uint32 delta_window_size) {
182 visitor_->OnWindowUpdate(stream_id, delta_window_size);
185 void BufferedSpdyFramer::OnSynStreamCompressed(
186 size_t uncompressed_size,
187 size_t compressed_size) {
188 visitor_->OnSynStreamCompressed(uncompressed_size, compressed_size);
191 int BufferedSpdyFramer::protocol_version() {
192 return spdy_framer_.protocol_version();
195 size_t BufferedSpdyFramer::ProcessInput(const char* data, size_t len) {
196 return spdy_framer_.ProcessInput(data, len);
199 void BufferedSpdyFramer::Reset() {
200 spdy_framer_.Reset();
203 SpdyFramer::SpdyError BufferedSpdyFramer::error_code() const {
204 return spdy_framer_.error_code();
207 SpdyFramer::SpdyState BufferedSpdyFramer::state() const {
208 return spdy_framer_.state();
211 bool BufferedSpdyFramer::MessageFullyRead() {
212 return state() == SpdyFramer::SPDY_AUTO_RESET;
215 bool BufferedSpdyFramer::HasError() {
216 return spdy_framer_.HasError();
219 SpdyFrame* BufferedSpdyFramer::CreateSynStream(
220 SpdyStreamId stream_id,
221 SpdyStreamId associated_stream_id,
222 SpdyPriority priority,
223 uint8 credential_slot,
224 SpdyControlFlags flags,
225 bool compressed,
226 const SpdyHeaderBlock* headers) {
227 return spdy_framer_.CreateSynStream(stream_id, associated_stream_id, priority,
228 credential_slot, flags, compressed,
229 headers);
232 SpdyFrame* BufferedSpdyFramer::CreateSynReply(
233 SpdyStreamId stream_id,
234 SpdyControlFlags flags,
235 bool compressed,
236 const SpdyHeaderBlock* headers) {
237 return spdy_framer_.CreateSynReply(stream_id, flags, compressed, headers);
240 SpdyFrame* BufferedSpdyFramer::CreateRstStream(
241 SpdyStreamId stream_id,
242 SpdyRstStreamStatus status) const {
243 return spdy_framer_.CreateRstStream(stream_id, status);
246 SpdyFrame* BufferedSpdyFramer::CreateSettings(
247 const SettingsMap& values) const {
248 return spdy_framer_.CreateSettings(values);
251 SpdyFrame* BufferedSpdyFramer::CreatePingFrame(
252 uint32 unique_id) const {
253 return spdy_framer_.CreatePingFrame(unique_id);
256 SpdyFrame* BufferedSpdyFramer::CreateGoAway(
257 SpdyStreamId last_accepted_stream_id,
258 SpdyGoAwayStatus status) const {
259 return spdy_framer_.CreateGoAway(last_accepted_stream_id, status);
262 SpdyFrame* BufferedSpdyFramer::CreateHeaders(
263 SpdyStreamId stream_id,
264 SpdyControlFlags flags,
265 bool compressed,
266 const SpdyHeaderBlock* headers) {
267 return spdy_framer_.CreateHeaders(stream_id, flags, compressed, headers);
270 SpdyFrame* BufferedSpdyFramer::CreateWindowUpdate(
271 SpdyStreamId stream_id,
272 uint32 delta_window_size) const {
273 return spdy_framer_.CreateWindowUpdate(stream_id, delta_window_size);
276 SpdyFrame* BufferedSpdyFramer::CreateCredentialFrame(
277 const SpdyCredential& credential) const {
278 return spdy_framer_.CreateCredentialFrame(credential);
281 SpdyFrame* BufferedSpdyFramer::CreateDataFrame(SpdyStreamId stream_id,
282 const char* data,
283 uint32 len,
284 SpdyDataFlags flags) {
285 return spdy_framer_.CreateDataFrame(stream_id, data, len, flags);
288 SpdyPriority BufferedSpdyFramer::GetHighestPriority() const {
289 return spdy_framer_.GetHighestPriority();
292 void BufferedSpdyFramer::InitHeaderStreaming(SpdyStreamId stream_id) {
293 memset(header_buffer_, 0, kHeaderBufferSize);
294 header_buffer_used_ = 0;
295 header_buffer_valid_ = true;
296 header_stream_id_ = stream_id;
297 DCHECK_NE(header_stream_id_, SpdyFramer::kInvalidStream);
300 } // namespace net