http.FileServer在编辑后缓存文件并提供旧版本

时间:2013-12-20 11:05:10

标签: http go

在go的核心中遇到http包的问题。虽然响应正文中的Content-Length是正确的,但似乎缓存了文件内容。这里演示的是我正在编写的应用程序的简化版本。

package main

import (
    "fmt"
    "net/http"
)

func main() {
    http.Handle("/", http.FileServer(http.Dir("./www/")))
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        fmt.Println(err)
    }
}

现在假设我们有一个非常简单的html页面:

<!doctype html>
<html>
<body>
    <p>Hello there</p>
</body>
</html>

我执行go程序并在浏览器中访问http://localhost:8080以显示:

Hello there

检查响应标题我可以看到以下内容:

Status Code:200 OK
Accept-Ranges:bytes
Content-Length:68
Content-Type:text/html; charset=utf-8
Date:Fri, 20 Dec 2013 10:04:03 GMT
Last-Modified:Fri, 20 Dec 2013 10:03:32 GMT

现在我编辑html文件,以便<p>标记包含Hello there everyone并重新加载页面。我得到以下内容:

Hello there

再次查看我得到的响应标题

Status Code:200 OK
Accept-Ranges:bytes
Content-Length:77
Content-Type:text/html; charset=utf-8
Date:Fri, 20 Dec 2013 10:04:34 GMT
Last-Modified:Fri, 20 Dec 2013 10:04:14 GMT

因此Content-Length已更改以及上次修改但不是http.FileServer处理程序提供的实际文件内容。即使在关闭程序并执行go run src/.../main.go之后,也会出现此问题。到目前为止,我发现清除文件的明显缓存版本的唯一方法是重启程序运行的机器。

我尝试了以下内容:

  • 在win / ubuntu / osx 10.8.5
  • 上执行程序
  • 浏览golang.org/src上的函数/接口链,看看服务文件是否缓存在磁盘上

非常感谢任何帮助。

4 个答案:

答案 0 :(得分:14)

好的,所以在几个星期之后忽略了这个问题并继续前进我终于解决了问题所在。

为了让我的主计算机相当不自定,我使用Vagrant使用golang,nodejs和php开发应用程序。看来,在Virtual Box上运行一个go应​​用程序与该共享上存储的所有html文件会导致此问题。

为了证明这一点,我跨越了一个Vagrant框并将文件从/ vagrant共享目录复制到/ home / vagrant / testing /,然后复制了之前列出的所有操作。这使问题消失了。

换句话说,不要使用Virtual Box共享文件夹来托管打算在http.FileServer方法中使用的文件。

答案 1 :(得分:2)

在VirtualBox修复了问题之前,我做了一个go文件,可以将其放入项目中以禁用当前进程的sendfile支持,然后http包将回退到io.Copy。也适用于boot2docker和一些小的docker配置更改。

https://github.com/wader/disable_sendfile_vbox_linux

使用较新版本的firejail,您可以使用以下方法执行相同的操作:

firejail --seccomp.enotsup=sendfile ./program

答案 2 :(得分:1)

如果你使用某种代理,那就是问题所在。一些代理缓存经常使用的文件(通常只有.js,.css等,但通常不是.html)和ip地址。如果服务器位于本地计算机上,请尝试使用localhost127.0.0.1而不是IP地址,因此请求不会通过代理。如果不是,您必须配置或禁用代理才能访问最新版本的网站。我不知道这有多常见但是,这将是问题所在。

答案 3 :(得分:0)

这可能是客户端问题,您使用的浏览器是什么? 也许你可以尝试不同的浏览器,卷曲,wget等......