OLD | NEW |
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2015 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_base.h" | 5 #include "net/tools/quic/quic_client_base.h" |
6 | 6 |
| 7 #include "base/strings/string_number_conversions.h" |
7 #include "net/quic/core/crypto/quic_random.h" | 8 #include "net/quic/core/crypto/quic_random.h" |
8 #include "net/quic/core/quic_server_id.h" | 9 #include "net/quic/core/quic_server_id.h" |
9 | 10 |
10 using base::StringPiece; | 11 using base::StringPiece; |
| 12 using base::StringToInt; |
| 13 using std::string; |
11 | 14 |
12 namespace net { | 15 namespace net { |
13 | 16 |
14 void QuicClientBase::ClientQuicDataToResend::Resend() { | 17 void QuicClientBase::ClientQuicDataToResend::Resend() { |
15 client_->SendRequest(*headers_, body_, fin_); | 18 client_->SendRequest(*headers_, body_, fin_); |
16 headers_ = nullptr; | 19 headers_ = nullptr; |
17 } | 20 } |
18 | 21 |
19 QuicClientBase::QuicDataToResend::QuicDataToResend( | 22 QuicClientBase::QuicDataToResend::QuicDataToResend( |
20 std::unique_ptr<SpdyHeaderBlock> headers, | 23 std::unique_ptr<SpdyHeaderBlock> headers, |
21 StringPiece body, | 24 StringPiece body, |
22 bool fin) | 25 bool fin) |
23 : headers_(std::move(headers)), body_(body), fin_(fin) {} | 26 : headers_(std::move(headers)), body_(body), fin_(fin) {} |
24 | 27 |
25 QuicClientBase::QuicDataToResend::~QuicDataToResend() {} | 28 QuicClientBase::QuicDataToResend::~QuicDataToResend() {} |
26 | 29 |
27 QuicClientBase::QuicClientBase(const QuicServerId& server_id, | 30 QuicClientBase::QuicClientBase(const QuicServerId& server_id, |
28 const QuicVersionVector& supported_versions, | 31 const QuicVersionVector& supported_versions, |
29 const QuicConfig& config, | 32 const QuicConfig& config, |
30 QuicConnectionHelperInterface* helper, | 33 QuicConnectionHelperInterface* helper, |
31 QuicAlarmFactory* alarm_factory, | 34 QuicAlarmFactory* alarm_factory, |
32 std::unique_ptr<ProofVerifier> proof_verifier) | 35 std::unique_ptr<ProofVerifier> proof_verifier) |
33 : server_id_(server_id), | 36 : server_id_(server_id), |
| 37 local_port_(0), |
34 config_(config), | 38 config_(config), |
35 crypto_config_(std::move(proof_verifier)), | 39 crypto_config_(std::move(proof_verifier)), |
36 helper_(helper), | 40 helper_(helper), |
37 alarm_factory_(alarm_factory), | 41 alarm_factory_(alarm_factory), |
38 supported_versions_(supported_versions), | 42 supported_versions_(supported_versions), |
39 initial_max_packet_length_(0), | 43 initial_max_packet_length_(0), |
40 num_stateless_rejects_received_(0), | 44 num_stateless_rejects_received_(0), |
41 num_sent_client_hellos_(0), | 45 num_sent_client_hellos_(0), |
42 connection_error_(QUIC_NO_ERROR), | 46 connection_error_(QUIC_NO_ERROR), |
43 connected_or_attempting_connect_(false) {} | 47 connected_or_attempting_connect_(false), |
| 48 store_response_(false), |
| 49 latest_response_code_(-1) {} |
44 | 50 |
45 QuicClientBase::~QuicClientBase() {} | 51 QuicClientBase::~QuicClientBase() {} |
46 | 52 |
| 53 void QuicClientBase::OnClose(QuicSpdyStream* stream) { |
| 54 DCHECK(stream != nullptr); |
| 55 QuicSpdyClientStream* client_stream = |
| 56 static_cast<QuicSpdyClientStream*>(stream); |
| 57 |
| 58 const SpdyHeaderBlock& response_headers = client_stream->response_headers(); |
| 59 if (response_listener_ != nullptr) { |
| 60 response_listener_->OnCompleteResponse(stream->id(), response_headers, |
| 61 client_stream->data()); |
| 62 } |
| 63 |
| 64 // Store response headers and body. |
| 65 if (store_response_) { |
| 66 auto status = response_headers.find(":status"); |
| 67 if (status == response_headers.end() || |
| 68 !StringToInt(status->second, &latest_response_code_)) { |
| 69 LOG(ERROR) << "Invalid response headers"; |
| 70 } |
| 71 latest_response_headers_ = response_headers.DebugString(); |
| 72 latest_response_body_ = client_stream->data(); |
| 73 latest_response_trailers_ = |
| 74 client_stream->received_trailers().DebugString(); |
| 75 } |
| 76 } |
| 77 |
47 bool QuicClientBase::Initialize() { | 78 bool QuicClientBase::Initialize() { |
48 num_sent_client_hellos_ = 0; | 79 num_sent_client_hellos_ = 0; |
49 num_stateless_rejects_received_ = 0; | 80 num_stateless_rejects_received_ = 0; |
50 connection_error_ = QUIC_NO_ERROR; | 81 connection_error_ = QUIC_NO_ERROR; |
51 connected_or_attempting_connect_ = false; | 82 connected_or_attempting_connect_ = false; |
52 return true; | 83 return true; |
53 } | 84 } |
54 | 85 |
55 ProofVerifier* QuicClientBase::proof_verifier() const { | 86 ProofVerifier* QuicClientBase::proof_verifier() const { |
56 return crypto_config_.proof_verifier(); | 87 return crypto_config_.proof_verifier(); |
(...skipping 12 matching lines...) Expand all Loading... |
69 bool QuicClientBase::EncryptionBeingEstablished() { | 100 bool QuicClientBase::EncryptionBeingEstablished() { |
70 return !session_->IsEncryptionEstablished() && | 101 return !session_->IsEncryptionEstablished() && |
71 session_->connection()->connected(); | 102 session_->connection()->connected(); |
72 } | 103 } |
73 | 104 |
74 QuicSpdyClientStream* QuicClientBase::CreateReliableClientStream() { | 105 QuicSpdyClientStream* QuicClientBase::CreateReliableClientStream() { |
75 if (!connected()) { | 106 if (!connected()) { |
76 return nullptr; | 107 return nullptr; |
77 } | 108 } |
78 | 109 |
79 return session_->CreateOutgoingDynamicStream(kDefaultPriority); | 110 QuicSpdyClientStream* stream = |
| 111 session_->CreateOutgoingDynamicStream(kDefaultPriority); |
| 112 if (stream) { |
| 113 stream->set_visitor(this); |
| 114 } |
| 115 return stream; |
80 } | 116 } |
81 | 117 |
82 void QuicClientBase::WaitForStreamToClose(QuicStreamId id) { | 118 void QuicClientBase::WaitForStreamToClose(QuicStreamId id) { |
83 DCHECK(connected()); | 119 DCHECK(connected()); |
84 | 120 |
85 while (connected() && !session_->IsClosedStream(id)) { | 121 while (connected() && !session_->IsClosedStream(id)) { |
86 WaitForEvents(); | 122 WaitForEvents(); |
87 } | 123 } |
88 } | 124 } |
89 | 125 |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 void QuicClientBase::MaybeAddQuicDataToResend( | 227 void QuicClientBase::MaybeAddQuicDataToResend( |
192 std::unique_ptr<QuicDataToResend> data_to_resend) { | 228 std::unique_ptr<QuicDataToResend> data_to_resend) { |
193 data_to_resend_on_connect_.push_back(std::move(data_to_resend)); | 229 data_to_resend_on_connect_.push_back(std::move(data_to_resend)); |
194 } | 230 } |
195 | 231 |
196 void QuicClientBase::ClearDataToResend() { | 232 void QuicClientBase::ClearDataToResend() { |
197 data_to_resend_on_connect_.clear(); | 233 data_to_resend_on_connect_.clear(); |
198 } | 234 } |
199 | 235 |
200 void QuicClientBase::ResendSavedData() { | 236 void QuicClientBase::ResendSavedData() { |
201 for (const auto& data : data_to_resend_on_connect_) { | 237 // Calling Resend will re-enqueue the data, so swap out |
| 238 // data_to_resend_on_connect_ before iterating. |
| 239 std::vector<std::unique_ptr<QuicDataToResend>> old_data; |
| 240 old_data.swap(data_to_resend_on_connect_); |
| 241 for (const auto& data : old_data) { |
202 data->Resend(); | 242 data->Resend(); |
203 } | 243 } |
204 data_to_resend_on_connect_.clear(); | 244 data_to_resend_on_connect_.clear(); |
205 } | 245 } |
206 | 246 |
207 void QuicClientBase::AddPromiseDataToResend(const SpdyHeaderBlock& headers, | 247 void QuicClientBase::AddPromiseDataToResend(const SpdyHeaderBlock& headers, |
208 StringPiece body, | 248 StringPiece body, |
209 bool fin) { | 249 bool fin) { |
210 std::unique_ptr<SpdyHeaderBlock> new_headers( | 250 std::unique_ptr<SpdyHeaderBlock> new_headers( |
211 new SpdyHeaderBlock(headers.Clone())); | 251 new SpdyHeaderBlock(headers.Clone())); |
(...skipping 11 matching lines...) Expand all Loading... |
223 std::unique_ptr<ClientQuicDataToResend> data_to_resend = | 263 std::unique_ptr<ClientQuicDataToResend> data_to_resend = |
224 std::move(push_promise_data_to_resend_); | 264 std::move(push_promise_data_to_resend_); |
225 if (stream) { | 265 if (stream) { |
226 stream->set_visitor(this); | 266 stream->set_visitor(this); |
227 stream->OnDataAvailable(); | 267 stream->OnDataAvailable(); |
228 } else if (data_to_resend.get()) { | 268 } else if (data_to_resend.get()) { |
229 data_to_resend->Resend(); | 269 data_to_resend->Resend(); |
230 } | 270 } |
231 } | 271 } |
232 | 272 |
| 273 size_t QuicClientBase::latest_response_code() const { |
| 274 QUIC_BUG_IF(!store_response_) << "Response not stored!"; |
| 275 return latest_response_code_; |
| 276 } |
| 277 |
| 278 const string& QuicClientBase::latest_response_headers() const { |
| 279 QUIC_BUG_IF(!store_response_) << "Response not stored!"; |
| 280 return latest_response_headers_; |
| 281 } |
| 282 |
| 283 const SpdyHeaderBlock& QuicClientBase::latest_response_header_block() const { |
| 284 QUIC_BUG_IF(!store_response_) << "Response not stored!"; |
| 285 return latest_response_header_block_; |
| 286 } |
| 287 |
| 288 const string& QuicClientBase::latest_response_body() const { |
| 289 QUIC_BUG_IF(!store_response_) << "Response not stored!"; |
| 290 return latest_response_body_; |
| 291 } |
| 292 |
| 293 const string& QuicClientBase::latest_response_trailers() const { |
| 294 QUIC_BUG_IF(!store_response_) << "Response not stored!"; |
| 295 return latest_response_trailers_; |
| 296 } |
| 297 |
233 } // namespace net | 298 } // namespace net |
OLD | NEW |