正在做一个HTTP代理,然而现在大部分的HTTP都使用了keep-alive,也就导致连接是一直开启并不close。然而我应该如何判断数据已经传输完成呢?
目前我是用了一个checker来对每个连接进行timeout检验,超过规定的时间就认定传输已完成。
所以,有更好的方法么?
1
wkdhf233 2015-08-02 22:40:35 +08:00
HTTP协议不是有结束界定的吗
GET的话俩回车,POST之类的到达Content-Length。。 |
2
zado 2015-08-02 22:47:28 +08:00
看那个Content-Length,这个数值加上http头大小就是全部数据的大小了。我也是定时检测,然后超过一定时间的就断开。
|
3
imn1 2015-08-02 22:50:18 +08:00
|
4
mason961125 OP @zado 虽然是个HTTP代理,但是遇到HTTPS的请求也是可以代理的。但是如果是HTTPS请求的话,是没办法知道请求头的吧(我记不太清楚了,错了求指正
|
5
mason961125 OP @imn1 但是我又怕如果是看YouTube那种的长连接,在连接时间里数据基本一直在传输的,就无解了。
|
6
wkdhf233 2015-08-02 23:27:03 +08:00
@imn1 同个socket多次请求,单次的结束界定你也得按协议规定来啊,你还能把俩GET挤到一起发出去?
长连接是socket层面的东西,HTTP协议层面除了个keep-alive之外没啥变化的 |
7
imn1 2015-08-02 23:28:43 +08:00
没做过proxy,不过个人觉得杀掉 http 就可以了
ssl 网站那边出于安全性和服务器性能,会有检查断开的机制 定时检查连接数量,把时间较长和“不合理”的长连接强制断开就行了 |
8
imn1 2015-08-02 23:39:43 +08:00
@wkdhf233
不是同时,是依次 你可以自己写一个测试一下,根据字节或结束符判断传输完毕,保存或处理,不发送close,然后send另一个http请求,会有新的返回的 反正我写过,较好的服务器连续请求5个不同url(当然服务器是同一个)成功,很多时候第6个请求失败(有些服务器线路不好的2~3个就不行了),但我的 socket 知识水平有限,异常处理得不好,所以没能继续写 |
9
wkdhf233 2015-08-03 00:15:24 +08:00
@imn1 =_=长连接的程序我写过,因为PHP不好多线程所以一次把40+个请求送出去再慢慢处理返回,复用长连接本来也是十分常见的做法。
我说的是,socket保持和HTTP协议的结束判断没有关系。socket只是承载传输,协议才是描述请求。要判断一个HTTP请求是否结束,只用根据协议的分割划分来就行。 请求和请求间按照协议规定划分,而要是某个请求里没有keep-alive了,说明这个socket不用保持了。 楼主担忧一个长连接照协议保持着但实际上没有作用了是多余的,不用了掐掉这是连接方的责任,还保持着就说明它还有可能传东西。 代理方要做的只是统一设置一个超时时间,超过时间未活动(注意是未活动,每个带keep-alive的请求都应该清零计数器)的连接都掐掉就行了。 |
10
zado 2015-08-03 00:25:07 +08:00
https 应该是没办法知道请求头的,所以应该也没有办法做代理吧,除非就是做成路由器那样的直接转发数据,那样就只能是在数据经过的时候记录一下时间,超过多长时间没有数据经过了就断开。
|
11
loggerhead 2015-08-03 00:38:35 +08:00 via iPhone 1
http 0.9或1.0 每次请求完成都会直接断开连接,并视为数据传完。
1.1如果没有connection: close就会被认为是keep-live。如果服务器主动断开连接,需要在响应报文中设置connection: close,否则tcp连接处于半关闭,客户端发的数据服务器照样接收,但是不进行任何处理。 不知道楼主是想问 如何判断还有没有请求,还是如何判断请求有没有传完? 前者没法判断,后者得分析报文。 |
12
julyclyde 2015-08-03 13:55:50 +08:00 1
content-length或者chunked的尾0报 代表一个HTTP body的结束
如果是没有body的,header行后面多加一个回车就算完 |