This does not work: only fixes the object server, but needs the proxy server doing the same thing, too. Needs proper logging (for some reason, the intercepted exception and the supposed 500 do not log ("supposed" because, of course, with the broken TCP connection 200 logs instead - with full length)). Needs a succint comment that explains why file.close() is not hooked. commit 311b158d735b749d5a1624fbd8000c496ca47481 Author: Pete Zaitcev Date: Thu Mar 15 15:56:07 2012 -0600 lp:704015 candidate 1 diff --git a/swift/obj/server.py b/swift/obj/server.py index f631507..f2a4d6a 100644 --- a/swift/obj/server.py +++ b/swift/obj/server.py @@ -122,6 +122,7 @@ class DiskFile(object): self.iter_etag = None self.started_at_0 = False self.read_to_eof = False + self.expect_to_read = 0 self.quarantined_dir = None self.keep_cache = False if not os.path.exists(self.datadir): @@ -175,10 +176,17 @@ class DiskFile(object): self.read_to_eof = True self.drop_cache(self.fp.fileno(), dropped_cache, read - dropped_cache) + # lp:704015 (could force verify_file, but read is here, so) + if self.expect_to_read != read: + # raise Exception("Unexpected EOF at %d" % read) + raise break finally: self.close() + def arm_expectation(self, file_size): + self.expect_to_read = file_size + def app_iter_range(self, start, stop): """Returns an iterator over the data file for range (start, stop)""" if start: @@ -670,6 +678,7 @@ class ObjectController(object): if_modified_since: file.close() return HTTPNotModified(request=request) + file.arm_expectation(file_size) response = Response(app_iter=file, request=request, conditional_response=True) response.headers['Content-Type'] = file.metadata.get('Content-Type',