def range_iter(): results = {} while True: next_range = self._next() headers, fragment_iters = next_range content_range = headers.get('Content-Range') if content_range is not None: fragment_start, fragment_end, fragment_length = \ parse_content_range(content_range) elif self.fragment_length <= 0: fragment_start = None fragment_end = None fragment_length = 0 else: fragment_start = 0 fragment_end = self.fragment_length - 1 fragment_length = self.fragment_length self._add_ranges_for_fragment(fragment_length, range_infos) satisfiable = False for range_info in range_infos: satisfiable |= range_info['satisfiable'] k = (range_info['resp_fragment_start'], range_info['resp_fragment_end']) results.setdefault(k, []).append(range_info) range_info = results[(fragment_start, fragment_end)].pop(0) segment_iter = self._decode_segments(fragment_iters) if not range_info['satisfiable']: io.consume(segment_iter) continue byterange_iter = self._iter_range(range_info, segment_iter) result = {'start': range_info['resp_meta_start'], 'end': range_info['resp_meta_end'], 'iter': byterange_iter} yield result
def make_iter_from_resp(resp): """ Makes a part iterator from a HTTP response iterator return tuples: (start, end, length, headers, body_file) """ if resp.status == 200: content_length = int(resp.getheader('Content-Length')) return iter([(0, content_length - 1, content_length, resp.getheaders(), resp)]) content_type, params = parse_content_type(resp.getheader('Content-Type')) if content_type != 'multipart/byteranges': start, end, length = parse_content_range( resp.getheader('Content-Range')) return iter([(start, end, length, resp.getheaders(), resp)]) else: raise ValueError("Invalid response")