【问题标题】:Does mod_php honor HEAD requests properly?mod_php 是否正确尊重 HEAD 请求?
【发布时间】:2011-02-05 21:10:38
【问题描述】:

HTTP/1.1 RFC 规定“HEAD 方法与 GET 相同,只是服务器不得在响应中返回消息体。”我知道 Apache 尊重 RFC,但模块不必这样做。我的问题是,mod_php5 是否尊重这一点?

我问的原因是因为我刚刚看到一篇文章说 PHP 开发人员应该自己检查一下:

    if (stripos($_SERVER['REQUEST_METHOD'], 'HEAD') !== FALSE) {
        exit();
    }

我在谷歌上搜索了一秒钟,但没有太多出现,除了一些人说他们在收到 HEAD 请求后尝试奇怪的事情,比如 mod_rewrite/redirect 和一些像 2002 年那样的旧错误票,声称 mod_php 仍然执行脚本的其余部分默认。所以我只是通过使用 PECL::HTTP 来运行一个快速测试

    http_head('http://mysite.com/test-head-request.php');

同时拥有:

    <?php error_log('REST OF SCRIPT STILL RAN'); ?>

在 test-head-request.php 中查看脚本的其余部分是否仍然执行,但它没有。

我认为这应该足以解决它,但希望获得更多反馈,并可能有助于为任何对此感到疑惑的人消除困惑。因此,如果有人知道他们的头脑(没有双关语) - 或者有他们用于接收 HEAD 请求的任何约定,那就太好了。否则,我稍后会 grep C 源代码并在评论中回复我的发现。谢谢。

【问题讨论】:

    标签: php http mod-php


    【解决方案1】:

    HEAD 方法与 GET 相同 除了服务器不能返回 响应中的消息正文。

    这就是为什么应该执行检查。客户端应该确信 HEAD 请求的处理与发出 GET 一样(数据库连接、处理等)。

    附录:

    表演时

    HEAD /test.php?a=3 HTTP/1.1
    Host: somesite.com
    

    PHP 仍然会用放置在查询字符串中的变量填充 $_GET(和 $_REQUEST),即使它不是 GET 请求。这允许符合 HEAD 定义。

    【讨论】:

    • 是的,如果你把 header('Foo: '.$_GET['header']);错误日志(“测试”);在脚本的顶部,它返回该标头/值和日志。如果将该代码放在 HTML 正文的输出缓冲区中,则两者都不会运行。所以 PHP 似乎不仅不返回消息体,甚至不处理它。我会继续退出;毕竟我的 header() 调用。谢谢
    • @rkulla 底层 PHP 代码始终以与 GET 请求相同的方式执行。如果不是,请检查您的错误日志。
    【解决方案2】:

    我刚刚对一个 PHP 文件进行了快速测试,temp.php,其中包含这部分代码:

    <?php
    
    echo "Hello, World!\n";
    
    die;
    


    向该文件发送 HTTP GET 请求可以让我获得页面内容:

    $ telnet localhost 80
    Trying ::1...
    Trying 127.0.0.1...
    Connected to localhost.
    Escape character is '^]'.
    GET /temp/temp.php HTTP/1.1
    Host: localhost
    
    HTTP/1.1 200 OK
    Date: Thu, 08 Apr 2010 20:17:35 GMT
    Server: Apache/2.2.12 (Ubuntu)
    X-Powered-By: PHP/5.3.2RC2
    Vary: Accept-Encoding
    Content-Length: 14
    Content-Type: text/html
    
    Hello, World!
    


    发送 HTTP HEAD 请求时不会:

    $ telnet localhost 80
    Trying ::1...
    Trying 127.0.0.1...
    Connected to localhost.
    Escape character is '^]'.
    HEAD /temp/temp.php HTTP/1.1
    Host: localhost
    
    HTTP/1.1 200 OK
    Date: Thu, 08 Apr 2010 20:17:50 GMT
    Server: Apache/2.2.12 (Ubuntu)
    X-Powered-By: PHP/5.3.2RC2
    Vary: Accept-Encoding
    Content-Type: text/html
    


    不过,不确定这是否总是正确的......

    我记得有一种情况(前一段时间是 PHP 5.1),我必须在 PHP 代码中测试自己是否收到 GET 或 HEAD 请求。



    编辑:附加测试后

    我刚刚做了另一个测试:我的temp.php 文件现在包含这个:

    <?php
    
    file_put_contents('/tmp/a.txt', $_SERVER['REQUEST_METHOD'], FILE_APPEND);
    var_dump($_SERVER['REQUEST_METHOD']);
    
    die;
    

    发送一个 HTTP HEAD 请求,我得到了这个:

    $ telnet localhost 80
    Trying ::1...
    Trying 127.0.0.1...
    Connected to localhost.
    Escape character is '^]'.
    HEAD /temp/temp.php HTTP/1.1
    Host: localhost
    
    HTTP/1.1 200 OK
    Date: Thu, 08 Apr 2010 20:21:30 GMT
    Server: Apache/2.2.12 (Ubuntu)
    X-Powered-By: PHP/5.3.2RC2
    Vary: Accept-Encoding
    Content-Type: text/html
    
    Connection closed by foreign host.
    

    这里,没有输出。

    但是,查看 /tmp/a.txt 文件:

    $ cat /tmp/a.txt 
    HEAD
    

    所以:服务器没有发送输出并不意味着什么都不做;-)

    【讨论】:

    • 对不起,我应该更清楚...我更关心是否仍会解析 HTML 正文中的任何嵌入式 PHP 代码。请参阅我对 webbiedave 答案的评论。谢谢
    • 我可以用 PHP 5.4 和 apache 确认这是正确的。当您发送头部请求时,它不会运行您的 PHP 代码
    • @JaseWhatson 我认为您的意思是,“当您发送 HEAD 请求时,它确实会运行您的 PHP 代码。”正如这个答案所解释的,执行 PHP 代码和输出响应数据是两件不同的事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-18
    • 2011-12-11
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    相关资源
    最近更新 更多