--- /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