博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一个关于Http的请求头Expect
阅读量:4077 次
发布时间:2019-05-25

本文共 4085 字,大约阅读时间需要 13 分钟。

最近遇到了个问题,我在csdn上发帖子了,不过问题还是自己解决的:

 

经过分析就是多了个expect的请求头,对方服务器就报404的错误。我仔细看了下这个请求头

,这里有篇文章很详细了,我转发吧:

 

转的哈:

 

这两天写代码,调用新浪微博的Rest API,使用HttpClient 4.0,以Post方式提交,请求参数以UrlEncodedFormEntity的形式设置到HttpPost对象中,提交到API时,出现如下异常:

417 Expectation Failed

Error 417 Expectation Failed

Expectation Failed

Guru Meditation:

XID: 2734998565

Varnish

刚开始有点莫名其妙,这是哪门子错误,没见过啊,于是去查HTTP状态字定义,得到如下描述:

The expectation given in an Expect request-header field (see section14.20) could not be met by this server, or, if the server is a proxy,the server has unambiguous evidence that the request could not be metby the next-hop server.

大致的意思是:

服务器不支持Expect请求头部域,或者,如果服务器是代理服务器的话,服务器有明确的证据表明请求不能到达下一跳服务器。

那,到底什么是Expect请求头部域呢?以前完全没用过,也很少见,跟踪浏览器的HTTP请求的时候也很少见这个头部域,继续查吧,根据HTTP请求头部Expect域的定义,得到如下信息:

The Expect request-header field is used to indicate that particularserver behaviors are required by the client.      Expect       =  "Expect" ":" 1#expectation      expectation  =  "100-continue" | expectation-extension      expectation-extension =  token [ "=" ( token | quoted-string )                               *expect-params ]      expect-params =  ";" token [ "=" ( token | quoted-string ) ]A server that does not understand or is unable to comply with any ofthe expectation values in the Expect field of a request MUST respond with appropriate error status. The server MUST respond with a417(Expectation Failed) status if any of the expectations cannot be metor, if there are other problems with the request, some other 4xx status.This header field is defined with extensible syntax to allow forfuture extensions. If a server receives a request containing anExpect field that includes an expectation-extension that it does notsupport, it MUST respond with a 417 (Expectation Failed) status.Comparison of expectation values is case-insensitive for unquotedtokens (including the 100-continue token), and is case-sensitive forquoted-string expectation-extensions.The Expect mechanism is hop-by-hop: that is, an HTTP/1.1 proxy MUSTreturn a 417 (Expectation Failed) status if it receives a requestwith an expectation that it cannot meet. However, the Expectrequest-header itself is end-to-end; it MUST be forwarded if therequest is forwarded.Many older HTTP/1.0 and HTTP/1.1 applications do not understand theExpect header.

大致意思如下:

Expect请求头部域,用于指出客户端要求的特殊服务器行为。若服务器不能理解或者满足Expect域中的任何期望值,则必须返回417(Expectation Failed)状态,或者如果请求有其他问题,返回4xx状态。这个头部域使用可扩展语法定义,以方便将来扩展。如果服务器收到包含Expect头部域的请求且包含一个它不支持的期望值扩展,则必须返回417(Expectation Failed)状态。期望值的比较,对于非引用符号(包括100-continue)是大小写无关的,对于引用字符串的期望值扩展,则是大小写敏感的。Expect域的机制是逐跳进行的,也就是说如果一个代理服务器收到包含不能满足的期望的请求时,必须返回417(Expectation Failed)状态。而Expect请求头部域自身,却是端到端的,如果请求被转发,则它也必须被转发。很多旧的HTTP/1.0和HTTP/1.1应用不支持Expect头部。

到这里,基本明白了为什么会出现这样的错误,说明代码最后生成的HTTP请求,包含了服务器不能处理的Expect头部,到底是什么?装上Wireshark,监听一下请求内容,发现出现异常时的请求中的Expect头部是这样的:Expect:100-Continue,难道是它引起的?继续查……

对于Expect:100-Continue,HttpClient的官方文档是这样描述的:

The purpose of the Expect: 100-Continue handshake is to allow the client thatis sending a request message with a request body to determine if the originserver is willing to accept the request (based on the request headers) before the client sends the request body.Expect: 100-continue handshake should be used with caution, as it may causeproblems with HTTP servers and proxies that do not support HTTP/1.1 protocol.

大意如下:

Expect:100-Continue握手的目的,是为了允许客户端在发送请求内容之前,判断源服务器是否愿意接受请求(基于请求头部)。Expect:100-Continue握手需谨慎使用,因为遇到不支持HTTP/1.1协议的服务器或者代理时会引起问题。

而HttpClient 4.0中,是否激活Expect:100-Continue,是由HTTP请求执行参数http.protocol.expect-continue来控制的,通过设置参数值为true或者false,可以相应的激活或者关闭Expect:100-Continue握手。注意,在HttpClient中,默认是激活的。

HttpClient 4 中关闭Expect:100-Continue握手的代码如下:

HttpPost httpPost = new HttpPost(url);httpPost.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE,false);

关闭HttpClient中的Expect:100-Continue握手之后,再执行程序,顺利地通过微博API发出了一条消息。

总结:通过这次的问题解决,可以看出,对于HTTP协议不够熟悉,底层了解不够,同时没有认真阅读HttpClient开发文档。我想,现在从事软件开发行业的大部分人都或多或少有这样的问题,即忽视底层协议及原理的学习。真正的了解底层原理,借以开源代码及开发文档的辅助,这样才会能够实现快速、高效、稳定的程序开发。

 

参见原文:

转载地址:http://gtini.baihongyu.com/

你可能感兴趣的文章
六角铜柱的型号
查看>>
pixhawk无GPS时可以在定高或者自稳模式下解锁起飞(见过多次别人说到)
查看>>
pixhawk(PX4)的一些论坛网站(包括中文版的PX4用户手册和PX4开发手册)
查看>>
串级 PID 为什么外环输出是内环的期望?(和我之前对串级PID的总结一样)
查看>>
APM/Pixhawk飞行日志分析入门(苍穹四轴)
查看>>
我刚刚才完全清楚GPS模块的那根杆子是怎么固定安装好的
查看>>
去github里面找找也没有别人无人机+SLAM的工程
查看>>
PX4与ROS关系以及仿真控制(键盘控制无人机)
查看>>
我对无人机重心高度的理解
查看>>
现在明白为什么无名博客里好几篇文章在讲传感器的滞后
查看>>
无人机不装脚架的好处就是降落时会比较稳,不怕倾斜侧翻。
查看>>
实际我看Pixhawk定高模式其实也是飞得很稳,飘得也不厉害
查看>>
我现在发现开课吧的智能无人机课程里面也讲GAAS
查看>>
Pixhawk解锁常见错误
查看>>
C++的模板化等等的确实比C用起来方便多了
查看>>
ROS是不是可以理解成一个虚拟机,就是操作系统之上的操作系统
查看>>
用STL algorithm轻松解决几道算法面试题
查看>>
ACfly之所以不怕炸机因为它觉得某个传感器数据不安全就立马不用了
查看>>
我发觉,不管是弄ROS OPENCV T265二次开发 SDK开发 caffe PX4 都是用的C++
查看>>
ROS的安装(包含文字和视频教程,我的ROS安装教程以这篇为准)
查看>>