00001
00002
00003 #ifndef ACE_HTTPS_SESSION_CPP
00004 #define ACE_HTTPS_SESSION_CPP
00005
00006 #include "ace/INet/HTTPS_Session.h"
00007 #include "ace/INet/INet_Log.h"
00008 #include "ace/INet/IOS_util.h"
00009 #include "ace/INet/HTTPS_URL.h"
00010 #include "ace/INet/Sock_IOStream.h"
00011 #include "ace/INet/String_IOStream.h"
00012 #include "ace/INet/SSL_Proxy_Connector.h"
00013 #include "ace/INET_Addr.h"
00014 #include "ace/Event_Handler.h"
00015 #include "ace/Connector.h"
00016 #include "ace/SSL/SSL_SOCK_Connector.h"
00017 #include "ace/String_Base.h"
00018 #include <istream>
00019 #include <ostream>
00020
00021 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00022
00023 namespace ACE
00024 {
00025 namespace HTTPS
00026 {
00027
00028 template <ACE_SYNCH_DECL>
00029 Session_T<ACE_SYNCH_USE>::Session_T (bool keep_alive
00030 #if defined (SSL_HAS_SSL_set_SSL_CTX) && (SSL_HAS_SSL_set_SSL_CTX == 1)
00031 , Context* ctx
00032 #endif
00033 )
00034 : SessionBase (URL::HTTPS_PORT, keep_alive),
00035 connection_ (0),
00036 sock_stream_ (0)
00037 #if defined (SSL_HAS_SSL_set_SSL_CTX) && (SSL_HAS_SSL_set_SSL_CTX == 1)
00038 , context_ (ctx)
00039 #endif
00040 {
00041 INET_TRACE ("ACE_HTTPS_Session - ctor");
00042 }
00043
00044 template <ACE_SYNCH_DECL>
00045 Session_T<ACE_SYNCH_USE>::Session_T (const ACE_Time_Value& timeout,
00046 bool keep_alive,
00047 const ACE_Time_Value* alive_timeout
00048 #if defined (SSL_HAS_SSL_set_SSL_CTX) && (SSL_HAS_SSL_set_SSL_CTX == 1)
00049 , Context* ctx
00050 #endif
00051 )
00052 : SessionBase (URL::HTTPS_PORT, timeout, keep_alive, alive_timeout),
00053 connection_ (0),
00054 sock_stream_ (0)
00055 #if defined (SSL_HAS_SSL_set_SSL_CTX) && (SSL_HAS_SSL_set_SSL_CTX == 1)
00056 , context_ (ctx)
00057 #endif
00058 {
00059 INET_TRACE ("ACE_HTTPS_Session - ctor");
00060 this->close_streams ();
00061 this->close_connection ();
00062 }
00063
00064 template <ACE_SYNCH_DECL>
00065 Session_T<ACE_SYNCH_USE>::~Session_T ()
00066 {
00067 INET_TRACE ("ACE_HTTPS_Session - dtor");
00068 }
00069
00070 template <ACE_SYNCH_DECL>
00071 bool Session_T<ACE_SYNCH_USE>::is_connected () const
00072 {
00073 return this->connection_ && this->connection_->is_connected ();
00074 }
00075
00076 template <ACE_SYNCH_DECL>
00077 bool Session_T<ACE_SYNCH_USE>::connect_i (const ACE_Synch_Options& sync_opt)
00078 {
00079 INET_TRACE ("ACE_HTTPS_Session::connect_i");
00080
00081 connection_type* new_connection = 0;
00082
00083 if (this->is_proxy_connection ())
00084 {
00085 typedef ACE::IOS::StreamHandler<ACE_SOCK_STREAM, ACE_SYNCH_USE> proxy_connection_type;
00086 typedef ACE_Connector<proxy_connection_type, ACE_SOCK_CONNECTOR> proxy_connector_type;
00087 typedef ACE::IOS::Sock_IOStreamBase<ACE_SYNCH_USE> proxy_stream_type;
00088
00089 proxy_connection_type proxy_connection(sync_opt);
00090 proxy_connector_type proxy_connector;
00091
00092 proxy_connection_type* proxy_connection_ptr = &proxy_connection;
00093 if (proxy_connector.connect (proxy_connection_ptr,
00094 ACE_INET_Addr (this->port_,
00095 this->host_.c_str ()),
00096 ACE_Synch_Options (0,this->http_timeout_)) == -1)
00097 {
00098 INET_ERROR (1, (LM_ERROR, DLINFO
00099 ACE_TEXT ("(%d) ACE_HTTPS_Session::connect_i - ")
00100 ACE_TEXT ("failed to connect to proxy; host=%C, port=%d\n"),
00101 ACE_OS::last_error (), this->host_.c_str (), this->port_));
00102 return false;
00103 }
00104
00105 proxy_stream_type proxy_stream (&proxy_connection);
00106 ACE::IOS::CString_OStream target_address;
00107 target_address << this->proxy_target_host_ << ':' << this->proxy_target_port_;
00108 ACE::HTTP::Request connect_request (ACE::HTTP::Request::HTTP_CONNECT,
00109 target_address.str ().c_str (),
00110 ACE::HTTP::Request::HTTP_1_1);
00111 connect_request.set("Proxy-Connection", "keep-alive");
00112 connect_request.set_host(this->proxy_target_host_);
00113 ACE::HTTP::Response connect_response;
00114
00115 connect_request.write (proxy_stream);
00116 proxy_stream.flush ();
00117 if (!connect_response.read (proxy_stream) ||
00118 !connect_response.get_status ().is_ok ())
00119 {
00120 INET_ERROR (1, (LM_ERROR, DLINFO
00121 ACE_TEXT ("ACE_HTTPS_Session::connect_i - ")
00122 ACE_TEXT ("cannot setup proxy tunnel; proxy replied: %d:%C\n"),
00123 connect_response.get_status ().get_status(),
00124 connect_response.get_status ().get_reason().c_str ()));
00125 return false;
00126 }
00127
00128 ACE_NEW_RETURN (new_connection,
00129 connection_type(sync_opt),
00130 false);
00131 #if defined (SSL_HAS_SSL_set_SSL_CTX) && (SSL_HAS_SSL_set_SSL_CTX == 1)
00132
00133 if (this->context_ != 0)
00134 {
00135 ::SSL * ssl_ptr = new_connection->peer ().ssl ();
00136 ::SSL_set_SSL_CTX (ssl_ptr, this->context_->ssl_context ().context ());
00137 }
00138 #endif
00139 ACE_HANDLE proxy_conn_handle = proxy_connection.peer ().get_handle ();
00140 proxy_connection.peer ().set_handle (ACE_INVALID_HANDLE);
00141
00142 ACE::INet::SSL_Proxy_Connector proxy_ssl_connector;
00143 ACE_Time_Value conn_timeout (this->http_timeout_);
00144 if (proxy_ssl_connector.connect (new_connection->peer (),
00145 proxy_conn_handle,
00146 &conn_timeout) != 0)
00147 {
00148 INET_ERROR (1, (LM_ERROR, DLINFO
00149 ACE_TEXT ("ACE_HTTPS_Session::connect_i - ")
00150 ACE_TEXT ("failed to setup proxy SSL connection\n")));
00151 return false;
00152 }
00153 new_connection->open ();
00154 }
00155 else
00156 {
00157 ACE_NEW_RETURN (new_connection,
00158 connection_type(sync_opt),
00159 false);
00160 #if defined (SSL_HAS_SSL_set_SSL_CTX) && (SSL_HAS_SSL_set_SSL_CTX == 1)
00161
00162 if (this->context_ != 0)
00163 {
00164 ::SSL * ssl_ptr = new_connection->peer ().ssl ();
00165 ::SSL_set_SSL_CTX (ssl_ptr, this->context_->ssl_context ().context ());
00166 }
00167 #endif
00168 typedef ACE_Connector<connection_type, ACE_SSL_SOCK_Connector> connector_type;
00169
00170 connector_type connector;
00171
00172 if (connector.connect (new_connection,
00173 ACE_INET_Addr (this->port_,
00174 this->host_.c_str ()),
00175 ACE_Synch_Options (0,this->http_timeout_)) == -1)
00176 {
00177 INET_ERROR (1, (LM_ERROR, DLINFO
00178 ACE_TEXT ("(%d) ACE_HTTPS_Session::connect_i - ")
00179 ACE_TEXT ("failed to connect; host=%C, port=%d\n"),
00180 ACE_OS::last_error (), this->host_.c_str (), this->port_));
00181
00182
00183
00184 return false;
00185 }
00186 }
00187
00188 this->connection_ = new_connection;
00189 this->connection_->reference_counting_policy ().value (
00190 ACE_Event_Handler::Reference_Counting_Policy::ENABLED);
00191
00192 ACE_NEW_NORETURN (this->sock_stream_,
00193 sock_stream_type (this->connection_));
00194 if (this->sock_stream_)
00195 {
00196 this->cannot_reconnect_ = false;
00197 this->reactive_ = sync_opt[ACE_Synch_Options::USE_REACTOR];
00198
00199
00200 this->reconnect_timer_ = this->keep_alive_timeout_;
00201 this->reconnect_countdown_.start ();
00202
00203 return true;
00204 }
00205 else
00206 {
00207 this->close ();
00208 return false;
00209 }
00210 }
00211
00212 template <ACE_SYNCH_DECL>
00213 bool Session_T<ACE_SYNCH_USE>::attach_connection (connection_type* connection)
00214 {
00215 INET_TRACE ("ACE_HTTPS_Session::attach_connection");
00216
00217 if (!connection->is_connected ())
00218 return false;
00219
00220 this->close ();
00221
00222 ACE_INET_Addr remote;
00223 connection->peer ().get_remote_addr (remote);
00224 this->host_ = remote.get_host_name ();
00225 this->port_ = remote.get_port_number ();
00226
00227 this->connection_ = connection;
00228 this->connection_->add_reference ();
00229
00230 ACE_NEW_NORETURN (this->sock_stream_,
00231 sock_stream_type (this->connection_));
00232
00233 if (this->sock_stream_)
00234 {
00235 this->keep_alive_ = true;
00236 this->keep_alive_timeout_ = ACE_Time_Value::zero;
00237 this->cannot_reconnect_ = true;
00238 return true;
00239 }
00240 else
00241 {
00242 this->close ();
00243 return false;
00244 }
00245 }
00246
00247 template <ACE_SYNCH_DECL>
00248 void Session_T<ACE_SYNCH_USE>::close_connection ()
00249 {
00250 if (this->sock_stream_)
00251 {
00252 delete this->sock_stream_;
00253 this->sock_stream_ = 0;
00254 }
00255
00256 if (this->connection_)
00257 {
00258
00259
00260 this->connection_->remove_reference ();
00261 this->connection_ = 0;
00262 }
00263 }
00264
00265 template <ACE_SYNCH_DECL>
00266 void Session_T<ACE_SYNCH_USE>::close_i ()
00267 {
00268 INET_TRACE ("ACE_HTTPS_Session::close_i");
00269
00270 this->close_connection ();
00271 }
00272
00273 template <ACE_SYNCH_DECL>
00274 std::iostream& Session_T<ACE_SYNCH_USE>::sock_stream ()
00275 {
00276 return *this->sock_stream_;
00277 }
00278
00279 }
00280 }
00281
00282 ACE_END_VERSIONED_NAMESPACE_DECL
00283
00284 #endif