⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gnhttpdown.cpp

📁 SYMIBNA 支持大型文件断点续传的引擎源代码
💻 CPP
字号:
/*
 ============================================================================
 Name        : GnHttpDown.cpp
 Author      : cheney.kan
 Version     : 1.0
 Copyright   : Your copyright notice
 Description : CGnHttpDown implementation
 ============================================================================
 */

#include <rhttpheaders.h>
#include <chttpformencoder.h>

#include <GnHttpDown.h>
#include <InternalGnHttpDown.h>
#include "GnHDRec.h"

_LIT8(KGnHDAcceptType, "*/*"); // any thing is ok

_LIT8(KGnHDBlank, ""); // no thing
_LIT8(KGnHDSpace, " "); // a Space

_LIT8(KGnUserAgent, "GnHttpDownloader 0.9");    // Name of this client app

_LIT8(KGnHDFromTo, "-");
_LIT8(KGnHDRangeTxt, "bytes=");





CGnHttpDown* CGnHttpDown::NewLC(MGnHTTPTransactionCallback & aNotifier)
    {
    CGnHttpDown* self = new (ELeave) CGnHttpDown();
    CleanupStack::PushL(self);
    self->ConstructL(aNotifier);
    return self;
    }

CGnHttpDown* CGnHttpDown::NewL(MGnHTTPTransactionCallback & aNotifier)
    {
    CGnHttpDown* self = CGnHttpDown::NewLC(aNotifier);
    CleanupStack::Pop(); // self;
    return self;
    }


void CGnHttpDown::SetFileUriL(const TDesC & aUri)
    {
    /*
    DeleteAndNull(iUri);
    iUri = HBufC8::NewL(aUri.Length());
    iUri->Des().Copy(aUri);
    User::LeaveIfError(iUriParser.Parse(*iUri));
    //*/
    __ASSERT_ALWAYS(iGnHDStatus != EDownlonding, 
        GnHttpDownPanic(EGnHttpDownBadStatus));
    
    iCurFileInfo->iUri.Copy(aUri);
    User::LeaveIfError(iUriParser.Parse(iCurFileInfo->iUri));

    iHasSepecUriInfo = ETrue;
    if(iHasSepecRecInfo)
        iGnHDStatus=EInitial;
    }

HBufC * CGnHttpDown::GetFileUriL() const
    {
    //__ASSERT_DEBUG(iUri != NULL, GnHttpDownPanic(EGnHttpDownNullPointer));
    HBufC * uri = HBufC::NewL(iCurFileInfo->iUri.Length());
    uri->Des().Copy(iCurFileInfo->iUri);
    return uri;
    }

void CGnHttpDown::RemoveUriInfoFromRecL(const TDesC & aUri)
{
    HBufC * internalUri = GetFileUriL();
    CleanupStack::PushL(internalUri);
    if(aUri == static_cast<const TDesC &>(internalUri->Des()) 
        && iGnHDStatus == CGnHttpDown::EDownlonding)
        {
        User::Leave(KErrInUse);
        }
    CleanupStack::PopAndDestroy(internalUri); internalUri = NULL;
    
    HBufC8 * internalUri8 = HBufC8::NewLC(aUri.Length());
    internalUri8->Des().Copy(aUri);
    iRecEngine->RemoveUriInfoFromRecL(*internalUri8);
    CleanupStack::PopAndDestroy(internalUri8); internalUri8 = NULL;
}

void CGnHttpDown::SetRecFileL(const TDesC & aRecFile)
{
    //__ASSERT_ALWAYS(!iIsRunning, GnHttpDownPanic(EGnHttpDownBadStatus));
    __ASSERT_ALWAYS(iGnHDStatus != EDownlonding, 
        GnHttpDownPanic(EGnHttpDownBadStatus));
    //iGnHDStatus=EInitial;
    TRAPD(err, iRecEngine->OpenRecFileL(aRecFile););
    if(err != KErrNone)
        iRecEngine->OpenOrCreateRecFileL(aRecFile);

    iHasSepecRecInfo = ETrue;
    if(iHasSepecUriInfo)
        iGnHDStatus=EInitial;
}

