Symbian C++ : Multipart/form-data
Article Metadata
The following code can be used to upload any file, image, text, video etc.. as a binary file to a server.
The HTTPEngine should have MHTTPDataSupplier as its parent class, as the following functions need to be implemented for the upload process
TBool GetNextDataPart(TPtrC8& aDataPart);
void ReleaseData();
TInt Reset();
TInt OverallDataSize();
The content-type for the post should be, hence add following lines to ClientEngine.h and declare variables under the CClientEngine class
_LIT8(KPostContentType, "multipart/form-data; boundary=AaB03x");
TBuf<255> iFileName;
HBufC8 *iPostDataImage;
HBufC16 *iResponseBuffer;
TBool iDataAvailable
In the MHFRunL the case EGotResponseBodyData should do this
MHTTPDataSupplier* dataSupplier = aTransaction.Response().Body();
TPtrC8 ptr;
iDataAvailable = dataSupplier->GetNextDataPart(ptr);
// Convert to 16-bit descriptor
HBufC* buf = HBufC::NewLC(ptr.Length());
buf->Des().Copy(ptr);
// Append to iResponseBuffer
if (iResponseBuffer==NULL)
{
iResponseBuffer = buf->AllocL();
}
else
{
iResponseBuffer = iResponseBuffer->ReAllocL(iResponseBuffer->Length()+buf->Length());
iResponseBuffer->Des().Append(*buf);
}
// Release buf
CleanupStack::PopAndDestroy(buf);
if(!iDataAvailable)
{
iRunning=EFalse;
iTransaction.Close();
}
else
{
dataSupplier->ReleaseData();
}
POST code
Get the file you want to upload in binary format
RFs aFs;
User::LeaveIfError(aFs.Connect());
CleanupClosePushL(aFs);
RFile aFile;
User::LeaveIfError(aFile.Open(aFs, iFileName, EFileShareAny));
TInt aSize;
User::LeaveIfError(aFile.Size(aSize));
iPostDataImage = HBufC8::NewL(aSize);
TPtr8 aPtr = iPostDataImage->Des();
//Obviously we have to read in the data to the iPostDataImage (ray)
aFile.Read(0, aPtr, aSize);
aFile.Close();
aFs.Close();
CleanupStack::PopAndDestroy(&aFs);
Using EFileShareAny ensures that if the file can be opened by any other application. The file is read into iPostDataImage as a binary file.
Now create the upload format
_LIT8(KDataStart,"--AaB03x");
_LIT8(KCrlf,"\r\n");
_LIT8(KContent,"Content-Disposition: form-data; name='userfile'; filename='");
_LIT8(KFileCompletion,"'");
_LIT(KContent2,"Content-Type: image/gif");
_LIT(KContent3,"Content-Transfer-Encoding: binary");
_LIT8(KDataEnd,"--AaB03x--");
iPostData = HBufC8::NewL(650+aPtr.Length());
TPtr8 iPostDataPtr = iPostData->Des();
iPostDataPtr.Zero();
iPostDataPtr.Append(KCrlf);
iPostDataPtr.Append(KDataStart);
iPostDataPtr.Append(KCrlf);
iPostDataPtr.Append(KContent);
iPostDataPtr.Append(iFileName);
iPostDataPtr.Append(KFileCompletion);
iPostDataPtr.Append(KCrlf);
iPostDataPtr.Append(KContent2);
iPostDataPtr.Append(KCrlf);
iPostDataPtr.Append(KContent3);
iPostDataPtr.Append(KCrlf);
iPostDataPtr.Append(KCrlf);
iPostDataPtr.Append(aPtr); //the file in binary
iPostDataPtr.Append(KCrlf);
iPostDataPtr.Append(KDataEnd);
iPostDataPtr.Append(KCrlf);
Submit the transaction
RHTTPHeaders hdr = iTransaction.Request().GetHeaderCollection();
SetHeaderL(hdr, HTTP::EUserAgent, KUserAgent);
SetHeaderL(hdr, HTTP::EAccept, KAccept);
SetHeaderL(hdr, HTTP::EContentType, KPostContentType);
MHTTPDataSupplier* dataSupplier = this;
iTransaction.Request().SetBody(*dataSupplier);
iTransaction.SubmitL();
Implement DataSupplier functions
TBool CHTTPExampleEngine::GetNextDataPart(TPtrC8& aDataPart)
{
TBool retVal = EFalse;
aDataPart.Set(iPostData->Des());
retVal = (aDataPart.Length() == 0);
iDataAvailable=retVal;
return retVal;
}
TInt CHTTPExampleEngine::OverallDataSize()
{
if(iPostData)
return iPostData->Length();
else
return KErrNotFound ;
}
void CHTTPExampleEngine::ReleaseData()
{
if(iDataAvailable)
iTransaction.NotifyNewRequestBodyPartL();
}
Any binary file can be uploaded with this upload code.


