1 #include "ace/INet/HTTP_ClientRequestHandler.h"
3 #if !defined (__ACE_INLINE__)
4 #include "ace/INet/HTTP_ClientRequestHandler.inl"
7 #include "ace/INet/INet_Log.h"
9 #include "ace/Functor_String.h"
11 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
17 SessionFactoryRegistry::SessionFactoryRegistry ()
21 SessionFactoryRegistry::~SessionFactoryRegistry ()
25 void SessionFactoryRegistry::register_session_factory (
26 const ACE_CString
& scheme
,
27 SessionFactory
* factory
)
30 this->factory_map_
.unbind (scheme
);
32 this->factory_map_
.rebind (scheme
, factory
);
36 SessionFactoryRegistry::find_session_factory (const ACE_CString
& scheme
)
38 SessionFactory
* factory
= 0;
39 this->factory_map_
.find (scheme
, factory
);
43 SessionFactoryRegistry
& SessionFactoryRegistry::instance ()
45 return *ACE_Singleton
<SessionFactoryRegistry
, ACE_SYNCH::MUTEX
>::instance ();
48 SessionHolder::SessionHolder ()
52 SessionHolder::~SessionHolder()
56 SessionFactory_Impl::SessionHolder_Impl::SessionHolder_Impl ()
61 SessionFactory_Impl::SessionHolder_Impl::~SessionHolder_Impl()
65 SessionBase
& SessionFactory_Impl::SessionHolder_Impl::session ()
67 return this->session_
;
70 SessionFactory_Impl
& SessionFactory_Impl::factory_
=
71 *ACE_Singleton
<SessionFactory_Impl
,ACE_SYNCH::NULL_MUTEX
>::instance ();
73 SessionFactory_Impl::SessionFactory_Impl ()
75 INET_DEBUG (6, (LM_INFO
, DLINFO
76 ACE_TEXT ("HTTP_SessionFactory_Impl::ctor - ")
77 ACE_TEXT ("registering session factory for scheme [%C]\n"),
78 URL::protocol ().c_str ()));
79 SessionFactoryRegistry::instance ().register_session_factory (URL::protocol (), this);
82 SessionFactory_Impl::~SessionFactory_Impl ()
86 ACE::INet::ConnectionHolder
*
87 SessionFactory_Impl::create_connection (
88 const ACE::INet::ConnectionKey
& key
) const
90 INET_TRACE ("HTTP_SessionFactory_Impl::create_connection");
92 const ClientRequestHandler::HttpConnectionKey
& ikey
=
93 dynamic_cast<const ClientRequestHandler::HttpConnectionKey
&> (key
);
95 SessionHolder_Impl
* session_holder
= 0;
96 ACE_NEW_RETURN (session_holder
,
97 SessionHolder_Impl (),
99 std::unique_ptr
<SessionHolder_Impl
> session_safe_ref (session_holder
);
101 (*session_holder
)->set_host (ikey
.host (), ikey
.port ());
102 if (ikey
.is_proxy_connection ())
104 (*session_holder
)->set_proxy_target (ikey
.proxy_target_host (),
105 ikey
.proxy_target_port ());
108 if ((*session_holder
)->connect (true))
110 return session_safe_ref
.release ();
116 ClientRequestHandler::HttpConnectionKey::HttpConnectionKey (
117 const ACE_CString
& host
,
119 : INetConnectionKey (host
, port
),
120 proxy_connection_ (false),
121 proxy_target_port_ (0)
125 ClientRequestHandler::HttpConnectionKey::HttpConnectionKey (
126 const ACE_CString
& proxy_host
,
128 const ACE_CString
& host
,
130 : INetConnectionKey (proxy_host
, proxy_port
),
131 proxy_connection_ (true),
132 proxy_target_host_ (host
),
133 proxy_target_port_ (port
)
137 ClientRequestHandler::HttpConnectionKey::~HttpConnectionKey()
141 u_long
ClientRequestHandler::HttpConnectionKey::hash () const
143 if (this->proxy_connection_
)
144 return ACE_Hash
<ACE_CString
>()(this->proxy_target_host_
) +
145 this->proxy_target_port_
+
146 (this->proxy_connection_
? 1 : 0);
148 return INetConnectionKey::hash () +
149 (this->proxy_connection_
? 1 : 0);
152 ACE::INet::ConnectionKey
* ClientRequestHandler::HttpConnectionKey::duplicate () const
154 ACE::INet::ConnectionKey
* k
= 0;
155 if (this->proxy_connection_
)
158 HttpConnectionKey (this->host (), this->port (),
159 this->proxy_target_host_
,
160 this->proxy_target_port_
),
166 HttpConnectionKey (this->host (), this->port ()),
172 bool ClientRequestHandler::HttpConnectionKey::equal (const ACE::INet::ConnectionKey
& key
) const
175 const HttpConnectionKey
& http_key
= dynamic_cast<const HttpConnectionKey
&> (key
);
176 return (INetConnectionKey::equal (key
) &&
177 this->proxy_connection_
== http_key
.is_proxy_connection () &&
178 (!this->proxy_connection_
||
179 (this->proxy_target_host_
== http_key
.proxy_target_host () &&
180 this->proxy_target_port_
== http_key
.proxy_target_port ())));
187 ClientRequestHandler::ClientRequestHandler ()
188 : request_ (Request::HTTP_1_0
),
193 ClientRequestHandler::~ClientRequestHandler ()
195 this->release_connection ();
198 bool ClientRequestHandler::is_response_ok () const
200 return this->response_
.get_status ().is_ok () &&
201 !const_cast<ClientRequestHandler
*> (this)->response_stream ().bad ();
204 std::istream
& ClientRequestHandler::handle_open_request (
205 const ACE::INet::URL_Base
& url
)
207 const URL
& http_url
= dynamic_cast<const URL
&> (url
);
208 return this->handle_get_request (http_url
);
211 std::istream
& ClientRequestHandler::handle_get_request (
214 bool connected
= false;
215 if (http_url
.has_proxy ())
216 connected
= this->initialize_connection (http_url
.get_scheme (),
218 http_url
.get_port (),
220 http_url
.get_proxy_host(),
221 http_url
.get_proxy_port ());
223 connected
= this->initialize_connection (http_url
.get_scheme (),
225 http_url
.get_port ());
229 this->request_
.reset (Request::HTTP_GET
,
230 http_url
.get_request_uri (),
231 this->request_
.get_version ());
233 this->response_
.reset ();
235 this->initialize_request (http_url
, this->request_
);
237 if (!this->session ()->send_request (this->request_
) ||
238 !this->session ()->receive_response (this->response_
))
240 this->close_connection ();
242 this->handle_request_error(http_url
);
247 this->handle_connection_error (http_url
);
250 return this->response_stream ();
253 void ClientRequestHandler::on_eof ()
255 this->release_connection ();
258 bool ClientRequestHandler::initialize_connection (const ACE_CString
& scheme
,
259 const ACE_CString
& host
,
262 const ACE_CString
& proxy_host
,
265 SessionFactory
* session_factory
=
266 SessionFactoryRegistry::instance ().find_session_factory (scheme
);
268 if (session_factory
== 0)
270 INET_ERROR (1, (LM_ERROR
, DLINFO
271 ACE_TEXT ("ClientRequestHandler::initialize_connection - ")
272 ACE_TEXT ("unable to find session factory for scheme [%C]\n"),
277 ACE::INet::ConnectionHolder
* pch
= 0;
280 if (!this->connection_cache ().claim_connection (HttpConnectionKey (proxy_host
,
290 if (!this->connection_cache ().claim_connection (HttpConnectionKey (host
,
297 this->session (dynamic_cast<SessionHolder
*> (pch
));
301 void ClientRequestHandler::initialize_request (const URL
& /*url*/, Request
& /*request*/)
305 void ClientRequestHandler::handle_request_error (const URL
& /*url*/)
309 void ClientRequestHandler::handle_connection_error (const URL
& /*url*/)
313 void ClientRequestHandler::release_connection ()
317 if (this->session ()->is_proxy_connection ())
319 this->connection_cache ().release_connection (
320 HttpConnectionKey (this->session ()->get_host (),
321 this->session ()->get_port (),
322 this->session ()->get_proxy_target_host (),
323 this->session ()->get_proxy_target_port ()),
328 this->connection_cache ().release_connection (
329 HttpConnectionKey (this->session ()->get_host (),
330 this->session ()->get_port ()),
337 void ClientRequestHandler::close_connection ()
341 if (this->session ()->is_proxy_connection ())
343 this->connection_cache ().release_connection (
344 HttpConnectionKey (this->session ()->get_host (),
345 this->session ()->get_port (),
346 this->session ()->get_proxy_target_host (),
347 this->session ()->get_proxy_target_port ()),
352 this->connection_cache ().release_connection (
353 HttpConnectionKey (this->session ()->get_host (),
354 this->session ()->get_port ()),
364 ACE_END_VERSIONED_NAMESPACE_DECL