|
|
-
- #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;
- }
-
-
|