2015-03-01 13 views
23

Jestem trochę zdezorientowany. Wiele przykładów pokazuje użycie obu: http.ServeFile(..) i http.FileServer(..), ale wydaje się, że mają bardzo zbliżoną funkcjonalność. Również nie znalazłem żadnych informacji o tym, jak ustawić niestandardową obsługę NotFound.Golang. Co używać? http.ServeFile (..) lub http.FileServer (..)?

// 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ć kodu źródłowego i oba z nich korzystać serveFile(ResponseWriter, *Request, FileSystem, string, bool) podstawową funkcję. Jednak http.FileServer zwraca fileHandler za pomocą własnej metody ServeHTTP() i wykonuje pewne prace przygotowawcze przed udostępnieniem pliku (np. Path.Clean()).

Po co więc ta separacja? Którą metodę lepiej zastosować? I jak mogę ustawić niestandardową obsługę NotFound, na przykład, gdy żądany plik nie zostanie znaleziony?

+0

Największą różnicą jest to, że 'http.FileServer' to' http.Handler', podczas gdy 'http.ServeFile' nie jest. –

+0

Dzięki, wiem o tym, ale to nie sprawia, że ​​sytuacja jest dla mnie lepsza) –

Odpowiedz

37

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

Załóżmy, że katalog nazywa /home/bob/static i trzeba było tę konfigurację:

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

Serwer zajęłoby żądania np /static/foo/bar i służyć to, co jest w /home/bob/static/foo/bar (lub 404)

Natomiast ServeFile jest pomocnikiem poziom niższy, które mogą być wykorzystywane do realizacji czegoś podobnego do serwera plików lub zaimplementować własną ścieżkę munging potencjalnie, a dowolną liczbę rzeczy. Po prostu pobiera nazwany plik lokalny i wysyła go przez połączenie HTTP. Sam w sobie, nie będzie służyć całe prefiks katalogów (chyba, że ​​napisał, że zrobił kilka obsługi odnośnika podobnego do serwera plików)

UWAGA obsługujących system plików naiwnie jest potencjalnie niebezpieczna rzecz (istnieją potencjalne sposoby rozkładają z drzewa zrootowanego), dlatego polecam, jeśli naprawdę nie wiesz, co robisz, używaj http.FileServer i http.Dir, ponieważ zawierają one sprawdzenia, aby upewnić się, że ludzie nie mogą wyrwać się z FS, którego nie ma.

Dodatek Twoje drugie pytanie, jak zrobić niestandardowy program obsługi NotFound, niestety nie jest łatwo odpowiedzieć. Ponieważ jest to wywoływane z funkcji wewnętrznej serveFile, jak zauważyłeś, nie ma tu super łatwego miejsca, w którym mógłby się do tego włamać. Potencjalnie niektóre podstępne rzeczy, takie jak przechwytywanie odpowiedzi z własnego ResponseWriter, które przechwytuje kod odpowiedzi 404, ale zostawi to ćwiczenie dla Ciebie.

+1

Bardzo, bardzo dobrze! Dokładnie to chcę usłyszeć! Wielkie dzięki!) Mój angielski nie jest językiem ojczystym, więc mógłbyś mi powiedzieć, co znaczy "munging"?) –

+2

Munging: https://en.wikipedia.org/wiki/Data_wprowadzanie ... więc w zasadzie oznacza tworzenie własnych mapowanie ścieżek –

+0

Albo nawet https://en.wikipedia.org/wiki/Mung_(computer_term) "Czasami używa się niejasnych kroków do transformacji danych, które nie są jeszcze jasne dla rozmówcy. [2] Typowe operacje wymazywania obejmują usuwanie interpunkcja lub tagi HTML, parsowanie danych, filtrowanie i transformacja. " – Crast