2019-10-17 00:35:08 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/sha1"
|
|
|
|
"encoding/hex"
|
|
|
|
"flag"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"log"
|
|
|
|
"net/http"
|
|
|
|
"os"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
token = flag.String("token", "", "Upload token")
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
flag.Parse()
|
|
|
|
|
|
|
|
args := flag.Args()
|
|
|
|
if len(args) != 2 {
|
|
|
|
fmt.Print("source file and target URL are required")
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
|
|
|
|
inPath := args[0]
|
|
|
|
outURL := args[1]
|
|
|
|
|
|
|
|
in, err := os.Open(inPath)
|
|
|
|
fail(err)
|
|
|
|
|
2019-10-18 00:41:16 +00:00
|
|
|
defer in.Close()
|
|
|
|
|
2019-10-17 00:35:08 +00:00
|
|
|
// hash the file
|
|
|
|
log.Print("hashing...")
|
|
|
|
h := sha1.New()
|
|
|
|
_, err = io.Copy(h, in)
|
|
|
|
fail(err)
|
|
|
|
|
|
|
|
sha1Hex := hex.EncodeToString(h.Sum(nil))
|
|
|
|
|
|
|
|
log.Print("SHA1 of source: ", sha1Hex)
|
|
|
|
|
2019-10-18 00:41:16 +00:00
|
|
|
// check remote
|
|
|
|
head, err := http.Head(outURL)
|
|
|
|
fail(err)
|
|
|
|
|
|
|
|
if head.StatusCode == 200 {
|
|
|
|
remoteSHA1 := head.Header.Get("X-Content-SHA1")
|
|
|
|
if sha1Hex == remoteSHA1 {
|
|
|
|
log.Print("remote is already up-to-date")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-17 00:35:08 +00:00
|
|
|
// rewind
|
|
|
|
_, err = in.Seek(0, os.SEEK_SET)
|
|
|
|
fail(err)
|
|
|
|
|
|
|
|
// upload
|
|
|
|
req, err := http.NewRequest("POST", outURL, in)
|
|
|
|
fail(err)
|
|
|
|
|
2020-10-02 04:40:57 +00:00
|
|
|
req.Header.Set("Authorization", "Bearer "+*token)
|
2019-10-17 00:35:08 +00:00
|
|
|
req.Header.Set("X-Content-SHA1", sha1Hex)
|
|
|
|
|
|
|
|
log.Print("uploading...")
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
fail(err)
|
|
|
|
|
|
|
|
if resp.StatusCode != http.StatusCreated {
|
|
|
|
log.Fatalf("unexpected HTTP status: %s", resp.Status)
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Print("uploaded successfully")
|
|
|
|
}
|
|
|
|
|
|
|
|
func fail(err error) {
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|