Golang. Czego użyć? http.ServeFile(..) lub http.FileServer(..)?

Jestem trochę zdezorientowany. Wiele przykładów pokazuje użycie obu: http.ServeFile(..) i http.FileServer(..), ale wydaje się, że mają one bardzo zbliżoną funkcjonalność. Nie znalazłem również informacji o tym, jak ustawić niestandardowy program obsługi NotFound.

// This works and strip "/static/" fragment from path
fs := http.FileServer(http.Dir("static"))
http.Handle("/static/", http.StripPrefix("/static/", fs))

// This works too, but "/static2/" fragment remains and need to be striped manually
http.HandleFunc("/static2/", func(w http.ResponseWriter, r *http.Request) {
    http.ServeFile(w, r, r.URL.Path[1:])
})

http.ListenAndServe(":8080", nil)

Próbowałem odczytać kod źródłowy i oba używają serveFile(ResponseWriter, *Request, FileSystem, string, bool) podstawowej funkcji. Jednak http.FileServer zwraca fileHandler własną metodą ServeHTTP() i przed podaniem pliku (np. path.Czyste()).

Po co więc ta separacja? Która metoda lepiej użyć? Jak Mogę ustawić niestandardową obsługę NotFound, na przykład, gdy żądany plik nie został znaleziony?
 23
Author: Timur Fayzrakhmanov, 2015-03-01

1 answers

Główna różnica polega na tym, że http.FileServer skutecznie odwzorowuje prawie 1: 1 prefiks HTTP z systemem plików. W prostym języku angielskim serwuje całą ścieżkę katalogu. i wszystkie jego dzieci.

Powiedzmy, że masz katalog o nazwie /home/bob/static i masz taką konfigurację:

fs := http.FileServer(http.Dir("/home/bob/static"))
http.Handle("/static/", http.StripPrefix("/static", fs))

Twój serwer będzie przyjmował żądania np. /static/foo/bar i obsługiwał cokolwiek jest na /home/bob/static/foo/bar (lub 404)

Natomiast ServeFile jest pomocnikiem niższego poziomu, który może być użyty do zaimplementowania czegoś podobnego do FileServer, lub zaimplementować własną ścieżkę i dowolną ilość rzeczy. Po prostu pobiera nazwany plik lokalny i wysyła go przez połączenie HTTP. Sam w sobie nie będzie obsługiwał całego prefiksu katalogu (chyba że napisałeś obsługę podobną do FileServer)

Uwaga serwowanie systemu plików naiwnie jest potencjalnie niebezpieczną rzeczą (są potencjalnie sposoby na wyrwanie się z zakorzenionego drzewa) dlatego polecam, chyba że naprawdę wiesz to, co robisz, użyj http.FileServer i http.Dir, ponieważ zawierają kontrole, aby upewnić się, że ludzie nie mogą wydostać się z FS, co ServeFile nie.

dodatek Na twoje drugie pytanie, Jak zrobić niestandardową obsługę NotFound, niestety, nie można łatwo odpowiedzieć. Ponieważ jest to wywołane z wewnętrznej funkcji serveFile jak zauważyłeś, nie ma super łatwego miejsca, aby się do tego włamać. Są potencjalnie pewne podstępne rzeczy, takie jak przechwytywanie odpowiedzi własną ResponseWriter, która przechwytuje Kod odpowiedzi 404, ale zostawię to ćwiczenie Tobie.

 44
Author: Crast,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-18 08:55:01