• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/http/http_basic_state.h"
6 
7 #include <set>
8 #include <utility>
9 
10 #include "base/check_op.h"
11 #include "base/no_destructor.h"
12 #include "net/base/io_buffer.h"
13 #include "net/base/ip_endpoint.h"
14 #include "net/base/load_timing_info.h"
15 #include "net/base/net_errors.h"
16 #include "net/http/http_request_info.h"
17 #include "net/http/http_response_body_drainer.h"
18 #include "net/http/http_stream_parser.h"
19 #include "net/http/http_util.h"
20 #include "net/socket/stream_socket.h"
21 #include "net/socket/stream_socket_handle.h"
22 #include "net/ssl/ssl_info.h"
23 #include "url/gurl.h"
24 
25 namespace net {
26 
HttpBasicState(std::unique_ptr<StreamSocketHandle> connection,bool is_for_get_to_http_proxy)27 HttpBasicState::HttpBasicState(std::unique_ptr<StreamSocketHandle> connection,
28                                bool is_for_get_to_http_proxy)
29     : read_buf_(base::MakeRefCounted<GrowableIOBuffer>()),
30       connection_(std::move(connection)),
31       is_for_get_to_http_proxy_(is_for_get_to_http_proxy) {
32   CHECK(connection_) << "StreamSocketHandle passed to HttpBasicState must "
33                         "not be NULL. See crbug.com/790776";
34 }
35 
36 HttpBasicState::~HttpBasicState() = default;
37 
Initialize(const HttpRequestInfo * request_info,RequestPriority priority,const NetLogWithSource & net_log)38 void HttpBasicState::Initialize(const HttpRequestInfo* request_info,
39                                 RequestPriority priority,
40                                 const NetLogWithSource& net_log) {
41   DCHECK(!parser_.get());
42   traffic_annotation_ = request_info->traffic_annotation;
43   parser_ = std::make_unique<HttpStreamParser>(
44       connection_->socket(),
45       connection_->reuse_type() ==
46           StreamSocketHandle::SocketReuseType::kReusedIdle,
47       request_info->url, request_info->method, request_info->upload_data_stream,
48       read_buf_.get(), net_log);
49 }
50 
Close(bool not_reusable)51 void HttpBasicState::Close(bool not_reusable) {
52   // `parser_` is null if the owner of `this` is created by an orphaned
53   // HttpStreamFactory::Job in which case InitializeStream() will not have been
54   // called. This also protects against null dereference in the case where
55   // ReleaseConnection() has been called.
56   //
57   // TODO(mmenke):  Can these cases be handled a bit more cleanly?
58   if (!parser_) {
59     return;
60   }
61   StreamSocket* socket = connection_->socket();
62   if (not_reusable && socket) {
63     socket->Disconnect();
64   }
65   parser()->OnConnectionClose();
66   connection_->Reset();
67 }
68 
ReleaseConnection()69 std::unique_ptr<StreamSocketHandle> HttpBasicState::ReleaseConnection() {
70   // The HttpStreamParser object still has a pointer to the connection. Just to
71   // be extra-sure it doesn't touch the connection again, delete it here rather
72   // than leaving it until the destructor is called.
73   parser_.reset();
74   return std::move(connection_);
75 }
76 
read_buf() const77 scoped_refptr<GrowableIOBuffer> HttpBasicState::read_buf() const {
78   return read_buf_;
79 }
80 
GenerateRequestLine() const81 std::string HttpBasicState::GenerateRequestLine() const {
82   return HttpUtil::GenerateRequestLine(parser_->method(), parser_->url(),
83                                        is_for_get_to_http_proxy_);
84 }
85 
IsConnectionReused() const86 bool HttpBasicState::IsConnectionReused() const {
87   return connection_->reuse_type() ==
88              StreamSocketHandle::SocketReuseType::kReusedIdle ||
89          connection_->reuse_type() ==
90              StreamSocketHandle::SocketReuseType::kUnusedIdle;
91 }
92 
SetConnectionReused()93 void HttpBasicState::SetConnectionReused() {
94   connection_->set_reuse_type(StreamSocketHandle::SocketReuseType::kReusedIdle);
95 }
96 
CanReuseConnection() const97 bool HttpBasicState::CanReuseConnection() const {
98   return parser_ && connection_->socket() && parser_->CanReuseConnection();
99 }
100 
GetLoadTimingInfo(LoadTimingInfo * load_timing_info) const101 bool HttpBasicState::GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const {
102   return connection_->GetLoadTimingInfo(IsConnectionReused(), load_timing_info);
103 }
104 
GetSSLInfo(SSLInfo * ssl_info)105 void HttpBasicState::GetSSLInfo(SSLInfo* ssl_info) {
106   CHECK(connection_);
107   if (!connection_->socket() || !connection_->socket()->GetSSLInfo(ssl_info)) {
108     *ssl_info = SSLInfo();
109   }
110 }
111 
GetRemoteEndpoint(IPEndPoint * endpoint)112 int HttpBasicState::GetRemoteEndpoint(IPEndPoint* endpoint) {
113   if (!connection_ || !connection_->socket()) {
114     return ERR_SOCKET_NOT_CONNECTED;
115   }
116   return connection_->socket()->GetPeerAddress(endpoint);
117 }
118 
GetDnsAliases() const119 const std::set<std::string>& HttpBasicState::GetDnsAliases() const {
120   static const base::NoDestructor<std::set<std::string>> emptyset_result;
121   return (connection_ && connection_->socket())
122              ? connection_->socket()->GetDnsAliases()
123              : *emptyset_result;
124 }
125 
126 }  // namespace net
127