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"
8effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/metrics/histogram.h"
95e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/io_buffer.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/net_errors.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/http/http_response_headers.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/http/http_util.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/quic_client_session.h"
15d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "net/quic/quic_http_utils.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/quic_reliable_client_stream.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/quic_utils.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/socket/next_proto.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_frame_builder.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_framer.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_http_utils.h"
227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "net/ssl/ssl_info.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace net {
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const size_t kHeaderBufInitialSize = 4096;
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)QuicHttpStream::QuicHttpStream(const base::WeakPtr<QuicClientSession>& session)
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : next_state_(STATE_NONE),
30a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      session_(session),
318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      session_error_(OK),
328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      was_handshake_confirmed_(session->IsCryptoHandshakeConfirmed()),
33a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      stream_(NULL),
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      request_info_(NULL),
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      request_body_stream_(NULL),
36d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      priority_(MINIMUM_PRIORITY),
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      response_info_(NULL),
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      response_status_(OK),
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      response_headers_received_(false),
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      read_buf_(new GrowableIOBuffer()),
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      closed_stream_received_bytes_(0),
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      user_buffer_len_(0),
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_factory_(this) {
44a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(session_);
458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  session_->AddObserver(this);
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)QuicHttpStream::~QuicHttpStream() {
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Close(false);
508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (session_)
518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    session_->RemoveObserver(this);
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int QuicHttpStream::InitializeStream(const HttpRequestInfo* request_info,
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     RequestPriority priority,
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     const BoundNetLog& stream_net_log,
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     const CompletionCallback& callback) {
58a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(!stream_);
59a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!session_)
608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return was_handshake_confirmed_ ? ERR_CONNECTION_CLOSED :
618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        ERR_QUIC_HANDSHAKE_FAILED;
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (request_info->url.SchemeIsSecure()) {
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    SSLInfo ssl_info;
65effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    bool secure_session = session_->GetSSLInfo(&ssl_info) && ssl_info.cert;
66effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.SecureResourceSecureSession",
67effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                          secure_session);
68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    if (!secure_session)
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return ERR_REQUEST_FOR_SECURE_RESOURCE_OVER_INSECURE_QUIC;
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stream_net_log_ = stream_net_log;
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request_info_ = request_info;
742f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  request_time_ = base::Time::Now();
75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  priority_ = priority;
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  int rv = stream_request_.StartRequest(
78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      session_, &stream_, base::Bind(&QuicHttpStream::OnStreamReady,
79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                     weak_factory_.GetWeakPtr()));
808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (rv == ERR_IO_PENDING) {
81a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    callback_ = callback;
828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  } else if (rv == OK) {
83a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    stream_->SetDelegate(this);
848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  } else if (!was_handshake_confirmed_) {
858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    rv = ERR_QUIC_HANDSHAKE_FAILED;
868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
87a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return rv;
89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
90a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
91a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void QuicHttpStream::OnStreamReady(int rv) {
92a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(rv == OK || !stream_);
938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (rv == OK) {
94a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    stream_->SetDelegate(this);
958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  } else if (!was_handshake_confirmed_) {
968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    rv = ERR_QUIC_HANDSHAKE_FAILED;
978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
99a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ResetAndReturn(&callback_).Run(rv);
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int QuicHttpStream::SendRequest(const HttpRequestHeaders& request_headers,
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                HttpResponseInfo* response,
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                const CompletionCallback& callback) {
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(stream_);
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(!request_body_stream_);
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(!response_info_);
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(!callback.is_null());
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(response);
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
111d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  QuicPriority priority = ConvertRequestPriorityToQuicPriority(priority_);
112d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  stream_->set_priority(priority);
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Store the serialized request headers.
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CreateSpdyHeadersFromHttpRequest(*request_info_, request_headers,
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                   &request_headers_, SPDY3, /*direct=*/true);
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Store the request body.
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request_body_stream_ = request_info_->upload_data_stream;
1197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (request_body_stream_) {
1207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // TODO(rch): Can we be more precise about when to allocate
1217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // raw_request_body_buf_. Removed the following check. DoReadRequestBody()
1227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // was being called even if we didn't yet allocate raw_request_body_buf_.
1237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    //   && (request_body_stream_->size() ||
1247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    //       request_body_stream_->is_chunked()))
1256d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // Use 10 packets as the body buffer size to give enough space to
1266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // help ensure we don't often send out partial packets.
1276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    raw_request_body_buf_ = new IOBufferWithSize(10 * kMaxPacketSize);
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The request body buffer is empty at first.
129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    request_body_buf_ = new DrainableIOBuffer(raw_request_body_buf_.get(), 0);
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Store the response info.
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_info_ = response;
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  next_state_ = STATE_SEND_HEADERS;
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = DoLoop(OK);
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rv == ERR_IO_PENDING)
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback_ = callback;
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return rv > 0 ? OK : rv;
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)UploadProgress QuicHttpStream::GetUploadProgress() const {
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!request_body_stream_)
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return UploadProgress();
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return UploadProgress(request_body_stream_->position(),
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        request_body_stream_->size());
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int QuicHttpStream::ReadResponseHeaders(const CompletionCallback& callback) {
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(!callback.is_null());
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (stream_ == NULL)
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return response_status_;
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check if we already have the response headers. If so, return synchronously.
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (response_headers_received_)
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return OK;
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Still waiting for the response, return IO_PENDING.
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(callback_.is_null());
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback_ = callback;
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ERR_IO_PENDING;
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int QuicHttpStream::ReadResponseBody(
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IOBuffer* buf, int buf_len, const CompletionCallback& callback) {
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(buf);
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(buf_len);
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(!callback.is_null());
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we have data buffered, complete the IO immediately.
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!response_body_.empty()) {
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int bytes_read = 0;
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    while (!response_body_.empty() && buf_len > 0) {
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scoped_refptr<IOBufferWithSize> data = response_body_.front();
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const int bytes_to_copy = std::min(buf_len, data->size());
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      memcpy(&(buf->data()[bytes_read]), data->data(), bytes_to_copy);
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      buf_len -= bytes_to_copy;
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (bytes_to_copy == data->size()) {
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        response_body_.pop_front();
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      } else {
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        const int bytes_remaining = data->size() - bytes_to_copy;
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IOBufferWithSize* new_buffer = new IOBufferWithSize(bytes_remaining);
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        memcpy(new_buffer->data(), &(data->data()[bytes_to_copy]),
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               bytes_remaining);
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        response_body_.pop_front();
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        response_body_.push_front(make_scoped_refptr(new_buffer));
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bytes_read += bytes_to_copy;
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return bytes_read;
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!stream_) {
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // If the stream is already closed, there is no body to read.
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return response_status_;
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(callback_.is_null());
202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CHECK(!user_buffer_.get());
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK_EQ(0, user_buffer_len_);
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback_ = callback;
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  user_buffer_ = buf;
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  user_buffer_len_ = buf_len;
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ERR_IO_PENDING;
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicHttpStream::Close(bool not_reusable) {
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Note: the not_reusable flag has no meaning for SPDY streams.
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (stream_) {
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    closed_stream_received_bytes_ = stream_->stream_bytes_read();
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stream_->SetDelegate(NULL);
216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    stream_->Reset(QUIC_STREAM_CANCELLED);
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)
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int64 QuicHttpStream::GetTotalReceivedBytes() const {
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (stream_) {
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return stream_->stream_bytes_read();
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return closed_stream_received_bytes_;
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicHttpStream::GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const {
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(mmenke):  Figure out what to do here.
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicHttpStream::GetSSLInfo(SSLInfo* ssl_info) {
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(stream_);
2627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  stream_->GetSSLInfo(ssl_info);
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicHttpStream::GetSSLCertRequestInfo(
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SSLCertRequestInfo* cert_request_info) {
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(stream_);
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NOTIMPLEMENTED();
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicHttpStream::IsSpdyHttpStream() const {
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicHttpStream::Drain(HttpNetworkSession* session) {
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Close(false);
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delete this;
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void QuicHttpStream::SetPriority(RequestPriority priority) {
281d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  priority_ = priority;
2823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int QuicHttpStream::OnDataReceived(const char* data, int length) {
285eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK_NE(0, length);
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Are we still reading the response headers.
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!response_headers_received_) {
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Grow the read buffer if necessary.
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (read_buf_->RemainingCapacity() < length) {
29058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      size_t additional_capacity = length - read_buf_->RemainingCapacity();
29158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      if (additional_capacity < kHeaderBufInitialSize)
29258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        additional_capacity = kHeaderBufInitialSize;
29358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      read_buf_->SetCapacity(read_buf_->capacity() + additional_capacity);
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    memcpy(read_buf_->data(), data, length);
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    read_buf_->set_offset(read_buf_->offset() + length);
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int rv = ParseResponseHeaders();
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (rv != ERR_IO_PENDING && !callback_.is_null()) {
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DoCallback(rv);
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return OK;
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (callback_.is_null()) {
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BufferResponseBody(data, length);
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return OK;
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (length <= user_buffer_len_) {
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    memcpy(user_buffer_->data(), data, length);
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    memcpy(user_buffer_->data(), data, user_buffer_len_);
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int delta = length - user_buffer_len_;
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BufferResponseBody(data + user_buffer_len_, delta);
3154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    length = user_buffer_len_;
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  user_buffer_ = NULL;
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  user_buffer_len_ = 0;
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DoCallback(length);
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return OK;
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicHttpStream::OnClose(QuicErrorCode error) {
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (error != QUIC_NO_ERROR) {
3268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    response_status_ = was_handshake_confirmed_ ?
3278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        ERR_QUIC_PROTOCOL_ERROR : ERR_QUIC_HANDSHAKE_FAILED;
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (!response_headers_received_) {
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    response_status_ = ERR_ABORTED;
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  closed_stream_received_bytes_ = stream_->stream_bytes_read();
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;
3408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  response_status_ = was_handshake_confirmed_ ?
3418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      error : ERR_QUIC_HANDSHAKE_FAILED;
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!callback_.is_null())
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DoCallback(response_status_);
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
346d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool QuicHttpStream::HasSendHeadersComplete() {
347d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return next_state_ > STATE_SEND_HEADERS_COMPLETE;
348d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
349d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
3508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void QuicHttpStream::OnCryptoHandshakeConfirmed() {
3518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  was_handshake_confirmed_ = true;
3528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void QuicHttpStream::OnSessionClosed(int error) {
3558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  session_error_ = error;
3568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  session_.reset();
3578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicHttpStream::OnIOComplete(int rv) {
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = DoLoop(rv);
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rv != ERR_IO_PENDING && !callback_.is_null()) {
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DoCallback(rv);
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicHttpStream::DoCallback(int rv) {
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK_NE(rv, ERR_IO_PENDING);
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(!callback_.is_null());
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The client callback can do anything, including destroying this class,
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // so any pending callback must be issued after everything else is done.
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ResetAndReturn(&callback_).Run(rv);
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int QuicHttpStream::DoLoop(int rv) {
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  do {
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    State state = next_state_;
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    next_state_ = STATE_NONE;
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    switch (state) {
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STATE_SEND_HEADERS:
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CHECK_EQ(OK, rv);
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rv = DoSendHeaders();
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STATE_SEND_HEADERS_COMPLETE:
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rv = DoSendHeadersComplete(rv);
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STATE_READ_REQUEST_BODY:
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CHECK_EQ(OK, rv);
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rv = DoReadRequestBody();
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STATE_READ_REQUEST_BODY_COMPLETE:
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rv = DoReadRequestBodyComplete(rv);
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STATE_SEND_BODY:
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CHECK_EQ(OK, rv);
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rv = DoSendBody();
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STATE_SEND_BODY_COMPLETE:
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rv = DoSendBodyComplete(rv);
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STATE_OPEN:
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CHECK_EQ(OK, rv);
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      default:
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        NOTREACHED() << "next_state_: " << next_state_;
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } while (next_state_ != STATE_NONE && next_state_ != STATE_OPEN &&
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           rv != ERR_IO_PENDING);
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return rv;
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int QuicHttpStream::DoSendHeaders() {
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!stream_)
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return ERR_UNEXPECTED;
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Log the actual request with the URL Request's net log.
420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  stream_net_log_.AddEvent(
4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_QUIC_SEND_REQUEST_HEADERS,
4220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      base::Bind(&QuicRequestNetLogCallback, stream_->id(), &request_headers_,
4230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 priority_));
424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Also log to the QuicSession's net log.
425f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  stream_->net_log().AddEvent(
426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      NetLog::TYPE_QUIC_HTTP_STREAM_SEND_REQUEST_HEADERS,
4270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      base::Bind(&QuicRequestNetLogCallback, stream_->id(), &request_headers_,
4280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 priority_));
429f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool has_upload_data = request_body_stream_ != NULL;
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  next_state_ = STATE_SEND_HEADERS_COMPLETE;
43323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  int rv = stream_->WriteHeaders(request_headers_, !has_upload_data, NULL);
4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request_headers_.clear();
4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return rv;
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int QuicHttpStream::DoSendHeadersComplete(int rv) {
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rv < 0)
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return rv;
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  next_state_ = request_body_stream_ ?
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      STATE_READ_REQUEST_BODY : STATE_OPEN;
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return OK;
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int QuicHttpStream::DoReadRequestBody() {
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  next_state_ = STATE_READ_REQUEST_BODY_COMPLETE;
450868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return request_body_stream_->Read(
451868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      raw_request_body_buf_.get(),
452868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      raw_request_body_buf_->size(),
453868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(&QuicHttpStream::OnIOComplete, weak_factory_.GetWeakPtr()));
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int QuicHttpStream::DoReadRequestBodyComplete(int rv) {
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |rv| is the result of read from the request body from the last call to
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // DoSendBody().
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rv < 0)
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return rv;
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
462868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  request_body_buf_ = new DrainableIOBuffer(raw_request_body_buf_.get(), rv);
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rv == 0) {  // Reached the end.
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(request_body_stream_->IsEOF());
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  next_state_ = STATE_SEND_BODY;
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return OK;
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int QuicHttpStream::DoSendBody() {
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!stream_)
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return ERR_UNEXPECTED;
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(request_body_stream_);
476868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CHECK(request_body_buf_.get());
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const bool eof = request_body_stream_->IsEOF();
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int len = request_body_buf_->BytesRemaining();
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (len > 0 || eof) {
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    next_state_ = STATE_SEND_BODY_COMPLETE;
48158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    base::StringPiece data(request_body_buf_->data(), len);
48258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return stream_->WriteStreamData(
48358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        data, eof,
48458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        base::Bind(&QuicHttpStream::OnIOComplete, weak_factory_.GetWeakPtr()));
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
48758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  next_state_ = STATE_OPEN;
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return OK;
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int QuicHttpStream::DoSendBodyComplete(int rv) {
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rv < 0)
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return rv;
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
49558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request_body_buf_->DidConsume(request_body_buf_->BytesRemaining());
49658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
49758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!request_body_stream_->IsEOF()) {
49858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    next_state_ = STATE_READ_REQUEST_BODY;
49958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return OK;
50058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
50158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
50258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  next_state_ = STATE_OPEN;
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return OK;
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int QuicHttpStream::ParseResponseHeaders() {
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t read_buf_len = static_cast<size_t>(read_buf_->offset());
50890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SpdyFramer framer(SPDY3);
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyHeaderBlock headers;
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  char* data = read_buf_->StartOfBuffer();
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t len = framer.ParseHeaderBlockInBuffer(data, read_buf_->offset(),
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               &headers);
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (len == 0) {
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return ERR_IO_PENDING;
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Save the remaining received data.
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t delta = read_buf_len - len;
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (delta > 0) {
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BufferResponseBody(data + len, delta);
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The URLRequest logs these headers, so only log to the QuicSession's
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // net log.
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stream_->net_log().AddEvent(
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NetLog::TYPE_QUIC_HTTP_STREAM_READ_RESPONSE_HEADERS,
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&SpdyHeaderBlockNetLogCallback, &headers));
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
530f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!SpdyHeadersToHttpResponse(headers, SPDY3, response_info_)) {
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DLOG(WARNING) << "Invalid headers";
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return ERR_QUIC_PROTOCOL_ERROR;
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Put the peer's IP address and port into the response.
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  IPEndPoint address = stream_->GetPeerAddress();
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_info_->socket_address = HostPortPair::FromIPEndPoint(address);
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_info_->connection_info =
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      HttpResponseInfo::CONNECTION_INFO_QUIC1_SPDY3;
539868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  response_info_->vary_data
540868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      .Init(*request_info_, *response_info_->headers.get());
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_info_->was_npn_negotiated = true;
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_info_->npn_negotiated_protocol = "quic/1+spdy/3";
5432f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  response_info_->response_time = base::Time::Now();
5442f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  response_info_->request_time = request_time_;
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_headers_received_ = true;
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return OK;
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicHttpStream::BufferResponseBody(const char* data, int length) {
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (length == 0)
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  IOBufferWithSize* io_buffer = new IOBufferWithSize(length);
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  memcpy(io_buffer->data(), data, length);
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_body_.push_back(make_scoped_refptr(io_buffer));
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace net
559