| Index: net/tools/quic/quic_spdy_server_stream.cc
|
| diff --git a/net/tools/quic/quic_spdy_server_stream.cc b/net/tools/quic/quic_spdy_server_stream.cc
|
| index e325fe3818ee3f55e20f2bdb799b3175a03c5e18..c1a9cf15e1809427c2f0b3608dc66e403a59871f 100644
|
| --- a/net/tools/quic/quic_spdy_server_stream.cc
|
| +++ b/net/tools/quic/quic_spdy_server_stream.cc
|
| @@ -4,10 +4,13 @@
|
|
|
| #include "net/tools/quic/quic_spdy_server_stream.h"
|
|
|
| +#include "base/memory/singleton.h"
|
| #include "net/quic/quic_session.h"
|
| #include "net/spdy/spdy_framer.h"
|
| +#include "net/tools/quic/quic_in_memory_cache.h"
|
| #include "net/tools/quic/spdy_utils.h"
|
|
|
| +using base::StringPiece;
|
| using std::string;
|
|
|
| namespace net {
|
| @@ -17,7 +20,7 @@ static const size_t kHeaderBufInitialSize = 4096;
|
|
|
| QuicSpdyServerStream::QuicSpdyServerStream(QuicStreamId id,
|
| QuicSession* session)
|
| - : QuicReliableServerStream(id, session),
|
| + : QuicDataStream(id, session),
|
| read_buf_(new GrowableIOBuffer()),
|
| request_headers_received_(false) {
|
| }
|
| @@ -38,8 +41,7 @@ uint32 QuicSpdyServerStream::ProcessData(const char* data, uint32 length) {
|
| read_buf_->set_offset(read_buf_->offset() + length);
|
| ParseRequestHeaders();
|
| } else {
|
| - mutable_body()->append(data + total_bytes_processed,
|
| - length - total_bytes_processed);
|
| + body_.append(data + total_bytes_processed, length - total_bytes_processed);
|
| }
|
| return length;
|
| }
|
| @@ -52,26 +54,15 @@ void QuicSpdyServerStream::OnFinRead() {
|
|
|
| if (!request_headers_received_) {
|
| SendErrorResponse(); // We're not done reading headers.
|
| - } else if ((headers().content_length_status() ==
|
| + } else if ((headers_.content_length_status() ==
|
| BalsaHeadersEnums::VALID_CONTENT_LENGTH) &&
|
| - mutable_body()->size() != headers().content_length()) {
|
| + body_.size() != headers_.content_length()) {
|
| SendErrorResponse(); // Invalid content length
|
| } else {
|
| SendResponse();
|
| }
|
| }
|
|
|
| -void QuicSpdyServerStream::SendHeaders(
|
| - const BalsaHeaders& response_headers) {
|
| - SpdyHeaderBlock header_block =
|
| - SpdyUtils::ResponseHeadersToSpdyHeaders(response_headers);
|
| -
|
| - string headers_string;
|
| - headers_string = session()->compressor()->CompressHeaders(header_block);
|
| -
|
| - WriteData(headers_string, false);
|
| -}
|
| -
|
| int QuicSpdyServerStream::ParseRequestHeaders() {
|
| size_t read_buf_len = static_cast<size_t>(read_buf_->offset());
|
| SpdyFramer framer(SPDY3);
|
| @@ -83,19 +74,61 @@ int QuicSpdyServerStream::ParseRequestHeaders() {
|
| return -1;
|
| }
|
|
|
| - if (!SpdyUtils::FillBalsaRequestHeaders(headers, mutable_headers())) {
|
| + if (!SpdyUtils::FillBalsaRequestHeaders(headers, &headers_)) {
|
| SendErrorResponse();
|
| return -1;
|
| }
|
|
|
| size_t delta = read_buf_len - len;
|
| if (delta > 0) {
|
| - mutable_body()->append(data + len, delta);
|
| + body_.append(data + len, delta);
|
| }
|
|
|
| request_headers_received_ = true;
|
| return len;
|
| }
|
|
|
| +void QuicSpdyServerStream::SendResponse() {
|
| + // Find response in cache. If not found, send error response.
|
| + const QuicInMemoryCache::Response* response =
|
| + QuicInMemoryCache::GetInstance()->GetResponse(headers_);
|
| + if (response == NULL) {
|
| + SendErrorResponse();
|
| + return;
|
| + }
|
| +
|
| + DLOG(INFO) << "Sending response for stream " << id();
|
| + SendHeadersAndBody(response->headers(), response->body());
|
| +}
|
| +
|
| +void QuicSpdyServerStream::SendErrorResponse() {
|
| + DLOG(INFO) << "Sending error response for stream " << id();
|
| + BalsaHeaders headers;
|
| + headers.SetResponseFirstlineFromStringPieces(
|
| + "HTTP/1.1", "500", "Server Error");
|
| + headers.ReplaceOrAppendHeader("content-length", "3");
|
| + SendHeadersAndBody(headers, "bad");
|
| +}
|
| +
|
| +void QuicSpdyServerStream:: SendHeadersAndBody(
|
| + const BalsaHeaders& response_headers,
|
| + StringPiece body) {
|
| + // We only support SPDY and HTTP, and neither handles bidirectional streaming.
|
| + if (!read_side_closed()) {
|
| + CloseReadSide();
|
| + }
|
| +
|
| + SpdyHeaderBlock header_block =
|
| + SpdyUtils::ResponseHeadersToSpdyHeaders(response_headers);
|
| +
|
| + string headers_string =
|
| + session()->compressor()->CompressHeaders(header_block);
|
| + WriteOrBufferData(headers_string, body.empty());
|
| +
|
| + if (!body.empty()) {
|
| + WriteOrBufferData(body, true);
|
| + }
|
| +}
|
| +
|
| } // namespace tools
|
| } // namespace net
|
|
|