const TDesC & CGnHttpDown::GetRecFileName() const
{
    return iRecEngine->GetRecFileName();
}

void CGnHttpDown::Stop()
{
    Cancel();
}

void CGnHttpDown::DownloadL(
    CGnHttpDown::TDownType aReqType, 
    TInt32 aFromBytes, 
    TInt32 aToBytes, 
    TBool aisSupportResume)
{   
    //__ASSERT_ALWAYS(!iIsRunning, GnHttpDownPanic(EGnHttpDownBadStatus));
    __ASSERT_ALWAYS(iGnHDStatus == EInitial, 
        GnHttpDownPanic(EGnHttpDownBadStatus));
    
    //iIsRunning = ETrue;
    iIsSupportResume = aisSupportResume;

    // Create the transaction
    iTransaction = iSession.OpenTransactionL(iUriParser, *this,
        iSession.StringPool().StringF(aReqType, RHTTPSession::GetTable()));

    // Set transaction headers
    RHTTPHeaders headers = iTransaction.Request().GetHeaderCollection();
    AddHeaderL(headers, HTTP::EUserAgent, KGnUserAgent);
    AddHeaderL(headers, HTTP::EAccept, KGnHDAcceptType);

    iRange.Zero();
    iRange.Append(KGnHDRangeTxt); // "bytes="
    iRange.AppendNum(aFromBytes); // for example, iRange = "bytes=1023"
    iRange.Append(KGnHDFromTo); // then, iRange = "bytes=1023-"
    
    //if(aToBytes > aFromBytes)
    if(aToBytes >= 0)
        iRange.AppendNum(aToBytes); // then, iRange = "bytes=1023-2009", 
    //else iRange = "bytes=1023-"
        
    AddHeaderL(headers, HTTP::ERange, iRange);
    if(HTTP::EPOST == aReqType)
        {
        __ASSERT_DEBUG(iFormEncoder != NULL, GnHttpDownPanic(EGnHttpDownNullPointer));
        // Set the form encoder as the data supplier
        iTransaction.Request().SetBody(*iFormEncoder);
        }
    iCurFileInfo->iPoint = aFromBytes;
    iGnHDStatus=EDownlonding;
    // Submit the request
    iTransaction.SubmitL();
}

TInt CGnHttpDown::DownloadResumeL(CGnHttpDown::TDownType aReqType, 
        TInt32 aToBytes, TBool aisSupportResume)
{
    //__ASSERT_ALWAYS(!iIsRunning, GnHttpDownPanic(EGnHttpDownBadStatus));
    __ASSERT_ALWAYS(iGnHDStatus == EInitial, 
        GnHttpDownPanic(EGnHttpDownBadStatus));
    //iGnHDStatus=EDownlonding;
    
    TInt errCode = KErrNotFound;
    // search the uri in the record table
    TInt32 fromBytes = iRecEngine->GetPositionPreTimeL(iCurFileInfo->iUri);
    // if find, deliver the process to DownloadL
    if(fromBytes > 0)
        {
        errCode = KErrNone;
        //TUint32 fromBytes = 0;
    
        DownloadL(aReqType, fromBytes, aToBytes, aisSupportResume);
        }

    // else return KErrNotFound
    
    return errCode;
}

void CGnHttpDown::SetPostDataBodyL(const TDesC &aFieldName, const TDesC &aFieldValue)
{
    DeleteAndNull(iFormEncoder);
    iFormEncoder = CHTTPFormEncoder::NewL();
    HBufC8 * fieldName = HBufC8::NewLC(aFieldName.Length());
    fieldName->Des().Copy(aFieldName);
    HBufC8 * fieldValue = HBufC8::NewLC(aFieldValue.Length());
    fieldValue->Des().Copy(aFieldValue);
    iFormEncoder->AddFieldL(*fieldName, *fieldValue);

    CleanupStack::PopAndDestroy(fieldValue);
    CleanupStack::PopAndDestroy(fieldName);
}

