-
-
Notifications
You must be signed in to change notification settings - Fork 6.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
178 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
/***************************************************************************** | ||
* _ _ ____ _ | ||
* Project ___| | | | _ \| | | ||
* / __| | | | |_) | | | ||
* | (__| |_| | _ <| |___ | ||
* \___|\___/|_| \_\_____| | ||
* | ||
* $Id$ | ||
* | ||
* This is a very simple example using the multi interface and the debug | ||
* callback. | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <string.h> | ||
|
||
/* somewhat unix-specific */ | ||
#include <sys/time.h> | ||
#include <unistd.h> | ||
|
||
/* curl stuff */ | ||
#include <curl/curl.h> | ||
|
||
typedef char bool; | ||
#define TRUE 1 | ||
|
||
static | ||
void dump(const char *text, | ||
FILE *stream, unsigned char *ptr, size_t size, | ||
bool nohex) | ||
{ | ||
size_t i; | ||
size_t c; | ||
|
||
unsigned int width=0x10; | ||
|
||
if(nohex) | ||
/* without the hex output, we can fit more on screen */ | ||
width = 0x40; | ||
|
||
fprintf(stream, "%s, %zd bytes (0x%zx)\n", text, size, size); | ||
|
||
for(i=0; i<size; i+= width) { | ||
|
||
fprintf(stream, "%04zx: ", i); | ||
|
||
if(!nohex) { | ||
/* hex not disabled, show it */ | ||
for(c = 0; c < width; c++) | ||
if(i+c < size) | ||
fprintf(stream, "%02x ", ptr[i+c]); | ||
else | ||
fputs(" ", stream); | ||
} | ||
|
||
for(c = 0; (c < width) && (i+c < size); c++) { | ||
/* check for 0D0A; if found, skip past and start a new line of output */ | ||
if (nohex && (i+c+1 < size) && ptr[i+c]==0x0D && ptr[i+c+1]==0x0A) { | ||
i+=(c+2-width); | ||
break; | ||
} | ||
fprintf(stream, "%c", | ||
(ptr[i+c]>=0x20) && (ptr[i+c]<0x80)?ptr[i+c]:'.'); | ||
/* check again for 0D0A, to avoid an extra \n if it's at width */ | ||
if (nohex && (i+c+2 < size) && ptr[i+c+1]==0x0D && ptr[i+c+2]==0x0A) { | ||
i+=(c+3-width); | ||
break; | ||
} | ||
} | ||
fputc('\n', stream); /* newline */ | ||
} | ||
fflush(stream); | ||
} | ||
|
||
static | ||
int my_trace(CURL *handle, curl_infotype type, | ||
unsigned char *data, size_t size, | ||
void *userp) | ||
{ | ||
const char *text; | ||
|
||
(void)handle; /* prevent compiler warning */ | ||
|
||
switch (type) { | ||
case CURLINFO_TEXT: | ||
fprintf(stderr, "== Info: %s", data); | ||
default: /* in case a new one is introduced to shock us */ | ||
return 0; | ||
|
||
case CURLINFO_HEADER_OUT: | ||
text = "=> Send header"; | ||
break; | ||
case CURLINFO_DATA_OUT: | ||
text = "=> Send data"; | ||
break; | ||
case CURLINFO_HEADER_IN: | ||
text = "<= Recv header"; | ||
break; | ||
case CURLINFO_DATA_IN: | ||
text = "<= Recv data"; | ||
break; | ||
} | ||
|
||
dump(text, stderr, data, size, TRUE); | ||
return 0; | ||
} | ||
|
||
/* | ||
* Simply download a HTTP file. | ||
*/ | ||
int main(int argc, char **argv) | ||
{ | ||
CURL *http_handle; | ||
CURLM *multi_handle; | ||
|
||
int still_running; /* keep number of running handles */ | ||
|
||
http_handle = curl_easy_init(); | ||
|
||
/* set the options (I left out a few, you'll get the point anyway) */ | ||
curl_easy_setopt(http_handle, CURLOPT_URL, "http://www.haxx.se/"); | ||
|
||
curl_easy_setopt(http_handle, CURLOPT_DEBUGFUNCTION, my_trace); | ||
curl_easy_setopt(http_handle, CURLOPT_VERBOSE, TRUE); | ||
|
||
/* init a multi stack */ | ||
multi_handle = curl_multi_init(); | ||
|
||
/* add the individual transfers */ | ||
curl_multi_add_handle(multi_handle, http_handle); | ||
|
||
/* we start some action by calling perform right away */ | ||
while(CURLM_CALL_MULTI_PERFORM == | ||
curl_multi_perform(multi_handle, &still_running)); | ||
|
||
while(still_running) { | ||
struct timeval timeout; | ||
int rc; /* select() return code */ | ||
|
||
fd_set fdread; | ||
fd_set fdwrite; | ||
fd_set fdexcep; | ||
int maxfd; | ||
|
||
FD_ZERO(&fdread); | ||
FD_ZERO(&fdwrite); | ||
FD_ZERO(&fdexcep); | ||
|
||
/* set a suitable timeout to play around with */ | ||
timeout.tv_sec = 1; | ||
timeout.tv_usec = 0; | ||
|
||
/* get file descriptors from the transfers */ | ||
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); | ||
|
||
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); | ||
|
||
switch(rc) { | ||
case -1: | ||
/* select error */ | ||
still_running = 0; | ||
printf("select() returns error, this is badness\n"); | ||
break; | ||
case 0: | ||
default: | ||
/* timeout or readable/writable sockets */ | ||
while(CURLM_CALL_MULTI_PERFORM == | ||
curl_multi_perform(multi_handle, &still_running)); | ||
break; | ||
} | ||
} | ||
|
||
curl_multi_cleanup(multi_handle); | ||
|
||
curl_easy_cleanup(http_handle); | ||
|
||
return 0; | ||
} |