bfile_cli/main.go

115 lines
2.7 KiB
Go

package main
import "os"
import "fmt"
import "time"
import "mime"
import "bytes"
import "strings"
import "net/http"
import "io/ioutil"
import "path/filepath"
import "mime/multipart"
import "net/textproto"
import "github.com/alecthomas/kong"
var (
version string // To be set by compiler
)
var Args struct {
Upload struct {
Filename string `optional:"" short:"n" help:"A short name by which the file can be accessed"`
File string `arg:"" help:"The URL or a path to a file to upload"`
Instance string `arg:"" help:"The URL of the instance to upload the file to"`
Tos bool `short:"t" default:"false"`
} `cmd:"" help:"Upload a file"`
}
func upload(args *kong.Context) {
if strings.HasSuffix(Args.Upload.Instance, "/") {
fmt.Fprintf(os.Stderr, "Error: instance URL must not end with /\n")
os.Exit(1)
}
if ! Args.Upload.Tos {
fmt.Println("You must agree to the ToS!");
fmt.Println("It can be found at", Args.Upload.Instance + "/tos")
os.Exit(2)
}
if _, err := os.Stat(Args.Upload.File); err != nil {
fmt.Fprintf(os.Stderr, "Error: can't read file %s\n", Args.Upload.File)
os.Exit(1)
}
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
ftype := mime.TypeByExtension(filepath.Ext(Args.Upload.File))
if ftype == "" {
ftype = "application/x-octet-stream"
}
fileHeader := textproto.MIMEHeader{}
fileHeader.Set("Content-Type", ftype)
fileHeader.Set("Content-Disposition", fmt.Sprintf("form-data; name=\"file\"; filename=\"%s\"", Args.Upload.File))
part, err := writer.CreatePart(fileHeader)
if err != nil {
panic(err)
}
file, err := ioutil.ReadFile(Args.Upload.File)
if err != nil {
panic(err)
}
part.Write([]byte(file))
tosHeader := textproto.MIMEHeader{}
tosHeader.Set("Content-Type", "text/plain")
tosHeader.Set("Content-Disposition", fmt.Sprintf("form-data; name=\"tos_consent\"; filename=\"%s\"", Args.Upload.File))
tos, err := writer.CreatePart(tosHeader)
if err != nil {
panic(err)
}
tos.Write([]byte("on"))
writer.Close()
req, err := http.NewRequest("POST", Args.Upload.Instance + "/curlapi/upload", body)
if err != nil {
panic(err)
}
cType := writer.FormDataContentType()
req.Header.Set("Content-Type", cType)
req.Header.Set("Content-Length", fmt.Sprintf("%d", body.Len()))
client := &http.Client{Timeout: 120 * time.Second}
api, err := client.Do(req)
if err != nil {
panic(err)
}
defer api.Body.Close()
data, err := ioutil.ReadAll(api.Body)
if err != nil {
panic(err)
}
fmt.Println(string(data))
}
func main() {
args := kong.Parse(&Args, kong.Description(fmt.Sprintf("The blek! File CLI %s", version)))
switch args.Command() {
case "upload <file> <instance>":
upload(args)
default:
panic(args.Command())
}
}