~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/http/response.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2007-10-24 12:49:17 UTC
  • mfrom: (2935.1.1 ianc-integration)
  • Revision ID: pqm@pqm.ubuntu.com-20071024124917-xb75eckyxx6vkrlg
Makefile fixes - hooks.html generation & allow python to be overridden (Ian Clatworthy)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006 Michael Ellerman
2
 
#           modified by John Arbash Meinel (Canonical Ltd)
 
1
# Copyright (C) 2006 Canonical Ltd
3
2
#
4
3
# This program is free software; you can redistribute it and/or modify
5
4
# it under the terms of the GNU General Public License as published by
60
59
                                 self._ent_start, self._ent_end,
61
60
                                 self._data_start)
62
61
 
 
62
    __repr__ = __str__
 
63
 
63
64
 
64
65
class RangeFile(object):
65
66
    """File-like object that allow access to partial available data.
96
97
        i = bisect(self._ranges, self._pos) - 1
97
98
 
98
99
        if i < 0 or self._pos > self._ranges[i]._ent_end:
 
100
            mutter('Bisect for pos: %s failed. Found offset: %d, ranges:%s',
 
101
                   self._pos, i, self._ranges)
99
102
            raise errors.InvalidRange(self._path, self._pos)
100
103
 
101
104
        r = self._ranges[i]
134
137
 
135
138
    # TODO: jam 20060706 Consider compiling these regexes on demand
136
139
    _CONTENT_RANGE_RE = re.compile(
137
 
        '\s*([^\s]+)\s+([0-9]+)-([0-9]+)/([0-9]+)\s*$')
 
140
        r'\s*([^\s]+)\s+([0-9]+)-([0-9]+)/([0-9]+)\s*$')
138
141
 
139
142
    def __init__(self, path, content_range, input_file):
140
143
        # mutter("parsing 206 non-multipart response for %s", path)
175
178
    """A multi-range HTTP response."""
176
179
    
177
180
    _CONTENT_TYPE_RE = re.compile(
178
 
        '^\s*multipart/byteranges\s*;\s*boundary\s*=\s*(.*?)\s*$')
 
181
        r'^\s*multipart/byteranges\s*;\s*boundary\s*=\s*("?)([^"]*?)\1\s*$')
179
182
    
180
183
    # Start with --<boundary>\r\n
181
184
    # and ignore all headers ending in \r\n
195
198
        RangeFile.__init__(self, path, input_file)
196
199
 
197
200
        self.boundary_regex = self._parse_boundary(content_type, path)
 
201
        # mutter('response:\n%r', self._data)
198
202
 
199
203
        for match in self.boundary_regex.finditer(self._data):
200
204
            ent_start, ent_end = HttpRangeResponse._parse_range(match.group(1),
216
220
            raise errors.InvalidHttpContentType(path, ctype,
217
221
                    "Expected multipart/byteranges with boundary")
218
222
 
219
 
        boundary = match.group(1)
 
223
        boundary = match.group(2)
220
224
        # mutter('multipart boundary is %s', boundary)
221
225
        pattern = HttpMultipartRangeResponse._BOUNDARY_PATT
222
226
        return re.compile(pattern % re.escape(boundary),
246
250
        try:
247
251
            content_type = headers['Content-Type']
248
252
        except KeyError:
249
 
            raise errors.InvalidHttpContentType(url, '',
250
 
                msg='Missing Content-Type')
 
253
            # When there is no content-type header we treat
 
254
            # the response as being of type 'application/octet-stream' as per
 
255
            # RFC2616 section 7.2.1.
 
256
            # Therefore it is obviously not multipart
 
257
            content_type = 'application/octet-stream'
 
258
            is_multipart = False
 
259
        else:
 
260
            is_multipart = _is_multipart(content_type)
251
261
 
252
 
        if _is_multipart(content_type):
 
262
        if is_multipart:
253
263
            # Full fledged multipart response
254
264
            return HttpMultipartRangeResponse(url, content_type, data)
255
265
        else:
269
279
        return data
270
280
    elif code == 404:
271
281
        raise errors.NoSuchFile(url)
 
282
    # Some servers will retun "400: Bad Request" when too much ranges are
 
283
    # specified
 
284
    elif code in (400, 416):
 
285
        # We don't know which, but one of the ranges we specified
 
286
        # was wrong. So we raise with 0 for a lack of a better
 
287
        # magic value.
 
288
        raise errors.InvalidRange(url,0)
272
289
 
273
290
    # TODO: jam 20060713 Properly handle redirects (302 Found, etc)
274
291
    #       The '_get' code says to follow redirects, we probably