Beispiel #1
0
void CL_cURL_PerformDownload(void)
{
	CURLMcode res;
	CURLMsg *msg;
	int c;
	int i = 0;

	res = qcurl_multi_perform(clc.downloadCURLM, &c);
	while(res == CURLM_CALL_MULTI_PERFORM && i < 100) {
		res = qcurl_multi_perform(clc.downloadCURLM, &c);
		i++;
	}
	if(res == CURLM_CALL_MULTI_PERFORM)
		return;
	msg = qcurl_multi_info_read(clc.downloadCURLM, &c);
	if(msg == NULL) {
		return;
	}
	FS_FCloseFile(clc.download);
	if(msg->msg == CURLMSG_DONE && msg->data.result == CURLE_OK) {
		FS_SV_Rename(clc.downloadTempName, clc.downloadName, false);
		clc.downloadRestart = true;
	}
	else {
		long code;

		qcurl_easy_getinfo(msg->easy_handle, CURLINFO_RESPONSE_CODE,
			&code);	
		Com_Error(ERR_DROP, "Download Error: %s Code: %ld URL: %s",
			qcurl_easy_strerror(msg->data.result),
			code, clc.downloadURL);
	}

	CL_NextDownload();
}
Beispiel #2
0
void CL_cURL_PerformDownload(void)
{
	CURLMcode res;
	CURLMsg *msg;
	int c;
	int i = 0;

	res = qcurl_multi_perform(clc.downloadCURLM, &c);
	while(res == CURLM_CALL_MULTI_PERFORM && i < 100) {
		res = qcurl_multi_perform(clc.downloadCURLM, &c);
		i++;
	}
	if(res == CURLM_CALL_MULTI_PERFORM)
		return;
	msg = qcurl_multi_info_read(clc.downloadCURLM, &c);
	if(msg == NULL) {
		return;
	}
	FS_FCloseFile(clc.download);
	if(msg->msg == CURLMSG_DONE && msg->data.result == CURLE_OK) {
		FS_SV_Rename(clc.downloadTempName, clc.downloadName);
	}
	else {
		long code;

		qcurl_easy_getinfo(msg->easy_handle, CURLINFO_RESPONSE_CODE,
			&code);	
		Com_Error(ERR_DROP, "Download Error: %s Code: %d",
			qcurl_easy_strerror(msg->data.result),
			code);
	}
	*clc.downloadTempName = *clc.downloadName = 0;
	Cvar_Set( "cl_downloadName", "" );
	CL_cURL_Cleanup();
	FS_Restart(clc.checksumFeed);
	CL_Reconnect_f();
}
Beispiel #3
0
/*
====================
Curl_Run

call this regularily as this will always download as much as possible without
blocking.
====================
*/
void Curl_Run(void)
{
	double maxspeed;
	downloadinfo *di;

	noclear = FALSE;

	if(!cl_curl_enabled.integer)
		return;

	if(!curl_dll)
		return;

	Curl_CheckCommandWhenDone();

	if(!downloads)
		return;

	if(realtime < curltime) // throttle
		return;

	{
		int remaining;
		CURLMcode mc;

		do
		{
			mc = qcurl_multi_perform(curlm, &remaining);
		}
		while(mc == CURLM_CALL_MULTI_PERFORM);

		for(di = downloads; di; di = di->next)
		{
			double b = 0;
			qcurl_easy_getinfo(di->curle, CURLINFO_SIZE_UPLOAD, &b);
			bytes_sent += (b - di->bytes_sent_curl);
			di->bytes_sent_curl = b;
			qcurl_easy_getinfo(di->curle, CURLINFO_SIZE_DOWNLOAD, &b);
			bytes_sent += (b - di->bytes_received_curl);
			di->bytes_received_curl = b;
		}

		for(;;)
		{
			CURLMsg *msg = qcurl_multi_info_read(curlm, &remaining);
			if(!msg)
				break;
			if(msg->msg == CURLMSG_DONE)
			{
				CurlStatus failed = CURL_DOWNLOAD_SUCCESS;
				CURLcode result;
				qcurl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &di);
				result = msg->data.result;
				if(result)
				{
					failed = CURL_DOWNLOAD_FAILED;
				}
				else
				{
					long code;
					qcurl_easy_getinfo(msg->easy_handle, CURLINFO_RESPONSE_CODE, &code);
					switch(code / 100)
					{
						case 4: // e.g. 404?
						case 5: // e.g. 500?
							failed = CURL_DOWNLOAD_SERVERERROR;
							result = (CURLcode) code;
							break;
					}
				}

				Curl_EndDownload(di, failed, result);
			}
		}
	}

	CheckPendingDownloads();

	// when will we curl the next time?
	// we will wait a bit to ensure our download rate is kept.
	// we now know that realtime >= curltime... so set up a new curltime

	// use the slowest allowing download to derive the maxspeed... this CAN
	// be done better, but maybe later
	maxspeed = cl_curl_maxspeed.value;
	for(di = downloads; di; di = di->next)
		if(di->maxspeed > 0)
			if(di->maxspeed < maxspeed || maxspeed <= 0)
				maxspeed = di->maxspeed;

	if(maxspeed > 0)
	{
		double bytes = bytes_sent + bytes_received; // maybe smoothen a bit?
		curltime = realtime + bytes / (cl_curl_maxspeed.value * 1024.0);
		bytes_sent = 0;
		bytes_received = 0;
	}
	else
		curltime = realtime;
}
Beispiel #4
0
int wswcurl_perform() {
	int ret = 0;
	wswcurl_req *r, *next;

	if( !curlmulti ) {
		return 0;
	}

	// process requests in FIFO manner

	QMutex_Lock( http_requests_mutex );

	// check for timed out requests and requests that need to be paused
	r = http_requests_hnode;
	while( r ) {
		next = r->prev;

		if( r->status == WSTATUS_QUEUED ) {
			// queued
			if( curlmulti_num_handles < WMAXMULTIHANDLES ) {
				if( qcurl_multi_add_handle( curlmulti, r->curl ) ) {
					CURLDBG( ( "OOPS: CURL MULTI ADD HANDLE FAIL!!!" ) );
				}
				r->status = WSTATUS_STARTED;
				r->last_action = wswcurl_now();
				curlmulti_num_handles++;
			} else {
				// stay in queue
			}
		}

		// handle pauses for synchronous requests
		if( r->status == WSTATUS_STARTED && !r->callback_read ) {
			if( r->rxreceived >= r->rxreturned + WMAXBUFFERING ) {
				wswcurl_pause( r );
			}
		}

		// handle timeouts
		if( r->status == WSTATUS_STARTED ) {
			time_t now = wswcurl_now();

			if( r->paused ) {
				// paused
				r->last_action = now;
			} else if( r->timeout && ( r->last_action + r->timeout <= now ) ) {
				// timed out
				r->respcode = -1;
				r->status = -CURLE_OPERATION_TIMEDOUT;
				if( r->callback_done ) {
					r->callback_done( r, r->status, r->customp );
				}
			}
		}

		r = next;
	}

	QMutex_Unlock( http_requests_mutex );

	//CURLDBG(("CURL BEFORE MULTI_PERFORM\n"));
	while( qcurl_multi_perform( curlmulti, &ret ) == CURLM_CALL_MULTI_PERFORM ) {
		CURLDBG( ( "   CURL MULTI LOOP\n" ) );
	}
	ret += wswcurl_checkmsg();
	//CURLDBG(("CURL after checkmsg\n"));

	return ret;
}