Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Pisarchik <pisarchik@mapswithme.com>2014-04-27 21:10:48 +0400
committerAlex Zolotarev <alex@maps.me>2015-09-23 02:15:09 +0300
commitb2b9e6e40a0d456b678eaadfcdeaf2a2795fece8 (patch)
tree2a6896d95d21572fbc416ce91f1ebf90bb49865b /platform
parent308503449ae98743122bac9dfe8b3ca5c25fc195 (diff)
[Tizen] Http thread implementation.
+ Move and scale
Diffstat (limited to 'platform')
-rw-r--r--platform/http_thread_tizen.cpp283
-rw-r--r--platform/http_thread_tizen.hpp77
-rw-r--r--platform/platform.pro6
-rw-r--r--platform/platform_tizen.cpp28
4 files changed, 378 insertions, 16 deletions
diff --git a/platform/http_thread_tizen.cpp b/platform/http_thread_tizen.cpp
new file mode 100644
index 0000000000..c57e2f60da
--- /dev/null
+++ b/platform/http_thread_tizen.cpp
@@ -0,0 +1,283 @@
+#include "http_thread_tizen.hpp"
+#include"../base/logging.hpp"
+
+#include "platform.hpp"
+#include "http_thread_callback.hpp"
+#include "tizen_string_utils.hpp"
+
+#include <FBaseColIEnumerator.h>
+
+using namespace std;
+using namespace Tizen::Net::Http;
+
+using Tizen::Base::String;
+using Tizen::Base::LongLong;
+using Tizen::Base::ByteBuffer;
+using Tizen::Base::Collection::IEnumerator;
+
+HttpThread::HttpThread(std::string const & url,
+ downloader::IHttpThreadCallback & callback,
+ int64_t beg,
+ int64_t end,
+ int64_t size,
+ string const & pb)
+ : m_callback(callback),
+ m_begRange(beg), m_endRange(end),
+ m_downloadedBytes(0), m_expectedSize(size),
+ m_url(url), m_pb(pb),
+ m_pTransaction(null)
+{
+ result r = E_SUCCESS;
+
+ String * pProxyAddr = null;
+ String hostAddr(m_url.c_str());
+ HttpHeader * header = NULL;
+
+ LOG(LDEBUG, ("Creating HttpSession", m_url));
+ m_pSession = new HttpSession();
+ r = m_pSession->Construct(NET_HTTP_SESSION_MODE_NORMAL, pProxyAddr, hostAddr, header);
+ if (r != E_SUCCESS)
+ {
+ LOG(LERROR, ("HttpSession Construction error:", r));
+ return;
+ }
+
+ // Open a new HttpTransaction.
+ m_pTransaction = m_pSession->OpenTransactionN();
+ if ((r = GetLastResult()) != E_SUCCESS)
+ {
+ LOG(LERROR, ("OpenTransactionN", GetLastResult()));
+ return;
+ }
+
+ m_pTransaction->AddHttpTransactionListener(*this);
+ m_pTransaction->SetHttpProgressListener(*this);
+
+ HttpRequest* pRequest = m_pTransaction->GetRequest();
+ pRequest->SetUri(m_url.c_str());
+
+ HttpHeader* pHeader = pRequest->GetHeader();
+
+ // use Range header only if we don't download whole file from start
+ if (!(m_begRange == 0 && m_endRange < 0))
+ {
+ if (m_endRange > 0)
+ {
+ LOG(LDEBUG, (m_url, "downloading range [", m_begRange, ",", m_endRange, "]"));
+ String range("bytes=");
+ range.Append(m_begRange);
+ range.Append('-');
+ range.Append(m_endRange);
+ pHeader->AddField(L"Range", range);
+ }
+ else
+ {
+ LOG(LDEBUG, (m_url, "resuming download from position", m_begRange));
+ String range("bytes=");
+ range.Append(m_begRange);
+ range.Append('-');
+ pHeader->AddField("Range", range);
+ }
+ }
+
+ // set user-agent with unique client id only for mapswithme requests
+ if (m_url.find("mapswithme.com") != string::npos)
+ {
+ static string const uid = GetPlatform().UniqueClientId();
+ pHeader->AddField("User-Agent", uid.c_str());
+ }
+
+ if (m_pb.empty())
+ {
+ pRequest->SetMethod(NET_HTTP_METHOD_GET);
+ }
+ else
+ {
+ pRequest->SetMethod(NET_HTTP_METHOD_POST);
+ pHeader->AddField("Content-Type", "application/json");
+ long long sz = m_pb.size();
+ String lenght;
+ lenght.Append(sz);
+ pHeader->AddField("Content-Length", lenght);
+ ByteBuffer body;
+ body.Construct((const byte *)m_pb.c_str(), 0, sz, sz);
+ pRequest->WriteBody(body);
+ }
+ LOG(LDEBUG, ("Connecting to", m_url, "[", m_begRange, ",", m_endRange, "]", "size=", m_expectedSize));
+ r = m_pTransaction->Submit();
+}
+
+HttpThread::~HttpThread()
+{
+ m_pTransaction->RemoveHttpTransactionListener(*this);
+ m_pSession->CloseTransaction(*m_pTransaction);
+ delete m_pTransaction;
+ delete m_pSession;
+}
+
+
+void HttpThread::OnTransactionHeaderCompleted (HttpSession &httpSession,
+ HttpTransaction &httpTransaction,
+ int headerLen, bool bAuthRequired)
+{
+ result r = E_SUCCESS;
+ HttpResponse* pResponse = httpTransaction.GetResponse();
+ if ((r = GetLastResult()) != E_SUCCESS)
+ {
+ LOG(LWARNING, ("httpTransaction.GetResponse error", r));
+ return;
+ }
+
+ int const httpStatusCode = pResponse->GetHttpStatusCode();
+ // When we didn't ask for chunks, code should be 200
+ // When we asked for a chunk, code should be 206
+ bool const isChunk = !(m_begRange == 0 && m_endRange < 0);
+ if ((isChunk && httpStatusCode != 206) || (!isChunk && httpStatusCode != 200))
+ {
+ LOG(LWARNING, ("Http request to", m_url, " aborted with HTTP code", httpStatusCode));
+ r = httpSession.CancelTransaction(httpTransaction);
+ r = httpSession.CloseTransaction(httpTransaction);
+ LOG(LDEBUG, ("CloseTransaction result", r));
+ return;
+ }
+ else if (m_expectedSize > 0)
+ {
+ bool bGoodSize = false;
+ // try to get content length from Content-Range header first
+ HttpHeader * pHeader = pResponse->GetHeader();
+ LOG(LDEBUG, ("Header:", FromTizenString(*pHeader->GetRawHeaderN())));
+ IEnumerator * pValues = pHeader->GetFieldValuesN("Content-Range");
+ if (GetLastResult() == E_SUCCESS)
+ {
+ bGoodSize = true;
+ pValues->MoveNext(); // strange, but works
+ String const * pString = dynamic_cast<String const *>(pValues->GetCurrent());
+
+ if (pString->GetLength())
+ {
+ int lastInd;
+ pString->LastIndexOf ('/', pString->GetLength()-1, lastInd);
+ long long value = -1;
+ String tail;
+ pString->SubString(lastInd + 1, tail);
+ LOG(LDEBUG, ("tail value:",FromTizenString(tail)));
+ LongLong::Parse(tail, value);
+ if (value != m_expectedSize)
+ {
+ LOG(LWARNING, ("Http request to", m_url,
+ "aborted - invalid Content-Range:", value, " expected:" ,m_expectedSize ));
+ r = httpSession.CancelTransaction(httpTransaction);
+ r = httpSession.CloseTransaction(httpTransaction);
+ LOG(LDEBUG, ("CloseTransaction result", r));
+ }
+ }
+ }
+ else
+ {
+
+ pValues = pHeader->GetFieldValuesN("Content-Length");
+ if (GetLastResult() == E_SUCCESS)
+ {
+ bGoodSize = true;
+ pValues->MoveNext(); // strange, but works
+ String const * pString = dynamic_cast<String const *>(pValues->GetCurrent());
+
+ if (pString)
+ {
+ long long value = -1;
+ LongLong::Parse(*pString, value);
+ if (value != m_expectedSize)
+ {
+ LOG(LWARNING, ("Http request to", m_url,
+ "aborted - invalid Content-Length:", value, " expected:" ,m_expectedSize ));
+ r = httpSession.CancelTransaction(httpTransaction);
+ r = httpSession.CloseTransaction(httpTransaction);
+ LOG(LDEBUG, ("CloseTransaction result", r));
+ }
+ }
+ }
+ }
+
+ if (!bGoodSize)
+ {
+
+ LOG(LWARNING, ("Http request to", m_url,
+ "aborted, server didn't send any valid file size"));
+ r = httpSession.CancelTransaction(httpTransaction);
+ r = httpSession.CloseTransaction(httpTransaction);
+ LOG(LDEBUG, ("CloseTransaction result", r));
+ }
+ }
+}
+
+void HttpThread::OnHttpDownloadInProgress (HttpSession &/*httpSession*/,
+ Tizen::Net::Http::HttpTransaction &httpTransaction,
+ long long currentLength,
+ long long totalLength)
+{
+ HttpResponse* pResponse = httpTransaction.GetResponse();
+
+ if (pResponse->GetHttpStatusCode() == HTTP_STATUS_OK
+ || pResponse->GetHttpStatusCode() == HTTP_STATUS_PARTIAL_CONTENT)
+ {
+ ByteBuffer* pBuffer = null;
+ pBuffer = pResponse->ReadBodyN();
+ int chunkSize = pBuffer->GetLimit();
+ m_downloadedBytes += chunkSize;
+ m_callback.OnWrite(m_begRange + m_downloadedBytes - chunkSize, pBuffer->GetPointer(), chunkSize);
+ delete pBuffer;
+ }
+ else
+ LOG(LERROR, ("OnHttpDownloadInProgress ERROR", FromTizenString(pResponse->GetStatusText())));
+}
+
+void HttpThread::OnTransactionCompleted (HttpSession &/*httpSession*/,
+ HttpTransaction & httpTransaction)
+{
+ HttpResponse* pResponse = httpTransaction.GetResponse();
+ if (pResponse->GetHttpStatusCode() == HTTP_STATUS_OK
+ || pResponse->GetHttpStatusCode() == HTTP_STATUS_PARTIAL_CONTENT)
+ {
+ m_callback.OnFinish(200, m_begRange, m_endRange);
+ }
+ else
+ {
+ LOG(LWARNING, ("Download has finished with status code:", pResponse->GetHttpStatusCode(),
+ " and text:", FromTizenString(pResponse->GetStatusText() )));
+ m_callback.OnFinish(-100, m_begRange, m_endRange);
+ }
+}
+
+void HttpThread::OnTransactionAborted (HttpSession &/*httpSession*/,
+ HttpTransaction &/*httpTransaction*/,
+ result r)
+{
+ LOG(LINFO, ("OnTransactionAborted result:", r));
+ m_callback.OnFinish(-100, m_begRange, m_endRange);
+}
+
+void HttpThread::OnTransactionCertVerificationRequiredN (HttpSession &/*httpSession*/,
+ HttpTransaction &/*httpTransaction*/,
+ String */*pCert*/)
+{
+ LOG(LERROR, ("OnTransactionCertVerificationRequiredN"));
+}
+
+void HttpThread::OnTransactionReadyToRead (HttpSession &/*httpSession*/,
+ HttpTransaction &/*httpTransaction*/,
+ int /*availableBodyLen*/)
+{
+}
+
+void HttpThread::OnTransactionReadyToWrite (HttpSession &/*httpSession*/,
+ HttpTransaction &/*httpTransaction*/,
+ int /*recommendedChunkSize*/)
+{
+}
+
+void HttpThread::OnHttpUploadInProgress (Tizen::Net::Http::HttpSession &/*httpSession*/,
+ Tizen::Net::Http::HttpTransaction &/*httpTransaction*/,
+ long long /*currentLength*/,
+ long long /*totalLength*/)
+{
+}
diff --git a/platform/http_thread_tizen.hpp b/platform/http_thread_tizen.hpp
new file mode 100644
index 0000000000..24232cc1c1
--- /dev/null
+++ b/platform/http_thread_tizen.hpp
@@ -0,0 +1,77 @@
+#pragma once
+#include "../../std/target_os.hpp"
+#include "../../std/noncopyable.hpp"
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wignored-qualifiers"
+#include <FNet.h>
+#pragma clang diagnostic pop
+
+namespace downloader
+{
+class IHttpThreadCallback;
+}
+using namespace Tizen::Net::Http;
+
+class HttpThread
+ : public Tizen::Net::Http::IHttpTransactionEventListener
+ , public Tizen::Net::Http::IHttpProgressEventListener
+ , noncopyable
+{
+public:
+
+ HttpThread(std::string const & url,
+ downloader::IHttpThreadCallback & callback,
+ int64_t beg, int64_t end,
+ int64_t size,
+ std::string const & pb);
+ ~HttpThread();
+
+ bool OnStart(void);
+
+ ///
+ ///Tizen::Net::Http::IHttpTransactionEventListener
+ ///
+ virtual void OnTransactionAborted (HttpSession &httpSession,
+ HttpTransaction &httpTransaction,
+ result r);
+ virtual void OnTransactionCertVerificationRequiredN (HttpSession &httpSession,
+ HttpTransaction &httpTransaction,
+ Tizen::Base::String *pCert);
+ virtual void OnTransactionCompleted (HttpSession &httpSession,
+ HttpTransaction &httpTransaction);
+ virtual void OnTransactionHeaderCompleted (HttpSession &httpSession,
+ HttpTransaction &httpTransaction,
+ int headerLen, bool bAuthRequired);
+ virtual void OnTransactionReadyToRead (HttpSession &httpSession,
+ HttpTransaction &httpTransaction,
+ int availableBodyLen);
+ virtual void OnTransactionReadyToWrite (HttpSession &httpSession,
+ HttpTransaction &httpTransaction,
+ int recommendedChunkSize);
+
+ ///
+ ///Tizen::Net::Http::IHttpProgressEventListener
+ ///
+ virtual void OnHttpDownloadInProgress (HttpSession &httpSession,
+ HttpTransaction &httpTransaction,
+ long long currentLength,
+ long long totalLength);
+ virtual void OnHttpUploadInProgress (HttpSession &httpSession,
+ HttpTransaction &httpTransaction,
+ long long currentLength,
+ long long totalLength);
+
+private:
+ downloader::IHttpThreadCallback & m_callback;
+
+ int64_t m_begRange;
+ int64_t m_endRange;
+ int64_t m_downloadedBytes;
+ int64_t m_expectedSize;
+ std::string const m_url;
+ std::string const & m_pb;
+
+ HttpSession * m_pSession;
+ HttpTransaction* m_pTransaction;
+};
diff --git a/platform/platform.pro b/platform/platform.pro
index f04e1092b9..8739a15896 100644
--- a/platform/platform.pro
+++ b/platform/platform.pro
@@ -41,10 +41,12 @@ INCLUDEPATH += $$ROOT_DIR/3party/jansson/src
SOURCES += platform_android.cpp \
pthread_video_timer.cpp
} else:tizen* {
- HEADERS += tizen_string_utils.hpp
+ HEADERS += tizen_string_utils.hpp \
+ http_thread_tizen.hpp
SOURCES += platform_tizen.cpp \
tizen_string_utils.cpp \
- pthread_video_timer.cpp
+ pthread_video_timer.cpp \
+ http_thread_tizen.cpp \
}
macx-*|iphone* {
diff --git a/platform/platform_tizen.cpp b/platform/platform_tizen.cpp
index 3591bbca4d..694843fb4b 100644
--- a/platform/platform_tizen.cpp
+++ b/platform/platform_tizen.cpp
@@ -1,23 +1,22 @@
#include "platform.hpp"
-#include <FAppApp.h>
-
-#include "../../tizen/inc/FIo.hpp"
-
-#include "constants.hpp"
-#include "platform_unix_impl.hpp"
-
-#include "../base/logging.hpp"
-#include "../coding/file_reader.hpp"
-
#include <stdlib.h>
#include <unistd.h>
-
#include <sys/stat.h>
#include <sys/types.h>
+#include "../base/logging.hpp"
+#include "../coding/file_reader.hpp"
+
+#include "constants.hpp"
+#include "platform_unix_impl.hpp"
+
#include "tizen_string_utils.hpp"
+#include "http_thread_tizen.hpp"
+
+#include <FAppApp.h>
+#include "../../tizen/inc/FIo.hpp"
Platform::Platform()
{
@@ -121,13 +120,14 @@ HttpThread * CreateNativeHttpThread(string const & url,
int64_t size,
string const & pb)
{
- // todo;
- return 0;
+
+ HttpThread * pRes = new HttpThread(url, cb, beg, end, size, pb);
+ return pRes;
}
void DeleteNativeHttpThread(HttpThread * request)
{
- // todo;
+ delete request;
}
}