Exemple #1
0
 def set_range_from_header(self, content_range):
     """Helper to set the new range from its description in the headers"""
     try:
         rtype, values = content_range.split()
     except ValueError:
         raise errors.InvalidHttpRange(self._path, content_range,
                                       'Malformed header')
     if rtype != 'bytes':
         raise errors.InvalidHttpRange(
             self._path, content_range,
             "Unsupported range type '%s'" % rtype)
     try:
         # We don't need total, but note that it may be either the file size
         # or '*' if the server can't or doesn't want to return the file
         # size.
         start_end, total = values.split('/')
         start, end = start_end.split('-')
         start = int(start)
         end = int(end)
     except ValueError:
         raise errors.InvalidHttpRange(self._path, content_range,
                                       'Invalid range values')
     size = end - start + 1
     if size <= 0:
         raise errors.InvalidHttpRange(self._path, content_range,
                                       'Invalid range, size <= 0')
     self.set_range(start, size)
Exemple #2
0
    def _get(self, relpath, offsets, tail_amount=0):
        """See HttpTransport._get"""

        abspath = self._remote_path(relpath)
        headers = {}
        accepted_errors = [200, 404]
        if offsets or tail_amount:
            range_header = self._attempted_range_header(offsets, tail_amount)
            if range_header is not None:
                accepted_errors.append(206)
                accepted_errors.append(400)
                accepted_errors.append(416)
                bytes = 'bytes=' + range_header
                headers = {'Range': bytes}

        request = Request('GET',
                          abspath,
                          None,
                          headers,
                          accepted_errors=accepted_errors)
        response = self._perform(request)

        code = response.code
        if code == 404:  # not found
            raise errors.NoSuchFile(abspath)
        elif code in (400, 416):
            # We don't know which, but one of the ranges we specified was
            # wrong.
            raise errors.InvalidHttpRange(abspath, range_header,
                                          'Server return code %d' % code)

        data = handle_response(abspath, code, response.info(), response)
        return code, data
Exemple #3
0
    def _get_ranged(self, relpath, offsets, tail_amount):
        """Make a request for just part of the file."""
        curl = self._get_curl()
        abspath, data, header = self._setup_get_request(curl, relpath)

        range_header = self._attempted_range_header(offsets, tail_amount)
        if range_header is None:
            # Forget ranges, the server can't handle them
            return self._get_full(relpath)

        self._curl_perform(curl, header, ['Range: bytes=%s' % range_header])
        data.seek(0)

        code = curl.getinfo(pycurl.HTTP_CODE)

        if code == 404:  # not found
            raise errors.NoSuchFile(abspath)
        elif code in (400, 416):
            # We don't know which, but one of the ranges we specified was
            # wrong.
            raise errors.InvalidHttpRange(
                abspath, range_header,
                'Server return code %d' % curl.getinfo(pycurl.HTTP_CODE))
        msg = self._parse_headers(header)
        return code, response.handle_response(abspath, code, msg, data)
Exemple #4
0
 def test_invalid_http_range(self):
     error = errors.InvalidHttpRange('path',
                                     'Content-Range: potatoes 0-00/o0oo0',
                                     'bad range')
     self.assertEquals(
         "Invalid http range"
         " 'Content-Range: potatoes 0-00/o0oo0'"
         " for path: bad range", str(error))