You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-commits@axis.apache.org by na...@apache.org on 2010/04/03 07:11:10 UTC
svn commit: r930475 - in /axis/axis1/c/trunk: include/axis/
include/axis/client/ src/cbindings/client/ src/engine/client/ src/soap/
src/transport/axis3/
Author: nadiramra
Date: Sat Apr 3 05:11:09 2010
New Revision: 930475
URL: http://svn.apache.org/viewvc?rev=930475&view=rev
Log:
AXISCPP-1068 - Support http redirects
Modified:
axis/axis1/c/trunk/include/axis/AxisException.h
axis/axis1/c/trunk/include/axis/AxisException.hpp
axis/axis1/c/trunk/include/axis/GDefine.h
axis/axis1/c/trunk/include/axis/GDefine.hpp
axis/axis1/c/trunk/include/axis/client/Stub.h
axis/axis1/c/trunk/src/cbindings/client/StubC.cpp
axis/axis1/c/trunk/src/engine/client/Stub.cpp
axis/axis1/c/trunk/src/soap/SoapFault.cpp
axis/axis1/c/trunk/src/transport/axis3/HTTPTransport.cpp
axis/axis1/c/trunk/src/transport/axis3/HTTPTransport.hpp
Modified: axis/axis1/c/trunk/include/axis/AxisException.h
URL: http://svn.apache.org/viewvc/axis/axis1/c/trunk/include/axis/AxisException.h?rev=930475&r1=930474&r2=930475&view=diff
==============================================================================
--- axis/axis1/c/trunk/include/axis/AxisException.h (original)
+++ axis/axis1/c/trunk/include/axis/AxisException.h Sat Apr 3 05:11:09 2010
@@ -382,12 +382,18 @@ typedef enum
* AxiscConfigException:configuration defaults have already been set
*/
/*74*/ CONFIG_DEFAULTS_ALREADY_SET,
+
+ /**
+ * HTTPTransportException: Redirect received
+ */
+/*75*/ SERVER_TRANSPORT_REDIRECT_RECEIVED,
+
/*
* This FAULT_LAST is not used as a fault code, but instead is used
* internaly in the code. Developers should not use this as a fault
* code.
*/
-/*75*/ FAULT_LAST
+/*76*/ FAULT_LAST
} AXISC_AXISC_EXCEPTIONS;
/**
Modified: axis/axis1/c/trunk/include/axis/AxisException.hpp
URL: http://svn.apache.org/viewvc/axis/axis1/c/trunk/include/axis/AxisException.hpp?rev=930475&r1=930474&r2=930475&view=diff
==============================================================================
--- axis/axis1/c/trunk/include/axis/AxisException.hpp (original)
+++ axis/axis1/c/trunk/include/axis/AxisException.hpp Sat Apr 3 05:11:09 2010
@@ -71,13 +71,13 @@ typedef enum
* it's fault code is CLIENT
*SERVER at the beginning means when this interpreted as a soap fault
* it's fault code is SERVER
- *SOAP that comes next to CLIENT/SERVER means this is a soap releated
+ *SOAP that comes next to CLIENT/SERVER means this is a soap related
* exception
*ENGINE that comes next to CLIENT/SERVER means this is a axisc++ engine
* related exception
- *WSDD that comes next to CLIENT/SERVER means this is a wsdd releated
+ *WSDD that comes next to CLIENT/SERVER means this is a wsdd related
* exception
- *TRANSPORT that comes next to CLIENT/SERVER means this is a transport releated
+ *TRANSPORT that comes next to CLIENT/SERVER means this is a transport related
* exception
*CONFIG that comes next to CLIENT/SERVER means this is a axisc++ configuration
* related exception
@@ -388,18 +388,24 @@ typedef enum
/*73*/ AXISC_READ_CONF_EXCEPTION,
/* CONFIG faults */
- /*Following exceptions are releated to configuration faults
+ /*Following exceptions are related to configuration faults
*/
/**
* AxisConfigException:configuration defaults have already been set
*/
/*74*/ CONFIG_DEFAULTS_ALREADY_SET,
+
+ /**
+ * HTTPTransportException: Redirect received
+ */
+/*75*/ SERVER_TRANSPORT_REDIRECT_RECEIVED,
+
/*
* This FAULT_LAST is not used as a fault code, but instead is used
* internaly in the code. Developers should not use this as a fault
* code.
*/
-/*75*/ FAULT_LAST
+/*76*/ FAULT_LAST
} AXISC_EXCEPTIONS;
/**
Modified: axis/axis1/c/trunk/include/axis/GDefine.h
URL: http://svn.apache.org/viewvc/axis/axis1/c/trunk/include/axis/GDefine.h?rev=930475&r1=930474&r2=930475&view=diff
==============================================================================
--- axis/axis1/c/trunk/include/axis/GDefine.h (original)
+++ axis/axis1/c/trunk/include/axis/GDefine.h Sat Apr 3 05:11:09 2010
@@ -173,7 +173,21 @@ typedef enum
/**
* Content type
*/
- AXISC_CONTENT_TYPE
+ AXISC_CONTENT_TYPE,
+
+ /**
+ * Whether redirect should be handled implicitly. Values can be "true" or "false".
+ * The default is true. Redirects will only be implicitly be handled if going from
+ * http:// to http:// or https:// to https://.
+ */
+ AXISC_ENABLE_AUTOMATIC_REDIRECT,
+
+ /**
+ * Maximum number of automatic redirects to follow. Property should be a numeric string.
+ * Default is 1. If "0" is specified, it will be as if AXISC_ENABLE_AUTOMATIC_REDIRECT is set to
+ * false.
+ */
+ AXISC_MAX_AUTOMATIC_REDIRECT
} AXISC_TRANSPORT_INFORMATION_TYPE;
#define AXISC_SOAPACTIONHEADER "SOAPAction"
Modified: axis/axis1/c/trunk/include/axis/GDefine.hpp
URL: http://svn.apache.org/viewvc/axis/axis1/c/trunk/include/axis/GDefine.hpp?rev=930475&r1=930474&r2=930475&view=diff
==============================================================================
--- axis/axis1/c/trunk/include/axis/GDefine.hpp (original)
+++ axis/axis1/c/trunk/include/axis/GDefine.hpp Sat Apr 3 05:11:09 2010
@@ -195,7 +195,22 @@ typedef enum
/**
* Content type
*/
- CONTENT_TYPE
+ CONTENT_TYPE,
+
+ /**
+ * Whether redirect should be handled implicitly. Values can be "true" or "false".
+ * The default is false. Redirects will only be implicitly be handled if going from
+ * http:// to http:// or https:// to https://.
+ */
+ ENABLE_AUTOMATIC_REDIRECT,
+
+ /**
+ * Maximum number of automatic redirects to follow. Property should be a numeric string.
+ * Default is 1. If "0" is specified, it will be as if ENABLE_AUTOMATIC_REDIRECT is set to
+ * false.
+ */
+ MAX_AUTOMATIC_REDIRECT
+
} AXIS_TRANSPORT_INFORMATION_TYPE;
#define SOAPACTIONHEADER "SOAPAction"
Modified: axis/axis1/c/trunk/include/axis/client/Stub.h
URL: http://svn.apache.org/viewvc/axis/axis1/c/trunk/include/axis/client/Stub.h?rev=930475&r1=930474&r2=930475&view=diff
==============================================================================
--- axis/axis1/c/trunk/include/axis/client/Stub.h (original)
+++ axis/axis1/c/trunk/include/axis/client/Stub.h Sat Apr 3 05:11:09 2010
@@ -550,6 +550,25 @@ void axiscStubSetSOAPHeaders(AXISCHANDLE
AXISC_STORAGE_CLASS_INFO
void axiscStubCheckForExtraneousElements(AXISCHANDLE stub);
+/**
+ * =============
+ * Following is not in stub C++ class but is here to make things easier for C users.
+ * =============
+ */
+
+/**
+ * Indicates whether transport is to automatically handle http redirects.
+ * By default, redirects are not handled by the transport. If enabled,
+ * auto-redirect will only occur when going from http to http or https to https.
+ *
+ * @param handleRedirect false=no auto-redirect. true=handle redirect automatically.
+ * @param maxCount how many redirects to follow. Default is 1. A value less than 1
+ * is the same as setting handleRedirect to false.
+ *
+ * @return 0=success; non-zero is failure.
+ */
+AXISC_STORAGE_CLASS_INFO
+void axiscStubSetTransportAutoRedirect(AXISCHANDLE stub, AxiscBool handleRedirect, int maxCount);
#ifdef __cplusplus
}
Modified: axis/axis1/c/trunk/src/cbindings/client/StubC.cpp
URL: http://svn.apache.org/viewvc/axis/axis1/c/trunk/src/cbindings/client/StubC.cpp?rev=930475&r1=930474&r2=930475&view=diff
==============================================================================
--- axis/axis1/c/trunk/src/cbindings/client/StubC.cpp (original)
+++ axis/axis1/c/trunk/src/cbindings/client/StubC.cpp Sat Apr 3 05:11:09 2010
@@ -863,6 +863,39 @@ void axiscStubCheckForExtraneousElements
}
}
+/**
+ * =============
+ * Following is not in stub C++ class but is here to make things easier for C users.
+ * =============
+ */
+
+AXISC_STORAGE_CLASS_INFO
+void axiscStubSetTransportAutoRedirect(AXISCHANDLE stub, AxiscBool handleRedirect, int maxCount)
+{
+ StubC *s = (StubC*)stub;
+
+ try
+ {
+ Call *c = s->getCallStubC();
+
+ char *propValue = handleRedirect ? "true" : "false";
+ c->setTransportProperty(ENABLE_AUTOMATIC_REDIRECT, (const char*)propValue);
+
+ char buf[100];
+ sprintf(buf, "%d", maxCount);
+ c->setTransportProperty(MAX_AUTOMATIC_REDIRECT, (const char*)buf);
+ }
+ catch ( AxisException& e )
+ {
+
+ processException(s, e.getExceptionCode(), e.what());
+ }
+ catch ( ... )
+ {
+ processException(s, -1, "Unrecognized exception thrown.");
+ }
+}
+
}
Modified: axis/axis1/c/trunk/src/engine/client/Stub.cpp
URL: http://svn.apache.org/viewvc/axis/axis1/c/trunk/src/engine/client/Stub.cpp?rev=930475&r1=930474&r2=930475&view=diff
==============================================================================
--- axis/axis1/c/trunk/src/engine/client/Stub.cpp (original)
+++ axis/axis1/c/trunk/src/engine/client/Stub.cpp Sat Apr 3 05:11:09 2010
@@ -561,7 +561,7 @@ Stub::checkForExtraneousElements ()
logEntryEngine("Stub::checkForExtraneousElements")
IWrapperSoapDeSerializer *pDeSerializer = m_pCall->getSOAPDeSerializer();
- if (pDeSerializer)
+ if (pDeSerializer && m_pTransport->isThereResponseData())
{
const char *peekedElementName = pDeSerializer->peekNextElementName();
if (0x00 != *peekedElementName)
Modified: axis/axis1/c/trunk/src/soap/SoapFault.cpp
URL: http://svn.apache.org/viewvc/axis/axis1/c/trunk/src/soap/SoapFault.cpp?rev=930475&r1=930474&r2=930475&view=diff
==============================================================================
--- axis/axis1/c/trunk/src/soap/SoapFault.cpp (original)
+++ axis/axis1/c/trunk/src/soap/SoapFault.cpp Sat Apr 3 05:11:09 2010
@@ -184,7 +184,12 @@ initialize()
/*70*/ {"AXISC", "Service thrown exception", "", ""},
/*71*/ {"AXISC", "Unknown element exception", "", ""},
/*72*/ {"AXISC", "Node value mismatch exception", "", ""},
- /*73*/ {"AXISC", "Configuration read exception", "", ""}
+ /*73*/ {"AXISC", "Configuration read exception", "", ""},
+
+ /*74*/ {"AXISC", "Configuration defaults already set", "", ""},
+
+ /*75*/ {"Server", "Redirect received", "", ""}
+
};
s_parrSoapFaultStruct = s_arrLocalFaultStruct;
m_bInit = true;
Modified: axis/axis1/c/trunk/src/transport/axis3/HTTPTransport.cpp
URL: http://svn.apache.org/viewvc/axis/axis1/c/trunk/src/transport/axis3/HTTPTransport.cpp?rev=930475&r1=930474&r2=930475&view=diff
==============================================================================
--- axis/axis1/c/trunk/src/transport/axis3/HTTPTransport.cpp (original)
+++ axis/axis1/c/trunk/src/transport/axis3/HTTPTransport.cpp Sat Apr 3 05:11:09 2010
@@ -56,6 +56,7 @@ m_bMaintainSession (false)
m_pReleaseBufferCallback = 0;
m_eProtocolType = APTHTTP1_1;
m_strBytesToSend = "";
+ m_strBytesToSendRedirect = "";
m_strHeaderBytesToSend = "";
m_bChannelSecure = false;
m_pNormalChannel = 0;
@@ -72,6 +73,12 @@ m_bMaintainSession (false)
#else
m_lChannelTimeout = 0;
#endif
+ m_strResponseLocationURI = "";
+ m_bPerformAutoRedirect = false;
+ m_iMaximumAutoRedirects = 1;
+ m_strMaximumAutoRedirects = "1";
+ m_iNbrOfRedirectAttempts = 0;
+ m_bHasReadBeenDone = false;
m_pNormalChannel = m_pChannelFactory->createChannel(UnsecureChannel);
m_pSecureChannel = m_pChannelFactory->createChannel(SecureChannel);
@@ -96,6 +103,31 @@ HTTPTransport::
}
void HTTPTransport::
+resetOutputStateMachine()
+{
+ logEntryTransport("HTTPTransport::resetOutputStateMachine")
+
+ // Empty the bytes to send string. Note that the payload is saved in the case
+ // we need to handle redirect.
+ if (m_bPerformAutoRedirect && m_iMaximumAutoRedirects > 0 && m_strBytesToSend.length() > 0)
+ m_strBytesToSendRedirect = m_strBytesToSend;
+
+ m_strBytesToSend = "";
+ m_strHeaderBytesToSend = "";
+
+ // Also empty the response headers as there aren't any yet until the response comes back !
+ m_vResponseHTTPHeaders.clear();
+ // TODO: Possible memory leak here - does the clear op clean out the memory too?
+
+ // Empty other variables set from response received
+ m_strResponseHTTPStatusMessage = "";
+ m_strResponseContentType = "";
+ m_strResponseLocationURI = "";
+
+ logExit()
+}
+
+void HTTPTransport::
resetInputStateMachine()
{
logEntryTransport("HTTPTransport::resetInputStateMachine")
@@ -114,7 +146,7 @@ resetInputStateMachine()
/*
* HTTPTransport::setEndpointUri( EndpointURI) sets the URI for the message.
- * Everytime the endpoint changes then currently connected channel is closed
+ * Every time the endpoint changes then currently connected channel is closed
* and a new channel connection is opened.
*
* @param EndpointURI - char * to a null terminated string that holds the
@@ -257,26 +289,39 @@ flushOutput() throw (AxisException, HTTP
{
logEntryTransport("HTTPTransport::flushOutput")
+ // since we are writing...we need to reset flag indicating a read has been done.
+ m_bHasReadBeenDone = false;
+
char *utf8BufHeader = NULL; // buffer for HTTP header when converting to utf8.
char *utf8BufPayload = NULL; // buffer for HTTP payload when converting to utf8.
char buff[24];
+ // Handle re-sending payload in case of redirect.
+ int payLoadLength = m_strBytesToSend.length();
+ const char *payLoad = m_strBytesToSend.c_str();
+
+ if (payLoadLength == 0 && m_bPerformAutoRedirect && m_iMaximumAutoRedirects > 0)
+ {
+ payLoadLength = m_strBytesToSendRedirect.length();
+ payLoad = m_strBytesToSendRedirect.c_str();
+ }
+
// Send HTTP headers and body
try
{
#ifndef __OS400__
// Generate HTTP header string - need to set content-length before generating headers.
- sprintf( buff, "%d", m_strBytesToSend.length ());
+ sprintf( buff, "%d", payLoadLength);
this->setTransportProperty ("Content-Length", buff);
generateHTTPHeaders ();
m_pActiveChannel->writeBytes(m_strHeaderBytesToSend.c_str(), m_strHeaderBytesToSend.length());
- m_pActiveChannel->writeBytes(m_strBytesToSend.c_str(), m_strBytesToSend.length());
+ m_pActiveChannel->writeBytes(payLoad, payLoadLength);
#else
// Generate HTTP header string - need to set content-length before generating headers.
// We need to convert payload to UTF-8 first to get accurate length of payload.
- utf8BufPayload = PlatformLanguage::toUTF8((const char *)m_strBytesToSend.c_str(), m_strBytesToSend.length()+1);
- int payLoadLength = strlen(utf8BufPayload);
+ utf8BufPayload = PlatformLanguage::toUTF8(payLoad, payLoadLength+1);
+ payLoadLength = strlen(utf8BufPayload);
sprintf( buff, "%d", payLoadLength);
this->setTransportProperty ("Content-Length", buff);
@@ -299,21 +344,15 @@ flushOutput() throw (AxisException, HTTP
{
delete utf8BufHeader;
delete utf8BufPayload;
- m_strBytesToSend = "";
- m_strHeaderBytesToSend = "";
+
+ resetOutputStateMachine();
logRethrowException()
throw;
}
- // Empty the bytes to send string.
- m_strBytesToSend = "";
- m_strHeaderBytesToSend = "";
-
- // Also empty the response headers as there aren't any yet until the response comes back !
- m_vResponseHTTPHeaders.clear();
- // TODO: Possible memory leak here - does the clear op clean out the memory too?
+ resetOutputStateMachine();
logExit()
@@ -501,6 +540,13 @@ sendBytes( const char *pcSendBuffer, con
{
m_strBytesToSend += std::string (pcSendBuffer);
+ // Since we are sending new data, ensure nothing in redirect buffer.
+ if (m_strBytesToSendRedirect.length() > 0)
+ {
+ m_iNbrOfRedirectAttempts = 0;
+ m_strBytesToSendRedirect = "";
+ }
+
return TRANSPORT_IN_PROGRESS;
}
@@ -511,7 +557,8 @@ isThereResponseData()
// We do not want to consume any SOAP data, just find out if there is any data.
int bufLen = 0;
- getBytes(NULL, &bufLen);
+ if (!m_bHasReadBeenDone)
+ getBytes(NULL, &bufLen);
bool returnValue = (m_GetBytesState != eWaitingForHTTPHeader || m_iBytesLeft != 0);
logExitWithBoolean(returnValue)
@@ -922,6 +969,30 @@ setTransportProperty( AXIS_TRANSPORT_INF
break;
}
+ case ENABLE_AUTOMATIC_REDIRECT:
+ {
+ if (value && strcmp(value, "true") == 0)
+ m_bPerformAutoRedirect = true;
+ else
+ m_bPerformAutoRedirect = false;
+ break;
+ }
+
+ case MAX_AUTOMATIC_REDIRECT:
+ {
+ if (value)
+ m_iMaximumAutoRedirects = atoi(value);
+
+ if (m_iMaximumAutoRedirects < 1)
+ m_iMaximumAutoRedirects = 0;
+
+ char buffer[100];
+ sprintf(buffer, "%d", m_iMaximumAutoRedirects);
+ m_strMaximumAutoRedirects = (const char *)buffer;
+
+ break;
+ }
+
default:
{
break;
@@ -1051,6 +1122,18 @@ getTransportProperty( AXIS_TRANSPORT_INF
{
break;
}
+
+ case ENABLE_AUTOMATIC_REDIRECT:
+ {
+ pszPropValue = m_bPerformAutoRedirect ? "true" : "false";
+ break;
+ }
+
+ case MAX_AUTOMATIC_REDIRECT:
+ {
+ pszPropValue = m_strMaximumAutoRedirects.c_str();
+ break;
+ }
}
logExitWithString(pszPropValue)
@@ -1327,6 +1410,8 @@ processHTTPHeader()
// Store as key-value pairs
string key = strHeaderLine.substr( 0, iSeperator);
string value = strHeaderLine.substr( iSeperator + 1, strHeaderLine.length() - iSeperator - 2);
+ trim(value);
+ trim(key);
m_vResponseHTTPHeaders.push_back( std::make_pair( key, value));
// Content length set? Chunked overrides Content-length. It should be noted
@@ -1337,30 +1422,34 @@ processHTTPHeader()
m_iContentLength = atoi(value.c_str());
m_GetBytesState = eSOAPMessageHasContentLength;
}
-
+
+ // Redirect?
+ if (key == "Location")
+ m_strResponseLocationURI = value;
+
// Is chunked?
- if (key == "Transfer-Encoding" && value == " chunked")
+ if (key == "Transfer-Encoding" && value == "chunked")
m_GetBytesState = eSOAPMessageIsChunked;
// Now handle whether we are going to close connection after processing
// request. If HTTP/1.0 we have to always close the connection by default; otherwise,
- // we assume persistant connection by default.
+ // we assume persistent connection by default.
if( m_eProtocolType == APTHTTP1_0)
m_bReopenConnection = true;
// We need to close the connection and open a new one if we have 'Connection: close'
- if( key == "Connection" && (value == " close" || value == " Close"))
+ if( key == "Connection" && (value == "close" || value == "Close"))
{
m_bReopenConnection = true;
m_pActiveChannel->closeQuietly( true);
}
// We need to close the connection and open a new one if we have 'Proxy-Connection: close'
- if (key == "Proxy-Connection" && (value == " close" || value == " Close"))
+ if (key == "Proxy-Connection" && (value == "close" || value == "Close"))
m_bReopenConnection = true;
// For both HTTP/1.0 and HTTP/1.1, We need to keep the connection if we have 'Connection: Keep-Alive'
- if( key == "Connection" && value == " Keep-Alive")
+ if( key == "Connection" && value == "Keep-Alive")
m_bReopenConnection = false;
// Look for cookies
@@ -1371,31 +1460,31 @@ processHTTPHeader()
/* If Content-Type: Multipart/Related; boundary=<MIME_boundary>; type=text/xml; start="<content id>" */
if( key == "Content-Type")
{
- m_strContentType = value;
+ m_strResponseContentType = value;
- string::size_type ulMimePos = m_strContentType.find( ";");
+ string::size_type ulMimePos = m_strResponseContentType.find( ";");
std::string strTypePart;
if( ulMimePos != std::string::npos)
- strTypePart = m_strContentType.substr( 1, ulMimePos - 1);
+ strTypePart = m_strResponseContentType.substr( 1, ulMimePos - 1);
if( "Multipart/Related" == strTypePart)
{
m_bMimeTrue = true;
- m_strContentType = m_strContentType.substr( ulMimePos + 1, m_strContentType.length());
+ m_strResponseContentType = m_strResponseContentType.substr( ulMimePos + 1, m_strResponseContentType.length());
- ulMimePos = m_strContentType.find( "boundary=");
- m_strMimeBoundary = m_strContentType.substr( ulMimePos);
+ ulMimePos = m_strResponseContentType.find( "boundary=");
+ m_strMimeBoundary = m_strResponseContentType.substr( ulMimePos);
ulMimePos = m_strMimeBoundary.find( ";");
m_strMimeBoundary = m_strMimeBoundary.substr( 9, ulMimePos - 9);
- ulMimePos = m_strContentType.find( "type=");
- m_strMimeType = m_strContentType.substr( ulMimePos);
+ ulMimePos = m_strResponseContentType.find( "type=");
+ m_strMimeType = m_strResponseContentType.substr( ulMimePos);
ulMimePos = m_strMimeType.find( ";");
m_strMimeType = m_strMimeType.substr( 5, ulMimePos - 5);
- ulMimePos = m_strContentType.find( "start=");
- m_strMimeStart = m_strContentType.substr( ulMimePos);
+ ulMimePos = m_strResponseContentType.find( "start=");
+ m_strMimeStart = m_strResponseContentType.substr( ulMimePos);
ulMimePos = m_strMimeStart.find( ";");
m_strMimeStart = m_strMimeStart.substr( 6, ulMimePos - 6);
}
@@ -1774,6 +1863,8 @@ readHTTPHeader()
resetInputStateMachine();
+ m_bHasReadBeenDone = true;
+
do
{
while (m_strReceived.find( ASCII_S_HTTP) == std::string::npos
@@ -1814,11 +1905,32 @@ readHTTPHeader()
}
while( m_iResponseHTTPStatusCode == 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 ( m_iResponseHTTPStatusCode != 500
- && (m_iResponseHTTPStatusCode < 200 || m_iResponseHTTPStatusCode >= 300))
+ // Now have a valid HTTP header that is not 100. Interrogate status code.
+ const char *contentType = m_strResponseContentType.c_str();
+ if (m_iResponseHTTPStatusCode > 199 && m_iResponseHTTPStatusCode < 300)
+ {
+ // SOAP return is OK - so fall through
+ }
+ else if ((contentType != NULL) && (strncmp(contentType, "text/html", 9) != 0)
+ && ((m_iResponseHTTPStatusCode > 499) && (m_iResponseHTTPStatusCode < 600)))
+ {
+ // SOAP Fault should be in here - so fall through
+ }
+ else if ((m_strResponseLocationURI.length() != 0)
+ && ((m_iResponseHTTPStatusCode == 301)
+ || (m_iResponseHTTPStatusCode == 302)
+ || (m_iResponseHTTPStatusCode == 307)))
{
+ // Redirect (HTTP: 301/302/307)
+ handleRedirect();
+ }
+ else
+ {
+ m_iNbrOfRedirectAttempts = 0;
+ m_strBytesToSendRedirect = "";
+
+ // Unknown return code - so wrap up the content into a SOAP fault TODO
+
m_strResponseHTTPStatusMessage = std::string( "Server sent HTTP error: '") +
m_strResponseHTTPStatusMessage + std::string("'\n");
@@ -1830,6 +1942,9 @@ readHTTPHeader()
throw HTTPTransportException( SERVER_TRANSPORT_HTTP_EXCEPTION, m_strResponseHTTPStatusMessage.c_str());
}
+ m_iNbrOfRedirectAttempts = 0;
+ m_strBytesToSendRedirect = "";
+
logExit()
}
@@ -1988,3 +2103,48 @@ enableTrace(const char* logFilePath, con
if (m_pSecureChannel)
m_pSecureChannel->enableTrace(logFilePath, filters);
}
+
+void HTTPTransport::
+handleRedirect()
+{
+ logEntryTransport("HTTPTransport::handleRedirect")
+
+ // close old connection
+ closeConnection(true);
+
+ // Setup exception data with redirect location.
+ m_strResponseHTTPStatusMessage = std::string( "Redirect: ") + m_strResponseLocationURI + std::string("'\n");
+
+ m_GetBytesState = eWaitingForHTTPHeader;
+
+ // See if we can process redirect seamlessly.
+ // We only do so if we are going from http -> http or https -> https.
+ const char *location = m_strResponseLocationURI.c_str();
+ bool throwException = true;
+ if (location
+ && m_bPerformAutoRedirect
+ && m_iNbrOfRedirectAttempts < m_iMaximumAutoRedirects
+ && ((m_bChannelSecure && strncmp("https:", location, 6) == 0)
+ || (!m_bChannelSecure && strncmp("http:", location, 5) == 0)))
+ {
+ throwException = false;
+ m_iNbrOfRedirectAttempts++;
+ setEndpointUri(location);
+ openConnection();
+ flushOutput();
+ readHTTPHeader();
+ }
+
+ if (throwException)
+ {
+ m_iNbrOfRedirectAttempts = 0;
+ m_strBytesToSendRedirect = "";
+
+ logThrowExceptionWithData("HTTPTransportException - SERVER_TRANSPORT_REDIRECT_RECEIVED",
+ m_strResponseHTTPStatusMessage.c_str())
+
+ throw HTTPTransportException( SERVER_TRANSPORT_REDIRECT_RECEIVED, m_strResponseHTTPStatusMessage.c_str());
+ }
+
+ logExit()
+}
Modified: axis/axis1/c/trunk/src/transport/axis3/HTTPTransport.hpp
URL: http://svn.apache.org/viewvc/axis/axis1/c/trunk/src/transport/axis3/HTTPTransport.hpp?rev=930475&r1=930474&r2=930475&view=diff
==============================================================================
--- axis/axis1/c/trunk/src/transport/axis3/HTTPTransport.hpp (original)
+++ axis/axis1/c/trunk/src/transport/axis3/HTTPTransport.hpp Sat Apr 3 05:11:09 2010
@@ -125,6 +125,8 @@ class HTTPTransport:public SOAPTransport
int getChunkSize(string::size_type pos=0);
void resetInputStateMachine();
+ void resetOutputStateMachine();
+ void handleRedirect();
unsigned int m_iChunkedDataLeftToConsume;
unsigned int m_iNextChunkedDataSize;
@@ -168,7 +170,7 @@ class HTTPTransport:public SOAPTransport
/**
* Keeps track of if we need to reopen connection.
* Set true by setEndpointUri.
- * Set false when a socket connection is established with the enpoint and
+ * Set false when a socket connection is established with the endpoint and
* when there is no need renew (that is close and open again) an existing connection.
*/
bool m_bReopenConnection;
@@ -286,7 +288,7 @@ class HTTPTransport:public SOAPTransport
/**
* Content-Type holder
*/
- std::string m_strContentType;
+ std::string m_strResponseContentType;
/**
* Mime Boundary value
@@ -326,6 +328,15 @@ class HTTPTransport:public SOAPTransport
* New getBytes variables
*/
EGETBYTESSTATE m_GetBytesState;
+
+ bool m_bHasReadBeenDone;
+
+ std::string m_strMaximumAutoRedirects;
+ int m_iNbrOfRedirectAttempts;
+ bool m_bPerformAutoRedirect;
+ int m_iMaximumAutoRedirects;
+ std::string m_strBytesToSendRedirect;
+ std::string m_strResponseLocationURI;
};
#endif