1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/tools/quic/test_tools/quic_test_client.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
71e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/time/time.h"
87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "net/base/completion_callback.h"
97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "net/base/net_errors.h"
107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "net/cert/cert_verify_result.h"
117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "net/cert/x509_certificate.h"
127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "net/quic/crypto/proof_verifier.h"
13e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "net/quic/quic_server_id.h"
141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "net/quic/test_tools/quic_connection_peer.h"
15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "net/quic/test_tools/quic_session_peer.h"
16e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "net/quic/test_tools/quic_test_utils.h"
17f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "net/quic/test_tools/reliable_quic_stream_peer.h"
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/tools/balsa/balsa_headers.h"
192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "net/tools/quic/quic_epoll_connection_helper.h"
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/tools/quic/quic_packet_writer_wrapper.h"
21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "net/tools/quic/quic_spdy_client_stream.h"
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/tools/quic/test_tools/http_message.h"
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/tools/quic/test_tools/quic_client_peer.h"
247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)using base::StringPiece;
27e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochusing net::QuicServerId;
281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)using net::test::QuicConnectionPeer;
29f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)using net::test::QuicSessionPeer;
30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)using net::test::ReliableQuicStreamPeer;
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using std::string;
327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing std::vector;
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)namespace net {
3523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)namespace tools {
3623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)namespace test {
377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace {
387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// RecordingProofVerifier accepts any certificate chain and records the common
407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// name of the leaf.
4123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)class RecordingProofVerifier : public ProofVerifier {
427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch public:
437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // ProofVerifier interface.
4446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual QuicAsyncStatus VerifyProof(
4546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      const string& hostname,
4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      const string& server_config,
4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      const vector<string>& certs,
4846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      const string& signature,
4946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      const ProofVerifyContext* context,
5046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      string* error_details,
5146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      scoped_ptr<ProofVerifyDetails>* details,
5246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      ProofVerifierCallback* callback) OVERRIDE {
537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    common_name_.clear();
547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (certs.empty()) {
5546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      return QUIC_FAILURE;
567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // Convert certs to X509Certificate.
597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    vector<StringPiece> cert_pieces(certs.size());
607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    for (unsigned i = 0; i < certs.size(); i++) {
617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      cert_pieces[i] = StringPiece(certs[i]);
627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    scoped_refptr<net::X509Certificate> cert =
647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        net::X509Certificate::CreateFromDERCertChain(cert_pieces);
657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (!cert.get()) {
6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      return QUIC_FAILURE;
677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    common_name_ = cert->subject().GetDisplayName();
7046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return QUIC_SUCCESS;
717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const string& common_name() const { return common_name_; }
747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch private:
767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  string common_name_;
777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch};
787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}  // anonymous namespace
807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)BalsaHeaders* MungeHeaders(const BalsaHeaders* const_headers,
82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           bool secure) {
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  StringPiece uri = const_headers->request_uri();
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (uri.empty()) {
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return NULL;
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (const_headers->request_method() == "CONNECT") {
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return NULL;
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BalsaHeaders* headers = new BalsaHeaders;
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  headers->CopyFrom(*const_headers);
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!uri.starts_with("https://") &&
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      !uri.starts_with("http://")) {
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // If we have a relative URL, set some defaults.
95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    string full_uri = secure ? "https://www.google.com" :
96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               "http://www.google.com";
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    full_uri.append(uri.as_string());
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    headers->SetRequestUri(full_uri);
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return headers;
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
103c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochMockableQuicClient::MockableQuicClient(
104c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    IPEndPoint server_address,
105c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    const QuicServerId& server_id,
1066d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const QuicVersionVector& supported_versions,
1076d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    EpollServer* epoll_server)
108c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    : QuicClient(server_address,
109c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                 server_id,
110c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                 supported_versions,
1116d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                 false,
1126d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                 epoll_server),
113c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      override_connection_id_(0),
114c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      test_writer_(NULL) {}
115c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
116c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochMockableQuicClient::MockableQuicClient(
117c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    IPEndPoint server_address,
118c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    const QuicServerId& server_id,
119c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    const QuicConfig& config,
1206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const QuicVersionVector& supported_versions,
1216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    EpollServer* epoll_server)
122c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    : QuicClient(server_address,
123c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                 server_id,
124c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                 supported_versions,
125f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                 false,
1266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                 config,
1276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                 epoll_server),
128c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      override_connection_id_(0),
129c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      test_writer_(NULL) {}
130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochMockableQuicClient::~MockableQuicClient() {
132c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (connected()) {
133c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    Disconnect();
1341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
135c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
1361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
137c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochQuicPacketWriter* MockableQuicClient::CreateQuicPacketWriter() {
138c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  QuicPacketWriter* writer = QuicClient::CreateQuicPacketWriter();
139c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!test_writer_) {
140c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return writer;
141e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
142c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  test_writer_->set_writer(writer);
143c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return test_writer_;
144c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
1451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
146c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochQuicConnectionId MockableQuicClient::GenerateConnectionId() {
147c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return override_connection_id_ ? override_connection_id_
148c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      : QuicClient::GenerateConnectionId();
149c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
1502385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
151c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Takes ownership of writer.
152c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid MockableQuicClient::UseWriter(QuicPacketWriterWrapper* writer) {
153c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  CHECK(test_writer_ == NULL);
154c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  test_writer_ = writer;
155c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
156e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
157c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid MockableQuicClient::UseConnectionId(QuicConnectionId connection_id) {
158c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  override_connection_id_ = connection_id;
159c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
1602385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
161e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochQuicTestClient::QuicTestClient(IPEndPoint server_address,
162e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                               const string& server_hostname,
1631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                               const QuicVersionVector& supported_versions)
164e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    : client_(new MockableQuicClient(server_address,
165e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                     QuicServerId(server_hostname,
166e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                                  server_address.port(),
167e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                                  false,
168e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                                  PRIVACY_MODE_DISABLED),
1696d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                     supported_versions,
1706d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                     &epoll_server_)) {
171c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  Initialize(true);
172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
174e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochQuicTestClient::QuicTestClient(IPEndPoint server_address,
175e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                               const string& server_hostname,
176558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                               bool secure,
1771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                               const QuicVersionVector& supported_versions)
178e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    : client_(new MockableQuicClient(server_address,
179e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                     QuicServerId(server_hostname,
180e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                                  server_address.port(),
181e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                                  secure,
182e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                                  PRIVACY_MODE_DISABLED),
1836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                     supported_versions,
1846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                     &epoll_server_)) {
185c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  Initialize(secure);
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
188e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochQuicTestClient::QuicTestClient(
189e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    IPEndPoint server_address,
190e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    const string& server_hostname,
191e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    bool secure,
192e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    const QuicConfig& config,
193f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const QuicVersionVector& supported_versions)
194e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    : client_(
195c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          new MockableQuicClient(server_address,
196c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                 QuicServerId(server_hostname,
197c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                              server_address.port(),
198c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                              secure,
199c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                              PRIVACY_MODE_DISABLED),
200c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                 config,
2016d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                 supported_versions,
2026d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                 &epoll_server_)) {
203c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  Initialize(secure);
204c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
205c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
206c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochQuicTestClient::QuicTestClient() {
207c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
208c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
209c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochQuicTestClient::~QuicTestClient() {
210c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (stream_) {
211c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    stream_->set_visitor(NULL);
212c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
213c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
214c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
215c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid QuicTestClient::Initialize(bool secure) {
216d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  priority_ = 3;
2171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  connect_attempted_ = false;
2182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  secure_ = secure;
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  auto_reconnect_ = false;
220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  buffer_body_ = true;
221f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  fec_policy_ = FEC_PROTECT_OPTIONAL;
2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  proof_verifier_ = NULL;
223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ClearPerRequestState();
2242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ExpectCertificates(secure_);
225b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
226b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid QuicTestClient::ExpectCertificates(bool on) {
2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (on) {
2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    proof_verifier_ = new RecordingProofVerifier;
2302385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    client_->SetProofVerifier(proof_verifier_);
2317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  } else {
2327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    proof_verifier_ = NULL;
2332385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    client_->SetProofVerifier(NULL);
2347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void QuicTestClient::SetUserAgentID(const string& user_agent_id) {
2386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  client_->SetUserAgentID(user_agent_id);
2396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
2406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ssize_t QuicTestClient::SendRequest(const string& uri) {
242c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  HTTPMessage message(HttpConstants::HTTP_1_1,
243c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                      HttpConstants::GET,
244c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                      uri);
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return SendMessage(message);
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ssize_t QuicTestClient::SendMessage(const HTTPMessage& message) {
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  stream_ = NULL;  // Always force creation of a stream for SendMessage.
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
25190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // If we're not connected, try to find an sni hostname.
25290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!connected()) {
25390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    GURL url(message.headers()->request_uri().as_string());
25490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (!url.host().empty()) {
255e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      client_->set_server_id(
256c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          QuicServerId(url.host(),
257c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                       url.EffectiveIntPort(),
258c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                       url.SchemeIs("https"),
259c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                       PRIVACY_MODE_DISABLED));
26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
26190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
26290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicSpdyClientStream* stream = GetOrCreateStream();
264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!stream) { return 0; }
26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<BalsaHeaders> munged_headers(MungeHeaders(message.headers(),
267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                          secure_));
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ssize_t ret = GetOrCreateStream()->SendRequest(
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      munged_headers.get() ? *munged_headers.get() : *message.headers(),
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      message.body(),
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      message.has_complete_message());
272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  WaitForWriteToFlush();
273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return ret;
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ssize_t QuicTestClient::SendData(string data, bool last_data) {
2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicSpdyClientStream* stream = GetOrCreateStream();
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!stream) { return 0; }
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetOrCreateStream()->SendBody(data, last_data);
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  WaitForWriteToFlush();
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return data.length();
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
284c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbool QuicTestClient::response_complete() const {
285c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return response_complete_;
286c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
287c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
288c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochint QuicTestClient::response_header_size() const {
289c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return response_header_size_;
290c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
291c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
2925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuint64 QuicTestClient::response_body_size() const {
293c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return response_body_size_;
294c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
295c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
296c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbool QuicTestClient::buffer_body() const {
297c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return buffer_body_;
298c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
299c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
300c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid QuicTestClient::set_buffer_body(bool buffer_body) {
301c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  buffer_body_ = buffer_body;
302c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
303c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
304c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbool QuicTestClient::ServerInLameDuckMode() const {
305c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return false;
306c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
307c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
308c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst string& QuicTestClient::response_body() {
309c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return response_;
310c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
311c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)string QuicTestClient::SendCustomSynchronousRequest(
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const HTTPMessage& message) {
314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SendMessage(message);
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  WaitForResponse();
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return response_;
317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)string QuicTestClient::SendSynchronousRequest(const string& uri) {
320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (SendRequest(uri) == 0) {
32190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    DLOG(ERROR) << "Failed the request for uri:" << uri;
32290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return "";
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  WaitForResponse();
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return response_;
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicSpdyClientStream* QuicTestClient::GetOrCreateStream() {
3291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!connect_attempted_ || auto_reconnect_) {
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!connected()) {
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      Connect();
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!connected()) {
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return NULL;
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!stream_) {
3382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    stream_ = client_->CreateReliableClientStream();
339d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (stream_ == NULL) {
340d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      return NULL;
341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
342d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    stream_->set_visitor(this);
343d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    reinterpret_cast<QuicSpdyClientStream*>(stream_)->set_priority(priority_);
344f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // Set FEC policy on stream.
345f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    ReliableQuicStreamPeer::SetFecPolicy(stream_, fec_policy_);
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
347d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return stream_;
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicErrorCode QuicTestClient::connection_error() {
3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return client()->session()->error();
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuMockableQuicClient* QuicTestClient::client() { return client_.get(); }
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst string& QuicTestClient::cert_common_name() const {
3587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return reinterpret_cast<RecordingProofVerifier*>(proof_verifier_)
3597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      ->common_name();
3607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
3617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicTagValueMap QuicTestClient::GetServerConfig() const {
363c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  QuicCryptoClientConfig* config =
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      QuicClientPeer::GetCryptoConfig(client_.get());
365c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  QuicCryptoClientConfig::CachedState* state =
366e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      config->LookupOrCreate(client_->server_id());
367c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  const CryptoHandshakeMessage* handshake_msg = state->GetServerConfig();
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (handshake_msg != NULL) {
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return handshake_msg->tag_value_map();
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return QuicTagValueMap();
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool QuicTestClient::connected() const {
3762385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return client_->connected();
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void QuicTestClient::Connect() {
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!connected());
3811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!connect_attempted_) {
3821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    client_->Initialize();
3831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
3842385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  client_->Connect();
3851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  connect_attempted_ = true;
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void QuicTestClient::ResetConnection() {
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Disconnect();
390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Connect();
391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void QuicTestClient::Disconnect() {
394f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  client_->Disconnect();
3951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  connect_attempted_ = false;
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IPEndPoint QuicTestClient::LocalSocketAddress() const {
3992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return client_->client_address();
400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void QuicTestClient::ClearPerRequestState() {
403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  stream_error_ = QUIC_STREAM_NO_ERROR;
404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  stream_ = NULL;
405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  response_ = "";
406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  response_complete_ = false;
407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  response_headers_complete_ = false;
408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  headers_.Clear();
409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bytes_read_ = 0;
410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bytes_written_ = 0;
411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  response_header_size_ = 0;
412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  response_body_size_ = 0;
413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void QuicTestClient::WaitForResponseForMs(int timeout_ms) {
4161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  int64 timeout_us = timeout_ms * base::Time::kMicrosecondsPerMillisecond;
4176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  int64 old_timeout_us = epoll_server()->timeout_in_us();
4181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (timeout_us > 0) {
4196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    epoll_server()->set_timeout_in_us(timeout_us);
4201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const QuicClock* clock =
4221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      QuicConnectionPeer::GetHelper(client()->session()->connection())->
4231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          GetClock();
4241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  QuicTime end_waiting_time = clock->Now().Add(
4251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      QuicTime::Delta::FromMicroseconds(timeout_us));
4261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  while (stream_ != NULL &&
4271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)         !client_->session()->IsClosedStream(stream_->id()) &&
4281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)         (timeout_us < 0 || clock->Now() < end_waiting_time)) {
4291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    client_->WaitForEvents();
4301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (timeout_us > 0) {
4326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    epoll_server()->set_timeout_in_us(old_timeout_us);
4331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
4351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void QuicTestClient::WaitForInitialResponseForMs(int timeout_ms) {
4371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  int64 timeout_us = timeout_ms * base::Time::kMicrosecondsPerMillisecond;
4386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  int64 old_timeout_us = epoll_server()->timeout_in_us();
4391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (timeout_us > 0) {
4406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    epoll_server()->set_timeout_in_us(timeout_us);
4411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const QuicClock* clock =
4431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      QuicConnectionPeer::GetHelper(client()->session()->connection())->
4441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          GetClock();
4451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  QuicTime end_waiting_time = clock->Now().Add(
4461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      QuicTime::Delta::FromMicroseconds(timeout_us));
4471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  while (stream_ != NULL &&
4481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)         !client_->session()->IsClosedStream(stream_->id()) &&
4491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)         stream_->stream_bytes_read() == 0 &&
4501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)         (timeout_us < 0 || clock->Now() < end_waiting_time)) {
4512385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    client_->WaitForEvents();
452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
4531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (timeout_us > 0) {
4546d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    epoll_server()->set_timeout_in_us(old_timeout_us);
4551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ssize_t QuicTestClient::Send(const void *buffer, size_t size) {
459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return SendData(string(static_cast<const char*>(buffer), size), false);
460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
462f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool QuicTestClient::response_headers_complete() const {
463f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (stream_ != NULL) {
464f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return stream_->headers_decompressed();
465f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else {
466f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return response_headers_complete_;
467f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
468f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
469f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
470f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const BalsaHeaders* QuicTestClient::response_headers() const {
471f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (stream_ != NULL) {
472f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return &stream_->headers();
473f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else {
474f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return &headers_;
475f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
476f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
477f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
4785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuint64 QuicTestClient::response_size() const {
479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return bytes_read_;
480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)size_t QuicTestClient::bytes_read() const {
483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return bytes_read_;
484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)size_t QuicTestClient::bytes_written() const {
487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return bytes_written_;
488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void QuicTestClient::OnClose(QuicDataStream* stream) {
49190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (stream_ != stream) {
49290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
49390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
494f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (buffer_body()) {
495f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // TODO(fnk): The stream still buffers the whole thing. Fix that.
496f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    response_ = stream_->data();
497f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
498f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  response_complete_ = true;
499f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  response_headers_complete_ = stream_->headers_decompressed();
500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  headers_.CopyFrom(stream_->headers());
501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  stream_error_ = stream_->stream_error();
5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bytes_read_ = stream_->stream_bytes_read() + stream_->header_bytes_read();
5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bytes_written_ =
5045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      stream_->stream_bytes_written() + stream_->header_bytes_written();
505f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  response_header_size_ = headers_.GetSizeForWriteBuffer();
506f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  response_body_size_ = stream_->data().size();
507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  stream_ = NULL;
508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void QuicTestClient::UseWriter(QuicPacketWriterWrapper* writer) {
5115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  client_->UseWriter(writer);
5122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
5132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
514a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void QuicTestClient::UseConnectionId(QuicConnectionId connection_id) {
5151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(!connected());
516a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  client_->UseConnectionId(connection_id);
5171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
5181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
519c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochssize_t QuicTestClient::SendAndWaitForResponse(const void *buffer,
520c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                               size_t size) {
521c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  LOG(DFATAL) << "Not implemented";
522c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return 0;
523c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
524c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
525c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid QuicTestClient::Bind(IPEndPoint* local_address) {
526c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DLOG(WARNING) << "Bind will be done during connect";
527c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
528c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
529c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochstring QuicTestClient::SerializeMessage(const HTTPMessage& message) {
530c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  LOG(DFATAL) << "Not implemented";
531c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return "";
532c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
533c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
534c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochIPAddressNumber QuicTestClient::bind_to_address() const {
535c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return client_->bind_to_address();
536c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
537c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
538c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid QuicTestClient::set_bind_to_address(IPAddressNumber address) {
539c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  client_->set_bind_to_address(address);
540c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
541c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
542c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst IPEndPoint& QuicTestClient::address() const {
543c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  LOG(DFATAL) << "Not implemented";
544c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return client_->server_address();
545c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
546c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
547c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochsize_t QuicTestClient::requests_sent() const {
548c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  LOG(DFATAL) << "Not implemented";
549c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return 0;
550c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
551c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
552f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void QuicTestClient::WaitForWriteToFlush() {
5535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  while (connected() && client()->session()->HasDataToWrite()) {
554f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    client_->WaitForEvents();
555f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
556f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
557f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
558f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void QuicTestClient::SetFecPolicy(FecPolicy fec_policy) {
559f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  fec_policy_ = fec_policy;
560f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Set policy for headers and crypto streams.
561f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ReliableQuicStreamPeer::SetFecPolicy(
562f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      QuicSessionPeer::GetHeadersStream(client()->session()), fec_policy);
563f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ReliableQuicStreamPeer::SetFecPolicy(client()->session()->GetCryptoStream(),
564f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                       fec_policy);
565f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
566f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace test
568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace tools
569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace net
570