webengine/osswebengine/WebCore/platform/network/symbian/HttpSessionManager.cpp
changeset 0 dd21522fd290
child 8 7c90e6132015
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/webengine/osswebengine/WebCore/platform/network/symbian/HttpSessionManager.cpp	Mon Mar 30 12:54:55 2009 +0300
@@ -0,0 +1,447 @@
+/*
+* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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:  
+*
+*/
+
+#include "config.h"
+
+#include "HttpFilterCommonStringsExt.h"
+#include "HttpFilterCommonStringsAddition.h"
+#include "HttpFilterConnHandlerInterface.h"
+#include "HttpFilterIopInterface.h"
+#include "HttpFilterAuthenticationInterface.h"
+#include "cookiefilterinterface.h"
+#include "uaproffilter_interface.h"
+#include "deflatefilterinterface.h"
+#include "HttpSessionManager.h"
+#include "HttpUiCallbacks.h"
+#include "HttpCacheManager.h"
+#include "HttpConnection.h"
+#include "HttpRequestHeaderManager.h"
+#include "CookieHandler.h"
+#include "HttpDlConnection.h"
+#include "SelfDownloadContentHandler.h"
+#include "BrCtl.h"
+#include "ResourceHandleManagerSymbian.h"
+#include "StaticObjectsContainer.h"
+#include "WebFrame.h"
+
+// CONSTANTS
+_LIT8( KHttpProtString, "HTTP/TCP" );
+_LIT (KNullStr, "");
+
+class MBrCtlSpecialLoadObserver;
+
+using namespace WebCore;
+
+HttpSessionManager::HttpSessionManager()
+{
+    m_sessionRunning = false;
+    m_cookiesEnabled = false;
+    m_cookieFilterLoaded = false;
+    m_httpPipelining = true;
+    m_cacheManager = NULL;
+    m_ReqHdrManager = NULL;
+    m_cookieHandler = NULL;
+    m_httpDownload = NULL;
+    m_SelfDownloadContentHandler = NULL;
+    m_SelfDownloadContentTypes = KNullStr().Alloc();
+}
+
+HttpSessionManager::~HttpSessionManager()
+{
+    delete m_cacheManager;
+    m_cacheManager = NULL;
+    delete m_ReqHdrManager;
+    m_ReqHdrManager = NULL;
+    delete m_cookieHandler;
+    delete m_httpDownload;
+    m_httpDownload = NULL;
+    delete m_SelfDownloadContentHandler;
+    m_SelfDownloadContentHandler = NULL;
+    m_ClientAcceptHeaders.ResetAndDestroy();
+    m_ClientAcceptHeaders.Close();
+    closeHttpSession();
+}
+
+void HttpSessionManager::openHttpSessionIfNeededL()
+{
+    if (!m_sessionRunning) {
+        m_httpSession.OpenL( KHttpProtString );
+        m_sessionRunning = true;
+        // get the connection info
+        RStringPool strP = m_httpSession.StringPool();
+        const TStringTable& stringTable = RHTTPSession::GetTable();
+        RHTTPConnectionInfo connInfo = m_httpSession.ConnectionInfo();
+
+        // set shutdown
+        THTTPHdrVal immediateShutdown = strP.StringF( HTTP::ESocketShutdownImmediate, stringTable );
+        connInfo.SetPropertyL ( strP.StringF( HTTP::ESocketShutdownMode, stringTable ), immediateShutdown );
+
+        // set pipelining
+        RStringF maxConnection = strP.StringF( HTTP::EMaxNumTransportHandlers , stringTable );
+        connInfo.SetPropertyL( maxConnection, THTTPHdrVal( KHttpMaxConnectionNum ) );
+
+        RStringF maxToPipeline = strP.StringF(HTTP::EMaxNumTransactionsToPipeline, stringTable );
+        connInfo.SetPropertyL( maxToPipeline, THTTPHdrVal( KHttpMaxTransactionNumPerConnection ) );
+
+		//set HTTP receive Buffer Size property
+		RStringF receiveBuffSize = strP.StringF(HTTP::ERecvBufferSize, stringTable );
+		connInfo.SetPropertyL( receiveBuffSize, THTTPHdrVal(KHttpReceiveBuffSize));
+
+		//set HTTP batching enable
+		THTTPHdrVal batchingSupport(strP.StringF(HTTP::EEnableBatching,RHTTPSession::GetTable()));
+		connInfo.SetPropertyL( strP.StringF( HTTP::EHttpBatching, RHTTPSession::GetTable() ), batchingSupport );
+
+		//set HTTP batching Buffer Size property
+		RStringF batchingBuffSize = strP.StringF(HTTP::EBatchingBufferSize, stringTable );
+		connInfo.SetPropertyL( batchingBuffSize, THTTPHdrVal(KHttpBatchingBuffSize));
+
+
+        strP.OpenL( HttpFilterCommonStringsExt::GetTable() );
+        strP.OpenL( HttpFilterCommonStringsExt::GetLanguageTable() );
+        strP.OpenL( HttpFilterCommonStringsAddition::GetTable() );
+
+        CHttpFilterAuthenticationInterface::InstallFilterL( m_httpSession, true );
+        CHttpFilterAuthenticationInterface::InstallFilterL( m_httpSession, false);
+        CHttpFilterConnHandlerInterface::InstallFilterL( m_httpSession, &m_uiCallbacks );
+        CHttpUAProfFilterInterface::InstallFilterL( m_httpSession );
+        CHttpDeflateFilter::InstallFilterL( m_httpSession );
+        CHttpFilterIopInterface::InstallFilterL( m_httpSession, iopOptionHostHeader );
+        // cache manager
+        if (!m_cacheManager) {
+            m_cacheManager = CHttpCacheManager::NewL();
+        }
+        // http request header manager
+        if (!m_ReqHdrManager) {
+            m_ReqHdrManager = HttpRequestHeaderManager::NewL(m_httpSession);
+        }
+        if (!m_cookieHandler) {
+            m_cookieHandler = CookieHandler::init();
+        }
+    }
+    updateFilters(true);
+}
+
+CHttpCacheManager* HttpSessionManager::cacheManager()
+{ 
+    if (!m_cacheManager)
+        TRAP_IGNORE(m_cacheManager = CHttpCacheManager::NewL());
+    return m_cacheManager; 
+}
+
+HttpDownload* HttpSessionManager::httpDownload(bool aCreate)
+{
+    if (!m_httpDownload && aCreate){
+        m_httpDownload = new HttpDownload(this);
+    }
+    return m_httpDownload;
+}
+
+void HttpSessionManager::closeHttpSession()
+{
+    if (m_sessionRunning) {
+        this->handleError(KErrCancel);
+
+        // disconnect the Dl Mgr
+        if (m_httpDownload){
+            m_httpDownload->disconnect();
+		}
+        m_httpSession.Close();
+        m_sessionRunning = false;
+
+        delete m_ReqHdrManager;
+        m_ReqHdrManager = NULL;
+    }
+}
+
+void HttpSessionManager::enableCookies(int cookiesEnabled)
+{
+    m_cookiesEnabled = cookiesEnabled;
+    updateFilters();
+}
+
+void HttpSessionManager::addRequest(HttpConnection* connection, ResourceHandle* handle)
+{
+    m_pendingHttpRequests.add(connection, handle);
+}
+
+void HttpSessionManager::removeRequest(HttpConnection* connection)
+{
+    m_pendingHttpRequests.remove(connection);
+}
+
+void HttpSessionManager::addAuthRequest(HttpConnection* connection, ResourceHandle* handle)
+{
+    m_pendingHttpAuthRequests.add(connection, handle);
+}
+
+void HttpSessionManager::removeAuthRequest(HttpConnection* connection)
+{
+    m_pendingHttpAuthRequests.remove(connection);
+}
+
+bool HttpSessionManager::findDownloadConnection (HttpDlConnection* dlConnection, int& position)
+{
+    // check if this connection is in the list
+    HttpDlConnection* dlConnLocal = NULL;
+    bool found = false;
+    int index = 0;
+    int size = m_pendingHttpDownloadRequests.size();
+    while (index < size){
+        dlConnLocal = m_pendingHttpDownloadRequests[index];
+        if (dlConnection == dlConnLocal){
+            position = index;
+            found = true;
+            break;
+        }
+        index++;
+    }
+    return found;
+}
+
+void HttpSessionManager::addDlRequest(HttpDlConnection* dlConnection)
+{
+    m_pendingHttpDownloadRequests.append(dlConnection);
+}
+
+void HttpSessionManager::removeDlRequest(HttpDlConnection* dlConnection)
+{
+    int position = 0;
+    bool found = findDownloadConnection (dlConnection, position);
+    if (found){
+        m_pendingHttpDownloadRequests.remove(position);
+    }
+}
+
+void HttpSessionManager::handleError(int error)
+{
+    Vector<HttpConnection *> requests;
+    
+    for(HashMap<HttpConnection *, ResourceHandle *>::iterator tmpit = m_pendingHttpRequests.begin();
+        tmpit != m_pendingHttpRequests.end(); ++tmpit)
+        {
+            requests.append(tmpit->first);
+        }
+    
+    for (int i=0; i<requests.size(); ++i)
+        {
+            requests[i]->handleError(error);
+        }
+}
+
+HttpConnection* HttpSessionManager::firstHttpConnection()
+{
+    HashMap<HttpConnection *, ResourceHandle *>::const_iterator it = m_pendingHttpRequests.begin();
+    return it->first;
+}
+
+void HttpSessionManager::updateFilters(bool initializing)
+{
+    if (!m_sessionRunning || count() > 1 || (count() == 1 && !initializing)) {
+        return;
+    }
+    // Cookie Filter
+    if (m_cookiesEnabled != m_cookieFilterLoaded) {
+        if (m_cookiesEnabled) {
+            TRAP_IGNORE(
+                CHttpCookieFilter::InstallFilterL( m_httpSession );
+                m_cookieFilterLoaded = true;
+            );
+        }
+        else {
+            RHTTPFilterCollection filterColl = m_httpSession.FilterCollection();
+            filterColl.RemoveFilter(m_httpSession.StringPool().StringF(HTTP::ECookieFilter, RHTTPSession::GetTable()));
+            m_cookieFilterLoaded = false;
+        }
+		// inform the download manager
+        if(httpDownload(false)) {
+            httpDownload()->enableCookies(m_cookiesEnabled);
+        }
+    }    
+}
+
+int HttpSessionManager::count()
+{
+    return m_pendingHttpRequests.size() + !httpDownload(false) ? 0 : httpDownload()->numOfDownloads();
+}
+
+HttpDlConnection* HttpSessionManager::CreateHttpDlConnection()
+{
+    HttpDlConnection* dlConnection = new HttpDlConnection();
+    return dlConnection;
+}
+
+void HttpSessionManager::downloadL(ResourceHandle* handle, const ResourceRequest& request,
+                                  const ResourceResponse& response, HttpConnection* connection)
+{
+    RHTTPTransaction* connTransaction = connection->takeOwnershipHttpTransaction();
+    WebFrame* webFrame = kit(connection->frame());
+    if (!m_SelfDownloadContentHandler) {
+        m_SelfDownloadContentHandler = SelfDownloadContentHandler::NewL(
+            webFrame, *m_SelfDownloadContentTypes);
+    } else  { //m_SpecialLoadObserver in static object m_SelfDownloadContentHandler has to reinitialize
+    	m_SelfDownloadContentHandler->ReinitializeSpecialLoadObserver(webFrame);
+    }
+    if(m_SelfDownloadContentHandler->IsSupported(request, response, *connTransaction)
+		!= KErrNotSupported) {
+		if (m_OutstandingSelfDl) {
+			// only one outstanding self download is supported
+			User::Leave(KErrCancel);
+		}
+		else {
+			m_OutstandingSelfDl = true;
+			m_SelfDownloadContentHandler->HandleResponseHeadersL(request, response, *connTransaction);
+			RHTTPTransactionPropertySet propSet = connTransaction->PropertySet();
+			RStringPool stringPool = m_httpSession.StringPool();
+
+			RStringF selfDownloadCallbackStr = stringPool.OpenFStringL( KSelfDownloadCallback );
+			// Add own adress to the transaction properties		
+			propSet.RemoveProperty(selfDownloadCallbackStr);
+			propSet.SetPropertyL(selfDownloadCallbackStr, ((TInt) (MHTTPTransactionCallback*)m_SelfDownloadContentHandler));
+			if (connection->totalContentSize()) {
+				m_SelfDownloadContentHandler->HandleResponseBodyL(*connTransaction);
+			}
+		}
+    } else {
+        m_httpPipelining = false;
+        HttpDlConnection* dlConnection = CreateHttpDlConnection();
+        httpDownload()->continueDownloadL(connTransaction, dlConnection);
+        if (connection->totalContentSize()) {
+            THTTPEvent ev(THTTPEvent::EGotResponseBodyData);
+            m_transactionCallbacks.MHFRunL(*connTransaction, ev);
+        }
+    }
+    // Note: connection is  cleanuped in the HttpConnection::MHFRunL() THTTPEvent::EGotResponseHeaders
+}
+
+void HttpSessionManager::download(ResourceHandle* handle, const ResourceRequest& request,
+                                  const ResourceResponse& response, HttpConnection* connection)
+{
+		TRAPD(ret, downloadL(handle, request,response, connection));
+		if (ret != KErrNone) {
+           MBrCtlDialogsProvider* dialogsProvider = StaticObjectsContainer::instance()->brctl()->brCtlDialogsProvider();
+           if ( dialogsProvider && (ret == KErrNoMemory)) {
+              TRAP_IGNORE(dialogsProvider->DialogNotifyErrorL(ret));
+		   }
+		}
+}
+
+void HttpSessionManager::setSelfDownloadContentTypes(
+    const TDesC& types)
+{
+    delete m_SelfDownloadContentTypes;
+    m_SelfDownloadContentTypes = types.Alloc();
+}
+
+void HttpSessionManager::setClientAcceptHeadersL(
+    const TDesC& headers)
+{
+    // cleanup pervious accept headers
+    m_ClientAcceptHeaders.ResetAndDestroy();
+
+    TInt endName = 0;
+    TInt startValue = 0;
+    TInt endValue = 0;
+    TInt consumed = 0;
+    TInt len = headers.Length();    
+    
+    HBufC8* acceptHeaders = HBufC8::NewLC(headers.Length());
+    acceptHeaders->Des().Copy(headers);
+    while (consumed < len)
+        {
+        TPtrC8 ptr(acceptHeaders->Ptr() + consumed, len - consumed);
+        // find the headers separator first
+        endValue = ptr.Locate('\r');
+        if (endValue == 0)
+            {
+            // skip empty headers
+            consumed++;
+            continue;
+            }
+        if (endValue == KErrNotFound)
+            {
+            endValue = ptr.Length();
+            }
+        TPtrC8 header(ptr.Ptr(), endValue);
+
+        endName = header.Locate(':');
+        if (endName <= 0)
+            {
+            // No separator in the header, or it is the first character
+            User::Leave(KErrArgument);
+            }
+        // Skip leading spaces in header value
+        for (startValue = endName + 1; startValue < endValue && header[startValue] == ' '; startValue++)
+            {
+            }
+
+        HBufC8* headerBuf = HBufC8::NewLC(endName);
+        HBufC8* valueBuf = HBufC8::NewLC(endValue-startValue);
+
+        headerBuf->Des().Copy(ptr.Left(endName));
+        valueBuf->Des().Copy(ptr.Mid(startValue, endValue - startValue));
+        
+        User::LeaveIfError(m_ClientAcceptHeaders.Append(headerBuf)); 
+        User::LeaveIfError(m_ClientAcceptHeaders.Append(valueBuf));
+        CleanupStack::Pop(2); // headerBuf, valueBuf   
+        consumed += (endValue + 1);
+        }
+    CleanupStack::PopAndDestroy(); // acceptHeaders
+}
+
+void HttpSessionManager::enableAutoOpenDownloads(bool autoOpen)
+{
+    m_autoOpenDownloads = autoOpen;
+    if(httpDownload(false)) {
+        httpDownload()->updateDownloadsOpenEnabled();
+    }
+}
+
+void HttpSessionManager::UpdateCacheL(const String& url, const String &equiv, const String &content)
+{
+    CHttpCacheManager* cache = cacheManager();
+    if( cache ) {
+        TPtrC urlPtr( url );
+        HBufC8* url8 = HBufC8::NewLC( urlPtr.Length() );
+        url8->Des().Copy( urlPtr );
+        if (equalIgnoringCase(equiv, "expires")) {
+            TPtrC expPtr( content );
+            if(expPtr.Length()) {
+                HBufC8* exp8 = HBufC8::NewLC( expPtr.Length() );
+                exp8->Des().Copy( expPtr );
+                cache->AddHeaderL( *url8, _L8("Expires"), *exp8 );
+                CleanupStack::PopAndDestroy(); // exp8
+            }
+        }
+        else {
+            String str = content.lower().stripWhiteSpace();
+            if (str.contains("no-cache") || str.contains("no-store")) {
+                cache->RemoveL( *url8 );
+            }
+            else if (equalIgnoringCase(equiv, "cache-control") && str.contains("max-age")) {
+                HBufC8* name8 = HBufC8::NewLC( equiv.length() );
+                name8->Des().Copy( equiv );
+                HBufC8* value8 = HBufC8::NewLC( content.length() );
+                value8->Des().Copy( content );
+                cache->AddHeaderL( *url8, *name8, *value8 );
+                CleanupStack::PopAndDestroy(2); // name8, value8
+            }
+        }
+        CleanupStack::PopAndDestroy(); // url8
+    }
+}
+
+// end of file