libevent as client

         Libevent is usually used as a server, but there are scenarios where it will be used as a client to fetch other services. Usually, libcurl can be used to fetch, but the entire thread will be in a waiting state. In this case, the libevent client mode can be used to make the request completely asynchronous. .

 

    

#ifndef _EVENT_CURL_H_
#define _EVENT_CURL_H_

#include <string>

using namespace std;

typedef void (*RequestFinishHandler)(struct evhttp_request *req, void *arg);

struct event_base;

class EventHttpReq
{
public:
    EventHttpReq()
    {
        m_time_out = 300;
        finish_handler = NULL;
        finish_arg = NULL;
    }

    string m_url;
    string m_post_data;
    int m_time_out;
    RequestFinishHandler finish_handler;
    void *finish_arg;
};

class EventCurl
{
public:
   static bool curl(EventHttpReq &eventHttpReq, struct event_base *, struct evhttp_connection *& conn);
};



#endif

 

 

 

#include <signal.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include "EventCurl.h"
#include "event2/util.h"
#include "event2/http.h"
#include "event2/http_struct.h"
#include "event2/buffer.h"


bool EventCurl::curl(EventHttpReq &eventHttpReq, struct event_base *base, struct evhttp_connection *& conn)
{
    struct evhttp_request *req;

    const char *scheme, *host, *path, *query;
    struct evhttp_uri *http_uri = evhttp_uri_parse(eventHttpReq.m_url.c_str());
    if (NULL == http_uri)
    {
        return false;
    }
    string uri;
    int port;
    scheme = evhttp_uri_get_scheme(http_uri);
    if (scheme == NULL || (strcasecmp(scheme, "https") != 0 &&
                              strcasecmp(scheme, "http") != 0))
    {
        evhttp_uri_free(http_uri);
        return false;
    }

    host = evhttp_uri_get_host(http_uri);
    if (NULL == host)
    {
        evhttp_uri_free(http_uri);
        return false;
    }

    port = evhttp_uri_get_port(http_uri);
    if (port == -1)
    {
        port = (strcasecmp(scheme, "http") == 0) ? 80 : 443;
    }

    path = evhttp_uri_get_path(http_uri);
    if (path == NULL || strlen(path) == 0)
    {
        uri = "/";
    }
    else
    {
        uri = path;  
    }

    query = evhttp_uri_get_query(http_uri);
    if (query != NULL)
    {
        uri += "?";
        uri += query;
    }

    conn = evhttp_connection_base_new(base, NULL, host, port);
    if (NULL == conn)
    {
        evhttp_uri_free(http_uri);
        return false;
    }
    req = evhttp_request_new(eventHttpReq.finish_handler, eventHttpReq.finish_arg);
    if (NULL == req)
    {
        evhttp_connection_free(conn);
        evhttp_uri_free(http_uri);
        conn = NULL;
        return false;
    }
    evhttp_add_header(req->output_headers, "Host", host);
    int make_request_ret = 0;
    if (eventHttpReq.m_post_data.size() > 0) //post request, add the content of post
    {
        evbuffer_add(req->output_buffer, eventHttpReq.m_post_data.c_str(), eventHttpReq.m_post_data.size());
        make_request_ret = evhttp_make_request(conn, req, EVHTTP_REQ_POST, uri.c_str());
    }   
    else //get request
    {
        make_request_ret = evhttp_make_request(conn, req, EVHTTP_REQ_GET, uri.c_str());
    }

    if (make_request_ret != 0)
    {
        evhttp_connection_free(conn);
        evhttp_request_free(req);
        evhttp_uri_free(http_uri);
        conn = NULL;
        return false;
    }
    evhttp_connection_set_timeout(req->evcon, eventHttpReq.m_time_out);
    evhttp_uri_free(http_uri);

    return true;
}

 

 

 

    Receive the return result, or handle exceptions.

void  finish_handler(struct evhttp_request *req, void *arg)
{
   EParser *parser = (EParser *)arg;
   
   parser->m_curl_time = parser->m_timer.ElapseTime();

   int http_code = 0;
   if (req != NULL)
   {
       http_code = evhttp_request_get_response_code(req);    //http码
       parser->m_http_code = http_code;
       if (http_code == HTTP_OK)
       {
           int s = evbuffer_remove(req->input_buffer, &parser->curl_result, E_MAX_SIZE_BUF);
           struct evkeyvalq* headers = evhttp_request_get_input_headers(req);  //http头部
           for (evkeyval* header = headers->tqh_first; header != NULL; header = header->next.tqe_next)
           {
               parser->m_receive_header.insert(std::pair<string, string>(header->key, header->value));
           }
       }
   }

   parser->m_is_finish = true;
   ProcessRequestSend(EParser);
}

 

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326551715&siteId=291194637