~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/http.py

Readv patch from Johan Rydberg giving knits partial download support.

Show diffs side-by-side

added added

removed removed

Lines of Context:
74
74
            return urllib2.Request.get_method(self)
75
75
 
76
76
 
77
 
def get_url(url, method=None):
 
77
def get_url(url, method=None, ranges=None):
78
78
    import urllib2
79
79
    mutter("get_url %s", url)
80
80
    manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
85
85
    request = Request(url)
86
86
    request.method = method
87
87
    request.add_header('User-Agent', 'bzr/%s' % bzrlib.__version__)
 
88
    if ranges:
 
89
        request.add_header('Range', ranges)
88
90
    response = opener.open(request)
89
91
    return response
90
92
 
190
192
                return False
191
193
            raise TransportError(orig_error=e)
192
194
 
193
 
    def get(self, relpath, decode=False):
194
 
        """Get the file at the given relative path.
195
 
 
196
 
        :param relpath: The relative path to the file
197
 
        """
 
195
    def _get(self, relpath, decode=False, ranges=None):
198
196
        path = relpath
199
197
        try:
200
198
            path = self.abspath(relpath)
201
 
            return get_url(path)
 
199
            return get_url(path, ranges=ranges)
202
200
        except urllib2.HTTPError, e:
203
201
            mutter('url error code: %s for has url: %r', e.code, path)
204
202
            if e.code == 404:
214
212
                             % (self.abspath(relpath), str(e)),
215
213
                             orig_error=e)
216
214
 
 
215
    def get(self, relpath, decode=False):
 
216
        """Get the file at the given relative path.
 
217
 
 
218
        :param relpath: The relative path to the file
 
219
        """
 
220
        return self._get(relpath, decode=decode)
 
221
 
 
222
    def readv(self, relpath, offsets):
 
223
        """Get parts of the file at the given relative path.
 
224
 
 
225
        :offsets: A list of (offset, size) tuples.
 
226
        :return: A list or generator of (offset, data) tuples
 
227
        """
 
228
        response = self._get(relpath,
 
229
            ranges=','.join(['%d-%d' % (off, off + size - 1)
 
230
                             for off, size in offsets]))
 
231
        if response.code == 206:
 
232
            for off, size in offsets:
 
233
                yield off, response.read(size)
 
234
        elif response.code == 200:
 
235
            fp = StringIO(response.read())
 
236
            for off, size in offsets:
 
237
                fp.seek(off)
 
238
                yield off, fp.read(size)
 
239
 
217
240
    def put(self, relpath, f, mode=None):
218
241
        """Copy the file-like or string object into the location.
219
242