From bd23c64a1283835f5991444bb47ec3da1895ff42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20J=C3=A4ckel?= Date: Mon, 1 Jul 2024 13:05:01 +0200 Subject: Fix gophercloud lint complains --- account.go | 8 +-- backend.go | 22 ++++---- bulk.go | 60 +++++++++++----------- container.go | 2 +- container_iterator.go | 18 +++---- errors.go | 54 ++++++++++---------- iterator.go | 4 +- largeobject.go | 136 +++++++++++++++++++++++++------------------------- largeobject_test.go | 6 +-- object.go | 80 ++++++++++++++--------------- object_iterator.go | 40 +++++++-------- object_test.go | 8 +-- request.go | 24 ++++----- 13 files changed, 231 insertions(+), 231 deletions(-) diff --git a/account.go b/account.go index 90139cc..cdccc78 100644 --- a/account.go +++ b/account.go @@ -32,10 +32,10 @@ import ( // upwards from a container with Container.Account(). type Account struct { backend Backend - //URL parts + // URL parts baseURL string name string - //cache + // cache headers *AccountHeaders caps *Capabilities capsMutex sync.Mutex @@ -216,8 +216,8 @@ func (a *Account) Capabilities() (Capabilities, error) { // this account, and returns the response body. Unlike Account.Capabilities, // this method does not employ any caching. func (a *Account) RawCapabilities() ([]byte, error) { - //This method is the only one in Schwift that bypasses struct Request since - //the request URL is not below the endpoint URL. + // This method is the only one in Schwift that bypasses struct Request since + // the request URL is not below the endpoint URL. req, err := http.NewRequestWithContext(context.TODO(), http.MethodGet, a.baseURL+"info", http.NoBody) if err != nil { return nil, err diff --git a/backend.go b/backend.go index 9a7bfc3..e45822f 100644 --- a/backend.go +++ b/backend.go @@ -26,20 +26,20 @@ import ( // authentication for it. Each instance of Backend represents a particular Swift // account. type Backend interface { - //EndpointURL returns the endpoint URL from the Keystone catalog for the - //Swift account that this backend operates on. It should look like - //`http://domain.tld/v1/AUTH_projectid/`. The trailing slash is required. + // EndpointURL returns the endpoint URL from the Keystone catalog for the + // Swift account that this backend operates on. It should look like + // `http://domain.tld/v1/AUTH_projectid/`. The trailing slash is required. EndpointURL() string - //Clone returns a deep clone of this backend with the endpoint URL changed to - //the given URL. This is used by Account.SwitchAccount(). + // Clone returns a deep clone of this backend with the endpoint URL changed to + // the given URL. This is used by Account.SwitchAccount(). Clone(newEndpointURL string) Backend - //Do executes the given HTTP request after adding to it the X-Auth-Token - //header containing the backend's current Keystone (or Swift auth) token. If - //the status code returned is 401, it shall attempt to acquire a new auth - //token and restart the request with the new token. + // Do executes the given HTTP request after adding to it the X-Auth-Token + // header containing the backend's current Keystone (or Swift auth) token. If + // the status code returned is 401, it shall attempt to acquire a new auth + // token and restart the request with the new token. // - //If the user has not supplied their own User-Agent string to the backend, - //the backend should use the schwift.DefaultUserAgent constant instead. + // If the user has not supplied their own User-Agent string to the backend, + // the backend should use the schwift.DefaultUserAgent constant instead. Do(req *http.Request) (*http.Response, error) } diff --git a/bulk.go b/bulk.go index d8b96ca..e0d3f0b 100644 --- a/bulk.go +++ b/bulk.go @@ -35,11 +35,11 @@ import ( type BulkUploadFormat string const ( - //BulkUploadTar is a plain tar archive. + // BulkUploadTar is a plain tar archive. BulkUploadTar BulkUploadFormat = "tar" - //BulkUploadTarGzip is a GZip-compressed tar archive. + // BulkUploadTarGzip is a GZip-compressed tar archive. BulkUploadTarGzip BulkUploadFormat = "tar.gz" - //BulkUploadTarBzip2 is a BZip2-compressed tar archive. + // BulkUploadTarBzip2 is a BZip2-compressed tar archive. BulkUploadTarBzip2 BulkUploadFormat = "tar.bz2" ) @@ -99,7 +99,7 @@ func (a *Account) BulkUpload(uploadPath string, format BulkUploadFormat, content } func parseResponseStatus(status string) (int, error) { - //`status` looks like "201 Created" + // `status` looks like "201 Created" fields := strings.SplitN(status, " ", 2) return strconv.Atoi(fields[0]) } @@ -144,7 +144,7 @@ func makeBulkObjectError(fullName string, statusCode int) BulkObjectError { // containers must all be located in the given account. (Otherwise, // ErrAccountMismatch is returned.) func (a *Account) BulkDelete(objects []*Object, containers []*Container, opts *RequestOptions) (numDeleted, numNotFound int, deleteError error) { - //validate that all given objects are in this account + // validate that all given objects are in this account for _, obj := range objects { if !a.IsEqualTo(obj.Container().Account()) { return 0, 0, ErrAccountMismatch @@ -156,7 +156,7 @@ func (a *Account) BulkDelete(objects []*Object, containers []*Container, opts *R } } - //check capabilities to choose deletion method + // check capabilities to choose deletion method caps, err := a.Capabilities() if err != nil { return 0, 0, err @@ -166,24 +166,24 @@ func (a *Account) BulkDelete(objects []*Object, containers []*Container, opts *R } chunkSize := int(caps.BulkDelete.MaximumDeletesPerRequest) - //collect names of things to delete into one big list + // collect names of things to delete into one big list var names []string for _, object := range objects { - object.Invalidate() //deletion must invalidate objects! + object.Invalidate() // deletion must invalidate objects! names = append(names, fmt.Sprintf("/%s/%s", url.PathEscape(object.Container().Name()), url.PathEscape(object.Name()), )) } for _, container := range containers { - container.Invalidate() //deletion must invalidate objects! + container.Invalidate() // deletion must invalidate objects! names = append(names, "/"+url.PathEscape(container.Name())) } - //split list into chunks according to maximum allowed - //chunk size; aggregate results + // split list into chunks according to maximum allowed + // chunk size; aggregate results for len(names) > 0 { - //this condition holds only in the final iteration + // this condition holds only in the final iteration if chunkSize > len(names) { chunkSize = len(names) } @@ -223,12 +223,12 @@ func (a *Account) bulkDeleteSingle(objects []*Object, containers []*Container, o }) return nil } - //unexpected error type -> stop early + // unexpected error type -> stop early return err } for _, obj := range objects { - err := obj.Delete(nil, opts) //this implies Invalidate() + err := obj.Delete(nil, opts) // this implies Invalidate() err = handleSingleError(obj.Container().Name(), obj.Name(), err) if err != nil { return numDeleted, numNotFound, err @@ -236,7 +236,7 @@ func (a *Account) bulkDeleteSingle(objects []*Object, containers []*Container, o } for _, container := range containers { - err := container.Delete(opts) //this implies Invalidate() + err := container.Delete(opts) // this implies Invalidate() err = handleSingleError(container.Name(), "", err) if err != nil { return numDeleted, numNotFound, err @@ -276,22 +276,22 @@ func (a *Account) bulkDelete(names []string, opts *RequestOptions) (numDeleted, } type bulkResponse struct { - //ResponseStatus indicates the overall result as a HTTP status string, e.g. - //"201 Created" or "500 Internal Error". + // ResponseStatus indicates the overall result as a HTTP status string, e.g. + // "201 Created" or "500 Internal Error". ResponseStatus string `json:"Response Status"` - //ResponseBody contains an overall error message for errors that are not - //related to a single file in the archive (e.g. "invalid tar file" or "Max - //delete failures exceeded"). + // ResponseBody contains an overall error message for errors that are not + // related to a single file in the archive (e.g. "invalid tar file" or "Max + // delete failures exceeded"). ResponseBody string `json:"Response Body"` - //Errors contains error messages for individual files. Each entry is a - //[]string with 2 elements, the object's fullName and the HTTP status for - //this file's upload (e.g. "412 Precondition Failed"). + // Errors contains error messages for individual files. Each entry is a + // []string with 2 elements, the object's fullName and the HTTP status for + // this file's upload (e.g. "412 Precondition Failed"). Errors [][]string `json:"Errors"` - //NumberFilesCreated is included in the BulkUpload result only. + // NumberFilesCreated is included in the BulkUpload result only. NumberFilesCreated int `json:"Number Files Created"` - //NumberDeleted is included in the BulkDelete result only. + // NumberDeleted is included in the BulkDelete result only. NumberDeleted int `json:"Number Deleted"` - //NumberNotFound is included in the BulkDelete result only. + // NumberNotFound is included in the BulkDelete result only. NumberNotFound int `json:"Number Not Found"` } @@ -306,7 +306,7 @@ func parseBulkResponse(body io.ReadCloser) (bulkResponse, error) { return resp, err } - //parse `resp` into type BulkError + // parse `resp` into type BulkError bulkErr := BulkError{ OverallError: resp.ResponseBody, } @@ -316,7 +316,7 @@ func parseBulkResponse(body io.ReadCloser) (bulkResponse, error) { } for _, suberr := range resp.Errors { if len(suberr) != 2 { - continue //wtf + continue // wtf } statusCode, err := parseResponseStatus(suberr[1]) if err != nil { @@ -327,11 +327,11 @@ func parseBulkResponse(body io.ReadCloser) (bulkResponse, error) { ) } - //is BulkError really an error? + // is BulkError really an error? if len(bulkErr.ObjectErrors) == 0 && bulkErr.OverallError == "" && bulkErr.StatusCode >= 200 && bulkErr.StatusCode < 300 { return resp, nil } return resp, bulkErr //NOTE: `resp` is passed back to the caller to read the counters - //(resp.NumberFilesCreated etc.) + // (resp.NumberFilesCreated etc.) } diff --git a/container.go b/container.go index a1692d6..e5c57f3 100644 --- a/container.go +++ b/container.go @@ -28,7 +28,7 @@ import ( type Container struct { a *Account name string - //cache + // cache headers *ContainerHeaders } diff --git a/container_iterator.go b/container_iterator.go index 71f799d..ef0a77c 100644 --- a/container_iterator.go +++ b/container_iterator.go @@ -61,10 +61,10 @@ type ContainerInfo struct { // return only container names. type ContainerIterator struct { Account *Account - //When Prefix is set, only containers whose name starts with this string are - //returned. + // When Prefix is set, only containers whose name starts with this string are + // returned. Prefix string - //Options may contain additional headers and query parameters for the GET request. + // Options may contain additional headers and query parameters for the GET request. Options *RequestOptions base *iteratorBase @@ -114,7 +114,7 @@ func (i *ContainerIterator) NextPageDetailed(limit int) ([]ContainerInfo, error) return nil, err } if len(document) == 0 { - b.setMarker("") //indicate EOF to iteratorBase + b.setMarker("") // indicate EOF to iteratorBase return nil, nil } @@ -125,7 +125,7 @@ func (i *ContainerIterator) NextPageDetailed(limit int) ([]ContainerInfo, error) result[idx].ObjectCount = data.ObjectCount result[idx].LastModified, err = time.Parse(time.RFC3339Nano, data.LastModifiedStr+"Z") if err != nil { - //this error is sufficiently obscure that we don't need to expose a type for it + // this error is sufficiently obscure that we don't need to expose a type for it return nil, fmt.Errorf("bad field containers[%d].last_modified: %s", idx, err.Error()) } } @@ -144,7 +144,7 @@ func (i *ContainerIterator) Foreach(callback func(*Container) error) error { return err } if len(containers) == 0 { - return nil //EOF + return nil // EOF } for _, c := range containers { err := callback(c) @@ -163,7 +163,7 @@ func (i *ContainerIterator) ForeachDetailed(callback func(ContainerInfo) error) return err } if len(infos) == 0 { - return nil //EOF + return nil // EOF } for _, ci := range infos { err := callback(ci) @@ -185,7 +185,7 @@ func (i *ContainerIterator) Collect() ([]*Container, error) { return nil, err } if len(containers) == 0 { - return result, nil //EOF + return result, nil // EOF } result = append(result, containers...) } @@ -200,7 +200,7 @@ func (i *ContainerIterator) CollectDetailed() ([]ContainerInfo, error) { return nil, err } if len(infos) == 0 { - return result, nil //EOF + return result, nil // EOF } result = append(result, infos...) } diff --git a/errors.go b/errors.go index a79dd60..b41b895 100644 --- a/errors.go +++ b/errors.go @@ -29,32 +29,32 @@ import ( ) var ( - //ErrChecksumMismatch is returned by Object.Upload() when the Etag in the - //server response does not match the uploaded data. + // ErrChecksumMismatch is returned by Object.Upload() when the Etag in the + // server response does not match the uploaded data. ErrChecksumMismatch = errors.New("Etag on uploaded object does not match MD5 checksum of uploaded data") - //ErrNoContainerName is returned by Request.Do() if ObjectName is given, but - //ContainerName is empty. + // ErrNoContainerName is returned by Request.Do() if ObjectName is given, but + // ContainerName is empty. ErrNoContainerName = errors.New("missing container name") - //ErrMalformedContainerName is returned by Request.Do() if ContainerName - //contains slashes. + // ErrMalformedContainerName is returned by Request.Do() if ContainerName + // contains slashes. ErrMalformedContainerName = errors.New("container name may not contain slashes") - //ErrNotSupported is returned by bulk operations, large object operations, - //etc. if the server does not support the requested operation. + // ErrNotSupported is returned by bulk operations, large object operations, + // etc. if the server does not support the requested operation. ErrNotSupported = errors.New("operation not supported by this Swift server") - //ErrAccountMismatch is returned by operations on an account that accept - //containers/objects as arguments, if some or all of the provided - //containers/objects are located in a different account. + // ErrAccountMismatch is returned by operations on an account that accept + // containers/objects as arguments, if some or all of the provided + // containers/objects are located in a different account. ErrAccountMismatch = errors.New("some of the given objects are not in this account") - //ErrContainerMismatch is returned by operations on a container that accept - //objects as arguments, if some or all of the provided objects are located in - //a different container. + // ErrContainerMismatch is returned by operations on a container that accept + // objects as arguments, if some or all of the provided objects are located in + // a different container. ErrContainerMismatch = errors.New("some of the given objects are not in this container") - //ErrNotLarge is returned by Object.AsLargeObject() if the object does not - //exist, or if it is not a large object composed out of segments. + // ErrNotLarge is returned by Object.AsLargeObject() if the object does not + // exist, or if it is not a large object composed out of segments. ErrNotLarge = errors.New("not a large object") - //ErrSegmentInvalid is returned by LargeObject.AddSegment() if the segment - //provided is malformed or uses features not supported by the LargeObject's - //strategy. See documentation for LargeObject.AddSegment() for details. + // ErrSegmentInvalid is returned by LargeObject.AddSegment() if the segment + // provided is malformed or uses features not supported by the LargeObject's + // strategy. See documentation for LargeObject.AddSegment() for details. ErrSegmentInvalid = errors.New("segment invalid or incompatible with large object strategy") ) @@ -62,8 +62,8 @@ var ( // a response with the expected successful status code. The actual status code // can be checked with the Is() function; see documentation over there. type UnexpectedStatusCodeError struct { - Method string //e.g. http.MethodGet - Target string //either "" or "$CONTAINER_NAME" or "$CONTAINER_NAME/$OBJECT_NAME" + Method string // e.g. http.MethodGet + Target string // either "" or "$CONTAINER_NAME" or "$CONTAINER_NAME/$OBJECT_NAME" ExpectedStatusCodes []int ActualResponse *http.Response ResponseBody []byte @@ -81,7 +81,7 @@ func (e UnexpectedStatusCodeError) Error() string { ) if e.Method != "" && e.Target != "" { //NOTE: Method and Target were added in a minor version change, - //and may not be filled if `e` was constructed outside the library. + // and may not be filled if `e` was constructed outside the library. msg = fmt.Sprintf("could not %s %q in Swift: %s", e.Method, e.Target, msg) } if len(e.ResponseBody) > 0 { @@ -111,13 +111,13 @@ func (e BulkObjectError) Error() string { // saved in Swift; and by Account.BulkDelete() when not all requested objects // could be deleted. type BulkError struct { - //StatusCode contains the overall HTTP status code of the operation. + // StatusCode contains the overall HTTP status code of the operation. StatusCode int - //OverallError contains the fatal error that aborted the bulk operation, or a - //summary of which recoverable errors were encountered. It may be empty. + // OverallError contains the fatal error that aborted the bulk operation, or a + // summary of which recoverable errors were encountered. It may be empty. OverallError string - //ObjectErrors contains errors that occurred while working on individual - //objects or containers. It may be empty if no such errors occurred. + // ObjectErrors contains errors that occurred while working on individual + // objects or containers. It may be empty if no such errors occurred. ObjectErrors []BulkObjectError } diff --git a/iterator.go b/iterator.go index 6ae132b..8d451ac 100644 --- a/iterator.go +++ b/iterator.go @@ -33,8 +33,8 @@ type iteratorInterface interface { getDelimiter() string getPrefix() string getOptions() *RequestOptions - //putHeader initializes the AccountHeaders/ContainerHeaders field of the - //Account/Container using the response headers from the GET request. + // putHeader initializes the AccountHeaders/ContainerHeaders field of the + // Account/Container using the response headers from the GET request. putHeader(http.Header) error } diff --git a/largeobject.go b/largeobject.go index 4def0d0..44acca7 100644 --- a/largeobject.go +++ b/largeobject.go @@ -61,13 +61,13 @@ type SegmentInfo struct { Etag string RangeLength uint64 RangeOffset int64 - //Static Large Objects support data segments that are not backed by actual - //objects. For those kinds of segments, only the Data attribute is set and - //all other attributes are set to their default values (esp. .Object == nil). + // Static Large Objects support data segments that are not backed by actual + // objects. For those kinds of segments, only the Data attribute is set and + // all other attributes are set to their default values (esp. .Object == nil). // - //Data segments can only be used for small chunks of data because the SLO - //manifest (the list of all SegmentInfo encoded as JSON) is severely limited - //in size (usually to 8 MiB). + // Data segments can only be used for small chunks of data because the SLO + // manifest (the list of all SegmentInfo encoded as JSON) is severely limited + // in size (usually to 8 MiB). Data []byte } @@ -88,11 +88,11 @@ type LargeObjectStrategy int // strategies become available. The choice may also start to depend on the // capabilities advertised by the server. const ( - //StaticLargeObject is the default LargeObjectStrategy used by Schwift. + // StaticLargeObject is the default LargeObjectStrategy used by Schwift. StaticLargeObject LargeObjectStrategy = iota + 1 - //DynamicLargeObject is an older LargeObjectStrategy that is not recommended - //for new applications because of eventual consistency problems and missing - //support for several newer features (e.g. data segments, range specifications). + // DynamicLargeObject is an older LargeObjectStrategy that is not recommended + // for new applications because of eventual consistency problems and missing + // support for several newer features (e.g. data segments, range specifications). DynamicLargeObject ) @@ -183,7 +183,7 @@ func (lo *LargeObject) Strategy() LargeObjectStrategy { // Segments returns a list of all segments for this object, in order. func (lo *LargeObject) Segments() ([]SegmentInfo, error) { //NOTE: This method has an error return value because we might later switch - //to loading segments lazily inside this method. + // to loading segments lazily inside this method. return lo.segments, nil } @@ -199,7 +199,7 @@ func (lo *LargeObject) SegmentObjects() []*Object { seen := make(map[string]bool) result := make([]*Object, 0, len(lo.segments)) for _, segment := range lo.segments { - if segment.Object == nil { //can happen because of data segments + if segment.Object == nil { // can happen because of data segments continue } fullName := segment.Object.FullName() @@ -289,10 +289,10 @@ func (o *Object) asSLO() (*LargeObject, error) { return lo, nil } - //read the segments first, then deduce the SegmentContainer/SegmentPrefix from these + // read the segments first, then deduce the SegmentContainer/SegmentPrefix from these lo.segments = make([]SegmentInfo, 0, len(data)) for _, info := range data { - //option 1: data segment + // option 1: data segment if info.DataBase64 != "" { data, err := base64.StdEncoding.DecodeString(info.DataBase64) if err != nil { @@ -302,7 +302,7 @@ func (o *Object) asSLO() (*LargeObject, error) { continue } - //option 2: segment backed by object + // option 2: segment backed by object pathElements := strings.SplitN(strings.TrimPrefix(info.Path, "/"), "/", 2) if len(pathElements) != 2 { return nil, errors.New("invalid SLO segment: malformed path: " + info.Path) @@ -322,11 +322,11 @@ func (o *Object) asSLO() (*LargeObject, error) { lo.segments = append(lo.segments, s) } - //choose the SegmentContainer by majority vote (in the spirit of "be liberal - //in what you accept") + // choose the SegmentContainer by majority vote (in the spirit of "be liberal + // in what you accept") containerNames := make(map[string]uint) for _, s := range lo.segments { - if s.Object == nil { //can happen for data segments + if s.Object == nil { // can happen for data segments continue } containerNames[s.Object.c.Name()]++ @@ -341,11 +341,11 @@ func (o *Object) asSLO() (*LargeObject, error) { } lo.segmentContainer = lo.object.c.a.Container(maxName) - //choose the SegmentPrefix as the longest common prefix of all segments in - //the chosen SegmentContainer... + // choose the SegmentPrefix as the longest common prefix of all segments in + // the chosen SegmentContainer... names := make([]string, 0, len(lo.segments)) for _, s := range lo.segments { - if s.Object == nil { //can happen for data segments + if s.Object == nil { // can happen for data segments continue } name := s.Object.c.Name() @@ -355,9 +355,9 @@ func (o *Object) asSLO() (*LargeObject, error) { } lo.segmentPrefix = longestcommon.Prefix(names) - //..BUT if the prefix is a path with slashes, do not consider the part after - //the last slash; e.g. if we have segments "foo/bar/0001" and "foo/bar/0002", - //the longest common prefix is "foo/bar/000", but we actually want "foo/bar/" + // ..BUT if the prefix is a path with slashes, do not consider the part after + // the last slash; e.g. if we have segments "foo/bar/0001" and "foo/bar/0002", + // the longest common prefix is "foo/bar/000", but we actually want "foo/bar/" if strings.Contains(lo.segmentPrefix, "/") { lo.segmentPrefix = path.Dir(lo.segmentPrefix) + "/" } @@ -372,12 +372,12 @@ func parseHTTPRange(str string) (offsetVal int64, lengthVal uint64, ok bool) { } if fields[0] == "" { - //case 1: "-" + // case 1: "-" if fields[1] == "" { return 0, 0, true } - //case 2: "-N" + // case 2: "-N" numBytes, err := strconv.ParseUint(fields[1], 10, 64) if err != nil { return 0, 0, false @@ -385,15 +385,15 @@ func parseHTTPRange(str string) (offsetVal int64, lengthVal uint64, ok bool) { return -1, numBytes, true } - firstByte, err := strconv.ParseUint(fields[0], 10, 63) //not 64; needs to be unsigned, but also fit into int64 + firstByte, err := strconv.ParseUint(fields[0], 10, 63) // not 64; needs to be unsigned, but also fit into int64 if err != nil { return 0, 0, false } if fields[1] == "" { - //case 3: "N-" + // case 3: "N-" return int64(firstByte), 0, true } - //case 4: "M-N" + // case 4: "M-N" lastByte, err := strconv.ParseUint(fields[1], 10, 64) if err != nil || lastByte < firstByte { return 0, 0, false @@ -410,8 +410,8 @@ func parseHTTPRange(str string) (offsetVal int64, lengthVal uint64, ok bool) { // are initialized from the method's SegmentingOptions argument rather than from // the existing manifest. func (o *Object) AsNewLargeObject(sopts SegmentingOptions, topts *TruncateOptions) (*LargeObject, error) { - //we only need to load the existing large object if we want to do something - //with the old segments + // we only need to load the existing large object if we want to do something + // with the old segments if topts != nil && topts.DeleteSegments { lo, err := o.AsLargeObject() switch { @@ -421,15 +421,15 @@ func (o *Object) AsNewLargeObject(sopts SegmentingOptions, topts *TruncateOption return nil, err } case errors.Is(err, ErrNotLarge): - //not an error, continue down below + // not an error, continue down below default: - return nil, err //unexpected error + return nil, err // unexpected error } } lo := &LargeObject{object: o} - //validate segment container + // validate segment container lo.segmentContainer = sopts.SegmentContainer if sopts.SegmentContainer == nil { panic("missing value for sopts.SegmentingContainer") @@ -438,14 +438,14 @@ func (o *Object) AsNewLargeObject(sopts SegmentingOptions, topts *TruncateOption return nil, ErrAccountMismatch } - //apply default value for strategy + // apply default value for strategy if sopts.Strategy == 0 { lo.strategy = StaticLargeObject } else { lo.strategy = sopts.Strategy } - //apply default value for segmenting prefix + // apply default value for segmenting prefix lo.segmentPrefix = sopts.SegmentPrefix if lo.segmentPrefix == "" { now := time.Now() @@ -465,10 +465,10 @@ func (o *Object) AsNewLargeObject(sopts SegmentingOptions, topts *TruncateOption // TruncateOptions contains options that can be passed to LargeObject.Truncate() // and Object.AsNewLargeObject(). type TruncateOptions struct { - //When truncating a large object's manifest, delete its segments. - //This will cause Truncate() to call into BulkDelete(), so a BulkError may be - //returned. If this is false, the segments will not be deleted even though - //they may not be referenced by any large object anymore. + // When truncating a large object's manifest, delete its segments. + // This will cause Truncate() to call into BulkDelete(), so a BulkError may be + // returned. If this is false, the segments will not be deleted even though + // they may not be referenced by any large object anymore. DeleteSegments bool } @@ -511,21 +511,21 @@ func (lo *LargeObject) Truncate(opts *TruncateOptions) error { // lo.segmentContainer and lo.segmentPrefix, the first segment name is chosen as // lo.segmentPrefix + "0000000000000001". func (lo *LargeObject) NextSegmentObject() *Object { - //find the name of the last-most segment that is within the designated - //segment container and prefix + // find the name of the last-most segment that is within the designated + // segment container and prefix var prevSegmentName string for _, s := range lo.segments { o := s.Object - if o == nil { //can happen for data segments + if o == nil { // can happen for data segments continue } if lo.segmentContainer.IsEqualTo(o.c) && strings.HasPrefix(o.Name(), lo.segmentPrefix) { prevSegmentName = s.Object.Name() - //keep going, we want to find the last such segment + // keep going, we want to find the last such segment } } - //choose the next segment name based on the previous one + // choose the next segment name based on the previous one var segmentName string if prevSegmentName == "" { segmentName = lo.segmentPrefix + initialIndex @@ -550,14 +550,14 @@ func nextSegmentName(segmentName string) string { base, idxStr := match[1], match[2] idx, err := strconv.ParseUint(idxStr, 10, 64) - if err != nil || idx == math.MaxUint64 { //overflow - //start from one again, but separate with a dash to ensure that the new - //index can be parsed properly in the next call to this function + if err != nil || idx == math.MaxUint64 { // overflow + // start from one again, but separate with a dash to ensure that the new + // index can be parsed properly in the next call to this function return segmentName + "-" + initialIndex } - //print next index with same number of digits as previous index, - //e.g. "00001" -> "00002" (except if overflow, e.g. "9999" -> "10000") + // print next index with same number of digits as previous index, + // e.g. "00001" -> "00002" (except if overflow, e.g. "9999" -> "10000") formatStr := fmt.Sprintf("%%0%dd", len(idxStr)) return base + fmt.Sprintf(formatStr, idx+1) } @@ -589,10 +589,10 @@ func nextSegmentName(segmentName string) string { // large objects (DLOs do not support data segments). func (lo *LargeObject) AddSegment(segment SegmentInfo) error { if len(segment.Data) == 0 { - //validate segments backed by objects + // validate segments backed by objects o := segment.Object if o == nil { - //required attributes + // required attributes return ErrSegmentInvalid } if !o.c.a.IsEqualTo(lo.segmentContainer.a) { @@ -602,7 +602,7 @@ func (lo *LargeObject) AddSegment(segment SegmentInfo) error { switch lo.strategy { case DynamicLargeObject: if segment.RangeLength != 0 || segment.RangeOffset != 0 { - //not supported for DLO + // not supported for DLO return ErrSegmentInvalid } @@ -615,18 +615,18 @@ func (lo *LargeObject) AddSegment(segment SegmentInfo) error { case StaticLargeObject: if segment.RangeLength == 0 && segment.RangeOffset < 0 { - //malformed range + // malformed range return ErrSegmentInvalid } } } else { - //validate plain-data segments + // validate plain-data segments if lo.strategy != StaticLargeObject { - //not supported for DLO + // not supported for DLO return ErrSegmentInvalid } if segment.Object != nil || segment.SizeBytes != 0 || segment.Etag != "" || segment.RangeLength != 0 || segment.RangeOffset != 0 { - //all other attributes must be unset + // all other attributes must be unset return ErrSegmentInvalid } } @@ -665,7 +665,7 @@ func (lo *LargeObject) Append(contents io.Reader, segmentSizeBytes int64, opts * panic("segmentSizeBytes may not be negative") } if segmentSizeBytes == 0 { - //apply default value for segmenting size + // apply default value for segmenting size caps, err := lo.object.c.a.Capabilities() if err != nil { return err @@ -708,11 +708,11 @@ func (lo *LargeObject) Append(contents io.Reader, segmentSizeBytes int64, opts * type segmentingReader struct { Reader io.Reader - SegmentSizeBytes int64 //must be >0 + SegmentSizeBytes int64 // must be >0 } func (sr *segmentingReader) NextSegment() io.Reader { - //peek if there is more content in the backing reader + // peek if there is more content in the backing reader buf := make([]byte, 1) var ( n int @@ -722,18 +722,18 @@ func (sr *segmentingReader) NextSegment() io.Reader { n, err = sr.Reader.Read(buf) if err == io.EOF { if n == 0 { - //EOF encountered + // EOF encountered return nil } - //that was the last byte - return only that (next NextSegment() will return nil) + // that was the last byte - return only that (next NextSegment() will return nil) return bytes.NewReader(buf) } } - //looks like there is more stuff in the backing reader + // looks like there is more stuff in the backing reader return io.MultiReader( bytes.NewReader(buf), - io.LimitReader(sr.Reader, sr.SegmentSizeBytes-1), //1 == len(buf) + io.LimitReader(sr.Reader, sr.SegmentSizeBytes-1), // 1 == len(buf) ) } @@ -770,7 +770,7 @@ func (lo *LargeObject) WriteManifest(opts *RequestOptions) error { func (lo *LargeObject) writeDLOManifest(opts *RequestOptions) error { manifest := lo.segmentContainer.Name() + "/" + lo.segmentPrefix - //check if the manifest is already set correctly + // check if the manifest is already set correctly headers, err := lo.object.Headers() if err != nil && !Is(err, http.StatusNotFound) { return err @@ -779,7 +779,7 @@ func (lo *LargeObject) writeDLOManifest(opts *RequestOptions) error { return nil } - //write manifest; make sure that this is a DLO + // write manifest; make sure that this is a DLO opts = cloneRequestOptions(opts, nil) opts.Headers.Set("X-Object-Manifest", manifest) return lo.object.Upload(nil, nil, opts) @@ -813,12 +813,12 @@ func (lo *LargeObject) writeSLOManifest(opts *RequestOptions) error { manifest, err := json.Marshal(sloSegments) if err != nil { - //failing json.Marshal() on such a trivial data structure is alarming + // failing json.Marshal() on such a trivial data structure is alarming panic(err.Error()) } opts = cloneRequestOptions(opts, nil) - opts.Headers.Del("X-Object-Manifest") //ensure sanity :) + opts.Headers.Del("X-Object-Manifest") // ensure sanity :) opts.Values.Set("multipart-manifest", "put") return lo.object.Upload(bytes.NewReader(manifest), nil, opts) } diff --git a/largeobject_test.go b/largeobject_test.go index e5b790b..fc0a2e4 100644 --- a/largeobject_test.go +++ b/largeobject_test.go @@ -31,17 +31,17 @@ func TestParseHTTPRange(t *testing.T) { offset int64 length uint64 }{ - //all the testcases from RFC 7233, section 3.1 + // all the testcases from RFC 7233, section 3.1 {"0-499", true, 0, 500}, {"500-999", true, 500, 500}, {"-500", true, -1, 500}, {"9500-", true, 9500, 0}, {"0-0", true, 0, 1}, {"-1", true, -1, 1}, - //and then some more + // and then some more {"0-", true, 0, 0}, {"-", true, 0, 0}, - //some error cases for 100% coverage + // some error cases for 100% coverage {"no dash", false, 0, 0}, {"what-the-heck", false, 0, 0}, {"-X", false, 0, 0}, diff --git a/object.go b/object.go index 8e2becd..6e0dc92 100644 --- a/object.go +++ b/object.go @@ -41,9 +41,9 @@ import ( type Object struct { c *Container name string - //cache - headers *ObjectHeaders //from HEAD/GET without ?symlink=get - symlinkHeaders *ObjectHeaders //from HEAD/GET with ?symlink=get + // cache + headers *ObjectHeaders // from HEAD/GET without ?symlink=get + symlinkHeaders *ObjectHeaders // from HEAD/GET with ?symlink=get } // IsEqualTo returns true if both Object instances refer to the same object. @@ -128,8 +128,8 @@ func (o *Object) fetchHeaders(opts *RequestOptions) (*ObjectHeaders, error) { ContainerName: o.c.name, ObjectName: o.name, Options: opts, - //since Openstack LOVES to be inconsistent with everything (incl. itself), - //this returns 200 instead of 204 + // since Openstack LOVES to be inconsistent with everything (incl. itself), + // this returns 200 instead of 204 ExpectStatusCodes: []int{http.StatusOK}, DrainResponseBody: true, }.Do(o.c.a.backend) @@ -165,8 +165,8 @@ func (o *Object) Update(headers ObjectHeaders, opts *RequestOptions) error { // UploadOptions invokes advanced behavior in the Object.Upload() method. type UploadOptions struct { - //When overwriting a large object, delete its segments. This will cause - //Upload() to call into BulkDelete(), so a BulkError may be returned. + // When overwriting a large object, delete its segments. This will cause + // Upload() to call into BulkDelete(), so a BulkError may be returned. DeleteSegments bool } @@ -220,9 +220,9 @@ func (o *Object) Upload(content io.Reader, opts *UploadOptions, ropts *RequestOp } } - //do not attempt to add the Etag header when we're writing a large object - //manifest; the header refers to the content, but we would be computing the - //manifest's hash instead + // do not attempt to add the Etag header when we're writing a large object + // manifest; the header refers to the content, but we would be computing the + // manifest's hash instead isManifestUpload := ropts.Values.Get("multipart-manifest") == "put" || hdr.IsDynamicLargeObject() var hasher hash.Hash @@ -232,7 +232,7 @@ func (o *Object) Upload(content io.Reader, opts *UploadOptions, ropts *RequestOp return err } - //could not compute Etag in advance -> need to check on the fly + // could not compute Etag in advance -> need to check on the fly if !hdr.Etag().Exists() { hasher = md5.New() //nolint:gosec // Etag uses md5 if content != nil { @@ -243,19 +243,19 @@ func (o *Object) Upload(content io.Reader, opts *UploadOptions, ropts *RequestOp var lo *LargeObject if opts.DeleteSegments { - //enumerate segments in large object before overwriting it, but only delete - //the segments after successfully uploading the new object to decrease the - //chance of an inconsistent state following an upload error + // enumerate segments in large object before overwriting it, but only delete + // the segments after successfully uploading the new object to decrease the + // chance of an inconsistent state following an upload error var err error lo, err = o.AsLargeObject() switch { case err == nil: - //okay, delete segments at the end + // okay, delete segments at the end case errors.Is(err, ErrNotLarge): - //okay, do not try to delete segments + // okay, do not try to delete segments lo = nil default: - //unexpected error + // unexpected error return err } } @@ -293,8 +293,8 @@ func (o *Object) Upload(content io.Reader, opts *UploadOptions, ropts *RequestOp } type readerWithLen interface { - //Returns the number of bytes in the unread portion of the buffer. - //Implemented by bytes.Reader, bytes.Buffer and strings.Reader. + // Returns the number of bytes in the unread portion of the buffer. + // Implemented by bytes.Reader, bytes.Buffer and strings.Reader. Len() int } @@ -320,13 +320,13 @@ func tryComputeEtag(content io.Reader, headers ObjectHeaders) error { sum := md5.Sum(nil) h.Set(hex.EncodeToString(sum[:])) case *bytes.Buffer: - //bytes.Buffer has a method that returns the unread portion of the buffer, - //so this one is easy + // bytes.Buffer has a method that returns the unread portion of the buffer, + // so this one is easy sum := md5.Sum(r.Bytes()) h.Set(hex.EncodeToString(sum[:])) case io.ReadSeeker: - //bytes.Reader does not have such a method, but it is an io.Seeker, so we - //can read the entire thing and then seek back to where we started + // bytes.Reader does not have such a method, but it is an io.Seeker, so we + // can read the entire thing and then seek back to where we started md5Hash := md5.New() n, err := io.Copy(md5Hash, r) if err != nil { @@ -366,17 +366,17 @@ func (o *Object) UploadFromWriter(opts *UploadOptions, ropts *RequestOptions, ca errChan := make(chan error) go func() { err := o.Upload(reader, opts, ropts) - reader.CloseWithError(err) //stop the writer if it is still writing + reader.CloseWithError(err) // stop the writer if it is still writing errChan <- err }() - writer.CloseWithError(callback(writer)) //stop the reader if it is still reading + writer.CloseWithError(callback(writer)) // stop the reader if it is still reading return <-errChan } // DeleteOptions invokes advanced behavior in the Object.Delete() method. type DeleteOptions struct { - //When deleting a large object, also delete its segments. This will cause - //Delete() to call into BulkDelete(), so a BulkError may be returned. + // When deleting a large object, also delete its segments. This will cause + // Delete() to call into BulkDelete(), so a BulkError may be returned. DeleteSegments bool } @@ -399,14 +399,14 @@ func (o *Object) Delete(opts *DeleteOptions, ropts *RequestOptions) error { lo, err := o.AsLargeObject() switch { case err == nil: - //is large object - delete segments and the object itself in one step + // is large object - delete segments and the object itself in one step _, _, err := o.c.a.BulkDelete(append(lo.SegmentObjects(), o), nil, nil) o.Invalidate() return err case errors.Is(err, ErrNotLarge): - //not a large object - use regular DELETE request + // not a large object - use regular DELETE request default: - //unexpected error + // unexpected error return err } } @@ -477,10 +477,10 @@ func (o *Object) Download(opts *RequestOptions) DownloadedObject { // CopyOptions invokes advanced behavior in the Object.Copy() method. type CopyOptions struct { - //Copy only the object's content, not its metadata. New metadata can always - //be supplied in the RequestOptions argument of Object.CopyTo(). + // Copy only the object's content, not its metadata. New metadata can always + // be supplied in the RequestOptions argument of Object.CopyTo(). FreshMetadata bool - //When the source is a symlink, copy the symlink instead of the target object. + // When the source is a symlink, copy the symlink instead of the target object. ShallowCopySymlinks bool } @@ -520,8 +520,8 @@ func (o *Object) CopyTo(target *Object, opts *CopyOptions, ropts *RequestOptions // SymlinkOptions invokes advanced behavior in the Object.SymlinkTo() method. type SymlinkOptions struct { - //When overwriting a large object, delete its segments. This will cause - //SymlinkTo() to call into BulkDelete(), so a BulkError may be returned. + // When overwriting a large object, delete its segments. This will cause + // SymlinkTo() to call into BulkDelete(), so a BulkError may be returned. DeleteSegments bool } @@ -538,8 +538,8 @@ func (o *Object) SymlinkTo(target *Object, opts *SymlinkOptions, ropts *RequestO ropts.Headers.Set("X-Symlink-Target-Account", target.c.a.Name()) } if ropts.Headers.Get("Content-Type") == "" { - //recommended Content-Type for symlinks as per - // + // recommended Content-Type for symlinks as per + // ropts.Headers.Set("Content-Type", "application/symlink") } @@ -581,10 +581,10 @@ func (o *Object) SymlinkHeaders() (headers ObjectHeaders, target *Object, err er } } - //is this a symlink? + // is this a symlink? targetFullName := o.symlinkHeaders.Get("X-Symlink-Target") if targetFullName == "" { - //not a symlink - the o.symlinkHeaders are just the regular headers + // not a symlink - the o.symlinkHeaders are just the regular headers o.headers = o.symlinkHeaders return *o.headers, nil, nil } @@ -596,7 +596,7 @@ func (o *Object) SymlinkHeaders() (headers ObjectHeaders, target *Object, err er } } - //cross-account symlink? + // cross-account symlink? accountName := o.symlinkHeaders.Get("X-Symlink-Target-Account") targetAccount := o.c.a if accountName != "" && accountName != targetAccount.Name() { diff --git a/object_iterator.go b/object_iterator.go index 64b5551..c6efa78 100644 --- a/object_iterator.go +++ b/object_iterator.go @@ -34,12 +34,12 @@ type ObjectInfo struct { ContentType string Etag string LastModified time.Time - //SymlinkTarget is only set for symlinks. + // SymlinkTarget is only set for symlinks. SymlinkTarget *Object - //If the ObjectInfo refers to an actual object, then SubDirectory is empty. - //If the ObjectInfo refers to a pseudo-directory, then SubDirectory contains - //the path of the pseudo-directory and all other fields are nil/zero/empty. - //Pseudo-directories will only be reported for ObjectIterator.Delimiter != "". + // If the ObjectInfo refers to an actual object, then SubDirectory is empty. + // If the ObjectInfo refers to a pseudo-directory, then SubDirectory contains + // the path of the pseudo-directory and all other fields are nil/zero/empty. + // Pseudo-directories will only be reported for ObjectIterator.Delimiter != "". SubDirectory string } @@ -74,14 +74,14 @@ type ObjectInfo struct { // which case Exists() will return false. type ObjectIterator struct { Container *Container - //When Prefix is set, only objects whose name starts with this string are - //returned. + // When Prefix is set, only objects whose name starts with this string are + // returned. Prefix string - //When Delimiter is set, objects whose name contains this string (after the - //prefix, if any) will be condensed into pseudo-directories in the result. - //See documentation for Swift for details. + // When Delimiter is set, objects whose name contains this string (after the + // prefix, if any) will be condensed into pseudo-directories in the result. + // See documentation for Swift for details. Delimiter string - //Options may contain additional headers and query parameters for the GET request. + // Options may contain additional headers and query parameters for the GET request. Options *RequestOptions base *iteratorBase @@ -124,14 +124,14 @@ func (i *ObjectIterator) NextPageDetailed(limit int) ([]ObjectInfo, error) { b := i.getBase() var document []struct { - //either all of this: + // either all of this: SizeBytes uint64 `json:"bytes"` ContentType string `json:"content_type"` Etag string `json:"hash"` LastModifiedStr string `json:"last_modified"` Name string `json:"name"` SymlinkPath string `json:"symlink_path"` - //or just this: + // or just this: Subdir string `json:"subdir"` } err := b.nextPageDetailed(limit, &document) @@ -139,7 +139,7 @@ func (i *ObjectIterator) NextPageDetailed(limit int) ([]ObjectInfo, error) { return nil, err } if len(document) == 0 { - b.setMarker("") //indicate EOF to iteratorBase + b.setMarker("") // indicate EOF to iteratorBase return nil, nil } @@ -154,13 +154,13 @@ func (i *ObjectIterator) NextPageDetailed(limit int) ([]ObjectInfo, error) { result[idx].SizeBytes = data.SizeBytes result[idx].LastModified, err = time.Parse(time.RFC3339Nano, data.LastModifiedStr+"Z") if err != nil { - //this error is sufficiently obscure that we don't need to expose a type for it + // this error is sufficiently obscure that we don't need to expose a type for it return nil, fmt.Errorf("bad field objects[%d].last_modified: %s", idx, err.Error()) } if data.SymlinkPath != "" { match := symlinkPathRx.FindStringSubmatch(data.SymlinkPath) if match == nil { - //like above + // like above return nil, fmt.Errorf("bad field objects[%d].symlink_path: %q", idx, data.SymlinkPath) } a := i.Container.a @@ -189,7 +189,7 @@ func (i *ObjectIterator) Foreach(callback func(*Object) error) error { return err } if len(objects) == 0 { - return nil //EOF + return nil // EOF } for _, o := range objects { err := callback(o) @@ -208,7 +208,7 @@ func (i *ObjectIterator) ForeachDetailed(callback func(ObjectInfo) error) error return err } if len(infos) == 0 { - return nil //EOF + return nil // EOF } for _, ci := range infos { err := callback(ci) @@ -230,7 +230,7 @@ func (i *ObjectIterator) Collect() ([]*Object, error) { return nil, err } if len(objects) == 0 { - return result, nil //EOF + return result, nil // EOF } result = append(result, objects...) } @@ -245,7 +245,7 @@ func (i *ObjectIterator) CollectDetailed() ([]ObjectInfo, error) { return nil, err } if len(infos) == 0 { - return result, nil //EOF + return result, nil // EOF } result = append(result, infos...) } diff --git a/object_test.go b/object_test.go index a385434..e5ad385 100644 --- a/object_test.go +++ b/object_test.go @@ -59,8 +59,8 @@ func must(t *testing.T, err error) { } func TestObjectTempURLSha1Only(t *testing.T) { - //setup a bogus backend, account, container and object with exact names to - //reproducibly generate a temp URL + // setup a bogus backend, account, container and object with exact names to + // reproducibly generate a temp URL account, err := InitializeAccount(tempurlBogusBackend{ mockInfoText: `{ "tempurl": { "allowed_digests": [ "sha1" ]}}`, }) @@ -74,8 +74,8 @@ func TestObjectTempURLSha1Only(t *testing.T) { } func TestObjectTempURL(t *testing.T) { - //setup a bogus backend, account, container and object with exact names to - //reproducibly generate a temp URL + // setup a bogus backend, account, container and object with exact names to + // reproducibly generate a temp URL account, err := InitializeAccount(tempurlBogusBackend{ mockInfoText: `{ "tempurl": { "allowed_digests": [ "sha1", "sha256", "sha512"]}}`, }) diff --git a/request.go b/request.go index 01f052f..63d4963 100644 --- a/request.go +++ b/request.go @@ -65,16 +65,16 @@ func cloneRequestOptions(orig *RequestOptions, additional Headers) *RequestOptio // Request contains the parameters that can be set in a request to the Swift API. type Request struct { - Method string //"GET", "HEAD", "PUT", "POST" or "DELETE" - ContainerName string //empty for requests on accounts - ObjectName string //empty for requests on accounts/containers + Method string // "GET", "HEAD", "PUT", "POST" or "DELETE" + ContainerName string // empty for requests on accounts + ObjectName string // empty for requests on accounts/containers Options *RequestOptions Body io.Reader - //ExpectStatusCodes can be left empty to disable this check, otherwise - //schwift.UnexpectedStatusCodeError may be returned. + // ExpectStatusCodes can be left empty to disable this check, otherwise + // schwift.UnexpectedStatusCodeError may be returned. ExpectStatusCodes []int - //DrainResponseBody can be set if the caller is not interested in the - //response body. This is implied for Response.StatusCode == 204. + // DrainResponseBody can be set if the caller is not interested in the + // response body. This is implied for Response.StatusCode == 204. DrainResponseBody bool } @@ -107,7 +107,7 @@ func (r Request) URL(backend Backend, values url.Values) (string, error) { // Do executes this request on the given Backend. func (r Request) Do(backend Backend) (*http.Response, error) { - //build URL + // build URL var values url.Values if r.Options != nil { values = r.Options.Values @@ -117,7 +117,7 @@ func (r Request) Do(backend Backend) (*http.Response, error) { return nil, err } - //build request + // build request req, err := http.NewRequest(r.Method, uri, r.Body) if err != nil { return nil, err @@ -140,9 +140,9 @@ func (r Request) Do(backend Backend) (*http.Response, error) { return nil, err } - //return success if error code matches expectation + // return success if error code matches expectation if len(r.ExpectStatusCodes) == 0 { - //check disabled -> return response unaltered + // check disabled -> return response unaltered return resp, nil } for _, code := range r.ExpectStatusCodes { @@ -155,7 +155,7 @@ func (r Request) Do(backend Backend) (*http.Response, error) { } } - //unexpected status code -> generate error + // unexpected status code -> generate error buf, err := collectResponseBody(resp) if err != nil { return nil, err -- cgit v1.2.3