libcurl+libevent封装httpclient

近期更换了项目使用的http动态库, 对新的http库有以下几点要求:

  • 不关心http请求的响应结果, 只关心请求是否发送成功
  • 对并发有一定的要求, 异步发送
  • 如果请求发送失败, 应当返回失败详细信息
  • 支持GETPOST

最终使用libcurllibevent封装了一个http动态库, 提供给lua层使用
libevent管理各种回调事件, libcurl发送http请求, 相关实现如下
项目github地址

核心接口就两个, start send_request

  • 初始化libcurllibevent
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    static int 
    start(const char * method) {
    pthread_mutex_lock(&mutex);
    int result = curl_global_init(CURL_GLOBAL_ALL);
    pthread_mutex_unlock(&mutex);
    if(result) {
    return 1;
    }

    event_config * config = event_config_new();
    const char ** pstr = event_get_supported_methods();
    for (int i = 0; nullptr != pstr[i]; i++) {
    if (strcmp(method, pstr[i]) != 0) {
    event_config_avoid_method(config, pstr[i]);
    }
    }
    base = event_base_new_with_config(config);
    if (!base)
    return 2;

    event_config_free(config);
    timeout = evtimer_new(base, on_timeout, NULL);

    curl_handle = curl_multi_init();
    curl_multi_setopt(curl_handle, CURLMOPT_SOCKETFUNCTION, handle_socket);
    curl_multi_setopt(curl_handle, CURLMOPT_TIMERFUNCTION, start_timeout);

    return 0;
    }
  • 发送请求
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    static void 
    send_request(const char * url, bool lose_content, curl_httppost * post_form, const char* postdata, size_t postlen) {
    CURL * handle = curl_easy_init();
    webrequest * req = new_request(handle, lose_content);
    curl_easy_setopt(handle, CURLOPT_NOSIGNAL, 1);
    curl_easy_setopt(handle, CURLOPT_TCP_KEEPALIVE, 1);
    curl_easy_setopt(handle, CURLOPT_TCP_KEEPIDLE, 1 * 60);
    curl_easy_setopt(handle, CURLOPT_TCP_KEEPINTVL, 10);
    curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0);
    curl_easy_setopt(handle, CURLOPT_SSL_VERIFYHOST, 0);
    curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1);
    curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_callback);
    curl_easy_setopt(handle, CURLOPT_WRITEDATA, req);
    curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, req->error);
    curl_easy_setopt(handle, CURLOPT_CONNECTTIMEOUT_MS, 10 * 1000);
    curl_easy_setopt(handle, CURLOPT_URL, url);

    if (post_form) {
    curl_easy_setopt(handle, CURLOPT_HTTPPOST, post_form);
    }
    else if (postdata) {
    curl_easy_setopt(handle, CURLOPT_POSTFIELDSIZE, postlen);
    curl_easy_setopt(handle, CURLOPT_COPYPOSTFIELDS, postdata);
    }

    curl_multi_add_handle(curl_handle, handle);
    }