void CL_cURL_Cleanup(void) { if(clc.downloadCURLM) { CURLMcode result; if(clc.downloadCURL) { result = qcurl_multi_remove_handle(clc.downloadCURLM, clc.downloadCURL); if(result != CURLM_OK) { Com_DPrintf("qcurl_multi_remove_handle failed: %s\n", qcurl_multi_strerror(result)); } qcurl_easy_cleanup(clc.downloadCURL); } result = qcurl_multi_cleanup(clc.downloadCURLM); if(result != CURLM_OK) { Com_DPrintf("CL_cURL_Cleanup: qcurl_multi_cleanup failed: %s\n", qcurl_multi_strerror(result)); } clc.downloadCURLM = NULL; clc.downloadCURL = NULL; } else if(clc.downloadCURL) { qcurl_easy_cleanup(clc.downloadCURL); clc.downloadCURL = NULL; } }
void CL_cURL_Cleanup(void) { if(clc.curl.downloadCURLM) { if(clc.curl.downloadCURL) { qcurl_multi_remove_handle(clc.curl.downloadCURLM, clc.curl.downloadCURL); qcurl_easy_cleanup(clc.curl.downloadCURL); } qcurl_multi_cleanup(clc.curl.downloadCURLM); clc.curl.downloadCURLM = NULL; clc.curl.downloadCURL = NULL; } else if(clc.curl.downloadCURL) { qcurl_easy_cleanup(clc.curl.downloadCURL); clc.curl.downloadCURL = NULL; } }
static void Curl_EndDownload(downloadinfo *di, CurlStatus status, CURLcode error) { qboolean ok = false; if(!curl_dll) return; switch(status) { case CURL_DOWNLOAD_SUCCESS: ok = true; di->callback(CURLCBSTATUS_OK, di->bytes_received, di->buffer, di->callback_data); break; case CURL_DOWNLOAD_FAILED: di->callback(CURLCBSTATUS_FAILED, di->bytes_received, di->buffer, di->callback_data); break; case CURL_DOWNLOAD_ABORTED: di->callback(CURLCBSTATUS_ABORTED, di->bytes_received, di->buffer, di->callback_data); break; case CURL_DOWNLOAD_SERVERERROR: // reopen to enforce it to have zero bytes again if(di->stream) { FS_Close(di->stream); di->stream = FS_OpenRealFile(di->filename, "wb", false); } if(di->callback) di->callback(error ? (int) error : CURLCBSTATUS_SERVERERROR, di->bytes_received, di->buffer, di->callback_data); break; default: if(di->callback) di->callback(CURLCBSTATUS_UNKNOWN, di->bytes_received, di->buffer, di->callback_data); break; } if(di->curle) { qcurl_multi_remove_handle(curlm, di->curle); qcurl_easy_cleanup(di->curle); if(di->slist) qcurl_slist_free_all(di->slist); } if(!di->callback && ok && !di->bytes_received) { Con_Printf("ERROR: empty file\n"); ok = false; } if(di->stream) FS_Close(di->stream); if(ok && di->ispak) { ok = FS_AddPack(di->filename, NULL, true); if(!ok) { // pack loading failed? // this is critical // better clear the file again... di->stream = FS_OpenRealFile(di->filename, "wb", false); FS_Close(di->stream); if(di->startpos && !di->callback) { // this was a resume? // then try to redownload it without reporting the error Curl_Begin(di->url, di->extraheaders, di->maxspeed, di->filename, di->ispak, di->forthismap, di->post_content_type, di->postbuf, di->postbufsize, NULL, 0, NULL, NULL); di->forthismap = false; // don't count the error } } } if(di->prev) di->prev->next = di->next; else downloads = di->next; if(di->next) di->next->prev = di->prev; --numdownloads; if(di->forthismap) { if(ok) ++numdownloads_success; else ++numdownloads_fail; } Z_Free(di); }
static void Curl_EndDownload(downloadinfo *di, CurlStatus status, CURLcode error, const char *content_type_) { char content_type[64]; qboolean ok = false; if(!curl_dll) return; switch(status) { case CURL_DOWNLOAD_SUCCESS: ok = true; di->callback(CURLCBSTATUS_OK, di->bytes_received, di->buffer, di->callback_data); break; case CURL_DOWNLOAD_FAILED: di->callback(CURLCBSTATUS_FAILED, di->bytes_received, di->buffer, di->callback_data); break; case CURL_DOWNLOAD_ABORTED: di->callback(CURLCBSTATUS_ABORTED, di->bytes_received, di->buffer, di->callback_data); break; case CURL_DOWNLOAD_SERVERERROR: // reopen to enforce it to have zero bytes again if(di->stream) { FS_Close(di->stream); di->stream = FS_OpenRealFile(di->filename, "wb", false); } if(di->callback) di->callback(error ? (int) error : CURLCBSTATUS_SERVERERROR, di->bytes_received, di->buffer, di->callback_data); break; default: if(di->callback) di->callback(CURLCBSTATUS_UNKNOWN, di->bytes_received, di->buffer, di->callback_data); break; } if(content_type_) strlcpy(content_type, content_type_, sizeof(content_type)); else *content_type = 0; if(di->curle) { qcurl_multi_remove_handle(curlm, di->curle); qcurl_easy_cleanup(di->curle); if(di->slist) qcurl_slist_free_all(di->slist); } if(!di->callback && ok && !di->bytes_received) { Con_Printf("ERROR: empty file\n"); ok = false; } if(di->stream) FS_Close(di->stream); #define CLEAR_AND_RETRY() \ do \ { \ di->stream = FS_OpenRealFile(di->filename, "wb", false); \ FS_Close(di->stream); \ if(di->startpos && !di->callback) \ { \ Curl_Begin(di->url, di->extraheaders, di->maxspeed, di->filename, di->loadtype, di->forthismap, di->post_content_type, di->postbuf, di->postbufsize, NULL, 0, NULL, NULL); \ di->forthismap = false; \ } \ } \ while(0) if(ok && di->loadtype == LOADTYPE_PAK) { ok = FS_AddPack(di->filename, NULL, true); if(!ok) CLEAR_AND_RETRY(); } else if(ok && di->loadtype == LOADTYPE_CACHEPIC) { const char *p; unsigned char *pixels = NULL; p = di->filename; #ifdef WE_ARE_EVIL if(!strncmp(p, "dlcache/", 8)) p += 8; #endif pixels = decode_image(di, content_type); if(pixels) Draw_NewPic(p, image_width, image_height, true, pixels); else CLEAR_AND_RETRY(); } else if(ok && di->loadtype == LOADTYPE_SKINFRAME) { const char *p; unsigned char *pixels = NULL; p = di->filename; #ifdef WE_ARE_EVIL if(!strncmp(p, "dlcache/", 8)) p += 8; #endif pixels = decode_image(di, content_type); if(pixels) R_SkinFrame_LoadInternalBGRA(p, TEXF_FORCE_RELOAD | TEXF_MIPMAP | TEXF_ALPHA, pixels, image_width, image_height, false); // TODO what sRGB argument to put here? else CLEAR_AND_RETRY(); } if(di->prev) di->prev->next = di->next; else downloads = di->next; if(di->next) di->next->prev = di->prev; --numdownloads; if(di->forthismap) { if(ok) ++numdownloads_success; else ++numdownloads_fail; } Z_Free(di); }
void wswcurl_delete( wswcurl_req *req ) { if( ( !req ) || ( !wswcurl_isvalidhandle( req ) ) ) { return; } // if (req->callback_done && req->active ) // req->callback_done ( req, 0, req->customp ); if( req->txhead ) { qcurl_slist_free_all( req->txhead ); req->txhead = NULL; } if( req->post ) { qcurl_formfree( req->post ); req->post = NULL; req->post_last = NULL; } if( req->url ) { WFREE( req->url ); } if( req->bhead ) { chained_buffer_t *cb = req->bhead; chained_buffer_t *next = cb->next; while( cb ) { WFREE( cb ); cb = next; if( cb ) { next = cb->next; } } } // remove from list QMutex_Lock( http_requests_mutex ); if( req->curl ) { if( curlmulti && req->status && req->status != WSTATUS_QUEUED ) { qcurl_multi_remove_handle( curlmulti, req->curl ); curlmulti_num_handles--; } qcurl_easy_cleanup( req->curl ); req->curl = NULL; } if( http_requests_hnode == req ) { http_requests_hnode = req->prev; } if( http_requests == req ) { http_requests = req->next; } if( req->prev ) { req->prev->next = req->next; } if( req->next ) { req->next->prev = req->prev; } QMutex_Unlock( http_requests_mutex ); WFREE( req ); }