Ejemplo n.º 1
0
void wswcurl_start(wswcurl_req *req)
{
    CURLcode res;
    if (!req) return;
    if (req->status) return; // was already started
    if (!req) return;
    if (!req->curl) {
        wswcurl_delete(req);
        return;
    }

    if (req->txhead) {
        CURLSETOPT(req->curl, res, CURLOPT_HTTPHEADER, req->txhead);
    }
    if (req->post) {
        CURLSETOPT(req->curl, res, CURLOPT_HTTPPOST, req->post);
        req->post_last = NULL;
    }
    // Initialize multi handle if needed
    if (curlmulti == NULL) {
        curlmulti = curl_multi_init();
        if (curlmulti == NULL) {
            CURLDBG(("OOPS: CURL MULTI NULL!!!"));
        }
    }
    if (curl_multi_add_handle(curlmulti, req->curl)) {
        CURLDBG(("OOPS: CURL MULTI ADD HANDLE FAIL!!!"));
    }
    req->status = 1; // Started
}
Ejemplo n.º 2
0
int wswcurl_perform()
{
    int ret = 0;
    wswcurl_req *r;
    if (!curlmulti) return 0;
    r = http_requests;
    while (r) {
        r->activity = 0;
        r = r->next;
    }
    //CURLDBG(("CURL BEFORE MULTI_PERFORM\n"));
    while ( curl_multi_perform(curlmulti, &ret) == CURLM_CALL_MULTI_PERFORM) {
        CURLDBG(("   CURL MULTI LOOP\n"));
    }
    ret += wswcurl_checkmsg();
    //CURLDBG(("CURL after checkmsg\n"));
    return ret;
}
Ejemplo n.º 3
0
size_t wswcurl_getsize( wswcurl_req *req, size_t *rxreceived )
{
#if 0
	while( !req->headers_done && req->status >= 0 && req->status != WSTATUS_FINISHED/* && req->status != WSTATUS_QUEUED*/ ) {
		// blocking read until we finish reading all headers
		CURLDBG(("   CURL BLOCKING GETSIZE LOOP\n"));
		wswcurl_perform_single( req );
	}
#endif

	if( rxreceived ) {
		*rxreceived = req->rxreceived;
	}
	if( req->status < 0 ) {
		return 0;
	}

	return req->rx_expsize;
}
Ejemplo n.º 4
0
wswcurl_req *wswcurl_create( const char *furl, ... )
{
	wswcurl_req *retreq;
	CURL *curl;
	CURLcode res;
	char url[4 * 1024]; // 4kb url buffer?
	va_list arg;
	const char *proxy = http_proxy->string;
	const char *proxy_userpwd = http_proxyuserpwd->string;

	// Prepare url formatting with variable arguments
	va_start( arg, furl );
	Q_vsnprintfz( url, sizeof( url ), furl, arg );
	va_end( arg );

	// Initialize structure
	if( !(curl = curl_easy_init()) ) {
		return NULL;
	}

	// allocate, copy
	retreq = ( wswcurl_req * )WMALLOC( sizeof( wswcurl_req ) );
	memset( retreq, 0, sizeof( *retreq ) );

	retreq->curl = curl;
	retreq->url = ( char* )WMALLOC( strlen( url ) + 1 );
	memcpy( retreq->url, url, strlen( url ) + 1 );

	CURLSETOPT( curl, res, CURLOPT_URL, retreq->url );
	CURLSETOPT( curl, res, CURLOPT_WRITEFUNCTION, wswcurl_write );
	CURLSETOPT( curl, res, CURLOPT_NOPROGRESS, 1 );
	CURLSETOPT( curl, res, CURLOPT_FOLLOWLOCATION, 1 );
	CURLSETOPT( curl, res, CURLOPT_HEADERFUNCTION, wswcurl_readheader );
	CURLSETOPT( curl, res, CURLOPT_CONNECTTIMEOUT, WCONNECTTIMEOUT );
#if defined( APPLICATION ) && defined( APP_VERSION_STR ) && defined( OSNAME ) && defined( CPUSTRING )
	CURLSETOPT( curl, res, CURLOPT_USERAGENT, APPLICATION"/"APP_VERSION_STR" (compatible; N; "OSNAME"; "CPUSTRING")" );
#endif
	CURLSETOPT( curl, res, CURLOPT_WRITEDATA, ( void * )retreq );
	CURLSETOPT( curl, res, CURLOPT_WRITEHEADER, ( void * )retreq );
	CURLSETOPT( curl, res, CURLOPT_PRIVATE, ( void * )retreq );

	if( developer->integer ) {
		CURLSETOPT( curl, res, CURLOPT_DEBUGFUNCTION, &wswcurl_debug_callback );
		CURLSETOPT( curl, res, CURLOPT_DEBUGDATA, ( void * )retreq );
		CURLSETOPT( curl, res, CURLOPT_VERBOSE, 1 );
	}

	// HTTP proxy settings
	if( proxy && *proxy ) {
		CURLSETOPT( curl, res, CURLOPT_PROXYTYPE, CURLPROXY_HTTP );

		CURLSETOPT( curl, res, CURLOPT_PROXY, proxy );
		if( proxy_userpwd && *proxy_userpwd ) {
			CURLSETOPT( curl, res, CURLOPT_PROXYUSERPWD, proxy_userpwd );
		}
	}

	wswcurl_set_timeout( retreq, WTIMEOUT );

	// link
	retreq->prev = NULL;
	retreq->next = http_requests;
	if( retreq->next ) {
		retreq->next->prev = retreq;
	}
	else {
		http_requests_hnode = retreq;
	}
	http_requests = retreq;

	CURLDBG((va("   CURL CREATE %s\n", url)));

	return retreq;
}
Ejemplo n.º 5
0
int wswcurl_perform()
{
	int ret = 0;
	wswcurl_req *r, *next;

	if (!curlmulti) return 0;

	// process requests in FIFO manner

	// 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 (curl_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;
	}

	//CURLDBG(("CURL BEFORE MULTI_PERFORM\n"));
	while ( curl_multi_perform(curlmulti, &ret) == CURLM_CALL_MULTI_PERFORM) {
		CURLDBG(("   CURL MULTI LOOP\n"));
	}
	ret += wswcurl_checkmsg();
	//CURLDBG(("CURL after checkmsg\n"));
	return ret;
}
Ejemplo n.º 6
0
size_t wswcurl_read(wswcurl_req *req, void *buffer, size_t size)
{
	size_t written = 0;
	chained_buffer_t *cb;

	if( (req->rxreceived-req->rxreturned) < (size+WMINBUFFERING) && req->paused )
		wswcurl_unpause(req);

#if 0
	// Make sure we have data in buffer
	while ( req->status >= 0 && req->status != WSTATUS_FINISHED && req->status != WSTATUS_QUEUED && (req->rxreceived-req->rxreturned) < size ) {
		CURLDBG(("   CURL BLOCKING READ LOOP\n"));
		wswcurl_perform_single (req);
	}
#endif

	// hmm, signal an error?
	if( req->status < 0 )
		return 0;

	// go through the buffers in chain, dropping them if not needed
	// start from the beginning (chronological order)
	cb = req->bhead;
	while( cb && written < size )
	{
		size_t numb = cb->rxsize - cb->rxoffset;
		if( numb + written > size )
			numb = size - written;
		if( !numb )
			break;

		if( req->ignore_bytes >= numb ) {
			req->ignore_bytes -= numb;
			cb->rxoffset += numb;
			continue;
		}
		else {
			cb->rxoffset += req->ignore_bytes;
			req->ignore_bytes = 0;
		}
		
		memcpy( ((char*)buffer)+written, cb->data+cb->rxoffset, numb );
		written += numb;
		cb->rxoffset += numb;

		if( cb->rxoffset >= cb->rxsize )
		{
			// flush the buffer away
			req->bhead = cb->next;
			if( req->btail == cb )
				req->btail = NULL;
			WFREE( cb );
			// advance to the next buffer in chain
			cb = req->bhead;
		}
		// else break;
	}

	if( written < size )
		((char*)buffer)[written] = '\0';

	req->rxreturned += written;

#if 0
	if( req->paused)
		Com_Printf(S_COLOR_RED "%d - ", req->rxreturned - req->rxreceived);
	else
		Com_Printf(S_COLOR_CYAN "%d - ", req->rxreturned - req->rxreceived);
#endif

	return written;
}