2013-12-20 14 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ページを持っていると仮定します

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

私が提示するブラウザに行くプログラムやアクセス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 

<p>タグにHello there everyoneが含まれるようにhtmlファイルを編集し、ページをリロードします。私は

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ハンドラによって配信取得

Hello there 

が再び応答ヘッダを見て:私は、次を得ます。この問題は、プログラムを終了してgo run src/.../main.goを行っても発生します。明らかにキャッシュされたバージョンのファイルをクリアするために今まで見つかった唯一の方法は、プログラムが実行されているマシンを再起動することです。

私は次のことを試してみました:

  • 勝利/ Ubuntuの/ OSX 10.8.5
  • が務めたファイルかどうかを確認するためにgolang.org/srcの機能/インターフェースの連鎖を通って行く上でプログラムを実行しますどこのディスクにもキャッシュされています

これについてのお手伝いをさせていただきます。

+0

Webブラウザまたはコマンドラインツールを使用していますか? – Javier

+0

入力いただきありがとうございます、コメントをお読みください。私は、いくつかのWebブラウザ、コマンドラインツール、Windows、Linux、Mac上でgoサーバを実行することで動作を再現しました。 – onmylemon

+0

このバージョンのgo go go2.2 darwin/amd64を使用して問題を再現できませんでした。 – Javier

答えて

14

問題を無視してから数週間後、私は最終的に問題点を解決しました。

私のメインコンピュータをかなりカスタマイズしないために、私はVagrantを使ってgolang、nodejs、phpを使ってアプリケーションを開発しています。その共有に格納されているすべてのhtmlファイルでVirtual Box共有上のgoアプリケーションを実行すると、この問題が発生するようです。

これを証明するために、私はバゲッジボックスをスパンアップし、/ vagrant共有ディレクトリから/ home/vagrant/testing /にファイルをコピーしてから、前述のすべてのアクションを複製しました。これは問題を消した。

つまり、http.FileServerメソッドで使用するファイルをホストするためにVirtual Box共有フォルダを使用しないでください。

+5

これはVirtualBoxの問題で、sendfile()を使用しています(net/httpが内部で使用しています)。https://abitwiser.wordpress.com/2011/02/24/virtualbox-hates-sendfile/ – kitsune

+0

この問題が発生しましたドッカーのボリュームを使用して問題を解決します。 – threeve

0

これはクライアントの問題ですが、どのブラウザを使用していますか? 多分、さまざまなブラウザ、カール、wgetなどを試すことができます。

+0

入力してくれてありがとう、私はUbuntu/os10.8.5/winとie10/11でchromeとffを試しました。 curl/wgetでは試していませんが、すべてのブラウザ/ osの組み合わせで失敗した場合はそれほど重要ではありません。 – onmylemon

+0

ブラウザは、再起動とシステムの再起動の間に応答をキャッシュできますが、wgetは使用できません。 – mechmind

+0

こんにちは、私はそれを理解しています。私は今wgetでテストしており、前と同じ問題が存在します。私は、いくつかのブラウザを試してみるとブラウザの問題ではないと確信していました.HTMLファイルを編集する間にキャッシュを完全にクリアしました。 – onmylemon

1

何らかの種類のプロキシを使用すると問題になります。一部のプロキシは頻繁に使用されるファイルをキャッシュします(通常は.js、.cssなどですが、通常は.htmlではありません)。サーバーがローカルコンピュータ上にある場合は、IPアドレスの代わりにlocalhostまたは127.0.0.1を使用して、要求がプロキシを通過しないようにしてください。そうでない場合は、ウェブサイトの最新バージョンにアクセスするためにプロキシを設定または無効にする必要があります。私はこれがどれほど共通しているのかは分かりませんが、問題になるでしょう。

+0

ありがとうございました。サーバーがローカルマシン上で実行されているプロキシはありません(そのうちのどれか、Mac、Windows PC、およびubuntu PCを試しました)。この問題は、クロスブラウザ、コマンドライン(wgetなど)、およびVMや物理マシン上のいくつかの異なるマシン(Windows、Mac、Linux)上で実行されるgoプログラムで複製されます。 – onmylemon

2

VirtualBoxで問題が修正されるまで、プロジェクトにドロップして現在のプロセスのsendfileサポートを無効にすることができるgoファイルを作成するまで、httpパッケージはio.Copyにフォールバックします。また、いくつかの小さなドッカー設定の変更でboot2dockerで動作します。

あなたが使用して同じことを行うことができます firejailの新しいバージョンで

https://github.com/wader/disable_sendfile_vbox_linux

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

素晴らしい、正確な問題を修正!私はこの問題が長い間vboxsfにあることを知っていました。これは実質的にWinホスト+ Linuxゲストの開発を使用不可能にしています。バグがどれくらいの間存在し、修正されていないのかは信じられないほどです。 –

+0

ニース。ドッカーMac/Windowsを使用して開発することが可能な場合は、もうハックする必要はないと思う –

関連する問題