objects: Escape names in Gophercloud#2821
Conversation
|
TODO:
|
6425888 to
700520e
Compare
700520e to
a1d5368
Compare
d4341f5 to
8f398f8
Compare
8f398f8 to
7c35633
Compare
7c35633 to
04e5b36
Compare
d08c293 to
bcebe30
Compare
bcebe30 to
89ae5cd
Compare
89ae5cd to
50a9cf7
Compare
b5c0fe2 to
0254522
Compare
0254522 to
7fa945d
Compare
7fa945d to
26ef2f7
Compare
26ef2f7 to
104cb14
Compare
104cb14 to
3e398db
Compare
3e398db to
4c35c1f
Compare
With this change, container and object names passed to the Gophercloud functions in `objectstorage/v1/containers` and `objectstorage/v1/objects` are now URL-escaped. If you were escaping them prior to passing them to Gophercloud, you should now remove escaping and pass the intended name to Gophercloud directly. **This is a breaking change.** API CHANGES: * Before this change, container and object names were sent as-is to Swift. With this change, **Gophercloud now escapes container and object names in all `objects` and `containers` functions**. If you were previously escaping names ( with, for example: `url.PathEscape` or `url.QueryEscape`), then you should REMOVE that and pass the intended names to Gophercloud directly. * The **`containers.ListOpts#Full` and `objects.ListOpts#Full` properties are REMOVED** from the Gophercloud API. The reason for that is: plaintext listing is unfixably wrong and won't handle special characters reliably (i.e. `\n`). * Empty container names, container names containing a slash (`/`), and empty object names are now rejected in Gophercloud before any call to Swift. * `containers.ErrInvalidContainerName` is now `v1.ErrInvalidContainerName` * New name validation errors: * `v1.ErrEmptyContainerName` * `v1.ErrEmptyObjectName` * In `objects.Copy`: the `destination` field (e.g. `objects.CopyOpts#Destination`) must be in the form `/container/object`: the function will reject a destination path if it doesn't start with a slash (`/`). CODE CHANGES: * `containers.List` and `objects.List` are now always setting `accept: application/json`. There is no plaintext listing any more, for the reason detailed above. * `containers` and `objects` acceptance tests are now run with nasty Unicode code points (including European characters, a space, "\n", backslash, slash where appropriate, emojis, emojis with modifiers, Chinese traditional characters), instead of only using nice ASCII characters. * Container and object names are now systematically validated before being sent to Swift. INCIDENTAL FIX: * it is now possible to successfuly call `objects.CreateTempURL` with a container name or object name containing the string `/v1/`.
4c35c1f to
9d0243f
Compare
| // Copy the contents of one object to another. | ||
| copyOpts := objects.CopyOpts{ | ||
| Destination: cName + "/" + oNames[1], | ||
| Destination: "/" + cName + "/" + oNames[1], |
There was a problem hiding this comment.
As per the docs: the Copy Destination header must be in the form of /container/object.
|
|
||
| // List all created objects | ||
| listOpts := objects.ListOpts{ | ||
| Full: true, |
There was a problem hiding this comment.
List option Full: false (accept: text/plain) doesn't work and should not be used
| for i := 0; i < len(oNames)-1; i++ { | ||
| oNames[i] = "test-object-" + tools.RandomFunnyString(8) | ||
| } | ||
| oNames[len(oNames)-1] = "test-object-with-/v1/-in-the-name" |
There was a problem hiding this comment.
There were two test cases. Now there are three: the last one tests that we correctly split the object path in CreateTempURL.
| }() | ||
|
|
||
| listOpts := objects.ListOpts{ | ||
| Full: true, |
There was a problem hiding this comment.
List option Full: false (accept: text/plain) doesn't work and should not be used. We always list "full" now (accept: application/json).
| } | ||
|
|
||
| listOpts = objects.ListOpts{ | ||
| Full: true, |
There was a problem hiding this comment.
List option Full: false (accept: text/plain) doesn't work and should not be used. We always list "full" now (accept: application/json).
|
|
||
| const forbiddenContainerRunes = "/" | ||
|
|
||
| func CheckContainerName(s string) error { |
There was a problem hiding this comment.
Moved to the parent directory v1
|
|
||
| // Copy is a function that copies one object to another. | ||
| func Copy(c *gophercloud.ServiceClient, containerName, objectName string, opts CopyOptsBuilder) (r CopyResult) { | ||
| url, err := copyURL(c, containerName, objectName) |
There was a problem hiding this comment.
moving this just a bit down below, just because url shadows the net/url package which we need for escaping.
| if err != nil { | ||
| return "", err | ||
| } | ||
| urlToBeSigned, err := tempURL(c, containerName, objectName) |
There was a problem hiding this comment.
We need two different URLs: one with non-escaped names (which will be signed), and one with escaped names (which will be used as the actual URL to send back to the caller). Documented here: https://docs.openstack.org/swift/latest/api/temporary_url_middleware.html#hmac-signature-for-temporary-urls
| } | ||
|
|
||
| secretKey := []byte(tempURLKey) | ||
| splitPath := strings.Split(url, opts.Split) |
There was a problem hiding this comment.
incidental fix: Split splits url each time opts.Split (default: /v1/) is found. But below, we only joined the first two parts back into a full URL. Which means that a path like https://swift/v1/AUTH_123/container/my/v1/object became https://swift/v1/AUTH_123/container/my (see #2827)
| // ExpectedListNames is the result expected from a call to `List` when just | ||
| // object names are requested. | ||
| var ExpectedListNames = []string{"hello", "goodbye"} | ||
| var ExpectedListNames = []string{"goodbye", "hello"} |
There was a problem hiding this comment.
I am not sure how this ever worked. Objects are always returned lexicographically sorted.
With this change, container and object names passed to the Gophercloud functions in
objectstorage/v1/containersandobjectstorage/v1/objectsare now URL-escaped. If you were escaping them prior to passing them to Gophercloud, you should now remove escaping and pass the intended name to Gophercloud directly.This is a breaking change.
API CHANGES:
objectsandcontainersfunctions. If you were previously escaping names ( with, for example:url.PathEscapeorurl.QueryEscape), then you should REMOVE that and pass the intended names to Gophercloud directlycontainers.ListOpts#Fullandobjects.ListOpts#Fullproperties are REMOVED from the Gophercloud API. The reason for that is: plaintext listing is unfixably wrong and won't handle special characters reliably (i.e.\n)./), and empty object names are now rejected in Gophercloud before any call to Swift.containers.ErrInvalidContainerNameis nowv1.ErrInvalidContainerNamev1.ErrEmptyContainerNamev1.ErrEmptyObjectNameobjects.Copy: thedestinationfield (e.g.objects.CopyOpts#Destination) must be in the form/container/object: the function will reject a destination path if it doesn't start with a slash (/).CODE CHANGES:
containers.Listandobjects.Listare now always settingaccept: application/json. There is no plaintext listing any more, for the reason detailed above.containersandobjectsacceptance tests are now run with nasty Unicode code points (including European characters, a space, "\n", backslash, slash where appropriate, emojis, emojis with modifiers, Chinese traditional characters), instead of only using nice ASCII characters.INCIDENTAL FIX:
objects.CreateTempURLwith a container name or object name containing the string/v1/.Fixes #2816
Fixes #2547
Fixes #2827