libevent测试

原创 2015年11月20日 19:04:55
#include <errno.h>
#include <stdlib.h>
#include <string.h>

#include "event2/event.h"
#include "event2/buffer.h"
#include "event2/http.h"
#include "event2/http_struct.h"
#include "event2/keyvalq_struct.h"

// (default)
#define HTTP_CONTENT_TYPE_URL_ENCODED   "application/x-www-form-urlencoded"
// (use for files: picture, mp3, tar-file etc.)
#define HTTP_CONTENT_TYPE_FORM_DATA     "multipart/form-data"
// (use for plain text)
#define HTTP_CONTENT_TYPE_TEXT_PLAIN    "text/plain"

#define REQUEST_POST_FLAG               2
#define REQUEST_GET_FLAG                3

struct http_request_get {
    struct evhttp_uri *uri;
    struct event_base *base;
    struct evhttp_connection *cn;
    struct evhttp_request *req;
};

struct http_request_post {
    struct evhttp_uri *uri;
    struct event_base *base;
    struct evhttp_connection *cn;
    struct evhttp_request *req;
    char *content_type;
    char *post_data;
};

/************************** Ahead Declare ******************************/
void http_requset_post_cb(struct evhttp_request *req, void *arg);
void http_requset_get_cb(struct evhttp_request *req, void *arg);
int start_url_request(struct http_request_get *http_req, int req_get_flag);

/************************** Tools Function ******************************/
static inline void print_request_head_info(struct evkeyvalq *header)
{
    struct evkeyval *first_node = header->tqh_first;
    while (first_node) {
        printf("key:%s  value:%s", first_node->key, first_node->value);
        first_node = first_node->next.tqe_next;
    }
}

static inline void print_uri_parts_info(const struct evhttp_uri * http_uri)
{
    printf("scheme:%s", evhttp_uri_get_scheme(http_uri));
    printf("host:%s", evhttp_uri_get_host(http_uri));
    printf("path:%s", evhttp_uri_get_path(http_uri));
    printf("port:%d", evhttp_uri_get_port(http_uri));
    printf("query:%s", evhttp_uri_get_query(http_uri));
    printf("userinfo:%s", evhttp_uri_get_userinfo(http_uri));
    printf("fragment:%s", evhttp_uri_get_fragment(http_uri));
}

/************************** Request Function ******************************/
void http_requset_post_cb(struct evhttp_request *req, void *arg)
{
    struct http_request_post *http_req_post = (struct http_request_post *)arg;
    switch(req->response_code)
    {
        case HTTP_OK:
        {
            struct evbuffer* buf = evhttp_request_get_input_buffer(req);
            size_t len = evbuffer_get_length(buf);
            printf("print the head info:");
            print_request_head_info(req->output_headers);

            printf("len:%zu  body size:%zu", len, req->body_size);
            char *tmp = malloc(len+1);
            memcpy(tmp, evbuffer_pullup(buf, -1), len);
            tmp[len] = '\0';
            printf("print the body:");
            printf("HTML BODY:%s", tmp);
            free(tmp);

            event_base_loopexit(http_req_post->base, 0);
            break;
        }
        case HTTP_MOVEPERM:
            printf( "%s", "the uri moved permanently");
            break;
        case HTTP_MOVETEMP:
        {
            const char *new_location = evhttp_find_header(req->input_headers, "Location");
            struct evhttp_uri *new_uri = evhttp_uri_parse(new_location);
            evhttp_uri_free(http_req_post->uri);
            http_req_post->uri = new_uri;
            start_url_request((struct http_request_get *)http_req_post, REQUEST_POST_FLAG);
            return;
        }

        default:
            event_base_loopexit(http_req_post->base, 0);
            return;
    }
}
void http_requset_get_cb(struct evhttp_request *req, void *arg)
{
    struct http_request_get *http_req_get = (struct http_request_get *)arg;
    switch(req->response_code)
    {
        case HTTP_OK:
        {
            struct evbuffer* buf = evhttp_request_get_input_buffer(req);
            size_t len = evbuffer_get_length(buf);
            printf("print the head info:");
            print_request_head_info(req->output_headers);

            printf("len:%zu  body size:%zu", len, req->body_size);
            char *tmp = malloc(len+1);
            memcpy(tmp, evbuffer_pullup(buf, -1), len);
            tmp[len] = '\0';
            printf("print the body:");
            printf("HTML BODY:%s", tmp);
            free(tmp);

            event_base_loopexit(http_req_get->base, 0);
            break;
        }
        case HTTP_MOVEPERM:
            printf( "%s", "the uri moved permanently");
            break;
        case HTTP_MOVETEMP:
        {
            const char *new_location = evhttp_find_header(req->input_headers, "Location");
            struct evhttp_uri *new_uri = evhttp_uri_parse(new_location);
            evhttp_uri_free(http_req_get->uri);
            http_req_get->uri = new_uri;
            start_url_request(http_req_get, REQUEST_GET_FLAG);
            return;
        }

        default:
            event_base_loopexit(http_req_get->base, 0);
            return;
    }
}

