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

huangapple go评论78阅读模式
英文:

http.FileServer caching files and serving old versions after edit

问题

在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之后,这个问题仍然存在。到目前为止,我发现清除文件的缓存版本的唯一方法是重新启动运行程序的机器。

我尝试了以下方法:

  • 在Windows / Ubuntu / OSX 10.8.5上执行程序
  • 浏览golang.org/src上的函数/接口链,看看是否在磁盘上缓存了提供的文件

非常感谢您对此的任何帮助。

英文:

Having issues with the http package in the core of go. It appears that the file contents is cached although the Content-Length in the response body is correct. To demonstrate here is a simplified version of the application I am writing.

package main

import (
    &quot;fmt&quot;
    &quot;net/http&quot;
)

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

Now suppose we have a very simple html page:

&lt;!doctype html&gt;
&lt;html&gt;
&lt;body&gt;
    &lt;p&gt;Hello there&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;

I execute the go program and access http://localhost:8080 in the browser to be presented with:

Hello there

Checking the response headers I can see the following:

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

Now I edit the html file so the &lt;p&gt; tag contains Hello there everyone and reload the page. I get the following:

Hello there

Again looking at the response headers I get

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

So the Content-Length has changed as well as last modified but not the actual file content delivered by the http.FileServer handler. This issue happens even after closing the program down and doing go run src/.../main.go. The only way I have found so far to clear the apparently cached version of the file is to reboot the machine the program is running on.

I have tried the following:

  • Executing program on win / ubuntu / osx 10.8.5
  • Going through the chain of functions / interfaces on golang.org/src to see if the served file is cached on disk anywhere

Any help with this would be very much appreciated.

答案1

得分: 15

好的,以下是翻译好的内容:

好的,经过几周的忽视和继续前进,我终于找出了问题所在。

为了保持我的主要计算机相对未定制化,我使用 Vagrant 来开发使用 golang、nodejs 和 php 的应用程序。似乎在 Virtual Box 共享上运行 go 应用程序,并将所有 html 文件存储在该共享上会导致此问题。

为了证明这一点,我启动了一个 Vagrant 虚拟机,并将文件从 /vagrant 共享目录复制到 /home/vagrant/testing/,然后复制了之前列出的所有操作。这样问题就消失了。

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

英文:

Ok, so after a few weeks of ignoring the problem and moving on I have finally worked out what the issue is.

In order to leave my main computer fairly uncustomised I use Vagrant to develop applications using golang, nodejs and php. It appears that running a go application on a Virtual Box share with all the html files stored on that share causes this issue.

To prove this I span up a Vagrant box and copied the files from the /vagrant shared directory to /home/vagrant/testing/, then replicated all the previously listed actions. This made the problem disappear.

So in other words, don't use a Virtual Box shared folder to host files intended for use in a http.FileServer method.

答案2

得分: 2

直到VirtualBox解决了这个问题,我创建了一个go文件,可以将其放入项目中以禁用当前进程的sendfile支持,go http包将会回退到io.Copy。也可以通过对boot2docker进行一些小的docker配置更改来实现。

https://github.com/wader/disable_sendfile_vbox_linux

使用更新版本的firejail,您可以使用以下命令执行相同的操作:

firejail --seccomp.enotsup=sendfile ./program
英文:

Until VirtualBox has fixed the issue I made a go file that can be dropped into a project to disable sendfile support for the current process, go http package will then fallback to io.Copy. Also works with boot2docker with some small docker config changes.

https://github.com/wader/disable_sendfile_vbox_linux

With newer versions of firejail you can do the same thing using:

firejail --seccomp.enotsup=sendfile ./program

答案3

得分: 1

如果你使用某种代理,那可能是问题所在。一些代理会缓存经常使用的文件(通常只有.js、.css等,但通常不包括.html)和IP地址。如果服务器在你的本地计算机上,尝试使用localhost127.0.0.1而不是IP地址,这样请求就不会经过代理。如果不是这种情况,你需要配置或禁用代理以访问网站的最新版本。我不知道这种情况有多常见,但这可能是问题所在。

英文:

If you use some kind of an proxy, that would be the problem. Some proxies cache frequently used files (usually only .js, .css etc., but usually not .html) and ip addresses. If the server is on your local computer, try to use localhost or 127.0.0.1 instead of an ip address, so the request doesn't go trough the proxy. If it's not you have to configure or disable the proxy to access the newest version of the website. I don't know how common this is but, it would be the problem.

答案4

得分: 0

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

英文:

This can be a client issue, what browser are you using ?
Maybe you could try different browsers, curl, wget etc...

huangapple
  • 本文由 发表于 2013年12月20日 19:05:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/20702221.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定