1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
|
package lfstransfer
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"net/http"
"time"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/config"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet"
)
type Client struct {
config *config.Config
args *commandargs.Shell
href string
auth string
}
type BatchAction struct {
Href string `json:"href"`
Header map[string]string `json:"header,omitempty"`
ExpiresAt time.Time `json:"expires_at,omitempty"`
ExpiresIn int `json:"expires_in,omitempty"`
}
type BatchObject struct {
Oid string `json:"oid,omitempty"`
Size int64 `json:"size"`
Authenticated bool `json:"authenticated,omitempty"`
Actions map[string]*BatchAction `json:"actions,omitempty"`
}
type batchRef struct {
Name string `json:"name,omitempty"`
}
type batchRequest struct {
Operation string `json:"operation"`
Objects []*BatchObject `json:"objects"`
Ref *batchRef `json:"ref,omitempty"`
HashAlgorithm string `json:"hash_algo,omitempty"`
}
type BatchResponse struct {
Objects []*BatchObject `json:"objects"`
HashAlgorithm string `json:"hash_algo,omitempty"`
}
func NewClient(config *config.Config, args *commandargs.Shell, href string, auth string) (*Client, error) {
return &Client{config: config, args: args, href: href, auth: auth}, nil
}
func (c *Client) Batch(operation string, reqObjects []*BatchObject, ref string, reqHashAlgo string) (*BatchResponse, error) {
var bref *batchRef
// FIXME: This causes tests to fail
// if ref == "" {
// return nil, errors.New("A ref must be specified.")
// }
bref = &batchRef{Name: ref}
body := batchRequest{
Operation: operation,
Objects: reqObjects,
Ref: bref,
HashAlgorithm: reqHashAlgo,
}
jsonData, err := json.Marshal(body)
if err != nil {
return nil, err
}
jsonReader := bytes.NewReader(jsonData)
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/objects/batch", c.href), jsonReader)
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/vnd.git-lfs+json")
req.Header.Set("Authorization", c.auth)
client := http.Client{}
res, err := client.Do(req)
if err != nil {
return nil, err
}
// Error condition taken from example: https://pkg.go.dev/net/http#example-Get
if res.StatusCode > 399 {
return nil, errors.New(fmt.Sprintf("Response failed with status code: %d", res.StatusCode))
}
defer func() { _ = res.Body.Close() }()
response := &BatchResponse{}
if err := gitlabnet.ParseJSON(res, response); err != nil {
return nil, err
}
return response, nil
}
|