// TODO LEGACY API: remove when legacy API removed func UploadCheck(cfg *config.Configuration, oid string, size int64) (*ObjectResource, error) { reqObj := &ObjectResource{ Oid: oid, Size: size, } by, err := json.Marshal(reqObj) if err != nil { return nil, errors.Wrap(err, "upload check") } req, err := NewRequest(cfg, "POST", oid) if err != nil { return nil, errors.Wrap(err, "upload check") } req.Header.Set("Content-Type", MediaType) req.Header.Set("Content-Length", strconv.Itoa(len(by))) req.ContentLength = int64(len(by)) req.Body = tools.NewReadSeekCloserWrapper(bytes.NewReader(by)) tracerx.Printf("api: uploading (%s)", oid) res, obj, err := DoLegacyRequest(cfg, req) if err != nil { if errors.IsAuthError(err) { httputil.SetAuthType(cfg, req, res) return UploadCheck(cfg, oid, size) } return nil, errors.NewRetriableError(err) } httputil.LogTransfer(cfg, "lfs.upload", res) if res.StatusCode == 200 { return nil, nil } if obj.Oid == "" { obj.Oid = oid } if obj.Size == 0 { obj.Size = reqObj.Size } return obj, nil }
// Internal http request management func doHttpRequest(cfg *config.Configuration, req *http.Request, creds auth.Creds) (*http.Response, error) { var ( res *http.Response cause string err error ) if cfg.NtlmAccess(auth.GetOperationForRequest(req)) { cause = "ntlm" res, err = doNTLMRequest(cfg, req, true) } else { cause = "http" res, err = NewHttpClient(cfg, req.Host).Do(req) } if res == nil { res = &http.Response{ StatusCode: 0, Header: make(http.Header), Request: req, Body: ioutil.NopCloser(bytes.NewBufferString("")), } } if err != nil { if errors.IsAuthError(err) { SetAuthType(cfg, req, res) doHttpRequest(cfg, req, creds) } else { err = errors.Wrap(err, cause) } } else { err = handleResponse(cfg, res, creds) } if err != nil { if res != nil { SetErrorResponseContext(cfg, err, res) } else { setErrorRequestContext(cfg, err, req) } } return res, err }
// Batch calls the batch API and returns object results func Batch(cfg *config.Configuration, objects []*ObjectResource, operation string, transferAdapters []string) (objs []*ObjectResource, transferAdapter string, e error) { if len(objects) == 0 { return nil, "", nil } // Compatibility; omit transfers list when only basic // older schemas included `additionalproperties=false` if len(transferAdapters) == 1 && transferAdapters[0] == "basic" { transferAdapters = nil } o := &batchRequest{Operation: operation, Objects: objects, TransferAdapterNames: transferAdapters} by, err := json.Marshal(o) if err != nil { return nil, "", errors.Wrap(err, "batch request") } req, err := NewBatchRequest(cfg, operation) if err != nil { return nil, "", errors.Wrap(err, "batch request") } req.Header.Set("Content-Type", MediaType) req.Header.Set("Content-Length", strconv.Itoa(len(by))) req.ContentLength = int64(len(by)) req.Body = tools.NewReadSeekCloserWrapper(bytes.NewReader(by)) tracerx.Printf("api: batch %d files", len(objects)) res, bresp, err := DoBatchRequest(cfg, req) if err != nil { if res == nil { return nil, "", errors.NewRetriableError(err) } if res.StatusCode == 0 { return nil, "", errors.NewRetriableError(err) } if errors.IsAuthError(err) { httputil.SetAuthType(cfg, req, res) return Batch(cfg, objects, operation, transferAdapters) } switch res.StatusCode { case 404, 410: return nil, "", errors.NewNotImplementedError(errors.Errorf("api: batch not implemented: %d", res.StatusCode)) } tracerx.Printf("api error: %s", err) return nil, "", errors.Wrap(err, "batch response") } httputil.LogTransfer(cfg, "lfs.batch", res) if res.StatusCode != 200 { return nil, "", errors.Errorf("Invalid status for %s: %d", httputil.TraceHttpReq(req), res.StatusCode) } return bresp.Objects, bresp.TransferAdapterName, nil }