Exemple #1
0
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);
}
Exemple #2
0
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);
}
Exemple #3
0
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 );
}