diff options
| author | Rose Hogenson <rosehogenson@posteo.net> | 2025-10-06 22:15:22 -0700 |
|---|---|---|
| committer | Rose Hogenson <rosehogenson@posteo.net> | 2025-10-06 22:15:22 -0700 |
| commit | 65b1ed1ff56e4d795c67d4d0b31634decec7767b (patch) | |
| tree | 40fb48480c7d9273e084ad317378d5cd7384c44f | |
| parent | c5a5b24cf6370ab549c033b20ad0389ec3ce8ec1 (diff) | |
| download | roseh.moe-65b1ed1ff56e4d795c67d4d0b31634decec7767b.tar.zst | |
Add uploader tool
| -rw-r--r-- | internal/wordlist/wordlist.go | 11 | ||||
| -rw-r--r-- | internal/wordlist/wordlist.txt (renamed from wordlist.txt) | 0 | ||||
| -rw-r--r-- | roseh.moe.go | 18 | ||||
| -rw-r--r-- | tools/hole/hole.go | 91 |
4 files changed, 112 insertions, 8 deletions
diff --git a/internal/wordlist/wordlist.go b/internal/wordlist/wordlist.go new file mode 100644 index 0000000..de929bc --- /dev/null +++ b/internal/wordlist/wordlist.go @@ -0,0 +1,11 @@ +package wordlist + +import ( + _ "embed" + "strings" +) + +//go:embed wordlist.txt +var wordList string + +var Words = strings.Split(strings.TrimSuffix(wordList, "\n"), "\n") diff --git a/wordlist.txt b/internal/wordlist/wordlist.txt index 5e304ce..5e304ce 100644 --- a/wordlist.txt +++ b/internal/wordlist/wordlist.txt diff --git a/roseh.moe.go b/roseh.moe.go index 9b5c1a6..140b1de 100644 --- a/roseh.moe.go +++ b/roseh.moe.go @@ -20,6 +20,8 @@ import ( "strings" "sync" "time" + + "gitlab.com/rhogenson/roseh.moe/internal/wordlist" ) var ( @@ -119,10 +121,6 @@ func favicon(w http.ResponseWriter, r *http.Request) { } var ( - //go:embed wordlist.txt - wordListString string - wordList = strings.Split(strings.TrimSuffix(wordListString, "\n"), "\n") - //go:embed templates/wormhole.html.template wormholeTemplateString string wormholeTemplate = template.Must(template.Must(outlineTemplate.Clone()).New("body").Parse(wormholeTemplateString)).Lookup("outline") @@ -133,15 +131,19 @@ type wormholeTemplateArgs struct { Hole string } -func wormhole(w http.ResponseWriter, r *http.Request) { +func makeHole() string { const nWords = 10 buf := make([]byte, 2*nWords) rand.Read(buf) words := make([]string, nWords) for i := range words { - words[i] = wordList[binary.NativeEndian.Uint16(buf[2*i:])&0x1fff] + words[i] = wordlist.Words[binary.NativeEndian.Uint16(buf[2*i:])&0x1fff] } - if err := wormholeTemplate.Execute(w, wormholeTemplateArgs{Self: *selfURL, Hole: strings.Join(words, "-")}); err != nil { + return strings.Join(words, "-") +} + +func wormhole(w http.ResponseWriter, r *http.Request) { + if err := wormholeTemplate.Execute(w, wormholeTemplateArgs{Self: *selfURL, Hole: makeHole()}); err != nil { log.Printf("Warning: wormhole: %s", err) } } @@ -160,7 +162,7 @@ var wormholeNotify = make(map[string]chan struct{}) func wormholeSend(w http.ResponseWriter, r *http.Request) { reader, err := r.MultipartReader() if err != nil { - http.Error(w, "not a multipart/form-data request", http.StatusBadRequest) + http.Error(w, fmt.Sprintf("Not a multipart/form-data request: %s", err), http.StatusBadRequest) return } for { diff --git a/tools/hole/hole.go b/tools/hole/hole.go new file mode 100644 index 0000000..d701c40 --- /dev/null +++ b/tools/hole/hole.go @@ -0,0 +1,91 @@ +package main + +import ( + "crypto/rand" + "encoding/binary" + "flag" + "fmt" + "io" + "mime/multipart" + "net/http" + "os" + "strings" + + "gitlab.com/rhogenson/roseh.moe/internal/wordlist" +) + +var url = flag.String("url", "https://roseh.moe", "server URL") + +func makeHole() string { + const nWords = 10 + buf := make([]byte, 2*nWords) + rand.Read(buf) + words := make([]string, nWords) + for i := range words { + words[i] = wordlist.Words[binary.NativeEndian.Uint16(buf[2*i:])&0x1fff] + } + return strings.Join(words, "-") +} + +func hole() error { + args := flag.Args() + if len(args) != 1 { + return fmt.Errorf("usage error") + } + fileName := args[0] + f, err := os.Open(fileName) + if err != nil { + return err + } + defer f.Close() + hole := makeHole() + fmt.Println(*url + "/wormhole/" + hole) + resp, err := http.Get(*url + "/wormhole/" + hole + "/ready") + if err != nil { + return err + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("%s", resp.Status) + } + if _, err := io.Copy(io.Discard, resp.Body); err != nil { + return err + } + pipeReader, pipeWriter := io.Pipe() + multipartWriter := multipart.NewWriter(pipeWriter) + go func() { + defer pipeWriter.Close() + part, err := multipartWriter.CreateFormFile("file", fileName) + if err != nil { + fmt.Fprintln(os.Stderr, err) + return + } + if _, err := io.Copy(part, f); err != nil { + fmt.Fprintln(os.Stderr, err) + return + } + if err := multipartWriter.Close(); err != nil { + fmt.Fprintln(os.Stderr, err) + return + } + }() + resp, err = http.Post(*url+"/wormhole/"+hole, multipartWriter.FormDataContentType(), pipeReader) + if err != nil { + return fmt.Errorf("upload: %s", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("%s", resp.Status) + } + io.Copy(os.Stderr, resp.Body) + fmt.Fprintln(os.Stderr) + return nil +} + +func main() { + flag.Parse() + if err := hole(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} |
