diff --git a/app.info.go b/app.info.go index 84627c5..daaf044 100644 --- a/app.info.go +++ b/app.info.go @@ -23,7 +23,7 @@ type info struct{} func (info) RegisterHTTP(mux *http.ServeMux) { mux.HandleFunc("/app-info", func(w http.ResponseWriter, r *http.Request) { name, version := service.AppName() - fmt.Fprint(w, name, version) + fmt.Fprint(w, name, '@', version) }) } diff --git a/app.paste.go b/app.paste.go index 7dd9d42..eeda8e8 100644 --- a/app.paste.go +++ b/app.paste.go @@ -2,19 +2,12 @@ package main import ( "context" - "crypto/rand" - "errors" - "fmt" - "log" - "net/http" "strconv" - "strings" "go.sour.is/pkg/env" "go.sour.is/pkg/lg" "go.sour.is/pkg/service" - "go.sour.is/paste/v2/assets" "go.sour.is/paste/v2/paste" ) @@ -28,104 +21,12 @@ var _ = apps.Register(50, func(ctx context.Context, svc *service.Harness) error return err } - p, err := paste.New(store) + srv, err := paste.NewService(store, randBytes) if err != nil { return err } - svc.Add(&pasteSRV{ - ui: http.FileServer(http.FS(assets.GetUI())), - paste: p, - randBytes: int(randBytes), - }) + svc.Add(srv) return nil }) - -type pasteSRV struct { - ui http.Handler - paste *paste.Paste - randBytes int -} - -func (a *pasteSRV) RegisterHTTP(mux *http.ServeMux) { - mux.Handle("/ui/", lg.Htrace(http.StripPrefix("/ui/", a.ui), "paste-assets")) - - mux.Handle("/api", http.StripPrefix("/api", a)) - mux.Handle("/api/", http.StripPrefix("/api/", a)) - - mux.Handle("/paste", http.StripPrefix("/paste", a)) - mux.Handle("/paste/", http.StripPrefix("/paste/", a)) -} - -func (p *pasteSRV) ServeHTTP(w http.ResponseWriter, r *http.Request) { - switch r.Method { - case http.MethodGet: - switch { - case strings.HasPrefix(r.URL.Path, "rng"): - p.getRandom(w) - - case strings.HasPrefix(r.URL.Path, "get"), r.URL.Path != "": - p.getPaste(w, strings.TrimPrefix(r.URL.Path, "get/")) - - default: - http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) - } - - case http.MethodPost: - switch { - case r.URL.Path == "": - p.postPaste(w, r) - - default: - http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) - } - - default: - http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed) - } -} - -func (p *pasteSRV) getRandom(w http.ResponseWriter) { - log.Println("get random") - s := make([]byte, p.randBytes) - _, _ = rand.Read(s) - - w.Header().Set("content-type", "application/octet-stream") - w.WriteHeader(http.StatusOK) - _, _ = w.Write(s) -} - -func (p *pasteSRV) getPaste(w http.ResponseWriter, id string) { - log.Println("get paste", id) - w.Header().Set("content-type", "application/octet-stream") - - err := p.paste.Get(w, id) - if err != nil { - switch { - case errors.Is(err, paste.ErrGone): - w.WriteHeader(http.StatusGone) - case errors.Is(err, paste.ErrNotFound): - w.WriteHeader(http.StatusNotFound) - case errors.Is(err, paste.ErrReadingContent): - w.WriteHeader(http.StatusInternalServerError) - } - - fmt.Fprintf(w, "ERR %s", err) - return - } -} - -func (p *pasteSRV) postPaste(w http.ResponseWriter, r *http.Request) { - w.Header().Set("content-type", "application/octet-stream") - - id, err := p.paste.Set(r.Body) - if err != nil { - fmt.Fprintf(w, "ERR %s", err) - return - - } - - log.Println("post paste", id) - fmt.Fprint(w, "OK ", id) -} diff --git a/paste/public/index.html b/paste/public/index.html new file mode 100644 index 0000000..ceea047 --- /dev/null +++ b/paste/public/index.html @@ -0,0 +1,19 @@ + + + + + + + + + + + DN42 Paste + + + + + + + + diff --git a/paste/public/paste.css b/paste/public/paste.css new file mode 100644 index 0000000..e69de29 diff --git a/paste/service.go b/paste/service.go new file mode 100644 index 0000000..e304d42 --- /dev/null +++ b/paste/service.go @@ -0,0 +1,114 @@ +package paste + +import ( + "crypto/rand" + "errors" + "fmt" + "log" + "net/http" + "strings" + + "go.sour.is/paste/v2/assets" + "go.sour.is/pkg/lg" +) + +type service struct { + ui http.Handler + paste *Paste + randBytes int +} + +func NewService(store string, randBytes int64) (*service, error) { + p, err := New(store) + if err != nil { + return nil, err + } + + return &service{ + ui: http.FileServer(http.FS(assets.GetUI())), + paste: p, + randBytes: int(randBytes), + }, nil +} + +func (a *service) RegisterHTTP(mux *http.ServeMux) { + mux.Handle("/ui/", lg.Htrace(http.StripPrefix("/ui/", a.ui), "paste-assets")) + + mux.Handle("/api", http.StripPrefix("/api", a)) + mux.Handle("/api/", http.StripPrefix("/api/", a)) + + mux.Handle("/paste", http.StripPrefix("/paste", a)) + mux.Handle("/paste/", http.StripPrefix("/paste/", a)) +} + +func (p *service) ServeHTTP(w http.ResponseWriter, r *http.Request) { + switch r.Method { + case http.MethodGet: + switch { + case strings.HasPrefix(r.URL.Path, "rng"): + p.getRandom(w) + + case strings.HasPrefix(r.URL.Path, "get"), r.URL.Path != "": + p.getPaste(w, strings.TrimPrefix(r.URL.Path, "get/")) + + default: + http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) + } + + case http.MethodPost: + switch { + case r.URL.Path == "": + p.postPaste(w, r) + + default: + http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) + } + + default: + http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed) + } +} + +func (p *service) getRandom(w http.ResponseWriter) { + log.Println("get random") + s := make([]byte, p.randBytes) + _, _ = rand.Read(s) + + w.Header().Set("content-type", "application/octet-stream") + w.WriteHeader(http.StatusOK) + _, _ = w.Write(s) +} + +func (p *service) getPaste(w http.ResponseWriter, id string) { + log.Println("get paste", id) + w.Header().Set("content-type", "application/octet-stream") + + err := p.paste.Get(w, id) + if err != nil { + switch { + case errors.Is(err, ErrGone): + w.WriteHeader(http.StatusGone) + case errors.Is(err, ErrNotFound): + w.WriteHeader(http.StatusNotFound) + case errors.Is(err, ErrReadingContent): + w.WriteHeader(http.StatusInternalServerError) + } + + fmt.Fprintf(w, "ERR %s", err) + return + } +} + +func (p *service) postPaste(w http.ResponseWriter, r *http.Request) { + w.Header().Set("content-type", "application/octet-stream") + + id, err := p.paste.Set(r.Body) + if err != nil { + fmt.Fprintf(w, "ERR %s", err) + return + + } + + log.Println("post paste", id) + fmt.Fprint(w, "OK ", id) +}