summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormcorino <mcorino@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2010-07-17 10:29:57 +0000
committermcorino <mcorino@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2010-07-17 10:29:57 +0000
commitfc613365076f33584680f484b28d6d5a0691e465 (patch)
treeee38af158bb6e0847af16873ba98214aad9a034d
parent40055ec908c4203bad26c8ecd1a462f316e9491c (diff)
downloadATCD-fc613365076f33584680f484b28d6d5a0691e465.tar.gz
Sat Jul 17 10:26:30 UTC 2010 Martin Corino <mcorino@remedy.nl>
* bin/MakeProjectCreator/config/inetssl.mpb: * bin/MakeProjectCreator/config/inet.mpb: Added feature project for SSL based parts of INet. Setting feature ssl=1 will automatically cause correct dependencies for SSL to be generated in INet based projects. * protocols/ace/INet/HTTPS_Context.cpp: * protocols/ace/INet/HTTPS_Context.h: * protocols/ace/INet/HTTPS_Context.inl: * protocols/ace/INet/HTTP_SessionBase.cpp: * protocols/ace/INet/HTTP_SessionBase.h: * protocols/ace/INet/HTTP_SessionBase.inl: * protocols/ace/INet/HTTPS_Session.cpp: * protocols/ace/INet/HTTPS_SessionFactory.cpp: * protocols/ace/INet/HTTPS_SessionFactory.h: * protocols/ace/INet/HTTPS_Session.h: * protocols/ace/INet/HTTPS_URL.cpp: * protocols/ace/INet/HTTPS_URL.h: * protocols/ace/INet/HTTPS_URL.inl: * protocols/ace/INet/SSL_CallbackManager.cpp: * protocols/ace/INet/SSL_CallbackManager.h: * protocols/ace/INet/SSL_CallbackManager.inl: * protocols/ace/INet/SSL_CertificateCallback.cpp: * protocols/ace/INet/SSL_CertificateCallback.h: * protocols/ace/INet/SSL_CertificateCallback.inl: * protocols/ace/INet/SSL_PasswordCallback.cpp: * protocols/ace/INet/SSL_PasswordCallback.h: * protocols/ace/INet/SSL_Proxy_Connector.cpp: * protocols/ace/INet/SSL_Proxy_Connector.h: * protocols/ace/INet/SSLSock_IOStream.cpp: * protocols/ace/INet/SSLSock_IOStream.h: * protocols/ace/INet/SSL_X509Cert.cpp: * protocols/ace/INet/SSL_X509Cert.h: * protocols/ace/INet/SSL_X509Cert.inl: New files implementing SSL/HTTPS support. Includes support for proxy CONNECT tunneling. * protocols/ace/INet/inet_ssl.mpb: Feature project which will include SSL/HTTPS support into INet when MPC feature ssl=1 is set. * protocols/ace/INet/ClientRequestHandler.cpp: * protocols/ace/INet/ClientRequestHandler.h: * protocols/ace/INet/ConnectionCache.cpp: * protocols/ace/INet/ConnectionCache.h: * protocols/ace/INet/FTP_ClientRequestHandler.cpp: * protocols/ace/INet/FTP_URL.cpp: * protocols/ace/INet/FTP_URL.h: * protocols/ace/INet/FTP_URL.inl: * protocols/ace/INet/HeaderBase.h: * protocols/ace/INet/HTTP_ClientRequestHandler.cpp: * protocols/ace/INet/HTTP_ClientRequestHandler.h: * protocols/ace/INet/HTTP_ClientRequestHandler.inl: * protocols/ace/INet/HTTP_Session.cpp: * protocols/ace/INet/HTTP_Session.h: * protocols/ace/INet/HTTP_StreamPolicyBase.h: * protocols/ace/INet/HTTP_StreamPolicy.h: * protocols/ace/INet/HTTP_URL.cpp: * protocols/ace/INet/HTTP_URL.h: * protocols/ace/INet/HTTP_URL.inl: * protocols/ace/INet/inet.mpc: * protocols/ace/INet/RequestHandler.h: * protocols/ace/INet/StreamHandler.cpp: * protocols/ace/INet/StreamInterceptor.h: * protocols/ace/INet/URLBase.h: Some redesign to accomodate addition of HTTPS. Some additional logging. Some additional documentation. * protocols/ace/INet/HTTP_Simple_exec.cpp: Extended to include HTTPS support. * protocols/tests/INet/MT_Get/Main.cpp: Added some traces.
-rw-r--r--ACE/ChangeLog77
-rw-r--r--ACE/bin/MakeProjectCreator/config/inet.mpb2
-rw-r--r--ACE/bin/MakeProjectCreator/config/inetssl.mpb2
-rw-r--r--ACE/protocols/ace/INet/ClientRequestHandler.cpp9
-rw-r--r--ACE/protocols/ace/INet/ClientRequestHandler.h1
-rw-r--r--ACE/protocols/ace/INet/ConnectionCache.cpp37
-rw-r--r--ACE/protocols/ace/INet/ConnectionCache.h6
-rw-r--r--ACE/protocols/ace/INet/FTP_ClientRequestHandler.cpp2
-rw-r--r--ACE/protocols/ace/INet/FTP_URL.cpp10
-rw-r--r--ACE/protocols/ace/INet/FTP_URL.h4
-rw-r--r--ACE/protocols/ace/INet/FTP_URL.inl2
-rw-r--r--ACE/protocols/ace/INet/HTTPS_Context.cpp125
-rw-r--r--ACE/protocols/ace/INet/HTTPS_Context.h105
-rw-r--r--ACE/protocols/ace/INet/HTTPS_Context.inl94
-rw-r--r--ACE/protocols/ace/INet/HTTPS_Session.cpp265
-rw-r--r--ACE/protocols/ace/INet/HTTPS_Session.h85
-rw-r--r--ACE/protocols/ace/INet/HTTPS_SessionFactory.cpp77
-rw-r--r--ACE/protocols/ace/INet/HTTPS_SessionFactory.h70
-rw-r--r--ACE/protocols/ace/INet/HTTPS_URL.cpp109
-rw-r--r--ACE/protocols/ace/INet/HTTPS_URL.h89
-rw-r--r--ACE/protocols/ace/INet/HTTPS_URL.inl27
-rw-r--r--ACE/protocols/ace/INet/HTTP_ClientRequestHandler.cpp257
-rw-r--r--ACE/protocols/ace/INet/HTTP_ClientRequestHandler.h158
-rw-r--r--ACE/protocols/ace/INet/HTTP_ClientRequestHandler.inl28
-rw-r--r--ACE/protocols/ace/INet/HTTP_Session.cpp397
-rw-r--r--ACE/protocols/ace/INet/HTTP_Session.h72
-rw-r--r--ACE/protocols/ace/INet/HTTP_SessionBase.cpp308
-rw-r--r--ACE/protocols/ace/INet/HTTP_SessionBase.h134
-rw-r--r--ACE/protocols/ace/INet/HTTP_SessionBase.inl124
-rw-r--r--ACE/protocols/ace/INet/HTTP_Simple_exec.cpp101
-rw-r--r--ACE/protocols/ace/INet/HTTP_StreamPolicy.h6
-rw-r--r--ACE/protocols/ace/INet/HTTP_StreamPolicyBase.h2
-rw-r--r--ACE/protocols/ace/INet/HTTP_URL.cpp16
-rw-r--r--ACE/protocols/ace/INet/HTTP_URL.h10
-rw-r--r--ACE/protocols/ace/INet/HTTP_URL.inl2
-rw-r--r--ACE/protocols/ace/INet/HeaderBase.h18
-rw-r--r--ACE/protocols/ace/INet/RequestHandler.h2
-rw-r--r--ACE/protocols/ace/INet/SSLSock_IOStream.cpp130
-rw-r--r--ACE/protocols/ace/INet/SSLSock_IOStream.h169
-rw-r--r--ACE/protocols/ace/INet/SSL_CallbackManager.cpp122
-rw-r--r--ACE/protocols/ace/INet/SSL_CallbackManager.h78
-rw-r--r--ACE/protocols/ace/INet/SSL_CallbackManager.inl33
-rw-r--r--ACE/protocols/ace/INet/SSL_CertificateCallback.cpp62
-rw-r--r--ACE/protocols/ace/INet/SSL_CertificateCallback.h102
-rw-r--r--ACE/protocols/ace/INet/SSL_CertificateCallback.inl57
-rw-r--r--ACE/protocols/ace/INet/SSL_PasswordCallback.cpp23
-rw-r--r--ACE/protocols/ace/INet/SSL_PasswordCallback.h44
-rw-r--r--ACE/protocols/ace/INet/SSL_Proxy_Connector.cpp212
-rw-r--r--ACE/protocols/ace/INet/SSL_Proxy_Connector.h60
-rw-r--r--ACE/protocols/ace/INet/SSL_X509Cert.cpp18
-rw-r--r--ACE/protocols/ace/INet/SSL_X509Cert.h57
-rw-r--r--ACE/protocols/ace/INet/SSL_X509Cert.inl65
-rw-r--r--ACE/protocols/ace/INet/StreamHandler.cpp4
-rw-r--r--ACE/protocols/ace/INet/StreamInterceptor.h2
-rw-r--r--ACE/protocols/ace/INet/URLBase.h7
-rw-r--r--ACE/protocols/ace/INet/inet.mpc3
-rw-r--r--ACE/protocols/ace/INet/inet_ssl.mpb18
-rw-r--r--ACE/protocols/tests/INet/MT_Get/Main.cpp8
58 files changed, 3567 insertions, 540 deletions
diff --git a/ACE/ChangeLog b/ACE/ChangeLog
index e31a732c557..e4fb4cb24c4 100644
--- a/ACE/ChangeLog
+++ b/ACE/ChangeLog
@@ -1,3 +1,80 @@
+Sat Jul 17 10:26:30 UTC 2010 Martin Corino <mcorino@remedy.nl>
+
+ * bin/MakeProjectCreator/config/inetssl.mpb:
+ * bin/MakeProjectCreator/config/inet.mpb:
+ Added feature project for SSL based parts of INet.
+ Setting feature ssl=1 will automatically cause correct
+ dependencies for SSL to be generated in INet based projects.
+
+ * protocols/ace/INet/HTTPS_Context.cpp:
+ * protocols/ace/INet/HTTPS_Context.h:
+ * protocols/ace/INet/HTTPS_Context.inl:
+ * protocols/ace/INet/HTTP_SessionBase.cpp:
+ * protocols/ace/INet/HTTP_SessionBase.h:
+ * protocols/ace/INet/HTTP_SessionBase.inl:
+ * protocols/ace/INet/HTTPS_Session.cpp:
+ * protocols/ace/INet/HTTPS_SessionFactory.cpp:
+ * protocols/ace/INet/HTTPS_SessionFactory.h:
+ * protocols/ace/INet/HTTPS_Session.h:
+ * protocols/ace/INet/HTTPS_URL.cpp:
+ * protocols/ace/INet/HTTPS_URL.h:
+ * protocols/ace/INet/HTTPS_URL.inl:
+ * protocols/ace/INet/SSL_CallbackManager.cpp:
+ * protocols/ace/INet/SSL_CallbackManager.h:
+ * protocols/ace/INet/SSL_CallbackManager.inl:
+ * protocols/ace/INet/SSL_CertificateCallback.cpp:
+ * protocols/ace/INet/SSL_CertificateCallback.h:
+ * protocols/ace/INet/SSL_CertificateCallback.inl:
+ * protocols/ace/INet/SSL_PasswordCallback.cpp:
+ * protocols/ace/INet/SSL_PasswordCallback.h:
+ * protocols/ace/INet/SSL_Proxy_Connector.cpp:
+ * protocols/ace/INet/SSL_Proxy_Connector.h:
+ * protocols/ace/INet/SSLSock_IOStream.cpp:
+ * protocols/ace/INet/SSLSock_IOStream.h:
+ * protocols/ace/INet/SSL_X509Cert.cpp:
+ * protocols/ace/INet/SSL_X509Cert.h:
+ * protocols/ace/INet/SSL_X509Cert.inl:
+ New files implementing SSL/HTTPS support.
+ Includes support for proxy CONNECT tunneling.
+
+ * protocols/ace/INet/inet_ssl.mpb:
+ Feature project which will include SSL/HTTPS support
+ into INet when MPC feature ssl=1 is set.
+
+ * protocols/ace/INet/ClientRequestHandler.cpp:
+ * protocols/ace/INet/ClientRequestHandler.h:
+ * protocols/ace/INet/ConnectionCache.cpp:
+ * protocols/ace/INet/ConnectionCache.h:
+ * protocols/ace/INet/FTP_ClientRequestHandler.cpp:
+ * protocols/ace/INet/FTP_URL.cpp:
+ * protocols/ace/INet/FTP_URL.h:
+ * protocols/ace/INet/FTP_URL.inl:
+ * protocols/ace/INet/HeaderBase.h:
+ * protocols/ace/INet/HTTP_ClientRequestHandler.cpp:
+ * protocols/ace/INet/HTTP_ClientRequestHandler.h:
+ * protocols/ace/INet/HTTP_ClientRequestHandler.inl:
+ * protocols/ace/INet/HTTP_Session.cpp:
+ * protocols/ace/INet/HTTP_Session.h:
+ * protocols/ace/INet/HTTP_StreamPolicyBase.h:
+ * protocols/ace/INet/HTTP_StreamPolicy.h:
+ * protocols/ace/INet/HTTP_URL.cpp:
+ * protocols/ace/INet/HTTP_URL.h:
+ * protocols/ace/INet/HTTP_URL.inl:
+ * protocols/ace/INet/inet.mpc:
+ * protocols/ace/INet/RequestHandler.h:
+ * protocols/ace/INet/StreamHandler.cpp:
+ * protocols/ace/INet/StreamInterceptor.h:
+ * protocols/ace/INet/URLBase.h:
+ Some redesign to accomodate addition of HTTPS.
+ Some additional logging.
+ Some additional documentation.
+
+ * protocols/ace/INet/HTTP_Simple_exec.cpp:
+ Extended to include HTTPS support.
+
+ * protocols/tests/INet/MT_Get/Main.cpp:
+ Added some traces.
+
Fri Jul 16 22:08:05 UTC 2010 Phil Mesnier <mesnier_p@ociweb.com>
* ace/Service_Gestalt.h:
diff --git a/ACE/bin/MakeProjectCreator/config/inet.mpb b/ACE/bin/MakeProjectCreator/config/inet.mpb
index 56efc1b9542..e596af03f56 100644
--- a/ACE/bin/MakeProjectCreator/config/inet.mpb
+++ b/ACE/bin/MakeProjectCreator/config/inet.mpb
@@ -1,7 +1,7 @@
// -*- MPC -*-
// $Id$
-project : acelib {
+project : acelib, inetssl {
avoids += wince
avoids += old_stdstream
after += INet
diff --git a/ACE/bin/MakeProjectCreator/config/inetssl.mpb b/ACE/bin/MakeProjectCreator/config/inetssl.mpb
new file mode 100644
index 00000000000..92e0d5d7036
--- /dev/null
+++ b/ACE/bin/MakeProjectCreator/config/inetssl.mpb
@@ -0,0 +1,2 @@
+feature(ssl) : ssl {
+}
diff --git a/ACE/protocols/ace/INet/ClientRequestHandler.cpp b/ACE/protocols/ace/INet/ClientRequestHandler.cpp
index 5f58ff8d053..3a0a12d6eb5 100644
--- a/ACE/protocols/ace/INet/ClientRequestHandler.cpp
+++ b/ACE/protocols/ace/INet/ClientRequestHandler.cpp
@@ -57,8 +57,13 @@ namespace ACE
bool ClientINetRequestHandler::INetConnectionKey::equal (const ConnectionKey& key) const
{
- const INetConnectionKey& ikey = dynamic_cast<const INetConnectionKey&> (key);
- return this->host_ == ikey.host_ && this->port_ == ikey.port_;
+ try {
+ const INetConnectionKey& ikey = dynamic_cast<const INetConnectionKey&> (key);
+ return this->host_ == ikey.host_ && this->port_ == ikey.port_;
+ }
+ catch (...) {
+ return false;
+ }
}
}
diff --git a/ACE/protocols/ace/INet/ClientRequestHandler.h b/ACE/protocols/ace/INet/ClientRequestHandler.h
index 227934c89e7..212adeb98d8 100644
--- a/ACE/protocols/ace/INet/ClientRequestHandler.h
+++ b/ACE/protocols/ace/INet/ClientRequestHandler.h
@@ -67,7 +67,6 @@ namespace ACE
ClientINetRequestHandler ();
virtual ~ClientINetRequestHandler ();
- protected:
/**
* @class ACE_INet_INetConnectionKey
*
diff --git a/ACE/protocols/ace/INet/ConnectionCache.cpp b/ACE/protocols/ace/INet/ConnectionCache.cpp
index dda10d74208..ed3bb000b92 100644
--- a/ACE/protocols/ace/INet/ConnectionCache.cpp
+++ b/ACE/protocols/ace/INet/ConnectionCache.cpp
@@ -153,8 +153,8 @@ namespace ACE
}
else
{
- ACE_ERROR ((LM_ERROR, ACE_TEXT ("%P|%t) ConnectionCache::claim_existing_connection - ")
- ACE_TEXT ("failed to claim connection entry")));
+ INET_ERROR (1, (LM_ERROR, DLINFO ACE_TEXT ("ConnectionCache::claim_existing_connection - ")
+ ACE_TEXT ("failed to claim connection entry")));
}
}
}
@@ -181,6 +181,8 @@ namespace ACE
if (this->claim_existing_connection (key, connection, state))
{
+ INET_DEBUG (9, (LM_INFO, DLINFO ACE_TEXT ("%P|%t) ConnectionCache::claim_connection - ")
+ ACE_TEXT ("successfully claimed existing connection\n")));
return true;
}
@@ -193,8 +195,8 @@ namespace ACE
{
if (!this->set_connection (key, ConnectionCacheValue ()))
{
- ACE_ERROR ((LM_ERROR, ACE_TEXT ("%P|%t) ConnectionCache::claim_connection - ")
- ACE_TEXT ("failed to initialize connection entry")));
+ INET_ERROR (1, (LM_ERROR, DLINFO ACE_TEXT ("ConnectionCache::claim_connection - ")
+ ACE_TEXT ("failed to initialize connection entry")));
return false;
}
@@ -202,13 +204,17 @@ namespace ACE
}
else
{
+ INET_DEBUG (9, (LM_INFO, DLINFO ACE_TEXT ("ConnectionCache::claim_connection - ")
+ ACE_TEXT ("waiting for connection to become available\n")));
// wait for connection to become ready/free
if (this->condition_.wait () != 0)
{
- ACE_ERROR ((LM_ERROR, ACE_TEXT ("%P|%t) ConnectionCache::claim_connection - ")
- ACE_TEXT ("error waiting for connection condition (%p)\n")));
+ INET_ERROR (1, (LM_ERROR, DLINFO ACE_TEXT ("(%P|%t) ConnectionCache::claim_connection - ")
+ ACE_TEXT ("error waiting for connection condition (%p)\n")));
return false;
}
+ INET_DEBUG (9, (LM_INFO, DLINFO ACE_TEXT ("ConnectionCache::claim_connection - ")
+ ACE_TEXT ("awoken and retrying to claim connection\n")));
}
}
while (0);
@@ -218,6 +224,9 @@ namespace ACE
connection = connection_factory.create_connection (key);
if (connection)
{
+ INET_DEBUG (9, (LM_INFO, DLINFO ACE_TEXT ("ConnectionCache::claim_connection - ")
+ ACE_TEXT ("successfully created new connection\n")));
+
ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX,
guard_,
this->lock_,
@@ -227,6 +236,8 @@ namespace ACE
cacheval.state (ConnectionCacheValue::CST_BUSY);
return this->set_connection (key, cacheval);
}
+ else
+ return false;
}
}
}
@@ -236,6 +247,9 @@ namespace ACE
{
INET_TRACE ("ConnectionCache::release_connection");
+ INET_DEBUG (9, (LM_INFO, DLINFO ACE_TEXT ("ConnectionCache::release_connection - ")
+ ACE_TEXT ("releasing connection\n")));
+
ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX,
guard_,
this->lock_,
@@ -255,8 +269,8 @@ namespace ACE
}
else
{
- ACE_ERROR ((LM_ERROR, ACE_TEXT ("%P|%t) ConnectionCache::release_connection - ")
- ACE_TEXT ("failed to release connection entry")));
+ INET_ERROR (1, (LM_ERROR, DLINFO ACE_TEXT ("ConnectionCache::release_connection - ")
+ ACE_TEXT ("failed to release connection entry")));
return false;
}
}
@@ -269,6 +283,9 @@ namespace ACE
{
INET_TRACE ("ConnectionCache::close_connection");
+ INET_DEBUG (9, (LM_INFO, DLINFO ACE_TEXT ("ConnectionCache::close_connection - ")
+ ACE_TEXT ("closing connection\n")));
+
ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX,
guard_,
this->lock_,
@@ -291,8 +308,8 @@ namespace ACE
}
else
{
- ACE_ERROR ((LM_ERROR, ACE_TEXT ("%P|%t) ConnectionCache::close_connection - ")
- ACE_TEXT ("failed to close connection entry")));
+ INET_ERROR (1, (LM_ERROR, DLINFO ACE_TEXT ("ConnectionCache::close_connection - ")
+ ACE_TEXT ("failed to close connection entry")));
return false;
}
}
diff --git a/ACE/protocols/ace/INet/ConnectionCache.h b/ACE/protocols/ace/INet/ConnectionCache.h
index 194f4fc67fa..0776fe295da 100644
--- a/ACE/protocols/ace/INet/ConnectionCache.h
+++ b/ACE/protocols/ace/INet/ConnectionCache.h
@@ -31,7 +31,7 @@ namespace ACE
* @brief Base class for connection keys.
*
*/
- class ConnectionKey
+ class ACE_INET_Export ConnectionKey
{
public:
ConnectionKey ();
@@ -85,7 +85,7 @@ namespace ACE
* @brief Generic base for connection wrappers.
*
*/
- class ConnectionHolder
+ class ACE_INET_Export ConnectionHolder
{
public:
virtual ~ConnectionHolder ();
@@ -103,7 +103,7 @@ namespace ACE
* return those for caching wrapped in a connection
* holder.
*/
- class ConnectionFactory
+ class ACE_INET_Export ConnectionFactory
{
public:
ConnectionFactory ();
diff --git a/ACE/protocols/ace/INet/FTP_ClientRequestHandler.cpp b/ACE/protocols/ace/INet/FTP_ClientRequestHandler.cpp
index 08d2f2686ee..0234c74fb10 100644
--- a/ACE/protocols/ace/INet/FTP_ClientRequestHandler.cpp
+++ b/ACE/protocols/ace/INet/FTP_ClientRequestHandler.cpp
@@ -79,7 +79,7 @@ namespace ACE
const ACE_CString& ClientRequestHandler::Authentication::scheme () const
{
- return URL::PROTOCOL;
+ return URL::protocol ();
}
const ACE_CString& ClientRequestHandler::Authentication::realm () const
diff --git a/ACE/protocols/ace/INet/FTP_URL.cpp b/ACE/protocols/ace/INet/FTP_URL.cpp
index 3a07ad3c965..b6a8118a2d0 100644
--- a/ACE/protocols/ace/INet/FTP_URL.cpp
+++ b/ACE/protocols/ace/INet/FTP_URL.cpp
@@ -15,7 +15,13 @@ namespace ACE
{
namespace FTP
{
- const ACE_CString URL::PROTOCOL ("ftp");
+ const char* URL::PROTOCOL = "ftp";
+
+ const ACE_CString& URL::protocol ()
+ {
+ static const ACE_CString protocol_ (PROTOCOL);
+ return protocol_;
+ }
URL::URL ()
: URL_INetAuthBase (FTP_PORT)
@@ -75,7 +81,7 @@ namespace ACE
const ACE_CString& URL::Factory::protocol ()
{
- return URL::PROTOCOL;
+ return URL::protocol ();
}
ACE::INet::URL_Base* URL::Factory::create_from_string (const ACE_CString& url_string)
diff --git a/ACE/protocols/ace/INet/FTP_URL.h b/ACE/protocols/ace/INet/FTP_URL.h
index d33cfd29732..68f505e550d 100644
--- a/ACE/protocols/ace/INet/FTP_URL.h
+++ b/ACE/protocols/ace/INet/FTP_URL.h
@@ -49,7 +49,9 @@ namespace ACE
virtual u_short default_port () const;
- static const ACE_CString PROTOCOL;
+ static const char* PROTOCOL;
+
+ static const ACE_CString& protocol ();
enum
{
diff --git a/ACE/protocols/ace/INet/FTP_URL.inl b/ACE/protocols/ace/INet/FTP_URL.inl
index b5ae8aebde6..0a5cd7fb23d 100644
--- a/ACE/protocols/ace/INet/FTP_URL.inl
+++ b/ACE/protocols/ace/INet/FTP_URL.inl
@@ -12,7 +12,7 @@ namespace ACE
ACE_INLINE
const ACE_CString& URL::get_scheme () const
{
- return PROTOCOL;
+ return protocol ();
}
ACE_INLINE
diff --git a/ACE/protocols/ace/INet/HTTPS_Context.cpp b/ACE/protocols/ace/INet/HTTPS_Context.cpp
new file mode 100644
index 00000000000..6eff53b4daf
--- /dev/null
+++ b/ACE/protocols/ace/INet/HTTPS_Context.cpp
@@ -0,0 +1,125 @@
+// $Id$
+
+#include "ace/INet/HTTPS_Context.h"
+
+#if !defined (__ACE_INLINE__)
+#include "ace/INet/HTTPS_Context.inl"
+#endif
+
+#include "ace/OS_NS_stdlib.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/OS_NS_sys_stat.h"
+#include "ace/INet/INet_Log.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace ACE
+{
+ namespace HTTPS
+ {
+
+ int Context::ssl_mode_ = ACE_SSL_Context::SSLv3;
+ bool Context::ssl_strict_ = false;
+ bool Context::ssl_once_ = true;
+ int Context::ssl_depth_ = 0;
+ bool Context::ssl_verify_peer_ = true;
+
+ Context::Context (bool verify_peer,
+ bool strict,
+ bool once,
+ int depth,
+ int ssl_mode,
+ ACE_SSL_Context* ssl_ctx,
+ bool release,
+ ACE::INet::SSL_CallbackManager* ssl_cbmngr)
+ : ssl_ctx_ (0)
+ {
+ if (ssl_ctx == 0)
+ {
+ ACE_NEW_NORETURN (ssl_ctx, ACE_SSL_Context ());
+ release = true;
+ }
+ if (ssl_ctx != 0)
+ {
+ if (release)
+ {
+ this->alloc_safe.reset (ssl_ctx);
+ }
+ this->ssl_ctx_ = ssl_ctx;
+
+ this->ssl_ctx_->set_mode (ssl_mode);
+ if (verify_peer)
+ this->ssl_ctx_->set_verify_peer (strict ? 1 : 0,
+ once ? 1 : 0,
+ depth);
+ if (ssl_cbmngr != 0)
+ ssl_cbmngr->initialize_callbacks (this->ssl_ctx_);
+ // do this to be sure that these settings have been properly set
+ // ACE_SSL_Context does not handle this quite correctly
+ ::SSL_CTX_set_verify (this->ssl_ctx_->context (),
+ this->ssl_ctx_->default_verify_mode (),
+ this->ssl_ctx_->default_verify_callback ());
+ INET_DEBUG (9,(LM_INFO, DLINFO
+ ACE_TEXT ("HTTPS_Context::ctor - ")
+ ACE_TEXT ("ssl_mode = [%d], ")
+ ACE_TEXT ("verify_peer = [%d], ")
+ ACE_TEXT ("verify_mode = [%d]\n"),
+ this->ssl_ctx_->get_mode (),
+ (verify_peer ? 1 : 0),
+ this->ssl_ctx_->default_verify_mode ()));
+ }
+ }
+
+ Context::Context (ACE_SSL_Context* ssl_ctx,
+ bool release,
+ ACE::INet::SSL_CallbackManager* ssl_cbmngr)
+ : ssl_ctx_ (ssl_ctx)
+ {
+ if (this->ssl_ctx_ != 0)
+ {
+ if (release)
+ this->alloc_safe.reset (this->ssl_ctx_);
+
+ if (ssl_cbmngr != 0)
+ ssl_cbmngr->initialize_callbacks (this->ssl_ctx_);
+ }
+ }
+
+ Context& Context::instance ()
+ {
+ return *ACE_Unmanaged_Singleton<Context, ACE_SYNCH::MUTEX>::instance ();
+ }
+
+ Context::Context (const Context&)
+ {
+ }
+
+ Context::~Context ()
+ {
+ }
+
+ bool Context::load_trusted_ca (const char* ca_location)
+ {
+ ACE_stat stat;
+ if (ca_location != 0 && ACE_OS::stat (ca_location, &stat) == 0)
+ {
+ bool is_dir = ((stat.st_mode & S_IFMT) == S_IFDIR);
+ if (this->ssl_ctx_->load_trusted_ca (is_dir ? 0 : ca_location,
+ is_dir ? ca_location : 0,
+ false) == 0)
+ return true;
+ }
+ else
+ {
+ INET_ERROR (1, (LM_ERROR, DLINFO
+ ACE_TEXT ("Context::load_trusted_ca - ")
+ ACE_TEXT ("invalid ca_location [%C]\n"),
+ ca_location == 0 ? "(null)" : ca_location));
+ }
+ return false;
+ }
+
+ }
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/protocols/ace/INet/HTTPS_Context.h b/ACE/protocols/ace/INet/HTTPS_Context.h
new file mode 100644
index 00000000000..713bd7dde97
--- /dev/null
+++ b/ACE/protocols/ace/INet/HTTPS_Context.h
@@ -0,0 +1,105 @@
+// $Id$
+
+/**
+ * @file HTTPS_Context.h
+ *
+ * @author Martin Corino <mcorino@remedy.nl>
+ */
+
+#ifndef ACE_HTTPS_CONTEXT_H
+#define ACE_HTTPS_CONTEXT_H
+
+#include /**/ "ace/pre.h"
+
+#include "ace/SString.h"
+#include "ace/Auto_Ptr.h"
+#include "ace/Singleton.h"
+#include "ace/SSL/SSL_Context.h"
+#include "ace/INet/SSL_CallbackManager.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace ACE
+ {
+ namespace HTTPS
+ {
+ /**
+ * @class ACE_HTTPS_Context
+ *
+ * @brief Implements security (SSL) context for HTTPS sessions.
+ *
+ */
+ class ACE_INET_Export Context
+ {
+ public:
+ Context (bool verify_peer = Context::ssl_verify_peer_,
+ bool strict = Context::ssl_strict_,
+ bool once = Context::ssl_once_,
+ int depth = Context::ssl_depth_,
+ int ssl_mode = Context::ssl_mode_,
+ ACE_SSL_Context* ssl_ctx =
+ ACE_SSL_Context::instance (),
+ bool release = false,
+ ACE::INet::SSL_CallbackManager* ssl_cbmngr =
+ ACE::INet::SSL_CallbackManager::instance ());
+
+ Context (ACE_SSL_Context* ssl_ctx,
+ bool release = false,
+ ACE::INet::SSL_CallbackManager* ssl_cbmngr = 0);
+
+ ~Context ();
+
+ operator bool (void) const;
+
+ bool operator ! (void) const;
+
+ ACE_SSL_Context& ssl_context (void);
+
+ const ACE_SSL_Context& ssl_context (void) const;
+
+ bool use_default_ca ();
+
+ bool set_key_files (const char* certificate_filename,
+ const char* private_key_filename,
+ int file_type = SSL_FILETYPE_PEM);
+
+ bool load_trusted_ca (const char* ca_location);
+
+ int has_trusted_ca ();
+
+ static void set_default_ssl_mode (int ssl_mode);
+
+ static void set_default_verify_mode (bool verify_peer);
+
+ static void set_default_verify_settings (bool strict,
+ bool once = true,
+ int depth = 0);
+
+ static Context& instance ();
+
+ private:
+ friend class ACE_Singleton<Context, ACE_SYNCH::MUTEX>;
+
+ //Context ();
+ Context (const Context&);
+
+ ACE_SSL_Context* ssl_ctx_;
+ ACE_Auto_Ptr<ACE_SSL_Context> alloc_safe;
+
+ static int ssl_mode_;
+ static bool ssl_strict_;
+ static bool ssl_once_;
+ static int ssl_depth_;
+ static bool ssl_verify_peer_;
+ };
+ }
+ }
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#if defined (__ACE_INLINE__)
+#include "ace/INet/HTTPS_Context.inl"
+#endif
+
+#include /**/ "ace/post.h"
+#endif /* ACE_SSL_CALLBACKMANAGER_H */
diff --git a/ACE/protocols/ace/INet/HTTPS_Context.inl b/ACE/protocols/ace/INet/HTTPS_Context.inl
new file mode 100644
index 00000000000..d4aaee7e8c8
--- /dev/null
+++ b/ACE/protocols/ace/INet/HTTPS_Context.inl
@@ -0,0 +1,94 @@
+// -*- C++ -*-
+//
+// $Id$
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace ACE
+{
+ namespace HTTPS
+ {
+
+ ACE_INLINE
+ Context::operator bool (void) const
+ {
+ return this->ssl_ctx_ != 0;
+ }
+
+ ACE_INLINE
+ bool Context::operator ! (void) const
+ {
+ return this->ssl_ctx_ == 0;
+ }
+
+ ACE_INLINE
+ ACE_SSL_Context& Context::ssl_context (void)
+ {
+ return *this->ssl_ctx_;
+ }
+
+ ACE_INLINE
+ const ACE_SSL_Context& Context::ssl_context (void) const
+ {
+ return *this->ssl_ctx_;
+ }
+
+ ACE_INLINE
+ bool Context::use_default_ca ()
+ {
+ if (::SSL_CTX_set_default_verify_paths(this->ssl_ctx_->context ()) != 1)
+ {
+ ACE_SSL_Context::report_error ();
+ return false;
+ }
+ return true;
+ }
+
+ ACE_INLINE
+ bool Context::set_key_files (const char* certificate_filename,
+ const char* private_key_filename,
+ int file_type)
+ {
+ if (this->ssl_ctx_->certificate (certificate_filename, file_type) == 0)
+ {
+ if (this->ssl_ctx_->private_key (private_key_filename, file_type) == 0)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ ACE_INLINE
+ int Context::has_trusted_ca ()
+ {
+ return this->ssl_ctx_->have_trusted_ca ();
+ }
+
+ ACE_INLINE
+ void Context::set_default_ssl_mode (int ssl_mode)
+ {
+ Context::ssl_mode_ = ssl_mode;
+ }
+
+ ACE_INLINE
+ void Context::set_default_verify_mode (bool verify_peer)
+ {
+ Context::ssl_verify_peer_ = verify_peer;
+ }
+
+ ACE_INLINE
+ void Context::set_default_verify_settings (bool strict,
+ bool once,
+ int depth)
+ {
+ Context::ssl_strict_ = strict;
+ Context::ssl_once_ = once;
+ Context::ssl_depth_ = depth;
+ }
+
+
+ }
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/protocols/ace/INet/HTTPS_Session.cpp b/ACE/protocols/ace/INet/HTTPS_Session.cpp
new file mode 100644
index 00000000000..da6098dfc1a
--- /dev/null
+++ b/ACE/protocols/ace/INet/HTTPS_Session.cpp
@@ -0,0 +1,265 @@
+// $Id$
+
+#ifndef ACE_HTTPS_SESSION_CPP
+#define ACE_HTTPS_SESSION_CPP
+
+#include "ace/INet/HTTPS_Session.h"
+#include "ace/INet/INet_Log.h"
+#include "ace/INet/IOS_util.h"
+#include "ace/INet/HTTPS_URL.h"
+#include "ace/INet/Sock_IOStream.h"
+#include "ace/INet/String_IOStream.h"
+#include "ace/INet/SSL_Proxy_Connector.h"
+#include "ace/INET_Addr.h"
+#include "ace/Event_Handler.h"
+#include "ace/Connector.h"
+#include "ace/SSL/SSL_SOCK_Connector.h"
+#include "ace/String_Base.h"
+#include <istream>
+#include <ostream>
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace ACE
+{
+ namespace HTTPS
+ {
+
+ template <ACE_SYNCH_DECL>
+ Session_T<ACE_SYNCH_USE>::Session_T (bool keep_alive, Context& ctx)
+ : SessionBase (URL::HTTPS_PORT, keep_alive),
+ connection_ (0),
+ sock_stream_ (0),
+ context_ (ctx)
+ {
+ INET_TRACE ("ACE_HTTPS_Session - ctor");
+ }
+
+ template <ACE_SYNCH_DECL>
+ Session_T<ACE_SYNCH_USE>::Session_T (const ACE_Time_Value& timeout,
+ bool keep_alive,
+ const ACE_Time_Value* alive_timeout,
+ Context& ctx)
+ : SessionBase (URL::HTTPS_PORT, timeout, keep_alive, alive_timeout),
+ connection_ (0),
+ sock_stream_ (0),
+ context_ (ctx)
+ {
+ INET_TRACE ("ACE_HTTPS_Session - ctor");
+ this->close_streams ();
+ this->close_connection ();
+ }
+
+ template <ACE_SYNCH_DECL>
+ Session_T<ACE_SYNCH_USE>::~Session_T ()
+ {
+ INET_TRACE ("ACE_HTTPS_Session - dtor");
+ }
+
+ template <ACE_SYNCH_DECL>
+ bool Session_T<ACE_SYNCH_USE>::is_connected () const
+ {
+ return this->connection_ && this->connection_->is_connected ();
+ }
+
+ template <ACE_SYNCH_DECL>
+ bool Session_T<ACE_SYNCH_USE>::connect_i (const ACE_Synch_Options& sync_opt)
+ {
+ INET_TRACE ("ACE_HTTPS_Session::connect_i");
+
+ connection_type* new_connection = 0;
+
+ if (this->is_proxy_connection ())
+ {
+ typedef ACE::IOS::StreamHandler<ACE_SOCK_STREAM, ACE_SYNCH_USE> proxy_connection_type;
+ typedef ACE_Connector<proxy_connection_type, ACE_SOCK_CONNECTOR> proxy_connector_type;
+ typedef ACE::IOS::Sock_IOStreamBase<ACE_SYNCH_USE> proxy_stream_type;
+
+ proxy_connection_type proxy_connection(sync_opt);
+ proxy_connector_type proxy_connector;
+
+ proxy_connection_type* proxy_connection_ptr = &proxy_connection;
+ if (proxy_connector.connect (proxy_connection_ptr,
+ ACE_INET_Addr (this->port_,
+ this->host_.c_str ()),
+ ACE_Synch_Options (0,this->http_timeout_)) == -1)
+ {
+ INET_ERROR (1, (LM_ERROR, DLINFO
+ ACE_TEXT ("(%d) ACE_HTTPS_Session::connect_i - ")
+ ACE_TEXT ("failed to connect to proxy; host=%C, port=%d\n"),
+ ACE_OS::last_error (), this->host_.c_str (), this->port_));
+ return false;
+ }
+
+ proxy_stream_type proxy_stream (&proxy_connection);
+ ACE::IOS::CString_OStream target_address;
+ target_address << this->proxy_target_host_ << ':' << this->proxy_target_port_;
+ ACE::HTTP::Request connect_request (ACE::HTTP::Request::HTTP_CONNECT,
+ target_address.str ().c_str (),
+ ACE::HTTP::Request::HTTP_1_1);
+ connect_request.set("Proxy-Connection", "keep-alive");
+ connect_request.set_host(this->proxy_target_host_);
+ ACE::HTTP::Response connect_response;
+
+ connect_request.write (proxy_stream);
+ proxy_stream.flush ();
+ if (!connect_response.read (proxy_stream) ||
+ !connect_response.get_status ().is_ok ())
+ {
+ INET_ERROR (1, (LM_ERROR, DLINFO
+ ACE_TEXT ("ACE_HTTPS_Session::connect_i - ")
+ ACE_TEXT ("cannot setup proxy tunnel; proxy replied: %d:%C\n"),
+ connect_response.get_status ().get_status(),
+ connect_response.get_status ().get_reason().c_str ()));
+ return false;
+ }
+
+ ACE_NEW_RETURN (new_connection,
+ connection_type(sync_opt),
+ false);
+ // set the provided SSL context for the SSL structure of the SSL_SOCK_Stream
+ ::SSL * ssl_ptr = new_connection->peer ().ssl ();
+ ::SSL_set_SSL_CTX (ssl_ptr, this->context_.ssl_context ().context ());
+
+ ACE_HANDLE proxy_conn_handle = proxy_connection.peer ().get_handle ();
+ proxy_connection.peer ().set_handle (ACE_INVALID_HANDLE);
+
+ ACE::INet::SSL_Proxy_Connector proxy_ssl_connector;
+ ACE_Time_Value conn_timeout (this->http_timeout_);
+ if (proxy_ssl_connector.connect (new_connection->peer (),
+ proxy_conn_handle,
+ &conn_timeout) != 0)
+ {
+ INET_ERROR (1, (LM_ERROR, DLINFO
+ ACE_TEXT ("ACE_HTTPS_Session::connect_i - ")
+ ACE_TEXT ("failed to setup proxy SSL connection\n")));
+ return false;
+ }
+ new_connection->open (); // mark stream handler as connected
+ }
+ else
+ {
+ ACE_NEW_RETURN (new_connection,
+ connection_type(sync_opt),
+ false);
+ // set the provided SSL context for the SSL structure of the SSL_SOCK_Stream
+ ::SSL * ssl_ptr = new_connection->peer ().ssl ();
+ ::SSL_set_SSL_CTX (ssl_ptr, this->context_.ssl_context ().context ());
+
+ typedef ACE_Connector<connection_type, ACE_SSL_SOCK_Connector> connector_type;
+
+ connector_type connector;
+
+ if (connector.connect (new_connection,
+ ACE_INET_Addr (this->port_,
+ this->host_.c_str ()),
+ ACE_Synch_Options (0,this->http_timeout_)) == -1)
+ {
+ INET_ERROR (1, (LM_ERROR, DLINFO
+ ACE_TEXT ("(%d) ACE_HTTPS_Session::connect_i - ")
+ ACE_TEXT ("failed to connect; host=%C, port=%d\n"),
+ ACE_OS::last_error (), this->host_.c_str (), this->port_));
+ // as the connection was dynamically allocated
+ // the connector causes it to be destroyed after
+ // the connection failure
+ return false;
+ }
+ }
+
+ this->connection_ = new_connection;
+ this->connection_->reference_counting_policy ().value (
+ ACE_Event_Handler::Reference_Counting_Policy::ENABLED);
+
+ ACE_NEW_NORETURN (this->sock_stream_,
+ sock_stream_type (this->connection_));
+ if (this->sock_stream_)
+ {
+ this->cannot_reconnect_ = false;
+ this->reactive_ = sync_opt[ACE_Synch_Options::USE_REACTOR];
+
+ // reset reconnect timer
+ this->reconnect_timer_ = this->keep_alive_timeout_;
+ this->reconnect_countdown_.start ();
+
+ return true;
+ }
+ else
+ {
+ this->close ();
+ return false;
+ }
+ }
+
+ template <ACE_SYNCH_DECL>
+ bool Session_T<ACE_SYNCH_USE>::attach_connection (connection_type* connection)
+ {
+ INET_TRACE ("ACE_HTTPS_Session::attach_connection");
+
+ if (!connection->is_connected ())
+ return false;
+
+ this->close ();
+
+ ACE_INET_Addr remote;
+ connection->peer ().get_remote_addr (remote);
+ this->host_ = remote.get_host_name ();
+ this->port_ = remote.get_port_number ();
+
+ this->connection_ = connection;
+ this->connection_->add_reference ();
+
+ ACE_NEW_NORETURN (this->sock_stream_,
+ sock_stream_type (this->connection_));
+
+ if (this->sock_stream_)
+ {
+ this->keep_alive_ = true;
+ this->keep_alive_timeout_ = ACE_Time_Value::zero;
+ this->cannot_reconnect_ = true;
+ return true;
+ }
+ else
+ {
+ this->close ();
+ return false;
+ }
+ }
+
+ template <ACE_SYNCH_DECL>
+ void Session_T<ACE_SYNCH_USE>::close_connection ()
+ {
+ if (this->sock_stream_)
+ {
+ delete this->sock_stream_;
+ this->sock_stream_ = 0;
+ }
+
+ if (this->connection_)
+ {
+ // this should be the last referece and removing it
+ // causes the connection to be destroyed
+ this->connection_->remove_reference ();
+ this->connection_ = 0;
+ }
+ }
+
+ template <ACE_SYNCH_DECL>
+ void Session_T<ACE_SYNCH_USE>::close_i ()
+ {
+ INET_TRACE ("ACE_HTTPS_Session::close_i");
+
+ this->close_connection ();
+ }
+
+ template <ACE_SYNCH_DECL>
+ std::iostream& Session_T<ACE_SYNCH_USE>::sock_stream ()
+ {
+ return *this->sock_stream_;
+ }
+
+ }
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* ACE_HTTPS_SESSION_CPP */
diff --git a/ACE/protocols/ace/INet/HTTPS_Session.h b/ACE/protocols/ace/INet/HTTPS_Session.h
new file mode 100644
index 00000000000..5738ced375e
--- /dev/null
+++ b/ACE/protocols/ace/INet/HTTPS_Session.h
@@ -0,0 +1,85 @@
+// $Id$
+
+/**
+ * @file HTTPS_Session.h
+ *
+ * @author Martin Corino <mcorino@remedy.nl>
+ */
+
+#ifndef ACE_HTTPS_SESSION_H
+#define ACE_HTTPS_SESSION_H
+
+#include /**/ "ace/pre.h"
+
+#include "ace/SSL/SSL_SOCK_Connector.h"
+#include "ace/INet/HTTP_SessionBase.h"
+#include "ace/INet/StreamHandler.h"
+#include "ace/INet/SSLSock_IOStream.h"
+#include "ace/INet/HTTPS_Context.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace ACE
+ {
+ namespace HTTPS
+ {
+ /**
+ * @class ACE_HTTPS_Session
+ *
+ * @brief Encapsulates HTTPS session.
+ *
+ */
+ template <ACE_SYNCH_DECL>
+ class Session_T : public ACE::HTTP::SessionBase
+ {
+ public:
+ typedef ACE::IOS::StreamHandler<ACE_SSL_SOCK_Stream, ACE_SYNCH_USE> connection_type;
+
+ Session_T (bool keep_alive = true,
+ Context& ctx = Context::instance ());
+
+ Session_T (const ACE_Time_Value& timeout,
+ bool keep_alive = true,
+ const ACE_Time_Value* alive_timeout = 0,
+ Context& ctx = Context::instance ());
+
+ virtual ~Session_T ();
+
+ virtual bool is_connected () const;
+
+ bool attach_connection (connection_type* connection);
+
+ protected:
+
+ void close_connection ();
+
+ virtual bool connect_i (const ACE_Synch_Options& sync_opt);
+
+ virtual void close_i ();
+
+ virtual std::iostream& sock_stream ();
+
+ private:
+ typedef ACE::IOS::SSLSock_IOStreamBase<ACE_SYNCH_USE> sock_stream_type;
+
+ connection_type* connection_;
+ sock_stream_type* sock_stream_;
+ Context& context_;
+ };
+
+ typedef Session_T<ACE_NULL_SYNCH> Session;
+ }
+ }
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
+#include "ace/INet/HTTPS_Session.cpp"
+#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
+
+#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
+#pragma implementation ("HTTPS_Session.cpp")
+#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
+
+#include /**/ "ace/post.h"
+#endif /* ACE_HTTPS_SESSION_H */
diff --git a/ACE/protocols/ace/INet/HTTPS_SessionFactory.cpp b/ACE/protocols/ace/INet/HTTPS_SessionFactory.cpp
new file mode 100644
index 00000000000..787fc56c963
--- /dev/null
+++ b/ACE/protocols/ace/INet/HTTPS_SessionFactory.cpp
@@ -0,0 +1,77 @@
+// $Id$
+
+#include "ace/INet/HTTPS_SessionFactory.h"
+
+#include "ace/INet/INet_Log.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace ACE
+{
+ namespace HTTPS
+ {
+
+ SessionFactory_Impl::SessionHolder_Impl::SessionHolder_Impl ()
+ : session_ (true)
+ {
+ }
+
+ SessionFactory_Impl::SessionHolder_Impl::~SessionHolder_Impl()
+ {
+ }
+
+ ACE::HTTP::SessionBase& SessionFactory_Impl::SessionHolder_Impl::session ()
+ {
+ return this->session_;
+ }
+
+ SessionFactory_Impl& SessionFactory_Impl::factory_ =
+ *ACE_Singleton<SessionFactory_Impl,ACE_SYNCH::NULL_MUTEX>::instance ();
+
+ SessionFactory_Impl::SessionFactory_Impl ()
+ {
+ INET_DEBUG (6, (LM_INFO, DLINFO
+ ACE_TEXT ("HTTPS_SessionFactory_Impl::ctor - ")
+ ACE_TEXT ("registering session factory for scheme [%C]\n"),
+ URL::protocol ().c_str ()));
+ ACE::HTTP::SessionFactoryRegistry::instance ().register_session_factory (URL::protocol (), this);
+ }
+
+ SessionFactory_Impl::~SessionFactory_Impl ()
+ {
+ }
+
+ ACE::INet::ConnectionHolder*
+ SessionFactory_Impl::create_connection (
+ const ACE::INet::ConnectionKey& key) const
+ {
+ INET_TRACE ("HTTPS_SessionFactory_Impl::create_connection");
+
+ const ACE::HTTP::ClientRequestHandler::HttpConnectionKey& ikey =
+ dynamic_cast<const ACE::HTTP::ClientRequestHandler::HttpConnectionKey&> (key);
+
+ SessionHolder_Impl* session_holder = 0;
+ ACE_NEW_RETURN (session_holder,
+ SessionHolder_Impl (),
+ 0);
+ ACE_Auto_Ptr<SessionHolder_Impl> session_safe_ref (session_holder);
+
+ (*session_holder)->set_host (ikey.host (), ikey.port ());
+ if (ikey.is_proxy_connection ())
+ {
+ (*session_holder)->set_proxy_target (ikey.proxy_target_host (),
+ ikey.proxy_target_port ());
+ }
+
+ if ((*session_holder)->connect (true))
+ {
+ return session_safe_ref.release ();
+ }
+
+ return 0;
+ }
+
+ }
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/protocols/ace/INet/HTTPS_SessionFactory.h b/ACE/protocols/ace/INet/HTTPS_SessionFactory.h
new file mode 100644
index 00000000000..41dd3da5282
--- /dev/null
+++ b/ACE/protocols/ace/INet/HTTPS_SessionFactory.h
@@ -0,0 +1,70 @@
+// $Id$
+
+/**
+ * @file HTTPS_SessionFactory.h
+ *
+ * @author Martin Corino <mcorino@remedy.nl>
+ */
+
+#ifndef ACE_HTTPS_SESSION_FACTORY_H
+#define ACE_HTTPS_SESSION_FACTORY_H
+
+#include /**/ "ace/pre.h"
+
+#include /**/ "ace/config-all.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/INet/HTTP_ClientRequestHandler.h"
+#include "ace/INet/HTTPS_Session.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace ACE
+ {
+ namespace HTTPS
+ {
+ /**
+ * @class ACE_HTTPS_SessionFactory_Impl
+ *
+ * @brief Implements HTTPS session factory.
+ *
+ */
+ class ACE_INET_Export SessionFactory_Impl
+ : public ACE::HTTP::SessionFactory
+ {
+ private:
+ SessionFactory_Impl ();
+ virtual ~SessionFactory_Impl ();
+
+ friend class ACE_Singleton<SessionFactory_Impl, ACE_SYNCH::NULL_MUTEX>;
+
+ static SessionFactory_Impl& factory_;
+
+ class SessionHolder_Impl : public ACE::HTTP::SessionHolder
+ {
+ public:
+ SessionHolder_Impl ();
+ virtual ~SessionHolder_Impl();
+
+ protected:
+ virtual ACE::HTTP::SessionBase& session ();
+
+ private:
+ Session_T<ACE_SYNCH> session_;
+ };
+
+ public:
+ virtual ACE::INet::ConnectionHolder* create_connection (
+ const ACE::INet::ConnectionKey& key) const;
+ };
+
+ }
+ }
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+#endif /* ACE_HTTPS_SESSION_FACTORY_H */
diff --git a/ACE/protocols/ace/INet/HTTPS_URL.cpp b/ACE/protocols/ace/INet/HTTPS_URL.cpp
new file mode 100644
index 00000000000..0e0b0e35071
--- /dev/null
+++ b/ACE/protocols/ace/INet/HTTPS_URL.cpp
@@ -0,0 +1,109 @@
+// $Id$
+
+#include "ace/INet/HTTPS_URL.h"
+
+#if !defined (__ACE_INLINE__)
+#include "ace/INet/HTTPS_URL.inl"
+#endif
+
+#include "ace/INet/String_IOStream.h"
+#include "ace/INet/HTTP_ClientRequestHandler.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace ACE
+{
+ namespace HTTPS
+ {
+ const char* URL::PROTOCOL = "https";
+
+ const ACE_CString& URL::protocol ()
+ {
+ static const ACE_CString protocol_ (PROTOCOL);
+ return protocol_;
+ }
+
+ URL::URL ()
+ : ACE::HTTP::URL (HTTPS_PORT)
+ {
+ }
+
+ URL::URL (const ACE_CString& url_string)
+ : ACE::HTTP::URL (HTTPS_PORT)
+ {
+ this->parse (url_string);
+ }
+
+ URL::URL (const URL& url)
+ : ACE::HTTP::URL (0)
+ {
+ *this = url;
+ }
+
+ URL::~URL ()
+ {
+ }
+
+ URL& URL::operator =(const URL& url)
+ {
+ ACE::HTTP::URL::operator=(url);
+ return *this;
+ }
+
+ ACE_CString URL::get_request_uri () const
+ {
+ ACE::IOS::CString_OStream sos;
+#if 0
+ if (!this->proxy_host_.empty ())
+ {
+ sos << this->get_scheme ().c_str () << "://"
+ << ACE::INet::URL_INetBase::get_host ().c_str ();
+ if (ACE::INet::URL_INetBase::get_port () != HTTP_PORT)
+ {
+ sos << ':' << ACE::INet::URL_INetBase::get_port ();
+ }
+ }
+#endif
+ // if path is empty we're requesting the root
+ sos << (this->get_path ().empty () ?
+ "/" :
+ this->get_path ().c_str ());
+ if (!this->get_query ().empty ())
+ sos << '?' << this->get_query ().c_str ();
+ if (!this->get_fragment ().empty ())
+ sos << '#' << this->get_fragment ().c_str ();
+ return sos.str ();
+ }
+
+ ACE::INet::ClientRequestHandler* URL::create_default_request_handler () const
+ {
+ ACE::INet::ClientRequestHandler* prh = 0;
+ ACE_NEW_NORETURN (prh, ACE::HTTP::ClientRequestHandler ());
+ return prh;
+ }
+
+ const URL::Factory& URL::factory_ = *URL::TURLFactorySingleton::instance ();
+
+ URL::Factory::Factory ()
+ {
+ ACE::INet::URL_Base::register_factory (this);
+ }
+
+ URL::Factory::~Factory ()
+ {}
+
+ const ACE_CString& URL::Factory::protocol ()
+ {
+ return URL::protocol ();
+ }
+
+ ACE::INet::URL_Base* URL::Factory::create_from_string (const ACE_CString& url_string)
+ {
+ URL* purl = 0;
+ ACE_NEW_NORETURN (purl, URL (url_string));
+ return purl;
+ }
+ }
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/protocols/ace/INet/HTTPS_URL.h b/ACE/protocols/ace/INet/HTTPS_URL.h
new file mode 100644
index 00000000000..b4ab3a53bd4
--- /dev/null
+++ b/ACE/protocols/ace/INet/HTTPS_URL.h
@@ -0,0 +1,89 @@
+// $Id$
+
+/**
+ * @file HTTPS_URL.h
+ *
+ * @author Martin Corino <mcorino@remedy.nl>
+ */
+
+#ifndef ACE_HTTPS_URL_H
+#define ACE_HTTPS_URL_H
+
+#include /**/ "ace/pre.h"
+
+#include /**/ "ace/config-all.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/INet/INet_Export.h"
+#include "ace/INet/HTTP_URL.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace ACE
+ {
+ namespace HTTPS
+ {
+ /**
+ * @class ACE_HTTPS_URL
+ *
+ * @brief Implements HTTPS url support.
+ *
+ */
+ class ACE_INET_Export URL
+ : public ACE::HTTP::URL
+ {
+ public:
+ URL ();
+ URL (const ACE_CString& url_string);
+ URL (const URL& url);
+ virtual ~URL ();
+
+ URL& operator =(const URL& url);
+
+ virtual const ACE_CString& get_scheme () const;
+
+ virtual ACE_CString get_request_uri () const;
+
+ virtual u_short default_port () const;
+
+ static const char* PROTOCOL;
+
+ static const ACE_CString& protocol ();
+
+ enum
+ {
+ HTTPS_PORT = 443,
+ };
+
+ protected:
+ virtual ACE::INet::ClientRequestHandler* create_default_request_handler () const;
+
+ private:
+ class Factory
+ : public ACE::INet::URL_Base::Factory
+ {
+ public:
+ Factory ();
+ virtual ~Factory ();
+ virtual const ACE_CString& protocol ();
+ virtual ACE::INet::URL_Base* create_from_string (const ACE_CString& url_string);
+ };
+
+ typedef ACE_Singleton<Factory,
+ ACE_Null_Mutex> TURLFactorySingleton;
+ static const Factory& factory_;
+ };
+ }
+ }
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#if defined (__ACE_INLINE__)
+#include "ace/INet/HTTPS_URL.inl"
+#endif
+
+#include /**/ "ace/post.h"
+#endif /* ACE_HTTPS_URL_H */
diff --git a/ACE/protocols/ace/INet/HTTPS_URL.inl b/ACE/protocols/ace/INet/HTTPS_URL.inl
new file mode 100644
index 00000000000..4502825a57c
--- /dev/null
+++ b/ACE/protocols/ace/INet/HTTPS_URL.inl
@@ -0,0 +1,27 @@
+// -*- C++ -*-
+//
+// $Id$
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace ACE
+{
+ namespace HTTPS
+ {
+
+ ACE_INLINE
+ const ACE_CString& URL::get_scheme () const
+ {
+ return protocol ();
+ }
+
+ ACE_INLINE
+ u_short URL::default_port () const
+ {
+ return HTTPS_PORT;
+ }
+
+ }
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/protocols/ace/INet/HTTP_ClientRequestHandler.cpp b/ACE/protocols/ace/INet/HTTP_ClientRequestHandler.cpp
index ab2014e36cc..ade87052b37 100644
--- a/ACE/protocols/ace/INet/HTTP_ClientRequestHandler.cpp
+++ b/ACE/protocols/ace/INet/HTTP_ClientRequestHandler.cpp
@@ -6,9 +6,9 @@
#include "ace/INet/HTTP_ClientRequestHandler.inl"
#endif
+#include "ace/INet/INet_Log.h"
#include "ace/Auto_Ptr.h"
-
-ACE_RCSID(NET_CLIENT,ACE_HTTP_ClientRequestHandler,"$Id$")
+#include "ace/Functor_String.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
@@ -17,38 +17,96 @@ namespace ACE
namespace HTTP
{
- ClientRequestHandler::SessionHolder::SessionHolder ()
+ SessionFactoryRegistry::SessionFactoryRegistry ()
+ {
+ }
+
+ SessionFactoryRegistry::~SessionFactoryRegistry ()
+ {
+ }
+
+ void SessionFactoryRegistry::register_session_factory (
+ const ACE_CString& scheme,
+ SessionFactory* factory)
+ {
+ if (factory == 0)
+ this->factory_map_.unbind (scheme);
+ else
+ this->factory_map_.rebind (scheme, factory);
+ }
+
+ SessionFactory*
+ SessionFactoryRegistry::find_session_factory (const ACE_CString& scheme)
+ {
+ SessionFactory* factory = 0;
+ this->factory_map_.find (scheme, factory);
+ return factory;
+ }
+
+ SessionFactoryRegistry& SessionFactoryRegistry::instance ()
+ {
+ return *ACE_Singleton<SessionFactoryRegistry, ACE_SYNCH::MUTEX>::instance ();
+ }
+
+ SessionHolder::SessionHolder ()
+ {
+ }
+
+ SessionHolder::~SessionHolder()
+ {
+ }
+
+ SessionFactory_Impl::SessionHolder_Impl::SessionHolder_Impl ()
: session_ (true)
{
}
- ClientRequestHandler::SessionHolder::~SessionHolder()
+ SessionFactory_Impl::SessionHolder_Impl::~SessionHolder_Impl()
{
}
- ClientRequestHandler::SessionFactory::SessionFactory ()
+ SessionBase& SessionFactory_Impl::SessionHolder_Impl::session ()
+ {
+ return this->session_;
+ }
+
+ SessionFactory_Impl& SessionFactory_Impl::factory_ =
+ *ACE_Singleton<SessionFactory_Impl,ACE_SYNCH::NULL_MUTEX>::instance ();
+
+ SessionFactory_Impl::SessionFactory_Impl ()
{
+ INET_DEBUG (6, (LM_INFO, DLINFO
+ ACE_TEXT ("HTTP_SessionFactory_Impl::ctor - ")
+ ACE_TEXT ("registering session factory for scheme [%C]\n"),
+ URL::protocol ().c_str ()));
+ SessionFactoryRegistry::instance ().register_session_factory (URL::protocol (), this);
}
- ClientRequestHandler::SessionFactory::~SessionFactory ()
+ SessionFactory_Impl::~SessionFactory_Impl ()
{
}
ACE::INet::ConnectionHolder*
- ClientRequestHandler::SessionFactory::create_connection (
+ SessionFactory_Impl::create_connection (
const ACE::INet::ConnectionKey& key) const
{
- INET_TRACE ("ClientRequestHandler::SessionFactory::create_connection");
+ INET_TRACE ("HTTP_SessionFactory_Impl::create_connection");
- const INetConnectionKey& ikey = dynamic_cast<const INetConnectionKey&> (key);
+ const ClientRequestHandler::HttpConnectionKey& ikey =
+ dynamic_cast<const ClientRequestHandler::HttpConnectionKey&> (key);
- SessionHolder* session_holder = 0;
+ SessionHolder_Impl* session_holder = 0;
ACE_NEW_RETURN (session_holder,
- SessionHolder (),
+ SessionHolder_Impl (),
0);
- ACE_Auto_Ptr<SessionHolder> session_safe_ref (session_holder);
+ ACE_Auto_Ptr<SessionHolder_Impl> session_safe_ref (session_holder);
(*session_holder)->set_host (ikey.host (), ikey.port ());
+ if (ikey.is_proxy_connection ())
+ {
+ (*session_holder)->set_proxy_target (ikey.proxy_target_host (),
+ ikey.proxy_target_port ());
+ }
if ((*session_holder)->connect (true))
{
@@ -58,6 +116,77 @@ namespace ACE
return 0;
}
+ ClientRequestHandler::HttpConnectionKey::HttpConnectionKey (
+ const ACE_CString& host,
+ u_short port)
+ : INetConnectionKey (host, port),
+ proxy_connection_ (false),
+ proxy_target_port_ (0)
+ {
+ }
+
+ ClientRequestHandler::HttpConnectionKey::HttpConnectionKey (
+ const ACE_CString& proxy_host,
+ u_short proxy_port,
+ const ACE_CString& host,
+ u_short port)
+ : INetConnectionKey (proxy_host, proxy_port),
+ proxy_connection_ (true),
+ proxy_target_host_ (host),
+ proxy_target_port_ (port)
+ {
+ }
+
+ ClientRequestHandler::HttpConnectionKey::~HttpConnectionKey()
+ {
+ }
+
+ u_long ClientRequestHandler::HttpConnectionKey::hash () const
+ {
+ if (this->proxy_connection_)
+ return ACE_Hash<ACE_CString>()(this->proxy_target_host_) +
+ this->proxy_target_port_ +
+ (this->proxy_connection_ ? 1 : 0);
+ else
+ return INetConnectionKey::hash () +
+ (this->proxy_connection_ ? 1 : 0);
+ }
+
+ ACE::INet::ConnectionKey* ClientRequestHandler::HttpConnectionKey::duplicate () const
+ {
+ ConnectionKey* k = 0;
+ if (this->proxy_connection_)
+ {
+ ACE_NEW_RETURN (k,
+ HttpConnectionKey (this->host (), this->port (),
+ this->proxy_target_host_,
+ this->proxy_target_port_),
+ 0);
+ }
+ else
+ {
+ ACE_NEW_RETURN (k,
+ HttpConnectionKey (this->host (), this->port ()),
+ 0);
+ }
+ return k;
+ }
+
+ bool ClientRequestHandler::HttpConnectionKey::equal (const ACE::INet::ConnectionKey& key) const
+ {
+ try {
+ const HttpConnectionKey& http_key = dynamic_cast<const HttpConnectionKey&> (key);
+ return (INetConnectionKey::equal (key) &&
+ this->proxy_connection_ == http_key.is_proxy_connection () &&
+ (!this->proxy_connection_ ||
+ (this->proxy_target_host_ == http_key.proxy_target_host () &&
+ this->proxy_target_port_ == http_key.proxy_target_port ())));
+ }
+ catch (...) {
+ return false;
+ }
+ }
+
ClientRequestHandler::ClientRequestHandler ()
: request_ (Request::HTTP_1_0),
session_ (0)
@@ -85,12 +214,20 @@ namespace ACE
std::istream& ClientRequestHandler::handle_get_request (
const URL& http_url)
{
- if (this->initialize_connection (http_url.has_proxy () ?
- http_url.get_proxy_host () :
- http_url.get_host (),
- http_url.has_proxy () ?
- http_url.get_proxy_port () :
- http_url.get_port ()))
+ bool connected = false;
+ if (http_url.has_proxy ())
+ connected = this->initialize_connection (http_url.get_scheme (),
+ http_url.get_host(),
+ http_url.get_port (),
+ true,
+ http_url.get_proxy_host(),
+ http_url.get_proxy_port ());
+ else
+ connected = this->initialize_connection (http_url.get_scheme (),
+ http_url.get_host(),
+ http_url.get_port ());
+
+ if (connected)
{
this->request_.reset (Request::HTTP_GET,
http_url.get_request_uri (),
@@ -121,21 +258,47 @@ namespace ACE
this->release_connection ();
}
- bool ClientRequestHandler::initialize_connection (const ACE_CString& host,
- u_short port)
+ bool ClientRequestHandler::initialize_connection (const ACE_CString& scheme,
+ const ACE_CString& host,
+ u_short port,
+ bool proxy_conn,
+ const ACE_CString& proxy_host,
+ u_short proxy_port)
{
- static const SessionFactory session_factory;
+ SessionFactory* session_factory =
+ SessionFactoryRegistry::instance ().find_session_factory (scheme);
+
+ if (session_factory == 0)
+ {
+ INET_ERROR (1, (LM_ERROR, DLINFO
+ ACE_TEXT ("ClientRequestHandler::initialize_connection - ")
+ ACE_TEXT ("unable to find session factory for scheme [%C]\n"),
+ scheme.c_str ()));
+ return false;
+ }
ACE::INet::ConnectionHolder* pch = 0;
- if (this->connection_cache ().claim_connection (INetConnectionKey (host, port),
- pch,
- session_factory))
+ if (proxy_conn)
{
- this->session (dynamic_cast<SessionHolder*> (pch));
- return true;
+ if (!this->connection_cache ().claim_connection (HttpConnectionKey (proxy_host,
+ proxy_port,
+ host,
+ port),
+ pch,
+ *session_factory))
+ return false;
}
else
- return false;
+ {
+ if (!this->connection_cache ().claim_connection (HttpConnectionKey (host,
+ port),
+ pch,
+ *session_factory))
+ return false;
+ }
+
+ this->session (dynamic_cast<SessionHolder*> (pch));
+ return true;
}
void ClientRequestHandler::initialize_request (const URL& /*url*/, Request& /*request*/)
@@ -154,10 +317,22 @@ namespace ACE
{
if (this->session_)
{
- this->connection_cache ().release_connection (
- INetConnectionKey (this->session ()->get_host (),
- this->session ()->get_port ()),
- this->session_);
+ if (this->session ()->is_proxy_connection ())
+ {
+ this->connection_cache ().release_connection (
+ HttpConnectionKey (this->session ()->get_host (),
+ this->session ()->get_port (),
+ this->session ()->get_proxy_target_host (),
+ this->session ()->get_proxy_target_port ()),
+ this->session_);
+ }
+ else
+ {
+ this->connection_cache ().release_connection (
+ HttpConnectionKey (this->session ()->get_host (),
+ this->session ()->get_port ()),
+ this->session_);
+ }
this->session_ = 0;
}
}
@@ -166,10 +341,22 @@ namespace ACE
{
if (this->session_)
{
- this->connection_cache ().close_connection (
- INetConnectionKey (this->session ()->get_host (),
- this->session ()->get_port ()),
- this->session_);
+ if (this->session ()->is_proxy_connection ())
+ {
+ this->connection_cache ().release_connection (
+ HttpConnectionKey (this->session ()->get_host (),
+ this->session ()->get_port (),
+ this->session ()->get_proxy_target_host (),
+ this->session ()->get_proxy_target_port ()),
+ this->session_);
+ }
+ else
+ {
+ this->connection_cache ().release_connection (
+ HttpConnectionKey (this->session ()->get_host (),
+ this->session ()->get_port ()),
+ this->session_);
+ }
this->session_ = 0;
}
}
diff --git a/ACE/protocols/ace/INet/HTTP_ClientRequestHandler.h b/ACE/protocols/ace/INet/HTTP_ClientRequestHandler.h
index 9e987bc03ba..9cade87bf0e 100644
--- a/ACE/protocols/ace/INet/HTTP_ClientRequestHandler.h
+++ b/ACE/protocols/ace/INet/HTTP_ClientRequestHandler.h
@@ -18,6 +18,7 @@
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/Synch_Traits.h"
+#include "ace/Singleton.h"
#include "ace/Thread_Mutex.h"
#include "ace/INet/INet_Export.h"
#include "ace/INet/IOS_util.h"
@@ -25,8 +26,8 @@
#include "ace/INet/ClientRequestHandler.h"
#include "ace/INet/HTTP_Request.h"
#include "ace/INet/HTTP_Response.h"
-#include "ace/INet/HTTP_Session.h"
#include "ace/INet/HTTP_URL.h"
+#include "ace/INet/HTTP_Session.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
@@ -35,10 +36,110 @@ namespace ACE
namespace HTTP
{
/**
+ * @class ACE_HTTP_SessionHolder
+ *
+ * @brief Abstract base class for HTTP session objects.
+ *
+ */
+ class ACE_INET_Export SessionHolder
+ : public ACE::INet::ConnectionHolder
+ {
+ protected:
+ SessionHolder ();
+ virtual ~SessionHolder();
+
+ virtual SessionBase& session () = 0;
+
+ public:
+ SessionBase& operator *();
+ SessionBase* operator ->();
+ };
+
+ /**
+ * @class ACE_HTTP_SessionFactory
+ *
+ * @brief Abstract base class for HTTP session factories.
+ *
+ */
+ class ACE_INET_Export SessionFactory
+ : public ACE::INet::ConnectionFactory
+ {
+ protected:
+ SessionFactory () {}
+ virtual ~SessionFactory () {}
+ };
+
+ /**
+ * @class ACE_HTTP_SessionFactory_Impl
+ *
+ * @brief Implementation of HTTP session factory.
+ *
+ */
+ class ACE_INET_Export SessionFactory_Impl
+ : public SessionFactory
+ {
+ private:
+ SessionFactory_Impl ();
+ virtual ~SessionFactory_Impl ();
+
+ friend class ACE_Singleton<SessionFactory_Impl, ACE_SYNCH::NULL_MUTEX>;
+
+ static SessionFactory_Impl& factory_;
+
+ class SessionHolder_Impl : public SessionHolder
+ {
+ public:
+ SessionHolder_Impl ();
+ virtual ~SessionHolder_Impl();
+
+ protected:
+ virtual SessionBase& session ();
+
+ private:
+ Session_T<ACE_SYNCH> session_;
+ };
+
+ public:
+ virtual ACE::INet::ConnectionHolder* create_connection (
+ const ACE::INet::ConnectionKey& key) const;
+ };
+
+ /**
+ * @class ACE_HTTP_SessionFactoryRegistry
+ *
+ * @brief Implements registry of HTTP session factories.
+ *
+ */
+ class ACE_INET_Export SessionFactoryRegistry
+ {
+ private:
+ SessionFactoryRegistry ();
+ ~SessionFactoryRegistry ();
+
+ friend class ACE_Singleton<SessionFactoryRegistry, ACE_SYNCH::MUTEX>;
+
+ public:
+
+ void register_session_factory (const ACE_CString& scheme,
+ SessionFactory* factory);
+
+ SessionFactory* find_session_factory (const ACE_CString& scheme);
+
+ static SessionFactoryRegistry& instance ();
+
+ private:
+ typedef ACE_Map_Manager<ACE_CString,
+ SessionFactory*,
+ ACE_SYNCH::MUTEX> TSessionFactoryMap;
+
+ TSessionFactoryMap factory_map_;
+ };
+
+ /**
* @class ACE_HTTP_ClientRequestHandler
*
* @brief This class implements clientside request handling
- * for HTTP URLs.
+ * for HTTP(S) URLs.
*
* The class supports the HTTP protocol as specified in RFC 2616.
*/
@@ -74,42 +175,51 @@ namespace ACE
virtual std::istream& handle_put_request (const URL& url,
std::istream* put_data = 0);
*/
- protected:
- virtual void on_eof ();
- class SessionHolder
- : public ACE::INet::ConnectionHolder
+ class HttpConnectionKey
+ : public INetConnectionKey
{
public:
- typedef Session_T<ACE_SYNCH> session_type;
+ HttpConnectionKey (const ACE_CString& host,
+ u_short port);
+ HttpConnectionKey (const ACE_CString& proxy_host,
+ u_short proxy_port,
+ const ACE_CString& target_host,
+ u_short target_port);
+ virtual ~HttpConnectionKey();
- SessionHolder ();
- virtual ~SessionHolder();
+ virtual u_long hash () const;
- session_type& operator *();
- session_type* operator ->();
+ virtual ConnectionKey* duplicate () const;
- private:
- session_type session_;
- };
+ bool is_proxy_connection () const;
- class SessionFactory
- : public ACE::INet::ConnectionFactory
- {
- public:
- SessionFactory ();
- virtual ~SessionFactory ();
+ const ACE_CString& proxy_target_host () const;
+
+ u_short proxy_target_port () const;
+
+ protected:
+ virtual bool equal (const ConnectionKey& key) const;
- virtual ACE::INet::ConnectionHolder* create_connection (
- const ACE::INet::ConnectionKey& key) const;
+ private:
+ bool proxy_connection_;
+ ACE_CString proxy_target_host_;
+ u_short proxy_target_port_;
};
+ protected:
+ virtual void on_eof ();
+
SessionHolder& session ();
void session (SessionHolder* session);
- virtual bool initialize_connection (const ACE_CString& host,
- u_short port);
+ virtual bool initialize_connection (const ACE_CString& scheme,
+ const ACE_CString& host,
+ u_short port,
+ bool proxy_conn = false,
+ const ACE_CString& proxy_host = Request::EMPTY,
+ u_short proxy_port = 0);
virtual void initialize_request (const URL& url, Request& request);
diff --git a/ACE/protocols/ace/INet/HTTP_ClientRequestHandler.inl b/ACE/protocols/ace/INet/HTTP_ClientRequestHandler.inl
index 1540651f7af..3e023ecd6e7 100644
--- a/ACE/protocols/ace/INet/HTTP_ClientRequestHandler.inl
+++ b/ACE/protocols/ace/INet/HTTP_ClientRequestHandler.inl
@@ -9,15 +9,33 @@ namespace ACE
namespace HTTP
{
ACE_INLINE
- ClientRequestHandler::SessionHolder::session_type& ClientRequestHandler::SessionHolder::operator *()
+ SessionBase& SessionHolder::operator *()
{
- return this->session_;
+ return this->session ();
}
ACE_INLINE
- ClientRequestHandler::SessionHolder::session_type* ClientRequestHandler::SessionHolder::operator -> ()
+ SessionBase* SessionHolder::operator -> ()
{
- return &this->session_;
+ return &this->session ();
+ }
+
+ ACE_INLINE
+ bool ClientRequestHandler::HttpConnectionKey::is_proxy_connection () const
+ {
+ return this->proxy_connection_;
+ }
+
+ ACE_INLINE
+ const ACE_CString& ClientRequestHandler::HttpConnectionKey::proxy_target_host () const
+ {
+ return this->proxy_target_host_;
+ }
+
+ ACE_INLINE
+ u_short ClientRequestHandler::HttpConnectionKey::proxy_target_port () const
+ {
+ return this->proxy_target_port_;
}
ACE_INLINE
@@ -45,7 +63,7 @@ namespace ACE
}
ACE_INLINE
- ClientRequestHandler::SessionHolder& ClientRequestHandler::session ()
+ SessionHolder& ClientRequestHandler::session ()
{
return *this->session_;
}
diff --git a/ACE/protocols/ace/INet/HTTP_Session.cpp b/ACE/protocols/ace/INet/HTTP_Session.cpp
index 10d1df95ff6..a0e37795799 100644
--- a/ACE/protocols/ace/INet/HTTP_Session.cpp
+++ b/ACE/protocols/ace/INet/HTTP_Session.cpp
@@ -3,11 +3,10 @@
#ifndef ACE_HTTP_SESSION_CPP
#define ACE_HTTP_SESSION_CPP
-#include "ace/INet/INet_Log.h"
#include "ace/INet/HTTP_Session.h"
-#include "ace/INet/HTTP_StreamPolicy.h"
-#include "ace/INet/String_IOStream.h"
+#include "ace/INet/INet_Log.h"
#include "ace/INet/IOS_util.h"
+#include "ace/INet/HTTP_URL.h"
#include "ace/INET_Addr.h"
#include "ace/Event_Handler.h"
#include "ace/Connector.h"
@@ -24,20 +23,9 @@ namespace ACE
template <ACE_SYNCH_DECL>
Session_T<ACE_SYNCH_USE>::Session_T (bool keep_alive)
- : port_ (HTTP_PORT),
- reactive_ (false),
+ : SessionBase (URL::HTTP_PORT, keep_alive),
connection_ (0),
- sock_stream_ (0),
- in_stream_ (0),
- out_stream_ (0),
- http_timeout_ (DEFAULT_TIMEOUT),
- keep_alive_timeout_ (DEFAULT_KEEP_ALIVE_TIMEOUT),
- reconnect_timer_ (DEFAULT_KEEP_ALIVE_TIMEOUT),
- reconnect_countdown_ (&reconnect_timer_),
- keep_alive_ (keep_alive),
- needs_reconnect_ (false),
- cannot_reconnect_ (false),
- expects_response_body_ (false)
+ sock_stream_ (0)
{
INET_TRACE ("ACE_HTTP_Session - ctor");
}
@@ -46,45 +34,19 @@ namespace ACE
Session_T<ACE_SYNCH_USE>::Session_T (const ACE_Time_Value& timeout,
bool keep_alive,
const ACE_Time_Value* alive_timeout)
- : port_ (HTTP_PORT),
- reactive_ (false),
+ : SessionBase (URL::HTTP_PORT, timeout, keep_alive, alive_timeout),
connection_ (0),
- sock_stream_ (0),
- in_stream_ (0),
- out_stream_ (0),
- http_timeout_ (timeout),
- keep_alive_timeout_ (DEFAULT_KEEP_ALIVE_TIMEOUT),
- reconnect_timer_ (DEFAULT_KEEP_ALIVE_TIMEOUT),
- reconnect_countdown_ (&reconnect_timer_),
- keep_alive_ (keep_alive),
- needs_reconnect_ (false),
- cannot_reconnect_ (false),
- expects_response_body_ (false)
+ sock_stream_ (0)
{
INET_TRACE ("ACE_HTTP_Session - ctor");
- if (keep_alive && alive_timeout)
- {
- this->keep_alive_timeout_ = *alive_timeout;
- }
}
template <ACE_SYNCH_DECL>
Session_T<ACE_SYNCH_USE>::~Session_T ()
{
INET_TRACE ("ACE_HTTP_Session - dtor");
- this->close ();
- }
-
- template <ACE_SYNCH_DECL>
- void Session_T<ACE_SYNCH_USE>::set_keep_alive (bool f)
- {
- this->keep_alive_ = f;
- }
-
- template <ACE_SYNCH_DECL>
- bool Session_T<ACE_SYNCH_USE>::keep_alive () const
- {
- return this->keep_alive_;
+ this->close_streams ();
+ this->close_connection ();
}
template <ACE_SYNCH_DECL>
@@ -94,57 +56,12 @@ namespace ACE
}
template <ACE_SYNCH_DECL>
- void Session_T<ACE_SYNCH_USE>::set_host (const ACE_CString& host, u_short port)
- {
- if (!this->is_connected ())
- {
- this->host_ = host;
- this->port_ = port;
- }
- }
-
- template <ACE_SYNCH_DECL>
- void Session_T<ACE_SYNCH_USE>::set_host (const ACE_CString& host)
- {
- if (!this->is_connected ())
- {
- this->host_ = host;
- }
- }
-
- template <ACE_SYNCH_DECL>
- void Session_T<ACE_SYNCH_USE>::set_port (u_short port)
- {
- if (!this->is_connected ())
- {
- this->port_ = port;
- }
- }
-
- template <ACE_SYNCH_DECL>
- const ACE_CString& Session_T<ACE_SYNCH_USE>::get_host () const
+ bool Session_T<ACE_SYNCH_USE>::connect_i (const ACE_Synch_Options& sync_opt)
{
- return this->host_;
- }
-
- template <ACE_SYNCH_DECL>
- u_short Session_T<ACE_SYNCH_USE>::get_port () const
- {
- return this->port_;
- }
-
- template <ACE_SYNCH_DECL>
- bool Session_T<ACE_SYNCH_USE>::connect (bool use_reactor)
- {
- INET_TRACE ("ACE_HTTP_Session::connect");
+ INET_TRACE ("ACE_HTTP_Session::connect_i");
typedef ACE_Connector<connection_type, ACE_SOCK_CONNECTOR> connector_type;
- this->close ();
-
- unsigned long f_reactor = use_reactor ? ACE_Synch_Options::USE_REACTOR : 0;
- ACE_Synch_Options sync_opt (ACE_Synch_Options::USE_TIMEOUT | f_reactor,
- this->http_timeout_);
connector_type connector;
connection_type* new_connection = 0;
@@ -157,8 +74,8 @@ namespace ACE
ACE_Synch_Options (0,this->http_timeout_)) == -1)
{
INET_ERROR (1, (LM_ERROR, DLINFO
- ACE_TEXT ("(%d) ACE_HTTP_Session::connect - ")
- ACE_TEXT ("failed to connect; host=%C, port=%d"),
+ ACE_TEXT ("(%d) ACE_HTTP_Session::connect_i - ")
+ ACE_TEXT ("failed to connect; host=%C, port=%d\n"),
ACE_OS::last_error (), this->host_.c_str (), this->port_));
// as the connection was dynamically allocated
// the connector causes it to be destroyed after
@@ -175,7 +92,7 @@ namespace ACE
if (this->sock_stream_)
{
this->cannot_reconnect_ = false;
- this->reactive_ = use_reactor;
+ this->reactive_ = sync_opt[ACE_Synch_Options::USE_REACTOR];
// reset reconnect timer
this->reconnect_timer_ = this->keep_alive_timeout_;
@@ -191,35 +108,19 @@ namespace ACE
}
template <ACE_SYNCH_DECL>
- bool Session_T<ACE_SYNCH_USE>::connect (connection_type* connection)
+ bool Session_T<ACE_SYNCH_USE>::attach_connection (connection_type* connection)
{
- INET_TRACE ("ACE_HTTP_Session::connect(connection)");
+ INET_TRACE ("ACE_HTTP_Session::attach_connection");
- this->close ();
+ if (!connection->is_connected ())
+ return false;
- if (connection->is_connected ())
- {
- ACE_INET_Addr remote;
- connection->peer ().get_remote_addr (remote);
- this->host_ = remote.get_host_name ();
- this->port_ = remote.get_port_number ();
- }
- else
- {
- typedef ACE_Connector<connection_type, ACE_SOCK_CONNECTOR> connector_type;
+ this->close ();
- connector_type connector;
- if (connector.connect (connection,
- ACE_INET_Addr (this->host_.c_str (),
- this->port_)) == -1)
- {
- INET_ERROR (1, (LM_ERROR, DLINFO
- ACE_TEXT ("(%d) ACE_HTTP_Session::connect(connection) - ")
- ACE_TEXT ("failed to connect; host=%C, port=%d"),
- ACE_OS::last_error (), this->host_.c_str (), this->port_));
- return false;
- }
- }
+ ACE_INET_Addr remote;
+ connection->peer ().get_remote_addr (remote);
+ this->host_ = remote.get_host_name ();
+ this->port_ = remote.get_port_number ();
this->connection_ = connection;
this->connection_->add_reference ();
@@ -242,243 +143,16 @@ namespace ACE
}
template <ACE_SYNCH_DECL>
- std::ostream& Session_T<ACE_SYNCH_USE>::send_request (Request& request)
+ void Session_T<ACE_SYNCH_USE>::close_connection ()
{
- INET_TRACE ("ACE_HTTP_Session::send_request");
-
- if (this->in_stream_)
- {
- delete this->in_stream_;
- this->in_stream_ = 0;
- }
-
- bool keep_alive = this->keep_alive ();
- if ((this->is_connected () && !keep_alive) || this->reconnect_needed ())
- {
- close();
- this->needs_reconnect_ = false;
- }
-
- if (this->out_stream_)
- {
- delete this->out_stream_;
- this->out_stream_ = 0;
- }
-
- if (!this->is_connected ())
- {
- if (this->cannot_reconnect_ || !this->connect(this->reactive_))
- {
- if (!this->cannot_reconnect_)
- INET_ERROR (1, (LM_ERROR, DLINFO
- ACE_TEXT ("(%d) HTTP_Session::send_request - ")
- ACE_TEXT ("reconnect failed\n"),
- ACE_OS::last_error ()));
- return ACE::IOS::Null::out_stream_;
- }
- }
- if (!keep_alive)
- request.set_keep_alive (false);
- if (!request.has_host ())
- {
- if (this->port_ == HTTP_PORT)
- request.set_host (this->host_);
- else
- request.set_host (this->host_, this->port_);
- }
-
- this->expects_response_body_ = request.get_method() != Request::HTTP_HEAD;
-
- if (request.has_chunked_transfer_encoding ())
- {
- request.write (*this->sock_stream_);
- ChunkedTransferStreamPolicy* pol;
- ACE_NEW_RETURN (pol,
- ChunkedTransferStreamPolicy (),
- ACE::IOS::Null::out_stream_);
- ACE_NEW_RETURN (this->out_stream_,
- OStream (*this->sock_stream_, pol),
- ACE::IOS::Null::out_stream_);
- }
- else if (request.get_content_length () != Header::UNKNOWN_CONTENT_LENGTH)
- {
- ACE::IOS::CString_OStream cs;
- request.write (cs);
- FixedLengthStreamPolicy* pol;
- ACE_NEW_RETURN (pol,
- FixedLengthStreamPolicy (cs.str ().length () + request.get_content_length ()),
- ACE::IOS::Null::out_stream_);
- ACE_NEW_RETURN (this->out_stream_,
- OStream (*this->sock_stream_, pol),
- ACE::IOS::Null::out_stream_);
- (*this->out_stream_) << cs.str ().c_str ();
- }
- else if (request.get_method () != Request::HTTP_PUT && request.get_method() != Request::HTTP_POST)
- {
- ACE::IOS::CString_OStream cs;
- request.write (cs);
- FixedLengthStreamPolicy* pol;
- ACE_NEW_RETURN (pol,
- FixedLengthStreamPolicy (cs.str ().length ()),
- ACE::IOS::Null::out_stream_);
- ACE_NEW_RETURN (this->out_stream_,
- OStream (*this->sock_stream_, pol),
- ACE::IOS::Null::out_stream_);
- (*this->out_stream_) << cs.str ().c_str ();
- }
- else
- {
- ACE_NEW_RETURN (this->out_stream_,
- OStream (*this->sock_stream_),
- ACE::IOS::Null::out_stream_);
- request.write (*this->out_stream_);
- }
- // reset reconnect timer
- this->reconnect_timer_ = this->keep_alive_timeout_;
- this->reconnect_countdown_.start ();
-
- return *this->out_stream_;
- }
-
- template <ACE_SYNCH_DECL>
- std::ostream& Session_T<ACE_SYNCH_USE>::request_stream ()
- {
- return this->out_stream_ ? *this->out_stream_ : ACE::IOS::Null::out_stream_;
- }
-
- template <ACE_SYNCH_DECL>
- std::ostream& Session_T<ACE_SYNCH_USE>::request_stream (
- ACE::IOS::StreamInterceptor& interceptor)
- {
- if (this->out_stream_)
- {
- this->out_stream_->set_interceptor (interceptor);
- return *this->out_stream_;
- }
- else
- return ACE::IOS::Null::out_stream_;
- }
-
- template <ACE_SYNCH_DECL>
- std::istream& Session_T<ACE_SYNCH_USE>::receive_response (Response& response)
- {
- INET_TRACE ("ACE_HTTP_Session::receive_response");
-
- if (this->in_stream_)
- {
- INET_ERROR (1, (LM_ERROR, DLINFO
- ACE_TEXT ("HTTP_Session::receive_response - ")
- ACE_TEXT ("invalid invocation without send_request\n")));
- // receive_response called second time without
- // new send_request in between
- return ACE::IOS::Null::in_stream_;
- }
-
- if (this->out_stream_)
- {
- delete this->out_stream_;
- this->out_stream_ = 0;
- }
-
- this->sock_stream_->flush ();
-
- do
- {
- response.clear ();
- if (!response.read (*this->sock_stream_))
- {
- INET_ERROR (1, (LM_ERROR, DLINFO
- ACE_TEXT ("(%d) HTTP_Session::receive_response - ")
- ACE_TEXT ("failed to read response\n"),
- ACE_OS::last_error ()));
- return ACE::IOS::Null::in_stream_;
- }
- }
- while (response.get_status ().get_status() == Status::HTTP_CONTINUE);
-
- this->needs_reconnect_ = this->keep_alive () && !response.has_keep_alive ();
-
- if (!this->expects_response_body_)
- {
- FixedLengthStreamPolicy* pol;
- ACE_NEW_RETURN (pol,
- FixedLengthStreamPolicy (0),
- ACE::IOS::Null::in_stream_);
- ACE_NEW_RETURN (this->in_stream_,
- IStream (*this->sock_stream_, pol),
- ACE::IOS::Null::in_stream_);
- }
- else if (response.has_chunked_transfer_encoding ())
- {
- ChunkedTransferStreamPolicy* pol;
- ACE_NEW_RETURN (pol,
- ChunkedTransferStreamPolicy (),
- ACE::IOS::Null::in_stream_);
- ACE_NEW_RETURN (this->in_stream_,
- IStream (*this->sock_stream_, pol),
- ACE::IOS::Null::in_stream_);
- }
- else if (response.get_content_length () != Header::UNKNOWN_CONTENT_LENGTH)
- {
- FixedLengthStreamPolicy* pol;
- ACE_NEW_RETURN (pol,
- FixedLengthStreamPolicy (response.get_content_length ()),
- ACE::IOS::Null::in_stream_);
- ACE_NEW_RETURN (this->in_stream_,
- IStream (*this->sock_stream_, pol),
- ACE::IOS::Null::in_stream_);
- }
- else
- {
- ACE_NEW_RETURN (this->in_stream_,
- IStream (*this->sock_stream_),
- ACE::IOS::Null::in_stream_);
- }
-
- return *this->in_stream_;
- }
-
- template <ACE_SYNCH_DECL>
- std::istream& Session_T<ACE_SYNCH_USE>::response_stream ()
- {
- return this->in_stream_ ? *this->in_stream_ : ACE::IOS::Null::in_stream_;
- }
-
- template <ACE_SYNCH_DECL>
- std::istream& Session_T<ACE_SYNCH_USE>::response_stream (
- ACE::IOS::StreamInterceptor& interceptor)
- {
- if (this->in_stream_)
+ if (this->sock_stream_)
{
- this->in_stream_->set_interceptor (interceptor);
- return *this->in_stream_;
+ delete this->sock_stream_;
+ this->sock_stream_ = 0;
}
- else
- return ACE::IOS::Null::in_stream_;
- }
-
- template <ACE_SYNCH_DECL>
- void Session_T<ACE_SYNCH_USE>::close ()
- {
- INET_TRACE ("ACE_HTTP_Session::close");
if (this->connection_)
{
- if (this->in_stream_)
- {
- delete this->in_stream_;
- this->in_stream_ = 0;
- }
- if (this->out_stream_)
- {
- delete this->out_stream_;
- this->out_stream_ = 0;
- }
- if (this->sock_stream_)
- {
- delete this->sock_stream_;
- this->sock_stream_ = 0;
- }
// this should be the last referece and removing it
// causes the connection to be destroyed
this->connection_->remove_reference ();
@@ -487,16 +161,17 @@ namespace ACE
}
template <ACE_SYNCH_DECL>
- bool Session_T<ACE_SYNCH_USE>::reconnect_needed ()
+ void Session_T<ACE_SYNCH_USE>::close_i ()
{
- if (this->cannot_reconnect_)
- return false;
- if (!this->needs_reconnect_)
- {
- this->reconnect_countdown_.update ();
- return this->reconnect_timer_ == ACE_Time_Value::zero;
- }
- return true;
+ INET_TRACE ("ACE_HTTP_Session::close_i");
+
+ this->close_connection ();
+ }
+
+ template <ACE_SYNCH_DECL>
+ std::iostream& Session_T<ACE_SYNCH_USE>::sock_stream ()
+ {
+ return *this->sock_stream_;
}
}
diff --git a/ACE/protocols/ace/INet/HTTP_Session.h b/ACE/protocols/ace/INet/HTTP_Session.h
index 518b0402856..0eac1ba24ff 100644
--- a/ACE/protocols/ace/INet/HTTP_Session.h
+++ b/ACE/protocols/ace/INet/HTTP_Session.h
@@ -11,15 +11,10 @@
#include /**/ "ace/pre.h"
-#include "ace/SString.h"
-#include "ace/Countdown_Time.h"
+#include "ace/INet/HTTP_SessionBase.h"
#include "ace/SOCK_Connector.h"
-#include "ace/INet/INet_Export.h"
-#include "ace/INet/HTTP_Request.h"
-#include "ace/INet/HTTP_Response.h"
#include "ace/INet/StreamHandler.h"
#include "ace/INet/Sock_IOStream.h"
-#include "ace/INet/HTTP_IOStream.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
@@ -34,16 +29,11 @@ namespace ACE
*
*/
template <ACE_SYNCH_DECL>
- class Session_T
+ class Session_T : public SessionBase
{
public:
typedef ACE::IOS::StreamHandler<ACE_SOCK_STREAM, ACE_SYNCH_USE> connection_type;
- enum
- {
- HTTP_PORT = 80
- };
-
Session_T (bool keep_alive = false);
Session_T (const ACE_Time_Value& timeout,
@@ -52,69 +42,25 @@ namespace ACE
virtual ~Session_T ();
- void set_keep_alive (bool f);
-
- bool keep_alive () const;
-
- bool is_connected () const;
-
- void set_host (const ACE_CString& host, u_short port);
-
- void set_host (const ACE_CString& host);
-
- void set_port (u_short port);
-
- const ACE_CString& get_host () const;
-
- u_short get_port () const;
-
- bool connect (bool use_reactor = false);
+ virtual bool is_connected () const;
- bool connect (connection_type* connection);
+ bool attach_connection (connection_type* connection);
- std::ostream& send_request (Request& request);
-
- std::ostream& request_stream ();
-
- std::ostream& request_stream (ACE::IOS::StreamInterceptor& interceptor);
-
- std::istream& receive_response (Response& response);
-
- std::istream& response_stream ();
+ protected:
- std::istream& response_stream (ACE::IOS::StreamInterceptor& interceptor);
+ void close_connection ();
- void close ();
+ virtual bool connect_i (const ACE_Synch_Options& sync_opt);
- protected:
+ virtual void close_i ();
- bool reconnect_needed ();
+ virtual std::iostream& sock_stream ();
private:
- enum
- {
- DEFAULT_TIMEOUT = 30, // sec
- DEFAULT_KEEP_ALIVE_TIMEOUT = 8 // sec
- };
-
- ACE_CString host_;
- u_short port_;
-
typedef ACE::IOS::Sock_IOStreamBase<ACE_SYNCH_USE> sock_stream_type;
- bool reactive_;
connection_type* connection_;
sock_stream_type* sock_stream_;
- IStream* in_stream_;
- OStream* out_stream_;
- ACE_Time_Value http_timeout_;
- ACE_Time_Value keep_alive_timeout_;
- ACE_Time_Value reconnect_timer_;
- ACE_Countdown_Time reconnect_countdown_;
- bool keep_alive_;
- bool needs_reconnect_;
- bool cannot_reconnect_;
- bool expects_response_body_;
};
typedef Session_T<ACE_NULL_SYNCH> Session;
diff --git a/ACE/protocols/ace/INet/HTTP_SessionBase.cpp b/ACE/protocols/ace/INet/HTTP_SessionBase.cpp
new file mode 100644
index 00000000000..d16188d51a6
--- /dev/null
+++ b/ACE/protocols/ace/INet/HTTP_SessionBase.cpp
@@ -0,0 +1,308 @@
+// $Id$
+
+#include "ace/INet/HTTP_SessionBase.h"
+
+#if !defined (__ACE_INLINE__)
+#include "ace/INet/HTTP_SessionBase.inl"
+#endif
+
+#include "ace/INet/INet_Log.h"
+#include "ace/INet/HTTP_StreamPolicy.h"
+#include "ace/INet/String_IOStream.h"
+#include "ace/INet/IOS_util.h"
+#include "ace/INet/HTTP_URL.h"
+#include "ace/INET_Addr.h"
+#include "ace/String_Base.h"
+#include <istream>
+#include <ostream>
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace ACE
+{
+ namespace HTTP
+ {
+
+ SessionBase::SessionBase (u_short port, bool keep_alive)
+ : port_ (port),
+ reactive_ (false),
+ in_stream_ (0),
+ out_stream_ (0),
+ http_timeout_ (DEFAULT_TIMEOUT),
+ keep_alive_timeout_ (DEFAULT_KEEP_ALIVE_TIMEOUT),
+ reconnect_timer_ (DEFAULT_KEEP_ALIVE_TIMEOUT),
+ reconnect_countdown_ (&reconnect_timer_),
+ keep_alive_ (keep_alive),
+ needs_reconnect_ (false),
+ cannot_reconnect_ (false),
+ expects_response_body_ (false)
+ {
+ INET_TRACE ("ACE_HTTP_SessionBase - ctor");
+ }
+
+ SessionBase::SessionBase (u_short port,
+ const ACE_Time_Value& timeout,
+ bool keep_alive,
+ const ACE_Time_Value* alive_timeout)
+ : port_ (port),
+ reactive_ (false),
+ in_stream_ (0),
+ out_stream_ (0),
+ http_timeout_ (timeout),
+ keep_alive_timeout_ (DEFAULT_KEEP_ALIVE_TIMEOUT),
+ reconnect_timer_ (DEFAULT_KEEP_ALIVE_TIMEOUT),
+ reconnect_countdown_ (&reconnect_timer_),
+ keep_alive_ (keep_alive),
+ needs_reconnect_ (false),
+ cannot_reconnect_ (false),
+ expects_response_body_ (false)
+ {
+ INET_TRACE ("ACE_HTTP_SessionBase - ctor");
+ if (keep_alive && alive_timeout)
+ {
+ this->keep_alive_timeout_ = *alive_timeout;
+ }
+ }
+
+ SessionBase::~SessionBase ()
+ {
+ INET_TRACE ("ACE_HTTP_SessionBase - dtor");
+ this->close_streams ();
+ }
+
+ bool SessionBase::connect (bool use_reactor)
+ {
+ INET_TRACE ("ACE_HTTP_SessionBase::connect");
+
+ this->close ();
+
+ unsigned long f_reactor = use_reactor ? ACE_Synch_Options::USE_REACTOR : 0;
+ ACE_Synch_Options sync_opt (ACE_Synch_Options::USE_TIMEOUT | f_reactor,
+ this->http_timeout_);
+
+ return this->connect_i (sync_opt);
+ }
+
+ std::ostream& SessionBase::send_request (Request& request)
+ {
+ INET_TRACE ("ACE_HTTP_SessionBase::send_request");
+
+ if (this->in_stream_)
+ {
+ delete this->in_stream_;
+ this->in_stream_ = 0;
+ }
+
+ bool keep_alive = this->keep_alive ();
+ if ((this->is_connected () && !keep_alive) || this->reconnect_needed ())
+ {
+ close();
+ this->needs_reconnect_ = false;
+ }
+
+ if (this->out_stream_)
+ {
+ delete this->out_stream_;
+ this->out_stream_ = 0;
+ }
+
+ if (!this->is_connected ())
+ {
+ if (this->cannot_reconnect_ || !this->connect(this->reactive_))
+ {
+ if (!this->cannot_reconnect_)
+ INET_ERROR (1, (LM_ERROR, DLINFO
+ ACE_TEXT ("(%d) HTTP_SessionBase::send_request - ")
+ ACE_TEXT ("reconnect failed\n"),
+ ACE_OS::last_error ()));
+ return ACE::IOS::Null::out_stream_;
+ }
+ }
+ if (!keep_alive)
+ request.set_keep_alive (false);
+ if (!request.has_host ())
+ {
+ if (this->port_ == URL::HTTP_PORT)
+ request.set_host (this->host_);
+ else
+ request.set_host (this->host_, this->port_);
+ }
+
+ this->expects_response_body_ = request.get_method() != Request::HTTP_HEAD;
+
+ if (request.has_chunked_transfer_encoding ())
+ {
+ request.write (this->sock_stream ());
+ ChunkedTransferStreamPolicy* pol;
+ ACE_NEW_RETURN (pol,
+ ChunkedTransferStreamPolicy (),
+ ACE::IOS::Null::out_stream_);
+ ACE_NEW_RETURN (this->out_stream_,
+ OStream (this->sock_stream (), pol),
+ ACE::IOS::Null::out_stream_);
+ }
+ else if (request.get_content_length () != Header::UNKNOWN_CONTENT_LENGTH)
+ {
+ ACE::IOS::CString_OStream cs;
+ request.write (cs);
+ FixedLengthStreamPolicy* pol;
+ ACE_NEW_RETURN (pol,
+ FixedLengthStreamPolicy (cs.str ().length () + request.get_content_length ()),
+ ACE::IOS::Null::out_stream_);
+ ACE_NEW_RETURN (this->out_stream_,
+ OStream (this->sock_stream (), pol),
+ ACE::IOS::Null::out_stream_);
+ (*this->out_stream_) << cs.str ().c_str ();
+ }
+ else if (request.get_method () != Request::HTTP_PUT && request.get_method() != Request::HTTP_POST)
+ {
+ ACE::IOS::CString_OStream cs;
+ request.write (cs);
+ FixedLengthStreamPolicy* pol;
+ ACE_NEW_RETURN (pol,
+ FixedLengthStreamPolicy (cs.str ().length ()),
+ ACE::IOS::Null::out_stream_);
+ ACE_NEW_RETURN (this->out_stream_,
+ OStream (this->sock_stream (), pol),
+ ACE::IOS::Null::out_stream_);
+ (*this->out_stream_) << cs.str ().c_str ();
+ }
+ else
+ {
+ ACE_NEW_RETURN (this->out_stream_,
+ OStream (this->sock_stream ()),
+ ACE::IOS::Null::out_stream_);
+ request.write (*this->out_stream_);
+ }
+ // reset reconnect timer
+ this->reconnect_timer_ = this->keep_alive_timeout_;
+ this->reconnect_countdown_.start ();
+
+ return *this->out_stream_;
+ }
+
+ std::ostream& SessionBase::request_stream ()
+ {
+ return this->out_stream_ ? *this->out_stream_ : ACE::IOS::Null::out_stream_;
+ }
+
+ std::ostream& SessionBase::request_stream (
+ ACE::IOS::StreamInterceptor& interceptor)
+ {
+ if (this->out_stream_)
+ {
+ this->out_stream_->set_interceptor (interceptor);
+ return *this->out_stream_;
+ }
+ else
+ return ACE::IOS::Null::out_stream_;
+ }
+
+ std::istream& SessionBase::receive_response (Response& response)
+ {
+ INET_TRACE ("ACE_HTTP_SessionBase::receive_response");
+
+ if (this->in_stream_)
+ {
+ INET_ERROR (1, (LM_ERROR, DLINFO
+ ACE_TEXT ("HTTP_Session::receive_response - ")
+ ACE_TEXT ("invalid invocation without send_request\n")));
+ // receive_response called second time without
+ // new send_request in between
+ return ACE::IOS::Null::in_stream_;
+ }
+
+ if (this->out_stream_)
+ {
+ delete this->out_stream_;
+ this->out_stream_ = 0;
+ }
+
+ this->sock_stream ().flush ();
+
+ do
+ {
+ response.clear ();
+ if (!response.read (this->sock_stream ()))
+ {
+ INET_ERROR (1, (LM_ERROR, DLINFO
+ ACE_TEXT ("(%d) HTTP_Session::receive_response - ")
+ ACE_TEXT ("failed to read response\n"),
+ ACE_OS::last_error ()));
+ return ACE::IOS::Null::in_stream_;
+ }
+ }
+ while (response.get_status ().get_status() == Status::HTTP_CONTINUE);
+
+ this->needs_reconnect_ = this->keep_alive () && !response.has_keep_alive ();
+
+ if (!this->expects_response_body_)
+ {
+ FixedLengthStreamPolicy* pol;
+ ACE_NEW_RETURN (pol,
+ FixedLengthStreamPolicy (0),
+ ACE::IOS::Null::in_stream_);
+ ACE_NEW_RETURN (this->in_stream_,
+ IStream (this->sock_stream (), pol),
+ ACE::IOS::Null::in_stream_);
+ }
+ else if (response.has_chunked_transfer_encoding ())
+ {
+ ChunkedTransferStreamPolicy* pol;
+ ACE_NEW_RETURN (pol,
+ ChunkedTransferStreamPolicy (),
+ ACE::IOS::Null::in_stream_);
+ ACE_NEW_RETURN (this->in_stream_,
+ IStream (this->sock_stream (), pol),
+ ACE::IOS::Null::in_stream_);
+ }
+ else if (response.get_content_length () != Header::UNKNOWN_CONTENT_LENGTH)
+ {
+ FixedLengthStreamPolicy* pol;
+ ACE_NEW_RETURN (pol,
+ FixedLengthStreamPolicy (response.get_content_length ()),
+ ACE::IOS::Null::in_stream_);
+ ACE_NEW_RETURN (this->in_stream_,
+ IStream (this->sock_stream (), pol),
+ ACE::IOS::Null::in_stream_);
+ }
+ else
+ {
+ ACE_NEW_RETURN (this->in_stream_,
+ IStream (this->sock_stream ()),
+ ACE::IOS::Null::in_stream_);
+ }
+
+ return *this->in_stream_;
+ }
+
+ std::istream& SessionBase::response_stream ()
+ {
+ return this->in_stream_ ? *this->in_stream_ : ACE::IOS::Null::in_stream_;
+ }
+
+ std::istream& SessionBase::response_stream (
+ ACE::IOS::StreamInterceptor& interceptor)
+ {
+ if (this->in_stream_)
+ {
+ this->in_stream_->set_interceptor (interceptor);
+ return *this->in_stream_;
+ }
+ else
+ return ACE::IOS::Null::in_stream_;
+ }
+
+ void SessionBase::close ()
+ {
+ INET_TRACE ("ACE_HTTP_SessionBase::close");
+
+ this->close_streams ();
+
+ this->close_i ();
+ }
+
+ }
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/protocols/ace/INet/HTTP_SessionBase.h b/ACE/protocols/ace/INet/HTTP_SessionBase.h
new file mode 100644
index 00000000000..6233f80c6dd
--- /dev/null
+++ b/ACE/protocols/ace/INet/HTTP_SessionBase.h
@@ -0,0 +1,134 @@
+// $Id$
+
+/**
+ * @file HTTP_SessionBase.h
+ *
+ * @author Martin Corino <mcorino@remedy.nl>
+ */
+
+#ifndef ACE_HTTP_SESSION_BASE_H
+#define ACE_HTTP_SESSION_BASE_H
+
+#include /**/ "ace/pre.h"
+
+#include "ace/SString.h"
+#include "ace/Countdown_Time.h"
+#include "ace/Synch_Options.h"
+#include "ace/INet/INet_Export.h"
+#include "ace/INet/HTTP_Request.h"
+#include "ace/INet/HTTP_Response.h"
+#include "ace/INet/HTTP_IOStream.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace ACE
+ {
+ namespace HTTP
+ {
+ /**
+ * @class ACE_HTTP_SessionBase
+ *
+ * @brief Abstract base class for HTTP(S) sessions.
+ *
+ */
+ class ACE_INET_Export SessionBase
+ {
+ public:
+ SessionBase (u_short port,
+ bool keep_alive = false);
+
+ SessionBase (u_short port,
+ const ACE_Time_Value& timeout,
+ bool keep_alive = false,
+ const ACE_Time_Value* alive_timeout = 0);
+
+ virtual ~SessionBase ();
+
+ void set_keep_alive (bool f);
+
+ bool keep_alive () const;
+
+ virtual bool is_connected () const = 0;
+
+ void set_host (const ACE_CString& host,
+ u_short port);
+
+ void set_host (const ACE_CString& host);
+
+ void set_port (u_short port);
+
+ void set_proxy_target (const ACE_CString& host, u_short port);
+
+ const ACE_CString& get_host () const;
+
+ u_short get_port () const;
+
+ bool is_proxy_connection () const;
+
+ const ACE_CString& get_proxy_target_host () const;
+
+ u_short get_proxy_target_port () const;
+
+ bool connect (bool use_reactor = false);
+
+ std::ostream& send_request (Request& request);
+
+ std::ostream& request_stream ();
+
+ std::ostream& request_stream (ACE::IOS::StreamInterceptor& interceptor);
+
+ std::istream& receive_response (Response& response);
+
+ std::istream& response_stream ();
+
+ std::istream& response_stream (ACE::IOS::StreamInterceptor& interceptor);
+
+ void close ();
+
+ protected:
+
+ bool reconnect_needed ();
+
+ void close_streams ();
+
+ virtual bool connect_i (const ACE_Synch_Options& sync_opt) = 0;
+
+ virtual void close_i () = 0;
+
+ virtual std::iostream& sock_stream () = 0;
+
+ enum
+ {
+ DEFAULT_TIMEOUT = 30, // sec
+ DEFAULT_KEEP_ALIVE_TIMEOUT = 8 // sec
+ };
+
+ ACE_CString host_;
+ u_short port_;
+ bool proxy_connection_;
+ ACE_CString proxy_target_host_;
+ u_short proxy_target_port_;
+
+ bool reactive_;
+ IStream* in_stream_;
+ OStream* out_stream_;
+ ACE_Time_Value http_timeout_;
+ ACE_Time_Value keep_alive_timeout_;
+ ACE_Time_Value reconnect_timer_;
+ ACE_Countdown_Time reconnect_countdown_;
+ bool keep_alive_;
+ bool needs_reconnect_;
+ bool cannot_reconnect_;
+ bool expects_response_body_;
+ };
+ }
+ }
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#if defined (__ACE_INLINE__)
+#include "ace/INet/HTTP_SessionBase.inl"
+#endif
+
+#include /**/ "ace/post.h"
+#endif /* ACE_HTTP_SESSION_BASE_H */
diff --git a/ACE/protocols/ace/INet/HTTP_SessionBase.inl b/ACE/protocols/ace/INet/HTTP_SessionBase.inl
new file mode 100644
index 00000000000..6539f51b284
--- /dev/null
+++ b/ACE/protocols/ace/INet/HTTP_SessionBase.inl
@@ -0,0 +1,124 @@
+// -*- C++ -*-
+//
+// $Id$
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace ACE
+{
+ namespace HTTP
+ {
+ ACE_INLINE
+ void SessionBase::set_keep_alive (bool f)
+ {
+ this->keep_alive_ = f;
+ }
+
+ ACE_INLINE
+ bool SessionBase::keep_alive () const
+ {
+ return this->keep_alive_;
+ }
+
+ ACE_INLINE
+ void SessionBase::set_host (const ACE_CString& host, u_short port)
+ {
+ if (!this->is_connected ())
+ {
+ this->host_ = host;
+ this->port_ = port;
+ this->proxy_connection_ = false;
+ }
+ }
+
+ ACE_INLINE
+ void SessionBase::set_host (const ACE_CString& host)
+ {
+ if (!this->is_connected ())
+ {
+ this->host_ = host;
+ this->proxy_connection_ = false;
+ }
+ }
+
+ ACE_INLINE
+ void SessionBase::set_port (u_short port)
+ {
+ if (!this->is_connected ())
+ {
+ this->port_ = port;
+ }
+ }
+
+ ACE_INLINE
+ void SessionBase::set_proxy_target (const ACE_CString& host, u_short port)
+ {
+ if (!this->is_connected ())
+ {
+ this->proxy_target_host_ = host;
+ this->proxy_target_port_ = port;
+ this->proxy_connection_ = true;
+ }
+ }
+
+ ACE_INLINE
+ const ACE_CString& SessionBase::get_host () const
+ {
+ return this->host_;
+ }
+
+ ACE_INLINE
+ u_short SessionBase::get_port () const
+ {
+ return this->port_;
+ }
+
+ ACE_INLINE
+ bool SessionBase::is_proxy_connection () const
+ {
+ return this->proxy_connection_;
+ }
+
+ ACE_INLINE
+ const ACE_CString& SessionBase::get_proxy_target_host () const
+ {
+ return this->proxy_target_host_;
+ }
+
+ ACE_INLINE
+ u_short SessionBase::get_proxy_target_port () const
+ {
+ return this->proxy_target_port_;
+ }
+
+ ACE_INLINE
+ bool SessionBase::reconnect_needed ()
+ {
+ if (this->cannot_reconnect_)
+ return false;
+ if (!this->needs_reconnect_)
+ {
+ this->reconnect_countdown_.update ();
+ return this->reconnect_timer_ == ACE_Time_Value::zero;
+ }
+ return true;
+ }
+
+ ACE_INLINE
+ void SessionBase::close_streams ()
+ {
+ if (this->in_stream_)
+ {
+ delete this->in_stream_;
+ this->in_stream_ = 0;
+ }
+ if (this->out_stream_)
+ {
+ delete this->out_stream_;
+ this->out_stream_ = 0;
+ }
+ }
+ }
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/protocols/ace/INet/HTTP_Simple_exec.cpp b/ACE/protocols/ace/INet/HTTP_Simple_exec.cpp
index 224c8851755..bf82a88fb5a 100644
--- a/ACE/protocols/ace/INet/HTTP_Simple_exec.cpp
+++ b/ACE/protocols/ace/INet/HTTP_Simple_exec.cpp
@@ -3,8 +3,11 @@
#include "ace/Get_Opt.h"
#include "ace/Auto_Ptr.h"
#include "ace/OS_NS_errno.h"
-#include "HTTP_URL.h"
-#include "HTTP_ClientRequestHandler.h"
+#include "ace/INet/HTTP_URL.h"
+#include "ace/INet/HTTP_ClientRequestHandler.h"
+#include "ace/INet/SSL_CallbackManager.h"
+#include "ace/INet/HTTPS_Context.h"
+#include "ace/INet/INet_Log.h"
#include <iostream>
#include <fstream>
@@ -12,21 +15,33 @@ ACE_CString proxy_hostname;
u_short proxy_port = ACE::HTTP::URL::HTTP_PROXY_PORT;
ACE_CString url;
ACE_CString outfile;
+int ssl_mode = ACE_SSL_Context::SSLv3;
+bool verify_peer = true;
+bool ignore_verify = false;
+ACE_CString certificate;
+ACE_CString private_key;
+ACE_CString ca_location;
void
usage (void)
{
std::cout << "usage: http_simple_wget [options] <url>\n";
std::cout << "Executes an HTTP GET request and sends the result to STDOUT or file\n";
- std::cout << "\t-H <hostname>\t\tproxy host to connect to\n";
- std::cout << "\t-p <port>\t\tproxy port to connect to\n";
- std::cout << "\t-o <filename>\t\tfile to write output to\n";
+ std::cout << "\t-H <hostname> \t\tproxy host to connect to\n";
+ std::cout << "\t-p <port> \t\tproxy port to connect to\n";
+ std::cout << "\t-o <filename> \t\tfile to write output to\n";
+ std::cout << "\t-v <ssl version>\t\tSSL version to use: 2, 23, 3\n";
+ std::cout << "\t-n \t\tno peer certificate verification\n";
+ std::cout << "\t-i \t\tignore peer certificate verification failures\n";
+ std::cout << "\t-c <filename> \t\tcertificate file (PEM format)\n";
+ std::cout << "\t-k <filename> \t\tprivate key file (PEM format); requires -c\n";
+ std::cout << "\t-C <path> \t\ttrusted CA file or directory\n";
}
bool
parse_args (int argc, ACE_TCHAR *argv [])
{
- ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("H:p:o:h"), 0, 0, ACE_Get_Opt::RETURN_IN_ORDER);
+ ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("H:p:o:hv:nic:k:C:"), 0, 0, ACE_Get_Opt::RETURN_IN_ORDER);
int c;
ACE_CString s;
@@ -49,6 +64,41 @@ parse_args (int argc, ACE_TCHAR *argv [])
outfile = ACE_TEXT_ALWAYS_CHAR (get_opt.opt_arg ());
break;
+ case 'v':
+ {
+ ACE_CString ver = ACE_TEXT_ALWAYS_CHAR (get_opt.opt_arg ());
+ if (ver == "2")
+ ssl_mode = ACE_SSL_Context::SSLv2;
+ else if (ver == "23")
+ ssl_mode = ACE_SSL_Context::SSLv23;
+ else if (ver != "3") // default mode
+ {
+ std::cerr << "ERROR: Invalid SSL mode [" << ver << "] specfied!" << std::endl;
+ return false;
+ }
+ }
+ break;
+
+ case 'n':
+ verify_peer = false;
+ break;
+
+ case 'i':
+ ignore_verify = true;
+ break;
+
+ case 'c':
+ certificate = ACE_TEXT_ALWAYS_CHAR (get_opt.opt_arg ());
+ break;
+
+ case 'k':
+ private_key = ACE_TEXT_ALWAYS_CHAR (get_opt.opt_arg ());
+ break;
+
+ case 'C':
+ ca_location = ACE_TEXT_ALWAYS_CHAR (get_opt.opt_arg ());
+ break;
+
case 'h':
default:
usage ();
@@ -119,6 +169,35 @@ ACE_TMAIN (int argc, ACE_TCHAR *argv [])
return 1;
}
+ ACE::HTTPS::Context::set_default_ssl_mode (ssl_mode);
+ ACE::HTTPS::Context::set_default_verify_mode (verify_peer);
+ ACE::HTTPS::Context::instance ().use_default_ca ();
+ if (!private_key.empty ())
+ {
+ if (certificate.empty ())
+ {
+ std::cerr << "ERROR: private key file [" << private_key << "] requires certificate file to be specified." << std::endl;
+ return 1;
+ }
+ if (!ACE::HTTPS::Context::instance ().set_key_files (private_key.c_str (), certificate.c_str ()))
+ {
+ std::cerr << "ERROR: failed to set private key [" << private_key << "]." << std::endl;
+ return 1;
+ }
+ }
+ if (!ca_location.empty ())
+ {
+ INET_DEBUG (6, (LM_INFO, DLINFO ACE_TEXT ("loading trusted CA [%C]\n"), ca_location.c_str ()));
+ if (!ACE::HTTPS::Context::instance ().load_trusted_ca (ca_location.c_str ()))
+ {
+ std::cerr << "ERROR: failed to load trusted CA from [" << ca_location << "]." << std::endl;
+ return 1;
+ }
+ INET_DEBUG (6, (LM_INFO, DLINFO ACE_TEXT ("loaded [%d] trusted CA\n"), ACE::HTTPS::Context::instance ().has_trusted_ca ()));
+ }
+ if (ignore_verify)
+ ACE::INet::SSL_CallbackManager::instance ()->set_certificate_callback (new ACE::INet::SSL_CertificateAcceptor);
+
std::cout << "Starting..." << std::endl;
if (!url.empty ())
@@ -136,17 +215,19 @@ ACE_TMAIN (int argc, ACE_TCHAR *argv [])
sout = fout.get ();
}
- ACE::HTTP::URL http_url;
-
std::cout << "Parsing url [" << url.c_str () << "]" << std::endl;
- if (!http_url.parse (url))
+ ACE_Auto_Ptr<ACE::INet::URL_Base> url_safe (ACE::INet::URL_Base::create_from_string (url));
+
+ if (url_safe.get () == 0 || url != url_safe->to_string ())
{
std::cerr << "Failed parsing url [" << url << "]" << std::endl;
- std::cerr << "\tresult = " << http_url.to_string ().c_str ();
+ std::cerr << "\tresult = " << (url_safe.get () == 0 ? "(null)" : url_safe->to_string ().c_str ()) << std::endl;
return 1;
}
+ ACE::HTTP::URL& http_url = *dynamic_cast<ACE::HTTP::URL*> (url_safe.get ());
+
if (!proxy_hostname.empty ())
{
std::cout << "Setting proxy: " << proxy_hostname.c_str () << ':' << proxy_port << std::endl;
diff --git a/ACE/protocols/ace/INet/HTTP_StreamPolicy.h b/ACE/protocols/ace/INet/HTTP_StreamPolicy.h
index c9c139a003e..9ec94680c97 100644
--- a/ACE/protocols/ace/INet/HTTP_StreamPolicy.h
+++ b/ACE/protocols/ace/INet/HTTP_StreamPolicy.h
@@ -25,7 +25,8 @@ namespace ACE
/**
* @class ACE_HTTP_FixedLengthStreamPolicy
*
- * @brief
+ * @brief Implements stream policy for fixed length data stream
+ * in HTTP response or request.
*
*/
template <class STREAM_BUFFER>
@@ -53,7 +54,8 @@ namespace ACE
/**
* @class ACE_HTTP_ChunkedTransferStreamPolicy
*
- * @brief
+ * @brief Implements stream policy for chunked data streams
+ * in HTTP response or request.
*
*/
template <class STREAM_BUFFER>
diff --git a/ACE/protocols/ace/INet/HTTP_StreamPolicyBase.h b/ACE/protocols/ace/INet/HTTP_StreamPolicyBase.h
index 814377b7050..2000eb3087e 100644
--- a/ACE/protocols/ace/INet/HTTP_StreamPolicyBase.h
+++ b/ACE/protocols/ace/INet/HTTP_StreamPolicyBase.h
@@ -23,7 +23,7 @@ namespace ACE
/**
* @class ACE_IOS_StreamPolicyBase
*
- * @brief
+ * @brief Abstract base for HTTP stream policies.
*
*/
template <class STREAM_BUFFER>
diff --git a/ACE/protocols/ace/INet/HTTP_URL.cpp b/ACE/protocols/ace/INet/HTTP_URL.cpp
index 6a7803d8408..01498682691 100644
--- a/ACE/protocols/ace/INet/HTTP_URL.cpp
+++ b/ACE/protocols/ace/INet/HTTP_URL.cpp
@@ -15,7 +15,13 @@ namespace ACE
{
namespace HTTP
{
- const ACE_CString URL::PROTOCOL ("http");
+ const char* URL::PROTOCOL = "http";
+
+ const ACE_CString& URL::protocol ()
+ {
+ static const ACE_CString protocol_ (PROTOCOL);
+ return protocol_;
+ }
URL::URL ()
: URL_INetAuthBase (HTTP_PORT),
@@ -36,6 +42,12 @@ namespace ACE
*this = url;
}
+ URL::URL (u_short port)
+ : URL_INetAuthBase (port),
+ proxy_port_ (HTTP_PROXY_PORT)
+ {
+ }
+
URL::~URL ()
{
}
@@ -107,7 +119,7 @@ namespace ACE
const ACE_CString& URL::Factory::protocol ()
{
- return URL::PROTOCOL;
+ return URL::protocol ();
}
ACE::INet::URL_Base* URL::Factory::create_from_string (const ACE_CString& url_string)
diff --git a/ACE/protocols/ace/INet/HTTP_URL.h b/ACE/protocols/ace/INet/HTTP_URL.h
index e392c17d727..7217ab6851d 100644
--- a/ACE/protocols/ace/INet/HTTP_URL.h
+++ b/ACE/protocols/ace/INet/HTTP_URL.h
@@ -29,7 +29,7 @@ namespace ACE
/**
* @class ACE_HTTP_URL
*
- * @brief
+ * @brief Implements HTTP url support.
*
*/
class ACE_INET_Export URL
@@ -49,7 +49,7 @@ namespace ACE
virtual const ACE_CString& get_fragment () const;
- ACE_CString get_request_uri () const;
+ virtual ACE_CString get_request_uri () const;
virtual void set_query (const ACE_CString& query);
@@ -67,7 +67,9 @@ namespace ACE
virtual u_short default_port () const;
- static const ACE_CString PROTOCOL;
+ static const char* PROTOCOL;
+
+ static const ACE_CString& protocol ();
enum
{
@@ -76,6 +78,8 @@ namespace ACE
};
protected:
+ URL (u_short port);
+
virtual ACE::INet::ClientRequestHandler* create_default_request_handler () const;
private:
diff --git a/ACE/protocols/ace/INet/HTTP_URL.inl b/ACE/protocols/ace/INet/HTTP_URL.inl
index df6a2a0cebc..398f4dc7c8d 100644
--- a/ACE/protocols/ace/INet/HTTP_URL.inl
+++ b/ACE/protocols/ace/INet/HTTP_URL.inl
@@ -12,7 +12,7 @@ namespace ACE
ACE_INLINE
const ACE_CString& URL::get_scheme () const
{
- return PROTOCOL;
+ return protocol ();
}
ACE_INLINE
diff --git a/ACE/protocols/ace/INet/HeaderBase.h b/ACE/protocols/ace/INet/HeaderBase.h
index bb6f61e16a3..67b10282192 100644
--- a/ACE/protocols/ace/INet/HeaderBase.h
+++ b/ACE/protocols/ace/INet/HeaderBase.h
@@ -30,6 +30,12 @@ namespace ACE
{
namespace INet
{
+ /**
+ * @class ACE_INet_NVPair
+ *
+ * @brief Name/Value pair holder class.
+ *
+ */
class NVPair
{
public:
@@ -110,15 +116,25 @@ namespace ACE
static const ACE_CString EMPTY;
- protected:
+ /// Sets header <name> to <value>. Overwrites existing vaues.
void set (const ACE_CString& name, const ACE_CString& value);
+
+ /// Adds header <name> with <value>. Allows duplicates.
void add (const ACE_CString& name, const ACE_CString& value);
+
+ /// Removes header <name> (first found).
void remove (const ACE_CString& name);
+
+ /// Retrieves value for header <name> into <value> (first found).
bool get (const ACE_CString& name, ACE_CString& value) const;
+
+ /// Returns true if a header <name> exists (1 or more), false otherwise.
bool has (const ACE_CString& name) const;
+ /// Retrieves values for all headers <name> into <values>.
void get_values (const ACE_CString& name, ACE_Array<ACE_CString>& values) const;
+ protected:
int read_field (std::istream& str, ACE_CString& var, size_t maxlen, char delim);
int read_ws_field (std::istream& str, ACE_CString& var, size_t maxlen);
diff --git a/ACE/protocols/ace/INet/RequestHandler.h b/ACE/protocols/ace/INet/RequestHandler.h
index 360d1e6f9de..73e1a7e7e70 100644
--- a/ACE/protocols/ace/INet/RequestHandler.h
+++ b/ACE/protocols/ace/INet/RequestHandler.h
@@ -25,7 +25,7 @@ namespace ACE
/**
* @class ACE_INet_RequestHandler
*
- * @brief
+ * @brief Abstract base for request handlers.
*
*/
class ACE_INET_Export RequestHandler
diff --git a/ACE/protocols/ace/INet/SSLSock_IOStream.cpp b/ACE/protocols/ace/INet/SSLSock_IOStream.cpp
new file mode 100644
index 00000000000..62de4128853
--- /dev/null
+++ b/ACE/protocols/ace/INet/SSLSock_IOStream.cpp
@@ -0,0 +1,130 @@
+// $Id$
+
+#ifndef ACE_IOS_SSLSOCK_IOSTREAM_CPP
+#define ACE_IOS_SSLSOCK_IOSTREAM_CPP
+
+#include "ace/INet/SSLSock_IOStream.h"
+#include "ace/INet/IOS_util.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace ACE
+{
+ namespace IOS
+ {
+
+ template <ACE_SYNCH_DECL>
+ SSLSock_StreamBufferBase<ACE_SYNCH_USE>::SSLSock_StreamBufferBase (stream_type* stream)
+ : BidirStreamBuffer<StreamHandler<ACE_SSL_SOCK_Stream, ACE_SYNCH_USE> > (
+ stream,
+ BUFFER_SIZE,
+ std::ios::in | std::ios::out)
+ {
+ }
+
+ template <ACE_SYNCH_DECL>
+ SSLSock_StreamBufferBase<ACE_SYNCH_USE>::~SSLSock_StreamBufferBase ()
+ {
+ }
+
+ template <ACE_SYNCH_DECL>
+ SSLSock_IOSBase<ACE_SYNCH_USE>::SSLSock_IOSBase (stream_type* stream)
+ : streambuf_ (stream)
+ {
+ ace_ios_init (&this->streambuf_);
+ }
+
+ template <ACE_SYNCH_DECL>
+ SSLSock_IOSBase<ACE_SYNCH_USE>::~SSLSock_IOSBase ()
+ {
+ try
+ {
+ this->streambuf_.sync();
+ }
+ catch (...)
+ {
+ }
+ }
+
+ template <ACE_SYNCH_DECL>
+ typename SSLSock_IOSBase<ACE_SYNCH_USE>::buffer_type*
+ SSLSock_IOSBase<ACE_SYNCH_USE>::rdbuf ()
+ {
+ return &this->streambuf_;
+ }
+
+ template <ACE_SYNCH_DECL>
+ void SSLSock_IOSBase<ACE_SYNCH_USE>::close ()
+ {
+ this->streambuf_.sync ();
+ this->streambuf_.close_stream ();
+ }
+
+ template <ACE_SYNCH_DECL>
+ const typename SSLSock_IOSBase<ACE_SYNCH_USE>::stream_type&
+ SSLSock_IOSBase<ACE_SYNCH_USE>::stream () const
+ {
+ return this->streambuf_.stream ();
+ }
+
+
+ template <ACE_SYNCH_DECL>
+ SSLSock_OStreamBase<ACE_SYNCH_USE>::SSLSock_OStreamBase(stream_type* stream)
+ : SSLSock_IOSBase<ACE_SYNCH_USE> (stream), std::ostream (SSLSock_IOSBase<ACE_SYNCH_USE>::rdbuf ())
+ {
+ }
+
+ template <ACE_SYNCH_DECL>
+ SSLSock_OStreamBase<ACE_SYNCH_USE>::~SSLSock_OStreamBase()
+ {
+ }
+
+ template <ACE_SYNCH_DECL>
+ void SSLSock_OStreamBase<ACE_SYNCH_USE>::set_interceptor (
+ typename buffer_type::interceptor_type& interceptor)
+ {
+ this->rdbuf ()->set_interceptor (interceptor);
+ }
+
+ template <ACE_SYNCH_DECL>
+ SSLSock_IStreamBase<ACE_SYNCH_USE>::SSLSock_IStreamBase(stream_type* stream)
+ : SSLSock_IOSBase<ACE_SYNCH_USE> (stream), std::istream (SSLSock_IOSBase<ACE_SYNCH_USE>::rdbuf ())
+ {
+ }
+
+ template <ACE_SYNCH_DECL>
+ SSLSock_IStreamBase<ACE_SYNCH_USE>::~SSLSock_IStreamBase ()
+ {
+ }
+
+ template <ACE_SYNCH_DECL>
+ void SSLSock_IStreamBase<ACE_SYNCH_USE>::set_interceptor (
+ typename buffer_type::interceptor_type& interceptor)
+ {
+ this->rdbuf ()->set_interceptor (interceptor);
+ }
+
+ template <ACE_SYNCH_DECL>
+ SSLSock_IOStreamBase<ACE_SYNCH_USE>::SSLSock_IOStreamBase(stream_type* stream)
+ : SSLSock_IOSBase<ACE_SYNCH_USE> (stream), std::iostream (SSLSock_IOSBase<ACE_SYNCH_USE>::rdbuf ())
+ {
+ }
+
+ template <ACE_SYNCH_DECL>
+ SSLSock_IOStreamBase<ACE_SYNCH_USE>::~SSLSock_IOStreamBase ()
+ {
+ }
+
+ template <ACE_SYNCH_DECL>
+ void SSLSock_IOStreamBase<ACE_SYNCH_USE>::set_interceptor (
+ typename buffer_type::interceptor_type& interceptor)
+ {
+ this->rdbuf ()->set_interceptor (interceptor);
+ }
+
+ }
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* ACE_IOS_SSLSOCK_IOSTREAM_CPP */
diff --git a/ACE/protocols/ace/INet/SSLSock_IOStream.h b/ACE/protocols/ace/INet/SSLSock_IOStream.h
new file mode 100644
index 00000000000..ad6df10810f
--- /dev/null
+++ b/ACE/protocols/ace/INet/SSLSock_IOStream.h
@@ -0,0 +1,169 @@
+// $Id$
+
+/**
+ * @file SSLSock_IOStream.h
+ *
+ * @author Martin Corino <mcorino@remedy.nl>
+ */
+
+#ifndef ACE_IOS_SSLSOCK_IOSTREAM_H
+#define ACE_IOS_SSLSOCK_IOSTREAM_H
+
+#include /**/ "ace/pre.h"
+
+#include /**/ "ace/config-all.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/SSL/SSL_SOCK_Stream.h"
+#include "ace/INet/BidirStreamBuffer.h"
+#include "ace/INet/StreamHandler.h"
+#include "ace/INet/StreamInterceptor.h"
+#include <istream>
+#include <ostream>
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace ACE
+ {
+ namespace IOS
+ {
+ /**
+ * @class ACE_IOS_SSLSock_StreamBuffer
+ *
+ * @brief
+ *
+ */
+ template <ACE_SYNCH_DECL>
+ class SSLSock_StreamBufferBase
+ : public BidirStreamBuffer<StreamHandler<ACE_SSL_SOCK_Stream, ACE_SYNCH_USE> >
+ {
+ public:
+ typedef StreamHandler<ACE_SSL_SOCK_Stream, ACE_SYNCH_USE> stream_type;
+
+ SSLSock_StreamBufferBase (stream_type* stream);
+ virtual ~SSLSock_StreamBufferBase ();
+
+ private:
+ enum
+ {
+ BUFFER_SIZE = 1024
+ };
+ };
+
+ /**
+ * @class ACE_IOS_SSLSock_IOS
+ *
+ * @brief
+ *
+ */
+ template <ACE_SYNCH_DECL>
+ class SSLSock_IOSBase
+ : public virtual std::ios
+ {
+ public:
+ typedef SSLSock_StreamBufferBase<ACE_SYNCH_USE> buffer_type;
+ typedef typename buffer_type::stream_type stream_type;
+
+ SSLSock_IOSBase (stream_type* stream);
+ ~SSLSock_IOSBase ();
+
+ buffer_type* rdbuf ();
+
+ void close ();
+
+ const stream_type& stream () const;
+
+ protected:
+ buffer_type streambuf_;
+ };
+
+ /**
+ * @class ACE_IOS_SSLSock_OStream
+ *
+ * @brief
+ *
+ */
+ template <ACE_SYNCH_DECL>
+ class SSLSock_OStreamBase
+ : public SSLSock_IOSBase<ACE_SYNCH_USE>, public std::ostream
+ {
+ public:
+ typedef SSLSock_IOSBase<ACE_SYNCH_USE> ios_base;
+ typedef typename ios_base::stream_type stream_type;
+ typedef SSLSock_StreamBufferBase<ACE_SYNCH_USE> buffer_type;
+
+ explicit SSLSock_OStreamBase(stream_type* stream);
+
+ ~SSLSock_OStreamBase();
+
+ void set_interceptor (typename buffer_type::interceptor_type& interceptor);
+ };
+
+ /**
+ * @class ACE_IOS_SSLSock_IStream
+ *
+ * @brief
+ *
+ */
+ template <ACE_SYNCH_DECL>
+ class SSLSock_IStreamBase
+ : public SSLSock_IOSBase<ACE_SYNCH_USE>, public std::istream
+ {
+ public:
+ typedef SSLSock_IOSBase<ACE_SYNCH_USE> ios_base;
+ typedef typename ios_base::stream_type stream_type;
+ typedef SSLSock_StreamBufferBase<ACE_SYNCH_USE> buffer_type;
+
+ explicit SSLSock_IStreamBase(stream_type* stream);
+
+ ~SSLSock_IStreamBase();
+
+ void set_interceptor (typename buffer_type::interceptor_type& interceptor);
+ };
+
+ /**
+ * @class ACE_IOS_SSLSock_IOStream
+ *
+ * @brief
+ *
+ */
+ template <ACE_SYNCH_DECL>
+ class SSLSock_IOStreamBase
+ : public SSLSock_IOSBase<ACE_SYNCH_USE>, public std::iostream
+ {
+ public:
+ typedef SSLSock_IOSBase<ACE_SYNCH_USE> ios_base;
+ typedef typename ios_base::stream_type stream_type;
+ typedef SSLSock_StreamBufferBase<ACE_SYNCH_USE> buffer_type;
+
+ explicit SSLSock_IOStreamBase(stream_type* stream);
+
+ ~SSLSock_IOStreamBase();
+
+ void set_interceptor (typename buffer_type::interceptor_type& interceptor);
+ };
+
+ typedef SSLSock_StreamBufferBase<ACE_NULL_SYNCH> SSLSock_StreamBuffer;
+ typedef SSLSock_IOSBase<ACE_NULL_SYNCH> SSLSock_IOS;
+ typedef SSLSock_IStreamBase<ACE_NULL_SYNCH> SSLSock_IStream;
+ typedef SSLSock_OStreamBase<ACE_NULL_SYNCH> SSLSock_OStream;
+ typedef SSLSock_IOStreamBase<ACE_NULL_SYNCH> SSLSock_IOStream;
+
+ }
+ }
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
+#include "ace/INet/SSLSock_IOStream.cpp"
+#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
+
+#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
+#pragma implementation ("SSLSock_IOStream.cpp")
+#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
+
+#include /**/ "ace/post.h"
+#endif /* ACE_IOS_SSLSOCK_IOSTREAM_H */
diff --git a/ACE/protocols/ace/INet/SSL_CallbackManager.cpp b/ACE/protocols/ace/INet/SSL_CallbackManager.cpp
new file mode 100644
index 00000000000..db93abb18de
--- /dev/null
+++ b/ACE/protocols/ace/INet/SSL_CallbackManager.cpp
@@ -0,0 +1,122 @@
+// $Id$
+
+#include "ace/INet/SSL_CallbackManager.h"
+
+#if !defined (__ACE_INLINE__)
+#include "ace/INet/SSL_CallbackManager.inl"
+#endif
+
+#include "ace/Truncate.h"
+#include "ace/Singleton.h"
+#include "ace/INet/INet_Log.h"
+
+#include <openssl/x509.h>
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace ACE
+{
+ namespace INet
+ {
+
+ int SSL_CallbackManager::ssl_ctx_mngr_index_ = (-2);
+
+ SSL_CallbackManager::SSL_CallbackManager ()
+ {
+ }
+
+ SSL_CallbackManager::~SSL_CallbackManager ()
+ {
+ }
+
+ void SSL_CallbackManager::initialize_callbacks (ACE_SSL_Context* ssl_ctx)
+ {
+ if (ssl_ctx_mngr_index_ < -1)
+ {
+ ssl_ctx_mngr_index_ = ::SSL_CTX_get_ex_new_index (0, 0, 0,0,0);
+ if (ssl_ctx_mngr_index_ < 0)
+ {
+ INET_ERROR (1, (LM_ERROR, DLINFO
+ ACE_TEXT ("SSL_CallbackManager::initialize_callbacks - ")
+ ACE_TEXT ("failed to allocate SSL_CTX ex_data index.\n")));
+ return;
+ }
+ }
+
+ this->ssl_ctx_ = ssl_ctx == 0 ? ACE_SSL_Context::instance () : ssl_ctx;
+ ::SSL_CTX_set_ex_data (this->ssl_ctx_->context (), ssl_ctx_mngr_index_, this);
+ this->ssl_ctx_->default_verify_callback (&verify_certificate_callback);
+ ::SSL_CTX_set_default_passwd_cb (ssl_ctx->context(), &passwd_callback);
+ ::SSL_CTX_set_default_passwd_cb_userdata (ssl_ctx->context(), this);
+ }
+
+ SSL_CallbackManager* SSL_CallbackManager::instance ()
+ {
+ return ACE_Singleton<SSL_CallbackManager, ACE_SYNCH::MUTEX>::instance ();
+ }
+
+ int SSL_CallbackManager::verify_certificate_callback (SSL_CertificateCallbackArg& arg)
+ {
+ TCertificateCallback cert_cb = this->cert_callback_;
+ if (cert_cb)
+ {
+ cert_cb->handle_certificate_failure (arg);
+ }
+ return (arg.ignore_error () ? 1 : 0);
+ }
+
+ void SSL_CallbackManager::passwd_callback (ACE_CString& pwd)
+ {
+ TPasswordCallback pw_cb = passwd_callback_;
+ if (pw_cb)
+ {
+ pw_cb->get_privatekey_password (pwd);
+ }
+ }
+
+ int SSL_CallbackManager::verify_certificate_callback (int ok, X509_STORE_CTX* cert_ctx)
+ {
+ if (!ok && ssl_ctx_mngr_index_>=0)
+ {
+ // Retrieve the pointer to the SSL of the connection currently treated
+ void* ex_data = ::X509_STORE_CTX_get_ex_data (cert_ctx, ::SSL_get_ex_data_X509_STORE_CTX_idx());
+ ::SSL* ssl = reinterpret_cast< ::SSL* > (ex_data);
+ // Retrieve SSL_CTX pointer of the connection currently treated
+ ::SSL_CTX* ssl_ctx = ::SSL_get_SSL_CTX (ssl);
+ // Retrieve our SSL_CallbackManager
+ ex_data = ::SSL_CTX_get_ex_data (ssl_ctx, ssl_ctx_mngr_index_);
+ SSL_CallbackManager* cbmngr = reinterpret_cast<SSL_CallbackManager*> (ex_data);
+
+ SSL_CertificateCallbackArg arg (cbmngr->context(), cert_ctx);
+ ok = cbmngr->verify_certificate_callback (arg);
+ }
+
+ return ok;
+ }
+
+ int SSL_CallbackManager::passwd_callback (char* buf, int size, int /*rwflag*/, void* user_data)
+ {
+ if (user_data == 0)
+ return 0;
+
+ SSL_CallbackManager* cbmngr = reinterpret_cast<SSL_CallbackManager*> (user_data);
+
+ ACE_CString pwd;
+ cbmngr->passwd_callback (pwd);
+ if (!pwd.empty ())
+ {
+ ACE_OS::strncpy (buf, pwd.c_str (), size);
+ buf[size - 1] = '\0';
+ if (size > ACE_Utils::truncate_cast<int> (pwd.length ()))
+ size = ACE_Utils::truncate_cast<int> (pwd.length ());
+
+ return size;
+ }
+ else
+ return 0;
+ }
+
+ }
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/protocols/ace/INet/SSL_CallbackManager.h b/ACE/protocols/ace/INet/SSL_CallbackManager.h
new file mode 100644
index 00000000000..80c51f81ec2
--- /dev/null
+++ b/ACE/protocols/ace/INet/SSL_CallbackManager.h
@@ -0,0 +1,78 @@
+// $Id$
+
+/**
+ * @file SSL_CertificateManager.h
+ *
+ * @author Martin Corino <mcorino@remedy.nl>
+ */
+
+#ifndef ACE_SSL_CALLBACKMANAGER_H
+#define ACE_SSL_CALLBACKMANAGER_H
+
+#include /**/ "ace/pre.h"
+
+#include "ace/SString.h"
+#include "ace/Refcounted_Auto_Ptr.h"
+#include "ace/SSL/SSL_Context.h"
+#include "ace/INet/SSL_CertificateCallback.h"
+#include "ace/INet/SSL_PasswordCallback.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace ACE
+ {
+ namespace INet
+ {
+ /**
+ * @class ACE_INet_SSL_CallbackManager
+ *
+ * @brief Implements manager class for configuring and handling
+ * SSL callbacks.
+ *
+ */
+ class ACE_INET_Export SSL_CallbackManager
+ {
+ public:
+ SSL_CallbackManager ();
+ ~SSL_CallbackManager ();
+
+ void initialize_callbacks (ACE_SSL_Context* ssl_ctx = ACE_SSL_Context::instance ());
+
+ const ACE_SSL_Context* context () const;
+
+ void set_certificate_callback (ACE::INet::SSL_CertificateCallback* cb);
+ void set_password_callback (ACE::INet::SSL_PasswordCallback* cb);
+
+ static SSL_CallbackManager* instance ();
+
+ private:
+ int verify_certificate_callback (SSL_CertificateCallbackArg& arg);
+ void passwd_callback (ACE_CString& pwd);
+
+ ACE_SSL_Context* ssl_ctx_;
+
+ typedef ACE_Refcounted_Auto_Ptr<ACE::INet::SSL_CertificateCallback,
+ ACE_SYNCH::MUTEX> TCertificateCallback;
+ typedef ACE_Refcounted_Auto_Ptr<ACE::INet::SSL_PasswordCallback,
+ ACE_SYNCH::MUTEX> TPasswordCallback;
+
+ TCertificateCallback cert_callback_;
+ TPasswordCallback passwd_callback_;
+
+ static int verify_certificate_callback (int ok, X509_STORE_CTX* cert_ctx);
+ static int passwd_callback (char* buf, int size, int rwflag, void* user_data);
+
+ static int ssl_ctx_mngr_index_;
+ };
+
+ }
+ }
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#if defined (__ACE_INLINE__)
+#include "ace/INet/SSL_CallbackManager.inl"
+#endif
+
+#include /**/ "ace/post.h"
+#endif /* ACE_SSL_CALLBACKMANAGER_H */
diff --git a/ACE/protocols/ace/INet/SSL_CallbackManager.inl b/ACE/protocols/ace/INet/SSL_CallbackManager.inl
new file mode 100644
index 00000000000..3728957c3f6
--- /dev/null
+++ b/ACE/protocols/ace/INet/SSL_CallbackManager.inl
@@ -0,0 +1,33 @@
+// -*- C++ -*-
+//
+// $Id$
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace ACE
+{
+ namespace INet
+ {
+
+ ACE_INLINE
+ const ACE_SSL_Context* SSL_CallbackManager::context () const
+ {
+ return this->ssl_ctx_;
+ }
+
+ ACE_INLINE
+ void SSL_CallbackManager::set_certificate_callback (ACE::INet::SSL_CertificateCallback* cb)
+ {
+ this->cert_callback_.reset (cb);
+ }
+
+ ACE_INLINE
+ void SSL_CallbackManager::set_password_callback (ACE::INet::SSL_PasswordCallback* cb)
+ {
+ this->passwd_callback_.reset (cb);
+ }
+
+ }
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/protocols/ace/INet/SSL_CertificateCallback.cpp b/ACE/protocols/ace/INet/SSL_CertificateCallback.cpp
new file mode 100644
index 00000000000..e1a4b0bce2e
--- /dev/null
+++ b/ACE/protocols/ace/INet/SSL_CertificateCallback.cpp
@@ -0,0 +1,62 @@
+// $Id$
+
+#include "ace/INet/SSL_CertificateCallback.h"
+
+#if !defined (__ACE_INLINE__)
+#include "ace/INet/SSL_CertificateCallback.inl"
+#endif
+
+#include "ace/Log_Msg.h"
+#include "ace/INet/INet_Log.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace ACE
+{
+ namespace INet
+ {
+
+ SSL_CertificateCallbackArg::SSL_CertificateCallbackArg (const ACE_SSL_Context* ssl_ctx,
+ ::X509_STORE_CTX* cert_ctx)
+ : ssl_ctx_ (ssl_ctx),
+ err_depth_ (0),
+ err_code_ (0),
+ ignore_err_ (false)
+ {
+ this->ssl_cert_ = ::X509_STORE_CTX_get_current_cert (cert_ctx);
+ this->err_depth_ = ::X509_STORE_CTX_get_error_depth (cert_ctx);
+ this->err_code_ = ::X509_STORE_CTX_get_error (cert_ctx);
+ }
+
+ SSL_CertificateCallbackArg::~SSL_CertificateCallbackArg ()
+ {
+ }
+
+ SSL_CertificateCallback::SSL_CertificateCallback ()
+ {
+ }
+
+ SSL_CertificateCallback::~SSL_CertificateCallback ()
+ {
+ }
+
+ SSL_CertificateAcceptor::SSL_CertificateAcceptor ()
+ {
+ }
+
+ SSL_CertificateAcceptor::~SSL_CertificateAcceptor ()
+ {
+ }
+
+ void SSL_CertificateAcceptor::handle_certificate_failure (SSL_CertificateCallbackArg& arg)
+ {
+ INET_DEBUG (3, (LM_INFO, DLINFO
+ ACE_TEXT ("SSL_CertificateAcceptor::handle_certificate_failure - ")
+ ACE_TEXT ("ignored certificate verification error: %C\n"),
+ arg.error_message ().c_str ()));
+ arg.ignore_error (true);
+ }
+ }
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/protocols/ace/INet/SSL_CertificateCallback.h b/ACE/protocols/ace/INet/SSL_CertificateCallback.h
new file mode 100644
index 00000000000..c48f7ab1f71
--- /dev/null
+++ b/ACE/protocols/ace/INet/SSL_CertificateCallback.h
@@ -0,0 +1,102 @@
+// $Id$
+
+/**
+ * @file SSL_CertificateCallback.h
+ *
+ * @author Martin Corino <mcorino@remedy.nl>
+ */
+
+#ifndef ACE_SSL_CERTIFICATECALLBACK_H
+#define ACE_SSL_CERTIFICATECALLBACK_H
+
+#include /**/ "ace/pre.h"
+
+#include "ace/SString.h"
+#include "ace/SSL/SSL_Context.h"
+#include "ace/INet/SSL_X509Cert.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace ACE
+ {
+ namespace INet
+ {
+ /**
+ * @class ACE_INet_SSL_CertificateCallbackArg
+ *
+ * @brief Encapsulates the arguments for an SSL certificate
+ * verification callback.
+ *
+ */
+ class ACE_INET_Export SSL_CertificateCallbackArg
+ {
+ public:
+ SSL_CertificateCallbackArg (const ACE_SSL_Context* ssl_ctx,
+ ::X509_STORE_CTX* cert_ctx);
+ ~SSL_CertificateCallbackArg ();
+
+ const ACE_SSL_Context& context () const;
+
+ SSL_X509Cert& certificate (void);
+
+ int error_depth () const;
+
+ int error_code () const;
+
+ ACE_CString error_message () const;
+
+ bool ignore_error () const;
+
+ void ignore_error (bool f);
+
+ private:
+ const ACE_SSL_Context* ssl_ctx_;
+ SSL_X509Cert ssl_cert_;
+ int err_depth_;
+ int err_code_;
+ bool ignore_err_;
+ };
+
+ /**
+ * @class ACE_INet_SSL_CertificateCallback
+ *
+ * @brief Abstract base class for SSL certificate
+ * verification callbacks.
+ *
+ */
+ class ACE_INET_Export SSL_CertificateCallback
+ {
+ public:
+ SSL_CertificateCallback ();
+ virtual ~SSL_CertificateCallback ();
+
+ virtual void handle_certificate_failure (SSL_CertificateCallbackArg& arg) = 0;
+ };
+
+ /**
+ * @class ACE_INet_SSL_CertificateAcceptor
+ *
+ * @brief Implements an SSL certificate callback that accepts
+ * all peer certificates.
+ *
+ */
+ class ACE_INET_Export SSL_CertificateAcceptor
+ : public SSL_CertificateCallback
+ {
+ public:
+ SSL_CertificateAcceptor ();
+ virtual ~SSL_CertificateAcceptor ();
+
+ virtual void handle_certificate_failure (SSL_CertificateCallbackArg& arg);
+ };
+ }
+ }
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#if defined (__ACE_INLINE__)
+#include "ace/INet/SSL_CertificateCallback.inl"
+#endif
+
+#include /**/ "ace/post.h"
+#endif /* ACE_SSL_CERTIFICATECALLBACK_H */
diff --git a/ACE/protocols/ace/INet/SSL_CertificateCallback.inl b/ACE/protocols/ace/INet/SSL_CertificateCallback.inl
new file mode 100644
index 00000000000..614db4394ac
--- /dev/null
+++ b/ACE/protocols/ace/INet/SSL_CertificateCallback.inl
@@ -0,0 +1,57 @@
+// -*- C++ -*-
+//
+// $Id$
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace ACE
+{
+ namespace INet
+ {
+
+ ACE_INLINE
+ const ACE_SSL_Context& SSL_CertificateCallbackArg::context () const
+ {
+ return *this->ssl_ctx_;
+ }
+
+ ACE_INLINE
+ SSL_X509Cert& SSL_CertificateCallbackArg::certificate (void)
+ {
+ return this->ssl_cert_;
+ }
+
+ ACE_INLINE
+ int SSL_CertificateCallbackArg::error_depth () const
+ {
+ return this->err_depth_;
+ }
+
+ ACE_INLINE
+ int SSL_CertificateCallbackArg::error_code () const
+ {
+ return this->err_code_;
+ }
+
+ ACE_INLINE
+ ACE_CString SSL_CertificateCallbackArg::error_message () const
+ {
+ return ACE_CString (X509_verify_cert_error_string (this->err_code_));
+ }
+
+ ACE_INLINE
+ bool SSL_CertificateCallbackArg::ignore_error () const
+ {
+ return this->ignore_err_;
+ }
+
+ ACE_INLINE
+ void SSL_CertificateCallbackArg::ignore_error (bool f)
+ {
+ this->ignore_err_ = f;
+ }
+
+ }
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/protocols/ace/INet/SSL_PasswordCallback.cpp b/ACE/protocols/ace/INet/SSL_PasswordCallback.cpp
new file mode 100644
index 00000000000..08811a19563
--- /dev/null
+++ b/ACE/protocols/ace/INet/SSL_PasswordCallback.cpp
@@ -0,0 +1,23 @@
+// $Id$
+
+#include "ace/INet/SSL_PasswordCallback.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace ACE
+{
+ namespace INet
+ {
+
+ SSL_PasswordCallback::SSL_PasswordCallback ()
+ {
+ }
+
+ SSL_PasswordCallback::~SSL_PasswordCallback ()
+ {
+ }
+
+ }
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/protocols/ace/INet/SSL_PasswordCallback.h b/ACE/protocols/ace/INet/SSL_PasswordCallback.h
new file mode 100644
index 00000000000..8c301964f03
--- /dev/null
+++ b/ACE/protocols/ace/INet/SSL_PasswordCallback.h
@@ -0,0 +1,44 @@
+// $Id$
+
+/**
+ * @file SSL_PasswordCallback.h
+ *
+ * @author Martin Corino <mcorino@remedy.nl>
+ */
+
+#ifndef ACE_SSL_PASSWORDCALLBACK_H
+#define ACE_SSL_PASSWORDCALLBACK_H
+
+#include /**/ "ace/pre.h"
+
+#include "ace/SString.h"
+#include "ace/INet/INet_Log.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace ACE
+ {
+ namespace INet
+ {
+ /**
+ * @class ACE_INet_SSL_PasswordCallback
+ *
+ * @brief Abstract base class for SSL private key
+ * password callback.
+ *
+ */
+ class ACE_INET_Export SSL_PasswordCallback
+ {
+ public:
+ SSL_PasswordCallback ();
+ virtual ~SSL_PasswordCallback ();
+
+ virtual void get_privatekey_password (ACE_CString& pwd) = 0;
+ };
+ }
+ }
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+#endif /* ACE_SSL_PASSWORDCALLBACK_H */
diff --git a/ACE/protocols/ace/INet/SSL_Proxy_Connector.cpp b/ACE/protocols/ace/INet/SSL_Proxy_Connector.cpp
new file mode 100644
index 00000000000..d1ffcbf7c1e
--- /dev/null
+++ b/ACE/protocols/ace/INet/SSL_Proxy_Connector.cpp
@@ -0,0 +1,212 @@
+// $Id$
+
+#include "ace/INet/SSL_Proxy_Connector.h"
+#include "ace/INet/INet_Log.h"
+
+#include "ace/OS_NS_errno.h"
+#include "ace/Handle_Set.h"
+#include "ace/Log_Msg.h"
+#include "ace/Countdown_Time.h"
+#include "ace/Truncate.h"
+
+#include <openssl/err.h>
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace ACE
+{
+ namespace INet
+ {
+
+ SSL_Proxy_Connector::SSL_Proxy_Connector () {}
+
+ SSL_Proxy_Connector::~SSL_Proxy_Connector () {}
+
+ /*
+ * This code is copied from ace/SSL/SSL_SOCK_Connector.cpp
+ */
+ int
+ SSL_Proxy_Connector::ssl_connect (ACE_SSL_SOCK_Stream &new_stream,
+ const ACE_Time_Value *timeout)
+ {
+ SSL *ssl = new_stream.ssl ();
+
+ if (SSL_is_init_finished (ssl))
+ return 0;
+
+ // Check if a connection is already pending for the given SSL
+ // structure.
+ if (!SSL_in_connect_init (ssl))
+ ::SSL_set_connect_state (ssl);
+
+ ACE_HANDLE handle = new_stream.get_handle ();
+
+ // We're going to call SSL_connect, optionally doing ACE::select and
+ // retrying the SSL_connect, until the SSL handshake is done or
+ // it fails.
+ // To get the timeout affect, set the socket to nonblocking mode
+ // before beginning if there is a timeout specified. If the timeout
+ // is 0 (wait as long as it takes) then don't worry about the blocking
+ // status; we'll block in SSL_connect if the socket is blocking, and
+ // block in ACE::select if not.
+ int reset_blocking_mode = 0;
+ if (timeout != 0)
+ {
+ reset_blocking_mode = ACE_BIT_DISABLED (ACE::get_flags (handle),
+ ACE_NONBLOCK);
+ // Set the handle into non-blocking mode if it's not already
+ // in it.
+ if (reset_blocking_mode
+ && ACE::set_flags (handle,
+ ACE_NONBLOCK) == -1)
+ return -1;
+ }
+
+ ACE_Time_Value t;
+ if (timeout != 0)
+ t = *timeout; // Need a non-const copy.
+
+ // Take into account the time between each select() call below.
+ ACE_Countdown_Time countdown ((timeout == 0 ? 0 : &t));
+
+ int status;
+
+ do
+ {
+ // These handle sets are used to set up for whatever SSL_connect
+ // says it wants next. They're reset on each pass around the loop.
+ ACE_Handle_Set rd_handle;
+ ACE_Handle_Set wr_handle;
+
+ status = ::SSL_connect (ssl);
+ switch (::SSL_get_error (ssl, status))
+ {
+ case SSL_ERROR_NONE:
+ // Start out with non-blocking disabled on the SSL stream.
+ new_stream.disable (ACE_NONBLOCK);
+ status = 0; // To tell caller about success
+ break; // Done
+
+ case SSL_ERROR_WANT_WRITE:
+ wr_handle.set_bit (handle);
+ status = 1; // Wait for more activity
+ break;
+
+ case SSL_ERROR_WANT_READ:
+ rd_handle.set_bit (handle);
+ status = 1; // Wait for more activity
+ break;
+
+ case SSL_ERROR_ZERO_RETURN:
+ // The peer has notified us that it is shutting down via
+ // the SSL "close_notify" message so we need to
+ // shutdown, too.
+ status = -1;
+ break;
+
+ case SSL_ERROR_SYSCALL:
+ // On some platforms (e.g. MS Windows) OpenSSL does not
+ // store the last error in errno so explicitly do so.
+ //
+ // Explicitly check for EWOULDBLOCK since it doesn't get
+ // converted to an SSL_ERROR_WANT_{READ,WRITE} on some
+ // platforms. If SSL_connect failed outright, though, don't
+ // bother checking more. This can happen if the socket gets
+ // closed during the handshake.
+ if (ACE_OS::set_errno_to_last_error () == EWOULDBLOCK &&
+ status == -1)
+ {
+ // Although the SSL_ERROR_WANT_READ/WRITE isn't getting
+ // set correctly, the read/write state should be valid.
+ // Use that to decide what to do.
+ status = 1; // Wait for more activity
+ if (SSL_want_write (ssl))
+ {
+ wr_handle.set_bit (handle);
+ }
+ else if (SSL_want_read (ssl))
+ {
+ rd_handle.set_bit (handle);
+ }
+ else
+ {
+ status = -1; // Doesn't want anything - bail out
+ }
+ }
+ else
+ {
+ status = -1;
+ }
+ break;
+
+ default:
+ ACE_SSL_Context::report_error ();
+ status = -1;
+ break;
+ }
+
+ if (status == 1)
+ {
+ // Must have at least one handle to wait for at this point.
+ ACE_ASSERT (rd_handle.num_set () == 1 || wr_handle.num_set () == 1);
+
+ // Block indefinitely if timeout pointer is zero.
+ status = ACE::select (int (handle) + 1,
+ &rd_handle,
+ &wr_handle,
+ 0,
+ (timeout == 0 ? 0 : &t));
+
+ (void) countdown.update ();
+
+ // 0 is timeout, so we're done.
+ // -1 is error, so we're done.
+ // Could be both handles set (same handle in both masks) so set to 1.
+ if (status >= 1)
+ {
+ status = 1;
+ }
+ else // Timeout or socket failure
+ {
+ status = -1;
+ }
+ }
+
+ } while (status == 1 && !SSL_is_init_finished (ssl));
+
+ if (reset_blocking_mode)
+ {
+ ACE_Errno_Guard eguard (errno);
+ ACE::clr_flags (handle, ACE_NONBLOCK);
+ }
+
+ return (status == -1 ? -1 : 0);
+ }
+
+ int
+ SSL_Proxy_Connector::connect (ACE_SSL_SOCK_Stream &new_stream,
+ ACE_HANDLE proxy_handle,
+ const ACE_Time_Value *timeout)
+ {
+ INET_TRACE ("SSL_Proxy_Connector::connect");
+
+ if (new_stream.get_handle () != ACE_INVALID_HANDLE)
+ return -1; // SSL already connected, somebody made a mistake here
+
+ // Set the handle from the established proxy connection in the
+ // SSL_SOCK_Stream.
+ new_stream.set_handle (proxy_handle);
+
+ // Finalize the connection by performing the SSL handshake
+ int result = this->ssl_connect (new_stream, timeout);
+
+ if (result == -1)
+ new_stream.close ();
+
+ return result;
+ }
+
+ }
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/protocols/ace/INet/SSL_Proxy_Connector.h b/ACE/protocols/ace/INet/SSL_Proxy_Connector.h
new file mode 100644
index 00000000000..501e22401ee
--- /dev/null
+++ b/ACE/protocols/ace/INet/SSL_Proxy_Connector.h
@@ -0,0 +1,60 @@
+// $Id$
+
+/**
+ * @file SSL_Proxy_Connector.h
+ *
+ * @author Martin Corino <mcorino@remedy.nl>
+ */
+
+#ifndef ACE_SSL_PROXY_CONNECTOR_H
+#define ACE_SSL_PROXY_CONNECTOR_H
+
+#include /**/ "ace/pre.h"
+
+#include "ace/SSL/SSL_SOCK_Stream.h"
+#include "ace/Time_Value.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace ACE
+ {
+ namespace INet
+ {
+ /**
+ * @class ACE_INet_SSL_Proxy_Connector
+ *
+ * @brief Provides the functionality to attach an SSL_SOCK_Stream
+ * to an established socket of a proxy tunneling service.
+ *
+ * The <connect> method will finalize the setting up an SSL connection
+ * over the tunnel by performing an SSL handhake after setting the socket
+ * in the @c SSL_SOCK_Stream.
+ */
+ class SSL_Proxy_Connector
+ {
+ public:
+ SSL_Proxy_Connector ();
+ ~SSL_Proxy_Connector ();
+
+ /**
+ * Actively connect to an already connected proxy peer, producing a
+ * connected @c ACE_SSL_SOCK_Stream object if the connection succeeds.
+ * This method uses the provided connection (socket) handle to initialize
+ * the @c ACE_SSL_SOCK_Stream object and than finalizes the connection
+ * by performing the SSL handshake.
+ */
+ int connect (ACE_SSL_SOCK_Stream& new_stream,
+ ACE_HANDLE proxy_handle,
+ const ACE_Time_Value *timeout = 0);
+ protected:
+ /// Complete non-blocking SSL active connection.
+ int ssl_connect (ACE_SSL_SOCK_Stream &new_stream,
+ const ACE_Time_Value *timeout);
+ };
+ }
+ }
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+#endif /* ACE_SSL_PROXY_CONNECTOR_H */
diff --git a/ACE/protocols/ace/INet/SSL_X509Cert.cpp b/ACE/protocols/ace/INet/SSL_X509Cert.cpp
new file mode 100644
index 00000000000..44845a70352
--- /dev/null
+++ b/ACE/protocols/ace/INet/SSL_X509Cert.cpp
@@ -0,0 +1,18 @@
+// $Id$
+
+#include "ace/INet/SSL_X509Cert.h"
+
+#if !defined (__ACE_INLINE__)
+#include "ace/INet/SSL_X509Cert.inl"
+#endif
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace ACE
+{
+ namespace INet
+ {
+ }
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/protocols/ace/INet/SSL_X509Cert.h b/ACE/protocols/ace/INet/SSL_X509Cert.h
new file mode 100644
index 00000000000..250c8c8e19c
--- /dev/null
+++ b/ACE/protocols/ace/INet/SSL_X509Cert.h
@@ -0,0 +1,57 @@
+// $Id$
+
+/**
+ * @file SSL_X509Cert.h
+ *
+ * @author Martin Corino <mcorino@remedy.nl>
+ */
+
+#ifndef ACE_SSL_X509CERT_H
+#define ACE_SSL_X509CERT_H
+
+#include /**/ "ace/pre.h"
+
+#include <openssl/x509.h>
+#include <openssl/crypto.h>
+#include "ace/INet/INet_Export.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace ACE
+ {
+ namespace INet
+ {
+ /**
+ * @class ACE_INet_SSL_X509Cert
+ *
+ * @brief Encapsulates an SSL X509 certificate object.
+ *
+ * Provides reference counting for the X509 certificate object.
+ */
+ class ACE_INET_Export SSL_X509Cert
+ {
+ public:
+ SSL_X509Cert ();
+ SSL_X509Cert (::X509* ssl_cert);
+ SSL_X509Cert (const SSL_X509Cert& cert);
+ ~SSL_X509Cert ();
+
+ SSL_X509Cert& operator= (::X509* ssl_cert);
+ SSL_X509Cert& operator= (const SSL_X509Cert& ssl_cert);
+
+ ::X509* operator & (void);
+
+ private:
+ ::X509* ssl_cert_;
+ };
+ }
+ }
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#if defined (__ACE_INLINE__)
+#include "ace/INet/SSL_X509Cert.inl"
+#endif
+
+#include /**/ "ace/post.h"
+#endif /* ACE_SSL_X509CERT_H */
diff --git a/ACE/protocols/ace/INet/SSL_X509Cert.inl b/ACE/protocols/ace/INet/SSL_X509Cert.inl
new file mode 100644
index 00000000000..0c0c0f8a88c
--- /dev/null
+++ b/ACE/protocols/ace/INet/SSL_X509Cert.inl
@@ -0,0 +1,65 @@
+// -*- C++ -*-
+//
+// $Id$
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace ACE
+{
+ namespace INet
+ {
+
+ ACE_INLINE
+ SSL_X509Cert::SSL_X509Cert ()
+ : ssl_cert_ (0)
+ {
+ }
+
+ ACE_INLINE
+ SSL_X509Cert::SSL_X509Cert (::X509* ssl_cert)
+ : ssl_cert_ (0)
+ {
+ *this = ssl_cert;
+ }
+
+ ACE_INLINE
+ SSL_X509Cert::SSL_X509Cert (const SSL_X509Cert& cert)
+ {
+ *this = cert;
+ }
+
+ ACE_INLINE
+ SSL_X509Cert::~SSL_X509Cert ()
+ {
+ }
+
+ ACE_INLINE
+ SSL_X509Cert& SSL_X509Cert::operator= (::X509* ssl_cert)
+ {
+ if (this->ssl_cert_ != 0)
+ ::X509_free (this->ssl_cert_);
+
+ if (ssl_cert != 0)
+ CRYPTO_add (&(ssl_cert->references),
+ 1,
+ CRYPTO_LOCK_X509);
+ this->ssl_cert_ = ssl_cert;
+ return *this;
+ }
+
+ ACE_INLINE
+ SSL_X509Cert& SSL_X509Cert::operator= (const SSL_X509Cert& ssl_cert)
+ {
+ return (*this = &(const_cast<SSL_X509Cert&> (ssl_cert)));
+ }
+
+ ACE_INLINE
+ ::X509* SSL_X509Cert::operator & (void)
+ {
+ return this->ssl_cert_;
+ }
+
+ }
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/protocols/ace/INet/StreamHandler.cpp b/ACE/protocols/ace/INet/StreamHandler.cpp
index c779692f384..083f0539296 100644
--- a/ACE/protocols/ace/INet/StreamHandler.cpp
+++ b/ACE/protocols/ace/INet/StreamHandler.cpp
@@ -160,8 +160,8 @@ namespace ACE
}
if (send_cnt <= 0)
{
- ACE_ERROR ((LM_ERROR,
- ACE_TEXT ("(%P|%t) %p; ACE_IOS_StreamHandler - "),
+ INET_ERROR (1, (LM_ERROR, DLINFO
+ ACE_TEXT ("%p; ACE_IOS_StreamHandler - "),
ACE_TEXT ("send failed\n")));
this->connected_ = false;
return this->using_reactor () ? -1 : 0;
diff --git a/ACE/protocols/ace/INet/StreamInterceptor.h b/ACE/protocols/ace/INet/StreamInterceptor.h
index 326f95b1739..94cf93125ac 100644
--- a/ACE/protocols/ace/INet/StreamInterceptor.h
+++ b/ACE/protocols/ace/INet/StreamInterceptor.h
@@ -30,7 +30,7 @@ namespace ACE
/**
* @class ACE_IOS_StreamInterceptorBase
*
- * @brief
+ * @brief Abstract base for stream interceptors.
*
*/
template <class ACE_CHAR_T, class TR = std::char_traits<ACE_CHAR_T> >
diff --git a/ACE/protocols/ace/INet/URLBase.h b/ACE/protocols/ace/INet/URLBase.h
index 01daed0b87f..923b6db07c1 100644
--- a/ACE/protocols/ace/INet/URLBase.h
+++ b/ACE/protocols/ace/INet/URLBase.h
@@ -32,8 +32,11 @@ namespace ACE
/**
* @class ACE_INet_URLStream
*
- * @brief
+ * @brief Provides abstracted wrapper class for the resulting
+ * stream of an URL <open> operation.
*
+ * Provides proper life cycle management for either factory provided
+ * or user provided request handlers.
*/
class ACE_INET_Export URLStream
{
@@ -142,7 +145,7 @@ namespace ACE
private:
typedef ACE_Map_Manager<ACE_CString,
Factory*,
- ACE_SYNCH::RECURSIVE_MUTEX> TURLFactoryMap;
+ ACE_SYNCH::MUTEX> TURLFactoryMap;
typedef ACE_Singleton<TURLFactoryMap,
ACE_SYNCH::NULL_MUTEX> TURLFactorySingleton;
static TURLFactoryMap* factories_;
diff --git a/ACE/protocols/ace/INet/inet.mpc b/ACE/protocols/ace/INet/inet.mpc
index 16e08e5a92c..a15427f79c0 100644
--- a/ACE/protocols/ace/INet/inet.mpc
+++ b/ACE/protocols/ace/INet/inet.mpc
@@ -1,7 +1,7 @@
// -*- MPC -*-
// $Id$
-project(INet) : acelib, ace_output, install {
+project(INet) : acelib, ace_output, install, inet_ssl {
sharedname = ACE_INet
dynamicflags += ACE_INET_BUILD_DLL
includes += $(ACE_ROOT)/protocols
@@ -21,6 +21,7 @@ project(INet) : acelib, ace_output, install {
HTTP_Response.cpp
HTTP_Request.cpp
HTTP_IOStream.cpp
+ HTTP_SessionBase.cpp
URLBase.cpp
AuthenticationBase.cpp
HTTP_URL.cpp
diff --git a/ACE/protocols/ace/INet/inet_ssl.mpb b/ACE/protocols/ace/INet/inet_ssl.mpb
new file mode 100644
index 00000000000..5442cfaedd5
--- /dev/null
+++ b/ACE/protocols/ace/INet/inet_ssl.mpb
@@ -0,0 +1,18 @@
+feature(ssl) : ace_openssl {
+ Source_Files {
+ SSL_X509Cert.cpp
+ SSL_CertificateCallback.cpp
+ SSL_PasswordCallback.cpp
+ SSL_CallbackManager.cpp
+ HTTPS_Context.cpp
+ HTTPS_URL.cpp
+ HTTPS_SessionFactory.cpp
+ SSL_Proxy_Connector.cpp
+ }
+ Template_Files {
+ SSLSock_IOStream.cpp
+ HTTPS_Session.cpp
+ }
+ Header_Files {
+ }
+}
diff --git a/ACE/protocols/tests/INet/MT_Get/Main.cpp b/ACE/protocols/tests/INet/MT_Get/Main.cpp
index e24c831bee6..a106c5e6fab 100644
--- a/ACE/protocols/tests/INet/MT_Get/Main.cpp
+++ b/ACE/protocols/tests/INet/MT_Get/Main.cpp
@@ -37,8 +37,10 @@ Get_Task::Get_Task (ACE_Thread_Manager *thr_mgr,
n_threads_ (n_threads)
{
// Create worker threads.
- if (this->activate (THR_NEW_LWP, n_threads) == -1)
+ if (this->activate (THR_NEW_LWP, n_threads_) == -1)
ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("activate failed")));
+ else
+ ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%P|%t) started %d threads\n"), n_threads_));
}
void Get_Task::shutdown ()
@@ -48,7 +50,7 @@ void Get_Task::shutdown ()
lock_);
--n_threads_;
- if (n_threads_ >= 0)
+ if (n_threads_ <= 0)
{
ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%P|%t) ending event loop\n")));
ACE_Reactor::instance ()->end_event_loop ();
@@ -178,7 +180,7 @@ void Get_MultiTask::shutdown ()
lock_);
--n_threads_;
- if (n_threads_ >= 0)
+ if (n_threads_ <= 0)
{
ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%P|%t) ending event loop\n")));
ACE_Reactor::instance ()->end_event_loop ();