Ejemplo n.º 1
0
// Some versions of CURL don't report the correct exepected size when following redirects
// This manual interpretation of the expected size fixes this.
static size_t wswcurl_readheader( void *ptr, size_t size, size_t nmemb, void *stream ) {
	char buf[1024], *str;
	int slen;
	wswcurl_req *req = (wswcurl_req*)stream;

	memset( buf, 0, sizeof( buf ) );
	memcpy( buf, ptr, ( size * nmemb ) > ( sizeof( buf ) - 1 ) ? ( sizeof( buf ) - 1 ) : ( size * nmemb ) );
	str = buf;
	while( *str ) {
		if( ( *str >= 'a' ) && ( *str <= 'z' ) ) {
			*str -= 'a' - 'A';
		}
		str++;
	}

	if( ( str = (char*)strstr( buf, "CONTENT-LENGTH:" ) ) ) {
		int length;

		while( *str && ( *str != ':' ) ) {
			str++;
		}
		str++;

		while( *str && ( *str == ' ' ) ) {
			str++;
		}
		slen = strlen( str ) - 1;

		while( ( slen > 0 ) && ( ( str[slen] == '\n' ) || ( str[slen] == '\r' ) || ( str[slen] == ' ' ) ) ) {
			str[slen] = '\0';
			slen = strlen( str ) - 1;
		}

		length = atoi( str );
		if( length >= 0 ) {
			req->rx_expsize = length;
		}
	} else if( ( str  = (char*)strstr( buf, "TRANSFER-ENCODING:" ) ) ) {
		req->rx_expsize = 0;
	}

	qcurl_easy_getinfo( req->curl, CURLINFO_RESPONSE_CODE, &( req->respcode ) );

	// call header callback function
	if( req->callback_header ) {
		req->callback_header( req, buf, req->customp );
	}

	req->last_action = wswcurl_now();
	return size * nmemb;
}
Ejemplo n.º 2
0
static size_t wswcurl_write(void *ptr, size_t size, size_t nmemb, void *stream)
{
	float progress;
	long numb;
	wswcurl_req *req = (wswcurl_req*)stream;

	if( !req->headers_done ) {
		req->headers_done = 1;
	}

	numb = size * nmemb;
	req->rxreceived += numb;
	req->last_action = wswcurl_now();

	progress = !req->rx_expsize ? 0.0 : (float)(((double)req->rxreceived / (double)req->rx_expsize) * 100.0);
	clamp( progress, 0, 100 );

	if( req->callback_read )
	{
		return req->callback_read( req, ptr, numb, progress, req->customp );
	}
	else
	{
		chained_buffer_t *cb;

		// Allocate new buffer
		cb = ( chained_buffer_t* )WMALLOC( sizeof(*cb) + numb );
		memset( cb, 0, sizeof(*cb) );

		// Stick the buffer to the end of the chain
		if( req->btail )
			req->btail->next = cb;
		req->btail = cb;
		if( !req->bhead )
			req->bhead = cb;

		memcpy( cb->data, ptr, numb );
		cb->data[numb] = '\0';
		cb->rxsize = numb;
	}

	return numb;
}
Ejemplo n.º 3
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;
}