aboutsummaryrefslogtreecommitdiffhomepage
path: root/mpaste.go
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2025-08-16 20:07:18 +0200
committerThomas Voss <mail@thomasvoss.com> 2025-08-16 20:07:18 +0200
commit7cf51e6fcd1cce954ffef5bbb71ae865b0d4d5d8 (patch)
treecb71c6e15a5caf73ab860cde170300761c2cad63 /mpaste.go
parentf9d7145f52004048f7c309f92f591db885803e02 (diff)
Slightly modernize everythingHEADmaster
Diffstat (limited to 'mpaste.go')
-rw-r--r--mpaste.go152
1 files changed, 77 insertions, 75 deletions
diff --git a/mpaste.go b/mpaste.go
index f65893a..f81ea12 100644
--- a/mpaste.go
+++ b/mpaste.go
@@ -2,6 +2,7 @@ package main
import (
"bufio"
+ "cmp"
"fmt"
"io"
"io/ioutil"
@@ -12,11 +13,11 @@ import (
"strings"
"sync"
+ "git.sr.ht/~mango/opts/v2"
"github.com/alecthomas/chroma/v2/formatters/html"
"github.com/alecthomas/chroma/v2/lexers"
"github.com/alecthomas/chroma/v2/styles"
"github.com/dgrijalva/jwt-go"
- "git.thomasvoss.com/getgopt"
)
const (
@@ -40,12 +41,12 @@ var (
func usage() {
fmt.Fprintf(os.Stderr,
- "Usage: %s [-c file] [-f directory] [-i file] [-u file] domain port\n",
+ "Usage: %s [-c file] [-i file] [-p directory] [-u file] domain port\n",
os.Args[0])
os.Exit(1)
}
-func die(e interface{}) {
+func die(e any) {
fmt.Fprintln(os.Stderr, e)
os.Exit(1)
}
@@ -165,87 +166,92 @@ func syntaxHighlighting(w http.ResponseWriter, r *http.Request) {
}
}
-func endpoint(w http.ResponseWriter, r *http.Request) {
- switch r.Method {
- case http.MethodGet:
- switch isValidUrl(r.URL.Path[1:]) {
- case urlHomepage:
- http.ServeFile(w, r, indexFile)
- case urlInvalid:
- writeHeader(w, http.StatusNotFound, "")
- return
- case urlSyntax:
- w.Header().Set("Content-Type", "text/html; charset=utf-8")
- syntaxHighlighting(w, r)
- case urlValid:
- w.Header().Set("Content-Type", "text/plain; charset=utf-8")
- http.ServeFile(w, r, filePrefix+r.URL.Path[1:])
- }
- case http.MethodPost:
- if secretKey != "" && !validateToken(r) {
- writeHeader(w, http.StatusForbidden, "")
- return
- }
-
- file, _, err := r.FormFile("data")
- defer file.Close()
- if err != nil {
- writeHeader(w, http.StatusInternalServerError, "Failed to parse form")
- return
- }
+func get(w http.ResponseWriter, r *http.Request) {
+ switch isValidUrl(r.URL.Path[1:]) {
+ case urlHomepage:
+ http.ServeFile(w, r, indexFile)
+ case urlInvalid:
+ writeHeader(w, http.StatusNotFound, "")
+ return
+ case urlSyntax:
+ w.Header().Set("Content-Type", "text/html; charset=utf-8")
+ syntaxHighlighting(w, r)
+ case urlValid:
+ w.Header().Set("Content-Type", "text/plain; charset=utf-8")
+ http.ServeFile(w, r, filePrefix+r.URL.Path[1:])
+ }
+}
- mutex.Lock()
- defer mutex.Unlock()
+func post(w http.ResponseWriter, r *http.Request) {
+ if secretKey != "" && !validateToken(r) {
+ writeHeader(w, http.StatusForbidden, "")
+ return
+ }
- fname := filePrefix + strconv.Itoa(counter)
- nfile, err := os.Create(fname)
- defer nfile.Close()
- if err != nil {
- writeHeader(w, http.StatusInternalServerError, "Failed to create file")
- return
- }
+ file, _, err := r.FormFile("data")
+ defer file.Close()
+ if err != nil {
+ writeHeader(w, http.StatusInternalServerError, "Failed to parse form")
+ return
+ }
- if _, err = io.Copy(nfile, file); err != nil {
- writeHeader(w, http.StatusInternalServerError, "Failed to write file")
- return
- }
+ mutex.Lock()
+ defer mutex.Unlock()
- if err = os.WriteFile(counterFile, []byte(strconv.Itoa(counter+1)), 0644); err != nil {
- writeHeader(w, http.StatusInternalServerError, "Failed to update counter")
- return
- }
+ fname := filePrefix + strconv.Itoa(counter)
+ nfile, err := os.Create(fname)
+ defer nfile.Close()
+ if err != nil {
+ writeHeader(w, http.StatusInternalServerError, "Failed to create file")
+ return
+ }
- w.WriteHeader(http.StatusOK)
- fmt.Fprintf(w, domain+"/%d\n", counter)
+ if _, err = io.Copy(nfile, file); err != nil {
+ writeHeader(w, http.StatusInternalServerError, "Failed to write file")
+ return
+ }
- counter++
- default:
- writeHeader(w, http.StatusMethodNotAllowed, "Only GET and POST requests are supported")
+ if err = os.WriteFile(counterFile, []byte(strconv.Itoa(counter+1)), 0644); err != nil {
+ writeHeader(w, http.StatusInternalServerError, "Failed to update counter")
+ return
}
+
+ w.WriteHeader(http.StatusOK)
+ fmt.Fprintf(w, domain+"/%d\n", counter)
+
+ counter++
}
func main() {
- for opt := byte(0); getgopt.Getopt(len(os.Args), os.Args, ":c:f:i:u:", &opt); {
- switch opt {
+ flags, rest, err := opts.GetLong(os.Args, []opts.LongOpt{
+ {Short: 'c', Long: "counter-file", Arg: opts.Required},
+ {Short: 'i', Long: "index", Arg: opts.Required},
+ {Short: 'p', Long: "prefix", Arg: opts.Required},
+ {Short: 'u', Long: "user-file", Arg: opts.Required},
+ })
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "%s: %s\n", os.Args[0], err)
+ usage()
+ }
+
+ for _, f := range flags {
+ switch f.Key {
case 'c':
- counterFile = getgopt.Optarg
- case 'f':
- filePrefix = getgopt.Optarg
+ counterFile = f.Value
case 'i':
- indexFile = getgopt.Optarg
+ indexFile = f.Value
+ case 'p':
+ filePrefix = f.Value
case 'u':
- userFile = getgopt.Optarg
- default:
- usage()
+ userFile = f.Value
}
}
- argv := os.Args[getgopt.Optind:]
- if len(argv) != 2 {
+ if len(rest) != 2 {
usage()
}
- domain = argv[0]
- port := argv[1]
+ domain = rest[0]
+ port := rest[1]
if filePrefix == "" {
filePrefix = "files/"
@@ -253,13 +259,8 @@ func main() {
filePrefix += "/"
}
- if counterFile == "" {
- counterFile = "counter"
- }
-
- if indexFile == "" {
- indexFile = "index.html"
- }
+ counterFile = cmp.Or(counterFile, "counter")
+ indexFile = cmp.Or(indexFile, "index.html")
if _, err := os.Stat(indexFile); os.IsNotExist(err) {
die(err)
@@ -281,6 +282,7 @@ func main() {
counter, _ = strconv.Atoi(string(data))
}
- http.HandleFunc("/", endpoint)
+ http.HandleFunc("GET /", get)
+ http.HandleFunc("POST /", post)
die(http.ListenAndServe(":"+port, nil))
-}
+} \ No newline at end of file