quic_http_stream.cc revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/quic_http_stream.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/callback_helpers.h"
85e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/io_buffer.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/net_errors.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/http/http_response_headers.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/http/http_util.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/quic_client_session.h"
14d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "net/quic/quic_http_utils.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/quic_reliable_client_stream.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/quic_utils.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/socket/next_proto.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_frame_builder.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_framer.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_http_utils.h"
217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "net/ssl/ssl_info.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace net {
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const size_t kHeaderBufInitialSize = 4096;
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)QuicHttpStream::QuicHttpStream(const base::WeakPtr<QuicClientSession> session)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : next_state_(STATE_NONE),
29a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      session_(session),
30a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      stream_(NULL),
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      request_info_(NULL),
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      request_body_stream_(NULL),
33d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      priority_(MINIMUM_PRIORITY),
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      response_info_(NULL),
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      response_status_(OK),
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      response_headers_received_(false),
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      read_buf_(new GrowableIOBuffer()),
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      user_buffer_len_(0),
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_factory_(this) {
40a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(session_);
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)QuicHttpStream::~QuicHttpStream() {
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Close(false);
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int QuicHttpStream::InitializeStream(const HttpRequestInfo* request_info,
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     RequestPriority priority,
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     const BoundNetLog& stream_net_log,
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     const CompletionCallback& callback) {
51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(!stream_);
52a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!session_)
53a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return ERR_CONNECTION_CLOSED;
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stream_net_log_ = stream_net_log;
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request_info_ = request_info;
57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  priority_ = priority;
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
59a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  int rv = stream_request_.StartRequest(
60a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      session_, &stream_, base::Bind(&QuicHttpStream::OnStreamReady,
61a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                     weak_factory_.GetWeakPtr()));
62a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
63a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    callback_ = callback;
64a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
65a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (rv == OK)
66a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    stream_->SetDelegate(this);
67a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
68a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return rv;
69a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
70a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
71a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void QuicHttpStream::OnStreamReady(int rv) {
72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(rv == OK || !stream_);
73a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (rv == OK)
74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    stream_->SetDelegate(this);
75a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ResetAndReturn(&callback_).Run(rv);
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int QuicHttpStream::SendRequest(const HttpRequestHeaders& request_headers,
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                HttpResponseInfo* response,
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                const CompletionCallback& callback) {
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(stream_);
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(!request_body_stream_);
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(!response_info_);
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(!callback.is_null());
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(response);
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  QuicPriority priority = ConvertRequestPriorityToQuicPriority(priority_);
89d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  stream_->set_priority(priority);
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Store the serialized request headers.
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyHeaderBlock headers;
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CreateSpdyHeadersFromHttpRequest(*request_info_, request_headers,
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   &headers, 3, /*direct=*/true);
94424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (session_->connection()->version() < QUIC_VERSION_9) {
95424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    request_ = stream_->compressor()->CompressHeaders(headers);
96424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  } else {
97d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    request_ = stream_->compressor()->CompressHeadersWithPriority(priority,
98d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                                                  headers);
99424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Log the actual request with the URL Request's net log.
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stream_net_log_.AddEvent(
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_SPDY_SEND_REQUEST_HEADERS,
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&SpdyHeaderBlockNetLogCallback, &headers));
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Also log to the QuicSession's net log.
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stream_->net_log().AddEvent(
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NetLog::TYPE_QUIC_HTTP_STREAM_SEND_REQUEST_HEADERS,
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&SpdyHeaderBlockNetLogCallback, &headers));
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Store the request body.
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request_body_stream_ = request_info_->upload_data_stream;
1117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (request_body_stream_) {
1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // TODO(rch): Can we be more precise about when to allocate
1137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // raw_request_body_buf_. Removed the following check. DoReadRequestBody()
1147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // was being called even if we didn't yet allocate raw_request_body_buf_.
1157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    //   && (request_body_stream_->size() ||
1167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    //       request_body_stream_->is_chunked()))
1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    //
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Use kMaxPacketSize as the buffer size, since the request
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // body data is written with this size at a time.
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(rch): use a smarter value since we can't write an entire
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // packet due to overhead.
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    raw_request_body_buf_ = new IOBufferWithSize(kMaxPacketSize);
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The request body buffer is empty at first.
124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    request_body_buf_ = new DrainableIOBuffer(raw_request_body_buf_.get(), 0);
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Store the response info.
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_info_ = response;
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  next_state_ = STATE_SEND_HEADERS;
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = DoLoop(OK);
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rv == ERR_IO_PENDING)
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback_ = callback;
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return rv > 0 ? OK : rv;
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)UploadProgress QuicHttpStream::GetUploadProgress() const {
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!request_body_stream_)
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return UploadProgress();
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return UploadProgress(request_body_stream_->position(),
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        request_body_stream_->size());
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int QuicHttpStream::ReadResponseHeaders(const CompletionCallback& callback) {
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(!callback.is_null());
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (stream_ == NULL)
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return response_status_;
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check if we already have the response headers. If so, return synchronously.
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (response_headers_received_)
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return OK;
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Still waiting for the response, return IO_PENDING.
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(callback_.is_null());
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback_ = callback;
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ERR_IO_PENDING;
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const HttpResponseInfo* QuicHttpStream::GetResponseInfo() const {
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return response_info_;
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int QuicHttpStream::ReadResponseBody(
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IOBuffer* buf, int buf_len, const CompletionCallback& callback) {
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(buf);
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(buf_len);
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(!callback.is_null());
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we have data buffered, complete the IO immediately.
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!response_body_.empty()) {
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int bytes_read = 0;
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    while (!response_body_.empty() && buf_len > 0) {
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scoped_refptr<IOBufferWithSize> data = response_body_.front();
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const int bytes_to_copy = std::min(buf_len, data->size());
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      memcpy(&(buf->data()[bytes_read]), data->data(), bytes_to_copy);
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      buf_len -= bytes_to_copy;
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (bytes_to_copy == data->size()) {
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        response_body_.pop_front();
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      } else {
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        const int bytes_remaining = data->size() - bytes_to_copy;
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IOBufferWithSize* new_buffer = new IOBufferWithSize(bytes_remaining);
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        memcpy(new_buffer->data(), &(data->data()[bytes_to_copy]),
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               bytes_remaining);
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        response_body_.pop_front();
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        response_body_.push_front(make_scoped_refptr(new_buffer));
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bytes_read += bytes_to_copy;
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return bytes_read;
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!stream_) {
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // If the stream is already closed, there is no body to read.
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return response_status_;
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(callback_.is_null());
201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CHECK(!user_buffer_.get());
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK_EQ(0, user_buffer_len_);
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback_ = callback;
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  user_buffer_ = buf;
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  user_buffer_len_ = buf_len;
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ERR_IO_PENDING;
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicHttpStream::Close(bool not_reusable) {
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Note: the not_reusable flag has no meaning for SPDY streams.
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (stream_) {
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stream_->SetDelegate(NULL);
214424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // TODO(rch): use new CANCELLED error code here once quic 11
215424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // is everywhere.
216d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    stream_->Close(QUIC_ERROR_PROCESSING_STREAM);
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stream_ = NULL;
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HttpStream* QuicHttpStream::RenewStreamForAuth() {
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return NULL;
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicHttpStream::IsResponseBodyComplete() const {
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return next_state_ == STATE_OPEN && !stream_;
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicHttpStream::CanFindEndOfResponse() const {
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicHttpStream::IsConnectionReused() const {
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(rch): do something smarter here.
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return stream_ && stream_->id() > 1;
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicHttpStream::SetConnectionReused() {
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // QUIC doesn't need an indicator here.
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicHttpStream::IsConnectionReusable() const {
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // QUIC streams aren't considered reusable.
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicHttpStream::GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const {
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(mmenke):  Figure out what to do here.
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicHttpStream::GetSSLInfo(SSLInfo* ssl_info) {
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(stream_);
2547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  stream_->GetSSLInfo(ssl_info);
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicHttpStream::GetSSLCertRequestInfo(
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SSLCertRequestInfo* cert_request_info) {
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(stream_);
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NOTIMPLEMENTED();
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicHttpStream::IsSpdyHttpStream() const {
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicHttpStream::Drain(HttpNetworkSession* session) {
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Close(false);
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delete this;
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void QuicHttpStream::SetPriority(RequestPriority priority) {
273d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  priority_ = priority;
2743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int QuicHttpStream::OnSendData() {
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(rch): Change QUIC IO to provide notifications to the streams.
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NOTREACHED();
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return OK;
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int QuicHttpStream::OnSendDataComplete(int status, bool* eof) {
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(rch): Change QUIC IO to provide notifications to the streams.
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NOTREACHED();
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return OK;
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int QuicHttpStream::OnDataReceived(const char* data, int length) {
289eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK_NE(0, length);
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Are we still reading the response headers.
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!response_headers_received_) {
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Grow the read buffer if necessary.
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (read_buf_->RemainingCapacity() < length) {
29458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      size_t additional_capacity = length - read_buf_->RemainingCapacity();
29558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      if (additional_capacity < kHeaderBufInitialSize)
29658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        additional_capacity = kHeaderBufInitialSize;
29758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      read_buf_->SetCapacity(read_buf_->capacity() + additional_capacity);
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    memcpy(read_buf_->data(), data, length);
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    read_buf_->set_offset(read_buf_->offset() + length);
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int rv = ParseResponseHeaders();
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (rv != ERR_IO_PENDING && !callback_.is_null()) {
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DoCallback(rv);
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return OK;
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (callback_.is_null()) {
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BufferResponseBody(data, length);
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return OK;
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (length <= user_buffer_len_) {
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    memcpy(user_buffer_->data(), data, length);
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    memcpy(user_buffer_->data(), data, user_buffer_len_);
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int delta = length - user_buffer_len_;
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BufferResponseBody(data + user_buffer_len_, delta);
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  user_buffer_ = NULL;
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  user_buffer_len_ = 0;
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DoCallback(length);
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return OK;
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicHttpStream::OnClose(QuicErrorCode error) {
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (error != QUIC_NO_ERROR) {
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    response_status_ = ERR_QUIC_PROTOCOL_ERROR;
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (!response_headers_received_) {
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    response_status_ = ERR_ABORTED;
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stream_ = NULL;
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!callback_.is_null())
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DoCallback(response_status_);
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicHttpStream::OnError(int error) {
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stream_ = NULL;
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_status_ = error;
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!callback_.is_null())
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DoCallback(response_status_);
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
345d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool QuicHttpStream::HasSendHeadersComplete() {
346d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return next_state_ > STATE_SEND_HEADERS_COMPLETE;
347d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
348d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicHttpStream::OnIOComplete(int rv) {
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = DoLoop(rv);
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rv != ERR_IO_PENDING && !callback_.is_null()) {
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DoCallback(rv);
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicHttpStream::DoCallback(int rv) {
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK_NE(rv, ERR_IO_PENDING);
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(!callback_.is_null());
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The client callback can do anything, including destroying this class,
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // so any pending callback must be issued after everything else is done.
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ResetAndReturn(&callback_).Run(rv);
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int QuicHttpStream::DoLoop(int rv) {
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  do {
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    State state = next_state_;
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    next_state_ = STATE_NONE;
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    switch (state) {
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STATE_SEND_HEADERS:
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CHECK_EQ(OK, rv);
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rv = DoSendHeaders();
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STATE_SEND_HEADERS_COMPLETE:
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rv = DoSendHeadersComplete(rv);
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STATE_READ_REQUEST_BODY:
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CHECK_EQ(OK, rv);
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rv = DoReadRequestBody();
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STATE_READ_REQUEST_BODY_COMPLETE:
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rv = DoReadRequestBodyComplete(rv);
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STATE_SEND_BODY:
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CHECK_EQ(OK, rv);
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rv = DoSendBody();
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STATE_SEND_BODY_COMPLETE:
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rv = DoSendBodyComplete(rv);
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STATE_OPEN:
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CHECK_EQ(OK, rv);
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      default:
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        NOTREACHED() << "next_state_: " << next_state_;
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } while (next_state_ != STATE_NONE && next_state_ != STATE_OPEN &&
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           rv != ERR_IO_PENDING);
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return rv;
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int QuicHttpStream::DoSendHeaders() {
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!stream_)
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return ERR_UNEXPECTED;
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool has_upload_data = request_body_stream_ != NULL;
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  next_state_ = STATE_SEND_HEADERS_COMPLETE;
41258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return stream_->WriteStreamData(
41358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      request_, !has_upload_data,
41458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::Bind(&QuicHttpStream::OnIOComplete, weak_factory_.GetWeakPtr()));
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int QuicHttpStream::DoSendHeadersComplete(int rv) {
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rv < 0)
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return rv;
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  next_state_ = request_body_stream_ ?
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      STATE_READ_REQUEST_BODY : STATE_OPEN;
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return OK;
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int QuicHttpStream::DoReadRequestBody() {
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  next_state_ = STATE_READ_REQUEST_BODY_COMPLETE;
429868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return request_body_stream_->Read(
430868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      raw_request_body_buf_.get(),
431868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      raw_request_body_buf_->size(),
432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(&QuicHttpStream::OnIOComplete, weak_factory_.GetWeakPtr()));
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int QuicHttpStream::DoReadRequestBodyComplete(int rv) {
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |rv| is the result of read from the request body from the last call to
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // DoSendBody().
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rv < 0)
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return rv;
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
441868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  request_body_buf_ = new DrainableIOBuffer(raw_request_body_buf_.get(), rv);
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rv == 0) {  // Reached the end.
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(request_body_stream_->IsEOF());
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  next_state_ = STATE_SEND_BODY;
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return OK;
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int QuicHttpStream::DoSendBody() {
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!stream_)
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return ERR_UNEXPECTED;
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(request_body_stream_);
455868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CHECK(request_body_buf_.get());
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const bool eof = request_body_stream_->IsEOF();
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int len = request_body_buf_->BytesRemaining();
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (len > 0 || eof) {
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    next_state_ = STATE_SEND_BODY_COMPLETE;
46058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    base::StringPiece data(request_body_buf_->data(), len);
46158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return stream_->WriteStreamData(
46258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        data, eof,
46358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        base::Bind(&QuicHttpStream::OnIOComplete, weak_factory_.GetWeakPtr()));
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
46658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  next_state_ = STATE_OPEN;
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return OK;
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int QuicHttpStream::DoSendBodyComplete(int rv) {
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rv < 0)
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return rv;
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
47458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request_body_buf_->DidConsume(request_body_buf_->BytesRemaining());
47558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
47658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!request_body_stream_->IsEOF()) {
47758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    next_state_ = STATE_READ_REQUEST_BODY;
47858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return OK;
47958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
48058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
48158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  next_state_ = STATE_OPEN;
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return OK;
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int QuicHttpStream::ParseResponseHeaders() {
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t read_buf_len = static_cast<size_t>(read_buf_->offset());
48790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SpdyFramer framer(SPDY3);
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyHeaderBlock headers;
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  char* data = read_buf_->StartOfBuffer();
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t len = framer.ParseHeaderBlockInBuffer(data, read_buf_->offset(),
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               &headers);
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (len == 0) {
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return ERR_IO_PENDING;
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Save the remaining received data.
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t delta = read_buf_len - len;
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (delta > 0) {
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BufferResponseBody(data + len, delta);
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The URLRequest logs these headers, so only log to the QuicSession's
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // net log.
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stream_->net_log().AddEvent(
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NetLog::TYPE_QUIC_HTTP_STREAM_READ_RESPONSE_HEADERS,
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&SpdyHeaderBlockNetLogCallback, &headers));
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!SpdyHeadersToHttpResponse(headers, 3, response_info_)) {
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DLOG(WARNING) << "Invalid headers";
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return ERR_QUIC_PROTOCOL_ERROR;
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Put the peer's IP address and port into the response.
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  IPEndPoint address = stream_->GetPeerAddress();
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_info_->socket_address = HostPortPair::FromIPEndPoint(address);
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_info_->connection_info =
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      HttpResponseInfo::CONNECTION_INFO_QUIC1_SPDY3;
518868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  response_info_->vary_data
519868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      .Init(*request_info_, *response_info_->headers.get());
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_info_->was_npn_negotiated = true;
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_info_->npn_negotiated_protocol = "quic/1+spdy/3";
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_headers_received_ = true;
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return OK;
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicHttpStream::BufferResponseBody(const char* data, int length) {
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (length == 0)
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  IOBufferWithSize* io_buffer = new IOBufferWithSize(length);
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  memcpy(io_buffer->data(), data, length);
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_body_.push_back(make_scoped_refptr(io_buffer));
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace net
536