Libevent HTTP client

Source: Internet
Author: User

When I implement an HTTP client and use libevent, the connection can be established due to some problems, but no response is returned after an HTTP request is sent. Both Windows and Linux versions have been tested. It may be a problem with my use.

According to the online example, you can run it in windows. No problem. The Code is as follows:

#include <stdlib.h>#include <string.h>#include "event2/event.h"#include "event2/http.h"#include "event2/buffer.h"#include "event2/http_struct.h"#include "event2/dns.h"struct download_context{    struct evhttp_uri * uri;    struct event_base * base;    struct evdns_base * dnsbase;    struct evhttp_connection * conn;    struct evhttp_request *req;    struct evbuffer *buffer;    int ok;};static void download_callback(struct evhttp_request *req, void *arg);static int download_renew_request(struct download_context *ctx);static void download_callback(struct evhttp_request *req, void *arg){    struct download_context * ctx = (struct download_context*)arg;    struct evhttp_uri * new_uri = 0;    const char * new_location = 0;    if(!req){        printf("timeout\n");        return;    }    switch(req->response_code)    {    case HTTP_OK:        event_base_loopexit(ctx->base, 0);        break;    case HTTP_MOVEPERM:    case HTTP_MOVETEMP:        new_location = evhttp_find_header(req->input_headers, "Location");        if(!new_location) return;        new_uri = evhttp_uri_parse(new_location);        if(!new_uri)return;        evhttp_uri_free(ctx->uri);        ctx->uri = new_uri;        download_renew_request(ctx);        return;    default:/* failed */        event_base_loopexit(ctx->base, 0);        return;    }    evbuffer_add_buffer(ctx->buffer, req->input_buffer);    ctx->ok = 1;}struct download_context * context_new(const char *url){    struct download_context * ctx = 0;    ctx = (struct download_context*)calloc(1, sizeof(struct download_context));    ctx->uri = evhttp_uri_parse(url);    if(!ctx->uri) return 0;    ctx->base = event_base_new();    ctx->buffer = evbuffer_new();    ctx->dnsbase = evdns_base_new(ctx->base, 1);    download_renew_request(ctx);    return ctx;}void context_free(struct download_context *ctx){    if(ctx->conn)        evhttp_connection_free(ctx->conn);    if(ctx->buffer)        evbuffer_free(ctx->buffer);    if(ctx->uri)        evhttp_uri_free(ctx->uri);    free(ctx);}static int download_renew_request(struct download_context *ctx){    int port = evhttp_uri_get_port(ctx->uri);    if(port == -1) port = 80;    if(ctx->conn) evhttp_connection_free(ctx->conn);    printf("host:%s, port:%d, path:%s\n", evhttp_uri_get_host(ctx->uri), port, evhttp_uri_get_path(ctx->uri));    ctx->conn = evhttp_connection_base_new(ctx->base, ctx->dnsbase, evhttp_uri_get_host(ctx->uri),  port );    ctx->req = evhttp_request_new(download_callback, ctx);    evhttp_make_request(ctx->conn, ctx->req, EVHTTP_REQ_GET, evhttp_uri_get_path(ctx->uri));    evhttp_add_header(ctx->req->output_headers, "Host", evhttp_uri_get_host(ctx->uri));    return 0;}struct evbuffer *download_url(const char *url){    struct download_context * ctx = context_new(url);    if(!ctx) return 0;    event_base_dispatch(ctx->base);    struct evbuffer * retval = 0;    if(ctx->ok)    {        retval = ctx->buffer;        ctx->buffer = 0;    }    context_free(ctx);    return retval;}int main(int argc, char **argv){    struct evbuffer * data = 0;    if(argc < 2){        printf("usage: %s example.com/\n", argv[0]);        return 1;    }#ifdef WIN32WORD wVersionRequested;WSADATA wsaData;wVersionRequested = MAKEWORD(2, 2);(void) WSAStartup(wVersionRequested, &wsaData);#endif    data = download_url(argv[1]);    printf("got %d bytes\n", data ? evbuffer_get_length(data) : -1);    if(data)    {        const unsigned char * joined = evbuffer_pullup(data, -1);        printf("data itself:\n====================\n");        fwrite(joined, evbuffer_get_length(data), 1, stderr);        printf("\n====================\n");        evbuffer_free(data);    }    return 0;}

Note that if you input a URL from the command line, for example, Baidu, you must input http://www.baidu.com/. if you do not use the signature, the download will fail.

This example is not the final result I want, and cannot control the download and data processing process. It is a one-time response after the download is completed. For large files, such as a few hundred megabytes or even GB, this processing policy is not enough. I wrote an HTTP processing module and some auxiliary Code. The Code is compiled and can be run. However, after the request is sent, the client never responds. After I check it out, the libevent HTTP client is still not found on the Internet. For example, there are echoserver and so on, that is, there is no client.

Research may be due to problems with the use of events.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.