int start_url_request(struct http_request_get *http_req, int req_get_flag)
{
    if (http_req->cn)
        evhttp_connection_free(http_req->cn);

    int port = evhttp_uri_get_port(http_req->uri);
    http_req->cn = evhttp_connection_base_new(http_req->base,
                                                   NULL,
                                                   evhttp_uri_get_host(http_req->uri),
                                                   (port == -1 ? 80 : port));

    /**
     * Request will be released by evhttp connection
     * See info of evhttp_make_request()
     */
    if (req_get_flag == REQUEST_POST_FLAG) {
        http_req->req = evhttp_request_new(http_requset_post_cb, http_req);
    } else if (req_get_flag ==  REQUEST_GET_FLAG) {
        http_req->req = evhttp_request_new(http_requset_get_cb, http_req);
    }

    if (req_get_flag == REQUEST_POST_FLAG) {
        const char *path = evhttp_uri_get_path(http_req->uri);
        evhttp_make_request(http_req->cn, http_req->req, EVHTTP_REQ_POST,
                            path ? path : "/");
        /** Set the post data */
        struct http_request_post *http_req_post = (struct http_request_post *)http_req;
        evbuffer_add(http_req_post->req->output_buffer, http_req_post->post_data, strlen(http_req_post->post_data));
        evhttp_add_header(http_req_post->req->output_headers, "Content-Type", http_req_post->content_type);
    } else if (req_get_flag == REQUEST_GET_FLAG) {
        const char *query = evhttp_uri_get_query(http_req->uri);
        const char *path = evhttp_uri_get_path(http_req->uri);
        size_t len = (query ? strlen(query) : 0) + (path ? strlen(path) : 0) + 1;
        char *path_query = NULL;
        if (len > 1) {
            path_query = calloc(len, sizeof(char));
            sprintf(path_query, "%s?%s", path, query);
        }
        evhttp_make_request(http_req->cn, http_req->req, EVHTTP_REQ_GET,
                             path_query ? path_query: "/");
    }
    /** Set the header properties */
    evhttp_add_header(http_req->req->output_headers, "Host", evhttp_uri_get_host(http_req->uri));

    return 0;
}

/************************** New/Free Function ******************************/
/**
 * @param get_flag: refer REQUEST_GET_*
 *
 */
void *http_request_new(struct event_base* base, const char *url, int req_get_flag, \
                       const char *content_type, const char* data)
{
    int len = 0;
    if (req_get_flag == REQUEST_GET_FLAG) {
        len = sizeof(struct http_request_get);
    } else if(req_get_flag == REQUEST_POST_FLAG) {
        len = sizeof(struct http_request_post);
    }

    struct http_request_get *http_req_get = calloc(1, len);
    http_req_get->uri = evhttp_uri_parse(url);
    print_uri_parts_info(http_req_get->uri);

    http_req_get->base = base;

    if (req_get_flag == REQUEST_POST_FLAG) {
        struct http_request_post *http_req_post = (struct http_request_post *)http_req_get;
        if (content_type == NULL) {
            content_type = HTTP_CONTENT_TYPE_URL_ENCODED;
        }
        http_req_post->content_type = strdup(content_type);

        if (data == NULL) {
            http_req_post->post_data = NULL;
        } else {
            http_req_post->post_data = strdup(data);
        }
    }

    return http_req_get;
}

void http_request_free(struct http_request_get *http_req_get, int req_get_flag)
{
    evhttp_connection_free(http_req_get->cn);
    evhttp_uri_free(http_req_get->uri);
    if (req_get_flag == REQUEST_GET_FLAG) {
        free(http_req_get);
    } else if(req_get_flag == REQUEST_POST_FLAG) {
        struct http_request_post *http_req_post = (struct http_request_post*)http_req_get;
        if (http_req_post->content_type) {
            free(http_req_post->content_type);
        }
        if (http_req_post->post_data) {
            free(http_req_post->post_data);
        }
        free(http_req_post);
    }
    http_req_get = NULL;
}

