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;