123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- #include "Main.h"
- #pragma warning(disable:4786)
- #include "DownloadThread.h"
- #include "api__ml_wire.h"
- #include "api/service/waServiceFactory.h"
- #include "../../..\Components\wac_network\wac_network_http_receiver_api.h"
- #include "errors.h"
- #include <strsafe.h>
- extern int winampVersion;
- #define USER_AGENT_SIZE (10 /*User-Agent*/ + 2 /*: */ + 6 /*Winamp*/ + 1 /*/*/ + 1 /*5*/ + 3/*.21*/ + 1 /*Null*/)
- void SetUserAgent( api_httpreceiver *http )
- {
- char user_agent[ USER_AGENT_SIZE ] = { 0 };
- int bigVer = ( ( winampVersion & 0x0000FF00 ) >> 12 );
- int smallVer = ( ( winampVersion & 0x000000FF ) );
- StringCchPrintfA( user_agent, USER_AGENT_SIZE, "User-Agent: Winamp/%01x.%02x", bigVer, smallVer );
- http->addheader( user_agent );
- }
- #define HTTP_BUFFER_SIZE 32768
- 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;
- }
- DownloadThread::DownloadThread() : parser( 0 ), parserFactory( 0 )
- {
- parserFactory = plugin.service->service_getServiceByGuid( obj_xmlGUID );
- if ( parserFactory )
- parser = (obj_xml *)parserFactory->getInterface();
- if ( parser )
- {
- parser->xmlreader_setCaseSensitive();
- parser->xmlreader_registerCallback( L"*", &xmlDOM );
- parser->xmlreader_open();
- }
- }
- DownloadThread::~DownloadThread()
- {
- if ( parser )
- {
- parser->xmlreader_unregisterCallback( &xmlDOM );
- parser->xmlreader_close();
- }
- if ( parserFactory && parser )
- parserFactory->releaseInterface( parser );
- parserFactory = 0;
- parser = 0;
- }
- void URLToFileName( wchar_t *url )
- {
- while ( url && *url != 0 )
- {
- switch ( *url )
- {
- case ':':
- case '/':
- case '\\':
- case '*':
- case '?':
- case '"':
- case '<':
- case '>':
- case '|':
- *url = '_';
- }
- url++;
- }
- }
- #define FILE_BUFFER_SIZE 32768
- void DownloadThread::DownloadFile( const wchar_t *fileName )
- {
- if ( !parser )
- return; // no sense in continuing if there's no parser available
- HANDLE file = CreateFile( fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL );
- if ( file == INVALID_HANDLE_VALUE )
- return;
- while ( true )
- {
- char data[ FILE_BUFFER_SIZE ] = { 0 };
- DWORD bytesRead = 0;
- if ( ReadFile( file, data, FILE_BUFFER_SIZE, &bytesRead, NULL ) && bytesRead )
- {
- parser->xmlreader_feed( (void *)data, bytesRead );
- }
- else
- break;
- }
- CloseHandle( file );
- parser->xmlreader_feed( 0, 0 );
- ReadNodes( fileName );
- }
- #ifdef _DEBUG
- #include <iostream>
- void ShowAllHeaders( api_httpreceiver *http )
- {
- std::cout << "--------------------" << std::endl;
- const char *blah = http->getallheaders();
- while ( blah && *blah )
- {
- std::cout << blah << std::endl;
- blah += strlen( blah ) + 1;
- }
- }
- #else
- #define ShowAllHeaders(x)
- #endif
- int RunXMLDownload( api_httpreceiver *http, obj_xml *parser )
- {
- int ret;
- bool noData;
- do
- {
- Sleep( 50 );
- ret = http->run();
- if ( FeedXMLHTTP( http, parser, &noData ) != API_XML_SUCCESS )
- return DOWNLOAD_ERROR_PARSING_XML;
- } while ( ret == HTTPRECEIVER_RUN_OK );
- // finish off the data
- do
- {
- if ( FeedXMLHTTP( http, parser, &noData ) != API_XML_SUCCESS )
- return DOWNLOAD_ERROR_PARSING_XML;
- } while ( !noData );
- parser->xmlreader_feed( 0, 0 );
- if ( ret != HTTPRECEIVER_RUN_ERROR )
- return DOWNLOAD_SUCCESS;
- else
- return DOWNLOAD_CONNECTIONRESET;
- }
- int DownloadThread::DownloadURL( const wchar_t *url )
- {
- if ( !parser )
- return DOWNLOAD_NOPARSER; // no sense in continuing if there's no parser available
- api_httpreceiver *http = 0;
- waServiceFactory *sf = plugin.service->service_getServiceByGuid( httpreceiverGUID );
- if ( sf )
- http = (api_httpreceiver *)sf->getInterface();
- if ( !http )
- return DOWNLOAD_NOHTTP;
- http->AllowCompression();
- http->open( API_DNS_AUTODNS, HTTP_BUFFER_SIZE, mediaLibrary.GetProxy() );
- SetUserAgent( http );
- http->connect( AutoChar( url ) );
- int ret;
- do
- {
- 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:
- {
- ShowAllHeaders( http ); // benski> don't cut, only enabled in debug mode
- int downloadError;
- downloadError = RunXMLDownload( http, parser );
- if ( downloadError == DOWNLOAD_SUCCESS )
- ReadNodes( url );
- sf->releaseInterface( http );
- return downloadError;
- }
- break;
- case HTTPRECEIVER_STATUS_ERROR:
- default:
- sf->releaseInterface( http );
- return DOWNLOAD_404;
- }
- } while ( ret == HTTPRECEIVER_RUN_OK );
- const char *er = http->geterrorstr();
- sf->releaseInterface( http );
- return DOWNLOAD_404;
- }
|