zeroconf/zeroconfsharing/bjrhttpserver.cpp
changeset 21 ff5174af067c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zeroconf/zeroconfsharing/bjrhttpserver.cpp	Wed Jul 21 14:28:48 2010 +0530
@@ -0,0 +1,789 @@
+/*
+* 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;
+    }
+*/
+