1 #ifndef ACE_HTTPS_SESSION_CPP
2 #define ACE_HTTPS_SESSION_CPP
4 #include "ace/INet/HTTPS_Session.h"
5 #include "ace/INet/INet_Log.h"
6 #include "ace/INet/IOS_util.h"
7 #include "ace/INet/HTTPS_URL.h"
8 #include "ace/INet/Sock_IOStream.h"
9 #include "ace/INet/String_IOStream.h"
10 #include "ace/INet/SSL_Proxy_Connector.h"
11 #include "ace/INET_Addr.h"
12 #include "ace/Event_Handler.h"
13 #include "ace/Connector.h"
14 #include "ace/SSL/SSL_SOCK_Connector.h"
15 #include "ace/String_Base.h"
19 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
25 template <ACE_SYNCH_DECL
>
26 Session_T
<ACE_SYNCH_USE
>::Session_T (bool keep_alive
27 #if defined (SSL_HAS_SSL_set_SSL_CTX) && (SSL_HAS_SSL_set_SSL_CTX == 1)
31 : SessionBase (URL::HTTPS_PORT
, keep_alive
),
34 #if defined (SSL_HAS_SSL_set_SSL_CTX) && (SSL_HAS_SSL_set_SSL_CTX == 1)
38 INET_TRACE ("ACE_HTTPS_Session - ctor");
41 template <ACE_SYNCH_DECL
>
42 Session_T
<ACE_SYNCH_USE
>::Session_T (const ACE_Time_Value
& timeout
,
44 const ACE_Time_Value
* alive_timeout
45 #if defined (SSL_HAS_SSL_set_SSL_CTX) && (SSL_HAS_SSL_set_SSL_CTX == 1)
49 : SessionBase (URL::HTTPS_PORT
, timeout
, keep_alive
, alive_timeout
),
52 #if defined (SSL_HAS_SSL_set_SSL_CTX) && (SSL_HAS_SSL_set_SSL_CTX == 1)
56 INET_TRACE ("ACE_HTTPS_Session - ctor");
57 this->close_streams ();
58 this->close_connection ();
61 template <ACE_SYNCH_DECL
>
62 Session_T
<ACE_SYNCH_USE
>::~Session_T ()
64 INET_TRACE ("ACE_HTTPS_Session - dtor");
67 template <ACE_SYNCH_DECL
>
68 bool Session_T
<ACE_SYNCH_USE
>::is_connected () const
70 return this->connection_
&& this->connection_
->is_connected ();
73 template <ACE_SYNCH_DECL
>
74 bool Session_T
<ACE_SYNCH_USE
>::connect_i (const ACE_Synch_Options
& sync_opt
)
76 INET_TRACE ("ACE_HTTPS_Session::connect_i");
78 connection_type
* new_connection
= 0;
80 if (this->is_proxy_connection ())
82 typedef ACE::IOS::StreamHandler
<ACE_SOCK_STREAM
, ACE_SYNCH_USE
> proxy_connection_type
;
83 typedef ACE_Connector
<proxy_connection_type
, ACE_SOCK_CONNECTOR
> proxy_connector_type
;
84 typedef ACE::IOS::Sock_IOStreamBase
<ACE_SYNCH_USE
> proxy_stream_type
;
86 proxy_connection_type
proxy_connection(sync_opt
);
87 proxy_connector_type proxy_connector
;
89 proxy_connection_type
* proxy_connection_ptr
= &proxy_connection
;
90 if (proxy_connector
.connect (proxy_connection_ptr
,
91 ACE_INET_Addr (this->port_
,
92 this->host_
.c_str ()),
93 ACE_Synch_Options (0,this->http_timeout_
)) == -1)
95 INET_ERROR (1, (LM_ERROR
, DLINFO
96 ACE_TEXT ("(%d) ACE_HTTPS_Session::connect_i - ")
97 ACE_TEXT ("failed to connect to proxy; host=%C, port=%d\n"),
98 ACE_OS::last_error (), this->host_
.c_str (), this->port_
));
102 proxy_stream_type
proxy_stream (&proxy_connection
);
103 ACE::IOS::CString_OStream target_address
;
104 target_address
<< this->proxy_target_host_
<< ':' << this->proxy_target_port_
;
105 ACE::HTTP::Request
connect_request (ACE::HTTP::Request::HTTP_CONNECT
,
106 target_address
.str ().c_str (),
107 ACE::HTTP::Request::HTTP_1_1
);
108 connect_request
.set("Proxy-Connection", "keep-alive");
109 connect_request
.set_host(this->proxy_target_host_
);
110 ACE::HTTP::Response connect_response
;
112 connect_request
.write (proxy_stream
);
113 proxy_stream
.flush ();
114 if (!connect_response
.read (proxy_stream
) ||
115 !connect_response
.get_status ().is_ok ())
117 INET_ERROR (1, (LM_ERROR
, DLINFO
118 ACE_TEXT ("ACE_HTTPS_Session::connect_i - ")
119 ACE_TEXT ("cannot setup proxy tunnel; proxy replied: %d:%C\n"),
120 connect_response
.get_status ().get_status(),
121 connect_response
.get_status ().get_reason().c_str ()));
125 ACE_NEW_RETURN (new_connection
,
126 connection_type(sync_opt
),
128 #if defined (SSL_HAS_SSL_set_SSL_CTX) && (SSL_HAS_SSL_set_SSL_CTX == 1)
129 // set the provided SSL context for the SSL structure of the SSL_SOCK_Stream
130 if (this->context_
!= 0)
132 ::SSL
* ssl_ptr
= new_connection
->peer ().ssl ();
133 ::SSL_set_SSL_CTX (ssl_ptr
, this->context_
->ssl_context ().context ());
136 ACE_HANDLE proxy_conn_handle
= proxy_connection
.peer ().get_handle ();
137 proxy_connection
.peer ().set_handle (ACE_INVALID_HANDLE
);
139 ACE::INet::SSL_Proxy_Connector proxy_ssl_connector
;
140 ACE_Time_Value
conn_timeout (this->http_timeout_
);
141 if (proxy_ssl_connector
.connect (new_connection
->peer (),
145 INET_ERROR (1, (LM_ERROR
, DLINFO
146 ACE_TEXT ("ACE_HTTPS_Session::connect_i - ")
147 ACE_TEXT ("failed to setup proxy SSL connection\n")));
150 new_connection
->open (); // mark stream handler as connected
154 ACE_NEW_RETURN (new_connection
,
155 connection_type(sync_opt
),
157 #if defined (SSL_HAS_SSL_set_SSL_CTX) && (SSL_HAS_SSL_set_SSL_CTX == 1)
158 // set the provided SSL context for the SSL structure of the SSL_SOCK_Stream
159 if (this->context_
!= 0)
161 ::SSL
* ssl_ptr
= new_connection
->peer ().ssl ();
162 ::SSL_set_SSL_CTX (ssl_ptr
, this->context_
->ssl_context ().context ());
165 typedef ACE_Connector
<connection_type
, ACE_SSL_SOCK_Connector
> connector_type
;
167 connector_type connector
;
169 if (connector
.connect (new_connection
,
170 ACE_INET_Addr (this->port_
,
171 this->host_
.c_str ()),
172 ACE_Synch_Options (0,this->http_timeout_
)) == -1)
174 INET_ERROR (1, (LM_ERROR
, DLINFO
175 ACE_TEXT ("(%d) ACE_HTTPS_Session::connect_i - ")
176 ACE_TEXT ("failed to connect; host=%C, port=%d\n"),
177 ACE_OS::last_error (), this->host_
.c_str (), this->port_
));
178 // as the connection was dynamically allocated
179 // the connector causes it to be destroyed after
180 // the connection failure
185 this->connection_
= new_connection
;
186 this->connection_
->reference_counting_policy ().value (
187 ACE_Event_Handler::Reference_Counting_Policy::ENABLED
);
189 ACE_NEW_NORETURN (this->sock_stream_
,
190 sock_stream_type (this->connection_
));
191 if (this->sock_stream_
)
193 this->cannot_reconnect_
= false;
194 this->reactive_
= sync_opt
[ACE_Synch_Options::USE_REACTOR
];
196 // reset reconnect timer
197 this->reconnect_timer_
= this->keep_alive_timeout_
;
198 this->reconnect_countdown_
.start ();
209 template <ACE_SYNCH_DECL
>
210 bool Session_T
<ACE_SYNCH_USE
>::attach_connection (connection_type
* connection
)
212 INET_TRACE ("ACE_HTTPS_Session::attach_connection");
214 if (!connection
->is_connected ())
219 ACE_INET_Addr remote
;
220 connection
->peer ().get_remote_addr (remote
);
221 this->host_
= remote
.get_host_name ();
222 this->port_
= remote
.get_port_number ();
224 this->connection_
= connection
;
225 this->connection_
->add_reference ();
227 ACE_NEW_NORETURN (this->sock_stream_
,
228 sock_stream_type (this->connection_
));
230 if (this->sock_stream_
)
232 this->keep_alive_
= true;
233 this->keep_alive_timeout_
= ACE_Time_Value::zero
;
234 this->cannot_reconnect_
= true;
244 template <ACE_SYNCH_DECL
>
245 void Session_T
<ACE_SYNCH_USE
>::close_connection ()
247 if (this->sock_stream_
)
249 delete this->sock_stream_
;
250 this->sock_stream_
= 0;
253 if (this->connection_
)
255 // this should be the last referece and removing it
256 // causes the connection to be destroyed
257 this->connection_
->remove_reference ();
258 this->connection_
= 0;
262 template <ACE_SYNCH_DECL
>
263 void Session_T
<ACE_SYNCH_USE
>::close_i ()
265 INET_TRACE ("ACE_HTTPS_Session::close_i");
267 this->close_connection ();
270 template <ACE_SYNCH_DECL
>
271 std::iostream
& Session_T
<ACE_SYNCH_USE
>::sock_stream ()
273 return *this->sock_stream_
;
279 ACE_END_VERSIONED_NAMESPACE_DECL
281 #endif /* ACE_HTTPS_SESSION_CPP */