libeventt9: HttpServer

使用Libevent 创建一个简单Http服务器,并实现解析响应请求数据。

代码地址:
http://121.4.70.4:3000/adminPyf/libevent_study.git libevent_study/test_http_server
支持linux 、windows

#include <iostream>
#include <event2/http.h>
#include<event2/event.h>
#include <event2/listener.h>
#include <event2/keyvalq_struct.h>
#include <event2/buffer.h>
#include <string.h>
#ifndef _WIN32
#include <signal.h>
#include "test_http_server.h"
#endif // !_WIN32

using namespace std;

#define WEBROOT "."
#define DEFAULTINDEX "index.html"

void http_cb(struct evhttp_request* request, void *arg) {
    cout << "http_cb" << endl;
    //1 获取浏览器请求信息
    //url
    const  char* uri = evhttp_request_get_uri(request);
    cout << "uri:" << uri << endl;

    //获取请求类型Get Post
    string cmdtype;
    evhttp_cmd_type type = evhttp_request_get_command(request);
    switch (type)
    {
    case EVHTTP_REQ_GET:
        cout << "EVHTTP_REQ_GET" << endl;
        break;
    case EVHTTP_REQ_POST:

        break;
    case EVHTTP_REQ_HEAD:
        break;
    case EVHTTP_REQ_PUT:
        break;
    case EVHTTP_REQ_DELETE:
        break;
    case EVHTTP_REQ_OPTIONS:
        break;
    case EVHTTP_REQ_TRACE:
        break;
    case EVHTTP_REQ_CONNECT:
        break;
    case EVHTTP_REQ_PATCH:
        break;
    default:
        break;
    }

    //消息报头
    evkeyvalq *headers = evhttp_request_get_input_headers(request);
    cout << "========headers========\n" << endl;

    for (evkeyval *p = headers->tqh_first; p != NULL; p = p->next.tqe_next) {
        cout << p->key << ":" << p->value << endl;
    }

    //请求正文
    evbuffer*inbuf = evhttp_request_get_input_buffer(request);
    char buf[1024] = { 0 };
    cout << "=========Input data ===========" << endl;
    while (evbuffer_get_length(inbuf)) {
        int n = evbuffer_remove(inbuf, buf, sizeof(buf) - 1);

        if (n > 0) {
            buf[n] = '\0';
            cout << buf << endl;
        }
    }


    //2 回复浏览器
    //状态行  响应正文

    //消息报头
    evkeyvalq *outhead = evhttp_request_get_output_headers(request);


    //分析URI
    //设置根目录
    string filepath = WEBROOT;
    filepath += uri;
    if (strcmp(uri, "/") == 0) {
        filepath += DEFAULTINDEX;
    }

    //文件后缀  
    int pos = filepath.rfind(".");
    string postfix = filepath.substr(pos+1,filepath.size() - (pos+1));
    if (postfix == "jpg" || postfix == "png" || postfix == "gif" || postfix == "ico") {
        string temp = "image/" + postfix;
        evhttp_add_header(outhead, "Content-Type", temp.c_str());
    }
    else if (postfix == "zip") {
        evhttp_add_header(outhead, "Content-Type", "application/zip");
    }
    else if (postfix == "html") {
        evhttp_add_header(outhead, "Content-Type", "text/html;charset=UTF8");
    }
    else if (postfix == "css") {
        evhttp_add_header(outhead, "Content-Type", "text/css");
    }

    FILE *fp = fopen(filepath.c_str(), "rb"); 
    if (!fp) {
        evhttp_send_reply(request, HTTP_NOTFOUND, "", 0);
        return;
    }

        evbuffer *outbuf = evhttp_request_get_output_buffer(request);

        for (;;) {
            int len = fread(buf, 1,sizeof(buf), fp);
            if (len <= 0)
                break;
            evbuffer_add(outbuf, buf, len);
        }
        fclose(fp);

        evhttp_send_reply(request, HTTP_OK, "", outbuf);


}

int main()
{
#ifdef _WIN32
    //初始化socket库
    WSADATA wsa;
    WSAStartup(MAKEWORD(2, 2), &wsa);
#else 
    if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) { //忽略管道信号,发送数据给已关闭的socket,会飞掉!
        return 1;
    }
#endif

    //创建libevent上下文
    event_base* base = event_base_new();
    if (base) {
        std::cout << "test server" << "\n";
    }

    //http 服务器
    //1.创建evhttp上下文
    evhttp *evh = evhttp_new(base);

    //2.绑定端口、IP
    if (evhttp_bind_socket(evh, "0.0.0.0", 8080) != 0) {
        cout << "绑定失败" << endl;
    }

    //3. 设定回调函数
    evhttp_set_gencb(evh, http_cb, 0);


    if (base)
        event_base_dispatch(base); //事件分发处理
    if (base)
        event_base_free(base);
    if (evh)
        evhttp_free(evh);

#if _WIN32
    WSACleanup();
#endif // _WIN32



    return 0;
}



libeventt9: HttpServer

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动到顶部