/* ======================================================================================================================================= DL_BeginDownload Inspired from http://www.w3.org/Library/Examples/LoadToFile.c, setup the download, return once we have a connection. ======================================================================================================================================= */ int DL_BeginDownload(char *localName, const char *remoteName) { char referer[MAX_STRING_CHARS + 5 /*"ET://"*/]; if (dl_request) { Com_Printf(S_COLOR_RED "DL_BeginDownload: Error - called with a download request already active\n"); return 0; } if (!localName[0] || !remoteName[0]) { Com_Printf(S_COLOR_RED "DL_BeginDownload: Error - empty download URL or empty local file name\n"); return 0; } if (FS_CreatePath(localName)) { Com_Printf(S_COLOR_RED "DL_BeginDownload: Error - unable to create directory(%s).\n", localName); return 0; } dl_file = fopen(localName, "wb + "); if (!dl_file) { Com_Printf(S_COLOR_RED "DL_BeginDownload: Error - unable to open '%s' for writing\n", localName); return 0; } DL_InitDownload(); // ET://ip:port strcpy(referer, "ET://"); Q_strncpyz(referer + 5, Cvar_VariableString("cl_currentServerIP"), MAX_STRING_CHARS); dl_request = curl_easy_init(); curl_easy_setopt(dl_request, CURLOPT_USERAGENT, va("%s %s", APP_NAME "/" APP_VERSION, curl_version())); curl_easy_setopt(dl_request, CURLOPT_REFERER, referer); curl_easy_setopt(dl_request, CURLOPT_URL, remoteName); curl_easy_setopt(dl_request, CURLOPT_WRITEFUNCTION, DL_cb_FWriteFile); curl_easy_setopt(dl_request, CURLOPT_WRITEDATA, (void *)dl_file); curl_easy_setopt(dl_request, CURLOPT_PROGRESSFUNCTION, DL_cb_Progress); curl_easy_setopt(dl_request, CURLOPT_NOPROGRESS, 0); curl_easy_setopt(dl_request, CURLOPT_FAILONERROR, 1); curl_easy_setopt(dl_request, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(dl_request, CURLOPT_MAXREDIRS, 5); #ifdef FEATURE_OPENSSL #if 0 curl_easy_setopt(dl_request, CURLOPT_CAINFO, "./cert.crt"); #else curl_easy_setopt(dl_request, CURLOPT_SSL_VERIFYHOST, 0); curl_easy_setopt(dl_request, CURLOPT_SSL_VERIFYPEER, 0); #endif #endif if (curl_multi_add_handle(dl_multi, dl_request) != CURLM_OK) { Com_Printf(S_COLOR_RED "DL_BeginDownload: Error - invalid handle.\n"); } Cvar_Set("cl_downloadName", remoteName); return 1; }
/* =============== inspired from http://www.w3.org/Library/Examples/LoadToFile.c setup the download, return once we have a connection =============== */ int DL_BeginDownload( const char *localName, const char *remoteName, int debug ) { char referer[ MAX_STRING_CHARS + URI_SCHEME_LENGTH ]; if ( dl_request ) { curl_multi_remove_handle( dl_multi, dl_request ); curl_easy_cleanup( dl_request ); dl_request = NULL; } if ( dl_file ) { FS_FCloseFile( dl_file ); dl_file = 0; } if ( !localName || !remoteName ) { Com_DPrintf( "Empty download URL or empty local file name\n" ); return 0; } dl_file = FS_SV_FOpenFileWrite( localName ); if ( !dl_file ) { Com_Printf( "ERROR: DL_BeginDownload unable to open '%s' for writing\n", localName ); return 0; } DL_InitDownload(); strcpy( referer, URI_SCHEME ); Q_strncpyz( referer + URI_SCHEME_LENGTH, Cvar_VariableString( "cl_currentServerIP" ), MAX_STRING_CHARS ); dl_request = curl_easy_init(); curl_easy_setopt( dl_request, CURLOPT_USERAGENT, va( "%s %s", PRODUCT_NAME "/" PRODUCT_VERSION, curl_version() ) ); curl_easy_setopt( dl_request, CURLOPT_REFERER, referer ); curl_easy_setopt( dl_request, CURLOPT_URL, remoteName ); curl_easy_setopt( dl_request, CURLOPT_WRITEFUNCTION, DL_cb_FWriteFile ); curl_easy_setopt( dl_request, CURLOPT_WRITEDATA, ( void * )( intptr_t ) dl_file ); curl_easy_setopt( dl_request, CURLOPT_PROGRESSFUNCTION, DL_cb_Progress ); curl_easy_setopt( dl_request, CURLOPT_NOPROGRESS, 0 ); curl_easy_setopt( dl_request, CURLOPT_FAILONERROR, 1 ); curl_multi_add_handle( dl_multi, dl_request ); Cvar_Set( "cl_downloadName", remoteName ); return 1; }
/* =============== inspired from http://www.w3.org/Library/Examples/LoadToFile.c setup the download, return once we have a connection =============== */ int DL_BeginDownload(const char *localName, const char *remoteName, int debug) { char referer[MAX_STRING_CHARS + 5 /*"ET://" */ ]; if(dl_request) { Com_Printf("ERROR: DL_BeginDownload called with a download request already active\n"); return 0; } if(!localName || !remoteName) { Com_DPrintf("Empty download URL or empty local file name\n"); return 0; } FS_CreatePath(localName); dl_file = fopen(localName, "wb+"); if(!dl_file) { Com_Printf("ERROR: DL_BeginDownload unable to open '%s' for writing\n", localName); return 0; } DL_InitDownload(); /* ET://ip:port */ strcpy(referer, "ET://"); Q_strncpyz(referer + 5, Cvar_VariableString("cl_currentServerIP"), MAX_STRING_CHARS); dl_request = curl_easy_init(); curl_easy_setopt(dl_request, CURLOPT_USERAGENT, va("%s %s", APP_NAME "/" APP_VERSION, curl_version())); curl_easy_setopt(dl_request, CURLOPT_REFERER, referer); curl_easy_setopt(dl_request, CURLOPT_URL, remoteName); curl_easy_setopt(dl_request, CURLOPT_WRITEFUNCTION, DL_cb_FWriteFile); curl_easy_setopt(dl_request, CURLOPT_WRITEDATA, (void *)dl_file); curl_easy_setopt(dl_request, CURLOPT_PROGRESSFUNCTION, DL_cb_Progress); curl_easy_setopt(dl_request, CURLOPT_NOPROGRESS, 0); curl_easy_setopt(dl_request, CURLOPT_FAILONERROR, 1); curl_multi_add_handle(dl_multi, dl_request); Cvar_Set("cl_downloadName", remoteName); return 1; }
/* =============== inspired from http://www.w3.org/Library/Examples/LoadToFile.c setup the download, return once we have a connection =============== */ int DL_BeginDownload( const char *localName, const char *remoteName, int debug ) { char *access = NULL; char *url = NULL; char *login = NULL; char *path = NULL; char *ptr = NULL; if ( dl_running ) { Com_Printf(_( "ERROR: DL_BeginDownload called with a download request already active\n" )); return 0; } terminate_status = HT_UNDEF; #ifdef HTDEBUG if ( debug ) { WWWTRACE = SHOW_ALL_TRACE; } #endif if ( !localName || !remoteName ) { Com_DPrintf( "Empty download URL or empty local file name\n" ); return 0; } DL_InitDownload(); /* need access for ftp behaviour and HTTP Basic Auth */ access = HTParse( remoteName, "", PARSE_ACCESS ); /* Set the timeout for how long we are going to wait for a response This needs to be set and reset to 0 after dl each time idcvs/2003-January/000449.html http://lists.w3.org/Archives/Public/www-lib/2003AprJun/0033.html In case of ftp download, we leave no timeout during connect phase cause of libwww bugs show_bug.cgi?id=605 */ if ( !Q_stricmp( access, "ftp" ) ) { dl_is_ftp = 1; HTHost_setEventTimeout( -1 ); } else { dl_is_ftp = 0; HTHost_setEventTimeout( 30000 ); } dl_request = HTRequest_new(); /* HTTP Basic Auth */ if ( !Q_stricmp( access, "http" ) ) { HTBasic *basic; login = HTParse( remoteName, "", PARSE_HOST ); path = HTParse( remoteName, "", PARSE_PATH + PARSE_PUNCTUATION ); ptr = strchr( login, '@' ); if ( ptr ) { /* Uid and/or passwd specified */ char *passwd; *ptr = '\0'; passwd = strchr( login, ':' ); if ( passwd ) { /* Passwd specified */ *passwd++ = '\0'; HTUnEscape( passwd ); } HTUnEscape( login ); /* proactively set the auth */ basic = HTBasic_new(); StrAllocCopy( basic->uid, login ); StrAllocCopy( basic->pw, passwd ); basic_credentials( dl_request, basic ); HTBasic_delete( basic ); /* correct the HTTP */ url = HT_MALLOC( 7 + strlen( ptr + 1 ) + strlen( path ) + 1 ); sprintf( url, "http://%s%s", ptr + 1, path ); Com_DPrintf( "HTTP Basic Auth – %s %s %s\n", login, passwd, url ); HT_FREE( login ); HT_FREE( path ); } else { StrAllocCopy( url, remoteName ); } } else { StrAllocCopy( url, remoteName ); } HT_FREE( access ); FS_CreatePath( localName ); /* Start the load */ if ( HTLoadToFile( url, dl_request, localName ) != YES ) { Com_DPrintf( "HTLoadToFile failed\n" ); HT_FREE( url ); HTProfile_delete(); return 0; } HT_FREE( url ); /* remove possible login/pass part for the ui */ access = HTParse( remoteName, "", PARSE_ACCESS ); login = HTParse( remoteName, "", PARSE_HOST ); path = HTParse( remoteName, "", PARSE_PATH + PARSE_PUNCTUATION ); ptr = strchr( login, '@' ); if ( ptr ) { /* Uid and/or passwd specified */ Cvar_Set( "cl_downloadName", va( "%s://*:*%s%s", access, ptr, path ) ); } else { Cvar_Set( "cl_downloadName", remoteName ); } HT_FREE( path ); HT_FREE( login ); HT_FREE( access ); if ( dl_is_ftp ) { HTHost_setEventTimeout( 30000 ); } /* Go into the event loop... */ HTEventList_init( dl_request ); dl_running = 1; return 1; }
char *DL_GetString(const char *url) { CURL *curl = NULL; CURLcode status; char *data = NULL; long code; write_result_t write_result = { NULL, 0 }; if (!url) { Com_Printf("Empty download URL\n"); return NULL; } DL_InitDownload(); curl = curl_easy_init(); data = (char *)malloc(GET_BUFFER_SIZE); if (!data) { goto error_get; } else { write_result.data = data; } curl_easy_setopt(curl, CURLOPT_USERAGENT, va("%s %s", APP_NAME "/" APP_VERSION, curl_version())); curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, DL_write_function); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &write_result); status = curl_easy_perform(curl); if (status != 0) { Com_Printf("DL_GetString unable to request data from %s\n", url); Com_Printf("DL_GetString %s\n", curl_easy_strerror(status)); goto error_get; } curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code); if (code != 200) { Com_Printf("DL_GetString server responded with code %ld\n", code); goto error_get; } curl_easy_cleanup(curl); data[write_result.pos] = '\0'; return data; error_get: if (curl) { curl_easy_cleanup(curl); } if (data) { free(data); } return NULL; }
/* ======================================================================================================================================= DL_GetString ======================================================================================================================================= */ char *DL_GetString(const char *url) { CURL *curl = NULL; CURLcode status; char *data = NULL; long code; write_result_t write_result = {NULL, 0}; if (!url) { Com_Printf(S_COLOR_RED "DL_GetString: Error - empty download URL\n"); return NULL; } DL_InitDownload(); curl = curl_easy_init(); data = (char *)Com_Allocate(GET_BUFFER_SIZE); if (!data) { goto error_get; } else { write_result.data = data; } curl_easy_setopt(curl, CURLOPT_USERAGENT, va("%s %s", APP_NAME "/" APP_VERSION, curl_version())); curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, DL_write_function); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&write_result); #ifdef FEATURE_OPENSSL #if 0 curl_easy_setopt(dl_request, CURLOPT_CAINFO, "./cert.crt"); #else curl_easy_setopt(dl_request, CURLOPT_SSL_VERIFYHOST, 0); curl_easy_setopt(dl_request, CURLOPT_SSL_VERIFYPEER, 0); #endif #endif status = curl_easy_perform(curl); if (status != 0) { Com_Printf(S_COLOR_RED "DL_GetString: Error - unable to request data from %s\n", url); Com_Printf(S_COLOR_RED "DL_GetString: Error - %s\n", curl_easy_strerror(status)); goto error_get; } curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code); if (code != 200) { Com_Printf(S_COLOR_RED "DL_GetString: Error - server responded with code %ld\n", code); goto error_get; } curl_easy_cleanup(curl); data[write_result.pos] = '\0'; return data; error_get: if (curl) { curl_easy_cleanup(curl); } if (data) { Com_Dealloc(data); } return NULL; }