最近本来有个长链接代理需求,我想用libevent做请求服务器,然后交给后面的线程池处理。这里将libevent处理http请求的过程做个备忘。
01 | #include <sys/types.h> |
02 | #include <sys/time.h> |
03 | #include <sys/queue.h> |
04 | #include <sys/types.h> |
05 | #include <ctype.h> |
06 | #include <stdio.h> |
07 | #include <stdlib.h> |
08 | #include <string.h> |
09 | #include <unistd.h> |
10 | #include <sys/socket.h> |
11 | #include <sys/stat.h> |
12 | #include <sys/mman.h> |
13 | #include <netinet/in.h> |
14 | #include <net/if.h> |
15 | #include <arpa/inet.h> |
16 | #include <netdb.h> |
17 | #include <arpa/inet.h> |
18 | #include <fcntl.h> |
19 | #include <time.h> |
20 | #include <sys/ioctl.h> |
21 | #include <errno.h> |
22 | #include <assert.h> |
23 | #include <signal.h> |
24 | #include <stdbool.h> |
25 | #include <err.h> |
26 | #include <event.h> |
27 | #include <evhttp.h> |
28 | #define VERSION "1.0" |
29 |
30 | /* |
31 | *处理模块 |
32 | */ |
33 | void api_proxy_handler( struct evhttp_request *req, void *arg) { |
34 |
35 | //初始化返回客户端的数据缓存 |
36 | struct evbuffer *buf; |
37 | buf = evbuffer_new(); |
38 |
39 | /* 分析URL参数 */ |
40 | char *decode_uri = strdup(( char *) evhttp_request_uri(req)); |
41 | struct evkeyvalq http_query; |
42 | evhttp_parse_query(decode_uri, &http_query); |
43 | free (decode_uri); |
44 |
45 | //接收GET表单参数name |
46 | const char *http_input_name = evhttp_find_header(&http_query, "name" ); |
47 |
48 | //处理输出header头 |
49 | evhttp_add_header(req->output_headers, "Content-Type" , "text/plain" ); |
50 | evhttp_add_header(req->output_headers, "Connection" , "keep-alive" ); |
51 | evhttp_add_header(req->output_headers, "Cache-Control" , "no-cache" ); |
52 |
53 | //处理输出数据 |
54 | evbuffer_add_printf(buf, "PROXY VERSION %s\n" , VERSION); |
55 | evbuffer_add_printf(buf, "------------------------------\n" ); |
56 | evbuffer_add_printf(buf, "YOU PASS NAME: %s\n" , http_input_name); |
57 |
58 | //返回code 200 |
59 | evhttp_send_reply(req, HTTP_OK, "OK" , buf); |
60 | //释放内存 |
61 | evhttp_clear_headers(&http_query); |
62 | evbuffer_free(buf); |
63 | } |
64 |
65 | int main( int argc, char ** argv) { |
66 |
67 | struct evhttp *httpd; |
68 | char *proxy_listen = "0.0.0.0" ; //绑定所有ip |
69 | int proxy_port = 2012; //端口号 |
70 | int proxy_settings_timeout = 5; //http请求超时时间 |
71 |
72 | //初始化监听ip和端口 |
73 | event_init(); |
74 | httpd = evhttp_start(proxy_listen, proxy_port); |
75 | if (httpd == NULL) { |
76 | fprintf (stderr, "Error: Unable to listen on %s:%d\n\n" , proxy_listen, proxy_port); |
77 | exit (1); |
78 | } |
79 | //设置http连接超时时间 |
80 | evhttp_set_timeout(httpd, proxy_settings_timeout); |
81 | //设置请求到达后的回调函数 |
82 | evhttp_set_gencb(httpd, api_proxy_handler, NULL); |
83 | //libevent循环处理事件 |
84 | event_dispatch(); |
85 | //释放资源 |
86 | evhttp_free(httpd); |
87 | return 0; |
88 | } |
使用浏览器测试,可以看到返回200,输入了get请求的name值与定义的版本号:
|Archiver|手机版|小黑屋|软路由 ( 渝ICP备15001194号-1|渝公网安备 50011602500124号 )
GMT+8, 2024-5-11 02:18 , Processed in 0.085626 second(s), 5 queries , Gzip On, Redis On.
Powered by Discuz! X3.5 Licensed
© 2001-2023 Discuz! Team.