GET on Static Large Object returns Content-Type application/json

Bug #1658295 reported by Monty Taylor
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
OpenStack Object Storage (swift)
Expired
Undecided
Unassigned

Bug Description

When doing a GET on an SLO, the content-type returned is application/json even though the body contains the binary content of the object. Headers/body from such a request in a devstack run can be seen here:

http://logs.openstack.org/39/415739/16/check/gate-shade-dsvm-functional-neutron/c0e2032/console.html#_2017-01-21_09_43_23_001119

But here are the headers:

{'X-Static-Large-Object': 'True', 'Content-Type': 'application/json', 'Accept-Ranges': 'bytes', 'X-Openstack-Request-Id': 'tx361f03d40e5b4ea0b18e8-0058832d3a', 'X-Object-Meta-Testk': 'testv', 'Etag': '"8378739fce1ddda7343b59ddfda0296d"', 'X-Timestamp': '1484991802.63134', 'X-Trans-Id': 'tx361f03d40e5b4ea0b18e8-0058832d3a', 'Date': 'Sat, 21 Jan 2017 09:43:22 GMT', 'Last-Modified': 'Sat, 21 Jan 2017 09:43:23 GMT', 'Content-Length': '65536', 'Connection': 'keep-alive'}

It probably doesn't surface for many people, but shade happens to have an auto-decode json step if the content-type is application/json so that the calling function gets the python object rather than the json string. We've added a workaround in shade, so it's not a big deal for us - but it does seem like cognitive dissonance at the very least.

Revision history for this message
Christian Schwede (cschwede) wrote :

I think this is related to used content-type when uploading the manifest. If I upload a manifest with content-type set to "application/octet-stream" I get the same back when downloading the object.

This is also the default when uploading a SLO using the swift CLI. For example:

[me@fedora ~]# dd if=/dev/zero of=bigobj bs=1k count=1
1+0 records in
1+0 records out
1024 bytes (1.0 kB, 1.0 KiB) copied, 0.00026279 s, 3.9 MB/s

[me@fedora ~]# swift upload -S 400 --use-slo cont bigobj
bigobj segment 1
bigobj segment 0
bigobj segment 2
bigobj/slo/1485165429.181910/1024/400/00000001
bigobj/slo/1485165429.181910/1024/400/00000002
bigobj/slo/1485165429.181910/1024/400/00000000
bigobj

[me@fedora ~]# swift --debug download cont bigobj
...
DEBUG:swiftclient:RESP HEADERS: {u'Content-Length': u'1024', u'Content-Type': u'application/octet-stream', u'Accept-Ranges': u'bytes', u'Last-Modified': u'Mon, 23 Jan 2017 10:00:54 GMT', u'Etag': u'"63e9547bb7d6a21b44e5828079396dbc"', u'X-Timestamp': u'1485165653.57339', u'X-Trans-Id': u'txfc77183eab7649b79805b-005885d459', u'Date': u'Mon, 23 Jan 2017 10:00:57 GMT', u'X-Static-Large-Object': u'True', u'X-Object-Meta-Mtime': u'1485165648.789943', u'X-Openstack-Request-Id': u'txfc77183eab7649b79805b-005885d459'}
bigobj [auth 0.011s, headers 0.034s, total 0.035s, 0.043 MB/s]

So I guess the content-type was set to JSON when uploading?

Changed in swift:
status: New → Incomplete
Revision history for this message
Alistair Coles (alistair-coles) wrote :

Christian beat me to it, but I had same response.

When SLO does override with content-type (when multipart-manifest=get query string is sent) then it also sets the charset (example below), and that is not seen in the logs reported in the bug. So the logs suggest that application/json was set when the SLO manifest was uploaded.

swift@u135:~/swift$ curl -i http://localhost:8080/v1/AUTH_test/c1/LICENSE?multipart-manifest=get -X GET -H "X-Auth-Token: AUTH_tkc14ede8a7c5b4181ae535bb6695f6421"
HTTP/1.1 200 OK
Content-Length: 2795
Content-Type: application/json; charset=utf-8

Revision history for this message
Monty Taylor (mordred) wrote :

AHA! Sweet - that makes total sense to me and I believe we can fix the initial SLO upload to work as we're expecting here. Thanks!

Revision history for this message
Monty Taylor (mordred) wrote :

FWIW - the thing that tripped me up can be seen here:

self._object_store_client.put(
    endpoint,
    params={'multipart-manifest': 'put'},
    headers=headers, json=manifest)

(where _object_store_client is a python requests object)

Because the manifest is json itself, it seemed to make sense to just pass a list to json= and have requests serialize it - but as you point out, that causes requests, in the absence of other instructions, to default content-type to application/json. I've fixed our code - mostly following up in case the source of my confusion is helpful to anyone else.

Revision history for this message
Launchpad Janitor (janitor) wrote :

[Expired for OpenStack Object Storage (swift) because there has been no activity for 60 days.]

Changed in swift:
status: Incomplete → Expired
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.