Revision 4a1c29ea pithos/api/util.py
b/pithos/api/util.py | ||
---|---|---|
173 | 173 |
return meta, get_sharing(request), get_public(request) |
174 | 174 |
|
175 | 175 |
def put_object_headers(response, meta, restricted=False): |
176 |
response['ETag'] = meta['hash']
|
|
176 |
response['ETag'] = meta['ETag']
|
|
177 | 177 |
response['Content-Length'] = meta['bytes'] |
178 | 178 |
response['Content-Type'] = meta.get('Content-Type', 'application/octet-stream') |
179 | 179 |
response['Last-Modified'] = http_date(int(meta['modified'])) |
180 | 180 |
if not restricted: |
181 |
response['X-Object-Hash'] = meta['hash'] |
|
181 | 182 |
response['X-Object-Modified-By'] = smart_str(meta['modified_by'], strings_only=True) |
182 | 183 |
response['X-Object-Version'] = meta['version'] |
183 | 184 |
response['X-Object-Version-Timestamp'] = http_date(int(meta['version_timestamp'])) |
... | ... | |
197 | 198 |
"""Update metadata if the object has an X-Object-Manifest.""" |
198 | 199 |
|
199 | 200 |
if 'X-Object-Manifest' in meta: |
200 |
hash = ''
|
|
201 |
etag = ''
|
|
201 | 202 |
bytes = 0 |
202 | 203 |
try: |
203 | 204 |
src_container, src_name = split_container_object_string('/' + meta['X-Object-Manifest']) |
... | ... | |
206 | 207 |
for x in objects: |
207 | 208 |
src_meta = request.backend.get_object_meta(request.user_uniq, |
208 | 209 |
v_account, src_container, x[0], x[1]) |
209 |
hash += src_meta['hash']
|
|
210 |
etag += src_meta['ETag']
|
|
210 | 211 |
bytes += src_meta['bytes'] |
211 | 212 |
except: |
212 | 213 |
# Ignore errors. |
213 | 214 |
return |
214 | 215 |
meta['bytes'] = bytes |
215 | 216 |
md5 = hashlib.md5() |
216 |
md5.update(hash)
|
|
217 |
meta['hash'] = md5.hexdigest().lower()
|
|
217 |
md5.update(etag)
|
|
218 |
meta['ETag'] = md5.hexdigest().lower()
|
|
218 | 219 |
|
219 | 220 |
def update_sharing_meta(request, permissions, v_account, v_container, v_object, meta): |
220 | 221 |
if permissions is None: |
... | ... | |
261 | 262 |
def validate_matching_preconditions(request, meta): |
262 | 263 |
"""Check that the ETag conforms with the preconditions set.""" |
263 | 264 |
|
264 |
hash = meta.get('hash', None)
|
|
265 |
etag = meta.get('ETag', None)
|
|
265 | 266 |
|
266 | 267 |
if_match = request.META.get('HTTP_IF_MATCH') |
267 | 268 |
if if_match is not None: |
268 |
if hash is None:
|
|
269 |
if etag is None:
|
|
269 | 270 |
raise PreconditionFailed('Resource does not exist') |
270 |
if if_match != '*' and hash not in [x.lower() for x in parse_etags(if_match)]:
|
|
271 |
if if_match != '*' and etag not in [x.lower() for x in parse_etags(if_match)]:
|
|
271 | 272 |
raise PreconditionFailed('Resource ETag does not match') |
272 | 273 |
|
273 | 274 |
if_none_match = request.META.get('HTTP_IF_NONE_MATCH') |
274 | 275 |
if if_none_match is not None: |
275 | 276 |
# TODO: If this passes, must ignore If-Modified-Since header. |
276 |
if hash is not None:
|
|
277 |
if if_none_match == '*' or hash in [x.lower() for x in parse_etags(if_none_match)]:
|
|
277 |
if etag is not None:
|
|
278 |
if if_none_match == '*' or etag in [x.lower() for x in parse_etags(if_none_match)]:
|
|
278 | 279 |
# TODO: Continue if an If-Modified-Since header is present. |
279 | 280 |
if request.method in ('HEAD', 'GET'): |
280 | 281 |
raise NotModified('Resource ETag matches') |
... | ... | |
665 | 666 |
ranges = [(0, size)] |
666 | 667 |
ret = 200 |
667 | 668 |
except ValueError: |
668 |
if if_range != meta['hash']:
|
|
669 |
if if_range != meta['ETag']:
|
|
669 | 670 |
ranges = [(0, size)] |
670 | 671 |
ret = 200 |
671 | 672 |
|
Also available in: Unified diff