/************************** Start POST/GET Function ******************************/
/**
 * @param content_type: refer HTTP_CONTENT_TYPE_*
 */
void *start_http_requset(struct event_base* base, const char *url, int req_get_flag, \
                                                const char *content_type, const char* data)
{
    struct http_request_get *http_req_get = http_request_new(base, url, req_get_flag, content_type, data);
    start_url_request(http_req_get, req_get_flag);

    return http_req_get;
}


int main(int argc, char *argv[])
{
//    MITLogOpen("LibeventHttpClient");
    struct event_base* base = event_base_new();

    struct http_request_post *http_req_post = start_http_requset(base,
                                                                 "http://172.16.239.93:8899/base/truck/delete",
                                                                 REQUEST_POST_FLAG,
                                                                 HTTP_CONTENT_TYPE_URL_ENCODED,
                                                                 "name=winlin&code=1234");
    struct http_request_get *http_req_get = start_http_requset(base,
                                                               "http://127.0.0.1?name=winlin",
                                                               REQUEST_GET_FLAG,
                                                               NULL, NULL);

    event_base_dispatch(base);

    http_request_free((struct http_request_get *)http_req_post, REQUEST_POST_FLAG);
    http_request_free(http_req_get, REQUEST_GET_FLAG);
    event_base_free(base);
//    MITLogClose();

    return 0;
}

Libevent0.1之测试Libevent自带的例子

因为0.1版本的只支持linux版本,所以本文章中的测试环境是在ubuntu下进行。 准备工作 下载0.1版本的libevent。 开始 先解压下载下来的源码 Download$ tar xzvf l...
  • LYH66
  • LYH66
  • 2015年06月02日 14:45
  • 1486

libevent例子--HTTP 服务器

使用内置的 HTTP 服务器 如果希望构建本机应用程序,可以使用一般的基于网络的 libevent 接口;但是,越来越常见的场景是开发基于 HTTP 协议的应用程序,以及装载或动态地重新装载信息...
  • imxiangzi
  • imxiangzi
  • 2016年08月08日 16:26
  • 335

网络库libevent、libev、libuv对比

http://blog.csdn.net/lijinqi1987/article/details/71214974 Libevent、libev、libuv三个网络库,都是c语言实现的异步事...
  • libaineu2004
  • libaineu2004
  • 2017年11月07日 09:54
  • 259

libevent安装编译并测试

由于之前在windows平台下接触过一个网络数据过滤的程序,当时也是第一次写关于网络方面的程序(之前写的小程序不算),明显的经验不足。很多知识都不够用,最后导致这个程序没有完成。但是过程中学到了不少的...
  • baidu_28563321
  • baidu_28563321
  • 2015年10月08日 16:14
  • 517

Libevent使用例子,从简单到复杂

转载请注明出处:http://blog.csdn.net/luotuo44/article/details/39670221         本文从简单到复杂,展示如何使用libev...
  • imxiangzi
  • imxiangzi
  • 2016年08月08日 16:17
  • 371

libevent在windows下使用步骤详解

libevent是一个常用的网络库,下面就看看在windows下面编译测试的过程吧。 一 环境 系统:win8.1 编译器:VS2013 官方下载地址:http://libevent.or...
  • xufeng0991
  • xufeng0991
  • 2015年03月08日 16:46
  • 5552

MinGW编译libevent和使用测试

在MinGW下找到msys.bat右键编辑,在首行添加  call "C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\vcvars32...
  • bojie5744
  • bojie5744
  • 2014年09月30日 18:03
  • 1345

libevent源码深度剖析12(让libevent支持多线程)

转自:http://wangjunle23.blog.163.com/blog/static/11783817120125991010311/ libevent源码深度剖析12(让libeven...
  • qiushanjushi
  • qiushanjushi
  • 2014年04月23日 17:57
  • 5627

libevent网络编程例子(1)

这篇文章介绍下libevent在socket异步编程中的应用。在一些对性能要求较高的网络应用程序中,为了防止程序阻塞在socket I/O操作上造成程序性能的下降,需要使用异步编程,即程序准备好读写的...
  • huangyimo
  • huangyimo
  • 2015年07月08日 17:26
  • 514

下载并安装libevent开发库详细步骤

下载并安装libevent开发库详细步骤
  • Linux_ever
  • Linux_ever
  • 2016年02月12日 15:21
  • 2167
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:libevent测试
举报原因:
原因补充:

(最多只允许输入30个字)