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) } }