这里说的坑,都是实际项目中遇到的,记录下来,也与读者分享。
1. Content-Length一定尽量与body长度一致
Content-Length用来标识http请求or响应的body的长度(即字节数),是http报文分界的一种方法。由于程序bug或者故障,有可能导致http报文中的body长度与Content-Length不一致:
-
http请求的body长度与其Content-Length不一致
后果- Content-Length > body长度,则服务器端卡住,只能通过超时或者关闭连接解决;
- Content-Length < body长度,则连接腐烂,只能关闭连接(影响长连接效果)。
-
http响应的body长度与其Content-Length不一致
后果- Content-Length > body长度 客户端卡着,只能通过超时或者关闭连接解决
- Content-Length < body长度 连接腐烂,只能关闭连接
这么看,Content-Length应该是要一定与body长度一致,为什么说尽量?因为出故障时我们可能无能为力:比如我们数据库记录了一个文件大小为100MB,于是设置Content-Length=100MB,然后把文件内容作为body返回客户端,但是文件已经损坏(只有读的时候才能发现),只有50M,由于http的start line和headers已经发给了客户端,没法更改了,客户端收到50M内容后,继续等待接收剩下的50M,直至超时或连接关闭,表现为客户端卡着。
2. 参数parameter最小化
举例: 如果我们有2个接口(来自AWS S3文档)
设置跨域规则接口
PUT /?cors HTTP/1.1
Host: bucketname.s3.amazonaws.com
设置生命周期管理接口
PUT /?lifecycle HTTP/1.1
Host: bucketname.s3.amazonaws.com
那么服务端应该这样实现:
- 参数只有cors -- 按照设置跨域规则来处理
- 参数只有lifecycle -- 按照设置生命周期管理来处理
- 否则 -- 返回400 Bad Request
不遵循的危害:影响接口扩展
比如 如果前期服务器将/?lifecycle
和/?lifecycle&haha
同等对待,那么由于Rest API是开放的以及客户端实现的不确定性,不好保证有的用户发的是/?lifecycle&haha
接口。如果后期服务器想加个接口/?lifecycle&haha
以实现其他功能,则因为该接口可能已被当做/?lifecycle
来对待而造成困扰。