00001
00002
00003 #include "ace/INet/HTTP_ClientRequestHandler.h"
00004
00005 #if !defined (__ACE_INLINE__)
00006 #include "ace/INet/HTTP_ClientRequestHandler.inl"
00007 #endif
00008
00009 #include "ace/INet/INet_Log.h"
00010 #include "ace/Auto_Ptr.h"
00011 #include "ace/Functor_String.h"
00012
00013 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00014
00015 namespace ACE
00016 {
00017 namespace HTTP
00018 {
00019
00020 SessionFactoryRegistry::SessionFactoryRegistry ()
00021 {
00022 }
00023
00024 SessionFactoryRegistry::~SessionFactoryRegistry ()
00025 {
00026 }
00027
00028 void SessionFactoryRegistry::register_session_factory (
00029 const ACE_CString& scheme,
00030 SessionFactory* factory)
00031 {
00032 if (factory == 0)
00033 this->factory_map_.unbind (scheme);
00034 else
00035 this->factory_map_.rebind (scheme, factory);
00036 }
00037
00038 SessionFactory*
00039 SessionFactoryRegistry::find_session_factory (const ACE_CString& scheme)
00040 {
00041 SessionFactory* factory = 0;
00042 this->factory_map_.find (scheme, factory);
00043 return factory;
00044 }
00045
00046 SessionFactoryRegistry& SessionFactoryRegistry::instance ()
00047 {
00048 return *ACE_Singleton<SessionFactoryRegistry, ACE_SYNCH::MUTEX>::instance ();
00049 }
00050
00051 SessionHolder::SessionHolder ()
00052 {
00053 }
00054
00055 SessionHolder::~SessionHolder()
00056 {
00057 }
00058
00059 SessionFactory_Impl::SessionHolder_Impl::SessionHolder_Impl ()
00060 : session_ (true)
00061 {
00062 }
00063
00064 SessionFactory_Impl::SessionHolder_Impl::~SessionHolder_Impl()
00065 {
00066 }
00067
00068 SessionBase& SessionFactory_Impl::SessionHolder_Impl::session ()
00069 {
00070 return this->session_;
00071 }
00072
00073 SessionFactory_Impl& SessionFactory_Impl::factory_ =
00074 *ACE_Singleton<SessionFactory_Impl,ACE_SYNCH::NULL_MUTEX>::instance ();
00075
00076 SessionFactory_Impl::SessionFactory_Impl ()
00077 {
00078 INET_DEBUG (6, (LM_INFO, DLINFO
00079 ACE_TEXT ("HTTP_SessionFactory_Impl::ctor - ")
00080 ACE_TEXT ("registering session factory for scheme [%C]\n"),
00081 URL::protocol ().c_str ()));
00082 SessionFactoryRegistry::instance ().register_session_factory (URL::protocol (), this);
00083 }
00084
00085 SessionFactory_Impl::~SessionFactory_Impl ()
00086 {
00087 }
00088
00089 ACE::INet::ConnectionHolder*
00090 SessionFactory_Impl::create_connection (
00091 const ACE::INet::ConnectionKey& key) const
00092 {
00093 INET_TRACE ("HTTP_SessionFactory_Impl::create_connection");
00094
00095 const ClientRequestHandler::HttpConnectionKey& ikey =
00096 dynamic_cast<const ClientRequestHandler::HttpConnectionKey&> (key);
00097
00098 SessionHolder_Impl* session_holder = 0;
00099 ACE_NEW_RETURN (session_holder,
00100 SessionHolder_Impl (),
00101 0);
00102 ACE_Auto_Ptr<SessionHolder_Impl> session_safe_ref (session_holder);
00103
00104 (*session_holder)->set_host (ikey.host (), ikey.port ());
00105 if (ikey.is_proxy_connection ())
00106 {
00107 (*session_holder)->set_proxy_target (ikey.proxy_target_host (),
00108 ikey.proxy_target_port ());
00109 }
00110
00111 if ((*session_holder)->connect (true))
00112 {
00113 return session_safe_ref.release ();
00114 }
00115
00116 return 0;
00117 }
00118
00119 ClientRequestHandler::HttpConnectionKey::HttpConnectionKey (
00120 const ACE_CString& host,
00121 u_short port)
00122 : INetConnectionKey (host, port),
00123 proxy_connection_ (false),
00124 proxy_target_port_ (0)
00125 {
00126 }
00127
00128 ClientRequestHandler::HttpConnectionKey::HttpConnectionKey (
00129 const ACE_CString& proxy_host,
00130 u_short proxy_port,
00131 const ACE_CString& host,
00132 u_short port)
00133 : INetConnectionKey (proxy_host, proxy_port),
00134 proxy_connection_ (true),
00135 proxy_target_host_ (host),
00136 proxy_target_port_ (port)
00137 {
00138 }
00139
00140 ClientRequestHandler::HttpConnectionKey::~HttpConnectionKey()
00141 {
00142 }
00143
00144 u_long ClientRequestHandler::HttpConnectionKey::hash () const
00145 {
00146 if (this->proxy_connection_)
00147 return ACE_Hash<ACE_CString>()(this->proxy_target_host_) +
00148 this->proxy_target_port_ +
00149 (this->proxy_connection_ ? 1 : 0);
00150 else
00151 return INetConnectionKey::hash () +
00152 (this->proxy_connection_ ? 1 : 0);
00153 }
00154
00155 ACE::INet::ConnectionKey* ClientRequestHandler::HttpConnectionKey::duplicate () const
00156 {
00157 ConnectionKey* k = 0;
00158 if (this->proxy_connection_)
00159 {
00160 ACE_NEW_RETURN (k,
00161 HttpConnectionKey (this->host (), this->port (),
00162 this->proxy_target_host_,
00163 this->proxy_target_port_),
00164 0);
00165 }
00166 else
00167 {
00168 ACE_NEW_RETURN (k,
00169 HttpConnectionKey (this->host (), this->port ()),
00170 0);
00171 }
00172 return k;
00173 }
00174
00175 bool ClientRequestHandler::HttpConnectionKey::equal (const ACE::INet::ConnectionKey& key) const
00176 {
00177 try {
00178 const HttpConnectionKey& http_key = dynamic_cast<const HttpConnectionKey&> (key);
00179 return (INetConnectionKey::equal (key) &&
00180 this->proxy_connection_ == http_key.is_proxy_connection () &&
00181 (!this->proxy_connection_ ||
00182 (this->proxy_target_host_ == http_key.proxy_target_host () &&
00183 this->proxy_target_port_ == http_key.proxy_target_port ())));
00184 }
00185 catch (...) {
00186 return false;
00187 }
00188 }
00189
00190 ClientRequestHandler::ClientRequestHandler ()
00191 : request_ (Request::HTTP_1_0),
00192 session_ (0)
00193 {
00194 }
00195
00196 ClientRequestHandler::~ClientRequestHandler ()
00197 {
00198 this->release_connection ();
00199 }
00200
00201 bool ClientRequestHandler::is_response_ok () const
00202 {
00203 return this->response_.get_status ().is_ok () &&
00204 !const_cast<ClientRequestHandler*> (this)->response_stream ().bad ();
00205 }
00206
00207 std::istream& ClientRequestHandler::handle_open_request (
00208 const ACE::INet::URL_Base& url)
00209 {
00210 const URL& http_url = dynamic_cast<const URL&> (url);
00211 return this->handle_get_request (http_url);
00212 }
00213
00214 std::istream& ClientRequestHandler::handle_get_request (
00215 const URL& http_url)
00216 {
00217 bool connected = false;
00218 if (http_url.has_proxy ())
00219 connected = this->initialize_connection (http_url.get_scheme (),
00220 http_url.get_host(),
00221 http_url.get_port (),
00222 true,
00223 http_url.get_proxy_host(),
00224 http_url.get_proxy_port ());
00225 else
00226 connected = this->initialize_connection (http_url.get_scheme (),
00227 http_url.get_host(),
00228 http_url.get_port ());
00229
00230 if (connected)
00231 {
00232 this->request_.reset (Request::HTTP_GET,
00233 http_url.get_request_uri (),
00234 this->request_.get_version ());
00235
00236 this->response_.reset ();
00237
00238 this->initialize_request (http_url, this->request_);
00239
00240 if (!this->session ()->send_request (this->request_) ||
00241 !this->session ()->receive_response (this->response_))
00242 {
00243 this->close_connection ();
00244
00245 this->handle_request_error(http_url);
00246 }
00247 }
00248 else
00249 {
00250 this->handle_connection_error (http_url);
00251 }
00252
00253 return this->response_stream ();
00254 }
00255
00256 void ClientRequestHandler::on_eof ()
00257 {
00258 this->release_connection ();
00259 }
00260
00261 bool ClientRequestHandler::initialize_connection (const ACE_CString& scheme,
00262 const ACE_CString& host,
00263 u_short port,
00264 bool proxy_conn,
00265 const ACE_CString& proxy_host,
00266 u_short proxy_port)
00267 {
00268 SessionFactory* session_factory =
00269 SessionFactoryRegistry::instance ().find_session_factory (scheme);
00270
00271 if (session_factory == 0)
00272 {
00273 INET_ERROR (1, (LM_ERROR, DLINFO
00274 ACE_TEXT ("ClientRequestHandler::initialize_connection - ")
00275 ACE_TEXT ("unable to find session factory for scheme [%C]\n"),
00276 scheme.c_str ()));
00277 return false;
00278 }
00279
00280 ACE::INet::ConnectionHolder* pch = 0;
00281 if (proxy_conn)
00282 {
00283 if (!this->connection_cache ().claim_connection (HttpConnectionKey (proxy_host,
00284 proxy_port,
00285 host,
00286 port),
00287 pch,
00288 *session_factory))
00289 return false;
00290 }
00291 else
00292 {
00293 if (!this->connection_cache ().claim_connection (HttpConnectionKey (host,
00294 port),
00295 pch,
00296 *session_factory))
00297 return false;
00298 }
00299
00300 this->session (dynamic_cast<SessionHolder*> (pch));
00301 return true;
00302 }
00303
00304 void ClientRequestHandler::initialize_request (const URL& , Request& )
00305 {
00306 }
00307
00308 void ClientRequestHandler::handle_request_error (const URL& )
00309 {
00310 }
00311
00312 void ClientRequestHandler::handle_connection_error (const URL& )
00313 {
00314 }
00315
00316 void ClientRequestHandler::release_connection ()
00317 {
00318 if (this->session_)
00319 {
00320 if (this->session ()->is_proxy_connection ())
00321 {
00322 this->connection_cache ().release_connection (
00323 HttpConnectionKey (this->session ()->get_host (),
00324 this->session ()->get_port (),
00325 this->session ()->get_proxy_target_host (),
00326 this->session ()->get_proxy_target_port ()),
00327 this->session_);
00328 }
00329 else
00330 {
00331 this->connection_cache ().release_connection (
00332 HttpConnectionKey (this->session ()->get_host (),
00333 this->session ()->get_port ()),
00334 this->session_);
00335 }
00336 this->session_ = 0;
00337 }
00338 }
00339
00340 void ClientRequestHandler::close_connection ()
00341 {
00342 if (this->session_)
00343 {
00344 if (this->session ()->is_proxy_connection ())
00345 {
00346 this->connection_cache ().release_connection (
00347 HttpConnectionKey (this->session ()->get_host (),
00348 this->session ()->get_port (),
00349 this->session ()->get_proxy_target_host (),
00350 this->session ()->get_proxy_target_port ()),
00351 this->session_);
00352 }
00353 else
00354 {
00355 this->connection_cache ().release_connection (
00356 HttpConnectionKey (this->session ()->get_host (),
00357 this->session ()->get_port ()),
00358 this->session_);
00359 }
00360 this->session_ = 0;
00361 }
00362 }
00363
00364 }
00365 }
00366
00367 ACE_END_VERSIONED_NAMESPACE_DECL