http_basic_stream.cc 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  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
  3. // found in the LICENSE file.
  4. #include "net/http/http_basic_stream.h"
  5. #include <set>
  6. #include <utility>
  7. #include "base/bind.h"
  8. #include "net/http/http_network_session.h"
  9. #include "net/http/http_raw_request_headers.h"
  10. #include "net/http/http_request_info.h"
  11. #include "net/http/http_response_body_drainer.h"
  12. #include "net/http/http_stream_parser.h"
  13. #include "net/socket/client_socket_handle.h"
  14. #include "net/ssl/ssl_cert_request_info.h"
  15. #include "net/ssl/ssl_info.h"
  16. namespace net {
  17. HttpBasicStream::HttpBasicStream(std::unique_ptr<ClientSocketHandle> connection,
  18. bool using_proxy)
  19. : state_(std::move(connection), using_proxy) {}
  20. HttpBasicStream::~HttpBasicStream() = default;
  21. void HttpBasicStream::RegisterRequest(const HttpRequestInfo* request_info) {
  22. DCHECK(request_info);
  23. DCHECK(request_info->traffic_annotation.is_valid());
  24. request_info_ = request_info;
  25. }
  26. int HttpBasicStream::InitializeStream(bool can_send_early,
  27. RequestPriority priority,
  28. const NetLogWithSource& net_log,
  29. CompletionOnceCallback callback) {
  30. DCHECK(request_info_);
  31. state_.Initialize(request_info_, priority, net_log);
  32. int ret = OK;
  33. if (!can_send_early) {
  34. // parser() cannot outlive |this|, so we can use base::Unretained().
  35. ret = parser()->ConfirmHandshake(
  36. base::BindOnce(&HttpBasicStream::OnHandshakeConfirmed,
  37. base::Unretained(this), std::move(callback)));
  38. }
  39. // RequestInfo is no longer needed after this point.
  40. request_info_ = nullptr;
  41. return ret;
  42. }
  43. int HttpBasicStream::SendRequest(const HttpRequestHeaders& headers,
  44. HttpResponseInfo* response,
  45. CompletionOnceCallback callback) {
  46. DCHECK(parser());
  47. if (request_headers_callback_) {
  48. HttpRawRequestHeaders raw_headers;
  49. raw_headers.set_request_line(state_.GenerateRequestLine());
  50. for (net::HttpRequestHeaders::Iterator it(headers); it.GetNext();)
  51. raw_headers.Add(it.name(), it.value());
  52. request_headers_callback_.Run(std::move(raw_headers));
  53. }
  54. return parser()->SendRequest(
  55. state_.GenerateRequestLine(), headers,
  56. NetworkTrafficAnnotationTag(state_.traffic_annotation()), response,
  57. std::move(callback));
  58. }
  59. int HttpBasicStream::ReadResponseHeaders(CompletionOnceCallback callback) {
  60. return parser()->ReadResponseHeaders(std::move(callback));
  61. }
  62. int HttpBasicStream::ReadResponseBody(IOBuffer* buf,
  63. int buf_len,
  64. CompletionOnceCallback callback) {
  65. return parser()->ReadResponseBody(buf, buf_len, std::move(callback));
  66. }
  67. void HttpBasicStream::Close(bool not_reusable) {
  68. // parser() is null if |this| is created by an orphaned HttpStreamFactory::Job
  69. // in which case InitializeStream() will not have been called. This also
  70. // protects against null dereference in the case where
  71. // state_.ReleaseConnection() has been called.
  72. //
  73. // TODO(mmenke): Can these cases be handled a bit more cleanly?
  74. // WebSocketHandshakeStream will need to be updated as well.
  75. if (!parser())
  76. return;
  77. StreamSocket* socket = state_.connection()->socket();
  78. if (not_reusable && socket)
  79. socket->Disconnect();
  80. parser()->OnConnectionClose();
  81. state_.connection()->Reset();
  82. }
  83. std::unique_ptr<HttpStream> HttpBasicStream::RenewStreamForAuth() {
  84. DCHECK(IsResponseBodyComplete());
  85. DCHECK(!parser()->IsMoreDataBuffered());
  86. // The HttpStreamParser object still has a pointer to the connection. Just to
  87. // be extra-sure it doesn't touch the connection again, delete it here rather
  88. // than leaving it until the destructor is called.
  89. state_.DeleteParser();
  90. return std::make_unique<HttpBasicStream>(state_.ReleaseConnection(),
  91. state_.using_proxy());
  92. }
  93. bool HttpBasicStream::IsResponseBodyComplete() const {
  94. return parser()->IsResponseBodyComplete();
  95. }
  96. bool HttpBasicStream::IsConnectionReused() const {
  97. return state_.IsConnectionReused();
  98. }
  99. void HttpBasicStream::SetConnectionReused() {
  100. state_.connection()->set_reuse_type(ClientSocketHandle::REUSED_IDLE);
  101. }
  102. bool HttpBasicStream::CanReuseConnection() const {
  103. return parser() && state_.connection()->socket() &&
  104. parser()->CanReuseConnection();
  105. }
  106. int64_t HttpBasicStream::GetTotalReceivedBytes() const {
  107. if (parser())
  108. return parser()->received_bytes();
  109. return 0;
  110. }
  111. int64_t HttpBasicStream::GetTotalSentBytes() const {
  112. if (parser())
  113. return parser()->sent_bytes();
  114. return 0;
  115. }
  116. bool HttpBasicStream::GetLoadTimingInfo(
  117. LoadTimingInfo* load_timing_info) const {
  118. if (!state_.connection()->GetLoadTimingInfo(IsConnectionReused(),
  119. load_timing_info) ||
  120. !parser()) {
  121. return false;
  122. }
  123. // If the request waited for handshake confirmation, shift |ssl_end| to
  124. // include that time.
  125. if (!load_timing_info->connect_timing.ssl_end.is_null() &&
  126. !confirm_handshake_end_.is_null()) {
  127. load_timing_info->connect_timing.ssl_end = confirm_handshake_end_;
  128. load_timing_info->connect_timing.connect_end = confirm_handshake_end_;
  129. }
  130. load_timing_info->receive_headers_start =
  131. parser()->first_response_start_time();
  132. load_timing_info->receive_non_informational_headers_start =
  133. parser()->non_informational_response_start_time();
  134. load_timing_info->first_early_hints_time = parser()->first_early_hints_time();
  135. return true;
  136. }
  137. bool HttpBasicStream::GetAlternativeService(
  138. AlternativeService* alternative_service) const {
  139. return false;
  140. }
  141. void HttpBasicStream::GetSSLInfo(SSLInfo* ssl_info) {
  142. if (!state_.connection()->socket()) {
  143. ssl_info->Reset();
  144. return;
  145. }
  146. parser()->GetSSLInfo(ssl_info);
  147. }
  148. void HttpBasicStream::GetSSLCertRequestInfo(
  149. SSLCertRequestInfo* cert_request_info) {
  150. if (!state_.connection()->socket()) {
  151. cert_request_info->Reset();
  152. return;
  153. }
  154. parser()->GetSSLCertRequestInfo(cert_request_info);
  155. }
  156. int HttpBasicStream::GetRemoteEndpoint(IPEndPoint* endpoint) {
  157. if (!state_.connection() || !state_.connection()->socket())
  158. return ERR_SOCKET_NOT_CONNECTED;
  159. return state_.connection()->socket()->GetPeerAddress(endpoint);
  160. }
  161. void HttpBasicStream::Drain(HttpNetworkSession* session) {
  162. session->StartResponseDrainer(
  163. std::make_unique<HttpResponseBodyDrainer>(this));
  164. // |drainer| will delete itself.
  165. }
  166. void HttpBasicStream::PopulateNetErrorDetails(NetErrorDetails* details) {
  167. // TODO(mmenke): Consumers don't actually care about HTTP version, but seems
  168. // like the right version should be reported, if headers were received.
  169. details->connection_info = HttpResponseInfo::CONNECTION_INFO_HTTP1_1;
  170. return;
  171. }
  172. void HttpBasicStream::SetPriority(RequestPriority priority) {
  173. // TODO(akalin): Plumb this through to |connection_|.
  174. }
  175. void HttpBasicStream::SetRequestHeadersCallback(
  176. RequestHeadersCallback callback) {
  177. request_headers_callback_ = std::move(callback);
  178. }
  179. const std::set<std::string>& HttpBasicStream::GetDnsAliases() const {
  180. return state_.GetDnsAliases();
  181. }
  182. base::StringPiece HttpBasicStream::GetAcceptChViaAlps() const {
  183. return {};
  184. }
  185. void HttpBasicStream::OnHandshakeConfirmed(CompletionOnceCallback callback,
  186. int rv) {
  187. if (rv == OK) {
  188. // Note this time is only recorded if ConfirmHandshake() completed
  189. // asynchronously. If it was synchronous, GetLoadTimingInfo() assumes the
  190. // handshake was already confirmed or there was nothing to confirm.
  191. confirm_handshake_end_ = base::TimeTicks::Now();
  192. }
  193. std::move(callback).Run(rv);
  194. }
  195. } // namespace net