Golang. Ce qu'il faut utiliser? http.ServeFile(..) ou http.Serveur de fichiers(..)?

je suis un peu confus. La plupart des exemples montrent l'utilisation des deux: http.ServeFile(..) et http.FileServer(..), mais ils semblent avoir une fonctionnalité très proche. En outre, je n'ai trouvé aucune information sur la façon de définir custom NotFound handler.

// 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)

j'ai essayé de lire le code source et les deux utilisent serveFile(ResponseWriter, *Request, FileSystem, string, bool) fonction sous-jacente. Cependant http.FileServer retour fileHandler avec sa ServeHTTP() méthode et faire un peu de travail de préparation avant de servir le fichier (par exemple chemin.Propre.))(

alors pourquoi en avoir besoin la séparation de corps? La méthode à utiliser le mieux? Et comment définir custom NotFound handler, par exemple lorsque le fichier demandé n'est pas trouvé?

23
demandé sur Timur Fayzrakhmanov 2015-03-01 15:38:50

1 réponses

La principale différence est que http.FileServer fait effectivement presque 1:1 de mappage D'un préfixe HTTP avec un système de fichiers. En anglais simple, il sert jusqu'à un chemin de répertoire entier. et tous ses enfants.

Dites que vous aviez un répertoire nommé /home/bob/static et vous avez eu cette configuration:

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

votre serveur accepterait des requêtes pour par exemple /static/foo/bar et servir ce qui est à /home/bob/static/foo/bar (ou 404)

par contraste, le ServeFile est un niveau inférieur helper qui peut être utilisé pour implémenter quelque chose de similaire à FileServer, ou implémenter votre propre chemin munging potentiellement, et n'importe quel nombre de choses. Il prend simplement le fichier local nommé et l'envoie via la connexion HTTP. Par lui-même, il ne servira pas un préfixe de répertoire entier (sauf si vous avez écrit un handler qui a fait une recherche similaire à FileServer)

NOTE servir naïvement un système de fichiers est une chose potentiellement dangereuse (il y a potentiellement des moyens de sortir de l'arbre des racines) d'où I recommandez que sauf si vous vraiment savez ce que vous faites, utilisez http.FileServer et http.Dir comme ils comprennent des vérifications pour s'assurer que les gens ne peuvent pas sortir du FS, qui ServeFile doesn'T.

Addendum Malheureusement, il n'est pas facile de répondre à votre question secondaire, comment faire un handler Personnalisé non trouvé. Parce que cela est appelé de la fonction interne serveFile comme vous l'avez remarqué, il n'y a pas d'endroit très facile pour y pénétrer. Il y a potentiellement quelques sournois des choses comme intercepter la réponse avec votre propre ResponseWriter qui intercepte le code de réponse 404, mais je vous laisse cet exercice.

44
répondu Crast 2017-05-18 08:55:01