upnp/upnpstack/dlnawebserver/src/upnphttpserver.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 02 Feb 2010 01:12:20 +0200
changeset 0 f5a58ecadc66
permissions -rw-r--r--
Revision: 201003

/** @file
* Copyright (c) 2005-2006 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:  Declares HttpServer class.
*
*/


// INCLUDE FILES
#include <e32std.h>
#include <upnpsettings.h>

#include "upnphttpserver.h"
#include "upnphttpsession.h"
#include "upnphttpfileaccess.h"
#include "upnpstring.h"
#include "upnpcommonupnplits.h"
#define KLogFile _L("DLNAWebServer.txt")
#include "upnpcustomlog.h"
#include "upnpcons.h"
#include "upnphttpmessagefactory.h"
#include "upnphttpservertransactioncreator.h"
#ifdef RD_UPNP_REMOTE_ACCESS
#include "upnpipfiltermanager.h"
#endif

// ============================ MEMBER FUNCTIONS ===============================

// -----------------------------------------------------------------------------
// CUpnpHttpServer::CUpnpHttpServer
// C++ default constructor
// -----------------------------------------------------------------------------
//
CUpnpHttpServer::CUpnpHttpServer( MUpnpHttpServerObserver* aObserver,
                                  MUpnpHttpServerTransactionCreator* aCreator,
                                  RSocketServ* aSocketServ,
                                  TInt aActiveIap )
    : CUpnpTcpServer( aSocketServ, KDefaultHttpPort, aActiveIap )
    {
    iObserver = aObserver;
    iTransactionCreator = aCreator;
    }

// -----------------------------------------------------------------------------
// CUpnpHttpServer::~CUpnpHttpServer
// C++ default destructor
// -----------------------------------------------------------------------------
//
CUpnpHttpServer::~CUpnpHttpServer()
    {
    delete iServerDescription;
    iFs.Close();
    }

// -----------------------------------------------------------------------------
// CUpnpHttpServer::NewL
// Two-phased constructor
// -----------------------------------------------------------------------------
//
CUpnpHttpServer* CUpnpHttpServer::NewL( MUpnpHttpServerObserver* aObserver,
                                                 RSocketServ* aSocketServ,
                                                 TInt aActiveIap )
    {
    LOG_FUNC_NAME;
       
    CUpnpHttpServer* self = new (ELeave) CUpnpHttpServer( aObserver, NULL,           
            aSocketServ, aActiveIap );
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop( self );

    return self;
    }


// -----------------------------------------------------------------------------
// CUpnpHttpServer::ConstructL
// Two-phased constructor
// -----------------------------------------------------------------------------
//
void CUpnpHttpServer::ConstructL()
    {
    BaseConstructL();
    User::LeaveIfError(iFs.Connect());
    iServerDescription =  CUpnpSettings::GetServerHeaderL();
    }

// -----------------------------------------------------------------------------
// CUpnpHttpServer::StartL
// Start tcp server
// -----------------------------------------------------------------------------
//
void CUpnpHttpServer::StartL( const TInt aPort )
    {
    LOG_FUNC_NAME;
    OpenSocketL();
    if ( aPort )
        {
        BindL( aPort );
        }
        else
        {
        BindRandomPortL();
        }
    }

// -----------------------------------------------------------------------------
// CUpnpHttpServer::Stop
// Stop tcp server
// -----------------------------------------------------------------------------
//
void CUpnpHttpServer::Stop()
    {
    LOG_FUNC_NAME;
    TRAP_IGNORE( StopTcpServerL() );
    }

// -----------------------------------------------------------------------------
// CUpnpHttpServer::ToReceiveStackD
//
// -----------------------------------------------------------------------------
//
void CUpnpHttpServer::ToReceiveStackD( CUpnpHttpMessage* aMsg )
    {
    LOG_FUNC_NAME;
    //to indicate that the upper layer can give a response for it is acting as a host in this session
    if ( !aMsg )
        {
        return;
        }
	aMsg->SetClientRequest(ETrue);
	//for redirection codes

    #ifdef _DEBUG
        TInt err;
        TRAP( err, iObserver->HttpEventLD( aMsg ) );
        LOGS1H( iHandle, "CUpnpHttpServer::ToReceiveStack() Error %i", err );

    #else
        TRAP_IGNORE(  iObserver->HttpEventLD( aMsg ) );
    #endif
    }

// -----------------------------------------------------------------------------
// CUpnpHttpServer::SendMessageL
// Send HTTP message
// -----------------------------------------------------------------------------
//
TInt CUpnpHttpServer::SendMessageL( CUpnpHttpMessage* aMessage )
    {
    LOG_FUNC_NAME;

    if (!aMessage)
		{
		LOGS("CUpnpHttpServer::SendMessageL - Tried to send Null");
		return KErrNotFound;
		}

    TInt trapError( KErrNone );
    TInt sessId( KErrNone );

    TRAP(trapError, sessId = TrapSendMessageL( aMessage ) );

    if( trapError < KErrNone )
        {
        LOGS1( "HTTP *** Sending of message failed. Error: %i", trapError );
        // HttpSession errors that cannot be forwarded to upper layers
        if( -trapError >= EHttpBadRequest && -trapError <= EHttpExpectationFailed )
            {
            CUpnpHttpMessage* notify = NULL;
            notify = RUpnpHttpMessageFactory::HttpResponseErrorL( aMessage, -trapError );
            CUpnpHttpSession* sess = GetSession( aMessage->SessionId() );
            sess->DeleteThisSessionL( sess );

            ToReceiveStackD( notify ); //Upper layer takes care about cleanup
            }
        else
            {
            User::Leave(trapError);
            }
        }
    // nobody use the value
    return sessId;
    }

