You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axis-cvs@ws.apache.org by na...@apache.org on 2009/11/11 22:05:30 UTC
svn commit: r835067 - in /webservices/axis/trunk/c/src/transport/axis3:
HTTPChannel/HTTPChannel.cpp HTTPChannel/HTTPChannel.hpp
HTTPSSLChannel/HTTPSSLChannel.cpp HTTPSSLChannel/HTTPSSLChannel.hpp
HTTPTransport.cpp HTTPTransport.hpp IChannel.hpp
Author: nadiramra
Date: Wed Nov 11 21:05:30 2009
New Revision: 835067
URL: http://svn.apache.org/viewvc?rev=835067&view=rev
Log:
AXISCPP-899 Tunnel https connections over http proxies
Modified:
webservices/axis/trunk/c/src/transport/axis3/HTTPChannel/HTTPChannel.cpp
webservices/axis/trunk/c/src/transport/axis3/HTTPChannel/HTTPChannel.hpp
webservices/axis/trunk/c/src/transport/axis3/HTTPSSLChannel/HTTPSSLChannel.cpp
webservices/axis/trunk/c/src/transport/axis3/HTTPSSLChannel/HTTPSSLChannel.hpp
webservices/axis/trunk/c/src/transport/axis3/HTTPTransport.cpp
webservices/axis/trunk/c/src/transport/axis3/HTTPTransport.hpp
webservices/axis/trunk/c/src/transport/axis3/IChannel.hpp
Modified: webservices/axis/trunk/c/src/transport/axis3/HTTPChannel/HTTPChannel.cpp
URL: http://svn.apache.org/viewvc/webservices/axis/trunk/c/src/transport/axis3/HTTPChannel/HTTPChannel.cpp?rev=835067&r1=835066&r2=835067&view=diff
==============================================================================
--- webservices/axis/trunk/c/src/transport/axis3/HTTPChannel/HTTPChannel.cpp (original)
+++ webservices/axis/trunk/c/src/transport/axis3/HTTPChannel/HTTPChannel.cpp Wed Nov 11 21:05:30 2009
@@ -134,7 +134,7 @@
*/
bool HTTPChannel::
-open() throw (HTTPTransportException&)
+open()
{
logEntryTransport("HTTPChannel::open")
Modified: webservices/axis/trunk/c/src/transport/axis3/HTTPChannel/HTTPChannel.hpp
URL: http://svn.apache.org/viewvc/webservices/axis/trunk/c/src/transport/axis3/HTTPChannel/HTTPChannel.hpp?rev=835067&r1=835066&r2=835067&view=diff
==============================================================================
--- webservices/axis/trunk/c/src/transport/axis3/HTTPChannel/HTTPChannel.hpp (original)
+++ webservices/axis/trunk/c/src/transport/axis3/HTTPChannel/HTTPChannel.hpp Wed Nov 11 21:05:30 2009
@@ -69,7 +69,7 @@
const char * getURL();
virtual void setURL( const char * cpURL);
virtual URL & getURLObject();
- bool open() throw (HTTPTransportException&);
+ bool open();
bool close();
const std::string & GetLastErrorMsg();
int readBytes(char *buf, int bufLen);
Modified: webservices/axis/trunk/c/src/transport/axis3/HTTPSSLChannel/HTTPSSLChannel.cpp
URL: http://svn.apache.org/viewvc/webservices/axis/trunk/c/src/transport/axis3/HTTPSSLChannel/HTTPSSLChannel.cpp?rev=835067&r1=835066&r2=835067&view=diff
==============================================================================
--- webservices/axis/trunk/c/src/transport/axis3/HTTPSSLChannel/HTTPSSLChannel.cpp (original)
+++ webservices/axis/trunk/c/src/transport/axis3/HTTPSSLChannel/HTTPSSLChannel.cpp Wed Nov 11 21:05:30 2009
@@ -143,7 +143,7 @@
*/
bool HTTPSSLChannel::
-open() throw (HTTPTransportException&)
+open()
{
bool bSuccess = (bool) AXIS_FAIL;
@@ -276,6 +276,193 @@
}
/**
+ * HTTPSSLChannel::writeProxyConnect()
+ *
+ * This method writes the CONNECT method unencrypted to the open channel.
+ *
+ * Based off the "CONNECT" method (http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.9),
+ * part of "Hypertext Transfer Protocol -- HTTP/1.1" (http://www.w3.org/Protocols/rfc2616/rfc2616.html)
+ *
+ * "Tunneling SSL Through a WWW Proxy"
+ * by Ari Luotonen, December 14, 1995
+ * http://muffin.doit.org/docs/rfc/tunneling_ssl.html
+ *
+ * "Tunneling TCP based protocols through Web proxy servers"
+ * by Ari Luotonen, August 1998
+ * http://www.web-cache.com/Writings/Internet-Drafts/draft-luotonen-web-proxy-tunneling-01.txt
+ *
+ * SSL tunneling patch for CERN httpd
+ * http://www.w3.org/Daemon/User/Patch/SSL.patch
+ *
+ *
+ * @param buf Character pointer pointing to the array of character containing the message to be transmitted.
+ * @param numBytes The number of bytes in the message to be transmitted.
+ * @return The number of bytes sent.
+ */
+bool HTTPSSLChannel::
+proxyConnect()
+{
+ // return value, default to failure
+ bool bSuccess = (bool)AXIS_FAIL;
+
+ // request a CONNECT to the server
+ int nBytesSent = writeProxyConnect();
+
+ // variables needed for recieving data
+ int iHTTPStatus = 100;
+ int iBytesReceived = 0;
+ int iBytesLeft = 0;
+ char rxBuffer[BUF_SIZE];
+ string strBytesReceived;
+ string strResponseHTTPHeaders;
+
+ // loop while the response is valid
+ do
+ {
+ while (strBytesReceived.find(ASCII_S_HTTP) == std::string::npos
+ || strBytesReceived.find(ASCII_S_CRLFCRLF) == std::string::npos)
+ {
+ iBytesReceived = readProxyConnect(rxBuffer, BUF_SIZE);
+
+ if (iBytesReceived > 0)
+ {
+ strBytesReceived += rxBuffer;
+ iBytesLeft = strBytesReceived.length();
+ }
+ else
+ {
+ throw HTTPTransportException(SERVER_TRANSPORT_INPUT_STREAMING_ERROR,
+ "Socket connection has been closed.");
+ }
+ }
+
+ // At this point the HTTP header has been found. Seperate the response headers
+ // from the payload (i.e. SOAP message).
+ string::size_type iHTTPStart = strBytesReceived.find(ASCII_S_HTTP);
+ string::size_type iHTTPEnd = strBytesReceived.find(ASCII_S_CRLFCRLF, iHTTPStart);
+
+ strResponseHTTPHeaders = strBytesReceived.substr(iHTTPStart, iHTTPEnd + 4 - iHTTPStart);
+
+ // Process the HTTP header
+ PLATFORM_ASCTOSTR(strBytesReceived.c_str());
+ string strHTTPStatus = strBytesReceived.substr(strlen("HTTP/1.x "), 3);
+ iHTTPStatus = atoi(strHTTPStatus.c_str());
+ }
+ while(iHTTPStatus == 100);
+
+ // Now have a valid HTTP header that is not 100. Throw an exception if some unexpected error.
+ // Note that error 500 are for for SOAP faults.
+ if (iHTTPStatus != 500 && (iHTTPStatus < 200 || iHTTPStatus >= 300))
+ {
+ throw HTTPTransportException(SERVER_TRANSPORT_HTTP_EXCEPTION, "Server sent HTTP error: \n");
+ }
+ if (iHTTPStatus == 200)
+ {
+ bSuccess = (bool)AXIS_SUCCESS;
+ }
+ return bSuccess;
+}
+
+int HTTPSSLChannel::
+writeProxyConnect()
+{
+ // send buffer
+ char buf[1024];
+
+ // server port, not proxy port
+ unsigned int uiPort = m_URL.getPort();
+
+ // the header should look liks this:
+ // CONNECT home1.netscape.com:443 HTTP/1.0
+ sprintf(buf, "CONNECT %s:%u HTTP/1.1\r\n\r\n", m_URL.getHostName(), uiPort);
+
+ // get the number of bytes, needed for send()
+ int numBytes = strlen(buf);
+
+ //
+ // SEND THE CONNECT
+ //
+ if (INVALID_SOCKET == m_Sock)
+ {
+ m_LastError = "No valid socket to perform write operation.";
+ throw HTTPTransportException( SERVER_TRANSPORT_INVALID_SOCKET, m_LastError.c_str());
+ }
+
+ int nByteSent = 0;
+
+ if ((nByteSent = send( m_Sock, buf, numBytes, 0)) == SOCKET_ERROR)
+ {
+ // This must be done first before closing channel in order to get actual error.
+ m_LastError = "Error sending data.";
+
+ // Close the channel and throw an exception.
+ CloseChannel();
+
+ throw HTTPTransportException( SERVER_TRANSPORT_OUTPUT_STREAMING_ERROR, m_LastError.c_str());
+ }
+ return nByteSent;
+}
+
+int HTTPSSLChannel::
+readProxyConnect(char* buf, int bufLen)
+{
+ //
+ // RECEIVE THE CONNECT
+ //
+ if (INVALID_SOCKET == m_Sock)
+ {
+ m_LastError = "Unable to perform read operation.";
+ throw HTTPTransportException( SERVER_TRANSPORT_INVALID_SOCKET, m_LastError.c_str());
+ }
+
+ int nByteRecv = 0;
+ int iBufSize = bufLen - 10;
+
+ // If timeout set then wait for maximum amount of time for data
+ if (m_lTimeoutSeconds)
+ {
+ int iTimeoutStatus = applyTimeout();
+
+ // Handle timeout outcome
+ if (iTimeoutStatus < 0)
+ {
+ throw HTTPTransportException( SERVER_TRANSPORT_TIMEOUT_EXCEPTION, m_LastError.c_str());
+ }
+
+ if (iTimeoutStatus == 0)
+ {
+ m_LastError = "Read operation timed-out while waiting for data.";
+ throw HTTPTransportException( SERVER_TRANSPORT_TIMEOUT_EXPIRED, m_LastError.c_str() );
+ }
+ }
+
+ // Either timeout was not set or data available before timeout; so read
+ nByteRecv = recv( m_Sock, buf, iBufSize, 0);
+ if (nByteRecv == SOCKET_ERROR)
+ {
+ // This must be done first before closing channel in order to get actual error.
+ m_LastError = "Error receiving data.";
+
+ // Close the channel and throw an exception.
+ CloseChannel();
+
+ if(!bNoExceptionOnForceClose)
+ {
+ throw HTTPTransportException( SERVER_TRANSPORT_INPUT_STREAMING_ERROR, m_LastError.c_str());
+ }
+ }
+ else if ( 0 == nByteRecv )
+ {
+ // read-side of socket is closed.
+ }
+ else if (nByteRecv)
+ {
+ buf[nByteRecv] = '\0';
+ }
+ return nByteRecv;
+}
+
+/**
* HTTPSSLChannel::setTimeout( const long lSeconds)
*
* Set the Rx message timeout (in seconds)
@@ -569,6 +756,9 @@
setsockopt( m_Sock, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(int));
+ if(m_bUseProxy)
+ proxyConnect();
+
bSuccess = OpenSSL_Open();
return bSuccess;
Modified: webservices/axis/trunk/c/src/transport/axis3/HTTPSSLChannel/HTTPSSLChannel.hpp
URL: http://svn.apache.org/viewvc/webservices/axis/trunk/c/src/transport/axis3/HTTPSSLChannel/HTTPSSLChannel.hpp?rev=835067&r1=835066&r2=835067&view=diff
==============================================================================
--- webservices/axis/trunk/c/src/transport/axis3/HTTPSSLChannel/HTTPSSLChannel.hpp (original)
+++ webservices/axis/trunk/c/src/transport/axis3/HTTPSSLChannel/HTTPSSLChannel.hpp Wed Nov 11 21:05:30 2009
@@ -71,7 +71,7 @@
const char * getURL();
virtual void setURL( const char * cpURL);
virtual URL & getURLObject();
- bool open() throw (HTTPTransportException&);
+ bool open();
bool close();
const std::string & GetLastErrorMsg();
int readBytes(char *buf, int bufLen);
@@ -95,6 +95,9 @@
bool OpenSSL_Open();
int OpenSSL_Close();
void OpenSSL_SetSecureError( int iError);
+ bool proxyConnect();
+ int writeProxyConnect();
+ int readProxyConnect(char* buf, int bufLen);
private:
URL m_URL; // URL
Modified: webservices/axis/trunk/c/src/transport/axis3/HTTPTransport.cpp
URL: http://svn.apache.org/viewvc/webservices/axis/trunk/c/src/transport/axis3/HTTPTransport.cpp?rev=835067&r1=835066&r2=835067&view=diff
==============================================================================
--- webservices/axis/trunk/c/src/transport/axis3/HTTPTransport.cpp (original)
+++ webservices/axis/trunk/c/src/transport/axis3/HTTPTransport.cpp Wed Nov 11 21:05:30 2009
@@ -37,39 +37,6 @@
static int axtoi( char *pcHexString);
-// =================================================================
-// In order to parse the HTTP protocol data on an ebcdic system, we
-// need to ensure that the various tokens we are looking for to distinguish
-// between the HTTP headers and payload are in ASCII. So the following
-// defines for carriage return-line feed, etc. are ensured to be in ascii
-// by using ascii hexadecimal representation of the tokens.
-// =================================================================
-
-// Ascii character defines
-#define ASCII_C_EQUAL '\x3D' // '='
-#define ASCII_C_DASH '\x2D' // '-'
-#define ASCII_C_LF '\x0A' // '\n'
-#define ASCII_C_CR '\x0D' // '\r'
-#define ASCII_C_SPACE '\x20' // ' '
-#define ASCII_C_SEMI '\x3B' // ';'
-
-#define ASCII_C_LOWERCASEA '\x61' // 'a'
-#define ASCII_C_LOWERCASEF '\x66' // 'f'
-#define ASCII_C_UPPERCASEA '\x41' // 'A'
-#define ASCII_C_UPPERCASEF '\x46' // 'F'
-
-#define ASCII_C_ZERO '\x30' // '0'
-#define ASCII_C_NINE '\x39' // '9'
-
-// Ascii string defines
-#define ASCII_S_LF "\x0a" // "\n"
-#define ASCII_S_CRLF "\x0d\x0a" // "\r\n"
-#define ASCII_S_CRLFCRLF "\x0d\x0a\x0d\x0a" // "\r\n\r\n"
-
-#define ASCII_S_HTTP "\x48\x54\x54\x50" // "HTTP"
-
-#define ASCII_S_LEFTPAREN "\x28" // "("
-
/*
* HTTPTransport constuctor
*/
Modified: webservices/axis/trunk/c/src/transport/axis3/HTTPTransport.hpp
URL: http://svn.apache.org/viewvc/webservices/axis/trunk/c/src/transport/axis3/HTTPTransport.hpp?rev=835067&r1=835066&r2=835067&view=diff
==============================================================================
--- webservices/axis/trunk/c/src/transport/axis3/HTTPTransport.hpp (original)
+++ webservices/axis/trunk/c/src/transport/axis3/HTTPTransport.hpp Wed Nov 11 21:05:30 2009
@@ -60,13 +60,13 @@
* e.g. http://localhost:8080/axis/services/echo
*/
void setEndpointUri( const char * pszEndpointURI) throw (HTTPTransportException);
- int openConnection();
+ int openConnection();
void closeConnection(bool forceClose=true);
- AXIS_TRANSPORT_STATUS sendBytes( const char *, const void *);
- AXIS_TRANSPORT_STATUS getBytes( char *, int *) throw (AxisException, HTTPTransportException);
- int setTransportProperty( AXIS_TRANSPORT_INFORMATION_TYPE, const char *) throw (HTTPTransportException);
+ AXIS_TRANSPORT_STATUS sendBytes( const char *, const void *);
+ AXIS_TRANSPORT_STATUS getBytes( char *, int *) throw (AxisException, HTTPTransportException);
+ int setTransportProperty( AXIS_TRANSPORT_INFORMATION_TYPE, const char *) throw (HTTPTransportException);
const char * getTransportProperty( AXIS_TRANSPORT_INFORMATION_TYPE) throw (HTTPTransportException);
- int setTransportProperty( const char *, const char *) throw (HTTPTransportException);
+ int setTransportProperty( const char *, const char *) throw (HTTPTransportException);
const char * getTransportProperty( const char * pcKey, bool response=true) throw (HTTPTransportException);
void setSessionId( const char * pcSessionId);
const char * getSessionId();
@@ -84,9 +84,9 @@
*
* @return AXIS_SUCCESS if the set worked and the protocol is supported AXIS_FAIL otherwise
*/
- int setProtocol( AXIS_PROTOCOL_TYPE eProtocol);
- int getSubProtocol();
- AXIS_TRANSPORT_STATUS flushOutput() throw (AxisException, HTTPTransportException);
+ int setProtocol( AXIS_PROTOCOL_TYPE eProtocol);
+ int getSubProtocol();
+ AXIS_TRANSPORT_STATUS flushOutput() throw (AxisException, HTTPTransportException);
void setProxy( const char *pcProxyHost, unsigned int uiProxyPort);
void setTimeout( long lSeconds);
const char * getHTTPProtocol();
@@ -103,9 +103,9 @@
virtual void setMaintainSession( bool bSession);
void setAttachment( const char * pcAttachmentId, const char * pcAttachment) {};
- ISoapAttachment * getAttachment( const char * pcAttachmentId) { return NULL;};
+ ISoapAttachment * getAttachment( const char * pcAttachmentId) { return NULL;};
ISoapAttachment** getAllAttachments(int *pAttchArraySize) { return NULL;};
- char * getIncomingSOAPMimeHeaders() {return NULL;}
+ char * getIncomingSOAPMimeHeaders() {return NULL;}
const char * getLastChannelError();
void enableTrace(const char* logFilePath, const char *filters);
@@ -115,7 +115,7 @@
void processMimeHeader();
void processMimeBody();
void getAttachment( char* pStrAttachment, int* pIntSize, int intAttachmentId);
- int FindTransportPropertyIndex( std::string);
+ int FindTransportPropertyIndex( std::string);
void readHTTPHeader();
void processHTTPHeader();
int getNextDataPacket( const char * pcszExceptionMessage, char *bufferToUse=NULL, int *bufferLen=NULL);
Modified: webservices/axis/trunk/c/src/transport/axis3/IChannel.hpp
URL: http://svn.apache.org/viewvc/webservices/axis/trunk/c/src/transport/axis3/IChannel.hpp?rev=835067&r1=835066&r2=835067&view=diff
==============================================================================
--- webservices/axis/trunk/c/src/transport/axis3/IChannel.hpp (original)
+++ webservices/axis/trunk/c/src/transport/axis3/IChannel.hpp Wed Nov 11 21:05:30 2009
@@ -32,6 +32,39 @@
AXIS_CPP_NAMESPACE_USE
+// =================================================================
+// In order to parse the HTTP protocol data on an ebcdic system, we
+// need to ensure that the various tokens we are looking for to distinguish
+// between the HTTP headers and payload are in ASCII. So the following
+// defines for carriage return-line feed, etc. are ensured to be in ascii
+// by using ascii hexadecimal representation of the tokens.
+// =================================================================
+
+// Ascii character defines
+#define ASCII_C_EQUAL '\x3D' // '='
+#define ASCII_C_DASH '\x2D' // '-'
+#define ASCII_C_LF '\x0A' // '\n'
+#define ASCII_C_CR '\x0D' // '\r'
+#define ASCII_C_SPACE '\x20' // ' '
+#define ASCII_C_SEMI '\x3B' // ';'
+
+#define ASCII_C_LOWERCASEA '\x61' // 'a'
+#define ASCII_C_LOWERCASEF '\x66' // 'f'
+#define ASCII_C_UPPERCASEA '\x41' // 'A'
+#define ASCII_C_UPPERCASEF '\x46' // 'F'
+
+#define ASCII_C_ZERO '\x30' // '0'
+#define ASCII_C_NINE '\x39' // '9'
+
+// Ascii string defines
+#define ASCII_S_LF "\x0a" // "\n"
+#define ASCII_S_CRLF "\x0d\x0a" // "\r\n"
+#define ASCII_S_CRLFCRLF "\x0d\x0a\x0d\x0a" // "\r\n\r\n"
+
+#define ASCII_S_HTTP "\x48\x54\x54\x50" // "HTTP"
+
+#define ASCII_S_LEFTPAREN "\x28" // "("
+
enum g_ChannelType
{
UnsecureChannel,
@@ -46,7 +79,7 @@
virtual const char* getURL()=0;
virtual void setURL( const char* cpURL)=0;
virtual URL & getURLObject()=0;
- virtual bool open() throw (HTTPTransportException&)=0;
+ virtual bool open()=0;
virtual bool close()=0;
virtual const std::string& GetLastErrorMsg()=0;
virtual int readBytes(char *buf, int bufLen)=0;