cowboy的一个小陷阱

本文详细探讨了在使用Cowboy框架时遇到的持久连接问题,特别是如何处理HTTP请求与响应之间的连接断开与重新连接。重点分析了Cowboy框架中`cowboy_req`模块的操作,特别是`reply`方法可能导致的意外`204 No Content`响应问题,并提供了正确的处理方法以避免此现象。文章旨在帮助开发者理解并解决在实际应用中遇到的HTTP连接与响应处理的挑战。
我在用cowboy时遇到了一个麻烦,通过HTTP连接获取数据时不能用的HTTP/1.1的持久连接(persistent connection)进行数据交换,每个请求-响应过程必须断开连接后重新连才行,也就是说只有Connection:close时才能正常工作。

用wireshark看连接的数据包发现一个奇怪的现象,就是每个响应的最后都会紧跟着出现一个204 No Content的响应。无论是持久连接还是断开再连接都会有这个奇怪的响应跟在后头。

后来发现,原因是这样的:

cowboy用http_req代表了一次用户请求的数据记录(似乎叫session比较好点),该record记录了socket连接信息、用户请求信息(包括请求消息头、消息体等),以及服务器的响应(例如响应状态、响应消息头,响应消息体等),由cowboy_req模块提供了该record相应的操作接口。

比如 cowboy_req:method/得到请求的方法类型
{Method, Req2} = cowboy_req:method(Req)

cowboy_req:path_info/1得到请求url的路径信息
{PathInfo, Req1} = cowboy_req:path_info(Req)

注意以上方法都会返回一个新的Req1结构数据,虽然许多情况下Req和Req1其实是同一个请求记录。但是某些方法是会修改Req的,例如修改响应的头信息时,因此Req /= Req1,这时再使用Req就有麻烦了。

我是在使用reply方法的时候遇到这个问题,而cowboy_req:rely/2,3,4方法也是会修改Req记录的,如果直接处理
cowboy_req:reply(200, Headers, BodyData, Req)
最后用老的Req作为handle方法的返回,cowboy会无以为没有进行响应,所以它会自己加一个 204 No Content的响应。
错误用法:
handle(Req, State) ->
cowboy_req:method(Req),
...
cowboy_req:reply(200, Headers, BodyData, Req),
...
{ok, Req}.


正确用法:
handle(Req, State) ->
cowboy_req:method(Req),
....
{ok, Req1} = cowboy_req:reply(200, Headers, BodyData, Req),
.....
{ok, Req1}.

也许对所有的cowboy_req模块方法,都应该同一采用这种方式使用比较好。时刻记住Req记录在cowboy_req可能发生变化。


因为所有的响应都是带Content-Length的,所以客户端可以正确的解析出连接中的第一个响应。但是在持久连接(persistent connection),即keep alive,的情况下,第二个响应就变成了204 No Content消息,就会出现上述问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值