2013年2月9日土曜日

[cUrl]cUrl ライブラリを使う

cUrl ライブラリを使用して HTTP Get をする
Example 1. first.c
#include <stdio.h>
#include <curl/curl.h>
#include <curl/easy.h>

typedef struct stRecvBuff {
    char buff[1024*1024];
    size_t pos;
    size_t size;
} RecvBuff;

size_t wirte_data(void *buffer, size_t size, size_t nmemb, void *userp)
{
    RecvBuff *buff;
    size_t recvLen;
    buff = (RecvBuff*)userp;

    printf("%s(%p, %d, %d, %p) called\n", __FUNCTION__, buffer, size, nmemb, userp);
    recvLen = size * nmemb;
    if ((buff->pos + recvLen) > buff->size) {
        printf("buffer overflow\n");
        return 0;
    }

    memcpy(&buff->buff[buff->pos], buffer, recvLen);
    buff->pos += recvLen;

    return recvLen;
}

int main(void)
{
    int i;
    CURL *handle;
    RecvBuff buff;
    CURLcode code;

    memset(buff.buff, 0, sizeof(buff.buff));
    buff.pos = 0;
    buff.size = sizeof(buff.buff);

    handle = curl_easy_init();

    /* 接続する URL を指定する */
    curl_easy_setopt(handle, CURLOPT_URL, "http://www.google.co.jp");

    /* 通信状況が分かるように詳細レポートを表示する */
    curl_easy_setopt(handle, CURLOPT_VERBOSE, 1);

    /* データ読み込み (バッファへの書き込み) 時にコールされる関数を設定 */
    curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, wirte_data);

    /* WRITEFUNCTION に渡す引数を設定 */
    curl_easy_setopt(handle, CURLOPT_WRITEDATA, &buff);

    /* 実行 */
    code = curl_easy_perform(handle);

    /* 結果表示 */
    printf("return code: %d\n", code);
    printf("buff.size=%d, pos=%d\n", buff.size, buff.pos);
    if (code == CURLE_OK) {
        printf("Receive data ------------------\n");
        for (i = 0; i < buff.pos; i++) {
            printf("%c", buff.buff[i]);
        }
        printf("\n---------------------\n");
    }

    return 0;
}
Example 2. Makefile
CC = gcc
# libcurl を Static library として使用するため CURL_STATICLIB フラグを付けてコンパイル
CFLAGS = -Wall -DCURL_STATICLIB
LDFLAGS = -lcurl -lwldap32 -lws2_32
TARGET = \
    first.exe

.SUFFIXES: .exe .c .o

.c.o:
    $(CC) $(CFLAGS) -c -o $@ $<
.o.exe:
    $(CC) -o $@ $< $(LDFLAGS)

default: $(TARGET)

clean:
    rm -rf *.o *.exe
実行結果
> first.exe
* About to connect() to proxy xx.xxxxx.xxx port 8080 (#0)
*   Trying xxx.xxx.xxx.xxx... * connected
* Connected to xxx.xxxx.xxx (xxx.xxx.xxx.xxx) port 8080 (#0)
> GET http://www.google.co.jp HTTP/1.1
Host: www.google.co.jp
Accept: */*
Proxy-Connection: Keep-Alive

* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Date: Tue, 06 Oct 2009 04:30:18 GMT
< Expires: -1
< Content-Type: text/html; charset=Shift_JIS
< Set-Cookie: PREF=ID=478ce5631e7dc9f7:TM=1254803418:LM=1254803418:S=QvEebzX1_N7
9UdgH; expires=Thu, 06-Oct-2011 04:30:18 GMT; path=/; domain=.google.co.jp
< Set-Cookie: NID=27=AmMQ61w5bbi_ehIiYmVmOLKJjRLU1kQeTGu3-Axq3w2mcJP0tRFCUITz7up
wHT6QsqXtvTnr_9_yaNxlZY2HgFk4bHGzz63vnPhHTKJxzpvh5pjvcgcrLBVCvm2aJB0G; expires=W
ed, 07-Apr-2010 04:30:18 GMT; path=/; domain=.google.co.jp; HttpOnly
< Server: gws
< X-XSS-Protection: 0
< X-Cache: MISS from g4.konicaminolta.jp
< Proxy-Connection: close
<
wirte_data(00034116, 1, 866, 0013FF50) called
wirte_data(00033EC4, 1, 1460, 0013FF50) called
wirte_data(00033EC4, 1, 1364, 0013FF50) called
wirte_data(00033EC4, 1, 1460, 0013FF50) called
wirte_data(00033EC4, 1, 1460, 0013FF50) called
wirte_data(00033EC4, 1, 1334, 0013FF50) called
wirte_data(00033EC4, 1, 1460, 0013FF50) called
wirte_data(00033EC4, 1, 2079, 0013FF50) called
* Closing connection #0
return code: 0
buff.size=1048576, pos=11483
Receive data ------------------
<html><head><meta http-equiv="content-type" content="text/html; charset=Shift_JIS"><title>Google</title>
(中略)
,a);google.timers.load.t.prt=(new Date).getTime();})();
</script>
---------------------

0 件のコメント:

コメントを投稿