使用Varnish缓存清空POST请求

时间:2013-08-05 14:44:53

标签: php html apache varnish

所以我在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(在某些)Web浏览器中时,login_auth1.php中的POST将为空。但是当从login_auth1.php再次提交完全相同的表单时,它可以正常工作。可能是导致此错误的原因是什么?如何进一步调试?仅供参考服务器正在运行Varnish

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

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

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

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

2 个答案:

答案 0 :(得分:0)

一个好的和持久的做法,取代你的快速黑客,是不通过以下方式缓存任何帖子请求:

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

答案 1 :(得分:0)

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或for_for_pass。

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