diff -r 5e43fd36ca1f dcpp/HttpManager.cpp --- a/dcpp/HttpManager.cpp Wed May 13 22:13:32 2015 -0400 +++ b/dcpp/HttpManager.cpp Thu May 14 19:15:29 2015 +0200 @@ -163,7 +163,7 @@ stream = findConn(c)->stream; } stream->write(data, len); - fire(HttpManagerListener::Updated(), c); + fire(HttpManagerListener::Updated(), c, data, len); } void HttpManager::on(HttpConnectionListener::Failed, HttpConnection* c, const string& str) noexcept { diff -r 5e43fd36ca1f dcpp/HttpManagerListener.h --- a/dcpp/HttpManagerListener.h Wed May 13 22:13:32 2015 -0400 +++ b/dcpp/HttpManagerListener.h Thu May 14 19:15:29 2015 +0200 @@ -40,7 +40,7 @@ typedef X<5> Removed; virtual void on(Added, HttpConnection*) noexcept { } - virtual void on(Updated, HttpConnection*) noexcept { } + virtual void on(Updated, HttpConnection*, const uint8_t* data, size_t len) noexcept { } virtual void on(Failed, HttpConnection*, const string&) noexcept { } virtual void on(Complete, HttpConnection*, OutputStream*) noexcept { } virtual void on(ResetStream, HttpConnection*) noexcept { } diff -r 5e43fd36ca1f dcpp/PluginApiImpl.cpp --- a/dcpp/PluginApiImpl.cpp Wed May 13 22:13:32 2015 -0400 +++ b/dcpp/PluginApiImpl.cpp Thu May 14 19:15:29 2015 +0200 @@ -39,10 +39,12 @@ #include "Tagger.h" #include "UserConnection.h" #include "version.h" +#include "HttpManager.h" +#include "HttpConnection.h" namespace dcpp { -#define IMPL_HOOKS_COUNT 23 +#define IMPL_HOOKS_COUNT 25 static const char* hookGuids[IMPL_HOOKS_COUNT] = { HOOK_CHAT_IN, @@ -72,7 +74,10 @@ HOOK_UI_CHAT_TAGS, HOOK_UI_CHAT_DISPLAY, HOOK_UI_CHAT_COMMAND, - HOOK_UI_CHAT_COMMAND_PM + HOOK_UI_CHAT_COMMAND_PM, + + HOOK_DATAACESSOR_HTTP_FILE_NOTIFICATION, + HOOK_DATAACESSOR_HTTP_FILE_STREAM }; static const char* hostName = APPNAME; @@ -178,6 +183,15 @@ &PluginApiImpl::replaceText }; +DCDataAccess PluginApiImpl::dcDataAccess = { + DCINTF_DCPP_DATAACCESSOR_VER, + + &PluginApiImpl::getHTTPFile, + + &PluginApiImpl::copyData, + &PluginApiImpl::releaseData +}; + Socket* PluginApiImpl::udpSocket = nullptr; Socket& PluginApiImpl::getUdpSocket() { if(!udpSocket) { @@ -210,6 +224,7 @@ dcCore.register_interface(DCINTF_DCPP_QUEUE, &dcQueue); dcCore.register_interface(DCINTF_DCPP_UTILS, &dcUtils); dcCore.register_interface(DCINTF_DCPP_TAGGER, &dcTagger); + dcCore.register_interface(DCINTF_DCPP_DATAACCESSOR, &dcDataAccess); // Create provided hooks (since these outlast any plugin they don't need to be explictly released) for(int i = 0; i < IMPL_HOOKS_COUNT; ++i) @@ -773,4 +788,123 @@ free(user); } +/* Functions for DataAccess */ +void PluginApiImpl::getHTTPFile(const char* uri, const char* localPath) { + try { + class HTTPDownloader : private dcpp::HttpManagerListener//, private dcpp::HttpConnectionListener + { + public: + + HTTPDownloader() { } + virtual ~HTTPDownloader() { }; + + void getFile(const char* uri, const char* file) + { + HttpManager::getInstance()->addListener(this); + if(strlen(file) == 0) + { + HttpManager::getInstance()->download(uri); + } + else + { + HttpManager::getInstance()->download(uri, file); + } + } + + private: + + DataArrayPtr getDataArrayPtr(const std::string& str) + { + DataArrayPtr pDataArray = (DataArrayPtr)malloc(sizeof(DataArray)); + memset(pDataArray, 0, sizeof(DataArray)); + + size_t bufLen = str.size() + 1; + char* pData = (char*)malloc(bufLen); + strncpy(pData, str.c_str(), bufLen); + pDataArray->pData = pData; + + pDataArray->size = bufLen; + + return pDataArray; + }; + + DataArrayPtr getDataArrayPtr(const uint8_t* data, size_t len) + { + DataArrayPtr pDataArray = (DataArrayPtr)malloc(sizeof(DataArray)); + memset(pDataArray, 0, sizeof(DataArray)); + + size_t bufLen = len + 1; + char* pData = (char*)malloc(bufLen); + strncpy(pData, (char*)data, bufLen); + pDataArray->pData = pData; + + pDataArray->size = bufLen; + + return pDataArray; + }; + + void runHookCompleted(const std::string& url, const std::string& data) + { + DataArrayPtr streamArray = getDataArrayPtr(data); + + PluginManager::getInstance()->runHook(HOOK_DATAACESSOR_HTTP_FILE_NOTIFICATION, const_cast(url.c_str()), streamArray); + + HttpManager::getInstance()->removeListener(this); + + delete this; + } + + void runHookPartial(const std::string& url, const uint8_t* data, size_t len) + { + DataArrayPtr streamArray = getDataArrayPtr(data, len); + + PluginManager::getInstance()->runHook(HOOK_DATAACESSOR_HTTP_FILE_STREAM, const_cast(url.c_str()), streamArray); + + } + + // HttpManagerListener + void on(HttpManagerListener::Failed, HttpConnection* c, const string&) noexcept + { + runHookCompleted(c->getUrl(), ""); + } + + void on(HttpManagerListener::Complete, HttpConnection* c, OutputStream* stream) noexcept + { + runHookCompleted(c->getUrl(), static_cast(stream)->getString()); + } + + void on(HttpManagerListener::Updated, HttpConnection* c, const uint8_t* data, size_t len) noexcept + { + runHookPartial(c->getUrl(), data, len); + } + }; + + HTTPDownloader* downloader = new HTTPDownloader(); + downloader->getFile(uri, localPath); + + } catch(const Exception& e) { + LogManager::getInstance()->message(e.getError()); + } +} + +DataArrayPtr PluginApiImpl::copyData(const DataArrayPtr val) +{ + DataArrayPtr copy = (DataArrayPtr)malloc(sizeof(DataArray)); + memcpy(copy, val, sizeof(DataArray)); + + size_t bufLen = strlen((char*)val->pData) + 1; + char* pData = (char*)malloc(bufLen); + strncpy(pData, (char*)val->pData, bufLen); + copy->pData = pData; + + return copy; +} + +void PluginApiImpl::releaseData(DataArrayPtr val) +{ + free(const_cast(val->pData)); + + free(val); +} + } // namespace dcpp diff -r 5e43fd36ca1f dcpp/PluginApiImpl.h --- a/dcpp/PluginApiImpl.h Wed May 13 22:13:32 2015 -0400 +++ b/dcpp/PluginApiImpl.h Thu May 14 19:15:29 2015 +0200 @@ -49,6 +49,9 @@ static ConfigValuePtr DCAPI copyData(const ConfigValuePtr val); static void DCAPI releaseData(ConfigValuePtr val); + static DataArrayPtr DCAPI copyData(const DataArrayPtr val); + static void DCAPI releaseData(DataArrayPtr val); + private: // Functions for DCCore static intfHandle DCAPI registerInterface(const char* guid, dcptr_t funcs); @@ -122,6 +125,8 @@ static UserDataPtr DCAPI findUser(const char* cid, const char* hubUrl); + static void DCAPI getHTTPFile(const char* uri, const char* localPath); + static DCHooks dcHooks; static DCConfig dcConfig; static DCLog dcLog; @@ -131,6 +136,7 @@ static DCQueue dcQueue; static DCUtils dcUtils; static DCTagger dcTagger; + static DCDataAccess dcDataAccess; static Socket* udpSocket; static Socket& getUdpSocket(); diff -r 5e43fd36ca1f dcpp/PluginDefs.h --- a/dcpp/PluginDefs.h Wed May 13 22:13:32 2015 -0400 +++ b/dcpp/PluginDefs.h Thu May 14 19:15:29 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001-2015 Jacek Sieka, arnetheduck on gmail point com + * Copyright (C) 2001-2013 Jacek Sieka, arnetheduck on gmail point com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -82,6 +82,9 @@ #define DCINTF_DCPP_UI "dcpp.ui.DCUI" /* User interface */ #define DCINTF_DCPP_UI_VER 1 +#define DCINTF_DCPP_DATAACCESSOR "dcpp.dataaccessor.DCDataAccess" /* Data access */ +#define DCINTF_DCPP_DATAACCESSOR_VER 1 + /* Hook GUID's for Hooks (events) system */ #define HOOK_CHAT_IN "dcpp.chat.onIncomingChat" /* Incoming chat from hub (obj: HubData) */ #define HOOK_CHAT_OUT "dcpp.chat.onOutgoingChat" /* Outgoing chat (obj: HubData) */ @@ -114,6 +117,9 @@ #define HOOK_UI_CHAT_COMMAND "dcpp.ui.onChatCommand" /* Client side commands in hub chat (obj: HubData; data: CommandData) */ #define HOOK_UI_CHAT_COMMAND_PM "dcpp.ui.onChatCommandPM" /* Client side commands in private chat (obj: UserData; data: CommandData) */ +#define HOOK_DATAACESSOR_HTTP_FILE_NOTIFICATION "dcpp.dataaccessor.onHTTPFileNotification" /* Notification that transfer has completed or failed */ +#define HOOK_DATAACESSOR_HTTP_FILE_STREAM "dcpp.dataaccessor.onHTTPFileStream" /* Notification that transfer has updated */ + /* Main hook events (returned by pluginInit) */ typedef enum tagPluginState { ON_INSTALL = 0, /* Replaces ON_LOAD for the very first loading of the plugin */ @@ -291,6 +297,11 @@ uint32_t apiVersion; } DCInterface, *DCInterfacePtr; +typedef struct { + const void* pData; + uint64_t size; +} DataArray, *DataArrayPtr; + /* Core plugin system */ typedef struct tagDCCore { /* Core API version */ @@ -459,6 +470,19 @@ void (DCAPI *notify) (const char* title, const char* message); } DCUI, *DCUIPtr; +/* Data access */ +typedef struct DCDataAccess { + uint32_t apiVersion; + + /* "uri" is the HTTP file path to grab. + "localPath" is the local file path to download to. + "localPath" may be NULL or empty to not download to a specific file. */ + void (DCAPI *get_http_file) (const char* uri, const char* localPath); + + DataArrayPtr (DCAPI *copy) (const DataArrayPtr hItem); + void (DCAPI *release) (DataArrayPtr hCopy); +} DCDataAcess, *DCDataAccessPtr; + #ifdef __cplusplus } #endif diff -r 5e43fd36ca1f win32/TransferView.cpp --- a/win32/TransferView.cpp Wed May 13 22:13:32 2015 -0400 +++ b/win32/TransferView.cpp Thu May 14 19:15:29 2015 +0200 @@ -1087,7 +1087,7 @@ addedConn(ui); } -void TransferView::on(HttpManagerListener::Updated, HttpConnection* c) noexcept { +void TransferView::on(HttpManagerListener::Updated, HttpConnection* c, const uint8_t* data, size_t len) noexcept { auto ui = makeHttpUI(c); ui->setTransferred(c->getDone(), c->getDone(), c->getSize()); ui->setSpeed(c->getSpeed()); diff -r 5e43fd36ca1f win32/TransferView.h --- a/win32/TransferView.h Wed May 13 22:13:32 2015 -0400 +++ b/win32/TransferView.h Thu May 14 19:15:29 2015 +0200 @@ -294,7 +294,7 @@ virtual void on(QueueManagerListener::CRCFailed, Download* d, const string& aReason) noexcept; virtual void on(HttpManagerListener::Added, HttpConnection*) noexcept; - virtual void on(HttpManagerListener::Updated, HttpConnection*) noexcept; + virtual void on(HttpManagerListener::Updated, HttpConnection*, const uint8_t* data, size_t len) noexcept; virtual void on(HttpManagerListener::Failed, HttpConnection*, const string&) noexcept; virtual void on(HttpManagerListener::Complete, HttpConnection*, OutputStream*) noexcept; virtual void on(HttpManagerListener::Removed, HttpConnection*) noexcept;