Skip to content

Commit

Permalink
I had an error while getting compressed attachments from
Browse files Browse the repository at this point in the history
couchdb/couchdbkit. This fix Deflate/Gzip compression and make it fully
streamed. Fix also issue benoitc#24.
  • Loading branch information
benoitc committed Sep 14, 2010
1 parent 03f652d commit d36b6de
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 19 deletions.
5 changes: 2 additions & 3 deletions restkit/client/request.py
Expand Up @@ -248,7 +248,6 @@ def request(self, url, method='GET', body=None, headers=None):

self.found_headers = found_headers


# Finally do the request
return self.do_send()

Expand All @@ -266,7 +265,7 @@ def _req_headers(self):


ua = self.found_headers.get('USER-AGENT')
accept_encoding = self.found_headers.get('CONTENT-ENCODING')
accept_encoding = self.found_headers.get('ACCEPT-ENCODING')
connection = self.found_headers.get('CONNECTION')

# default host header
Expand All @@ -280,7 +279,7 @@ def _req_headers(self):
req_headers = [
"%s %s %s\r\n" % (self.method, req_path, httpver),
"Host: %s\r\n" % host,
"User-Agent: %s\r\n" % ua or USER-AGENT,
"User-Agent: %s\r\n" % ua or USER_AGENT,
"Accept-Encoding: %s\r\n" % accept_encoding or 'identity'
]

Expand Down
23 changes: 13 additions & 10 deletions restkit/http/body.py
Expand Up @@ -135,6 +135,7 @@ def read(self, size):
break
data = self.unreader.read()


buf = buf.getvalue()
ret, rest = buf[:size], buf[size:]
self.unreader.unread(rest)
Expand Down Expand Up @@ -289,10 +290,10 @@ def readlines(self, size=None):
ret.append(line)
return ret


class GzipBody(Body):
def __init__(self, reader):
Body.__init__(self, reader)
super(GzipBody, self).__init__(reader)
self._d = zlib.decompressobj(16+zlib.MAX_WBITS)

def _decompress(self, data):
Expand All @@ -308,21 +309,20 @@ def read(self, size=None):
ret, rest = data[:size], data[size:]
self.buf.truncate(0)
self.buf.write(rest)
return ret
return self._decompress(ret)

while size > self.buf.tell():
data = self.reader.read(1024)
if not len(data):
self.close()
break
data = self._decompress(data)
self.buf.write(data)

data = self.buf.getvalue()
ret, rest = data[:size], data[size:]
self.buf.truncate(0)
self.buf.write(rest)
return ret
return self._decompress(ret)

def readline(self, size=None):
size = self.getsize(size)
Expand All @@ -335,8 +335,7 @@ def readline(self, size=None):
if not len(data):
self.close()
break
data = self._decompress(data)
self.buf.write(data)
self.buf.write(self._decompress(data))
idx = self.buf.getvalue().find("\n")
if size < self.buf.tell():
break
Expand All @@ -358,6 +357,10 @@ def readline(self, size=None):
self.buf.truncate(0)
self.buf.write(rest)
return ret





class DeflateBody(GzipBody):
def __init__(self, reader):
super(DeflateBody, self).__init__(reader)
self._d = zlib.decompressobj()

8 changes: 3 additions & 5 deletions restkit/http/message.py
Expand Up @@ -12,7 +12,7 @@
from StringIO import StringIO

from restkit.http.body import ChunkedReader, LengthReader, EOFReader, Body, \
GzipBody
GzipBody, DeflateBody
from restkit.errors import InvalidHeader, InvalidHeaderName, NoMoreData, \
InvalidRequestLine, InvalidRequestMethod, InvalidHTTPVersion, InvalidHTTPStatus

Expand Down Expand Up @@ -105,7 +105,6 @@ def parse_headers(self, data):
def set_body_reader(self):
chunked = False
clength = None

for (name, value) in self.headers:
if name.upper() == "CONTENT-LENGTH":
try:
Expand All @@ -117,9 +116,6 @@ def set_body_reader(self):
elif name.upper() == "CONTENT-ENCODING":
self.encoding = value.lower()

if clength is not None or chunked:
break

if chunked:
self.body = Body(ChunkedReader(self, self.unreader))
elif clength is not None:
Expand Down Expand Up @@ -223,5 +219,7 @@ def set_body_reader(self):
super(Response, self).set_body_reader()
if self.encoding == "gzip":
self.body = GzipBody(self.body.reader)
elif self.encoding == "deflate":
self.body = DeflateBody(self.body.reader)


Binary file added tests/responses/008.http
Binary file not shown.
11 changes: 11 additions & 0 deletions tests/responses/008.py
@@ -0,0 +1,11 @@
response = {
"status": "200 OK",
"version": (1, 1),
"headers": [
('Content-Type', 'text/html; charset=UTF-8'),
('Content-Length', '31'),
('Content-Encoding', 'gzip'),
('Date', 'Thu, 31 Dec 2009 20:55:48 +0000'),
],
"body": "hello world"
}
2 changes: 1 addition & 1 deletion tests/treq.py
Expand Up @@ -336,4 +336,4 @@ def same(self, resp, sizer, matcher, exp):
t.eq(resp.version, exp["version"])
t.eq(resp.headers, exp["headers"])
matcher(resp, exp["body"], sizer)
t.eq(resp.trailers, exp.get("trailers", []))
t.eq(resp.trailers, exp.get("trailers", []))

0 comments on commit d36b6de

Please sign in to comment.