diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/auth/post.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/auth/post.cpp')
-rw-r--r-- | Src/auth/post.cpp | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/Src/auth/post.cpp b/Src/auth/post.cpp new file mode 100644 index 00000000..db755671 --- /dev/null +++ b/Src/auth/post.cpp @@ -0,0 +1,218 @@ +#include "api.h" +#include "../xml/obj_xml.h" +#include "api_auth.h" +#include "../nu/AutoChar.h" +#include "../jnetlib/api_httpget.h" +#include "ifc_authcallback.h" +#include <api/service/waservicefactory.h> +#include <strsafe.h> + + +static const GUID internetConfigGroupGUID = +{ + 0xc0a565dc, 0xcfe, 0x405a, { 0xa2, 0x7c, 0x46, 0x8b, 0xc, 0x8a, 0x3a, 0x5c } +}; + + +#define USER_AGENT_SIZE (10 /*User-Agent*/ + 2 /*: */ + 6 /*Winamp*/ + 1 /*/*/ + 1 /*5*/ + 3/*.55*/ + 1 /*Null*/) +static void SetUserAgent(api_httpreceiver *http) +{ + char user_agent[USER_AGENT_SIZE] = {0}; + StringCchPrintfA(user_agent, USER_AGENT_SIZE, "User-Agent: Winamp/%S", WASABI_API_APP->main_getVersionNumString()); + http->addheader(user_agent); +} + + +#define HTTP_BUFFER_SIZE 8192 + +static int FeedXMLHTTP(api_httpreceiver *http, obj_xml *parser, bool *noData) +{ + char downloadedData[HTTP_BUFFER_SIZE] = {0}; + int xmlResult = API_XML_SUCCESS; + int downloadSize = http->get_bytes(downloadedData, HTTP_BUFFER_SIZE); + if (downloadSize) + { + xmlResult = parser->xmlreader_feed((void *)downloadedData, downloadSize); + *noData=false; + } + else + *noData = true; + + return xmlResult; +} + + +static int RunXMLDownload(api_httpreceiver *http, obj_xml *parser, ifc_authcallback *callback) +{ + int ret; + bool noData; + do + { + if (callback && callback->OnIdle()) + { + return AUTH_ABORT; + } + else if (!callback) + { + Sleep(50); + } + + ret = http->run(); + if (FeedXMLHTTP(http, parser, &noData) != API_XML_SUCCESS) + return AUTH_ERROR_PARSING_XML; + } + while (ret == HTTPRECEIVER_RUN_OK); + + // finish off the data + do + { + if (FeedXMLHTTP(http, parser, &noData) != API_XML_SUCCESS) + return AUTH_ERROR_PARSING_XML; + } while (!noData); + + parser->xmlreader_feed(0, 0); + if (ret != HTTPRECEIVER_RUN_ERROR) + return AUTH_SUCCESS; + else + return AUTH_CONNECTIONRESET; +} + + +int PostXML(const char *url, const char *post_data, obj_xml *parser, ifc_authcallback *callback) +{ + if (!parser) + return AUTH_NOPARSER; + + api_httpreceiver *http = 0; + waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(httpreceiverGUID); + if (sf) + http = (api_httpreceiver *)sf->getInterface(); + + if (!http) + return AUTH_NOHTTP; + + int use_proxy = 1; + bool proxy80 = AGAVE_API_CONFIG->GetBool(internetConfigGroupGUID, L"proxy80", false); + if (proxy80 && strstr(url, ":") && (!strstr(url, ":80/") && strstr(url, ":80") != (url + strlen(url) - 3))) + use_proxy = 0; + + const wchar_t *proxy = use_proxy?AGAVE_API_CONFIG->GetString(internetConfigGroupGUID, L"proxy", 0):0; + size_t clen = strlen(post_data); + + http->open(API_DNS_AUTODNS, HTTP_BUFFER_SIZE, (proxy && proxy[0]) ? (const char *)AutoChar(proxy) : NULL); + SetUserAgent(http); + + char clen_header[1024] = {0}; + StringCbPrintfA(clen_header, sizeof(clen_header), "Content-Length: %u", clen); + http->addheader(clen_header); + http->addheader("Content-Type: application/x-www-form-urlencoded; charset=UTF-8"); + if (callback && callback->OnConnecting()) + { + sf->releaseInterface(http); + return AUTH_ABORT; + } + http->connect(url, 0, "POST"); + + // POST the data + api_connection *connection = http->GetConnection(); + if (connection) + { + if (callback && callback->OnIdle()) + { + sf->releaseInterface(http); + return AUTH_ABORT; + } + else if (!callback) + { + Sleep(50); + } + + if (http->run() == -1) + goto connection_failed; + + if (callback && callback->OnSending()) + { + sf->releaseInterface(http); + return AUTH_ABORT; + } + + const char *dataIndex = post_data; + while (clen) + { + if (callback && callback->OnIdle()) + { + sf->releaseInterface(http); + return AUTH_ABORT; + } + else if (!callback) + { + Sleep(50); + } + + if (http->run() == -1) + goto connection_failed; + + size_t lengthToSend = min(clen, connection->GetSendBytesAvailable()); + if (lengthToSend) + { + connection->send(dataIndex, (int)lengthToSend); + dataIndex+=lengthToSend; + clen-=lengthToSend; + } + } + } + + // retrieve reply + if (callback && callback->OnReceiving()) + { + sf->releaseInterface(http); + return AUTH_ABORT; + } + + int ret; + do + { + if (callback && callback->OnIdle()) + { + sf->releaseInterface(http); + return AUTH_ABORT; + } + else if (!callback) + { + Sleep(50); + } + + ret = http->run(); + if (ret == -1) // connection failed + break; + + // ---- check our reply code ---- + int status = http->get_status(); + switch (status) + { + case HTTPRECEIVER_STATUS_CONNECTING: + case HTTPRECEIVER_STATUS_READING_HEADERS: + break; + + case HTTPRECEIVER_STATUS_READING_CONTENT: + { + int downloadError; + downloadError = RunXMLDownload(http, parser, callback); + sf->releaseInterface(http); + return downloadError; + } + break; + case HTTPRECEIVER_STATUS_ERROR: + default: + sf->releaseInterface(http); + return AUTH_404; + } + } + while (ret == HTTPRECEIVER_RUN_OK); + + +connection_failed: + sf->releaseInterface(http); + return AUTH_404; +} + |