diff --git a/src/client/Client.cpp b/src/client/Client.cpp index 22f1b4d41..a984dea1b 100644 --- a/src/client/Client.cpp +++ b/src/client/Client.cpp @@ -44,6 +44,7 @@ #include "client/UserInfo.h" #include "gui/preview/Comment.h" #include "ClientListener.h" +#include "client/Download.h" #include "requestbroker/RequestBroker.h" #include "requestbroker/WebRequest.h" #include "requestbroker/APIRequest.h" @@ -63,8 +64,8 @@ extern "C" Client::Client(): messageOfTheDay("Fetching the message of the day..."), - versionCheckRequest(NULL), - alternateVersionCheckRequest(NULL), + versionCheckRequest(nullptr), + alternateVersionCheckRequest(nullptr), usingAltUpdateServer(false), updateAvailable(false), authUser(0, "") @@ -134,28 +135,23 @@ void Client::Initialise(ByteString proxyString) stampsLib.close(); //Begin version check - versionCheckRequest = http_async_req_start(NULL, "http://" SERVER "/Startup.json", NULL, 0, 0); + versionCheckRequest = new Download("http://" SERVER "/Startup.json"); if (authUser.UserID) { - ByteString idTempString = ByteString::Build(authUser.UserID); - char *id = new char[idTempString.length() + 1]; - std::strcpy (id, idTempString.c_str()); - char *session = new char[authUser.SessionID.length() + 1]; - std::strcpy (session, authUser.SessionID.c_str()); - http_auth_headers(versionCheckRequest, id, NULL, session); - delete[] id; - delete[] session; + versionCheckRequest->AuthHeaders(ByteString::Build(authUser.UserID), authUser.SessionID); } + versionCheckRequest->Start(); #ifdef UPDATESERVER // use an alternate update server - alternateVersionCheckRequest = http_async_req_start(NULL, "http://" UPDATESERVER "/Startup.json", NULL, 0, 0); + alternateVersionCheckRequest = new Download("http://" UPDATESERVER "/Startup.json"); usingAltUpdateServer = true; if (authUser.UserID) { - http_auth_headers(alternateVersionCheckRequest, authUser.Username.c_str(), NULL, NULL); + alternateVersionCheckRequest->AuthHeaders(authUser.Username, ""); } + alternateVersionCheckRequest->Start(); #endif } @@ -664,11 +660,11 @@ std::vector > Client::GetServerNotifications() return serverNotifications; } -RequestStatus Client::ParseServerReturn(char *result, int status, bool json) +RequestStatus Client::ParseServerReturn(ByteString &result, int status, bool json) { lastError = ""; // no server response, return "Malformed Response" - if (status == 200 && !result) + if (status == 200 && !result.size()) { status = 603; } @@ -676,13 +672,13 @@ RequestStatus Client::ParseServerReturn(char *result, int status, bool json) return RequestOkay; if (status != 200) { - lastError = String::Build("HTTP Error ", status, ": ", ByteString(http_ret_text(status)).FromUtf8()); + lastError = String::Build("HTTP Error ", status, ": ", ByteString(Download::StatusText(status)).FromUtf8()); return RequestFailure; } if (json) { - std::istringstream datastream(result); + std::istringstream datastream(result.c_str()); Json::Value root; try @@ -703,10 +699,10 @@ RequestStatus Client::ParseServerReturn(char *result, int status, bool json) catch (std::exception &e) { // sometimes the server returns a 200 with the text "Error: 401" - if (!strncmp((const char *)result, "Error: ", 7)) + if (!strncmp(result.c_str(), "Error: ", 7)) { - status = atoi(result+7); - lastError = String::Build("HTTP Error ", status, ": ", ByteString(http_ret_text(status)).FromUtf8()); + status = ByteString(result.begin() + 7, result.end()).ToNumber(); + lastError = String::Build("HTTP Error ", status, ": ", ByteString(Download::StatusText(status)).FromUtf8()); return RequestFailure; } lastError = "Could not read response: " + ByteString(e.what()).FromUtf8(); @@ -715,9 +711,9 @@ RequestStatus Client::ParseServerReturn(char *result, int status, bool json) } else { - if (strncmp((const char *)result, "OK", 2)) + if (strncmp(result.c_str(), "OK", 2)) { - lastError = ByteString(result).FromUtf8(); + lastError = result.FromUtf8(); return RequestFailure; } } @@ -731,31 +727,31 @@ void Client::Tick() if (versionCheckRequest) { if (CheckUpdate(versionCheckRequest, true)) - versionCheckRequest = NULL; + versionCheckRequest = nullptr; } if (alternateVersionCheckRequest) { if (CheckUpdate(alternateVersionCheckRequest, false)) - alternateVersionCheckRequest = NULL; + alternateVersionCheckRequest = nullptr; } } -bool Client::CheckUpdate(void *updateRequest, bool checkSession) +bool Client::CheckUpdate(Download *updateRequest, bool checkSession) { //Check status on version check request - if (http_async_req_status(updateRequest)) + if (updateRequest->CheckDone()) { int status; int dataLength; - char * data = http_async_req_stop(updateRequest, &status, &dataLength); + ByteString data = updateRequest->Finish(&dataLength, &status); if (status != 200) { - free(data); + //free(data); } - else if(data) + else if(data.size()) { - std::istringstream dataStream(data); + std::istringstream dataStream(data.c_str()); try { @@ -844,8 +840,6 @@ bool Client::CheckUpdate(void *updateRequest, bool checkSession) { //Do nothing } - - free(data); } return true; } @@ -967,7 +961,7 @@ RequestStatus Client::UploadSave(SaveInfo & save) unsigned int gameDataLength; char * gameData = NULL; int dataStatus; - char * data; + ByteString data; int dataLength = 0; ByteString userID = ByteString::Build(authUser.UserID); if (authUser.UserID) @@ -995,24 +989,12 @@ RequestStatus Client::UploadSave(SaveInfo & save) } #endif - char *saveName = new char[save.GetName().length() + 1]; - std::strcpy (saveName, save.GetName().ToUtf8().c_str()); - char *saveDescription = new char[save.GetDescription().length() + 1]; - std::strcpy (saveDescription, save.GetDescription().ToUtf8().c_str()); - char *userid = new char[userID.size() + 1]; - std::strcpy (userid, userID.c_str()); - char *session = new char[authUser.SessionID.length() + 1]; - std::strcpy (session, authUser.SessionID.c_str()); - - const char *const postNames[] = { "Name", "Description", "Data:save.bin", "Publish", NULL }; - const char *const postDatas[] = { saveName, saveDescription, gameData, save.GetPublished()?"Public":"Private" }; - size_t postLengths[] = { save.GetName().length(), save.GetDescription().length(), gameDataLength, (size_t)(save.GetPublished()?6:7) }; - data = http_multipart_post("http://" SERVER "/Save.api", postNames, postDatas, postLengths, userid, NULL, session, &dataStatus, &dataLength); - - delete[] saveDescription; - delete[] saveName; - delete[] userid; - delete[] session; + data = Download::SimpleAuth("http://" SERVER "/Save.api", &dataLength, &dataStatus, userID, authUser.SessionID, { + { "Name", save.GetName().ToUtf8() }, + { "Description", save.GetDescription().ToUtf8() }, + { "Data:save.bin", ByteString(gameData, gameData + gameDataLength) }, + { "Publish", save.GetPublished() ? "Public" : "Private" }, + }); } else { @@ -1023,7 +1005,7 @@ RequestStatus Client::UploadSave(SaveInfo & save) RequestStatus ret = ParseServerReturn(data, dataStatus, false); if (ret == RequestOkay) { - int saveID = ByteString(data+3).ToNumber(); + int saveID = ByteString(data.begin() + 3, data.end()).ToNumber(); if (!saveID) { lastError = "Server did not return Save ID"; @@ -1032,7 +1014,6 @@ RequestStatus Client::UploadSave(SaveInfo & save) else save.SetID(saveID); } - free(data); delete[] gameData; return ret; } @@ -1198,30 +1179,17 @@ RequestStatus Client::ExecVote(int saveID, int direction) { lastError = ""; int dataStatus; - char * data; + ByteString data; int dataLength = 0; if (authUser.UserID) { - char * directionText = (char*)(direction==1?"Up":"Down"); ByteString saveIDText = ByteString::Build(saveID); ByteString userIDText = ByteString::Build(authUser.UserID); - - char *id = new char[saveIDText.length() + 1]; - std::strcpy(id, saveIDText.c_str()); - char *userid = new char[userIDText.length() + 1]; - std::strcpy(userid, userIDText.c_str()); - char *session = new char[authUser.SessionID.length() + 1]; - std::strcpy(session, authUser.SessionID.c_str()); - - const char *const postNames[] = { "ID", "Action", NULL }; - const char *const postDatas[] = { id, directionText }; - size_t postLengths[] = { saveIDText.length(), strlen(directionText) }; - data = http_multipart_post("http://" SERVER "/Vote.api", postNames, postDatas, postLengths, userid, NULL, session, &dataStatus, &dataLength); - - delete[] id; - delete[] userid; - delete[] session; + data = Download::SimpleAuth("http://" SERVER "/Vote.api", &dataLength, &dataStatus, userIDText, authUser.SessionID, { + { "ID", saveIDText }, + { "Action", direction == 1 ? "Up" : "Down" }, + }); } else { @@ -1236,7 +1204,7 @@ unsigned char * Client::GetSaveData(int saveID, int saveDate, int & dataLength) { lastError = ""; int dataStatus; - char *data; + ByteString data; dataLength = 0; ByteString urlStr; if (saveDate) @@ -1244,16 +1212,16 @@ unsigned char * Client::GetSaveData(int saveID, int saveDate, int & dataLength) else urlStr = ByteString::Build("http://", STATICSERVER, "/", saveID, ".cps"); - char *url = new char[urlStr.size() + 1]; - std::strcpy(url, urlStr.c_str()); - data = http_simple_get(url, &dataStatus, &dataLength); - delete[] url; + data = Download::Simple(urlStr, &dataLength, &dataStatus); // will always return failure ParseServerReturn(data, dataStatus, false); - if (data && dataStatus == 200) - return (unsigned char *)data; - free(data); + if (data.size() && dataStatus == 200) + { + unsigned char *data_out = (unsigned char *)malloc(dataLength); + std::copy(data_out, data_out + dataLength, data.begin()); + return data_out; + } return NULL; } @@ -1367,21 +1335,21 @@ LoginStatus Client::Login(ByteString username, ByteString password, User & user) md5_ascii(totalHash, (const unsigned char *)(total.c_str()), total.size()); totalHash[32] = 0; - char * data; + ByteString data; int dataStatus, dataLength; - const char *const postNames[] = { "Username", "Hash", NULL }; - const char *const postDatas[] = { username.c_str(), totalHash }; - size_t postLengths[] = { username.length(), 32 }; - data = http_multipart_post("http://" SERVER "/Login.json", postNames, postDatas, postLengths, NULL, NULL, NULL, &dataStatus, &dataLength); + data = Download::Simple("http://" SERVER "/Login.json", &dataLength, &dataStatus, { + { "Username", username }, + { "Hash", totalHash }, + }); + RequestStatus ret = ParseServerReturn(data, dataStatus, true); if (ret == RequestOkay) { try { - std::istringstream dataStream(data); + std::istringstream dataStream(data.c_str()); Json::Value objDocument; dataStream >> objDocument; - free(data); int userIDTemp = objDocument["UserID"].asInt(); ByteString sessionIDTemp = objDocument["SessionID"].asString(); @@ -1417,20 +1385,19 @@ LoginStatus Client::Login(ByteString username, ByteString password, User & user) return LoginError; } } - free(data); return LoginError; } RequestStatus Client::DeleteSave(int saveID) { lastError = ""; - char * data = NULL; + ByteString data; int dataStatus, dataLength; ByteString url = ByteString::Build("http://", SERVER, "/Browse/Delete.json?ID=", saveID, "&Mode=Delete&Key=", authUser.SessionKey); if(authUser.UserID) { ByteString userID = ByteString::Build(authUser.UserID); - data = http_auth_get(url.c_str(), userID.c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, &dataLength); + data = Download::SimpleAuth(url, &dataLength, &dataStatus, userID, authUser.SessionID); } else { @@ -1438,25 +1405,21 @@ RequestStatus Client::DeleteSave(int saveID) return RequestFailure; } RequestStatus ret = ParseServerReturn(data, dataStatus, true); - free(data); return ret; } RequestStatus Client::AddComment(int saveID, String comment) { lastError = ""; - char * data = NULL; + ByteString data; int dataStatus, dataLength; ByteString url = ByteString::Build("http://", SERVER, "/Browse/Comments.json?ID=", saveID); if(authUser.UserID) { ByteString userID = ByteString::Build(authUser.UserID); - - const char *const postNames[] = { "Comment", NULL }; - ByteString commentBytes = comment.ToUtf8(); - const char *const postDatas[] = { commentBytes.c_str() }; - size_t postLengths[] = { commentBytes.size() }; - data = http_multipart_post(url.c_str(), postNames, postDatas, postLengths, userID.c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, &dataLength); + data = Download::SimpleAuth(url, &dataLength, &dataStatus, userID, authUser.SessionID, { + { "Comment", comment.ToUtf8() }, + }); } else { @@ -1464,7 +1427,6 @@ RequestStatus Client::AddComment(int saveID, String comment) return RequestFailure; } RequestStatus ret = ParseServerReturn(data, dataStatus, true); - free(data); return ret; } @@ -1472,7 +1434,7 @@ RequestStatus Client::FavouriteSave(int saveID, bool favourite) { lastError = ""; ByteStringBuilder urlStream; - char * data = NULL; + ByteString data; int dataStatus, dataLength; urlStream << "http://" << SERVER << "/Browse/Favourite.json?ID=" << saveID << "&Key=" << authUser.SessionKey; if(!favourite) @@ -1480,7 +1442,7 @@ RequestStatus Client::FavouriteSave(int saveID, bool favourite) if(authUser.UserID) { ByteString userID = ByteString::Build(authUser.UserID); - data = http_auth_get(urlStream.Build().c_str(), userID.c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, &dataLength); + data = Download::SimpleAuth(urlStream.Build(), &dataLength, &dataStatus, userID, authUser.SessionID); } else { @@ -1488,25 +1450,21 @@ RequestStatus Client::FavouriteSave(int saveID, bool favourite) return RequestFailure; } RequestStatus ret = ParseServerReturn(data, dataStatus, true); - free(data); return ret; } RequestStatus Client::ReportSave(int saveID, String message) { lastError = ""; - char * data = NULL; + ByteString data; int dataStatus, dataLength; ByteString url = ByteString::Build("http://", SERVER, "/Browse/Report.json?ID=", saveID, "&Key=", authUser.SessionKey); if(authUser.UserID) { ByteString userID = ByteString::Build(authUser.UserID); - - const char *const postNames[] = { "Reason", NULL }; - ByteString messageBytes = message.ToUtf8(); - const char *const postDatas[] = { messageBytes.c_str() }; - size_t postLengths[] = { messageBytes.size() }; - data = http_multipart_post(url.c_str(), postNames, postDatas, postLengths, userID.c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, &dataLength); + data = Download::SimpleAuth(url, &dataLength, &dataStatus, userID, authUser.SessionID, { + { "Reason", message.ToUtf8() }, + }); } else { @@ -1514,21 +1472,19 @@ RequestStatus Client::ReportSave(int saveID, String message) return RequestFailure; } RequestStatus ret = ParseServerReturn(data, dataStatus, true); - free(data); return ret; } RequestStatus Client::UnpublishSave(int saveID) { lastError = ""; - char * data = NULL; + ByteString data; int dataStatus, dataLength; ByteString url = ByteString::Build("http://", SERVER, "/Browse/Delete.json?ID=", saveID, "&Mode=Unpublish&Key=", authUser.SessionKey); if(authUser.UserID) { ByteString userID = ByteString::Build(authUser.UserID); - - data = http_auth_get(url.c_str(), userID.c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, &dataLength); + data = Download::SimpleAuth(url, &dataLength, &dataStatus, userID, authUser.SessionID); } else { @@ -1536,31 +1492,28 @@ RequestStatus Client::UnpublishSave(int saveID) return RequestFailure; } RequestStatus ret = ParseServerReturn(data, dataStatus, true); - free(data); return ret; } RequestStatus Client::PublishSave(int saveID) { lastError = ""; - char *data; + ByteString data; int dataStatus; ByteString url = ByteString::Build("http://", SERVER, "/Browse/View.json?ID=", saveID, "&Key=", authUser.SessionKey); if (authUser.UserID) { ByteString userID = ByteString::Build(authUser.UserID); - - const char *const postNames[] = { "ActionPublish", NULL }; - const char *const postDatas[] = { "" }; - size_t postLengths[] = { 1 }; - data = http_multipart_post(url.c_str(), postNames, postDatas, postLengths, userID.c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, NULL); } + data = Download::SimpleAuth(url, nullptr, &dataStatus, userID, authUser.SessionID, { + { "ActionPublish", "bagels" }, + }); + } else { lastError = "Not authenticated"; return RequestFailure; } RequestStatus ret = ParseServerReturn(data, dataStatus, true); - free(data); return ret; } @@ -1573,23 +1526,23 @@ SaveInfo * Client::GetSave(int saveID, int saveDate) { urlStream << "&Date=" << saveDate; } - char * data; + ByteString data; int dataStatus, dataLength; if(authUser.UserID) { ByteString userID = ByteString::Build(authUser.UserID); - data = http_auth_get(urlStream.Build().c_str(), userID.c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, &dataLength); + data = Download::SimpleAuth(urlStream.Build(), &dataLength, &dataStatus, userID, authUser.SessionID); } else { - data = http_simple_get(urlStream.Build().c_str(), &dataStatus, &dataLength); + data = Download::Simple(urlStream.Build(), &dataLength, &dataStatus); } - if(dataStatus == 200 && data) + if(dataStatus == 200 && data.size()) { try { - std::istringstream dataStream(data); + std::istringstream dataStream(data.c_str()); Json::Value objDocument; dataStream >> objDocument; @@ -1620,20 +1573,17 @@ SaveInfo * Client::GetSave(int saveID, int saveDate) tempSave->Favourite = tempFavourite; tempSave->Views = tempViews; tempSave->Version = tempVersion; - free(data); return tempSave; } catch (std::exception & e) { lastError = "Could not read response: " + ByteString(e.what()).FromUtf8(); - free(data); return NULL; } } else { - free(data); - lastError = ByteString(http_ret_text(dataStatus)).FromUtf8(); + lastError = ByteString(Download::StatusText(dataStatus)).FromUtf8(); } return NULL; } @@ -1748,7 +1698,7 @@ std::vector > * Client::GetTags(int start, int count, resultCount = 0; std::vector > * tagArray = new std::vector >(); ByteStringBuilder urlStream; - char * data; + ByteString data; int dataStatus, dataLength; urlStream << "http://" << SERVER << "/Browse/Tags.json?Start=" << start << "&Count=" << count; if(query.length()) @@ -1758,12 +1708,12 @@ std::vector > * Client::GetTags(int start, int count, urlStream << format::URLEncode(query.ToUtf8()); } - data = http_simple_get(urlStream.Build().c_str(), &dataStatus, &dataLength); - if(dataStatus == 200 && data) + data = Download::Simple(urlStream.Build(), &dataLength, &dataStatus); + if(dataStatus == 200 && data.size()) { try { - std::istringstream dataStream(data); + std::istringstream dataStream(data.c_str()); Json::Value objDocument; dataStream >> objDocument; @@ -1783,9 +1733,8 @@ std::vector > * Client::GetTags(int start, int count, } else { - lastError = ByteString(http_ret_text(dataStatus)).FromUtf8(); + lastError = ByteString(Download::StatusText(dataStatus)).FromUtf8(); } - free(data); return tagArray; } @@ -1795,7 +1744,7 @@ std::vector * Client::SearchSaves(int start, int count, String query, resultCount = 0; std::vector * saveArray = new std::vector(); ByteStringBuilder urlStream; - char * data; + ByteString data; int dataStatus, dataLength; urlStream << "http://" << SERVER << "/Browse.json?Start=" << start << "&Count=" << count; if(query.length() || sort.length()) @@ -1817,18 +1766,18 @@ std::vector * Client::SearchSaves(int start, int count, String query, if(authUser.UserID) { ByteString userID = ByteString::Build(authUser.UserID); - data = http_auth_get(urlStream.Build().c_str(), userID.c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, &dataLength); + data = Download::SimpleAuth(urlStream.Build(), &dataLength, &dataStatus, userID, authUser.SessionID); } else { - data = http_simple_get(urlStream.Build().c_str(), &dataStatus, &dataLength); + data = Download::Simple(urlStream.Build(), &dataLength, &dataStatus); } ParseServerReturn(data, dataStatus, true); - if (dataStatus == 200 && data) + if (dataStatus == 200 && data.size()) { try { - std::istringstream dataStream(data); + std::istringstream dataStream(data.c_str()); Json::Value objDocument; dataStream >> objDocument; @@ -1856,7 +1805,6 @@ std::vector * Client::SearchSaves(int start, int count, String query, lastError = "Could not read response: " + ByteString(e.what()).FromUtf8(); } } - free(data); return saveArray; } @@ -1864,13 +1812,13 @@ std::list * Client::RemoveTag(int saveID, ByteString tag) { lastError = ""; std::list * tags = NULL; - char * data = NULL; + ByteString data; int dataStatus, dataLength; ByteString url = ByteString::Build("http://", SERVER, "/Browse/EditTag.json?Op=delete&ID=", saveID, "&Tag=", tag, "&Key=", authUser.SessionKey); if(authUser.UserID) { ByteString userID = ByteString::Build(authUser.UserID); - data = http_auth_get(url.c_str(), userID.c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, &dataLength); + data = Download::SimpleAuth(url, &dataLength, &dataStatus, userID, authUser.SessionID); } else { @@ -1882,7 +1830,7 @@ std::list * Client::RemoveTag(int saveID, ByteString tag) { try { - std::istringstream dataStream(data); + std::istringstream dataStream(data.c_str()); Json::Value responseObject; dataStream >> responseObject; @@ -1896,7 +1844,6 @@ std::list * Client::RemoveTag(int saveID, ByteString tag) lastError = "Could not read response: " + ByteString(e.what()).FromUtf8(); } } - free(data); return tags; } @@ -1904,13 +1851,13 @@ std::list * Client::AddTag(int saveID, ByteString tag) { lastError = ""; std::list * tags = NULL; - char * data = NULL; + ByteString data; int dataStatus, dataLength; ByteString url = ByteString::Build("http://", SERVER, "/Browse/EditTag.json?Op=add&ID=", saveID, "&Tag=", tag, "&Key=", authUser.SessionKey); if(authUser.UserID) { ByteString userID = ByteString::Build(authUser.UserID); - data = http_auth_get(url.c_str(), userID.c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, &dataLength); + data = Download::SimpleAuth(url, &dataLength, &dataStatus, userID, authUser.SessionID); } else { @@ -1922,7 +1869,7 @@ std::list * Client::AddTag(int saveID, ByteString tag) { try { - std::istringstream dataStream(data); + std::istringstream dataStream(data.c_str()); Json::Value responseObject; dataStream >> responseObject; @@ -1936,7 +1883,6 @@ std::list * Client::AddTag(int saveID, ByteString tag) lastError = "Could not read response: " + ByteString(e.what()).FromUtf8(); } } - free(data); return tags; } diff --git a/src/client/Client.h b/src/client/Client.h index 27f98feb4..18c45d40b 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -48,13 +48,14 @@ public: class RequestListener; class ClientListener; +class Download; class Client: public Singleton { private: String messageOfTheDay; std::vector > serverNotifications; - void * versionCheckRequest; - void * alternateVersionCheckRequest; + Download *versionCheckRequest; + Download *alternateVersionCheckRequest; bool usingAltUpdateServer; bool updateAvailable; UpdateInfo updateInfo; @@ -172,9 +173,9 @@ public: String GetLastError() { return lastError; } - RequestStatus ParseServerReturn(char *result, int status, bool json); + RequestStatus ParseServerReturn(ByteString &result, int status, bool json); void Tick(); - bool CheckUpdate(void *updateRequest, bool checkSession); + bool CheckUpdate(Download *updateRequest, bool checkSession); void Shutdown(); // preferences functions diff --git a/src/client/Download.cpp b/src/client/Download.cpp index da11c4c10..48d1362bb 100644 --- a/src/client/Download.cpp +++ b/src/client/Download.cpp @@ -2,6 +2,7 @@ #include "Download.h" #include "DownloadManager.h" #include "HTTP.h" +#include "Platform.h" Download::Download(ByteString uri_, bool keepAlive): http(NULL), @@ -84,10 +85,10 @@ bool Download::Reuse(ByteString newuri) } // finish the download (if called before the download is done, this will block) -char* Download::Finish(int *length, int *status) +ByteString Download::Finish(int *length, int *status) { if (CheckCanceled()) - return NULL; // shouldn't happen but just in case + return ""; // shouldn't happen but just in case while (!CheckDone()); // block DownloadManager::Ref().Lock(); downloadStarted = false; @@ -95,7 +96,12 @@ char* Download::Finish(int *length, int *status) *length = downloadSize; if (status) *status = downloadStatus; - char *ret = downloadData; + ByteString ret; + if (downloadData) + { + ret = ByteString(downloadData, downloadData + downloadSize); + free(downloadData); + } downloadData = NULL; if (!keepAlive) downloadCanceled = true; @@ -149,3 +155,34 @@ void Download::Cancel() downloadCanceled = true; DownloadManager::Ref().Unlock(); } + +ByteString Download::Simple(ByteString uri, int *length, int *status, std::map post_data) +{ + Download *request = new Download(uri); + request->AddPostData(post_data); + request->Start(); + while(!request->CheckDone()) + { + Platform::Millisleep(1); + } + return request->Finish(length, status); +} + +ByteString Download::SimpleAuth(ByteString uri, int *length, int *status, ByteString ID, ByteString session, std::map post_data) +{ + Download *request = new Download(uri); + request->AddPostData(post_data); + request->AuthHeaders(ID, session); + request->Start(); + while(!request->CheckDone()) + { + Platform::Millisleep(1); + } + return request->Finish(length, status); +} + +const char *Download::StatusText(int code) +{ + return http_ret_text(code); +} + diff --git a/src/client/Download.h b/src/client/Download.h index d925f3a46..c5017906a 100644 --- a/src/client/Download.h +++ b/src/client/Download.h @@ -33,7 +33,7 @@ public: void AuthHeaders(ByteString ID, ByteString session); void Start(); bool Reuse(ByteString newuri); - char* Finish(int *length, int *status); + ByteString Finish(int *length, int *status); void Cancel(); void CheckProgress(int *total, int *done); @@ -42,6 +42,11 @@ public: bool CheckStarted(); friend class DownloadManager; + + static ByteString Simple(ByteString uri, int *length, int *status, std::map post_data = {}); + static ByteString SimpleAuth(ByteString uri, int *length, int *status, ByteString ID, ByteString session, std::map post_data = {}); + + static const char *StatusText(int code); }; #endif diff --git a/src/client/requestbroker/APIRequest.cpp b/src/client/requestbroker/APIRequest.cpp index 084e580c9..1bb54497c 100644 --- a/src/client/requestbroker/APIRequest.cpp +++ b/src/client/requestbroker/APIRequest.cpp @@ -38,7 +38,8 @@ RequestBroker::ProcessResponse APIRequest::Process(RequestBroker & rb) int status, data_size; data = http_async_req_stop(HTTPContext, &status, &data_size); - Client::Ref().ParseServerReturn(data, status, true); + ByteString nice_data(data); + Client::Ref().ParseServerReturn(nice_data, status, true); if (status == 200 && data) { void * resultObject = Parser->ProcessResponse((unsigned char *)data, data_size); diff --git a/src/client/requestbroker/WebRequest.cpp b/src/client/requestbroker/WebRequest.cpp index c72b130d0..9910c7762 100644 --- a/src/client/requestbroker/WebRequest.cpp +++ b/src/client/requestbroker/WebRequest.cpp @@ -37,7 +37,8 @@ RequestBroker::ProcessResponse WebRequest::Process(RequestBroker & rb) int status, data_size; data = http_async_req_stop(HTTPContext, &status, &data_size); - Client::Ref().ParseServerReturn(NULL, status, true); + ByteString nothing; + Client::Ref().ParseServerReturn(nothing, status, true); if (status == 200 && data) { void * resultObject = new std::vector(data, data+data_size); diff --git a/src/gui/preview/PreviewModel.cpp b/src/gui/preview/PreviewModel.cpp index cb3987c12..3c607ce94 100644 --- a/src/gui/preview/PreviewModel.cpp +++ b/src/gui/preview/PreviewModel.cpp @@ -193,13 +193,13 @@ void PreviewModel::ClearComments() } } -bool PreviewModel::ParseSaveInfo(char * saveInfoResponse) +bool PreviewModel::ParseSaveInfo(ByteString &saveInfoResponse) { delete saveInfo; try { - std::istringstream dataStream(saveInfoResponse); + std::istringstream dataStream(saveInfoResponse.c_str()); Json::Value objDocument; dataStream >> objDocument; @@ -251,13 +251,13 @@ bool PreviewModel::ParseSaveInfo(char * saveInfoResponse) } } -bool PreviewModel::ParseComments(char *commentsResponse) +bool PreviewModel::ParseComments(ByteString &commentsResponse) { ClearComments(); saveComments = new std::vector(); try { - std::istringstream dataStream(commentsResponse); + std::istringstream dataStream(commentsResponse.c_str()); Json::Value commentsArray; dataStream >> commentsArray; @@ -284,13 +284,14 @@ void PreviewModel::Update() if (saveDataDownload && saveDataDownload->CheckDone()) { int status, length; - char *ret = saveDataDownload->Finish(&length, &status); + ByteString ret = saveDataDownload->Finish(&length, &status); - Client::Ref().ParseServerReturn(NULL, status, true); - if (status == 200 && ret) + ByteString nothing; + Client::Ref().ParseServerReturn(nothing, status, true); + if (status == 200 && ret.size()) { delete saveData; - saveData = new std::vector(ret, ret+length); + saveData = new std::vector(ret.begin(), ret.end()); if (saveInfo && saveData) OnSaveReady(); } @@ -302,16 +303,16 @@ void PreviewModel::Update() } } saveDataDownload = NULL; - free(ret); } if (saveInfoDownload && saveInfoDownload->CheckDone()) { int status; - char *ret = saveInfoDownload->Finish(NULL, &status); + ByteString ret = saveInfoDownload->Finish(NULL, &status); - Client::Ref().ParseServerReturn(NULL, status, true); - if (status == 200 && ret) + ByteString nothing; + Client::Ref().ParseServerReturn(nothing, status, true); + if (status == 200 && ret.size()) { if (ParseSaveInfo(ret)) { @@ -330,17 +331,17 @@ void PreviewModel::Update() observers[i]->SaveLoadingError(Client::Ref().GetLastError()); } saveInfoDownload = NULL; - free(ret); } if (commentsDownload && commentsDownload->CheckDone()) { int status; - char *ret = commentsDownload->Finish(NULL, &status); + ByteString ret = commentsDownload->Finish(NULL, &status); ClearComments(); - Client::Ref().ParseServerReturn(NULL, status, true); - if (status == 200 && ret) + ByteString nothing; + Client::Ref().ParseServerReturn(nothing, status, true); + if (status == 200 && ret.size()) ParseComments(ret); commentsLoaded = true; @@ -348,7 +349,6 @@ void PreviewModel::Update() notifyCommentsPageChanged(); commentsDownload = NULL; - free(ret); } } diff --git a/src/gui/preview/PreviewModel.h b/src/gui/preview/PreviewModel.h index 57a427cdc..4669d228d 100644 --- a/src/gui/preview/PreviewModel.h +++ b/src/gui/preview/PreviewModel.h @@ -57,8 +57,8 @@ public: void Update(); void ClearComments(); void OnSaveReady(); - bool ParseSaveInfo(char * saveInfoResponse); - bool ParseComments(char * commentsResponse); + bool ParseSaveInfo(ByteString &saveInfoResponse); + bool ParseComments(ByteString &commentsResponse); virtual ~PreviewModel(); }; diff --git a/src/gui/update/UpdateActivity.cpp b/src/gui/update/UpdateActivity.cpp index 03877c07d..00df33072 100644 --- a/src/gui/update/UpdateActivity.cpp +++ b/src/gui/update/UpdateActivity.cpp @@ -3,9 +3,9 @@ #include "gui/interface/Engine.h" #include "UpdateActivity.h" #include "tasks/Task.h" -#include "client/HTTP.h" #include "client/Client.h" #include "Update.h" +#include "client/Download.h" #include "Platform.h" @@ -26,27 +26,27 @@ private: virtual bool doWork() { String error; - void * request = http_async_req_start(NULL, (char*)updateName.c_str(), NULL, 0, 0); + Download *request = new Download(updateName); + request->Start(); notifyStatus("Downloading update"); notifyProgress(-1); - while(!http_async_req_status(request)) + while(!request->CheckDone()) { int total, done; - http_async_get_length(request, &total, &done); + request->CheckProgress(&total, &done); notifyProgress((float(done)/float(total))*100.0f); + Platform::Millisleep(1); } - char * data; int dataLength, status; - data = http_async_req_stop(request, &status, &dataLength); + ByteString data = request->Finish(&dataLength, &status); if (status!=200) { - free(data); error = String::Build("Server responded with Status ", status); notifyError("Could not download update: " + error); return false; } - if (!data) + if (data.size()) { error = "Server responded with nothing"; notifyError("Server did not return any data"); @@ -83,7 +83,7 @@ private: } int dstate; - dstate = BZ2_bzBuffToBuffDecompress((char *)res, (unsigned *)&uncompressedLength, (char *)(data+8), dataLength-8, 0, 0); + dstate = BZ2_bzBuffToBuffDecompress((char *)res, (unsigned *)&uncompressedLength, &data[8], dataLength-8, 0, 0); if (dstate) { error = String::Build("Unable to decompress update: ", dstate); @@ -91,8 +91,6 @@ private: goto corrupt; } - free(data); - notifyStatus("Applying update"); notifyProgress(-1); @@ -110,7 +108,6 @@ private: corrupt: notifyError("Downloaded update is corrupted\n" + error); - free(data); return false; } }; diff --git a/src/lua/LegacyLuaAPI.cpp b/src/lua/LegacyLuaAPI.cpp index 682825b8d..45595d5e9 100644 --- a/src/lua/LegacyLuaAPI.cpp +++ b/src/lua/LegacyLuaAPI.cpp @@ -4,7 +4,7 @@ #include #include -#include "client/HTTP.h" +#include "client/Download.h" #include "Format.h" #include "LuaScriptInterface.h" #include "LuaScriptHelper.h" @@ -1355,21 +1355,18 @@ int luatpt_getscript(lua_State* l) return 0; int ret, len; - char *scriptData = http_simple_get(url.c_str(), &ret, &len); + ByteString scriptData = Download::Simple(url, &len, &ret); if (len <= 0 || !filename) { - free(scriptData); return luaL_error(l, "Server did not return data"); } if (ret != 200) { - free(scriptData); - return luaL_error(l, http_ret_text(ret)); + return luaL_error(l, Download::StatusText(ret)); } - if (!strcmp(scriptData, "Invalid script ID\r\n")) + if (!strcmp(scriptData.c_str(), "Invalid script ID\r\n")) { - free(scriptData); return luaL_error(l, "Invalid Script ID"); } @@ -1384,7 +1381,6 @@ int luatpt_getscript(lua_State* l) } else { - free(scriptData); return 0; } } @@ -1394,11 +1390,10 @@ int luatpt_getscript(lua_State* l) } if (!outputfile) { - free(scriptData); return luaL_error(l, "Unable to write to file"); } - fputs(scriptData, outputfile); + fputs(scriptData.c_str(), outputfile); fclose(outputfile); outputfile = NULL; if (runScript)