From 5ade7a06420d6d771cfe7d17c3e0c40c2cca56da Mon Sep 17 00:00:00 2001 From: Tai Groot Date: Tue, 20 Apr 2021 06:20:39 -0700 Subject: [PATCH] Fix pb utility (#16) * Update dependencies and go compile target version * Adds deletion support to the server * Add form around delete button * Add support for returning the url in curl * remove -config option for now * Upload as form value instead of file * remove dependencies from go mod * update to README re: new curl usage --- README.md | 2 +- client/client.go | 15 +++++++++++-- cmd/pb/main.go | 11 --------- go.mod | 1 - go.sum | 2 -- server.go | 54 +++++++++++++++++++++++++++++++++++++++++++-- templates/view.html | 12 ++++++---- 7 files changed, 74 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 8e3098c..3e7c0d8 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ Or use the Web UI: http://localhost:8000/ Or curl: ```#bash -$ echo "hello World" | curl -q -L -d @- -o - http://localhost:8000/ +$ echo "Hello World" | curl -q -L --form blob='<-' -o - http://localhost:8000/ ... ``` diff --git a/client/client.go b/client/client.go index 2ccaeae..f1825de 100644 --- a/client/client.go +++ b/client/client.go @@ -7,6 +7,8 @@ import ( "io" "log" "net/http" + "net/url" + "strings" ) const ( @@ -31,13 +33,22 @@ func (c *Client) Paste(body io.Reader) error { } client := &http.Client{Transport: tr} - res, err := client.Post(c.url, contentType, body) + buf := new(strings.Builder) + _, err := io.Copy(buf, body) + // check errors + if err != nil { + log.Printf("error reading in file: %s", err) + return err + } + v := url.Values{} + v.Set("blob", buf.String()) + res, err := client.PostForm(c.url, v) if err != nil { log.Printf("error pasting to %s: %s", c.url, err) return err } - if res.StatusCode != 200 { + if res.StatusCode != 200 && res.StatusCode != 301 { log.Printf("unexpected response from %s: %d", c.url, res.StatusCode) return errors.New("unexpected response") } diff --git a/cmd/pb/main.go b/cmd/pb/main.go index 3aeb4f8..d58b73b 100644 --- a/cmd/pb/main.go +++ b/cmd/pb/main.go @@ -6,7 +6,6 @@ import ( "github.com/prologic/pastebin/client" - "github.com/mitchellh/go-homedir" "github.com/namsral/flag" ) @@ -16,22 +15,12 @@ const ( defaultURL = "http://localhost:8000" ) -func getDefaultConfig() string { - path, err := homedir.Expand(defaultUserConfig) - if err != nil { - return defaultConfig - } - return path -} - func main() { var ( - config string url string insecure bool ) - flag.StringVar(&config, "config", getDefaultConfig(), "path to config") flag.StringVar(&url, "url", defaultURL, "pastebin service url") flag.BoolVar(&insecure, "insecure", false, "insecure (skip ssl verify)") diff --git a/go.mod b/go.mod index f053853..c6bfaee 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,6 @@ go 1.16 require ( github.com/GeertJohan/go.rice v1.0.2 github.com/julienschmidt/httprouter v1.3.0 - github.com/mitchellh/go-homedir v1.1.0 github.com/namsral/flag v1.7.4-pre github.com/patrickmn/go-cache v2.1.0+incompatible github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 diff --git a/go.sum b/go.sum index 3c335e6..fdd2fd1 100644 --- a/go.sum +++ b/go.sum @@ -10,8 +10,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/namsral/flag v1.7.4-pre h1:b2ScHhoCUkbsq0d2C15Mv+VU8bl8hAXV8arnWiOHNZs= github.com/namsral/flag v1.7.4-pre/go.mod h1:OXldTctbM6SWH1K899kPZcf65KxJiD7MsceFUpB5yDo= github.com/nkovacs/streamquote v1.0.0/go.mod h1:BN+NaZ2CmdKqUuTUXUEm9j95B2TRbpOWpxbJYzzgUsc= diff --git a/server.go b/server.go index c9ffa04..bba047a 100644 --- a/server.go +++ b/server.go @@ -115,6 +115,15 @@ func (s *Server) PasteHandler() httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { s.counters.Inc("n_paste") + accepts, err := accept.Negotiate( + r.Header.Get("Accept"), AcceptedTypes..., + ) + if err != nil { + log.Printf("error negotiating: %s", err) + http.Error(w, "Internal Error", http.StatusInternalServerError) + return + } + blob := r.FormValue("blob") if len(blob) == 0 { @@ -129,7 +138,14 @@ func (s *Server) PasteHandler() httprouter.Handle { if err != nil { http.Error(w, "Internal Error", http.StatusInternalServerError) } - http.Redirect(w, r, r.URL.ResolveReference(u).String(), http.StatusFound) + switch accepts { + case "text/html": + http.Redirect(w, r, r.URL.ResolveReference(u).String(), http.StatusFound) + case "text/plain": + fallthrough + default: + w.Write([]byte(r.Host + r.URL.ResolveReference(u).String())) + } } } @@ -160,6 +176,35 @@ func (s *Server) DownloadHandler() httprouter.Handle { } } +// DeleteHandler +func (s *Server) DeleteHandler() httprouter.Handle { + return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + s.counters.Inc("n_delete") + _, err := accept.Negotiate( + r.Header.Get("Accept"), AcceptedTypes..., + ) + if err != nil { + log.Printf("error negotiating: %s", err) + http.Error(w, "Internal Error", http.StatusInternalServerError) + return + } + + uuid := p.ByName("uuid") + if uuid == "" { + http.Error(w, "Bad Request", http.StatusBadRequest) + return + } + + _, ok := s.store.Get(uuid) + if !ok { + http.Error(w, "Not Found", http.StatusNotFound) + return + } + s.store.Delete(uuid) + http.Error(w, "Deleted", http.StatusOK) + } +} + // ViewHandler ... func (s *Server) ViewHandler() httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { @@ -202,7 +247,7 @@ func (s *Server) ViewHandler() httprouter.Handle { }, ) case "text/plain": - w.Write([]byte(blob)) + fallthrough default: w.Write([]byte(blob)) } @@ -246,6 +291,11 @@ func (s *Server) initRoutes() { s.router.POST("/", s.PasteHandler()) s.router.GET("/download/:uuid", s.DownloadHandler()) s.router.GET("/p/:uuid", s.ViewHandler()) + // Enable DELETE from curl/wget/cli + s.router.DELETE("/p/:uuid", s.DeleteHandler()) + // Add alternate path since form actions don't support method=DELETE + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/DELETE + s.router.POST("/p/:uuid/delete", s.DeleteHandler()) } // NewServer ... diff --git a/templates/view.html b/templates/view.html index d22cc48..776668f 100644 --- a/templates/view.html +++ b/templates/view.html @@ -16,10 +16,14 @@