Windows should animate when they are about to get docked at screen edges.
[chromium-blink-merge.git] / net / tools / quic / quic_spdy_server_stream.cc
blobd6f3b7590ff50a1f366eada85b0cb6354a3a56d5
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/tools/quic/quic_spdy_server_stream.h"
7 #include "net/quic/quic_session.h"
8 #include "net/spdy/spdy_framer.h"
9 #include "net/tools/quic/spdy_utils.h"
11 using std::string;
13 namespace net {
14 namespace tools {
16 static const size_t kHeaderBufInitialSize = 4096;
18 QuicSpdyServerStream::QuicSpdyServerStream(QuicStreamId id,
19 QuicSession* session)
20 : QuicReliableServerStream(id, session),
21 read_buf_(new GrowableIOBuffer()),
22 request_headers_received_(false) {
25 QuicSpdyServerStream::~QuicSpdyServerStream() {
28 uint32 QuicSpdyServerStream::ProcessData(const char* data, uint32 length) {
29 uint32 total_bytes_processed = 0;
31 // Are we still reading the request headers.
32 if (!request_headers_received_) {
33 // Grow the read buffer if necessary.
34 if (read_buf_->RemainingCapacity() < (int)length) {
35 read_buf_->SetCapacity(read_buf_->capacity() + kHeaderBufInitialSize);
37 memcpy(read_buf_->data(), data, length);
38 read_buf_->set_offset(read_buf_->offset() + length);
39 ParseRequestHeaders();
40 } else {
41 mutable_body()->append(data + total_bytes_processed,
42 length - total_bytes_processed);
44 return length;
47 void QuicSpdyServerStream::TerminateFromPeer(bool half_close) {
48 ReliableQuicStream::TerminateFromPeer(half_close);
49 // This is a full close: do not send a response.
50 if (!half_close) {
51 return;
53 if (write_side_closed() || fin_buffered()) {
54 return;
57 if (!request_headers_received_) {
58 SendErrorResponse(); // We're not done writing headers.
59 } else if ((headers().content_length_status() ==
60 BalsaHeadersEnums::VALID_CONTENT_LENGTH) &&
61 mutable_body()->size() != headers().content_length()) {
62 SendErrorResponse(); // Invalid content length
63 } else {
64 SendResponse();
68 void QuicSpdyServerStream::SendHeaders(
69 const BalsaHeaders& response_headers) {
70 SpdyHeaderBlock header_block =
71 SpdyUtils::ResponseHeadersToSpdyHeaders(response_headers);
72 string headers =
73 session()->compressor()->CompressHeaders(header_block);
75 WriteData(headers, false);
78 int QuicSpdyServerStream::ParseRequestHeaders() {
79 size_t read_buf_len = static_cast<size_t>(read_buf_->offset());
80 SpdyFramer framer(SPDY3);
81 SpdyHeaderBlock headers;
82 char* data = read_buf_->StartOfBuffer();
83 size_t len = framer.ParseHeaderBlockInBuffer(data, read_buf_->offset(),
84 &headers);
85 if (len == 0) {
86 return -1;
89 if (!SpdyUtils::FillBalsaRequestHeaders(headers, mutable_headers())) {
90 SendErrorResponse();
91 return -1;
94 size_t delta = read_buf_len - len;
95 if (delta > 0) {
96 mutable_body()->append(data + len, delta);
99 request_headers_received_ = true;
100 return len;
103 } // namespace tools
104 } // namespace net