1

这是一个奇怪的问题。我们最近在我们的代码中发现了一个 3 个月大的错误,我们在 print_r 之后发布了一个 302 重定向标头。结果,浏览器将接收到字符串,而不是重定向到下一页。

这个 print_r 已经投入生产了很长时间,没有人提到它,这让我们相信这是生产和开发上的配置差异。最新的更改是对 IPtables 的更改,当我们恢复更改时,它似乎解决了问题。

奇怪的是,我们不能为了我们自己的启迪而重现这个问题。这让我想到了一个问题,IPtables 甚至可以影响 302 重定向吗?更不用说,关心数据是否在标头之前发送?根据我的研究,没有,但我想先 ping 无所不知的人。

几天前更改 IPtables 的人(我们恢复并以某种方式解决了问题)说这些是有问题的条目:

ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED

第一个条目是什么,第二个条目是他将其更改为破坏站点的内容。恢复到第一个条目“已修复”。首先,我知道,超级安全……这是一个本地开发盒。

我尝试卷曲 url(现在可以正常工作,因为我们无法破坏它)以查看我能看到的内容,并且我注意到了这个问题的第二部分。curl 在 print_r 进入之前注册* Closing connection #0,当它进入时,它会在我的提示下进入:

< HTTP/1.1 302 Found
< Date: Thu, 18 Apr 2013 16:14:55 GMT
< Server: Apache/2.2.3 (Red Hat)
< X-Powered-By: PHP/5.3.3
< location: app.php?cart_item_id=1234567
< X-UA-Compatible: IE=Edge
< Content-Length: 17
< Connection: close
< Content-Type: text/html; charset=UTF-8
<
* Closing connection #0
<pre>before</pre>[user@localhost ~]$

是的。有什么想法吗?我的意思是,现在一切都很好,我只是想知道为什么...

Bass:好的,但是当我 curl 时,yahoo.com 我得到了这个:

[user@localhost~]$ curl yahoo.com -v
* About to connect() to yahoo.com port 80 (#0)
*   Trying 206.190.36.45...
* connected
* Connected to yahoo.com (206.190.36.45) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.24.0 (x86_64-redhat-linux-gnu) libcurl/7.24.0 NSS/3.13.5.0 zlib/1.2.5 libidn/1.18 libssh2/1.2.2
> Host: yahoo.com
> Accept: */*
>
< HTTP/1.1 301 Redirect
< Date: Fri, 19 Apr 2013 13:28:10 GMT
< Connection: close
< Server: YTS/1.20.13
< Cache-Control: no-store
< Content-Type: text/html
< Content-Language: en
< Location: http://www.yahoo.com/
< Content-Length: 211
<
<HEAD><TITLE>Redirect</TITLE></HEAD>
<BODY BGCOLOR="white" FGCOLOR="black">
<FONT FACE="Helvetica,Arial"><B>
 "<em>http://www.yahoo.com/</em>".<p></B></FONT>

<!-- default "Redirect" response (301) -->
</BODY>
* Closing connection #0
[user@localhost~]$

我得到了* Closing connection #0毕竟内容。有什么区别?

至于 iptables 规则,在该规则之后还有其他允许,端口 80 等。所以我猜……呃……嗯,我不知道……

4

2 回答 2

1

正如巴斯所说,标题将在 print_r 之前发送。而且,iptables 不会做“深度包检测”,所以它看不到你的消息内容。

两行的区别在于,第一行允许从任何 ip 到任何 ip 的所有数据包,第二行仅允许已建立连接的数据包。

如果没有规则允许数据包进行新连接。没有一个数据包会被认为允许建立连接的规则流动。(有关 连接跟踪的更多信息?)

于 2013-04-19T05:25:58.433 回答
0

请参阅http://php.net/manual/en/function.print-r.php除非您将返回参数设置为 true,否则 print-r 的结果将被缓冲。所以 print_r 不会触发发送 HTTP 标头。然后阅读http://php.net/manual/en/function.header.php:无论实际的 header() 调用是否是第一个,HTTP 状态标题行将始终是第一个发送到客户端的。除非已经发送了 HTTP 标头,否则可以随时通过使用新状态行调用 header() 来覆盖状态。

于 2013-04-18T21:06:54.940 回答