libcurl的使用问题“Expect100-continue”
最近在做团购酒店APP分享到qzone功能,使用libcurl访问qzone的分享cgi接口,酒店分享信息以POST方式传输,在测试的时候发现分享接口平均有2s的延迟,这延迟也太大了吧,于是乎问了空间的接口人,答曰:怎么可能,这个接口的平均调用时延是100-200ms,肯定是你的代码有问题。好吧,开始检查代码,使用strace -p跟踪系统调用,发现curl发送了两次请求,其中第一次请求的响应特别的慢,额,原来这个才是导致延迟的罪魁祸首,tcpdump之后发现curl发送的第一个请求包含一个Expect: 100-continue的头,这是为什么呢,于是开始百度,google,得到的解释如下:
当使用libcurl的POST方式时,如果POST数据的大小大于1024个字节,libcurl不会直接发送POST请求,而是会分为两步执行请求:
1、发送一个请求,该请求头部包含一个Expect: 100-continue的字段,用来询问server是否愿意接受数据
2、当接收到从server返回的100-continue的应答后,它才会真正的发起POST请求,将数据发送给server。
对于“100-continue"这个字段,RFC文档(http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3)是这么解释的:它可以让客户端在发送请求数据之前去判断服务器是否愿意接收该数据,如果服务器愿意接收,客户端才会真正发送数据,这么做的原因是如果客户端直接发送请求数据,但是服务器又将该请求拒绝的话,这种行为将带来很大的资源开销。所以为了避免这种情况,libcurl在发送大于1024字节的POST请求时采用了这种方法,但是相对的,它会引起请求延迟的加大,另外并不是所有的server都会正确处理并且应答”100-continue“,比如lighttpd,就会返回417”Expectation Failed“,造成请求逻辑出错。
如果确定服务器不会拒绝1024个字节以上的POST请求,就可以不使用该方法而且也可以避免以上提到的两个副作用,解决的办法如下:
- // disable Expection header
- curl_easy_setopt(curl, CURLOPT_HTTPHEADER, array('Expect:'));
禁用该机制后,测试了一下qzone分享接口平均调用时延减小到了200ms,这才是正常的延时嘛,嘿嘿。
参考资料:
http://www.laruence.com/2011/01/20/1840.html
from:http://blog.csdn.net/zxgfa/article/details/7604624
libcurl的使用问题“Expect100-continue”的更多相关文章
- boost::asio 使用 libcurl
curl 使用 asio 的官方样例 http://curl.haxx.se/libcurl/c/asiohiper.html, 但这个例子用起来有很明细的 bug,asio 异步IO 只注册一次,也 ...
- libCurl的文件上传
最近在需要使用curl的上传功能,使用libCurl来实现.因此,先使用curl命令操作,然后再使用libCurl实现. 基于Http协议的文件上传的标准方法是: 基于POST Form的文件上传 ...
- 使用libcurl的正确姿势
libcurl支持访问http.ftp等各种服务器,下载图片AV什么的不在话下.但其存在多种接口,异步接口也很难以理解,到底什么样的使用姿势才是正确滴?我们来看看可用的体位: easy interfa ...
- libcurl实现解析(3) - libcurl对select的使用
1.前言 在本系列的前一篇文章中.介绍了libcurl对poll()的使用. 參考"libcurl原理解析(2) - libcurl对poll的使用". 本篇文章主要分析curl_ ...
- MinGW64 how-to(内含编译openssl,libjpeg,libcurl等例子)
Index of contents Setting up the MinGW 64 environment Step 1) building libiconv Step 2) building lib ...
- 基于libcurl的restfull接口 post posts get gets
头文件 #pragma once #ifndef __HTTP_CURL_H__ #define __HTTP_CURL_H__ #include <string> #include &q ...
- continue break 区别
在循环中有两种循环方式 continue , break continue 只是跳出本次循环, 不在继续往下走, 还是开始下一次循环 break 将会跳出整个循环, 此循环将会被终止 count = ...
- 《Note --- Unreal --- MemPro (CONTINUE... ...)》
Mem pro 是一个主要集成内存泄露检测的工具,其具有自身的源码和GUI,在GUI中利用"Launch" button进行加载自己待检测的application,目前支持的平台为 ...
- 《Note --- Unreal 4 --- Sample analyze --- StrategyGame(continue...)》
---------------------------------------------------------------------------------------------------- ...
- (转)利用libcurl和国内著名的两个物联网云端通讯的例程, ubuntu和openwrt下调试成功(四)
1. libcurl 的参考文档如下 CURLOPT_HEADERFUNCTION Pass a pointer to a function that matches the following pr ...
随机推荐
- SqLite 使用 Dapper 查询INTEGER类型的主键问题
在程序实体定义时: public int TableID { get; set; } 使用Dapper查询SqLite数据库时会报错 Error parsing column (= - Int64) ...
- 浅谈Mybatis(二)
一.resultMap 作用:发现数据库的查询结果与实体之间不匹配时,需要通过ResultMap来进行映射处理.常用于多表查询. 多表查询还是比较复杂的,因为可能的情况很多.这里只说两种情况: 1.1 ...
- C++_知识点_全局变量
全局变量 -全局变量即在函数之外定义的变量 -全局变量保存在静态存储区 注意: -全局变量只能声明和初始化 -全局变量不能进行运算.赋值(非初始化).调用函数 -否则会出现编译错误 -error: e ...
- IOS基础:深入理解Objective-c中@class的含义
objective-c中,当一个类使用到另一个类时,并且在类的头文件中需要创建被引用的指针时, 如下面代码: A.h文件 #import "B.h" @interface A : ...
- 联想V480关闭UEFI安装Win7
联想V480关闭UEFI安装Win7 http://www.dadclab.com/archives/3283.jiecao 故事背景 兔兔牛入了一枚Lenovo V480,预装Win8,想换成 ...
- Windows Phone
错误: DEP6100 : 引导阶段“正在连接到设备”出现以下意外错误: SmartDeviceException - Windows Phone IP over USB Transport (IpO ...
- uglifyjs note
uglifyjs UglifyJS is a JavaScript parser, minifier, compressor or beautifier toolkit. uglifyjs是用js写的 ...
- 使用PyQt来编写第一个Python GUI程序
原文:使用PyQt来编写第一个Python GUI程序 本文由 伯乐在线 - Lane 翻译,Daetalus 校稿.未经许可,禁止转载!英文出处:pythonforengineers.com.欢迎加 ...
- uva-12657 - Boxes in a Line(双向链表)
12657 - Boxes in a Line You have n boxes in a line on the table numbered 1 . . . n from left to righ ...
- 狼追兔子问题C模拟解
说,一只兔子在O点处,它的洞穴在正北20m的B点处,一只狼位于兔子正东33米的A点处,模拟如下追逐问题:狼以一倍于兔子的速度紧盯兔子追击,问兔子到达洞口前是否会被狼逮住? 网上很多人说能被追上,包括类 ...