本文同时发表在https://github.com/zhangyachen/zhangyachen.github.io/issues/90
在通过curl调用对方接口时,发现超时现象很严重,于是询问对方接口人,对方说需要加上:
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
加上之后发现果然好使了,于是调研了一下该用法。
在使用curl做POST的时候, 当要POST的数据大于1024字节的时候, curl并不会直接就发起POST请求, 而是会分为2个步骤:
- 发送一个请求, 包含一个Expect:100-continue, 询问Server使用愿意接受数据
- 接收到Server返回的100-continue应答以后, 才把数据POST给Server
但是这样会有几个问题:
- 不是所有的服务器都会正确应答100-continue, 比如lighttpd, 就会返回417 Expectation Failed。
- 造成延时,客户端在发送第一次的Expect:100-continue时,需要等待服务器端进行回答之后才发送request body。
如果确定对方的服务器不会拒绝1024个字节以上的POST请求,就可以不使用该方法而且也可以避免以上提到的两个副作用,解决的办法就是文章开头提到的。
关于100 continue
收到了请求的初始部分,请客户端继续。
这样做的目的是:它可以让客户端在发送请求数据之前去判断服务器是否愿意接收该数据,如果服务器愿意接收,客户端才会真正发送数据,如果客户端直接发送请求数据,但是服务器又将该请求拒绝的话,这种行为将带来很大的资源开销。
客户端行为
发送了100 continue的客户端不应该永远等待服务器端做出回应,超时一段时间之后,客户端应该直接将实体发送出去。
服务器端行为
如果服务器端收到了100 continue的请求,它会用100 continue响应或者发送一个错误码。服务端永远不能向没有发送100 continue的客户端发送100 continue。但是有的服务器会这么做。IIS 5 incorrectly sending 100-continue response
如果服务端在还没发送100 continue响应时就收到了客户端的body,那么说明客户端决定开始发送数据了,所以此时服务器端不能再向客户端发送100 continue。
参考资料:Expect:100-continue
http权威指南3.4.1