2017-09-25 1 views
1

J'utilise http.FileServer dans Go pour servir un fichier statique dans un répertoire.Répertoire énumérant les mauvais liens dans golang http.FileServer()

Voici comment je la carte à l'aide de MUX comme routeur:

r.PathPrefix("/download").Handler(http.StripPrefix("/download", http.FileServer(http.Dir(dirPath)))).Methods("GET") 

dirPath est un chemin absolu d'un répertoire dans mon système de fichiers.

Maintenant, il semble fonctionner très bien en demandant l'inscription à l'annuaire avec localhost: 8080/téléchargement, car elle retourne une page comme celle

<pre> 
<a href="a.xml">a.xml</a> 
<a href="b.xml">b.zip</a> 
</pre> 

Malheureusement, les liens sont rompus parce que je les attends à être mis en correspondance, pour exemple à localhost:8080/download/a.xml, tandis que le serveur de fichiers les mappe à localhost:8080/a.xml.

Comment puis-je faire en sorte que ma liste de répertoires conserve le préfixe de chemin /download dans les liens?

Répondre

2

Le problème est le modèle avec lequel vous enregistrez votre gestionnaire: "/download".

Il y a 2 problèmes avec elle:

  1. Les URL générées sont fausses parce que le gestionnaire renvoyé par la fonction http.FileServer() génère relatives URL aux fichiers et sous-dossiers; par rapport au dossier racine passé à http.FileServer(), et si votre page est disponible sous le chemin /download, une URL relative comme href="a.xml" sera résolue à /a.xml, et non à /download/a.xml.

  2. Même si les URL sont correctes, les fichiers ne seront pas diffusés car les requêtes ne seront pas acheminées vers votre gestionnaire (vers le gestionnaire de serveur de fichiers). Vous devez ajouter une barre oblique, car "/download" correspond uniquement à ce chemin unique, et pas tous les chemins commençant par ce chemin. Ajoutez une barre oblique finale: "/download/" et la sous-arborescence racine /download/*.

La solution est donc:

r.PathPrefix("/download/").Handler(
    http.StripPrefix("/download", http.FileServer(http.Dir(dirPath))), 
).Methods("GET") 

Ceci est documenté à http.ServeMux:

Patterns nom fixe, chemins enracinés, comme "/favicon.ico", ou sous-arbres enracinés, comme "/ images /" (notez la barre oblique).

Notez que même si nous sommes maintenant en utilisant le chemin enregistré "/download/", les utilisateurs ne sont pas tenus de taper la barre oblique dans le navigateur, comme laissant que le serveur envoie une redirection vers le chemin qui se termine par une barre oblique Cela arrivera automatiquement. Ceci est également documenté à http.ServeMux:

Si un sous-arbre a été enregistré et une demande est reçue nommant la racine de sous-arbre sans son slash, ServeMux redirige cette demande à la racine du sous-arbre (en ajoutant la barre oblique de fin). Ce comportement peut être remplacé par un enregistrement distinct pour le chemin sans la barre oblique finale. Par exemple, en enregistrant "/ images /", ServeMux redirige une requête pour "/ images" vers "/ images /", sauf si "/ images" a été enregistré séparément.

Lire question relative: Go web server is automatically redirecting POST requests

Voici une application simple serveur de fichiers en utilisant uniquement la bibliothèque standard:

http.Handle("/dl/", 
    http.StripPrefix("/dl", http.FileServer(http.Dir("/home/bob/Downloads"))), 
) 
panic(http.ListenAndServe("localhost:8080", nil)) 
+0

Vous avez raison. L'appelant est-il obligé de taper la barre oblique finale dans l'URL: localhost: 8080/download /? –

+0

@AndreaCastello Non, ce n'est pas nécessaire, car le serveur enverra une redirection et le navigateur suivra automatiquement. Voir la réponse éditée. Essayez-le vous-même. – icza

+0

@AndreaCastello S'il vous plaît voir la réponse révisée, ajouté des explications sur les mauvaises URL. – icza