Commit 04730a11 authored by rch's avatar rch Committed by Commit bot

Add a chromium based simple QUIC client.

Review URL: https://codereview.chromium.org/995423003

Cr-Commit-Position: refs/heads/master@{#321303}
parent 1ab731da
......@@ -1265,6 +1265,24 @@ source_set("quic_tools") {
]
}
executable("simple_quic_client") {
testonly = true
sources = [
"tools/quic/quic_simple_client.cc",
"tools/quic/quic_simple_client.h",
"tools/quic/quic_simple_client_bin.cc",
"tools/quic/quic_simple_client_session.cc",
"tools/quic/quic_simple_client_session.h",
"tools/quic/quic_simple_client_stream.cc",
"tools/quic/quic_simple_client_stream.h",
]
deps = [
":net",
"//base",
"//url",
]
}
# TODO(GYP) make this compile on Android, we need some native test deps done.
# TODO(GYP) Also doesn't work on Windows; dependency on boringssl is wrong.
# TODO(GYP) Also doesn't work on Mac, need to figure out why not.
......
......@@ -801,6 +801,24 @@
'quic/quic_time_wait_list_manager.h',
],
},
{
'target_name': 'simple_quic_client',
'type': 'executable',
'dependencies': [
'../base/base.gyp:base',
'../url/url.gyp:url_lib',
'net',
],
'sources': [
'tools/quic/quic_simple_client.cc',
'tools/quic/quic_simple_client.h',
'tools/quic/quic_simple_client_bin.cc',
'tools/quic/quic_simple_client_session.cc',
'tools/quic/quic_simple_client_session.h',
'tools/quic/quic_simple_client_stream.cc',
'tools/quic/quic_simple_client_stream.h',
],
},
],
'conditions': [
['use_v8_in_net == 1', {
......
......@@ -24,9 +24,10 @@ class HttpResponseHeaders;
// |response| output parameter for the HttpResponseInfo.
// Returns true if successfully converted. False if the SpdyHeaderBlock is
// incomplete (e.g. missing 'status' or 'version').
bool SpdyHeadersToHttpResponse(const SpdyHeaderBlock& headers,
SpdyMajorVersion protocol_version,
HttpResponseInfo* response);
NET_EXPORT_PRIVATE bool SpdyHeadersToHttpResponse(
const SpdyHeaderBlock& headers,
SpdyMajorVersion protocol_version,
HttpResponseInfo* response);
// Create a SpdyHeaderBlock from HttpRequestInfo and HttpRequestHeaders.
NET_EXPORT_PRIVATE void CreateSpdyHeadersFromHttpRequest(
......
......@@ -27,6 +27,7 @@
#endif
using std::string;
using std::vector;
namespace net {
namespace tools {
......@@ -252,19 +253,19 @@ void QuicClient::SendRequest(const BalsaHeaders& headers,
stream->set_visitor(this);
}
void QuicClient::SendRequestAndWaitForResponse(const BalsaHeaders& headers,
StringPiece body,
bool fin) {
SendRequest(headers, "", true);
while (WaitForEvents()) {
}
void QuicClient::SendRequestAndWaitForResponse(
const BalsaHeaders& headers,
StringPiece body,
bool fin) {
SendRequest(headers, body, fin);
while (WaitForEvents()) {}
}
void QuicClient::SendRequestsAndWaitForResponse(
const base::CommandLine::StringVector& args) {
for (size_t i = 0; i < args.size(); ++i) {
const vector<string>& url_list) {
for (size_t i = 0; i < url_list.size(); ++i) {
BalsaHeaders headers;
headers.SetRequestFirstlineFromStringPieces("GET", args[i], "HTTP/1.1");
headers.SetRequestFirstlineFromStringPieces("GET", url_list[i], "HTTP/1.1");
SendRequest(headers, "", true);
}
while (WaitForEvents()) {}
......@@ -282,7 +283,7 @@ void QuicClient::WaitForStreamToClose(QuicStreamId id) {
DCHECK(connected());
while (connected() && !session_->IsClosedStream(id)) {
epoll_server_->WaitForEventsAndExecuteCallbacks();
WaitForEvents();
}
}
......@@ -290,7 +291,7 @@ void QuicClient::WaitForCryptoHandshakeConfirmed() {
DCHECK(connected());
while (connected() && !session_->IsCryptoHandshakeConfirmed()) {
epoll_server_->WaitForEventsAndExecuteCallbacks();
WaitForEvents();
}
}
......
......@@ -97,8 +97,8 @@ class QuicClient : public EpollCallbackInterface,
// Sends a request simple GET for each URL in |args|, and then waits for
// each to complete.
void SendRequestsAndWaitForResponse(const
base::CommandLine::StringVector& args);
void SendRequestsAndWaitForResponse(
const std::vector<std::string>& url_list);
// Returns a newly created QuicSpdyClientStream, owned by the
// QuicClient.
......
This diff is collapsed.
......@@ -5,8 +5,8 @@
// A toy client, which connects to a specified port and sends QUIC
// request to that endpoint.
#ifndef NET_TOOLS_QUIC_QUIC_CLIENT_H_
#define NET_TOOLS_QUIC_QUIC_CLIENT_H_
#ifndef NET_TOOLS_QUIC_QUIC_SIMPLE_CLIENT_H_
#define NET_TOOLS_QUIC_QUIC_SIMPLE_CLIENT_H_
#include <string>
......@@ -14,54 +14,53 @@
#include "base/command_line.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_log.h"
#include "net/http/http_response_headers.h"
#include "net/quic/crypto/crypto_handshake.h"
#include "net/quic/quic_config.h"
#include "net/quic/quic_framer.h"
#include "net/quic/quic_packet_creator.h"
#include "net/tools/balsa/balsa_headers.h"
#include "net/tools/epoll_server/epoll_server.h"
#include "net/tools/quic/quic_client_session.h"
#include "net/tools/quic/quic_spdy_client_stream.h"
#include "net/tools/quic/quic_simple_client_session.h"
#include "net/tools/quic/quic_simple_client_stream.h"
namespace net {
struct HttpRequestInfo;
class ProofVerifier;
class QuicServerId;
class QuicConnectionHelper;
class UDPClientSocket;
namespace tools {
class QuicEpollConnectionHelper;
namespace test {
class QuicClientPeer;
} // namespace test
class QuicClient : public EpollCallbackInterface,
public QuicDataStream::Visitor {
class QuicSimpleClient : public QuicDataStream::Visitor {
public:
class ResponseListener {
public:
ResponseListener() {}
virtual ~ResponseListener() {}
virtual void OnCompleteResponse(QuicStreamId id,
const BalsaHeaders& response_headers,
const HttpResponseHeaders& response_headers,
const std::string& response_body) = 0;
};
// Create a quic client, which will have events managed by an externally owned
// EpollServer.
QuicClient(IPEndPoint server_address,
const QuicServerId& server_id,
const QuicVersionVector& supported_versions,
EpollServer* epoll_server);
QuicClient(IPEndPoint server_address,
const QuicServerId& server_id,
const QuicVersionVector& supported_versions,
const QuicConfig& config,
EpollServer* epoll_server);
~QuicClient() override;
QuicSimpleClient(IPEndPoint server_address,
const QuicServerId& server_id,
const QuicVersionVector& supported_versions);
QuicSimpleClient(IPEndPoint server_address,
const QuicServerId& server_id,
const QuicVersionVector& supported_versions,
const QuicConfig& config);
~QuicSimpleClient() override;
// Initializes the client to create a connection. Should be called exactly
// once before calling StartConnect or Connect. Returns true if the
......@@ -86,23 +85,23 @@ class QuicClient : public EpollCallbackInterface,
void Disconnect();
// Sends an HTTP request and does not wait for response before returning.
void SendRequest(const BalsaHeaders& headers,
void SendRequest(const HttpRequestInfo& headers,
base::StringPiece body,
bool fin);
// Sends an HTTP request and waits for response before returning.
void SendRequestAndWaitForResponse(const BalsaHeaders& headers,
void SendRequestAndWaitForResponse(const HttpRequestInfo& headers,
base::StringPiece body,
bool fin);
// Sends a request simple GET for each URL in |args|, and then waits for
// each to complete.
void SendRequestsAndWaitForResponse(const
base::CommandLine::StringVector& args);
void SendRequestsAndWaitForResponse(
const base::CommandLine::StringVector& url_list);
// Returns a newly created QuicSpdyClientStream, owned by the
// QuicClient.
QuicSpdyClientStream* CreateReliableClientStream();
// Returns a newly created QuicSimpleClientStream, owned by the
// QuicSimpleClient.
QuicSimpleClientStream* CreateReliableClientStream();
// Wait for events until the stream with the given ID is closed.
void WaitForStreamToClose(QuicStreamId id);
......@@ -114,20 +113,17 @@ class QuicClient : public EpollCallbackInterface,
// Returns true if there are any outstanding requests.
bool WaitForEvents();
// From EpollCallbackInterface
void OnRegistration(EpollServer* eps, int fd, int event_mask) override {}
void OnModification(int fd, int event_mask) override {}
void OnEvent(int fd, EpollEvent* event) override;
// |fd_| can be unregistered without the client being disconnected. This
// happens in b3m QuicProber where we unregister |fd_| to feed in events to
// the client from the SelectServer.
void OnUnregistration(int fd, bool replaced) override {}
void OnShutdown(EpollServer* eps, int fd) override {}
// Start the read loop on the socket.
void StartReading();
// Called on reads that complete asynchronously. Dispatches the packet and
// calls StartReading() again.
void OnReadComplete(int result);
// QuicDataStream::Visitor
void OnClose(QuicDataStream* stream) override;
QuicClientSession* session() { return session_.get(); }
QuicSimpleClientSession* session() { return session_.get(); }
bool connected() const;
bool goaway_received() const;
......@@ -144,8 +140,6 @@ class QuicClient : public EpollCallbackInterface,
const IPEndPoint& client_address() const { return client_address_; }
int fd() { return fd_; }
const QuicServerId& server_id() const { return server_id_; }
// This should only be set before the initial Connect()
......@@ -191,16 +185,9 @@ class QuicClient : public EpollCallbackInterface,
protected:
virtual QuicConnectionId GenerateConnectionId();
virtual QuicEpollConnectionHelper* CreateQuicConnectionHelper();
virtual QuicConnectionHelper* CreateQuicConnectionHelper();
virtual QuicPacketWriter* CreateQuicPacketWriter();
virtual int ReadPacket(char* buffer,
int buffer_len,
IPEndPoint* server_address,
IPAddressNumber* client_ip);
EpollServer* epoll_server() { return epoll_server_; }
private:
friend class net::tools::test::QuicClientPeer;
......@@ -220,12 +207,12 @@ class QuicClient : public EpollCallbackInterface,
// and binds the socket to our address.
bool CreateUDPSocket();
// If the socket has been created, then unregister and close() the FD.
void CleanUpUDPSocket();
// Read a UDP packet and hand it to the framer.
bool ReadAndProcessPacket();
// Used by |helper_| to time alarms.
QuicClock clock_;
// Address of the server.
const IPEndPoint server_address_;
......@@ -250,14 +237,16 @@ class QuicClient : public EpollCallbackInterface,
scoped_ptr<QuicPacketWriter> writer_;
// Session which manages streams.
scoped_ptr<QuicClientSession> session_;
// Listens for events on the client socket.
EpollServer* epoll_server_;
// UDP socket.
int fd_;
scoped_ptr<QuicSimpleClientSession> session_;
// UDP socket connected to the server.
scoped_ptr<UDPClientSocket> socket_;
// Connection on the socket. Owned by |session_|.
QuicConnection* connection_;
// Helper to be used by created connections.
scoped_ptr<QuicEpollConnectionHelper> helper_;
scoped_ptr<QuicConnectionHelper> helper_;
// Listens for full responses.
scoped_ptr<ResponseListener> response_listener_;
......@@ -289,10 +278,24 @@ class QuicClient : public EpollCallbackInterface,
// Body of most recent response.
std::string latest_response_body_;
DISALLOW_COPY_AND_ASSIGN(QuicClient);
bool read_pending_;
// The number of iterations of the read loop that have completed synchronously
// and without posting a new task to the message loop.
int synchronous_read_count_;
// The target buffer of the current read.
scoped_refptr<IOBufferWithSize> read_buffer_;
// The log used for the sockets.
NetLog net_log_;
base::WeakPtrFactory<QuicSimpleClient> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(QuicSimpleClient);
};
} // namespace tools
} // namespace net
#endif // NET_TOOLS_QUIC_QUIC_CLIENT_H_
#endif // NET_TOOLS_QUIC_QUIC_SIMPLE_CLIENT_H_
......@@ -49,14 +49,14 @@
#include "net/base/ip_endpoint.h"
#include "net/base/privacy_mode.h"
#include "net/cert/cert_verifier.h"
#include "net/http/http_request_info.h"
#include "net/http/transport_security_state.h"
#include "net/quic/crypto/proof_verifier_chromium.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_server_id.h"
#include "net/quic/quic_utils.h"
#include "net/tools/epoll_server/epoll_server.h"
#include "net/tools/quic/quic_client.h"
#include "net/tools/quic/spdy_utils.h"
#include "net/spdy/spdy_http_utils.h"
#include "net/tools/quic/quic_simple_client.h"
#include "url/gurl.h"
using base::StringPiece;
......@@ -161,6 +161,7 @@ int main(int argc, char *argv[]) {
<< " redirect_is_success: " << FLAGS_redirect_is_success;
base::AtExitManager exit_manager;
base::MessageLoopForIO message_loop;
// Determine IP address to connect to from supplied hostname.
net::IPAddressNumber ip_addr;
......@@ -184,7 +185,6 @@ int main(int argc, char *argv[]) {
// Build the client, and try to connect.
bool is_https = (FLAGS_port == 443);
net::EpollServer epoll_server;
net::QuicServerId server_id(host, FLAGS_port, is_https,
net::PRIVACY_MODE_DISABLED);
net::QuicVersionVector versions = net::QuicSupportedVersions();
......@@ -192,8 +192,8 @@ int main(int argc, char *argv[]) {
versions.clear();
versions.push_back(static_cast<net::QuicVersion>(FLAGS_quic_version));
}
net::tools::QuicClient client(net::IPEndPoint(ip_addr, FLAGS_port), server_id,
versions, &epoll_server);
net::tools::QuicSimpleClient client(net::IPEndPoint(ip_addr, FLAGS_port),
server_id, versions);
scoped_ptr<CertVerifier> cert_verifier;
scoped_ptr<TransportSecurityState> transport_security_state;
if (is_https) {
......@@ -223,9 +223,9 @@ int main(int argc, char *argv[]) {
cout << "Connected to " << host_port << endl;
// Construct a GET or POST request for supplied URL.
net::BalsaHeaders headers;
headers.SetRequestFirstlineFromStringPieces(
FLAGS_body.empty() ? "GET" : "POST", url.spec(), "HTTP/1.1");
net::HttpRequestInfo request;
request.method = FLAGS_body.empty() ? "GET" : "POST";
request.url = url;
// Append any additional headers supplied on the command line.
vector<string> headers_tokenized;
......@@ -243,16 +243,18 @@ int main(int argc, char *argv[]) {
base::TrimWhitespaceASCII(kv[0], base::TRIM_ALL, &key);
string value;
base::TrimWhitespaceASCII(kv[1], base::TRIM_ALL, &value);
headers.AppendHeader(key, value);
request.extra_headers.SetHeader(key, value);
}
// Make sure to store the response, for later output.
client.set_store_response(true);
// Send the request.
map<string, string> header_block =
net::tools::SpdyUtils::RequestHeadersToSpdy4Headers(headers);
client.SendRequestAndWaitForResponse(headers, FLAGS_body, /*fin=*/true);
net::SpdyHeaderBlock header_block;
net::CreateSpdyHeadersFromHttpRequest(request, request.extra_headers,
net::SPDY3, /*direct=*/ true,
&header_block);
client.SendRequestAndWaitForResponse(request, FLAGS_body, /*fin=*/true);
// Print request and response details.
if (!FLAGS_quiet) {
......@@ -262,7 +264,8 @@ int main(int argc, char *argv[]) {
cout << " " << kv.first << ": " << kv.second << endl;
}
cout << "body: " << FLAGS_body << endl;
cout << endl << "Response:";
cout << endl;
cout << "Response:" << endl;
cout << "headers: " << client.latest_response_headers() << endl;
cout << "body: " << client.latest_response_body() << endl;
}
......
......@@ -2,27 +2,27 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/tools/quic/quic_client_session.h"
#include "net/tools/quic/quic_simple_client_session.h"
#include "base/logging.h"
#include "net/quic/crypto/crypto_protocol.h"
#include "net/quic/quic_server_id.h"
#include "net/tools/quic/quic_spdy_client_stream.h"
#include "net/tools/quic/quic_simple_client_stream.h"
using std::string;
namespace net {
namespace tools {
QuicClientSession::QuicClientSession(const QuicConfig& config,
QuicConnection* connection)
QuicSimpleClientSession::QuicSimpleClientSession(const QuicConfig& config,
QuicConnection* connection)
: QuicClientSessionBase(connection, config), respect_goaway_(true) {
}
QuicClientSession::~QuicClientSession() {
QuicSimpleClientSession::~QuicSimpleClientSession() {
}
void QuicClientSession::InitializeSession(
void QuicSimpleClientSession::InitializeSession(
const QuicServerId& server_id,
QuicCryptoClientConfig* crypto_config) {
crypto_stream_.reset(
......@@ -30,13 +30,13 @@ void QuicClientSession::InitializeSession(
QuicClientSessionBase::InitializeSession();
}
void QuicClientSession::OnProofValid(
void QuicSimpleClientSession::OnProofValid(
const QuicCryptoClientConfig::CachedState& /*cached*/) {}
void QuicClientSession::OnProofVerifyDetailsAvailable(
void QuicSimpleClientSession::OnProofVerifyDetailsAvailable(
const ProofVerifyDetails& /*verify_details*/) {}
QuicSpdyClientStream* QuicClientSession::CreateOutgoingDataStream() {
QuicSimpleClientStream* QuicSimpleClientSession::CreateOutgoingDataStream() {
if (!crypto_stream_->encryption_established()) {
DVLOG(1) << "Encryption not active so no outgoing stream created.";
return nullptr;
......@@ -51,26 +51,26 @@ QuicSpdyClientStream* QuicClientSession::CreateOutgoingDataStream() {
<< "Already received goaway.";
return nullptr;
}
QuicSpdyClientStream* stream
= new QuicSpdyClientStream(GetNextStreamId(), this);
QuicSimpleClientStream* stream
= new QuicSimpleClientStream(GetNextStreamId(), this);
ActivateStream(stream);
return stream;
}
QuicCryptoClientStream* QuicClientSession::GetCryptoStream() {
QuicCryptoClientStream* QuicSimpleClientSession::GetCryptoStream() {
return crypto_stream_.get();
}
void QuicClientSession::CryptoConnect() {
void QuicSimpleClientSession::CryptoConnect() {
DCHECK(flow_controller());
crypto_stream_->CryptoConnect();
}
int QuicClientSession::GetNumSentClientHellos() const {
int QuicSimpleClientSession::GetNumSentClientHellos() const {
return crypto_stream_->num_sent_client_hellos();
}
QuicDataStream* QuicClientSession::CreateIncomingDataStream(
QuicDataStream* QuicSimpleClientSession::CreateIncomingDataStream(
QuicStreamId id) {
DLOG(ERROR) << "Server push not supported";
return nullptr;
......
......@@ -4,8 +4,8 @@
//
// A client specific QuicSession subclass.
#ifndef NET_TOOLS_QUIC_QUIC_CLIENT_SESSION_H_
#define NET_TOOLS_QUIC_QUIC_CLIENT_SESSION_H_
#ifndef NET_TOOLS_QUIC_QUIC_SIMPLE_CLIENT_SESSION_H_
#define NET_TOOLS_QUIC_QUIC_SIMPLE_CLIENT_SESSION_H_
#include <string>
......@@ -13,7 +13,7 @@
#include "net/quic/quic_client_session_base.h"
#include "net/quic/quic_crypto_client_stream.h"
#include "net/quic/quic_protocol.h"
#include "net/tools/quic/quic_spdy_client_stream.h"
#include "net/tools/quic/quic_simple_client_stream.h"
namespace net {
......@@ -23,19 +23,19 @@ class ReliableQuicStream;
namespace tools {
class QuicClientSession : public QuicClientSessionBase {
class QuicSimpleClientSession : public QuicClientSessionBase {
public:
QuicClientSession(const QuicConfig& config, QuicConnection* connection);
~QuicClientSession() override;
QuicSimpleClientSession(const QuicConfig& config, QuicConnection* connection);
~QuicSimpleClientSession() override;
void InitializeSession(const QuicServerId& server_id,
QuicCryptoClientConfig* config);
// QuicSession methods:
QuicSpdyClientStream* CreateOutgoingDataStream() override;
QuicSimpleClientStream* CreateOutgoingDataStream() override;
QuicCryptoClientStream* GetCryptoStream() override;
// QuicClientSessionBase methods:
// QuicSimpleClientSessionBase methods:
void OnProofValid(const QuicCryptoClientConfig::CachedState& cached) override;
void OnProofVerifyDetailsAvailable(
const ProofVerifyDetails& verify_details) override;
......@@ -63,10 +63,10 @@ class QuicClientSession : public QuicClientSessionBase {
// the creation of streams regardless of the high chance they will fail.
bool respect_goaway_;
DISALLOW_COPY_AND_ASSIGN(QuicClientSession);
DISALLOW_COPY_AND_ASSIGN(QuicSimpleClientSession);
};
} // namespace tools
} // namespace net
#endif // NET_TOOLS_QUIC_QUIC_CLIENT_SESSION_H_
#endif // NET_TOOLS_QUIC_QUIC_SIMPLE_CLIENT_SESSION_H_
......@@ -2,11 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/tools/quic/quic_spdy_client_stream.h"
#include "net/tools/quic/quic_simple_client_stream.h"
#include "net/http/http_response_info.h"
#include "net/spdy/spdy_framer.h"
#include "net/tools/quic/quic_client_session.h"
#include "net/tools/quic/spdy_utils.h"
#include "net/spdy/spdy_http_utils.h"
#include "net/tools/quic/quic_simple_client_session.h"
using base::StringPiece;
using std::string;
......@@ -16,19 +17,20 @@ namespace tools {
static const size_t kHeaderBufInitialSize = 4096;
QuicSpdyClientStream::QuicSpdyClientStream(QuicStreamId id,
QuicClientSession* session)
QuicSimpleClientStream::QuicSimpleClientStream(QuicStreamId id,
QuicSimpleClientSession* session)
: QuicDataStream(id, session),
read_buf_(new GrowableIOBuffer()),
response_headers_received_(false),
header_bytes_read_(0),
header_bytes_written_(0) {
read_buf_->SetCapacity(kHeaderBufInitialSize);
}
QuicSpdyClientStream::~QuicSpdyClientStream() {
QuicSimpleClientStream::~QuicSimpleClientStream() {
}
void QuicSpdyClientStream::OnStreamFrame(const QuicStreamFrame& frame) {
void QuicSimpleClientStream::OnStreamFrame(const QuicStreamFrame& frame) {
if (!write_side_closed()) {
DVLOG(1) << "Got a response before the request was complete. "
<< "Aborting request.";
......@@ -37,14 +39,14 @@ void QuicSpdyClientStream::OnStreamFrame(const QuicStreamFrame& frame) {
QuicDataStream::OnStreamFrame(frame);
}
void QuicSpdyClientStream::OnStreamHeadersComplete(bool fin,
void QuicSimpleClientStream::OnStreamHeadersComplete(bool fin,
size_t frame_len) {
header_bytes_read_ = frame_len;
QuicDataStream::OnStreamHeadersComplete(fin, frame_len);
}
uint32 QuicSpdyClientStream::ProcessData(const char* data,
uint32 data_len) {
uint32 QuicSimpleClientStream::ProcessData(const char* data,
uint32 data_len) {
int total_bytes_processed = 0;
// Are we still reading the response headers.
......@@ -63,22 +65,26 @@ uint32 QuicSpdyClientStream::ProcessData(const char* data,
return data_len;
}
void QuicSpdyClientStream::OnFinRead() {
void QuicSimpleClientStream::OnFinRead() {
ReliableQuicStream::OnFinRead();
if (!response_headers_received_) {
Reset(QUIC_BAD_APPLICATION_PAYLOAD);
} else if ((headers().content_length_status() ==
BalsaHeadersEnums::VALID_CONTENT_LENGTH) &&
data_.size() != headers().content_length()) {
} else if (headers()->GetContentLength() != -1 &&
data_.size() !=
static_cast<size_t>(headers()->GetContentLength())) {
Reset(QUIC_BAD_APPLICATION_PAYLOAD);
}
}
ssize_t QuicSpdyClientStream::SendRequest(const BalsaHeaders& headers,
StringPiece body,
bool fin) {
SpdyHeaderBlock header_block =
SpdyUtils::RequestHeadersToSpdyHeaders(headers);
size_t QuicSimpleClientStream::SendRequest(const HttpRequestInfo& headers,
StringPiece body,
bool fin) {
SpdyHeaderBlock header_block;
CreateSpdyHeadersFromHttpRequest(headers,
headers.extra_headers,
SPDY3,
/*direct=*/ true,
&header_block);
bool send_fin_with_headers = fin && body.empty();
size_t bytes_sent = body.size();
......@@ -93,7 +99,7 @@ ssize_t QuicSpdyClientStream::SendRequest(const BalsaHeaders& headers,
return bytes_sent;
}
int QuicSpdyClientStream::ParseResponseHeaders() {
int QuicSimpleClientStream::ParseResponseHeaders() {
size_t read_buf_len = static_cast<size_t>(read_buf_->offset());
SpdyFramer framer(SPDY3);
SpdyHeaderBlock headers;
......@@ -104,10 +110,13 @@ int QuicSpdyClientStream::ParseResponseHeaders() {
return -1;
}
if (!SpdyUtils::FillBalsaResponseHeaders(headers, &headers_)) {
HttpResponseInfo info;
if (!SpdyHeadersToHttpResponse(headers, SPDY3, &info)) {
Reset(QUIC_BAD_APPLICATION_PAYLOAD);
return -1;
}
headers_ = info.headers;
response_headers_received_ = true;
size_t delta = read_buf_len - len;
......@@ -115,14 +124,14 @@ int QuicSpdyClientStream::ParseResponseHeaders() {
data_.append(data + len, delta);
}
return len;
return static_cast<int>(len);
}
void QuicSpdyClientStream::SendBody(const string& data, bool fin) {
void QuicSimpleClientStream::SendBody(const string& data, bool fin) {
SendBody(data, fin, nullptr);
}
void QuicSpdyClientStream::SendBody(
void QuicSimpleClientStream::SendBody(
const string& data,
bool fin,
QuicAckNotifier::DelegateInterface* delegate) {
......
......@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_TOOLS_QUIC_QUIC_SPDY_CLIENT_STREAM_H_
#define NET_TOOLS_QUIC_QUIC_SPDY_CLIENT_STREAM_H_
#ifndef NET_TOOLS_QUIC_QUIC_SIMPLE_CLIENT_STREAM_H_
#define NET_TOOLS_QUIC_QUIC_SIMPLE_CLIENT_STREAM_H_
#include <sys/types.h>
#include <string>
......@@ -11,6 +11,8 @@
#include "base/basictypes.h"
#include "base/strings/string_piece.h"
#include "net/base/io_buffer.h"
#include "net/http/http_request_info.h"
#include "net/http/http_response_headers.h"
#include "net/quic/quic_data_stream.h"
#include "net/quic/quic_protocol.h"
#include "net/tools/balsa/balsa_frame.h"
......@@ -20,14 +22,14 @@ namespace net {
namespace tools {
class QuicClientSession;
class QuicSimpleClientSession;
// All this does right now is send an SPDY request, and aggregate the
// SPDY response.
class QuicSpdyClientStream : public QuicDataStream {
class QuicSimpleClientStream : public QuicDataStream {
public:
QuicSpdyClientStream(QuicStreamId id, QuicClientSession* session);
~QuicSpdyClientStream() override;
QuicSimpleClientStream(QuicStreamId id, QuicSimpleClientSession* session);
~QuicSimpleClientStream() override;
// Override the base class to close the write side as soon as we get a
// response.
......@@ -45,9 +47,9 @@ class QuicSpdyClientStream : public QuicDataStream {
// Serializes the headers and body, sends it to the server, and
// returns the number of bytes sent.
ssize_t SendRequest(const BalsaHeaders& headers,
base::StringPiece body,
bool fin);
size_t SendRequest(const HttpRequestInfo& headers,
base::StringPiece body,
bool fin);
// Sends body data to the server, or buffers if it can't be sent immediately.
void SendBody(const std::string& data, bool fin);
......@@ -60,7 +62,7 @@ class QuicSpdyClientStream : public QuicDataStream {
const std::string& data() { return data_; }
// Returns whatever headers have been received for this stream.
const BalsaHeaders& headers() { return headers_; }
scoped_refptr<HttpResponseHeaders> headers() { return headers_; }
size_t header_bytes_read() const { return header_bytes_read_; }
......@@ -73,7 +75,7 @@ class QuicSpdyClientStream : public QuicDataStream {
private:
int ParseResponseHeaders();
BalsaHeaders headers_;
scoped_refptr<HttpResponseHeaders> headers_;
std::string data_;
scoped_refptr<GrowableIOBuffer> read_buf_;
......@@ -81,10 +83,10 @@ class QuicSpdyClientStream : public QuicDataStream {
size_t header_bytes_read_;
size_t header_bytes_written_;
DISALLOW_COPY_AND_ASSIGN(QuicSpdyClientStream);
DISALLOW_COPY_AND_ASSIGN(QuicSimpleClientStream);
};
} // namespace tools
} // namespace net
#endif // NET_TOOLS_QUIC_QUIC_SPDY_CLIENT_STREAM_H_
#endif // NET_TOOLS_QUIC_QUIC_SIMPLE_CLIENT_STREAM_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment