/*
* Copyright (c) 2001-2008 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: 
*
*/


#include <uri8.h>
#include <e32base.h>
//#include <http.h>
#include <httpclientserver.h>
#include <chttpformencoder.h>
#include <ssl.h>
#include <signed.h>
#include <commdbconnpref.h>
#include "bjrhttpserver.h"
#include <escapeutils.h>

const TChar KHttpSlash          = '/';
const TChar KFileSlash          = '\\';

// format for output of data/time values
//_LIT(KDateFormat,"%D%M%Y%/0%1%/1%2%/2%3%/3 %:0%H%:1%T%:2%S.%C%:3");

// Format for hook file name and location for hooks
//_LIT(KHookFormat, "Z:\\httptest\\%S.esk");
//_LIT(KHookDir, "C:\\System\\Data\\");

//_LIT(KEnterProx, "Enter Proxy authority");
//_LIT(KEnterHook, "Enter Hook name (preface with '-' to delete)");
//_LIT(KEnterSessId, "Enter Session ID (positive integer or 'none')");

_LIT8 (KAbsDocumentRoot, "/Images/");
_LIT8 (KRelDocumentRoot, "/Images");
_LIT8 (KRoot, "c:\\data\\");
_LIT8 (KHomePage, "Images/index.html");
_LIT8 (KFound, "Found");
_LIT8 (KOk, "OK");
_LIT8 (KNotFound, "Not Found");
_LIT8(KTextContent, "text/");
_LIT8(KImageContent, "image/");
_LIT(KHtml, "html");
_LIT8(KGif, "gif");
/*  If the file httpexampleclient.txt exists in the root directory of a drive
    it will be used to provide default initial values for when setting the URL, 
    proxy, etc. The file format is:
        [var] = [value]
    for example:
        PROXY = my.proxy.co.uk:5473
        URL = http://www.example.org/dir/file.html
    whitespace is ignored.
    
    Note: these are the the values set at run time, they are merely the default
    options presented to the user. In the above example the proxy is not turned
    on by default, but the string "my.proxy.co.uk:5473" is presetned as the default
    option when the use hits "p", saving them the need to have to type it in. 
    */
// Defaults
_LIT(KDefaultFileFormat,"%c:\\httpexampleserver.txt");
_LIT(KHookString, "HOOK");
_LIT(KProxyString, "PROXY");
_LIT(KURLString, "URL");
_LIT(KSessionIdString, "SESSIONID");
//_LIT(KNone, "none");
//_LIT(KSchemeHttps, "https");



// File system root
//_LIT(KFileSystemRoot,"C:\\");
//added on July13,09
_LIT(KFileName,"c:\\logs\\logs.txt");
_LIT(KFileName2,"c:\\logs\\logs2.txt");

_LIT(KServerLog,"c:\\httpserverlog.txt");

const TInt endpos = 0;
enum THttpExampleClientPanics
    {
    EReqBodySumitBufferNotAllocated,
    KBodyWithInvalidSize,
    KCouldntNotifyBodyDataPart
    };

// Size of buffer used when submitting request bodies
//const TInt KMaxSubmitSize = 1024;
//const TInt KMaxHeaderNameLen = 32;
//const TInt KMaxHeaderValueLen = 128;


//
// Implementation of CHttpServer
//


// Supplied as the name of the test program to CHttpExampleUtils
_LIT(KHttpExampleClientTestName, "HttpExampleServer");

CHttpServer::CHttpServer () 
    {
    __FLOG_OPEN ( "http", "httpexampleserver.txt" );
    __FLOG_0 ( _T8 ( "CHttpServer::CHttpServer "));
    // Initial timestamp is time now
    ResetTimeElapsed(); 
    }


CHttpServer::~CHttpServer()
    {
    __FLOG_0 ( _T8 ( "CHttpServer::~CHttpServer"));
    CleanupTransactions ();
    //iLogFile.Close();
    iSess.Close();
    //delete iUtils;
    iFileServ.Close();
    iConnection.Close();
    iSocketServ.Close();
    
    iIPAddr.Close();
    }

CHttpServer* CHttpServer::NewLC()
    {
    CHttpServer* me = new(ELeave) CHttpServer;
    CleanupStack::PushL(me);
    me->ConstructL();
    return me;
    }

CHttpServer* CHttpServer::NewL()
    {   
    CHttpServer* me = NewLC();
    CleanupStack::Pop(me);
    return me;
    }

void CHttpServer::ConstructL()
    {
    __FLOG_0 ( _T8 ( "CHttpServer::ConstructL"));
    //iUtils = CHttpExampleUtils::NewL(KHttpExampleClientTestName, *this );   
    User::LeaveIfError(iFileServ.Connect());
    iLogFile.Replace(iFileServ,KServerLog,EFileWrite);
    _LIT8(Kmsg,"\nChttpServer::ConstructL");
    iLogFile.Write(Kmsg);
    User::LeaveIfError( iSocketServ.Connect() );
    
    }

RHTTPTransaction CHttpServer::NewTransactionL ( const TUriC8& aUri, RStringF aMethod )
    {
    __FLOG_0 ( _T8 ( "CHttpServer::NewTransactionL "));
    CHttpServerTransactionBase* trans = CHttpDataTransmitter::NewL (*this, /*iUtils,*/ iFileServ, iSess, aUri, aMethod);
    iTransactions.Append(trans);
    return trans->Transaction ();
    }

// to avoid code bloat
#define CHECKVAL(name)  if(var==K ##name##String)   {a##name.Copy(val);}

void CHttpServer::SetDefaults(TDes& aURL, TDes& aProxy, TDes& aHook, TDes& aSessionId)
    {
    __FLOG_4 ( _T8 ( "CHttpServer::SetDefaults [aURL=%S,aProxy=%S,aHook=%S,aSessionId=%S]"), &aURL, &aProxy, &aHook, &aSessionId);
    TFileName filename;
    RFile file;
    filename.Format(KDefaultFileFormat, 'C');
    TInt err = file.Open(iFileServ, filename, EFileRead);
    if(err != KErrNone) 
        {
        filename.Format(KDefaultFileFormat, 'Z');
        err = file.Open(iFileServ, filename, EFileRead);
        }
    if(err == KErrNone) 
        {
        TFileText line;
        line.Set(file);
        TInt err = line.Read(filename);
        while(err == KErrNone || err ==KErrTooBig) 
            {
            filename.Trim();
            TInt div = filename.Locate('=');
            if(div>0) 
                {
                TInt i;
                for (i=div-1;i>0 && filename[i]==' ';i--);  // ibid
                TPtrC var = filename.Left(i+1);
                for (i=div+1;i<filename.Length() && filename[i]==' ';i++);  //ibid
                TPtrC val = filename.Right(filename.Length()-i);
                CHECKVAL(Hook)
                else CHECKVAL(Proxy)
                else CHECKVAL(URL)
                else CHECKVAL(SessionId);   
                __FLOG_3 ( _T8 ( "CHttpServer::SetDefaults [URL=%S,Proxy=%S,SessionId=%S]"), &aURL, &aProxy, &aSessionId);
                }
            err = line.Read(filename);
            }
        }
        file.Close();
    }


void CHttpServer::SetupClientL ()
    {
    __FLOG_0 ( _T8 ( "CHttpServer::SetupClientL "));
    ResetTimeElapsed();
    TBuf<256> url;
    TBuf<256> prox;
    TBuf<256> hook;
    TBuf<16> sessid;
    SetDefaults(url, prox, hook, sessid);
    
    
    //iUtils->Test().Console()->ClearScreen();
    _LIT(KSelectOption, "\n\n Select an option \n\n");
    //iUtils->Test().Printf(KSelectOption);
    _LIT(KPossibleSelectionsText, " 1 Start \n 2 Stop \n 3 Exit\n");
    _LIT(KPossibleSelections,"123");
    //iUtils->RequestSelection ( KPossibleSelectionsText, KPossibleSelections );
    }

void CHttpServer::StartConnectionL(TInt aIapId)
    {
    // Connection preferences
    TCommDbConnPref commDbConnPref;
    TUint32 iap(aIapId);
    _LIT8(Kmsg,"\nCHttpServer::StartConnectionL");
    iLogFile.Write(Kmsg);
    commDbConnPref.SetIapId( iap );
    commDbConnPref.SetDialogPreference( ECommDbDialogPrefDoNotPrompt );
    commDbConnPref.SetBearerSet( ECommDbBearerWLAN );
    
    User::LeaveIfError( iConnection.Open( iSocketServ ) );
    User::LeaveIfError( iConnection.Start( commDbConnPref ) );
    _LIT8(Kmsg2,"\nConnection started");
    iLogFile.Write(Kmsg2);
    }


TInt CHttpServer::GetLocalHost ( TSockAddr& aAddr )
    {
    RSocket socket;
    TInt err = socket.Open ( iSocketServ, KAfInet, KSockStream, KProtocolInetTcp );

    if ( err == KErrNone )
        {
        TInetAddr localHost;
        localHost.SetAddress ( KInetAddrAny );
        TPckgBuf<TSoInetIfQuery> query;
        query ().iDstAddr = localHost;

        err = socket.GetOpt ( KSoInetIfQueryByDstAddr, KSolInetIfQuery, query );

        if ( err == KErrNone )
            {
            // its local IP address
            localHost = query ().iSrcAddr;
            aAddr = localHost;
            }
        }
    socket.Close ();
    return err;
    }

TDesC8& CHttpServer::GetIPAddress()
    {
    return iIPAddr;
    }


void CHttpServer::ProcessSelectionL ( TInt aSelection )
    {   
    __FLOG_1 ( _T8 ( "CHttpServer::ProcessSelection  [aSelection =%d]"), aSelection );
    //_LIT8(Kmsg,"\n CHttpServer::ProcessSelection");
    //iLogFile.Write(Kmsg);
    switch ( aSelection )
        {
        case EStart: 
            {
            _LIT8 ( KHTTPServer, "HTTd/TCP" );
            
            //_LIT8(Kmsg2,"Opening server RHTTPClientServerSession - ");
            //iLogFile.Write(Kmsg2);
            //iLogFile.Write(KHTTPServer);
            // Open the RHTTPClientServerSession
            _LIT8(Kmsg2,"\nTrying to connect...");
            iLogFile.Write(Kmsg2);
            //StartConnectionL(aIapId);
            
            iSess.OpenL ( KHTTPServer () );
            _LIT8(Kmsg3,"\nRHTTPClientServerSession opened");
            iLogFile.Write(Kmsg3);
            /*
            RHTTPConnectionInfo connInfo = iSess.ConnectionInfo();

            //Attach to socket server
            connInfo.SetPropertyL( iSess.StringPool().StringF(HTTP::EHttpSocketServ,
                                     RHTTPClientServerSession::GetTable() ),
                                     THTTPHdrVal(iSocketServ.Handle() ) );

            //Attach to connection
            TInt connPtr = reinterpret_cast<TInt>( &iConnection );
            connInfo.SetPropertyL( iSess.StringPool().StringF(
                                     HTTP::EHttpSocketConnection,
                                     RHTTPClientServerSession::GetTable() ),
                                     THTTPHdrVal(connPtr) );
            */
            
            iSess.RegisterDocumentRootL ( KAbsDocumentRoot, *this );
            _LIT8(Kmsg4,"\nDocumentRoot registered");
            iLogFile.Write(Kmsg4);
            iSess.SetSessionEventCallback ( this );
            
            //iUtils->Test ().Console ()->ClearScreen ();         
            _LIT ( KServerStartedMsg, "Http Server Started at Root..." );
            
            //_LIT8(Kmsg3,"server started");
            //iLogFile.Write(Kmsg3);
            
            //iUtils->Test ().Printf ( KServerStartedMsg );
            __FLOG_0 ( _T8 ( "Http Server Started at Root... "));
                        
            RStringPool stringPool = iSess.StringPool ();
            THTTPHdrVal ipValue;
            iSess.PropertySet ().Property ( stringPool.StringF ( HTTP::ELocalHost, RHTTPClientServerSession::GetTable () ), ipValue );
            //RBuf ipBuf;
            //ipBuf.Create ( ipValue.StrF ().DesC ().Length () );
            //ipBuf.Copy ( ipValue.StrF ().DesC () );
            //iUtils->Test ().Printf ( _L ( "http://" ) );
            //iUtils->Test ().Printf ( ipBuf );
            //iUtils->Test ().Printf ( _L ( "/pws/" ) );
            //ipBuf.Close ();
            TInt length = ipValue.StrF ().DesC ().Length ();
            
            iIPAddr.Create(length);
            iIPAddr.Copy(ipValue.StrF ().DesC ());
            
            _LIT8(Kmsg5,"\nIP addr obtained");
            iLogFile.Write(Kmsg5);
            
          
            _LIT ( KSelectOption, "\n\n Select an option \n\n" );
            //iUtils->Test ().Printf ( KSelectOption );
            _LIT ( KPossibleSelectionsText, " 2 Stop \n 3 Exit\n" );            
            _LIT ( KPossibleSelections,"23" );
            //iUtils->RequestSelection ( KPossibleSelectionsText, KPossibleSelections );  
            break;
            }
        case EStop:
            {           
            //iUtils->Test ().Console ()->ClearScreen ();
            _LIT ( KServerStoppedMsg, "Server Stopped..." );
            //iUtils->Test ().Printf ( KServerStoppedMsg );
            
            CleanupTransactions ();
            iSess.Close ();
            
            //SetupClientL ();
            
            break;
            }
        case EExit:
            {
            //CActiveScheduler::Stop ();
            }
            break;
        default: 
             break;
        } 
    }


void CHttpServer::CleanupTransactions ()
    {
    __FLOG_0 ( _T8 ( "CHttpServer::CleanupTransactions "));
    TInt i = iTransactions.Count () - 1;
    while ( iTransactions.Count () )
        {
        iTransactions[i]->Transaction ().Cancel ();
        CHttpServerTransactionBase* trans = iTransactions[i];
        iTransactions.Remove ( i );
        delete trans;
        --i;
        }
    iTransactions.Close (); 
    }
    
void CHttpServer::SetHeaderL(RHTTPHeaders aHeaders, TInt aHdrField, const TDesC8& aHdrValue)
    {
    __FLOG_1 ( _T8 ( "CHttpServer::SetHeaderL [aHdrField=%d]"), aHdrField);
    RStringF valStr = iSess.StringPool().OpenFStringL(aHdrValue);
    CleanupClosePushL(valStr);
    THTTPHdrVal val(valStr);
    aHeaders.SetFieldL(iSess.StringPool().StringF(aHdrField,RHTTPClientServerSession::GetTable()), val);
    CleanupStack::PopAndDestroy(&valStr); 
    }

void CHttpServer::ResetTimeElapsed()
// Resets timestamp to time now
    {
    __FLOG_0 ( _T8 ( "CHttpServer::ResetTimeElapsed"));
    iLastTimeStamp.UniversalTime(); 
    }


void CHttpServer::DisplayTimeElapsed()
// Calculate elapsed time since last measurement, and display
    {
    __FLOG_0 ( _T8 ( "CHttpServer::DisplayTimeElapsed"));
    TTime timeNow;
    timeNow.UniversalTime();
    TTimeIntervalMicroSeconds elapsedMicroSec =
                                    timeNow.MicroSecondsFrom(iLastTimeStamp);
    iLastTimeStamp = timeNow;
    /*
    iUtils->Test().Printf(
        _L("Time elapsed since last measurement is: %d ms\n"),
        elapsedMicroSec.Int64()/1000
        );
    */
    }

void CHttpServer::OnTransactionCompleted ( CHttpServerTransactionBase* iTrans )
    {
    __FLOG_1 ( _T8 ( "CHttpServer::OnTransactionCompleted  [iTrans =0x%X]"), iTrans );
    for ( TInt i = 0; i < iTransactions.Count (); ++i)
        {
        if (iTransactions[i] == iTrans)
            {
            delete iTrans;
            iTransactions.Remove (i);
            break;              
            }
        }
    }

void CHttpServer::MHFSessionRunL ( const THTTPSessionEvent& aEvent )
    {
    if ( aEvent.iStatus < 0 )
        {
        iSess.Close ();
        }
    }
    
TInt CHttpServer::MHFSessionRunError ( TInt /*aError*/, const THTTPSessionEvent& /*aEvent*/ )
    {
    return KErrNone;
    }
/*
void CHttpServer::StartHttpServer()
    {
    SetupClientL();
    }
*/

// ------------------------------------------------------

CHttpServerTransactionBase::~CHttpServerTransactionBase ()
    {
    __FLOG_0 ( _T8 ( "CHttpServerTransactionBase::~CHttpServerTransactionBase   "));
    iFile.Close ();     
    }

CHttpServerTransactionBase::CHttpServerTransactionBase ( MTransactionNotify& aNotify,/*CHttpExampleUtils& aUtils,*/ RFs& aFileServ )
: iNotify (aNotify), 
iFileServ ( aFileServ )
//iUtils ( aUtils )
    {
    __FLOG_OPEN ( "http", "httpexampleserver.txt" );
    __FLOG_0 ( _T8 ( "CHttpServerTransactionBase::CHttpServerTransactionBase "));       
    }

void CHttpServerTransactionBase::ConstructL ( RHTTPClientServerSession& aSession, const TUriC8& aUri, RStringF aMethod )
    {
    __FLOG_0 ( _T8 ( "CHttpServerTransactionBase::ConstructL "));
    iTransaction = aSession.OpenTransactionL(aUri, *this, aMethod);
    }


void CHttpServerTransactionBase::MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent& aEvent)
    {
    __FLOG_0 ( _T8 ( "CHttpServerTransactionBase::MHFRunL"));
    switch(aEvent.iStatus)
    {
    case THTTPEvent::ESucceeded:
    case THTTPEvent::EFailed:
        {
        aTransaction.Close();
        iNotify.OnTransactionCompleted(this);
        } break;
    default:
        {
        if (aEvent.iStatus < 0)
            {
            aTransaction.Close ();
            iNotify.OnTransactionCompleted ( this );            
            }
        } break;        
    }
    }




TInt CHttpServerTransactionBase::MHFRunError(TInt aError, RHTTPTransaction /* aTransaction */, const THTTPEvent& /* aEvent */)
    {
    __FLOG_1 ( _T8 ( "CHttpServerTransactionBase::MHFRunError [aError=%d]"), aError);
    //iUtils.Test().Printf(_L("MHFRunError fired with error code %d\n"), aError);
    return KErrNone;    
    }

void CHttpServerTransactionBase::SetHeaderL(RStringPool& aStringPool, RHTTPHeaders aHeaders, TInt aHdrField, const TDesC8& aHdrValue)
    {
    __FLOG_1 ( _T8 ( "CHttpServerTransactionBase::SetHeaderL [aHdrField=%d]"), aHdrField);
    RStringF valStr = aStringPool.OpenFStringL(aHdrValue);
    CleanupClosePushL(valStr);
    THTTPHdrVal val(valStr);
    aHeaders.SetFieldL(aStringPool.StringF(aHdrField,RHTTPClientServerSession::GetTable()), val);
    CleanupStack::PopAndDestroy(&valStr); 
    }


// -------------------------------------------------------

CHttpDataTransmitter* CHttpDataTransmitter::NewL ( MTransactionNotify& aNotify,/*CHttpExampleUtils& aUtils,*/ RFs& aFileServ, RHTTPClientServerSession& aSession, const TUriC8& aUri, RStringF aMethod )
    {   
    CHttpDataTransmitter* self = new (ELeave) CHttpDataTransmitter (aNotify, /*aUtils,*/ aFileServ);
    CleanupStack::PushL ( self );
    self->ConstructL ( aSession, aUri, aMethod );
    CleanupStack::Pop (); // self
    return self;    
    }

//
// methods from MHTTPTransactionCallback
//
void CHttpDataTransmitter::MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent& aEvent)
    {
    __FLOG_0 ( _T8 ( "CHttpDataTransmitter::MHFRunL"));
    switch (aEvent.iStatus)
        {
        case THTTPEvent::EGotRequestHeaders:
            {
            const TUriC8& uri = aTransaction.Request ().URI ();
            const TDesC8& uriDes = uri.UriDes ();
            
            if ( uriDes.CompareF ( KAbsDocumentRoot ) == 0 
                    || uriDes.CompareF ( KRelDocumentRoot ) == 0 )
                {
                RHTTPResponse response = aTransaction.Response ();
                RStringPool stringPool = aTransaction.Session ().StringPool ();
                RHTTPHeaders headers = response.GetHeaderCollection();
                TBuf8<128> referer;
                referer.Copy (_L("http://"));
                RStringF hostStr = stringPool.StringF (HTTP::EHost, RHTTPClientServerSession::GetTable());
                THTTPHdrVal hostVal;
                aTransaction.Request().GetHeaderCollection().GetField(hostStr, 0, hostVal);
                referer.Append(hostVal.StrF().DesC());
                referer.Append(KHttpSlash);
//              SetHeaderL (stringPool, headers, HTTP::EReferer, referer);
                referer.Append(KHomePage);
                // Root path. Redirect to the home page.
                SetHeaderL (stringPool, headers, HTTP::ELocation, referer);
                THTTPHdrVal hdr (0);
                headers.SetFieldL (stringPool.StringF (HTTP::EContentLength, RHTTPClientServerSession::GetTable()), hdr);
                response.SetStatusCode(HTTPStatus::EFound);
                RStringF statusText = stringPool.OpenFStringL ( KFound );
                
                response.SetStatusText (statusText);
                statusText.Close ();
                aTransaction.SubmitL ();
                //iTransSubmitted = ETrue;
                }           
            } 
            break;
        case THTTPEvent::EGotRequestBodyData:
            {
            User::Invariant ();
            }
            break;
        case THTTPEvent::ERequestComplete:
            {
            if ( !iTransSubmitted )
            {
            const TDesC8& uriDes = aTransaction.Request ().URI ().UriDes();
//          __FLOG_1 ( _T8 ("CHttpdProtocolHandler::MHFRunL: [uriDes = %S]"), uriDes );
                
            if ( OpenFile (uriDes) == KErrNone )
                {
                __FLOG_0 ( _T8 ( "CHttpDataTransmitter::MHFRunL: Sending Ok"));             
                RHTTPResponse response = aTransaction.Response();
                response.SetBody(*this);
                RHTTPHeaders headers = aTransaction.Response().GetHeaderCollection();
                RStringPool stringPool = aTransaction.Session().StringPool();
                SetHeaderL(stringPool, headers, HTTP::EContentType, iContentType);
                response.SetStatusCode (HTTPStatus::EOk);   
                RStringF statusText = stringPool.OpenFStringL ( KOk );
                
                response.SetStatusText (statusText);
                statusText.Close ();    
                THTTPHdrVal hdr (OverallDataSize());
                headers.SetFieldL (stringPool.StringF (HTTP::EContentLength, RHTTPClientServerSession::GetTable()), hdr);                                           
                }
            else
                {
                __FLOG_0 ( _T8 ( "CHttpDataTransmitter::MHFRunL: Sending Not Found"));
                
                RHTTPResponse response = aTransaction.Response();
                response.SetStatusCode (HTTPStatus::ENotFound);
                RStringF statusText = aTransaction.Session().StringPool().OpenFStringL ( KNotFound );
                
                response.SetStatusText (statusText);
                statusText.Close ();
                THTTPHdrVal hdr (0);
                response.GetHeaderCollection().SetFieldL (aTransaction.Session().StringPool().StringF (HTTP::EContentLength, RHTTPClientServerSession::GetTable()), hdr);                                                                                   
                }
            aTransaction.SubmitL ();
            iTransSubmitted = ETrue;
                
            }
            } 
            break;
        default:
            CHttpServerTransactionBase::MHFRunL(aTransaction, aEvent);
        }       
    }

TInt CHttpDataTransmitter::MHFRunError(TInt aError, RHTTPTransaction aTransaction, const THTTPEvent& aEvent)
    {
    __FLOG_1 ( _T8 ( "CHttpDataTransmitter::MHFRunError [aError=%d]"), aError);
    return CHttpServerTransactionBase::MHFRunError(aError, aTransaction, aEvent);   
    }

TInt CHttpDataTransmitter::OpenFile( const TDesC8& aHttpPath )
    {
    __FLOG_0 ( _T8 ( "CHttpDataTransmitter::OpenFile"));

    TBuf8<256> fileName;
    fileName.Copy(KRoot);           
    if (aHttpPath.Locate(KHttpSlash) == 0)  
        {
        // Skip that
        TPtrC8 ptr (aHttpPath.Mid(1));
        fileName.Append(ptr);
        //replace forward slash with backward
        for ( TInt index = 0; index < fileName.Length (); index++ )
            {
            if ( fileName[index] == TChar ( KHttpSlash ) )
                {
                fileName[index] = TChar ( '\\' );
                }
            }   
        }           
        
    HBufC* fileName16 = EscapeUtils::ConvertToUnicodeFromUtf8L (fileName);  
    TInt err = iFile.Open(iFileServ, *fileName16, EFileShareReadersOnly);
    
    TPtr ptr2 ( fileName16->Des() );
    //iUtils.Test().Printf(_L("File Name: %S"), &ptr2);
    __FLOG_1 ( _T8 ( "CHttpDataTransmitter::OpenFile [Error=%d]"), err);
    
    // For Hardware
    if ( err != KErrNone )
        {
        ptr2[0] = TChar ( 'Z' );
        err = iFile.Open ( iFileServ, ptr2, EFileShareReadersOnly );
        }
    __FLOG_1 ( _T8 ( "CHttpDataTransmitter::OpenFile [Error=%d]"), err);
    
    if ( err != KErrNone )  
        {       
        delete fileName16;
        return err;
        }
    
    TParse parser;
    parser.Set(ptr2, NULL, NULL);
    
    if ( ptr2.Find(KHtml) != KErrNotFound )
        {
        iContentType.Copy(KTextContent);            
        iContentType.Copy(KHtml);
        }
    else
        {
        iContentType.Copy(KImageContent);   
        iContentType.Copy(KGif);
        }
    delete fileName16;
    iFile.Size(iDataToSend);
    return KErrNone;
    }

CHttpDataTransmitter::CHttpDataTransmitter (MTransactionNotify& aNotify,/*CHttpExampleUtils& aUtils,*/ RFs& aFileServ)
: CHttpServerTransactionBase (aNotify, /*aUtils,*/ aFileServ)
    {
    __FLOG_OPEN ( "http", "httpexampleserver.txt" );
    __FLOG_0 ( _T8 ( "CHttpDataTransmitter::CHttpDataTransmitter "));       
    }

TBool CHttpDataTransmitter::GetNextDataPart(TPtrC8& aDataPart)
    {
    __FLOG_0 ( _T8 ( "CHttpDataTransmitter::GetNextDataPart"));
    iFile.Read (iData); 
    iDataToSend -= iData.Length ();
    aDataPart.Set (iData);
    return iDataToSend == 0;
    }

void CHttpDataTransmitter::ReleaseData()
    {
    __FLOG_0 ( _T8 ( "CHttpDataTransmitter::ReleaseData"));
    iData.SetLength (0);
    if (iDataToSend > 0)
        iTransaction.NotifyNewRequestBodyPartL ();
    else
        iFile.Close ();     
    }

TInt CHttpDataTransmitter::OverallDataSize()
    {
    __FLOG_0 ( _T8 ( "CHttpDataTransmitter::OverallDataSize"));
    TInt size;
    iFile.Size (size);
    return size;    
    }

TInt CHttpDataTransmitter::Reset()
    {
    __FLOG_0 ( _T8 ( "CHttpDataTransmitter::Reset"));
    return KErrNone;    
    }



/*
// ------------------------------------------------------------

LOCAL_D void TestL()
// Create a test object, invoke the tests using it and remove
    {
        
    //TRAPD(err,CHttpExampleUtils::InitCommsL()); 
    // create an active scheduler to use
    CActiveScheduler* scheduler = new(ELeave) CActiveScheduler();
    CleanupStack::PushL(scheduler);
    CActiveScheduler::Install(scheduler);
  
    // Create and start the client
    CHttpServer* httpCli = CHttpServer::NewL();         
    
    CZeroconfClient* browser = CZeroconfClient::NewL(*httpCli);
    browser->ConnectL();
    
    CActiveScheduler::Start();
    //
    CleanupStack::PopAndDestroy(1); //  scheduler
    delete httpCli;
    delete browser;
    }


GLDEF_C TInt E32Main()
// Main program - run the tests within a TRAP harness, reporting any errors that
// occur via the panic mechanism. Test for memory leaks using heap marking.
    {

    __UHEAP_MARK;
    CTrapCleanup* tc=CTrapCleanup::New();
    
    TRAPD(err,TestL());
    
    if (err!=KErrNone)
        User::Panic(_L("Test failed with error code: %i"), err);
    delete tc;
    __UHEAP_MARKEND;
    return KErrNone;
    }
*/

