117 lines
2.7 KiB
Go
117 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
|
|
)
|
|
|
|
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() {
|
|
version = "1.0.0"
|
|
|
|
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())
|
|
}
|
|
} |