diff --git a/go.mod b/go.mod index cab462d..34f9f53 100644 --- a/go.mod +++ b/go.mod @@ -8,14 +8,14 @@ require ( fornaxian.tech/config v0.0.0-20211108212237-6133aed90586 fornaxian.tech/log v0.0.0-20211102185326-552e9b1f8640 fornaxian.tech/pixeldrain_api_client v0.0.0-20221207191816-6872676df741 - fornaxian.tech/util v0.0.0-20230510125310-1bc41b5fe13b + fornaxian.tech/util v0.0.0-20230520114728-bd827686fec7 github.com/julienschmidt/httprouter v1.3.0 - github.com/microcosm-cc/bluemonday v1.0.23 + github.com/microcosm-cc/bluemonday v1.0.24 github.com/russross/blackfriday/v2 v2.1.0 ) require ( - github.com/BurntSushi/toml v1.2.1 // indirect + github.com/BurntSushi/toml v1.3.0 // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/gocql/gocql v1.4.0 // indirect github.com/golang/snappy v0.0.4 // indirect diff --git a/go.sum b/go.sum index 70bffeb..f217c4d 100644 --- a/go.sum +++ b/go.sum @@ -2,10 +2,10 @@ fornaxian.tech/config v0.0.0-20211108212237-6133aed90586 h1:/4a0Iq3cYeyTWcPHsN9p fornaxian.tech/config v0.0.0-20211108212237-6133aed90586/go.mod h1:ULIXF4J1DbBw4EsIPRNQDf6J3hl4P/jlihjy6UCm9FM= fornaxian.tech/log v0.0.0-20211102185326-552e9b1f8640 h1:UPDxJwLRCfh/cv80UMSanzmZ0jIcfS1mcd0Y06HYuLw= fornaxian.tech/log v0.0.0-20211102185326-552e9b1f8640/go.mod h1:sN82qMToeHhP2u3ehvrcE8y1IudRZJAZO9yG5OBYblo= -fornaxian.tech/util v0.0.0-20230510125310-1bc41b5fe13b h1:ZJXnWqTReW9OElnanpLlpl8ElVErbYZb4cK4zjnlM1E= -fornaxian.tech/util v0.0.0-20230510125310-1bc41b5fe13b/go.mod h1:lCmtcb4/SVt2ol55/EHDWGySY7o0ONbj97RR9CdsN4M= -github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= -github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +fornaxian.tech/util v0.0.0-20230520114728-bd827686fec7 h1:8I/BQQYO/cjREsGP+1fUqaXXM4dQ3BWfARnaUScLIec= +fornaxian.tech/util v0.0.0-20230520114728-bd827686fec7/go.mod h1:lCmtcb4/SVt2ol55/EHDWGySY7o0ONbj97RR9CdsN4M= +github.com/BurntSushi/toml v1.3.0 h1:Ws8e5YmnrGEHzZEzg0YvK/7COGYtTC5PbaH9oSSbgfA= +github.com/BurntSushi/toml v1.3.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY= @@ -29,8 +29,8 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/microcosm-cc/bluemonday v1.0.23 h1:SMZe2IGa0NuHvnVNAZ+6B38gsTbi5e4sViiWJyDDqFY= -github.com/microcosm-cc/bluemonday v1.0.23/go.mod h1:mN70sk7UkkF8TUr2IGBpNN0jAgStuPzlK76QuruE/z4= +github.com/microcosm-cc/bluemonday v1.0.24 h1:NGQoPtwGVcbGkKfvyYk1yRqknzBuoMiUrO6R7uFTPlw= +github.com/microcosm-cc/bluemonday v1.0.24/go.mod h1:ArQySAMps0790cHSkdPEJ7bGkF2VePWH773hsJNSHf8= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= diff --git a/webcontroller/file_viewer.go b/webcontroller/file_viewer.go index f3cf2d9..dded08a 100644 --- a/webcontroller/file_viewer.go +++ b/webcontroller/file_viewer.go @@ -3,6 +3,7 @@ package webcontroller import ( "fmt" "html/template" + "io" "net/http" "strings" "time" @@ -11,6 +12,8 @@ import ( "fornaxian.tech/pixeldrain_api_client/pixelapi" "fornaxian.tech/util" "github.com/julienschmidt/httprouter" + "github.com/microcosm-cc/bluemonday" + blackfriday "github.com/russross/blackfriday/v2" ) func (wc *WebController) viewTokenOrBust() (t string) { @@ -202,3 +205,39 @@ func (wc *WebController) serveListViewer(w http.ResponseWriter, r *http.Request, log.Error("Error executing template file_viewer: %s", err) } } + +func (wc *WebController) serveFilePreview(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + apiKey, _ := wc.getAPIKey(r) + api := wc.api.Login(apiKey).RealIP(util.RemoteAddress(r)).RealAgent(r.UserAgent()) + + file, err := api.GetFileInfo(p.ByName("id")) // TODO: Error handling + if err != nil { + wc.serveNotFound(w, r) + return + } + + if strings.HasPrefix(file.MimeType, "text") && + (strings.HasSuffix(file.Name, ".md") || strings.HasSuffix(file.Name, ".markdown")) { + if file.Size > 1<<22 { // Prevent out of memory errors + w.Write([]byte("File is too large to view online.\nPlease download and view it locally.")) + return + } + + body, err := api.GetFile(file.ID) + if err != nil { + log.Error("Can't download text file for preview: %s", err) + w.Write([]byte("An error occurred while downloading this file.")) + return + } + defer body.Close() + + bodyBytes, err := io.ReadAll(body) + if err != nil { + log.Error("Can't read text file for preview: %s", err) + w.Write([]byte("An error occurred while reading this file.")) + return + } + + w.Write(bluemonday.UGCPolicy().SanitizeBytes(blackfriday.Run(bodyBytes))) + } +} diff --git a/webcontroller/web_controller.go b/webcontroller/web_controller.go index 0d97268..7a09cb4 100644 --- a/webcontroller/web_controller.go +++ b/webcontroller/web_controller.go @@ -138,6 +138,7 @@ func New(r *httprouter.Router, prefix string, conf Config) (wc *WebController) { {GET, "api" /* */, wc.serveMarkdown("api.md", handlerOpts{})}, {GET, "history" /* */, wc.serveTemplate("history_cookies", handlerOpts{})}, {GET, "u/:id" /* */, wc.serveFileViewer}, + {GET, "u/:id/preview" /* */, wc.serveFilePreview}, {GET, "l/:id" /* */, wc.serveListViewer}, {GET, "d/*path" /* */, wc.serveDirectory}, {GET, "t" /* */, wc.serveTemplate("text_upload", handlerOpts{})},