OLD | NEW |
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> |
(...skipping 10 matching lines...) Expand all Loading... |
21 #include "net/tools/balsa/balsa_headers.h" | 21 #include "net/tools/balsa/balsa_headers.h" |
22 #include "net/tools/epoll_server/epoll_server.h" | 22 #include "net/tools/epoll_server/epoll_server.h" |
23 #include "net/tools/quic/quic_epoll_connection_helper.h" | 23 #include "net/tools/quic/quic_epoll_connection_helper.h" |
24 #include "net/tools/quic/quic_socket_utils.h" | 24 #include "net/tools/quic/quic_socket_utils.h" |
25 #include "net/tools/quic/quic_spdy_client_stream.h" | 25 #include "net/tools/quic/quic_spdy_client_stream.h" |
26 | 26 |
27 #ifndef SO_RXQ_OVFL | 27 #ifndef SO_RXQ_OVFL |
28 #define SO_RXQ_OVFL 40 | 28 #define SO_RXQ_OVFL 40 |
29 #endif | 29 #endif |
30 | 30 |
| 31 using std::string; |
| 32 |
31 namespace net { | 33 namespace net { |
32 namespace tools { | 34 namespace tools { |
33 | 35 |
34 const int kEpollFlags = EPOLLIN | EPOLLOUT | EPOLLET; | 36 const int kEpollFlags = EPOLLIN | EPOLLOUT | EPOLLET; |
35 | 37 |
36 QuicClient::QuicClient(IPEndPoint server_address, | 38 QuicClient::QuicClient(IPEndPoint server_address, |
37 const QuicServerId& server_id, | 39 const QuicServerId& server_id, |
38 const QuicVersionVector& supported_versions, | 40 const QuicVersionVector& supported_versions, |
39 bool print_response, | |
40 EpollServer* epoll_server) | 41 EpollServer* epoll_server) |
41 : server_address_(server_address), | 42 : server_address_(server_address), |
42 server_id_(server_id), | 43 server_id_(server_id), |
43 local_port_(0), | 44 local_port_(0), |
44 epoll_server_(epoll_server), | 45 epoll_server_(epoll_server), |
45 fd_(-1), | 46 fd_(-1), |
46 helper_(CreateQuicConnectionHelper()), | 47 helper_(CreateQuicConnectionHelper()), |
47 initialized_(false), | 48 initialized_(false), |
48 packets_dropped_(0), | 49 packets_dropped_(0), |
49 overflow_supported_(false), | 50 overflow_supported_(false), |
50 supported_versions_(supported_versions), | 51 supported_versions_(supported_versions), |
51 print_response_(print_response) { | 52 store_response_(false), |
| 53 latest_response_code_(-1) { |
52 } | 54 } |
53 | 55 |
54 QuicClient::QuicClient(IPEndPoint server_address, | 56 QuicClient::QuicClient(IPEndPoint server_address, |
55 const QuicServerId& server_id, | 57 const QuicServerId& server_id, |
56 const QuicVersionVector& supported_versions, | 58 const QuicVersionVector& supported_versions, |
57 bool print_response, | |
58 const QuicConfig& config, | 59 const QuicConfig& config, |
59 EpollServer* epoll_server) | 60 EpollServer* epoll_server) |
60 : server_address_(server_address), | 61 : server_address_(server_address), |
61 server_id_(server_id), | 62 server_id_(server_id), |
62 config_(config), | 63 config_(config), |
63 local_port_(0), | 64 local_port_(0), |
64 epoll_server_(epoll_server), | 65 epoll_server_(epoll_server), |
65 fd_(-1), | 66 fd_(-1), |
66 helper_(CreateQuicConnectionHelper()), | 67 helper_(CreateQuicConnectionHelper()), |
67 initialized_(false), | 68 initialized_(false), |
68 packets_dropped_(0), | 69 packets_dropped_(0), |
69 overflow_supported_(false), | 70 overflow_supported_(false), |
70 supported_versions_(supported_versions), | 71 supported_versions_(supported_versions), |
71 print_response_(print_response) { | 72 store_response_(false), |
| 73 latest_response_code_(-1) { |
72 } | 74 } |
73 | 75 |
74 QuicClient::~QuicClient() { | 76 QuicClient::~QuicClient() { |
75 if (connected()) { | 77 if (connected()) { |
76 session()->connection()->SendConnectionClosePacket( | 78 session()->connection()->SendConnectionClosePacket( |
77 QUIC_PEER_GOING_AWAY, ""); | 79 QUIC_PEER_GOING_AWAY, ""); |
78 } | 80 } |
79 | 81 |
80 CleanUpUDPSocket(); | 82 CleanUpUDPSocket(); |
81 } | 83 } |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 } | 240 } |
239 | 241 |
240 void QuicClient::CleanUpUDPSocket() { | 242 void QuicClient::CleanUpUDPSocket() { |
241 if (fd_ > -1) { | 243 if (fd_ > -1) { |
242 epoll_server_->UnregisterFD(fd_); | 244 epoll_server_->UnregisterFD(fd_); |
243 close(fd_); | 245 close(fd_); |
244 fd_ = -1; | 246 fd_ = -1; |
245 } | 247 } |
246 } | 248 } |
247 | 249 |
| 250 void QuicClient::SendRequest(const BalsaHeaders& headers, |
| 251 StringPiece body, |
| 252 bool fin) { |
| 253 QuicSpdyClientStream* stream = CreateReliableClientStream(); |
| 254 if (stream == nullptr) { |
| 255 LOG(DFATAL) << "stream creation failed!"; |
| 256 return; |
| 257 } |
| 258 stream->SendRequest(headers, body, fin); |
| 259 stream->set_visitor(this); |
| 260 } |
| 261 |
| 262 void QuicClient::SendRequestAndWaitForResponse(const BalsaHeaders& headers, |
| 263 StringPiece body, |
| 264 bool fin) { |
| 265 SendRequest(headers, "", true); |
| 266 while (WaitForEvents()) { |
| 267 } |
| 268 } |
| 269 |
248 void QuicClient::SendRequestsAndWaitForResponse( | 270 void QuicClient::SendRequestsAndWaitForResponse( |
249 const base::CommandLine::StringVector& args) { | 271 const base::CommandLine::StringVector& args) { |
250 for (size_t i = 0; i < args.size(); ++i) { | 272 for (size_t i = 0; i < args.size(); ++i) { |
251 BalsaHeaders headers; | 273 BalsaHeaders headers; |
252 headers.SetRequestFirstlineFromStringPieces("GET", args[i], "HTTP/1.1"); | 274 headers.SetRequestFirstlineFromStringPieces("GET", args[i], "HTTP/1.1"); |
253 QuicSpdyClientStream* stream = CreateReliableClientStream(); | 275 SendRequest(headers, "", true); |
254 DCHECK(stream != nullptr); | |
255 if (stream == nullptr) { | |
256 LOG(ERROR) << "stream creation failed!"; | |
257 break; | |
258 } | |
259 stream->SendRequest(headers, "", true); | |
260 stream->set_visitor(this); | |
261 } | 276 } |
262 | |
263 while (WaitForEvents()) {} | 277 while (WaitForEvents()) {} |
264 } | 278 } |
265 | 279 |
266 QuicSpdyClientStream* QuicClient::CreateReliableClientStream() { | 280 QuicSpdyClientStream* QuicClient::CreateReliableClientStream() { |
267 if (!connected()) { | 281 if (!connected()) { |
268 return nullptr; | 282 return nullptr; |
269 } | 283 } |
270 | 284 |
271 return session_->CreateOutgoingDataStream(); | 285 return session_->CreateOutgoingDataStream(); |
272 } | 286 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 } | 325 } |
312 | 326 |
313 void QuicClient::OnClose(QuicDataStream* stream) { | 327 void QuicClient::OnClose(QuicDataStream* stream) { |
314 QuicSpdyClientStream* client_stream = | 328 QuicSpdyClientStream* client_stream = |
315 static_cast<QuicSpdyClientStream*>(stream); | 329 static_cast<QuicSpdyClientStream*>(stream); |
316 if (response_listener_.get() != nullptr) { | 330 if (response_listener_.get() != nullptr) { |
317 response_listener_->OnCompleteResponse( | 331 response_listener_->OnCompleteResponse( |
318 stream->id(), client_stream->headers(), client_stream->data()); | 332 stream->id(), client_stream->headers(), client_stream->data()); |
319 } | 333 } |
320 | 334 |
321 if (!print_response_) { | 335 // Store response headers and body. |
322 return; | 336 if (store_response_) { |
| 337 latest_response_code_ = client_stream->headers().parsed_response_code(); |
| 338 client_stream->headers().DumpHeadersToString(&latest_response_headers_); |
| 339 latest_response_body_ = client_stream->data(); |
323 } | 340 } |
324 | |
325 const BalsaHeaders& headers = client_stream->headers(); | |
326 printf("%s\n", headers.first_line().as_string().c_str()); | |
327 for (BalsaHeaders::const_header_lines_iterator i = | |
328 headers.header_lines_begin(); | |
329 i != headers.header_lines_end(); ++i) { | |
330 printf("%s: %s\n", i->first.as_string().c_str(), | |
331 i->second.as_string().c_str()); | |
332 } | |
333 printf("%s\n", client_stream->data().c_str()); | |
334 } | 341 } |
335 | 342 |
336 bool QuicClient::connected() const { | 343 bool QuicClient::connected() const { |
337 return session_.get() && session_->connection() && | 344 return session_.get() && session_->connection() && |
338 session_->connection()->connected(); | 345 session_->connection()->connected(); |
339 } | 346 } |
340 | 347 |
341 bool QuicClient::goaway_received() const { | 348 bool QuicClient::goaway_received() const { |
342 return session_ != nullptr && session_->goaway_received(); | 349 return session_ != nullptr && session_->goaway_received(); |
343 } | 350 } |
344 | 351 |
| 352 size_t QuicClient::latest_response_code() const { |
| 353 LOG_IF(DFATAL, !store_response_) << "Response not stored!"; |
| 354 return latest_response_code_; |
| 355 } |
| 356 |
| 357 const string& QuicClient::latest_response_headers() const { |
| 358 LOG_IF(DFATAL, !store_response_) << "Response not stored!"; |
| 359 return latest_response_headers_; |
| 360 } |
| 361 |
| 362 const string& QuicClient::latest_response_body() const { |
| 363 LOG_IF(DFATAL, !store_response_) << "Response not stored!"; |
| 364 return latest_response_body_; |
| 365 } |
| 366 |
345 QuicConnectionId QuicClient::GenerateConnectionId() { | 367 QuicConnectionId QuicClient::GenerateConnectionId() { |
346 return QuicRandom::GetInstance()->RandUint64(); | 368 return QuicRandom::GetInstance()->RandUint64(); |
347 } | 369 } |
348 | 370 |
349 QuicEpollConnectionHelper* QuicClient::CreateQuicConnectionHelper() { | 371 QuicEpollConnectionHelper* QuicClient::CreateQuicConnectionHelper() { |
350 return new QuicEpollConnectionHelper(epoll_server_); | 372 return new QuicEpollConnectionHelper(epoll_server_); |
351 } | 373 } |
352 | 374 |
353 QuicPacketWriter* QuicClient::CreateQuicPacketWriter() { | 375 QuicPacketWriter* QuicClient::CreateQuicPacketWriter() { |
354 return new QuicDefaultPacketWriter(fd_); | 376 return new QuicDefaultPacketWriter(fd_); |
(...skipping 26 matching lines...) Expand all Loading... |
381 QuicEncryptedPacket packet(buf, bytes_read, false); | 403 QuicEncryptedPacket packet(buf, bytes_read, false); |
382 | 404 |
383 IPEndPoint client_address(client_ip, client_address_.port()); | 405 IPEndPoint client_address(client_ip, client_address_.port()); |
384 session_->connection()->ProcessUdpPacket( | 406 session_->connection()->ProcessUdpPacket( |
385 client_address, server_address, packet); | 407 client_address, server_address, packet); |
386 return true; | 408 return true; |
387 } | 409 } |
388 | 410 |
389 } // namespace tools | 411 } // namespace tools |
390 } // namespace net | 412 } // namespace net |
OLD | NEW |