[ https://issues.apache.org/jira/browse/JCLOUDS-1580?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Erik Ebert updated JCLOUDS-1580: -------------------------------- Description: I believe this is happening because jclouds/swift is specifically looking for user metadata with the prefix "X-Object-Meta-", case SENSITIVE: X-Object-Meta-foo But since header names are case-INSENSITIVE. per RFC 2616, this fails if the cloud provider returns header names in lower case: x-object-meta-foo I discovered this while using "openstack-swift" to access SAP's Converged Cloud, but it would affect any cloud provider that returns lower-case header names. In my case, this is an example of what is returned by Converged Cloud: curl <object url> --head -H "X-Auth-Token:<token>" HTTP/1.1 200 OK content-type: application/octet-stream *x-object-meta-original-created-time*: 1623984822180 *x-object-meta-content-md5*: rREHajOaHzUiU8DQoap9NA== etag: xxxxx last-modified: Fri, 18 Jun 2021 02:53:53 GMT x-timestamp: 1623984832.86825 accept-ranges: bytes content-length: 12 x-trans-id: xxxx x-openstack-request-id: xxxxx date: Fri, 18 Jun 2021 03:16:46 GMT Sample jclouds code: {code:java} BlobStoreContext blobStoreContext = ContextBuilder.newBuilder("openstack-swift") .endpoint(ENDPOINT) .credentials(INDENTITY, CREDENTIAL) .overrides(overrides) .buildApi(BlobStoreContext.class); BlobStore blobStore = blobStoreContext.getBlobStore(); BlobMetadata blobMetadata = blobStore.blobMetadata(CONTAINER, PATH); Map<String, String> userMetadata = blobMetadata.getUserMetadata() System.out.println(userMetadata.toString()) {code} blobMetadata.getUserMetadata() SHOULD return something like: *original-created-time*: 1623984822180 *content-md5*: rREHajOaHzUiU8DQoap9NA== (or similar), but instead it returns an empty Map object. Stepping through the code, I believe the source of the problem is line 41 of EntriesWithoutMetaPrefix.java: [https://github.com/apache/jclouds/blob/0b89ee0825d45de1193090cdd5efc5f1135fa200/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/EntriesWithoutMetaPrefix.java] Partial stack trace from the code example above: {code:java} at org.jclouds.openstack.swift.v1.functions.EntriesWithoutMetaPrefix.apply(EntriesWithoutMetaPrefix.java:41) at org.jclouds.openstack.swift.v1.functions.ParseObjectFromResponse.apply(ParseObjectFromResponse.java:81) at org.jclouds.openstack.swift.v1.functions.ParseObjectFromResponse.apply(ParseObjectFromResponse.java:41) at org.jclouds.rest.internal.InvokeHttpMethod.invoke(InvokeHttpMethod.java:91) at org.jclouds.rest.internal.InvokeHttpMethod.apply(InvokeHttpMethod.java:74) at org.jclouds.rest.internal.InvokeHttpMethod.apply(InvokeHttpMethod.java:45) at org.jclouds.reflect.FunctionalReflection$FunctionalInvocationHandler.handleInvocation(FunctionalReflection.java:117) at com.google.common.reflect.AbstractInvocationHandler.invoke(AbstractInvocationHandler.java:86) at com.sun.proxy.$Proxy199.getWithoutBody(Unknown Source:-1) {code} I believe the fix would be to change line 41 of EntriesWithoutMetaPrefix.java from int index = header.getKey().indexOf("-Meta-"); to something like: int index = header.getKey()*.toLowerCase()*.indexOf("*-meta-*"); {code:java} 41c41 < int index = header.getKey().indexOf("-Meta-"); --- > int index = header.getKey().toLowerCase().indexOf("-meta-"); {code} was: I believe this is happening because jclouds/swift is specifically looking for user metadata with the prefix "X-Object-Meta-", case SENSITIVE: X-Object-Meta-foo But since header names are case-INSENSITIVE. per RFC 2616, this fails if the cloud provider returns header names in lower case: x-object-meta-foo I discovered this while using "openstack-swift" to access SAP's Converged Cloud, but it would affect any cloud provider that returns lower-case header names. In my case, this is an example of what is returned by Converged Cloud: curl <object url> --head -H "X-Auth-Token:<token>" HTTP/1.1 200 OK content-type: application/octet-stream *x-object-meta-original-created-time*: 1623984822180 *x-object-meta-content-md5*: rREHajOaHzUiU8DQoap9NA== etag: xxxxx last-modified: Fri, 18 Jun 2021 02:53:53 GMT x-timestamp: 1623984832.86825 accept-ranges: bytes content-length: 12 x-trans-id: xxxx x-openstack-request-id: xxxxx date: Fri, 18 Jun 2021 03:16:46 GMT Sample jclouds code: {code:java} BlobStoreContext blobStoreContext = ContextBuilder.newBuilder(PROVIDER) .endpoint(ENDPOINT) .credentials(INDENTITY, CREDENTIAL) .overrides(overrides) .buildApi(BlobStoreContext.class); BlobStore blobStore = blobStoreContext.getBlobStore(); BlobMetadata blobMetadata = blobStore.blobMetadata(CONTAINER, PATH); Map<String, String> userMetadata = blobMetadata.getUserMetadata() System.out.println(userMetadata.toString()) {code} blobMetadata.getUserMetadata() SHOULD return something like: *original-created-time*: 1623984822180 *content-md5*: rREHajOaHzUiU8DQoap9NA== (or similar), but instead it returns an empty Map object. Stepping through the code, I believe the source of the problem is line 41 of EntriesWithoutMetaPrefix.java: [https://github.com/apache/jclouds/blob/0b89ee0825d45de1193090cdd5efc5f1135fa200/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/EntriesWithoutMetaPrefix.java] Partial stack trace from the code example above: {code:java} at org.jclouds.openstack.swift.v1.functions.EntriesWithoutMetaPrefix.apply(EntriesWithoutMetaPrefix.java:41) at org.jclouds.openstack.swift.v1.functions.ParseObjectFromResponse.apply(ParseObjectFromResponse.java:81) at org.jclouds.openstack.swift.v1.functions.ParseObjectFromResponse.apply(ParseObjectFromResponse.java:41) at org.jclouds.rest.internal.InvokeHttpMethod.invoke(InvokeHttpMethod.java:91) at org.jclouds.rest.internal.InvokeHttpMethod.apply(InvokeHttpMethod.java:74) at org.jclouds.rest.internal.InvokeHttpMethod.apply(InvokeHttpMethod.java:45) at org.jclouds.reflect.FunctionalReflection$FunctionalInvocationHandler.handleInvocation(FunctionalReflection.java:117) at com.google.common.reflect.AbstractInvocationHandler.invoke(AbstractInvocationHandler.java:86) at com.sun.proxy.$Proxy199.getWithoutBody(Unknown Source:-1) {code} I believe the fix would be to change line 41 of EntriesWithoutMetaPrefix.java from int index = header.getKey().indexOf("\-Meta\-"); to something like: int index = header.getKey()*.toLowerCase()*.indexOf("*\-meta\-*"); {code:java} 41c41 < int index = header.getKey().indexOf("-Meta-"); --- > int index = header.getKey().toLowerCase().indexOf("-meta-"); {code} > BlobStore.blobMetadata().getUserMetadata() returns empty Map when cloud > provider returns lowercase metadata headers > ------------------------------------------------------------------------------------------------------------------- > > Key: JCLOUDS-1580 > URL: https://issues.apache.org/jira/browse/JCLOUDS-1580 > Project: jclouds > Issue Type: Bug > Components: jclouds-blobstore > Affects Versions: 2.3.0 > Reporter: Erik Ebert > Priority: Major > > I believe this is happening because jclouds/swift is specifically looking for > user metadata with the prefix "X-Object-Meta-", case SENSITIVE: > X-Object-Meta-foo > > But since header names are case-INSENSITIVE. per RFC 2616, this fails if the > cloud provider returns header names in lower case: > x-object-meta-foo > > I discovered this while using "openstack-swift" to access SAP's Converged > Cloud, but it would affect any cloud provider that returns lower-case header > names. > > In my case, this is an example of what is returned by Converged Cloud: > curl <object url> --head -H "X-Auth-Token:<token>" > HTTP/1.1 200 OK > content-type: application/octet-stream > *x-object-meta-original-created-time*: 1623984822180 > *x-object-meta-content-md5*: rREHajOaHzUiU8DQoap9NA== > etag: xxxxx > last-modified: Fri, 18 Jun 2021 02:53:53 GMT > x-timestamp: 1623984832.86825 > accept-ranges: bytes > content-length: 12 > x-trans-id: xxxx > x-openstack-request-id: xxxxx > date: Fri, 18 Jun 2021 03:16:46 GMT > > Sample jclouds code: > > {code:java} > BlobStoreContext blobStoreContext = > ContextBuilder.newBuilder("openstack-swift") > .endpoint(ENDPOINT) > .credentials(INDENTITY, CREDENTIAL) > .overrides(overrides) > .buildApi(BlobStoreContext.class); > BlobStore blobStore = blobStoreContext.getBlobStore(); > BlobMetadata blobMetadata = blobStore.blobMetadata(CONTAINER, PATH); > Map<String, String> userMetadata = blobMetadata.getUserMetadata() > System.out.println(userMetadata.toString()) > > {code} > > blobMetadata.getUserMetadata() SHOULD return something like: > *original-created-time*: 1623984822180 > *content-md5*: rREHajOaHzUiU8DQoap9NA== > (or similar), but instead it returns an empty Map object. > > Stepping through the code, I believe the source of the problem is line 41 of > EntriesWithoutMetaPrefix.java: > [https://github.com/apache/jclouds/blob/0b89ee0825d45de1193090cdd5efc5f1135fa200/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/EntriesWithoutMetaPrefix.java] > > Partial stack trace from the code example above: > {code:java} > at > org.jclouds.openstack.swift.v1.functions.EntriesWithoutMetaPrefix.apply(EntriesWithoutMetaPrefix.java:41) > at > org.jclouds.openstack.swift.v1.functions.ParseObjectFromResponse.apply(ParseObjectFromResponse.java:81) > at > org.jclouds.openstack.swift.v1.functions.ParseObjectFromResponse.apply(ParseObjectFromResponse.java:41) > at > org.jclouds.rest.internal.InvokeHttpMethod.invoke(InvokeHttpMethod.java:91) > at > org.jclouds.rest.internal.InvokeHttpMethod.apply(InvokeHttpMethod.java:74) > at > org.jclouds.rest.internal.InvokeHttpMethod.apply(InvokeHttpMethod.java:45) > at > org.jclouds.reflect.FunctionalReflection$FunctionalInvocationHandler.handleInvocation(FunctionalReflection.java:117) > at > com.google.common.reflect.AbstractInvocationHandler.invoke(AbstractInvocationHandler.java:86) > at com.sun.proxy.$Proxy199.getWithoutBody(Unknown Source:-1) > {code} > > I believe the fix would be to change line 41 of EntriesWithoutMetaPrefix.java > from > int index = header.getKey().indexOf("-Meta-"); > to something like: > int index = header.getKey()*.toLowerCase()*.indexOf("*-meta-*"); > > {code:java} > 41c41 > < int index = header.getKey().indexOf("-Meta-"); > --- > > int index = header.getKey().toLowerCase().indexOf("-meta-"); > {code} -- This message was sent by Atlassian Jira (v8.3.4#803005)