技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> 系统运维 --> 由于 HTTP request 不规范导致的被防火墙拦截

由于 HTTP request 不规范导致的被防火墙拦截

浏览:2544次  出处信息

这个问题其实是刘涛发现的,我只是整理一下

一段程序在本地调试正常后,放到网上却时断时续,最后确认问题如下

1. HTTP request 中的 Host: 段是 HTTP 1.1 规范,在 1.0 中没有这个

2. 但是目前通常环境中(我用的 Ubuntu,不过其他发行版应该也有这问题),PHP 中的一些函数如 file_get_contents 会发送错误的 request

例如只是这么简单的一行

  1. file_get_contents('http://www.163.com');

发送的头两行是

GET / HTTP/1.0
Host: www.163.com

3. 有些防火墙会把这些不规范的 HTTP 通信拦截掉:就算你用的机器没设置 iptable,通常机房本身都会有硬件防火墙的

昨天出现问题,是没料想到 PECL OAuth 也是如此

Update in 2010.12.31
王博对这个问题做了补充
1.在他的 CentOS 5.3 上,PECL OAuth 默认用的 HTTP 1.1
2.OAuth::setRequestEngine 方法可以提供 OAUTH_REQENGINE_STREAMS 和 OAUTH_REQENGINE_CURL 两种不同方式,后者就可以避免上述问题了。

解决方法有很多种,不过为了代码最大适应性(就像为什么现在大家都不用短标签 <? 一样),我觉得不要使用 file_get_contents 获取远程数据(在该函数的官方页评论里,你会看到各种各样的相同功能的封装、弃用 PECL OAuth 比较好,虽然随着时间的流逝这个问题最终会被修正

编译也可以解决,我在虚拟机了编译了份 ./configure --disable-all --with-curl --with-curlwrappers,确认发的是 HTTP 1.1 了,但 with-curlwrappers 参数的解释是 EXPERIMENTAL: Use cURL for url streams

第一次见如何用 tcpdump,在调试这个问题时,可以用

sudo tcpdump -A host www.163.com and 'tcp[20:4] = 0x47455420'

前者是监听的域名,“and”后面的大概可以理解为条件 substr($line, 20, 4) == pack('H*', '47455420')

建议继续学习:

  1. HTTPS, SPDY和 HTTP/2性能的简单对比    (阅读:15647)
  2. 浅析http协议、cookies和session机制、浏览器缓存    (阅读:15477)
  3. 从输入 URL 到页面加载完成的过程中都发生了什么事情?    (阅读:14224)
  4. HTTP协议Keep-Alive模式详解    (阅读:10341)
  5. Oracle Database Firewall - 数据库防火墙    (阅读:6260)
  6. 各种浏览器审查、监听http头工具介绍    (阅读:6021)
  7. nginx中对http请求处理的各个阶段分析    (阅读:5821)
  8. nginx上,http状态200响应,PHP空白返回的问题    (阅读:5280)
  9. 你不知道的 HTTP    (阅读:5166)
  10. 计算机网络协议赏析-HTTP    (阅读:4752)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1