2013-12-20 90 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開發,我認爲你不需要再破解 –

    相關問題