Exemple #1
0
/*
===============
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;
}
Exemple #2
0
/**
 * @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;
}