2013-12-20 1 views
11

http 패키지의 핵심 기능인 go에 문제가 있습니다. 응답 본문의 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 

이제 <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을 수행 한 후에도 발생합니다. 지금까지 파일의 캐시 된 버전을 지우는 유일한 방법은 프로그램이 실행중인 컴퓨터를 재부팅하는 것입니다.

나는 다음과 같은 시도 : 함수의 체인을 통해가는 승리/우분투/OSX 10.8.5

    • 실행 프로그램을/golang.org/src에 대한 인터페이스는 제공 파일이 있는지 확인하기 위해 어디서나 디스크에 캐시됩니다.

    이 도움은 매우 감사하겠습니다.

  • +0

    는 웹 브라우저 또는 명령 줄 도구를 사용하고 있습니까 : 사용하여 같은 일을 할 수 firejail의 최신 버전으로

    https://github.com/wader/disable_sendfile_vbox_linux

    ? – Javier

    +0

    입력 해 주셔서 감사합니다. 의견을 읽어보십시오. 몇 가지 웹 브라우저, 명령 줄 도구 및 Windows, Linux 및 Mac에서 go 서버를 실행하여 동작을 복제했습니다. – onmylemon

    +0

    이 버전의 go go go1.2 darwin/amd64를 사용하여 문제를 재현 할 수 없습니다. – Javier

    답변

    14

    그래, 문제를 무시하고 몇 주 후에 나는 마침내 문제가 무엇인지 해결했습니다.

    내 메인 컴퓨터를 공정하게 사용자 정의하지 않으려면 Vagrant를 사용하여 golang, nodejs 및 php를 사용하는 응용 프로그램을 개발하십시오. 해당 공유에 저장된 모든 html 파일을 사용하여 가상 응용 프로그램을 실행중인 응용 프로그램을 실행하면이 문제가 발생합니다.

    이 것을 증명하기 위해 방황 통을 열고/vagrant 공유 디렉토리의 파일을/home/vagrant/testing /에 복사 한 다음 이전에 나열된 모든 작업을 복제했습니다. 이로 인해 문제가 사라졌습니다.

    즉, http.FileServer 메서드에서 사용할 파일을 호스팅하기 위해 가상 상자 공유 폴더를 사용하지 마십시오.

    +5

    이것은 VirtualBox의 문제이며 sendfile() (net/http가 내부적으로 사용함)을 사용하는 경우 https://abitwiser.wordpress.com/2011/02/24/virtualbox-hates-sendfile/ – kitsune

    +0

    을 참조하십시오. 도커 볼륨을 사용하여 문제를 해결할 수 있습니다. – threeve

    0

    이것은 클라이언트 문제 일 수 있습니다. 어떤 브라우저를 사용하고 있습니까? 어쩌면 다른 브라우저, 컬, wget 등을 시도해 볼 수 있습니다 ...

    +0

    입력 해 주셔서 감사합니다. 우분투/os10.8.5/win 및 ie10/11에서 chrome 및 ff를 사용했습니다. curl/wget으로 시도하지는 않았지만 모든 브라우저/운영 체제 조합에서 실패한 경우에는 많은 점수를 얻지 못했습니다. – onmylemon

    +0

    브라우저는 재시작 및 시스템 재부팅간에 응답을 캐시 할 수 있지만 wget은 없습니다. – mechmind

    +0

    안녕, 여보. 나는 그것을 이해한다. 나는 wget으로 테스트했고 이전과 같은 문제가 존재한다. 나는 여러 브라우저를 시험해 보았을 때 브라우저 문제가되지 않을 것이라고 확신했고, 제공되는 HTML 파일을 편집하는 사이에 캐시를 완전히 지웠다. – onmylemon

    1

    어떤 종류의 프록시를 사용하면 문제가 될 수 있습니다. 일부 프록시는 자주 사용되는 파일 (일반적으로 .js, .css 등. 그러나 일반적으로 .html이 아님)과 IP 주소를 캐시합니다. 서버가 로컬 컴퓨터에있는 경우 IP 주소 대신 localhost 또는 127.0.0.1을 사용해보십시오. 따라서 요청은 프록시를 통과하지 않습니다. 그렇지 않은 경우 웹 사이트의 최신 버전에 액세스하기 위해 프록시를 구성하거나 비활성화해야합니다. 나는 그것이 얼마나 일반적인지는 모르겠지만 문제 일 것입니다.

    +0

    입력 해 주셔서 감사합니다. 서버가 로컬 컴퓨터에서 실행되고있는 프록시는 없습니다 (그 중 Mac, Windows PC 및 우분투 PC). 문제는 크로스 브라우저, 명령 줄 (wget 등), VM 및 실제 컴퓨터의 여러 다른 컴퓨터 (Windows, Mac, Linux)에서 실행되는 go 프로그램으로 복제됩니다. – onmylemon

    2

    VirtualBox가 문제를 해결할 때까지 현재 프로세스에 대한 sendfile 지원을 사용하지 않도록 설정할 수있는 파일을 만들었습니다. http 패키지가 io.Copy으로 대체됩니다. 또한 몇 가지 작은 도커 설정 변경과 함께 boot2docker와 함께 작동합니다.

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

    굉장하고 정확한 문제를 해결했습니다! 문제가 vboxsf에 오랫동안 있다는 것을 알았습니다. 실제로이 문제는 Win 호스트 + Linux 게스트에서 사용할 수 없게 만듭니다. 벌레가 얼마나 오래 있었고 고치지 않았는지 믿을 수 없습니다. –

    +0

    니스. 그것은 도커 맥/윈도우를 사용하여 개발하는 것이 가능하다면 더 이상 해킹해야 할 것 같지 않아요 –

    관련 문제