--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/httpfilters/httpfilteriop/Src/HttpFilterIop.cpp Tue Feb 02 01:09:52 2010 +0200
@@ -0,0 +1,321 @@
+/*
+* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Iop filter
+*
+*/
+
+
+
+// INCLUDE FILES
+#include <http.h>
+#include <es_sock.h>
+
+// User Includes
+#include "httpfilterIop.h"
+#include "httpfiltercommonstringsext.h"
+
+#include "MIopRedirectCallback.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+void PanicHttpFiltersIop(TInt aErr = 0);
+
+// CONSTANTS
+const TInt KIopOrderOffset = 10;
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CHttpFilterIop::CHttpFilterIop
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CHttpFilterIop::CHttpFilterIop(RHTTPSession* aSession, MIopRedirectCallback* aIopRedirectCallback, TUint aIopCapabilities)
+{
+ __ASSERT_DEBUG(aSession != NULL, PanicHttpFiltersIop());
+ iSession = aSession;
+ iIopCapabilities = aIopCapabilities;
+ iIopRedirectCallback = aIopRedirectCallback; //can be null for backward compatibility or iopOptionRedirectAction not used
+ iLoadCount = 0;
+}
+
+
+// ------------------------------------------------------------------------------------------
+// CHttpFilterIop::ConstructL
+// Symbian 2nd phase constructor can leave.
+// ------------------------------------------------------------------------------------------
+//
+void CHttpFilterIop::ConstructL()
+{
+ if (iIopCapabilities & iopOptionHostHeader)
+ {
+ // Register the filter for submit events,
+ // Adds a filter to the session's filter queue.
+
+ iSession->FilterCollection().AddFilterL(*this, // The filter to add
+ THTTPEvent::ESubmit, // The event that triggers this filter
+ RStringF(), // The header whose presence triggers this filter, or KNullDesC to trigger on any header
+ KAnyStatusCode, // The status code that triggers this filter, or KAnyStatusCode to trigger on any status code
+ EStatusCodeHandler - KIopOrderOffset, // The position of the filter in the queue
+ iSession->StringPool().StringF(HttpFilterCommonStringsExt::EIopFilter,
+ HttpFilterCommonStringsExt::GetTable())); //The name of the filter to add
+ }
+
+ if ( (iIopCapabilities & iopOptionRedirectAction) && iIopRedirectCallback)
+ {
+ // 301 Found
+ iSession->FilterCollection().AddFilterL(*this, // The filter to add
+ THTTPEvent::EGotResponseHeaders, // The event that triggers this filter
+ RStringF(), // The header whose presence triggers this filter, or KNullDesC to trigger on any header
+ 301, // The status code that triggers this filter, or KAnyStatusCode to trigger on any status code
+ EStatusCodeHandler-10, // The position of the filter in the queue
+ iSession->StringPool().StringF(HttpFilterCommonStringsExt::EIopFilter,
+ HttpFilterCommonStringsExt::GetTable())); //The name of the filter to add
+ // 302 Found
+ iSession->FilterCollection().AddFilterL(*this, // The filter to add
+ THTTPEvent::EGotResponseHeaders, // The event that triggers this filter
+ RStringF(), // The header whose presence triggers this filter, or KNullDesC to trigger on any header
+ 302, // The status code that triggers this filter, or KAnyStatusCode to trigger on any status code
+ EStatusCodeHandler-10, // The position of the filter in the queue
+ iSession->StringPool().StringF(HttpFilterCommonStringsExt::EIopFilter,
+ HttpFilterCommonStringsExt::GetTable())); //The name of the filter to add
+
+ // 303 See other
+ iSession->FilterCollection().AddFilterL(*this, // The filter to add
+ THTTPEvent::EGotResponseHeaders, // The event that triggers this filter
+ RStringF(), // The header whose presence triggers this filter, or KNullDesC to trigger on any header
+ 303, // The status code that triggers this filter, or KAnyStatusCode to trigger on any status code
+ EStatusCodeHandler-10, // The position of the filter in the queue
+ iSession->StringPool().StringF(HttpFilterCommonStringsExt::EIopFilter,
+ HttpFilterCommonStringsExt::GetTable())); //The name of the filter to add
+ // 307 See other
+ iSession->FilterCollection().AddFilterL(*this, // The filter to add
+ THTTPEvent::EGotResponseHeaders, // The event that triggers this filter
+ RStringF(), // The header whose presence triggers this filter, or KNullDesC to trigger on any header
+ 307, // The status code that triggers this filter, or KAnyStatusCode to trigger on any status code
+ EStatusCodeHandler-10, // The position of the filter in the queue
+ iSession->StringPool().StringF(HttpFilterCommonStringsExt::EIopFilter,
+ HttpFilterCommonStringsExt::GetTable())); //The name of the filter to add
+
+ }
+
+}
+
+//---------------------------------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------------------------------
+//
+CHttpFilterIop::~CHttpFilterIop()
+{
+ // If we've been destroyed from the cleanup stack during creation
+ // of the object, it might still be loaded. So check. (Normaly the
+ // delete is initiated by the 'delete this' in MHFUnload)
+ if (iLoadCount)
+ {
+ // As we're already in a destructor, MHFUnload must not delete us again
+ iLoadCount = -1;
+ if( NULL != iSession)
+ {
+ iSession->FilterCollection().RemoveFilter(iSession->StringPool().StringF( HttpFilterCommonStringsExt::EIopFilter, HttpFilterCommonStringsExt::GetTable()));
+ }
+
+ }
+}
+
+// ---------------------------------------------------------------------------------------------
+// CHttpFilterIop::InstallFilterL
+// Two-phased constructor. This function replaces NewL.
+// ---------------------------------------------------------------------------------------------
+//
+CHttpFilterIop* CHttpFilterIop::InstallFilterL(TAny* aParams)
+{
+ __ASSERT_DEBUG(aParams != NULL, PanicHttpFiltersIop());
+ TIopParams* iopParams = REINTERPRET_CAST(TIopParams*, aParams);
+ __ASSERT_DEBUG(iopParams->iSession != NULL, PanicHttpFiltersIop());
+
+ CHttpFilterIop* filter = new (ELeave) CHttpFilterIop( iopParams->iSession, iopParams->iIopRedirectCallback, iopParams->iIopCapabilities );
+ CleanupStack::PushL(filter);
+ filter->ConstructL();
+ CleanupStack::Pop(filter);
+ return filter;
+}
+
+// ---------------------------------------------------------------------------------------------
+// CHttpFilterIop::MHFLoad
+// Called when the filter is being added to the session's filter queue.
+// ---------------------------------------------------------------------------------------------
+//
+void CHttpFilterIop::MHFLoad(RHTTPSession, THTTPFilterHandle)
+{
+ ++iLoadCount;
+}
+
+// ----------------------------------------------------------------------------------------------
+// CHttpFilterIop::MHFUnload
+// Called when the filter is being removed from a session's filter queue.
+// ----------------------------------------------------------------------------------------------
+//
+void CHttpFilterIop::MHFUnload(RHTTPSession /*aSession*/, THTTPFilterHandle /*aFilterHandler*/)
+{
+ __ASSERT_DEBUG(iLoadCount >= 0, PanicHttpFiltersIop());
+ if (--iLoadCount)
+ {
+ return;
+ }
+ delete this;
+}
+
+// ------------------------------------------------------------------------------------------------
+// CHttpFilterIop::MHFRunL
+// Process a transaction event.
+// ------------------------------------------------------------------------------------------------
+//
+void CHttpFilterIop::MHFRunL(RHTTPTransaction aTransaction,
+ const THTTPEvent& aEvent)
+{
+ switch (aEvent.iStatus)
+ {
+ case THTTPEvent::ESubmit:
+ {
+ _LIT8(KPort80, "80");
+ TPtrC8 port80Ptr = KPort80();
+
+ RHTTPHeaders headers(aTransaction.Request().GetHeaderCollection());
+ if (iIopCapabilities & iopOptionHostHeader)
+ {
+ TUriC8 uri = aTransaction.Request().URI();
+ TPtrC8 hostPtr = uri.Extract(EUriHost);
+ TPtrC8 portPtr = uri.Extract(EUriPort);
+ if (portPtr.Length() > 0 && portPtr.Compare(port80Ptr))
+ {
+ hostPtr.Set(hostPtr.Ptr(), hostPtr.Length() + 1 + portPtr.Length());
+ }
+
+ headers.RemoveField(iSession->StringPool().StringF(HTTP::EHost, RHTTPSession::GetTable()));
+ if (hostPtr.Length() > 0)
+ {
+ RStringF hostString = iSession->StringPool().OpenFStringL(hostPtr);
+ CleanupClosePushL(hostString);
+ headers.SetFieldL(iSession->StringPool().StringF(HTTP::EHost, RHTTPSession::GetTable()),
+ THTTPHdrVal(hostString));
+ CleanupStack::PopAndDestroy(); // hostString
+ }
+ }
+ break;
+ } // case THTTPEvent::ESubmit:
+ case THTTPEvent::EGotResponseHeaders:
+ {
+ switch (aTransaction.Response().StatusCode())
+ {
+ case 301:
+ case 302:
+ case 303:
+ case 307:
+ {
+ if (iIopRedirectCallback) // can not be null
+ HandleRedirectL(aTransaction);
+ break;
+ }
+ default:
+ break;
+ } // switch (aTransaction.Response().StatusCode())
+ } // case THTTPEvent::EGotResponseHeaders:
+ default:
+ break;
+ } // switch (aEvent.iStatus)
+}
+
+// -----------------------------------------------------------------------------
+// CHttpFilterIop::MHFRunError
+// Process an error that occured while processing the transaction.
+// -----------------------------------------------------------------------------
+//
+TInt CHttpFilterIop::MHFRunError(TInt ,
+ RHTTPTransaction ,
+ const THTTPEvent& )
+{
+// aTransaction.Fail();
+ return KErrNone;
+}
+
+// -----------------------------------------------------------------------------
+// CHttpFilterIop::MHFSessionRunL
+// Process a session event.
+// -----------------------------------------------------------------------------
+//
+void CHttpFilterIop::MHFSessionRunL(const THTTPSessionEvent& /*aEvent*/)
+{
+}
+
+// -----------------------------------------------------------------------------
+// CHttpFilterIop::MHFSessionRunError
+// Called when MHFRunL leaves from a session event.
+// -----------------------------------------------------------------------------
+//
+TInt CHttpFilterIop::MHFSessionRunError(TInt aError, const THTTPSessionEvent& /*aEvent*/)
+{
+ return aError;
+}
+
+// -----------------------------------------------------------------------------
+// CHttpFilterIop::HandleRedirectL
+// Called when received redirection status code
+// -----------------------------------------------------------------------------
+//
+void CHttpFilterIop::HandleRedirectL(RHTTPTransaction aTransaction)
+ {
+
+ RStringPool strPool = iSession->StringPool();
+ RStringF location = strPool.StringF(HTTP::ELocation,RHTTPSession::GetTable());
+ RHTTPHeaders responseHeaders(aTransaction.Response().GetHeaderCollection());
+ THTTPHdrVal locationValue;
+
+ TInt err = responseHeaders.GetField(location, 0, locationValue);
+ if (err == KErrNotFound) // location not present when redirected
+ return; // Redirect filter will deal with it, we care only about non http, https and relative(assumes http(s) ) schemes
+ else
+ {
+ User::LeaveIfError(err);
+ TUriParser8 uri;
+ uri.Parse(locationValue.StrF().DesC());
+ if (uri.IsPresent(EUriHost) && uri.IsPresent(EUriScheme)) // looking only for absolue Url path and schemes other than http(s)
+ {
+ const TDesC8& scheme = uri.Extract(EUriScheme);
+ if (scheme.FindF(_L8("http")) == KErrNotFound) // everything but http(s)
+ {
+ TPtrC8 ptr(uri.UriDes());
+ iIopRedirectCallback->NonHttpRedirect(ptr, aTransaction);
+ aTransaction.Cancel();
+ }
+ }
+ }
+ }
+
+// End of File
+