【问题标题】:Empty POST requests with Varnish cache使用 Varnish 缓存的空 POST 请求
【发布时间】:2013-08-05 14:44:53
【问题描述】:

所以我在 html/php 中有一个非常简单的登录表单

login1.php

<?php include('settings.php'); ?>
<!DOCTYPE html>
<html>
<head>
    <title>login</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
    <form id="form1" name="form1" method="post" action="<?=$basehttp;?>/login_auth1.php">
    <input name="ahd_username" type="text" id="ahd_username" size="35" maxlength="255" />
    <input name="ahd_password" type="password" id="ahd_password" size="35" maxlength="35" />
    <input type="submit" name="Submit" value="Login" />
    </form>
</body>
</html>

login_auth1.php

<?php
include('settings.php'); 
print_r($_POST);
print_r(getallheaders());

if(isset($_POST['ahd_username']) && isset($_POST['ahd_password'])){
  //database queries and stuff, send user elsewhere if login correct
}
?>
<!DOCTYPE html>
<html>
<head>
    <title>login</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
    <form id="form1" name="form1" method="post" action="<?=$basehttp;?>/login_auth1.php">
    <input name="ahd_username" type="text" id="ahd_username" size="35" maxlength="255" />
    <input name="ahd_password" type="password" id="ahd_password" size="35" maxlength="35" />
    <input type="submit" name="Submit" value="Login" />
    </form>
</body>
</html>

当运行 login1.php(在某些网络浏览器中)时,login_auth1.php 中的 POST 将为空。但是当再次从 login_auth1.php 提交完全相同的表单时,它工作得很好。这个错误的原因可能是什么?如何进一步调试?仅供参考服务器正在运行Varnish

可以在this textfile 中找到带有某些调用标头的输出链接。

编辑: 现在我的头上没有头发了,但我已经找到了一种“有效”的方法。如果我将我的登录文件合并到一个文件中,将该文件放入单独的文件夹 /login 中,完全删除 action 标签中的 url(因此它将是 action="")并将 Varnish 配置为

if (req.url ~ "/login"){
  set req.backend = mybackend;
  return (pass);
}

它会起作用的。这感觉像是一个非常糟糕的“解决方案”,尤其是在操作标签中删除字符串的部分,但这是我让它工作的唯一方法。我尝试了很多不同的 Varnish 配置,包括返回(管道)。有谁知道如何让它正常工作?或者为什么上面这个奇怪的版本有效?

【问题讨论】:

  • 是否有可能像 GoogleBot 这样的网络爬虫在没有任何 post 参数的情况下访问 action 网址?
  • &lt;?=$basehttp;&gt; 我觉得这可能会导致问题,因为您写的是&gt; 而不是?&gt;。也许有些浏览器解析正确,而其他浏览器正在破坏?
  • Firts van Campen:是的,这是可能的。但这不影响我的会话吗? ಠ_ಠ:Ops,只是论坛中的一个错字。不在运行代码中。
  • 不知道这是否会导致此问题,但您的表单标签未关闭。这样的事情通常会导致浏览器的行为不一致。
  • @MarcelGwerder 另一个错字 - 关闭正在运行的代码。页面验证。

标签: php html apache varnish


【解决方案1】:

一个好的和持久的做法,取代你的快速破解,是不缓存任何帖子请求:

if ( req.request == "POST" ) {
   return (hit_for_pass);
}

【讨论】:

    【解决方案2】:

    Varnish 的标准行为[1](至少在 3.0,debian 中)是将 POST 请求直接传递到后端:

    sub vcl_recv {
    #...
      if (req.request != "GET" && req.request != "HEAD") {
        /* We only deal with GET and HEAD by default */
        return (pass);
      }
    #...
    }
    

    因此,如果未达到默认代码(您在 vcl_recv 中调用 return(xxx)),您应该在自己的 VCL 代码中处理此类请求,按照 Clarence 的建议返回 pass 或 hit_for_pass。

    [1]https://www.varnish-cache.org/docs/3.0/reference/vcl.html#examples

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-20
      • 1970-01-01
      • 2012-09-22
      • 2014-11-25
      • 2012-02-19
      • 2016-12-26
      • 2014-06-17
      • 1970-01-01
      相关资源
      最近更新 更多