package http import ( "bytes" "errors" "fmt" "net/http" "path/filepath" "strings" "time" "github.com/mediocregopher/blog.mediocregopher.com/srv/http/apiutil" "github.com/mediocregopher/blog.mediocregopher.com/srv/post/asset" ) func (a *api) managePostAssetsHandler() http.Handler { tpl := a.mustParseBasedTpl("post-assets-manage.html") return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { ids, err := a.params.PostAssetStore.List() if err != nil { apiutil.InternalServerError( rw, r, fmt.Errorf("getting list of asset ids: %w", err), ) return } tplPayload := struct { IDs []string }{ IDs: ids, } executeTemplate(rw, r, tpl, tplPayload) }) } func (a *api) getPostAssetHandler() http.Handler { return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { maxWidth, err := apiutil.StrToInt(r.FormValue("w"), 0) if err != nil { apiutil.BadRequest(rw, r, fmt.Errorf("invalid w parameter: %w", err)) return } var ( path = strings.TrimPrefix(r.URL.Path, "/") buf = new(bytes.Buffer) ) err = a.params.PostAssetLoader.Load( path, buf, asset.LoadOpts{ ImageWidth: maxWidth, }, ) if errors.Is(err, asset.ErrNotFound) { http.Error(rw, "Asset not found", 404) return } else if errors.Is(err, asset.ErrCannotResize) { http.Error(rw, "Image resizing not supported", 400) return } else if err != nil { apiutil.InternalServerError( rw, r, fmt.Errorf("fetching asset at path %q: %w", path, err), ) return } http.ServeContent( rw, r, path, time.Time{}, bytes.NewReader(buf.Bytes()), ) }) } func (a *api) postPostAssetHandler() http.Handler { return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { id := r.PostFormValue("id") if id == "" { apiutil.BadRequest(rw, r, errors.New("id is required")) return } file, _, err := r.FormFile("file") if err != nil { apiutil.BadRequest(rw, r, fmt.Errorf("reading multipart file: %w", err)) return } defer file.Close() if err := a.params.PostAssetStore.Set(id, file); err != nil { apiutil.InternalServerError(rw, r, fmt.Errorf("storing file: %w", err)) return } a.executeRedirectTpl(rw, r, a.manageAssetsURL(false)) }) } func (a *api) deletePostAssetHandler() http.Handler { return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { id := filepath.Base(r.URL.Path) if id == "/" { apiutil.BadRequest(rw, r, errors.New("id is required")) return } err := a.params.PostAssetStore.Delete(id) if errors.Is(err, asset.ErrNotFound) { http.Error(rw, "Asset not found", 404) return } else if err != nil { apiutil.InternalServerError( rw, r, fmt.Errorf("deleting asset with id %q: %w", id, err), ) return } a.executeRedirectTpl(rw, r, a.manageAssetsURL(false)) }) }