Http.FileServer кэширует файлы и обслуживает старые версии после редактирования

Проблемы с пакетом http в ядре go. Похоже, что содержимое файла кэшируется, хотя длина содержимого в теле ответа правильная. Чтобы продемонстрировать здесь, это упрощенная версия приложения, которое я пишу.

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. Единственный способ, которым я нашел, чтобы очистить, по-видимому, кэшированную версию файла, - перезагрузить компьютер, на котором работает программа.

Я пробовал следующее:

  • Выполнение программы по win/ubuntu/osx 10.8.5
  • Переходя через цепочку функций/интерфейсов на golang.org/src, чтобы проверить, сохранен ли кеш файл на диске в любом месте

Любая помощь с этим будет очень оценена.

Ответ 1

Хорошо, поэтому через несколько недель, не обращая внимания на проблему и двигаясь дальше, я наконец-то выяснил, в чем проблема.

Чтобы оставить мой основной компьютер довольно нестандартным, я использую Vagrant для разработки приложений с использованием golang, nodejs и php. Похоже, что запуск приложения go на виртуальном блоке совместно со всеми html файлами, хранящимися на этом ресурсе, вызывает эту проблему.

Чтобы доказать это, я разворачиваю окно Vagrant и копировал файлы из /vagrant shared directory в /home/vagrant/testing/, а затем реплицировал все ранее перечисленные действия. Это заставило проблему исчезнуть.

Иными словами, не используйте общую папку Virtual Box для размещения файлов, предназначенных для использования в методе http.FileServer.

Ответ 2

До тех пор, пока VirtualBox не устранит проблему, я сделал файл go, который можно удалить в проект, чтобы отключить поддержку sendfile для текущего процесса, и затем http-пакет отменится на io.Copy. Также работает с boot2docker с небольшими изменениями конфигурации докеры.

https://github.com/wader/disable_sendfile_vbox_linux

С более новыми версиями firejail вы можете сделать то же самое, используя:

firejail --seccomp.enotsup=sendfile ./program

Ответ 3

Если вы используете какой-то прокси-сервер, это будет проблемой. Некоторые прокси кэшируют часто используемые файлы (обычно только .js,.css и т.д., Но обычно не .html) и IP-адреса. Если сервер находится на вашем локальном компьютере, попробуйте использовать localhost или 127.0.0.1 вместо ip-адреса, поэтому запрос не проходит через прокси-сервер. Если вам не нужно настраивать или отключать прокси для доступа к новейшей версии веб-сайта. Я не знаю, насколько это распространено, но это проблема.

Ответ 4

Это может быть проблема с клиентом, какой браузер вы используете? Возможно, вы можете попробовать разные браузеры, завитки, wget и т.д.