package routes import ( "encoding/json" "log" "net/http" "net/url" "path" "strconv" "tomatentum.net/svg-templater/pkg/format" "tomatentum.net/svg-templater/pkg/svg/actions" ) type downloadRequest struct { TemplateKeys map[string]string } type downloadResponse struct { Urls []string } func DownloadSVG(w http.ResponseWriter, r *http.Request) { contentType := r.Header.Get("Content-Type") if contentType != "application/json" { http.Error(w, "Incorrect Content-Type. Needs application/json.", http.StatusUnsupportedMediaType) return } var request downloadRequest if err := json.NewDecoder(r.Body).Decode(&request); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } var err error id := r.PathValue("id") if id == "" { http.Error(w, "No ID provided", http.StatusBadRequest) return } widthString := r.URL.Query().Get("w") width := 0 if widthString != "" { width, err = strconv.Atoi(widthString) if err != nil { http.Error(w, "Invalid w parameter", http.StatusBadRequest) return } } heightString := r.URL.Query().Get("h") height := 0 if heightString != "" { height, err = strconv.Atoi(heightString) if err != nil { http.Error(w, "Invalid h parameter", http.StatusBadRequest) return } } convParam := format.ConversionParameters{ Format: r.URL.Query().Get("format"), Width: width, Height: height, } if convParam.Format == "" { convParam.Format = "svg" } templateParam := actions.TemplateParameters{ Id: id, Keys: request.TemplateKeys, } filenames, err := actions.ProvideFile(&templateParam, &convParam) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } urlsparsed := make([]string, len(filenames)) for i, filename := range filenames { urlsparsed[i] = getPublicUrl(r, filename) log.Printf("Made %s page %d available as %s\n", id, i, urlsparsed[i]) } response := downloadResponse{ Urls: urlsparsed, } w.Header().Add("Content-Type", "application/json") json, err := json.Marshal(response) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Write(json) } func getPublicUrl(r *http.Request, subpath string) string { newURL := url.URL{ Host: r.Host, Path: path.Join("public", subpath), } newURL.Scheme = determineScheme(r) return newURL.String() } func determineScheme(r *http.Request) string { if proto := r.Header.Get("X-Forwarded-Proto"); proto != "" { return proto } if r.TLS != nil { return "https" } return "http" }