Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(267)

Side by Side Diff: net/tools/quic/quic_client.cc

Issue 2363393004: Remove usage of BalsaHeaders from QuicClient. Also move QuicDataToResend from QuicClient to QuicCli… (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/tools/quic/quic_client.h" 5 #include "net/tools/quic/quic_client.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <netinet/in.h> 8 #include <netinet/in.h>
9 #include <string.h> 9 #include <string.h>
10 #include <sys/epoll.h> 10 #include <sys/epoll.h>
11 #include <sys/socket.h> 11 #include <sys/socket.h>
12 #include <unistd.h> 12 #include <unistd.h>
13 13
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/run_loop.h" 15 #include "base/run_loop.h"
16 #include "base/strings/string_number_conversions.h"
16 #include "net/base/sockaddr_storage.h" 17 #include "net/base/sockaddr_storage.h"
17 #include "net/quic/core/crypto/quic_random.h" 18 #include "net/quic/core/crypto/quic_random.h"
18 #include "net/quic/core/quic_bug_tracker.h" 19 #include "net/quic/core/quic_bug_tracker.h"
19 #include "net/quic/core/quic_connection.h" 20 #include "net/quic/core/quic_connection.h"
20 #include "net/quic/core/quic_data_reader.h" 21 #include "net/quic/core/quic_data_reader.h"
21 #include "net/quic/core/quic_flags.h" 22 #include "net/quic/core/quic_flags.h"
22 #include "net/quic/core/quic_protocol.h" 23 #include "net/quic/core/quic_protocol.h"
23 #include "net/quic/core/quic_server_id.h" 24 #include "net/quic/core/quic_server_id.h"
25 #include "net/quic/core/spdy_utils.h"
24 #include "net/tools/quic/quic_epoll_alarm_factory.h" 26 #include "net/tools/quic/quic_epoll_alarm_factory.h"
25 #include "net/tools/quic/quic_epoll_connection_helper.h" 27 #include "net/tools/quic/quic_epoll_connection_helper.h"
26 #include "net/tools/quic/quic_socket_utils.h" 28 #include "net/tools/quic/quic_socket_utils.h"
27 #include "net/tools/quic/spdy_balsa_utils.h" 29 #include "net/tools/quic/spdy_balsa_utils.h"
28 30
29 #ifndef SO_RXQ_OVFL 31 #ifndef SO_RXQ_OVFL
30 #define SO_RXQ_OVFL 40 32 #define SO_RXQ_OVFL 40
31 #endif 33 #endif
32 34
33 // TODO(rtenneti): Add support for MMSG_MORE. 35 // TODO(rtenneti): Add support for MMSG_MORE.
34 #define MMSG_MORE 0 36 #define MMSG_MORE 0
35 37
36 using base::StringPiece; 38 using base::StringPiece;
39 using base::StringToInt;
37 using std::string; 40 using std::string;
38 using std::vector; 41 using std::vector;
39 42
40 namespace net { 43 namespace net {
41 44
42 const int kEpollFlags = EPOLLIN | EPOLLOUT | EPOLLET; 45 const int kEpollFlags = EPOLLIN | EPOLLOUT | EPOLLET;
43 46
44 void QuicClient::ClientQuicDataToResend::Resend() { 47 void QuicClient::ClientQuicDataToResend::Resend() {
45 client_->SendRequest(*headers_, body_, fin_); 48 client_->SendRequest(*headers_, body_, fin_);
46 delete headers_;
47 headers_ = nullptr; 49 headers_ = nullptr;
48 } 50 }
49 51
50 QuicClient::QuicClient(IPEndPoint server_address, 52 QuicClient::QuicClient(IPEndPoint server_address,
51 const QuicServerId& server_id, 53 const QuicServerId& server_id,
52 const QuicVersionVector& supported_versions, 54 const QuicVersionVector& supported_versions,
53 EpollServer* epoll_server, 55 EpollServer* epoll_server,
54 std::unique_ptr<ProofVerifier> proof_verifier) 56 std::unique_ptr<ProofVerifier> proof_verifier)
55 : QuicClient(server_address, 57 : QuicClient(server_address,
56 server_id, 58 server_id,
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 119
118 if (!CreateUDPSocketAndBind()) { 120 if (!CreateUDPSocketAndBind()) {
119 return false; 121 return false;
120 } 122 }
121 123
122 epoll_server_->RegisterFD(GetLatestFD(), this, kEpollFlags); 124 epoll_server_->RegisterFD(GetLatestFD(), this, kEpollFlags);
123 initialized_ = true; 125 initialized_ = true;
124 return true; 126 return true;
125 } 127 }
126 128
127 QuicClient::QuicDataToResend::QuicDataToResend(BalsaHeaders* headers,
128 StringPiece body,
129 bool fin)
130 : headers_(headers), body_(body), fin_(fin) {}
131
132 QuicClient::QuicDataToResend::~QuicDataToResend() {
133 if (headers_) {
134 delete headers_;
135 }
136 }
137
138 bool QuicClient::CreateUDPSocketAndBind() { 129 bool QuicClient::CreateUDPSocketAndBind() {
139 int fd = 130 int fd =
140 QuicSocketUtils::CreateUDPSocket(server_address_, &overflow_supported_); 131 QuicSocketUtils::CreateUDPSocket(server_address_, &overflow_supported_);
141 if (fd < 0) { 132 if (fd < 0) {
142 return false; 133 return false;
143 } 134 }
144 135
145 IPEndPoint client_address; 136 IPEndPoint client_address;
146 if (bind_to_address_.size() != 0) { 137 if (bind_to_address_.size() != 0) {
147 client_address = IPEndPoint(bind_to_address_, local_port_); 138 client_address = IPEndPoint(bind_to_address_, local_port_);
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 } 258 }
268 259
269 void QuicClient::CleanUpUDPSocketImpl(int fd) { 260 void QuicClient::CleanUpUDPSocketImpl(int fd) {
270 if (fd > -1) { 261 if (fd > -1) {
271 epoll_server_->UnregisterFD(fd); 262 epoll_server_->UnregisterFD(fd);
272 int rc = close(fd); 263 int rc = close(fd);
273 DCHECK_EQ(0, rc); 264 DCHECK_EQ(0, rc);
274 } 265 }
275 } 266 }
276 267
277 void QuicClient::SendRequest(const BalsaHeaders& headers, 268 void QuicClient::SendRequest(const SpdyHeaderBlock& headers,
278 StringPiece body, 269 StringPiece body,
279 bool fin) { 270 bool fin) {
280 QuicClientPushPromiseIndex::TryHandle* handle; 271 QuicClientPushPromiseIndex::TryHandle* handle;
281 QuicAsyncStatus rv = push_promise_index()->Try( 272 QuicAsyncStatus rv = push_promise_index()->Try(headers, this, &handle);
282 SpdyBalsaUtils::RequestHeadersToSpdyHeaders(headers), this, &handle);
283 if (rv == QUIC_SUCCESS) 273 if (rv == QUIC_SUCCESS)
284 return; 274 return;
285 275
286 if (rv == QUIC_PENDING) { 276 if (rv == QUIC_PENDING) {
287 // May need to retry request if asynchronous rendezvous fails. 277 // May need to retry request if asynchronous rendezvous fails.
288 auto* new_headers = new BalsaHeaders; 278 std::unique_ptr<SpdyHeaderBlock> new_headers(
289 new_headers->CopyFrom(headers); 279 new SpdyHeaderBlock(headers.Clone()));
290 push_promise_data_to_resend_.reset( 280 push_promise_data_to_resend_.reset(
291 new ClientQuicDataToResend(new_headers, body, fin, this)); 281 new ClientQuicDataToResend(std::move(new_headers), body, fin, this));
292 return; 282 return;
293 } 283 }
294 284
295 QuicSpdyClientStream* stream = CreateReliableClientStream(); 285 QuicSpdyClientStream* stream = CreateReliableClientStream();
296 if (stream == nullptr) { 286 if (stream == nullptr) {
297 QUIC_BUG << "stream creation failed!"; 287 QUIC_BUG << "stream creation failed!";
298 return; 288 return;
299 } 289 }
300 stream->SendRequest(SpdyBalsaUtils::RequestHeadersToSpdyHeaders(headers), 290 stream->SendRequest(headers.Clone(), body, fin);
301 body, fin);
302 if (FLAGS_enable_quic_stateless_reject_support) { 291 if (FLAGS_enable_quic_stateless_reject_support) {
303 // Record this in case we need to resend. 292 // Record this in case we need to resend.
304 auto* new_headers = new BalsaHeaders; 293 std::unique_ptr<SpdyHeaderBlock> new_headers(
305 new_headers->CopyFrom(headers); 294 new SpdyHeaderBlock(headers.Clone()));
306 auto* data_to_resend = 295 auto data_to_resend =
307 new ClientQuicDataToResend(new_headers, body, fin, this); 296 new ClientQuicDataToResend(std::move(new_headers), body, fin, this);
308 MaybeAddQuicDataToResend(std::unique_ptr<QuicDataToResend>(data_to_resend)); 297 MaybeAddQuicDataToResend(std::unique_ptr<QuicDataToResend>(data_to_resend));
309 } 298 }
310 } 299 }
311 300
312 void QuicClient::MaybeAddQuicDataToResend( 301 void QuicClient::MaybeAddQuicDataToResend(
313 std::unique_ptr<QuicDataToResend> data_to_resend) { 302 std::unique_ptr<QuicDataToResend> data_to_resend) {
314 DCHECK(FLAGS_enable_quic_stateless_reject_support); 303 DCHECK(FLAGS_enable_quic_stateless_reject_support);
315 if (session()->IsCryptoHandshakeConfirmed()) { 304 if (session()->IsCryptoHandshakeConfirmed()) {
316 // The handshake is confirmed. No need to continue saving requests to 305 // The handshake is confirmed. No need to continue saving requests to
317 // resend. 306 // resend.
318 data_to_resend_on_connect_.clear(); 307 data_to_resend_on_connect_.clear();
319 return; 308 return;
320 } 309 }
321 310
322 // The handshake is not confirmed. Push the data onto the queue of data to 311 // The handshake is not confirmed. Push the data onto the queue of data to
323 // resend if statelessly rejected. 312 // resend if statelessly rejected.
324 data_to_resend_on_connect_.push_back(std::move(data_to_resend)); 313 data_to_resend_on_connect_.push_back(std::move(data_to_resend));
325 } 314 }
326 315
327 void QuicClient::SendRequestAndWaitForResponse(const BalsaHeaders& headers, 316 void QuicClient::SendRequestAndWaitForResponse(const SpdyHeaderBlock& headers,
328 StringPiece body, 317 StringPiece body,
329 bool fin) { 318 bool fin) {
330 SendRequest(headers, body, fin); 319 SendRequest(headers, body, fin);
331 while (WaitForEvents()) { 320 while (WaitForEvents()) {
332 } 321 }
333 } 322 }
334 323
335 void QuicClient::SendRequestsAndWaitForResponse( 324 void QuicClient::SendRequestsAndWaitForResponse(
336 const vector<string>& url_list) { 325 const vector<string>& url_list) {
337 for (size_t i = 0; i < url_list.size(); ++i) { 326 for (size_t i = 0; i < url_list.size(); ++i) {
338 BalsaHeaders headers; 327 SpdyHeaderBlock headers;
339 headers.SetRequestFirstlineFromStringPieces("GET", url_list[i], "HTTP/1.1"); 328 if (!SpdyUtils::PopulateHeaderBlockFromUrl(url_list[i], &headers)) {
329 QUIC_BUG << "Unable to create request";
330 continue;
331 }
340 SendRequest(headers, "", true); 332 SendRequest(headers, "", true);
341 } 333 }
342 while (WaitForEvents()) { 334 while (WaitForEvents()) {
343 } 335 }
344 } 336 }
345 337
346 QuicSpdyClientStream* QuicClient::CreateReliableClientStream() { 338 QuicSpdyClientStream* QuicClient::CreateReliableClientStream() {
347 QuicSpdyClientStream* stream = QuicClientBase::CreateReliableClientStream(); 339 QuicSpdyClientStream* stream = QuicClientBase::CreateReliableClientStream();
348 if (stream) { 340 if (stream) {
349 stream->set_visitor(this); 341 stream->set_visitor(this);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 } 401 }
410 if (event->in_events & EPOLLERR) { 402 if (event->in_events & EPOLLERR) {
411 DVLOG(1) << "Epollerr"; 403 DVLOG(1) << "Epollerr";
412 } 404 }
413 } 405 }
414 406
415 void QuicClient::OnClose(QuicSpdyStream* stream) { 407 void QuicClient::OnClose(QuicSpdyStream* stream) {
416 DCHECK(stream != nullptr); 408 DCHECK(stream != nullptr);
417 QuicSpdyClientStream* client_stream = 409 QuicSpdyClientStream* client_stream =
418 static_cast<QuicSpdyClientStream*>(stream); 410 static_cast<QuicSpdyClientStream*>(stream);
419 BalsaHeaders response_headers;
420 SpdyBalsaUtils::SpdyHeadersToResponseHeaders(
421 client_stream->response_headers(), &response_headers);
422 411
412 const SpdyHeaderBlock& response_headers = client_stream->response_headers();
423 if (response_listener_.get() != nullptr) { 413 if (response_listener_.get() != nullptr) {
424 response_listener_->OnCompleteResponse(stream->id(), response_headers, 414 response_listener_->OnCompleteResponse(stream->id(), response_headers,
425 client_stream->data()); 415 client_stream->data());
426 } 416 }
427 417
428 // Store response headers and body. 418 // Store response headers and body.
429 if (store_response_) { 419 if (store_response_) {
430 latest_response_code_ = response_headers.parsed_response_code(); 420 auto status = response_headers.find(":status");
431 response_headers.DumpHeadersToString(&latest_response_headers_); 421 if (status == response_headers.end() ||
422 !StringToInt(status->second, &latest_response_code_)) {
423 LOG(ERROR) << "Invalid response headers: no status code";
424 }
425 latest_response_headers_ = response_headers.DebugString();
426 latest_response_header_block_ = response_headers.Clone();
432 latest_response_body_ = client_stream->data(); 427 latest_response_body_ = client_stream->data();
433 latest_response_trailers_ = 428 latest_response_trailers_ =
434 client_stream->received_trailers().DebugString(); 429 client_stream->received_trailers().DebugString();
435 } 430 }
436 } 431 }
437 432
438 bool QuicClient::CheckVary(const SpdyHeaderBlock& client_request, 433 bool QuicClient::CheckVary(const SpdyHeaderBlock& client_request,
439 const SpdyHeaderBlock& promise_request, 434 const SpdyHeaderBlock& promise_request,
440 const SpdyHeaderBlock& promise_response) { 435 const SpdyHeaderBlock& promise_response) {
441 return true; 436 return true;
(...skipping 13 matching lines...) Expand all
455 size_t QuicClient::latest_response_code() const { 450 size_t QuicClient::latest_response_code() const {
456 QUIC_BUG_IF(!store_response_) << "Response not stored!"; 451 QUIC_BUG_IF(!store_response_) << "Response not stored!";
457 return latest_response_code_; 452 return latest_response_code_;
458 } 453 }
459 454
460 const string& QuicClient::latest_response_headers() const { 455 const string& QuicClient::latest_response_headers() const {
461 QUIC_BUG_IF(!store_response_) << "Response not stored!"; 456 QUIC_BUG_IF(!store_response_) << "Response not stored!";
462 return latest_response_headers_; 457 return latest_response_headers_;
463 } 458 }
464 459
460 const SpdyHeaderBlock& QuicClient::latest_response_header_block() const {
461 QUIC_BUG_IF(!store_response_) << "Response not stored!";
462 return latest_response_header_block_;
463 }
464
465 const string& QuicClient::latest_response_body() const { 465 const string& QuicClient::latest_response_body() const {
466 QUIC_BUG_IF(!store_response_) << "Response not stored!"; 466 QUIC_BUG_IF(!store_response_) << "Response not stored!";
467 return latest_response_body_; 467 return latest_response_body_;
468 } 468 }
469 469
470 const string& QuicClient::latest_response_trailers() const { 470 const string& QuicClient::latest_response_trailers() const {
471 QUIC_BUG_IF(!store_response_) << "Response not stored!"; 471 QUIC_BUG_IF(!store_response_) << "Response not stored!";
472 return latest_response_trailers_; 472 return latest_response_trailers_;
473 } 473 }
474 474
(...skipping 17 matching lines...) Expand all
492 return fd_address_map_.back().first; 492 return fd_address_map_.back().first;
493 } 493 }
494 494
495 void QuicClient::ProcessPacket(const IPEndPoint& self_address, 495 void QuicClient::ProcessPacket(const IPEndPoint& self_address,
496 const IPEndPoint& peer_address, 496 const IPEndPoint& peer_address,
497 const QuicReceivedPacket& packet) { 497 const QuicReceivedPacket& packet) {
498 session()->connection()->ProcessUdpPacket(self_address, peer_address, packet); 498 session()->connection()->ProcessUdpPacket(self_address, peer_address, packet);
499 } 499 }
500 500
501 } // namespace net 501 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698