// -----------------------------------------------------------------------------
// CUpnpHttpServer::TrapSendMessageL
// Send HTTP message
// -----------------------------------------------------------------------------
//
TInt CUpnpHttpServer::TrapSendMessageL( CUpnpHttpMessage* aMessage )
    {
    CUpnpHttpSession* sess = GetSession( aMessage->SessionId() );
    if( sess )
        {
        sess->SendL( aMessage );
        return sess->Id();
        }
    else
        {
        // If running out of memory, there is nothing else to do but leave
        if ( KErrNoMemory == aMessage->SessionId() )
            {
            LOGS("CUpnpHttpServer::TrapSendMessageL - OUT OF MEMORY");
            User::Leave( KErrNoMemory );
            }        
        }
    return KErrNotFound;
    }

// -----------------------------------------------------------------------------
// CUpnpHttpServer::GetSession
//
// -----------------------------------------------------------------------------
//
CUpnpHttpSession* CUpnpHttpServer::GetSession( TInt aSessionId )
    {
    CUpnpHttpSession* sess = NULL;

    for ( TInt i=0; i < iSessionList.Count(); i++ )
        {
        if ( ( (CUpnpHttpSession*) iSessionList[i] )->Id() == aSessionId )
            {
            sess = (CUpnpHttpSession*) iSessionList[i];
            return sess;
            }
        }

    return sess;
    }

// -----------------------------------------------------------------------------
// CUpnpHttpServer::ServerDescription
// Returns server's description
// -----------------------------------------------------------------------------
//
TDesC8& CUpnpHttpServer::ServerDescription()
    {
    return *iServerDescription;
    }

// -----------------------------------------------------------------------------
// CUpnpHttpServer::ConnectionAcceptedL
//
// -----------------------------------------------------------------------------
//
CUpnpTcpSession* CUpnpHttpServer::ConnectionAcceptedL( RSocket aSocket )
    {
    LOG_FUNC_NAME;

    #ifdef _DEBUG
    TInetAddr tempAddr;
    aSocket.RemoteName( tempAddr );
    tempAddr.ConvertToV4();

    const TInt KMaxAdressLength = 20;
    TBuf<KMaxAdressLength> addrBuf;
    tempAddr.Output( addrBuf );

    HBufC8* addrBuf8 = UpnpString::FromUnicodeL( addrBuf );
    CleanupStack::PushL( addrBuf8 );

    LOGS( "CUpnpHttpServer::ConnectionAcceptedL - Remote socket connected" );
    LOGT( addrBuf8->Des() );

    LOGS1("CUpnpHttpServer::ConnectionAcceptedL - Creating a new Http session. Session count: %i", iSessionList.Count());

    CleanupStack::PopAndDestroy(addrBuf8);
    #endif //_DEBUG
    CUpnpHttpSession* sess = CUpnpHttpSession::NewL( aSocket, this,
        CUpnpHttpMessage::NewSessionIdL(), EPriorityNormal );

    return sess;
    }


// -----------------------------------------------------------------------------
// CUpnpHttpServer::SetCdDataFinder
//
// -----------------------------------------------------------------------------
//
void CUpnpHttpServer::SetTransactionCreator( 
                                 MUpnpHttpServerTransactionCreator* aTransactionCreator )
    {
    iTransactionCreator = aTransactionCreator;
    }

// -----------------------------------------------------------------------------
// CUpnpHttpServer::HttpFilter
//
// -----------------------------------------------------------------------------
//
MUpnpHttpServerTransactionCreator* CUpnpHttpServer::TransactionCreator()
    {
    //ASSERT( iHttpFilter ) set in constructor defaultHttpFilter to ensure not null
    return iTransactionCreator;
    }

// -----------------------------------------------------------------------------
// CUpnpHttpServer::FileSession
// -----------------------------------------------------------------------------
//
RFs& CUpnpHttpServer::FileSession()
    {
    return iFs;
    }

// -----------------------------------------------------------------------------
// CUpnpHttpServer::ConnectionL
// -----------------------------------------------------------------------------
//
RConnection& CUpnpHttpServer::ConnectionL()
    {
    return iConnectionManagerProxy->ConnectionL();
    }

// -----------------------------------------------------------------------------
// CUpnpHttpServer::StartIPFilteringL
// -----------------------------------------------------------------------------
//
EXPORT_C void CUpnpHttpServer::StartIPFilteringL()
    {
    #ifdef RD_UPNP_REMOTE_ACCESS
    if( !iIPFilteringManager )
    {
    iIPFilteringManager = CUpnpIPFilterManager::NewL();
    }
    #endif
    }

// -----------------------------------------------------------------------------
// CUpnpHttpServer::StopIPFiltering
// -----------------------------------------------------------------------------
//
EXPORT_C void CUpnpHttpServer::StopIPFiltering()
    {
    #ifdef RD_UPNP_REMOTE_ACCESS
    delete iIPFilteringManager;
    iIPFilteringManager = NULL;
    #endif
    }

//  End of File