Use a variable on the stack to not have a temporary in the call
[ACE_TAO.git] / ACE / protocols / ace / INet / HTTP_ClientRequestHandler.cpp
blobdd916369dddbe77571273d352b8de18cbeb2ebb7
1 #include "ace/INet/HTTP_ClientRequestHandler.h"
3 #if !defined (__ACE_INLINE__)
4 #include "ace/INet/HTTP_ClientRequestHandler.inl"
5 #endif
7 #include "ace/INet/INet_Log.h"
8 #include <memory>
9 #include "ace/Functor_String.h"
11 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
13 namespace ACE
15 namespace HTTP
17 SessionFactoryRegistry::SessionFactoryRegistry ()
21 SessionFactoryRegistry::~SessionFactoryRegistry ()
25 void SessionFactoryRegistry::register_session_factory (
26 const ACE_CString& scheme,
27 SessionFactory* factory)
29 if (factory == 0)
30 this->factory_map_.unbind (scheme);
31 else
32 this->factory_map_.rebind (scheme, factory);
35 SessionFactory*
36 SessionFactoryRegistry::find_session_factory (const ACE_CString& scheme)
38 SessionFactory* factory = 0;
39 this->factory_map_.find (scheme, factory);
40 return 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 ()
57 : session_ (true)
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 (),
98 0);
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 ();
113 return 0;
116 ClientRequestHandler::HttpConnectionKey::HttpConnectionKey (
117 const ACE_CString& host,
118 u_short port)
119 : INetConnectionKey (host, port),
120 proxy_connection_ (false),
121 proxy_target_port_ (0)
125 ClientRequestHandler::HttpConnectionKey::HttpConnectionKey (
126 const ACE_CString& proxy_host,
127 u_short proxy_port,
128 const ACE_CString& host,
129 u_short port)
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);
147 else
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_)
157 ACE_NEW_RETURN (k,
158 HttpConnectionKey (this->host (), this->port (),
159 this->proxy_target_host_,
160 this->proxy_target_port_),
163 else
165 ACE_NEW_RETURN (k,
166 HttpConnectionKey (this->host (), this->port ()),
169 return k;
172 bool ClientRequestHandler::HttpConnectionKey::equal (const ACE::INet::ConnectionKey& key) const
174 try {
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 ())));
182 catch (...) {
183 return false;
187 ClientRequestHandler::ClientRequestHandler ()
188 : request_ (Request::HTTP_1_0),
189 session_ (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 (
212 const URL& http_url)
214 bool connected = false;
215 if (http_url.has_proxy ())
216 connected = this->initialize_connection (http_url.get_scheme (),
217 http_url.get_host(),
218 http_url.get_port (),
219 true,
220 http_url.get_proxy_host(),
221 http_url.get_proxy_port ());
222 else
223 connected = this->initialize_connection (http_url.get_scheme (),
224 http_url.get_host(),
225 http_url.get_port ());
227 if (connected)
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);
245 else
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,
260 u_short port,
261 bool proxy_conn,
262 const ACE_CString& proxy_host,
263 u_short proxy_port)
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"),
273 scheme.c_str ()));
274 return false;
277 ACE::INet::ConnectionHolder* pch = 0;
278 if (proxy_conn)
280 if (!this->connection_cache ().claim_connection (HttpConnectionKey (proxy_host,
281 proxy_port,
282 host,
283 port),
284 pch,
285 *session_factory))
286 return false;
288 else
290 if (!this->connection_cache ().claim_connection (HttpConnectionKey (host,
291 port),
292 pch,
293 *session_factory))
294 return false;
297 this->session (dynamic_cast<SessionHolder*> (pch));
298 return true;
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 ()
315 if (this->session_)
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 ()),
324 this->session_);
326 else
328 this->connection_cache ().release_connection (
329 HttpConnectionKey (this->session ()->get_host (),
330 this->session ()->get_port ()),
331 this->session_);
333 this->session_ = 0;
337 void ClientRequestHandler::close_connection ()
339 if (this->session_)
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 ()),
348 this->session_);
350 else
352 this->connection_cache ().release_connection (
353 HttpConnectionKey (this->session ()->get_host (),
354 this->session ()->get_port ()),
355 this->session_);
357 this->session_ = 0;
364 ACE_END_VERSIONED_NAMESPACE_DECL