diff --git a/test_http_server/Makefile b/test_http_server/Makefile new file mode 100644 index 0000000..5ea24e9 --- /dev/null +++ b/test_http_server/Makefile @@ -0,0 +1,2 @@ +test_http_server: test_http_server.cpp + g++ $^ -o $@ -levent \ No newline at end of file diff --git a/test_http_server/app.ico b/test_http_server/app.ico new file mode 100644 index 0000000..13824e3 Binary files /dev/null and b/test_http_server/app.ico differ diff --git a/test_http_server/first_libevent.vcxproj b/test_http_server/first_libevent.vcxproj new file mode 100644 index 0000000..91811b3 --- /dev/null +++ b/test_http_server/first_libevent.vcxproj @@ -0,0 +1,167 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {129BF326-BFEE-4F1C-920C-0C302BB84895} + Win32Proj + firstlibevent + 10.0.17763.0 + test_http_server + + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + + + Level3 + Disabled + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + NotUsing + Level3 + Disabled + true + _DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + ..\..\include + + + Console + true + ..\..\lib + libevent.lib;ws2_32.lib;%(AdditionalDependencies) + + + + + + + Level3 + MaxSpeed + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + Level3 + MaxSpeed + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + true + + + + + + \ No newline at end of file diff --git a/test_http_server/index.html b/test_http_server/index.html new file mode 100644 index 0000000..6eac519 --- /dev/null +++ b/test_http_server/index.html @@ -0,0 +1,17 @@ + + + +test http server + + +

test http server

+ 111112222 + + +
+ + + +
+ + diff --git a/test_http_server/test_http_server.cpp b/test_http_server/test_http_server.cpp new file mode 100644 index 0000000..0b36c16 --- /dev/null +++ b/test_http_server/test_http_server.cpp @@ -0,0 +1,177 @@ + +#include +#include +#include +#include +#include +#include +#include +#ifndef _WIN32 +#include +#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; +} + +