2013-12-20 60 views
11

在go的核心中存在http包的问题。尽管响应正文中的Content-Length是正确的,但看起来文件内容已被缓存。这里演示的是我正在编写的应用程序的简化版本。http.FileServer缓存文件并在编辑后提供旧版本

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页面:

Hello there 

检查响应:

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

我执行的围棋程序,并在浏览器中访问http://localhost:8080与呈现我可以看到以下内容:

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接口,看是否送达文件随时随地缓存在磁盘上

    任何与此有关的帮助将非常感激。

  • +0

    您使用的网络浏览器或命令行工具? – Javier

    +0

    感谢您的意见,请阅读评论。我用几个Web浏览器,命令行工具以及在Windows,Linux和Mac上运行go服务器来复制行为。 – onmylemon

    +0

    我无法用这个版本'go version go1.2 darwin/amd64'重现问题。 – Javier

    回答

    14

    好吧,所以在忽视问题并继续前进几周后,我终于找出了问题所在。

    为了让我的主电脑相当不习惯我使用Vagrant来开发使用golang,nodejs和php的应用程序。看起来,在Virtual Box共享上运行一个去应用程序共享存储在该共享上的所有html文件会导致此问题。

    为了证明这一点,我跨越了一个流浪箱,并从/游民共享目录将文件复制到/ home /流浪者/测试/,然后复制所有先前列出的行动。这使问题消失。

    所以,换句话说,不要使用虚拟箱共享文件夹主办旨在用于http.FileServer方法使用的文件。

    +5

    这是VirtualBox和使用的sendfile()(其中网/ HTTP内部使用)问题,请参阅https://abitwiser.wordpress.com/2011/02/24/virtualbox-hates-sendfile/ – kitsune

    +0

    我现在遇到这个使用码头卷也是一个问题。 – threeve

    0

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

    +0

    感谢您的输入,我已经试过铬和FF在Ubuntu/os10.8.5/WIN和IE10/11。没有使用curl/wget尝试过,但如果使用所有这些浏览器/操作系统组合失败,则没有多大意义。 – onmylemon

    +0

    浏览器可以在重启和系统重启之间缓存响应,但wget不会。 – mechmind

    +0

    嗨,yeup我明白这一点。我现在已经用wget进行了测试,并且与之前一样存在相同的问题。我很确定它不会像浏览器那样成为浏览器问题,在编辑所提供的html文件之间完全清除缓存。 – onmylemon

    1

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

    +0

    感谢您的意见。没有代理服务器在本地机器上运行(我已经尝试过一个mac,一台windows pc和一台ubuntu pc)。这个问题被复制跨浏览器,在命令行(wget的,等等),并在虚拟机和物理机上的几个不同的机器(在Windows,Mac,Linux)的运行围棋程序。 – onmylemon

    2

    直到VirtualBox解决了问题我做了一个go文件,可以放到一个项目中去关闭当前进程的sendfile支持,去http包然后回退到io.Copy。还可以与boot2docker一起使用一些小的docker配置更改。

    https://github.com/wader/disable_sendfile_vbox_linux

    随着使用的firejail你可以做同样的事情,新的版本:

    firejail --seccomp.enotsup=sendfile ./program 
    
    +0

    太棒了,修正了确切的问题!我已经知道这个问题很长一段时间在vboxsf上,这实际上使Win host + Linux guest上的开发无法使用。这个bug存在多久并且没有修复是令人难以置信的。 –

    +0

    不错。如果你有可能使用docker mac/windows开发,我认为你不需要再破解 –

    相关问题