HTTPSQS 1.7 发布:Libevent 2.0.x 的 evhttp_parse_query BUG 与动态编译时指定动态链接库 .so 寻找路径
[
2011-7-26 17:07 | by 张宴 ]
![不指定 不指定](images/weather/blank.gif)
[文章作者:张宴 本文版本:v1.0 最后修改:2011.07.26 转载请注明原文链接:http://blog.zyan.cc/httpsqs_1_7/]
HTTPSQS(HTTP Simple Queue Service)是一款基于 HTTP GET/POST 协议的轻量级开源简单消息队列服务,使用 Tokyo Cabinet 的 B+Tree Key/Value 数据库来做数据的持久化存储。
项目网址:http://code.google.com/p/httpsqs/
使用文档:http://blog.zyan.cc/httpsqs/
使用环境:Linux(同时支持32位、64位操作系统,推荐使用64位操作系统)
软件作者:张宴
HTTPSQS 1.7 版本更新内容:
下面的内容不只是介绍 HTTPSQS 1.7 更新了哪些东西,更多的介绍在于:如何绕开 Libevent 2.0.x evhttp 使用过程中,无法正常处理包含“|”字符的 URI 参数的问题;提供了一份比 Libevent 官方网站更新的在线文档;Linux 下如何动态编译程序,运行时不用在 /etc/ld.so.conf 文件中添加动态链接库路径。
1、针对 Libevent 2.0.x 版本 evhttp_parse_query 函数的 BUG。
网友发邮件,反应了一个 HTTPSQS 的 BUG,见下图,data 的值为NULL。我查找发现,这不是 HTTPSQS 的 BUG,而是 Libevent 2.0.x 版本的 BUG。在 Libevent 1.4.14b 版本中,evhttp_parse_query 函数是能够正常处理包含“|”字符的 URI 的,而在 Libevent 2.0.12 版本中,同样使用 evhttp_parse_query 函数,包含“|”字符的 URI 处理后的结果是 NULL。
![点击在新窗口中浏览此图片 点击在新窗口中浏览此图片](attachment/201107/evbug0.gif)
对比 Libevent 2.0.12 和 1.4.14b 版本的 evhttp_parse_query 函数代码,发现在 2.0.12 版本中,evhttp_parse_query(const char *uri, struct evkeyvalq *headers) 实际变成了调用 evhttp_parse_query_impl(uri, headers, 1) 函数,该函数内再调用的一个 2.0.x 版本新增的函数 evhttp_uri_parse(const char *source_uri),逻辑处理代码在 evhttp_uri_parse_with_flags(const char *source_uri, unsigned flags) 函数中。evhttp_uri_parse(const char *source_uri) 无法正确解析含有“|”的URL,遇到类似“http://127.0.0.1:1218/?opt=get&name=aaa|bbb”的URL,直接返回NULL,也就是 BUG 所在。
libevent-2.0.12-stable/http.c
![点击在新窗口中浏览此图片 点击在新窗口中浏览此图片](attachment/201107/evbug1.gif)
![点击在新窗口中浏览此图片 点击在新窗口中浏览此图片](attachment/201107/evbug2.gif)
![点击在新窗口中浏览此图片 点击在新窗口中浏览此图片](attachment/201107/evbug3.gif)
不建议修改第三方库,这个 BUG 还是留给 Libevent 自己去解决吧。使用 Libevent 2.0.x evhttp 作开发的同学,遇到URI参数中包含“|”的问题,注意一下吧。
我修改了 HTTPSQS 代码,在 HTTPSQS 1.7 版本,采用以下方式来绕开evhttp_uri_parse(const char *source_uri)函数,解决这个问题。其中用到了 Libevent 2.0.x evhttp_request 结构体中新增的 struct evhttp_uri *uri_elems,以及新增的函数 evhttp_parse_query_str (const char *uri, struct evkeyvalq *headers)。
Libevent 的官方文档只有 1.4.10-stable 和 2.0.1-alpha 版本的,2.0.1x 很多新增的函数、结构体都没有。
我这里提供一份最新的 Libevent 在线文档: http://blog.zyan.cc/book/libevent/
2、静态编译改为动态编译,并指定程序运行时查找的动态链接库路径
一些网友反映,CentOS 6.0、Fedora 等系统没有默认安装lz、lbz2、lrt、...等静态链接库,出现无法编译HTTPSQS的情况:
HTTPSQS 1.7 版本改为动态编译,编译时使用“-Wl,-rpath”参数指定了程序运行时的动态库搜索路径。这样就不需要在 /etc/ld.so.conf 中 添加 HTTPSQS 程序运行时需要的 libevent、tokyocabinet 动态链接库路径了,可以避免与其他软件(例如:Memcached、TT)使用的 libevent、tokyocabinet 动态链接库版本相冲突。详情请见 Makefile 文件:
HTTPSQS(HTTP Simple Queue Service)是一款基于 HTTP GET/POST 协议的轻量级开源简单消息队列服务,使用 Tokyo Cabinet 的 B+Tree Key/Value 数据库来做数据的持久化存储。
项目网址:http://code.google.com/p/httpsqs/
使用文档:http://blog.zyan.cc/httpsqs/
使用环境:Linux(同时支持32位、64位操作系统,推荐使用64位操作系统)
软件作者:张宴
HTTPSQS 1.7 版本更新内容:
下面的内容不只是介绍 HTTPSQS 1.7 更新了哪些东西,更多的介绍在于:如何绕开 Libevent 2.0.x evhttp 使用过程中,无法正常处理包含“|”字符的 URI 参数的问题;提供了一份比 Libevent 官方网站更新的在线文档;Linux 下如何动态编译程序,运行时不用在 /etc/ld.so.conf 文件中添加动态链接库路径。
1、针对 Libevent 2.0.x 版本 evhttp_parse_query 函数的 BUG。
网友发邮件,反应了一个 HTTPSQS 的 BUG,见下图,data 的值为NULL。我查找发现,这不是 HTTPSQS 的 BUG,而是 Libevent 2.0.x 版本的 BUG。在 Libevent 1.4.14b 版本中,evhttp_parse_query 函数是能够正常处理包含“|”字符的 URI 的,而在 Libevent 2.0.12 版本中,同样使用 evhttp_parse_query 函数,包含“|”字符的 URI 处理后的结果是 NULL。
![点击在新窗口中浏览此图片 点击在新窗口中浏览此图片](attachment/201107/evbug0.gif)
对比 Libevent 2.0.12 和 1.4.14b 版本的 evhttp_parse_query 函数代码,发现在 2.0.12 版本中,evhttp_parse_query(const char *uri, struct evkeyvalq *headers) 实际变成了调用 evhttp_parse_query_impl(uri, headers, 1) 函数,该函数内再调用的一个 2.0.x 版本新增的函数 evhttp_uri_parse(const char *source_uri),逻辑处理代码在 evhttp_uri_parse_with_flags(const char *source_uri, unsigned flags) 函数中。evhttp_uri_parse(const char *source_uri) 无法正确解析含有“|”的URL,遇到类似“http://127.0.0.1:1218/?opt=get&name=aaa|bbb”的URL,直接返回NULL,也就是 BUG 所在。
libevent-2.0.12-stable/http.c
![点击在新窗口中浏览此图片 点击在新窗口中浏览此图片](attachment/201107/evbug1.gif)
![点击在新窗口中浏览此图片 点击在新窗口中浏览此图片](attachment/201107/evbug2.gif)
![点击在新窗口中浏览此图片 点击在新窗口中浏览此图片](attachment/201107/evbug3.gif)
不建议修改第三方库,这个 BUG 还是留给 Libevent 自己去解决吧。使用 Libevent 2.0.x evhttp 作开发的同学,遇到URI参数中包含“|”的问题,注意一下吧。
我修改了 HTTPSQS 代码,在 HTTPSQS 1.7 版本,采用以下方式来绕开evhttp_uri_parse(const char *source_uri)函数,解决这个问题。其中用到了 Libevent 2.0.x evhttp_request 结构体中新增的 struct evhttp_uri *uri_elems,以及新增的函数 evhttp_parse_query_str (const char *uri, struct evkeyvalq *headers)。
Libevent 的官方文档只有 1.4.10-stable 和 2.0.1-alpha 版本的,2.0.1x 很多新增的函数、结构体都没有。
我这里提供一份最新的 Libevent 在线文档: http://blog.zyan.cc/book/libevent/
2、静态编译改为动态编译,并指定程序运行时查找的动态链接库路径
一些网友反映,CentOS 6.0、Fedora 等系统没有默认安装lz、lbz2、lrt、...等静态链接库,出现无法编译HTTPSQS的情况:
gcc -o httpsqs httpsqs.c prename.c -L/usr/local/libevent-2.0.10-stable/lib/ -levent -L/usr/local/tokyocabinet-1.4.47/lib/ -ltokyocabinet -I/usr/local/libevent-2.0.10-stable/include/ -I/usr/local/tokyocabinet-1.4.47/include/ -lz -lbz2 -lrt -lpthread -lm -lc -O2 -g --static
/usr/bin/ld: cannot find -lz
/usr/bin/ld: cannot find -lbz2
/usr/bin/ld: cannot find -lrt
/usr/bin/ld: cannot find -lpthread
/usr/bin/ld: cannot find -lm
/usr/bin/ld: cannot find -lc
/usr/bin/ld: cannot find -lc
collect2: ld 返回 1
make: *** [httpsqs] 错误 1
/usr/bin/ld: cannot find -lz
/usr/bin/ld: cannot find -lbz2
/usr/bin/ld: cannot find -lrt
/usr/bin/ld: cannot find -lpthread
/usr/bin/ld: cannot find -lm
/usr/bin/ld: cannot find -lc
/usr/bin/ld: cannot find -lc
collect2: ld 返回 1
make: *** [httpsqs] 错误 1
HTTPSQS 1.7 版本改为动态编译,编译时使用“-Wl,-rpath”参数指定了程序运行时的动态库搜索路径。这样就不需要在 /etc/ld.so.conf 中 添加 HTTPSQS 程序运行时需要的 libevent、tokyocabinet 动态链接库路径了,可以避免与其他软件(例如:Memcached、TT)使用的 libevent、tokyocabinet 动态链接库版本相冲突。详情请见 Makefile 文件:
# Makefile for httpsqs
CC=gcc
CFLAGS=-Wl,-rpath,/usr/local/libevent-2.0.12-stable/lib/:/usr/local/tokyocabinet-1.4.47/lib/ -L/usr/local/libevent-2.0.12-stable/lib/ -levent -L/usr/local/tokyocabinet-1.4.47/lib/ -ltokyocabinet -I/usr/local/libevent-2.0.12-stable/include/ -I/usr/local/tokyocabinet-1.4.47/include/ -lz -lbz2 -lrt -lpthread -lm -lc -O2 -g
httpsqs: httpsqs.c
$(CC) -o httpsqs httpsqs.c prename.c $(CFLAGS)
@echo ""
@echo "httpsqs build complete."
@echo ""
clean: httpsqs
rm -f httpsqs
install: httpsqs
install $(INSTALL_FLAGS) -m 4755 -o root httpsqs $(DESTDIR)/usr/bin
CC=gcc
CFLAGS=-Wl,-rpath,/usr/local/libevent-2.0.12-stable/lib/:/usr/local/tokyocabinet-1.4.47/lib/ -L/usr/local/libevent-2.0.12-stable/lib/ -levent -L/usr/local/tokyocabinet-1.4.47/lib/ -ltokyocabinet -I/usr/local/libevent-2.0.12-stable/include/ -I/usr/local/tokyocabinet-1.4.47/include/ -lz -lbz2 -lrt -lpthread -lm -lc -O2 -g
httpsqs: httpsqs.c
$(CC) -o httpsqs httpsqs.c prename.c $(CFLAGS)
@echo ""
@echo "httpsqs build complete."
@echo ""
clean: httpsqs
rm -f httpsqs
install: httpsqs
install $(INSTALL_FLAGS) -m 4755 -o root httpsqs $(DESTDIR)/usr/bin