package ui import ( "code.osinet.fr/fgm/kurz/web/i18n" "fmt" "io" "net/http" "strings" "code.osinet.fr/fgm/kurz/domain" "github.com/gorilla/mux" ) /* Template variables: - assetsBaseURL http://plusvite-cdn.osinet.eu - FullyQualifiedShortURL (short string) - SiteBaseURL http://plusvite.net/ - FullyQualifiedTargetURL (target string) - RefreshDelay (seconds int) - SiteName PlusVite */ func build403(w http.ResponseWriter, short string) { data := struct { FullyQualifiedShortURL string Globals }{ short, globals, } sw := &strings.Builder{} err := tmpl.ExecuteTemplate(sw, "403", data) if err != nil { w.WriteHeader(http.StatusInternalServerError) } else { w.WriteHeader(http.StatusForbidden) io.Copy(w, strings.NewReader(sw.String())) } } func build404(w http.ResponseWriter, short string) { data := struct { FullyQualifiedShortURL string Globals }{ short, globals, } sw := &strings.Builder{} err := tmpl.ExecuteTemplate(sw, "404", data) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) } else { w.WriteHeader(http.StatusNotFound) io.Copy(w, strings.NewReader(sw.String())) } } func build451(w http.ResponseWriter, router *mux.Router, short string) { hr := router.Get(RouteGetRoot) _, err := hr.URL() if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } data := struct { FullyQualifiedShortURL string Globals }{ short, globals, } sw := &strings.Builder{} err = tmpl.ExecuteTemplate(sw, "404", data) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) } else { w.WriteHeader(http.StatusNotFound) io.Copy(w, strings.NewReader(sw.String())) } } // handleGetShort handles path / func handleGetShort(w http.ResponseWriter, r *http.Request, router *mux.Router) { short, ok := mux.Vars(r)["short"] if !ok { w.WriteHeader(http.StatusBadRequest) return } target, err := domain.GetTargetURL(short, i18n.Localizer(r)) // Happy path. if err == nil { w.Header().Set("Location", target) w.WriteHeader(http.StatusSeeOther) return } // Very sad path. domainErr, ok := err.(domain.Error) if !ok { // All errors return by the API should be domain-specific errors. w.WriteHeader(http.StatusInternalServerError) return } // Normal sad paths. switch domainErr.Kind { case domain.ShortNotFound.ID: build404(w, short) case domain.TargetBlocked.ID: build403(w, short) case domain.TargetCensored.ID: build451(w, router, short) default: // TargetInvalid is not supposed to happen in this case, so it is an internal error too. w.WriteHeader(http.StatusInternalServerError) } }