123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- #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;
- }
|