summaryrefslogtreecommitdiffstats
path: root/tools/hole
diff options
context:
space:
mode:
Diffstat (limited to 'tools/hole')
-rw-r--r--tools/hole/hole.go91
1 files changed, 91 insertions, 0 deletions
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)
+ }
+}