I am currently starting with Symbian, and trying to implement this example. To me it seems as if the file would actually never be read? I tried
iPostDataImage = HBufC8::NewL(aSize); TPtr8 aPtr = iPostDataImage->Des();
aFile.Read(aPtr);
aFile.Close(); aFs.Close();
and this worked. After I am done with all the programming i will update this example.
Contents
file size limit
hi, i've used the way mentioned in this article to upload images to my server.
however for small files which file size is <200KB it works fine
for files larger than that i face a problem with the application crashing everytime it tries to allocate the HBufC8*....
any work around to this problem? anyone else faced it?
it works fine on emulator only crashes on phone due to memory limitations i suspect
== Video upload using Multipart form ==
Hi,
I am trying to upload a recorded video file to a server. I followed all the steps mentioned in the article. My question is- where do i make a call to a function which creates the upload Format while posting data in multipart form from my HTTPEngine.?
I have created the following function for upload format::
SetHTTPMultiFormData() { _LIT8(KDataStart,"--AaB03x"); _LIT8(KCrlf,"\r\n"); //_LIT8(KContent,"Content-Disposition: form-data; name='userfile'; filename='"); _LIT8(KContent,"Content-Disposition: form-data; name='"); _LIT8(KFileCompletion,"'");
_LIT(KContent2,"Content-Type: video/3gpp"); _LIT(KContent3,"Content-Transfer-Encoding: binary"); _LIT8(KDataEnd,"--AaB03x--");
CVRexAppUi* iVRecorderAppUi = static_cast<CVRexAppUi*>(iAvkonAppUi); TFileName filePath = PathInfo::PhoneMemoryRootPath(); filePath.Append(PathInfo::VideosPath()); filePath.Append(KNewVideoFileName);
TPtr8 FilePtr = iVRecorderAppUi->iVideoFileData->Des();
iPostData = HBufC8::NewL(650+FilePtr.Length());
TPtr8 iPostDataPtr = iPostData->Des(); iPostDataPtr.Zero();
iPostDataPtr.Append(KCrlf); iPostDataPtr.Append(KDataStart); iPostDataPtr.Append(KCrlf); iPostDataPtr.Append(KContent); iPostDataPtr.Append(filePath);//KNewVideoFileName); iPostDataPtr.Append(KFileCompletion); iPostDataPtr.Append(KCrlf); iPostDataPtr.Append(KContent2); iPostDataPtr.Append(KCrlf); iPostDataPtr.Append(KContent3); iPostDataPtr.Append(KCrlf); iPostDataPtr.Append(KCrlf); iPostDataPtr.Append(FilePtr); //the file in binary iPostDataPtr.Append(KCrlf); iPostDataPtr.Append(KDataEnd); iPostDataPtr.Append(KCrlf); }
Where do i make a call to this function in HTTPEngine.. I tried to invoke the upload format Inside IssueHTTPPostL(), but it doesn't work out..
Please correct me if i am on wrong trial...
Thanks, Datta
MultiPart form upload video----How to set upload format
Hi,
I am trying to upload a recorded video file to a server. I followed all the steps mentioned in the article. Symbian C++ : Multipart/form-data
My question is- where do i make a call to a function which creates the upload Format while posting data in multipart form from my HTTPEngine.?
I have created the following function for upload format::
SetHTTPMultiFormData() { _LIT8(KDataStart,"--AaB03x"); _LIT8(KCrlf,"\r\n"); //_LIT8(KContent,"Content-Disposition: form-data; name='userfile'; filename='"); _LIT8(KContent,"Content-Disposition: form-data; name='"); _LIT8(KFileCompletion,"'");
_LIT(KContent2,"Content-Type: video/3gpp"); _LIT(KContent3,"Content-Transfer-Encoding: binary"); _LIT8(KDataEnd,"--AaB03x--");
CVRexAppUi* iVRecorderAppUi = static_cast<CVRexAppUi*>(iAvkonAppUi); TFileName filePath = PathInfo::PhoneMemoryRootPath(); filePath.Append(PathInfo::VideosPath()); filePath.Append(KNewVideoFileName);
TPtr8 FilePtr = iVRecorderAppUi->iVideoFileData->Des();
iPostData = HBufC8::NewL(650+FilePtr.Length());
TPtr8 iPostDataPtr = iPostData->Des(); iPostDataPtr.Zero();
iPostDataPtr.Append(KCrlf); iPostDataPtr.Append(KDataStart); iPostDataPtr.Append(KCrlf); iPostDataPtr.Append(KContent); iPostDataPtr.Append(filePath);//KNewVideoFileName); iPostDataPtr.Append(KFileCompletion); iPostDataPtr.Append(KCrlf); iPostDataPtr.Append(KContent2); iPostDataPtr.Append(KCrlf); iPostDataPtr.Append(KContent3); iPostDataPtr.Append(KCrlf); iPostDataPtr.Append(KCrlf); iPostDataPtr.Append(FilePtr); //the file in binary iPostDataPtr.Append(KCrlf); iPostDataPtr.Append(KDataEnd); iPostDataPtr.Append(KCrlf); }
Where do i make a call to this function in HTTPEngine.. I tried to invoke the upload format Inside IssueHTTPPostL(), but it doesn't work out..
Please correct me if i am on wrong trial...
Thanks, Datta
Upload Engine.h and Engine.cpp files
Hi, Could any one please upload the .h and .cpp files or tell me what is iResponce buffer in "EGotResponseBodyData"... I am also implementing this example but facing some problems in sending larger files >1k. Thanx in anticipation.
regards, Farhan
Cryptyritu - Image upload example not working
Hi, I tried uploading an image of 4kb using the above code snippet. But it is not working. I am getting an http code 200 as response from server, but then the server says there is no uploaded file or the length of file is 0. I have used the HttpClientExample and the above code snippet.I have pasted the whole ClientAppUi.cpp and ClientEngine.cpp. But the relevant part is case:EClientPost in HandleCommandL(TInt aCommand) and CreateImageData(KServerUrl, KMimeType)) method in ClientEngine.cpp.
In ClientAppUi:
/*
// Schemes for given uris _LIT(KHttpPrefix, "http://"); _LIT8(KHttpPrefix8, "http://");
// HTTPS schemes _LIT(KHttpsPrefix, "https://"); _LIT8(KHttpsPrefix8, "https://");
_LIT8(KMimeType, "text/plain"); _LIT8(KServerUrl,"http://my.uploaded.image.aspx"); //server url
// ---------------------------------------------------------------------------- // CClientAppUi::ConstructL() // // Second phase construction. // ---------------------------------------------------------------------------- void CClientAppUi::ConstructL()
{ BaseConstructL(EAknEnableSkin);// ---------------------------------------------------------------------------- // CClientAppUi::CClientAppUi() // // First phase construction. // ---------------------------------------------------------------------------- CClientAppUi::CClientAppUi()
{ }// ---------------------------------------------------------------------------- // CClientAppUi::~CClientAppUi() // // Destructor. // ---------------------------------------------------------------------------- CClientAppUi::~CClientAppUi()
{ delete iEngine; if (iAppView) { iEikonEnv->RemoveFromStack(iAppView); delete iAppView; } }// ---------------------------------------------------------------------------- // CClientAppUi::HandleCommandL() // // Handles user commands. // ---------------------------------------------------------------------------- void CClientAppUi::HandleCommandL(TInt aCommand)
{ switch(aCommand) { case EEikCmdExit: case EAknSoftkeyExit: Exit(); break;case EClientGet: { // Issue HTTP get to engine; first cancel possible existing transaction iEngine->CancelTransaction();// Query uri TBuf<KDefaultBufferSize> uri; CAknTextQueryDialog* dlg = new (ELeave) CAknTextQueryDialog(uri, CAknQueryDialog::ENoTone);if (! dlg->ExecuteLD(R_DIALOG_URI_QUERY)) break;// Insert prefix to uri (it must begin with "http://" or "https://") TBuf8<KDefaultBufferSize> uri8; uri.LowerCase(); if(uri.Find(KHttpPrefix) == KErrNotFound && uri.Find(KHttpsPrefix) == KErrNotFound) { // If the uri does not contain http or https, // use the default, "http://" uri8.Append(KHttpPrefix8); uri8.Append(uri); } else { uri8.Copy(uri); }// Start transaction // TODO: TRAPD(err, iEngine->IssueHTTPGetL(uri8)); } break;case EClientPost: { // Issue HTTP post to engine; first cancel possible existing transaction iEngine->CancelTransaction();// Query uri and data to post TBuf<KDefaultBufferSize> uri; TBuf<KDefaultBufferSize> postData; CAknMultiLineDataQueryDialog* dlg = CAknMultiLineDataQueryDialog::NewL(uri, postData);if (!dlg->ExecuteLD(R_DIALOG_URI_POST_QUERY)) break;// Insert prefix to uri (it must begin with "http://" or "https://") TBuf8<KDefaultBufferSize> uri8; uri.LowerCase(); if(uri.Find(KHttpPrefix) == KErrNotFound && uri.Find(KHttpsPrefix) == KErrNotFound) { // If uri does not contain http or https, // use the default, "http://" uri8.Append(KHttpPrefix8); uri8.Append(uri); } else { uri8.Copy(uri); }TBuf8<KDefaultBufferSize> postData8; postData8.Copy(postData);// TRAPD(err, iEngine->IssueHTTPPostL(uri8, KMimeType, postData8));
// iEngine->CreateImageData(uri8, KMimeType);
// TODO: Error handling if (err) { } } break; case EClientCancel: { // Cancel current transaction iEngine->CancelTransaction(); } break;// Switch focus to the other rich text editor case EClientSwitchFocus: { iAppView->SwitchFocus(); } break; case EClientHelp: { CArrayFix <TCoeHelpContext>* buf = CCoeAppUi::AppHelpContextL(); HlpLauncher::LaunchHelpApplicationL( iEikonEnv->WsSession(), buf ); } break;case EClientAbout: { HBufC* title = iEikonEnv->AllocReadResourceLC(R_ABOUT_DIALOG_TITLE); HBufC* msg = iEikonEnv->AllocReadResourceLC(R_ABOUT_DIALOG_TEXT);// Note: CodeScanner gives a false positive of "Neglected to put // variable on cleanup stack (Id: 35)" on dlg. CAknMessageQueryDialog* dlg = CAknMessageQueryDialog::NewL(*msg); // CSI: 35 # dlg->PrepareLC(R_DIALOG_ABOUT); dlg->SetHeaderTextL(*title); dlg->RunLD();CleanupStack::PopAndDestroy(msg); CleanupStack::PopAndDestroy(title); } break;default: { Panic(EClientUi); } break; } }// ----------------------------------------------------------------------------- // CClientAppUi::HelpContextL() // // Return the help context for this application. // ----------------------------------------------------------------------------- CArrayFix <TCoeHelpContext>* CClientAppUi::HelpContextL() const
{ CArrayFixFlat <TCoeHelpContext>* array = new (ELeave)CArrayFixFlat <TCoeHelpContext>(1); CleanupStack::PushL(array); array->AppendL(TCoeHelpContext(KUidHelpFile, KContextApplication)); CleanupStack::Pop(array); return array; }// ---------------------------------------------------------------------------- // CClientAppUi::DynInitMenuPaneL() // // Initializes the menu pane when it's activated. // ---------------------------------------------------------------------------- void CClientAppUi::DynInitMenuPaneL(TInt aMenuId, CEikMenuPane* aMenuPane)
{ // "Cancel" selection is only available when trasaction running in engine if (aMenuId == R_EXAMPLECLIENT_MENU) aMenuPane->SetItemDimmed(EClientCancel, !iEngine->IsRunning()); }// end of file
In ClientEngine.cpp
/*
// Used user agent for requests _LIT8(KUserAgent, "SimpleClient 1.0"); //_LIT8(KPostContentType, "multipart/form-data; boundary=AaB03x");
// This client accepts all content types. // (change to e.g. "text/plain" for plain text only) _LIT8(KAccept, "*/*");
_LIT(KTextPreferredCarrierAvailable,"Preferred carrier available"); _LIT(KTextNewCarrierActive, "New carrier active"); _LIT8(KContType,"Content-Type: image/jpeg"); _LIT(KFilePath,"E:\\Images\\star.jpg"); _LIT(KFileDestPath,"E:\\Images\\star1.jpg");
const TInt KStatustextBufferSize = 32; const TInt KInfotextBufferSize = 64; const TInt KURIBufferSize = 128;
// ---------------------------------------------------------------------------- // CClientEngine::NewL() // ---------------------------------------------------------------------------- CClientEngine* CClientEngine::NewL(MClientObserver& aObserver)
{ CClientEngine* self = CClientEngine::NewLC(aObserver); CleanupStack::Pop(self); return self; }// ---------------------------------------------------------------------------- // CClientEngine::NewLC() // ---------------------------------------------------------------------------- CClientEngine* CClientEngine::NewLC(MClientObserver& aObserver)
{ CClientEngine* self = new (ELeave) CClientEngine(aObserver); CleanupStack::PushL(self); self->ConstructL(); return self; }// ---------------------------------------------------------------------------- // CClientEngine::CClientEngine() // ---------------------------------------------------------------------------- CClientEngine::CClientEngine(MClientObserver& aObserver)
iObserver(aObserver), iPostData(NULL), iConnectionSetupDone(EFalse), iPrevProfileId(-1), iTransactionOpen(EFalse) { }// ---------------------------------------------------------------------------- // CClientEngine::~CClientEngine() // ---------------------------------------------------------------------------- CClientEngine::~CClientEngine()
{ Cancel();if (iTransactionOpen) { iTransaction.Close(); iTransactionOpen = EFalse; } if (iMobility) { iMobility->Cancel(); } delete iMobility;// ---------------------------------------------------------------------------- // CClientEngine::ConstructL() // ---------------------------------------------------------------------------- void CClientEngine::ConstructL()
{ CActiveScheduler::Add(this); }// ---------------------------------------------------------------------------- // CClientEngine::SetupConnectionL() // ---------------------------------------------------------------------------- void CClientEngine::SetupConnectionL()
{ if (iConnectionSetupDone) { // Connection setup is done User::Leave(KErrAlreadyExists); } if (IsActive()) { User::Leave(KErrInUse); }// Open CCmApplicationSettingsUi TCmSettingSelection userSelection; CCmApplicationSettingsUi* settings = CCmApplicationSettingsUi::NewL(); CleanupStack::PushL(settings); TUint listedItems = CMManager::EShowAlwaysAsk | CMManager::EShowDefaultConnection | CMManager::EShowDestinations | CMManager::EShowConnectionMethods; TBearerFilterArray filter; TBool selected = settings->RunApplicationSettingsL(userSelection,listedItems,filter); CleanupStack::PopAndDestroy(settings);// Check selection if (selected) { switch (userSelection.iResult) { case CMManager::EDestination: { TConnSnapPref prefs; prefs.SetSnap(userSelection.iId); User::LeaveIfError(iSocketServ.Connect()); User::LeaveIfError(iConnection.Open(iSocketServ)); iConnection.Start(prefs, iStatus); break; } case CMManager::EConnectionMethod: { TCommDbConnPref prefs; prefs.SetIapId(userSelection.iId); prefs.SetDialogPreference(ECommDbDialogPrefDoNotPrompt); User::LeaveIfError(iSocketServ.Connect()); User::LeaveIfError(iConnection.Open(iSocketServ)); iConnection.Start(prefs, iStatus); break; } case CMManager::EDefaultConnection: { User::LeaveIfError(iSocketServ.Connect()); User::LeaveIfError(iConnection.Open(iSocketServ)); iConnection.Start(iStatus); break; } default: // EAlwaysAsk { TCommDbConnPref prefs; prefs.SetDialogPreference(ECommDbDialogPrefPrompt); User::LeaveIfError(iSocketServ.Connect()); User::LeaveIfError(iConnection.Open(iSocketServ)); iConnection.Start(prefs, iStatus); } } SetActive(); } }// ---------------------------------------------------------------------------- // CClientEngine::FindExistingConnection() // ---------------------------------------------------------------------------- TBool CClientEngine::FindExistingConnection()
{ // NOTE: this method is not in use// Enumerates through existing connections and tries to find one that matches // the selected IAP. If one is found, ETrue is returned; otherwise, EFalse. TBool connected = EFalse; TConnectionInfoBuf connInfo; TUint count; if (iConnection.EnumerateConnections(count) == KErrNone) { for (TUint i=1; i<=count; i++) { // Note: GetConnectionInfo expects 1-based index. if (iConnection.GetConnectionInfo(i, connInfo) == KErrNone) { if (connInfo().iIapId == iSelectedIap) { connected = ETrue; break; } } } } return connected; }// ---------------------------------------------------------------------------- // CClientEngine::SetHeaderL() // ---------------------------------------------------------------------------- void CClientEngine::SetHeaderL(RHTTPHeaders aHeaders,
TInt aHdrField, const TDesC8& aHdrValue) { RStringF valStr = iSession.StringPool().OpenFStringL(aHdrValue); CleanupClosePushL(valStr); THTTPHdrVal val(valStr); aHeaders.SetFieldL(iSession.StringPool().StringF(aHdrField, RHTTPSession::GetTable()), val); CleanupStack::PopAndDestroy(); // valStr }// ---------------------------------------------------------------------------- // CClientEngine::IssueHTTPGetL() // ---------------------------------------------------------------------------- void CClientEngine::IssueHTTPGetL(const TDesC8& aUri)
{ if (IsActive()) { return; } iEngineState = EGet; delete iUri; iUri = NULL; delete iContentType; iContentType = NULL; delete iBody; iBody = NULL; iUri = aUri.AllocL();// Create HTTP connection TRAPD(err, SetupConnectionL()); if (err == KErrAlreadyExists) { DoHTTPGetL(); } else if (err != KErrNone) { HBufC* resTxCancelled = StringLoader::LoadLC(R_HTTP_TX_CANCELLED); iObserver.ClientEvent(*resTxCancelled); CleanupStack::PopAndDestroy(resTxCancelled); return; } }// ---------------------------------------------------------------------------- // CClientEngine::CreateImageData1() //
void CClientEngine::CreateImageData1(const TDesC8& aUri,
{ iFileName.Copy(KFilePath); RFs aFs; User::LeaveIfError(aFs.Connect()); CleanupClosePushL(aFs);
RFile aFile;
User::LeaveIfError(aFile.Open(aFs, iFileName, EFileShareAny));
TInt aSize; User::LeaveIfError(aFile.Size(aSize));
iPostDataImage = HBufC8::NewL(aSize); TPtr8 aPtr = iPostDataImage->Des();
//Obviously we have to read in the data to the iPostDataImage (ray) // aFile.Read(0, aPtr, aSize); aFile.Read(aPtr);
aFile.Close(); aFs.Close(); CleanupStack::PopAndDestroy(&aFs);
/////////////////////////////////////////////
RFile file; RFs fsSession; //= iCoeEnv->FsSession(); User::LeaveIfError(fsSession.Connect()); CleanupClosePushL(fsSession); User::LeaveIfError(file.Create(fsSession, KFileDestPath, EFileWrite)); CleanupClosePushL(file); User::LeaveIfError(file.Write(aPtr, aPtr.Length()));
file.Close(); fsSession.Close(); CleanupStack::PopAndDestroy(&file); CleanupStack::PopAndDestroy(&fsSession); /////////////////////////////////////////////
}
// ---------------------------------------------------------------------------- // CClientEngine::CreateImageData() // void CClientEngine::CreateImageData(const TDesC8& aUri,
{ iFileName.Copy(KFilePath); RFs aFs; User::LeaveIfError(aFs.Connect()); CleanupClosePushL(aFs);
RFile aFile;
User::LeaveIfError(aFile.Open(aFs, iFileName, EFileRead|EFileShareAny));
TInt aSize; User::LeaveIfError(aFile.Size(aSize));
iPostDataImage = HBufC8::NewL(aSize); TPtr8 aPtr = iPostDataImage->Des();
//Obviously we have to read in the data to the iPostDataImage (ray) // aFile.Read(0, aPtr, aSize); aFile.Read(aPtr);
aFile.Close(); aFs.Close(); CleanupStack::PopAndDestroy(&aFs);
_LIT8(KDataStart,"--AaB03x"); _LIT8(KCrlf,"\r\n"); _LIT8(KContent,"Content-Disposition: form-data;name='userfile';filename='"); _LIT8(KFileCompletion,"'");
_LIT(KContent2,"Content-Type: image/jpeg"); _LIT(KContent3,"Content-Transfer-Encoding: binary"); _LIT8(KDataEnd,"--AaB03x--");
iPostData = HBufC8::NewL(650+aPtr.Length());
TPtr8 iPostDataPtr = iPostData->Des(); iPostDataPtr.Zero();
iPostDataPtr.Append(KCrlf); iPostDataPtr.Append(KDataStart); iPostDataPtr.Append(KCrlf); iPostDataPtr.Append(KContent); iPostDataPtr.Append(_L("star.jpg")); iPostDataPtr.Append(KFileCompletion); iPostDataPtr.Append(KCrlf); iPostDataPtr.Append(KContent2); iPostDataPtr.Append(KCrlf); iPostDataPtr.Append(KContent3); iPostDataPtr.Append(KCrlf); iPostDataPtr.Append(KCrlf); iPostDataPtr.Append(aPtr); //the file in binary iPostDataPtr.Append(KCrlf); iPostDataPtr.Append(KDataEnd); iPostDataPtr.Append(KCrlf);
/////////////////////////////// // HBufC8 *bod = HBufC8::NewL(iPostDataPtr.Length()); // *bod = iPostDataPtr; IssueHTTPPostL(aUri,KContType,iPostDataPtr); } // ---------------------------------------------------------------------------- // CClientEngine::DoHTTPGetL() // ---------------------------------------------------------------------------- void CClientEngine::DoHTTPGetL()
{ // Parse string to URI (as defined in RFC2396) TUriParser8 uri; uri.Parse(*iUri); // Get request method string for HTTP GET RStringF method = iSession.StringPool().StringF(HTTP::EGET,RHTTPSession::GetTable());// ---------------------------------------------------------------------------- // CClientEngine::IssueHTTPPostL() // ---------------------------------------------------------------------------- void CClientEngine::IssueHTTPPostL(const TDesC8& aUri,
const TDesC8& aContentType, const TDesC8& aBody) { if (IsActive()) { return; }// Create HTTP connection TRAPD(err, SetupConnectionL()); if (err == KErrAlreadyExists) { DoHTTPPostL(); } else if (err != KErrNone) { HBufC* resTxCancelled = StringLoader::LoadLC(R_HTTP_TX_CANCELLED); iObserver.ClientEvent(*resTxCancelled); CleanupStack::PopAndDestroy(resTxCancelled); return; }}
// ---------------------------------------------------------------------------- // CClientEngine::DoHTTPPostL() // ---------------------------------------------------------------------------- void CClientEngine::DoHTTPPostL()
{ // Parse string to URI TUriParser8 uri; uri.Parse(*iUri);// SetHeaderL(hdr, HTTP::EContentType, KPostContentType);
// iObserver.ClientEvent(*resConnecting);
iObserver.ClientEvent(_L("inside DoHTTPPostL")); CleanupStack::PopAndDestroy(resConnecting); }// ---------------------------------------------------------------------------- // CClientEngine::CancelTransaction() // ---------------------------------------------------------------------------- void CClientEngine::CancelTransaction()
{ iEngineState = EIdle; delete iUri; iUri = NULL; delete iContentType; iContentType = NULL; delete iBody; iBody = NULL; // Close() also cancels transaction (Cancel() can also be used but // resources allocated by transaction must be still freed with Close()) if (iTransactionOpen) { iTransaction.Close(); iTransactionOpen = EFalse;HBufC* resTxCancelled = StringLoader::LoadLC(R_HTTP_TX_CANCELLED); iObserver.ClientEvent(*resTxCancelled); CleanupStack::PopAndDestroy(resTxCancelled); } }// ---------------------------------------------------------------------------- // CClientEngine::MHFRunL() // ---------------------------------------------------------------------------- void CClientEngine::MHFRunL(RHTTPTransaction aTransaction,
const THTTPEvent& aEvent) { switch (aEvent.iStatus) { case THTTPEvent::EGotResponseHeaders: { // HTTP response headers have been received. Use // aTransaction.Response() to get the response. However, it's not // necessary to do anything with the response when this event occurs.// Get HTTP status code from header (e.g. 200) RHTTPResponse resp = aTransaction.Response(); TInt status = resp.StatusCode();// Get status text (e.g. "OK") TBuf<KStatustextBufferSize> statusText; statusText.Copy(resp.StatusText().DesC());HBufC* resHeaderReceived = StringLoader::LoadLC(R_HTTP_HEADER_RECEIVED, statusText, status); iObserver.ClientEvent(*resHeaderReceived);// iObserver.ClientEvent(_L("hi there!!!"));
CleanupStack::PopAndDestroy(resHeaderReceived); break; }case THTTPEvent::EGotResponseBodyData: { // Part (or all) of response's body data received. Use // aTransaction.Response().Body()->GetNextDataPart() to get the actual // body data.// MHTTPDataSupplier* body = aTransaction.Response().Body(); // TPtrC8 dataChunk; // // // GetNextDataPart() returns ETrue, if the received part is the last // // one. // TBool isLast = body->GetNextDataPart(dataChunk); // iObserver.ClientBodyReceived(dataChunk); // // HBufC* resBytesReceived = StringLoader::LoadLC(R_HTTP_BYTES_RECEIVED, dataChunk.Length()); // iObserver.ClientEvent(*resBytesReceived); // CleanupStack::PopAndDestroy(resBytesReceived); // // // NOTE: isLast may not be ETrue even if last data part received. // // (e.g. multipart response without content length field) // // Use EResponseComplete to reliably determine when body is completely // // received. // if (isLast) // { // HBufC* resBodyReceived = StringLoader::LoadLC(R_HTTP_BODY_RECEIVED); //// iObserver.ClientEvent(*resBodyReceived); // iObserver.ClientEvent(_L("inisde isLast")); // CleanupStack::PopAndDestroy(resBodyReceived); // } // // // Always remember to release the body data. // body->ReleaseData();
///////////////////////////////////// MHTTPDataSupplier* dataSupplier = aTransaction.Response().Body(); TPtrC8 ptr; iDataAvailable = dataSupplier->GetNextDataPart(ptr); // Convert to 16-bit descriptor HBufC* buf = HBufC::NewLC(ptr.Length()); buf->Des().Copy(ptr); // Append to iResponseBuffer if (iResponseBuffer==NULL) { iResponseBuffer = buf->AllocL(); } else { iResponseBuffer = iResponseBuffer->ReAllocL(iResponseBuffer->Length()+buf->Length()); iResponseBuffer->Des().Append(*buf); } // Release buf CleanupStack::PopAndDestroy(buf); if(!iDataAvailable) { iRunning=EFalse; iTransaction.Close(); } else { dataSupplier->ReleaseData(); } break; }case THTTPEvent::EResponseComplete: { // Indicates that header & body of response is completely received. // No further action here needed. HBufC* resTxComplete = StringLoader::LoadLC(R_HTTP_TX_COMPLETE);// iObserver.ClientEvent(*resTxComplete);
iObserver.ClientEvent(_L("Inside EResponseComplete")); CleanupStack::PopAndDestroy(resTxComplete); break; }case THTTPEvent::ESucceeded: { // Indicates that transaction succeeded. HBufC* resTxSuccessful = StringLoader::LoadLC(R_HTTP_TX_SUCCESSFUL);// iObserver.ClientEvent(*resTxSuccessful);
iObserver.ClientEvent(_L("Inside ESucceeded")); CleanupStack::PopAndDestroy(resTxSuccessful);// Transaction can be closed now. It's not needed anymore. aTransaction.Close(); iTransactionOpen = EFalse; ////////////////////////////////////////////////////////////////////////// HBufC* resTxSuccessful = StringLoader::LoadLC(R_HTTP_TX_SUCCESSFUL);
// CleanupStack::PopAndDestroy(resTxSuccessful);
//////////////////////////////////////////////////////////////////////// break; }case THTTPEvent::EFailed: { // Transaction completed with failure. HBufC* resTxFailed = StringLoader::LoadLC(R_HTTP_TX_FAILED);// iObserver.ClientEvent(*resTxFailed);
iObserver.ClientEvent(_L("Inside EFailed")); CleanupStack::PopAndDestroy(resTxFailed); aTransaction.Close(); iTransactionOpen = EFalse; break; }default: // There are more events in THTTPEvent, but they are not usually // needed. However, event status smaller than zero should be handled // correctly since it's error. { if (aEvent.iStatus < 0) { HBufC* resNoInternetConnection = StringLoader::LoadLC( R_HTTP_NO_INTERNET_CONNECTION, aEvent.iStatus);// iObserver.ClientEvent(*resNoInternetConnection);
iObserver.ClientEvent(_L("Inside Default")); CleanupStack::PopAndDestroy(resNoInternetConnection);// Close the transaction on errors aTransaction.Close(); iTransactionOpen = EFalse; } break; } } }// ---------------------------------------------------------------------------- // CClientEngine::IsRunning() // ---------------------------------------------------------------------------- TBool CClientEngine::IsRunning()
{ if (IsActive()) return ETrue; else return EFalse; }// ---------------------------------------------------------------------------- // CClientEngine::MHFRunError() // ---------------------------------------------------------------------------- TInt CClientEngine::MHFRunError(TInt aError,
RHTTPTransaction /*aTransaction*/, const THTTPEvent& /*aEvent*/) { // Just notify about the error and return KErrNone. HBufC* resMHFRunError = StringLoader::LoadLC(R_HTTP_MHFRUN_ERROR, aError);// iObserver.ClientEvent(*resMHFRunError);
iObserver.ClientEvent(_L("Inside MHFRunError")); CleanupStack::PopAndDestroy(resMHFRunError); return KErrNone; }// ---------------------------------------------------------------------------- // CClientEngine::GetNextDataPart() // ---------------------------------------------------------------------------- //TBool CClientEngine::GetNextDataPart(TPtrC8& aDataPart) // { // if(iPostData) // { // // Provide pointer to next chunk of data (return ETrue, if last chunk) // // Usually only one chunk is needed, but sending big file could require // // loading the file in small parts. //// iObserver.ClientEvent(_L("there is more data")); // aDataPart.Set(iPostData->Des()); // } // return ETrue; // }
// ---------------------------------------------------------------------------- // CClientEngine::ReleaseData() // ---------------------------------------------------------------------------- //void CClientEngine::ReleaseData() // { // // It's safe to delete iPostData now. // delete iPostData; // iPostData = NULL; // }
// ---------------------------------------------------------------------------- // CClientEngine::Reset() // ---------------------------------------------------------------------------- TInt CClientEngine::Reset()
{ // Nothing needed since iPostData still exists and contains all the data. // (If a file is used and read in small parts we should seek to beginning // of file and provide the first chunk again in GetNextDataPart() ) return KErrNone; }// ---------------------------------------------------------------------------- // CClientEngine::OverallDataSize() // ---------------------------------------------------------------------------- //TInt CClientEngine::OverallDataSize() // { // if(iPostData) // return iPostData->Length(); // else // return KErrNotFound ; // }
// ---------------------------------------------------------------------------- // CClientEngine::GetCredentialsL() // ---------------------------------------------------------------------------- TBool CClientEngine::GetCredentialsL(const TUriC8& aURI,
RString aRealm, RStringF aAuthenticationType, RString& aUsername, RString& aPassword) { // aURI, aReal and aAuthenticationType are informational only. We only need // to set aUsername and aPassword and return ETrue, if aUsername and // aPassword are provided by user.// Set aUsername and aPassword TBuf8<KDefaultBufferSize> temp; temp.Copy(userName); TRAPD(err, aUsername = aRealm.Pool().OpenStringL(temp)); if (!err) { temp.Copy(password); TRAP(err, aPassword = aRealm.Pool().OpenStringL(temp)); if (!err) return ETrue; }// ---------------------------------------------------------------------------- // CClientEngine::PreferredCarrierAvailable() // ---------------------------------------------------------------------------- void CClientEngine::PreferredCarrierAvailable(TAccessPointInfo /*aOldAPInfo*/,
TAccessPointInfo /*aNewAPInfo*/, TBool /*aIsUpgrade*/, TBool aIsSeamless) { if (!aIsSeamless) { iMobility->MigrateToPreferredCarrier(); } }// ---------------------------------------------------------------------------- // CClientEngine::NewCarrierActive() // ---------------------------------------------------------------------------- void CClientEngine::NewCarrierActive(TAccessPointInfo /*aNewAPInfo*/,
TBool aIsSeamless) { if (!aIsSeamless) { iMobility->NewCarrierAccepted(); } }// ---------------------------------------------------------------------------- // CClientEngine::Error() // ---------------------------------------------------------------------------- void CClientEngine::Error(TInt /*aError*/)
{ }// ---------------------------------------------------------------------------- // CClientEngine::DoCancel() // ---------------------------------------------------------------------------- void CClientEngine::DoCancel()
{ iConnection.Stop(); }// ---------------------------------------------------------------------------- // CClientEngine::RunL() // ---------------------------------------------------------------------------- void CClientEngine::RunL()
{ TInt statusCode = iStatus.Int();if (!iConnectionSetupDone && statusCode == KErrNone) { // Connection done ok iConnectionSetupDone = ETrue; // Register for mobility API iMobility = CActiveCommsMobilityApiExt::NewL(iConnection, *this); // Start selected HTTP action switch (iEngineState) { case EIdle: { CancelTransaction(); break; } case EGet: { DoHTTPGetL(); break; } case EPost: { DoHTTPPostL(); break; } }; } }TBool CClientEngine::GetNextDataPart(TPtrC8& aDataPart) { iObserver.ClientEvent(_L("there is more data")); TBool retVal = EFalse; aDataPart.Set(iPostData->Des()); retVal = (aDataPart.Length() == 0); iDataAvailable=retVal; return retVal; }
TInt CClientEngine::OverallDataSize() { if(iPostData) return iPostData->Length(); else return KErrNotFound ; }
void CClientEngine::ReleaseData() { if(iDataAvailable) iTransaction.NotifyNewRequestBodyPartL(); }
// end of filecryptyritu 12:39, 20 February 2012 (EET)