vistas poner pagina miniaturas las inicio google español como chrome celular cambiar buscar webserver go

webserver - poner - Sirve la página principal y el contenido estático de la raíz



google pagina de inicio en español (3)

En Golang, ¿cómo sirvo contenido estático fuera del directorio raíz mientras todavía tengo un controlador de directorio raíz para servir la página de inicio.

Utilice el siguiente servidor web simple como ejemplo:

package main import ( "fmt" "net/http" ) func main() { http.HandleFunc("/", HomeHandler) // homepage http.ListenAndServe(":8080", nil) } func HomeHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "HomeHandler") }

Si lo hago

http.Handle("/", http.FileServer(http.Dir("./")))

Recibo pánico al decir que tengo dos registros para "/". Todos los ejemplos de Golang que he encontrado en Internet sugieren que se saque su contenido estático de diferentes directorios, pero eso no ayuda mucho en cosas como sitemap.xml, favicon.ico, robots.txt y otros archivos que son de práctica o mandato para siempre ser servido desde la raíz.

El comportamiento que busco es el comportamiento que se encuentra en la mayoría de los servidores web, como Apache, Nginx o IIS, donde primero cruza las reglas, y si no se encuentra una regla, busca un archivo real y, si no se encuentra ningún archivo, 404s. Supongo que en lugar de escribir un http.HandlerFunc , necesito escribir un http.Handler que verifique si estoy haciendo referencia a un archivo con una extensión, y si es así, comprueba la existencia del archivo y sirve el archivo; de lo contrario, 404s o sirve el la página de inicio es la solicitud para "/". Lamentablemente, no estoy seguro de cómo comenzar esa tarea.

Parte de mí dice que estoy complicando demasiado la situación que me hace pensar que me falta algo. Cualquier orientación sería apreciada.


Una cosa que pensé que podría ayudarte es que puedes crear tu propio ServeMux. Añadí a su ejemplo para que chttp sea ServeMux y pueda tener archivos estáticos. El HomeHandler luego verifica si debe servir un archivo o no. Solo compruebo un "." pero podrías hacer muchas cosas. Solo una idea, puede que no sea lo que estás buscando.

package main import ( "fmt" "net/http" "strings" ) var chttp = http.NewServeMux() func main() { chttp.Handle("/", http.FileServer(http.Dir("./"))) http.HandleFunc("/", HomeHandler) // homepage http.ListenAndServe(":8080", nil) } func HomeHandler(w http.ResponseWriter, r *http.Request) { if (strings.Contains(r.URL.Path, ".")) { chttp.ServeHTTP(w, r) } else { fmt.Fprintf(w, "HomeHandler") } }


Una solución alternativa (que no utiliza ServeMux ) es servir explícitamente cada archivo ubicado en el directorio raíz. La idea detrás es mantener muy pequeña la cantidad de archivos basados ​​en la raíz. sitemap.xml , favicon.ico , robots.txt hecho son obligatorios para ser atendidos desde la raíz:

package main import ( "fmt" "net/http" ) func HomeHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "HomeHandler") } func serveSingle(pattern string, filename string) { http.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, filename) }) } func main() { http.HandleFunc("/", HomeHandler) // homepage // Mandatory root-based resources serveSingle("/sitemap.xml", "./sitemap.xml") serveSingle("/favicon.ico", "./favicon.ico") serveSingle("/robots.txt", "./robots.txt") // Normal resources http.Handle("/static", http.FileServer(http.Dir("./static/"))) http.ListenAndServe(":8080", nil) }

Mueva todos los demás recursos (CSS, JS, etc.) a un subdirectorio apropiado, p. Ej. /static/ .


Usando el paquete mux de Gorilla :

r := mux.NewRouter() //put your regular handlers here //then comes root handler r.HandleFunc("/", homePageHandler) //if a path not found until now, e.g. "/image/tiny.png" //this will look at "./public/image/tiny.png" at filesystem r.PathPrefix("/").Handler(http.FileServer(http.Dir("./public/"))) http.Handle("/", r) http.ListenAndServe(":8080", nil)