diff options
Diffstat (limited to 'plugins/viewhtml/plugin.go')
-rw-r--r-- | plugins/viewhtml/plugin.go | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/plugins/viewhtml/plugin.go b/plugins/viewhtml/plugin.go index f22364e..b34372f 100644 --- a/plugins/viewhtml/plugin.go +++ b/plugins/viewhtml/plugin.go @@ -1,10 +1,59 @@ package koushinviewhtml import ( + "io" + "mime" + "net/http" + "net/url" + "strconv" + "strings" + "git.sr.ht/~emersion/koushin" + "github.com/labstack/echo/v4" +) + +var ( + proxyEnabled = true + proxyMaxSize = 5 * 1024 * 1024 // 5 MiB ) func init() { p := koushin.GoPlugin{Name: "viewhtml"} + + p.GET("/proxy", func(ctx *koushin.Context) error { + if !proxyEnabled { + return echo.NewHTTPError(http.StatusForbidden, "proxy disabled") + } + + u, err := url.Parse(ctx.QueryParam("src")) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, "invalid URL") + } + + if u.Scheme != "https" { + return echo.NewHTTPError(http.StatusBadRequest, "invalid scheme") + } + + resp, err := http.Get(u.String()) + if err != nil { + return err + } + defer resp.Body.Close() + + mediaType, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil || !strings.HasPrefix(mediaType, "image/") { + return echo.NewHTTPError(http.StatusBadRequest, "invalid resource type") + } + + size, err := strconv.Atoi(resp.Header.Get("Content-Length")) + if err != nil || size > proxyMaxSize { + return echo.NewHTTPError(http.StatusBadRequest, "invalid resource length") + } + + ctx.Response().Header().Set("Content-Length", strconv.Itoa(size)) + lr := io.LimitedReader{resp.Body, int64(proxyMaxSize)} + return ctx.Stream(http.StatusOK, mediaType, &lr) + }) + koushin.RegisterPluginLoader(p.Loader()) } |