2014-09-20 13 views
21
http.Handle("/", http.FileServer(http.Dir("static"))) 

Serve il file html nella directory statica.Go Golang per servire uno specifico file html

C'è qualche modo in cui è possibile specificare il file html da servire?

Qualcosa di simile render_template in Flask

voglio fare qualcosa di simile:

http.Handle("/hello", http.FileServer(http.Dir("static/hello.html"))) 

risposta

27

Forse usando una custom http.HandlerFunc sarebbe stato più facile:

Tranne nel tuo caso, il vostro func sarebbe il http.ServeFile uno, per servire un solo file.

si veda ad esempio "Go Web Applications: Serving Static Files":

Aggiungere il seguente sotto il gestore di casa (vedi sotto):

http.HandleFunc("/static/", func(w http.ResponseWriter, r *http.Request) { 
    http.ServeFile(w, r, r.URL.Path[1:]) 
}) 

Questo sta usando la funzione ServeFile il pacchetto del net/http per servire i nostri contenuti.
Qualsiasi funzione che faccia partire una richiesta con il percorso /static/ verrà gestita da questa funzione.
Una cosa che ho trovato che ho dovuto fare in modo che la richiesta di essere trattati in modo corretto era tagliare il leader ‘/’ con:

r.URL.Path[1:] 

In realtà, non farlo.
questo non sarà possibile in Go 1.6, come sztanpetcomments, con commit 9b67a5d:

Se il file fornito o il nome della directory è un percorso relativo, è interpretato come relativo alla directory corrente e può salire alle directory principali .
Se il nome fornito viene creato dall'input dell'utente, deve essere disinfettato prima di chiamare ServeFile.
Come precauzione, ServeFile rifiuterà le richieste in cui r.URL.Path contiene un elemento del percorso "..".

che proteggeranno contro la seguente "url":

/../file 
/.. 
/../ 
/../foo 
/..\\foo 
/file/a 
/file/a.. 
/file/a/.. 
/file/a\\.. 
+4

Complimenti, questo cattivo consiglio ispirato questo commit https://github.com/golang/go/commit/9b67a5de79af56541c48c95c6d7ddc8630e1d0dc – sztanpet

+3

@sztanpet Grazie per questo feedback. Ho modificato la risposta di conseguenza. – VonC

+3

Grazie per essere stato responsabile e non aver preso personalmente il mio snark – sztanpet

1

forse ho perso qualcosa qui, ma dopo un sacco di ricerca confusa, ho messo questo insieme:

...

func downloadHandler(w http.ResponseWriter, r *http.Request) { 
     r.ParseForm() 
     StoredAs := r.Form.Get("StoredAs") // file name 
     data, err := ioutil.ReadFile("files/"+StoredAs) 
     if err != nil { fmt.Fprint(w, err) } 
     http.ServeContent(w, r, StoredAs, time.Now(), bytes.NewReader(data)) 
} 

...

Dove downloadHandler è invocato come parte di un semplice server upload e download:

func main() { 
       http.HandleFunc("/upload", uploadHandler) 
       http.HandleFunc("/download", downloadHandler) 
       http.ListenAndServe(":3001", nil) 
} 

funziona bene con Firefox e Chrome. Non ha nemmeno bisogno di un tipo di file.

+0

Cosa succede se il parametro StoredAs contiene "../../mysecrets? –

+0

Non so. Cosa succede? – user2099484

+0

Un attacco directory traversal –

1

Si potrebbe utilizzare http.StripPrefix

Ti piace questa:

http.Handle("/hello/", http.StripPrefix("/hello/",http.FileServer(http.Dir("static")))) 
Problemi correlati