/* =============== CL_StartHTTPDownload Actually starts a download by adding it to the curl multi handle. =============== */ static void CL_StartHTTPDownload (dlqueue_t *entry, dlhandle_t *dl) { size_t len; char tempFile[MAX_OSPATH]; char escapedFilePath[MAX_QPATH*4]; //yet another hack to accomodate filelists, how i wish i could push :( //NULL file handle indicates filelist. len = strlen (entry->quakePath); if (len > 9 && !strcmp (entry->quakePath + len - 9, ".filelist")) { dl->file = NULL; CL_EscapeHTTPPath (entry->quakePath, escapedFilePath); } else { CL_HTTP_Reset_KBps_counter (); // Knightmare- for KB/s counter Com_sprintf (dl->filePath, sizeof(dl->filePath), "%s/%s", FS_Gamedir(), entry->quakePath); Com_sprintf (tempFile, sizeof(tempFile), "%s/%s", cl.gamedir, entry->quakePath); CL_EscapeHTTPPath (dl->filePath, escapedFilePath); // strncat (dl->filePath, ".tmp"); Q_strncatz (dl->filePath, ".tmp", sizeof(dl->filePath)); FS_CreatePath (dl->filePath); //don't bother with http resume... too annoying if server doesn't support it. dl->file = fopen (dl->filePath, "wb"); if (!dl->file) { Com_Printf ("CL_StartHTTPDownload: Couldn't open %s for writing.\n", dl->filePath); entry->state = DLQ_STATE_DONE; //CL_RemoveHTTPDownload (entry->quakePath); return; } } dl->tempBuffer = NULL; dl->speed = 0; dl->fileSize = 0; dl->position = 0; dl->queueEntry = entry; if (!dl->curl) dl->curl = curl_easy_init (); Com_sprintf (dl->URL, sizeof(dl->URL), "%s%s", cls.downloadServer, escapedFilePath); curl_easy_setopt (dl->curl, CURLOPT_ENCODING, ""); //curl_easy_setopt (dl->curl, CURLOPT_DEBUGFUNCTION, CL_CURL_Debug); //curl_easy_setopt (dl->curl, CURLOPT_VERBOSE, 1); curl_easy_setopt (dl->curl, CURLOPT_NOPROGRESS, 0); if (dl->file) { curl_easy_setopt (dl->curl, CURLOPT_WRITEDATA, dl->file); curl_easy_setopt (dl->curl, CURLOPT_WRITEFUNCTION, NULL); } else { curl_easy_setopt (dl->curl, CURLOPT_WRITEDATA, dl); curl_easy_setopt (dl->curl, CURLOPT_WRITEFUNCTION, CL_HTTP_Recv); } curl_easy_setopt (dl->curl, CURLOPT_PROXY, cl_http_proxy->string); curl_easy_setopt (dl->curl, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt (dl->curl, CURLOPT_MAXREDIRS, 5); curl_easy_setopt (dl->curl, CURLOPT_WRITEHEADER, dl); curl_easy_setopt (dl->curl, CURLOPT_HEADERFUNCTION, CL_HTTP_Header); curl_easy_setopt (dl->curl, CURLOPT_PROGRESSFUNCTION, CL_HTTP_Progress); curl_easy_setopt (dl->curl, CURLOPT_PROGRESSDATA, dl); curl_easy_setopt (dl->curl, CURLOPT_USERAGENT, Cvar_VariableString ("version")); curl_easy_setopt (dl->curl, CURLOPT_REFERER, cls.downloadReferer); curl_easy_setopt (dl->curl, CURLOPT_URL, dl->URL); if (curl_multi_add_handle (multi, dl->curl) != CURLM_OK) { Com_Printf ("curl_multi_add_handle: error\n"); dl->queueEntry->state = DLQ_STATE_DONE; return; } handleCount++; //Com_Printf ("started dl: hc = %d\n", LOG_GENERAL, handleCount); Com_DPrintf ("CL_StartHTTPDownload: Fetching %s...\n", dl->URL); dl->queueEntry->state = DLQ_STATE_RUNNING; }
/** * @brief Actually starts a download by adding it to the curl multi handle. */ static void CL_StartHTTPDownload (dlqueue_t *entry, dlhandle_t *dl) { char tempFile[MAX_OSPATH]; char escapedFilePath[MAX_QPATH * 4]; const char *extension = Com_GetExtension(entry->ufoPath); /* yet another hack to accomodate filelists, how i wish i could push :( * NULL file handle indicates filelist. */ if (extension != NULL && Q_streq(extension, "filelist")) { dl->file = NULL; CL_EscapeHTTPPath(entry->ufoPath, escapedFilePath); } else { /** @todo use the FS_OpenFile function here */ Com_sprintf(dl->filePath, sizeof(dl->filePath), "%s/%s", FS_Gamedir(), entry->ufoPath); Com_sprintf(tempFile, sizeof(tempFile), BASEDIRNAME"/%s", entry->ufoPath); CL_EscapeHTTPPath(tempFile, escapedFilePath); strcat(dl->filePath, ".tmp"); FS_CreatePath(dl->filePath); /* don't bother with http resume... too annoying if server doesn't support it. */ dl->file = fopen(dl->filePath, "wb"); if (!dl->file) { Com_Printf("CL_StartHTTPDownload: Couldn't open %s for writing.\n", dl->filePath); entry->state = DLQ_STATE_DONE; /* CL_RemoveHTTPDownload(entry->ufoPath); */ return; } } dl->tempBuffer = NULL; dl->speed = 0; dl->fileSize = 0; dl->position = 0; dl->queueEntry = entry; if (!dl->curl) dl->curl = curl_easy_init(); Com_sprintf(dl->URL, sizeof(dl->URL), "%s%s", cls.downloadServer, escapedFilePath); curl_easy_setopt(dl->curl, CURLOPT_ENCODING, ""); #ifdef PARANOID curl_easy_setopt(dl->curl, CURLOPT_VERBOSE, 1); #endif curl_easy_setopt(dl->curl, CURLOPT_NOPROGRESS, 0); if (dl->file) { curl_easy_setopt(dl->curl, CURLOPT_WRITEDATA, dl->file); curl_easy_setopt(dl->curl, CURLOPT_WRITEFUNCTION, NULL); } else { curl_easy_setopt(dl->curl, CURLOPT_WRITEDATA, dl); curl_easy_setopt(dl->curl, CURLOPT_WRITEFUNCTION, HTTP_Recv); } curl_easy_setopt(dl->curl, CURLOPT_CONNECTTIMEOUT, http_timeout->integer); curl_easy_setopt(dl->curl, CURLOPT_TIMEOUT, http_timeout->integer); curl_easy_setopt(dl->curl, CURLOPT_FAILONERROR, 1); curl_easy_setopt(dl->curl, CURLOPT_PROXY, http_proxy->string); curl_easy_setopt(dl->curl, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(dl->curl, CURLOPT_MAXREDIRS, 5); curl_easy_setopt(dl->curl, CURLOPT_WRITEHEADER, dl); curl_easy_setopt(dl->curl, CURLOPT_HEADERFUNCTION, HTTP_Header); curl_easy_setopt(dl->curl, CURLOPT_PROGRESSFUNCTION, CL_HTTP_Progress); curl_easy_setopt(dl->curl, CURLOPT_PROGRESSDATA, dl); curl_easy_setopt(dl->curl, CURLOPT_USERAGENT, GAME_TITLE " " UFO_VERSION); curl_easy_setopt(dl->curl, CURLOPT_REFERER, cls.downloadReferer); curl_easy_setopt(dl->curl, CURLOPT_URL, dl->URL); curl_easy_setopt(dl->curl, CURLOPT_NOSIGNAL, 1); if (curl_multi_add_handle(multi, dl->curl) != CURLM_OK) { Com_Printf("curl_multi_add_handle: error\n"); dl->queueEntry->state = DLQ_STATE_DONE; return; } handleCount++; /*Com_Printf("started dl: hc = %d\n", handleCount); */ Com_Printf("CL_StartHTTPDownload: Fetching %s...\n", dl->URL); dl->queueEntry->state = DLQ_STATE_RUNNING; }