void CGnHttpDown::Cancel()
{
    iTransaction.Cancel();
    if(EDownlonding == iGnHDStatus)
    {
        iGnHDStatus = EInitial;
    }
}

CGnHttpDown::GnHDStatus CGnHttpDown::CurrentStatus()
{
    return iGnHDStatus;
}

/*
void CGnHttpDown::CloseAndReset()
{
    Cancel();
}
//*/

CGnHttpDown::~CGnHttpDown()
    {
    DeleteAndNull(iResponseBuffer);
    //DeleteAndNull(iUri);
    DeleteAndNull(iFormEncoder);
    DeleteAndNull(iRecEngine);
    DeleteAndNull(iCurFileInfo);
    iSession.Close();
    }

CGnHttpDown::CGnHttpDown()
    {
    // No implementation required
    }




void CGnHttpDown::ConstructL(MGnHTTPTransactionCallback & aNotifier)
    {
    iUiNotifier = &aNotifier;
    
    iSession.OpenL();
    
    // Construct the form encoder
    iFormEncoder = CHTTPFormEncoder::NewL();
    iFormEncoder->AddFieldL(KGnHDSpace, KGnHDSpace); // the content is blank
    
    //DeleteAndNull(iUri);
    //iUri = HBufC8::NewL(1);
    iCurFileInfo = new (ELeave) CGnHDRecFmt;
    iRecEngine = CGnHDRec::NewL();
    iGnHDStatus = EUninitial;
    }

/*
void CGnHttpDown::ParseUriL(const TDesC& aUri)
{
    DeleteAndNull(iUri);
    iUri = HBufC8::NewL(aUri.Length());
    iUri->Des().Copy(aUri);
    User::LeaveIfError(iUriParser.Parse(*iUri));
}
//*/

void CGnHttpDown::AddHeaderL(
    RHTTPHeaders aHeaders, 
    TInt aHeaderField, 
    const TDesC8& aHeaderValue)
{
    RStringPool stringPool = iSession.StringPool();
    RStringF valStr = stringPool.OpenFStringL(aHeaderValue);
    THTTPHdrVal headerVal(valStr);
    aHeaders.SetFieldL(stringPool.StringF(aHeaderField, RHTTPSession::GetTable()), headerVal);
    valStr.Close();
}

void CGnHttpDown::MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent& aEvent)
{
    RDebug::Printf("aEvent.iStatus=%d", aEvent.iStatus);

    MHTTPDataSupplier* dataSupplier = NULL;
    TPtrC8 ptr;
    
    switch (aEvent.iStatus)
    {
        case THTTPEvent::EGotResponseHeaders:
        {
        }
            break;

        case THTTPEvent::EGotResponseBodyData:
        {   
            // Get text of response body
            dataSupplier = aTransaction.Response().Body();
            dataSupplier->GetNextDataPart(ptr);
                        
            if(iIsSupportResume)
            {
                iCurFileInfo->iPoint += ptr.Size();

                // update the recored file.
                if(iUiNotifier->ShouldUpdateTheResumeRecL(ptr, this))
                {
                    iRecEngine->UpdateRecPosL(*iCurFileInfo);
                }
            }
        }
            break;

        case THTTPEvent::EResponseComplete:
        {
            iCurFileInfo->iPoint = 0;
            
            iGnHDStatus = EInitial;
            // remove this record from the record file
            if(iIsSupportResume)
                iRecEngine->DeleteRecAndCloseL();
        }
            break;
    }

    if(dataSupplier != NULL)
        {
        iUiNotifier->MHFRunL(aTransaction, aEvent, ptr, this);
        dataSupplier->ReleaseData();
        }
    else
        {
        iUiNotifier->MHFRunL(aTransaction, aEvent, KGnHDBlank, this);
        }
}

TInt CGnHttpDown::MHFRunError(TInt aError, RHTTPTransaction aTransaction, const THTTPEvent& aEvent)
{
    return iUiNotifier->MHFRunError(aError, aTransaction, aEvent, this);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -