sliproad/router/router.go
Gabriel Simmer 5e345f11af
Tweaked spacing for file list, icons.
Icons! Finally, signifying type of link without relying on colours. Also
added some margin to help alleviate strain from contrasting colours.
Fixed background-color of "NAS" home link maintaining white background.
2020-04-05 19:32:35 +01:00

99 lines
2.4 KiB
Go

package router
import (
"fmt"
"github.com/gorilla/mux"
"io"
"log"
"net/http"
"os"
"strconv"
)
type Handler func(context *Context, w http.ResponseWriter, r *http.Request) *HTTPError
type HTTPError struct {
Message string
StatusCode int
}
// Context contains any information to be shared with middlewares.
type Context struct {}
func Handle(handlers ...Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
context := &Context{}
for _, handler := range handlers {
err := handler(context, w, r)
if err != nil {
log.Printf("%v", err)
w.Write([]byte(http.StatusText(err.StatusCode)))
return
}
}
})
}
// Actual router, define endpoints here.
func Init() *mux.Router {
r := mux.NewRouter()
// "Static" paths
r.PathPrefix("/javascript/").Handler(http.StripPrefix("/javascript/", http.FileServer(http.Dir("assets/web/javascript"))))
r.PathPrefix("/css/").Handler(http.StripPrefix("/css/", http.FileServer(http.Dir("assets/web/css"))))
r.PathPrefix("/icons/").Handler(http.StripPrefix("/icons/", http.FileServer(http.Dir("assets/web/icons"))))
// Paths that require specific handlers
r.Handle("/", Handle(
rootHandler(),
)).Methods("GET")
r.Handle("/api/providers", Handle(
ListProviders(),
)).Methods("GET")
r.Handle(`/api/files/{provider:[a-zA-Z0-9]+\/*}`, Handle(
HandleProvider(),
)).Methods("GET", "POST")
r.Handle(`/api/files/{provider:[a-zA-Z0-9]+}/{file:[a-zA-Z0-9=\-\/\s.,&_+]+}`, Handle(
HandleProvider(),
)).Methods("GET", "POST")
return r
}
// Handles serving index page.
func rootHandler() Handler {
return func(context *Context, w http.ResponseWriter, r *http.Request) *HTTPError {
f, err := os.Open("assets/web/index.html")
if err != nil {
return &HTTPError{
Message: fmt.Sprintf("error serving index page from assets/web"),
StatusCode: http.StatusInternalServerError,
}
}
defer f.Close()
stats, err := f.Stat()
if err != nil {
return &HTTPError{
Message: fmt.Sprintf("error serving index page from assets/web"),
StatusCode: http.StatusInternalServerError,
}
} else {
w.Header().Add("Content-Length", strconv.FormatInt(stats.Size(), 10))
}
_, err = io.Copy(w, f)
if err != nil {
return &HTTPError{
Message: fmt.Sprintf("error serving index page from assets/web"),
StatusCode: http.StatusInternalServerError,
}
}
return nil
}
}