<s> """<STR_LIT>""" <EOL> import logging <EOL> import weakref <EOL> import zlib <EOL> from . . common . decoder import DeflateDecoder <EOL> from . . common . exceptions import ChunkedDecodeError , InvalidResponseError <EOL> from . . common . exceptions import ConnectionResetError <EOL> log = logging . getLogger ( __name__ ) <EOL> class HTTP11Response ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , code , reason , headers , sock , connection = None ) : <EOL> self . reason = reason <EOL> self . status = code <EOL> self . headers = headers <EOL> self . trailers = None <EOL> self . _sock = sock <EOL> self . _expect_close = False <EOL> if b'<STR_LIT>' in self . headers . get ( b'<STR_LIT>' , [ ] ) : <EOL> self . _expect_close = True <EOL> try : <EOL> self . _length = int ( self . headers [ b'<STR_LIT>' ] [ <NUM_LIT:0> ] ) <EOL> except KeyError : <EOL> self . _length = None <EOL> self . _chunked = ( <EOL> b'<STR_LIT>' in self . headers . get ( b'<STR_LIT>' , [ ] ) <EOL> ) <EOL> assert self . _expect_close or self . _length is not None or self . _chunked <EOL> if b'<STR_LIT>' in self . headers . get ( b'<STR_LIT>' , [ ] ) : <EOL> self . _decompressobj = zlib . decompressobj ( <NUM_LIT:16> + zlib . MAX_WBITS ) <EOL> elif b'<STR_LIT>' in self . headers . get ( b'<STR_LIT>' , [ ] ) : <EOL> self . _decompressobj = DeflateDecoder ( ) <EOL> else : <EOL> self . _decompressobj = None <EOL> if connection is not None : <EOL> self . _parent = weakref . ref ( connection ) <EOL> else : <EOL> self . _parent = None <EOL> self . _buffered_data = b'<STR_LIT>' <EOL> self . _chunker = None <EOL> def read ( self , amt = None , decode_content = True ) : <EOL> """<STR_LIT>""" <EOL> if self . _sock is None : <EOL> return b'<STR_LIT>' <EOL> if self . _chunked : <EOL> return self . _normal_read_chunked ( amt , decode_content ) <EOL> if amt is None : <EOL> if self . _length is not None : <EOL> amt = self . _length <EOL> elif self . _expect_close : <EOL> return self . _read_expect_closed ( decode_content ) <EOL> else : <EOL> raise InvalidResponseError ( <EOL> "<STR_LIT>" <EOL> ) <EOL> if self . _length is not None : <EOL> amt = min ( amt , self . _length ) <EOL> to_read = amt <EOL> chunks = [ ] <EOL> while to_read > <NUM_LIT:0> : <EOL> chunk = self . _sock . recv ( amt ) . tobytes ( ) <EOL> if not chunk : <EOL> if self . _length is not None or not self . _expect_close : <EOL> self . close ( socket_close = True ) <EOL> raise ConnectionResetError ( "<STR_LIT>" ) <EOL> break <EOL> to_read -= len ( chunk ) <EOL> chunks . append ( chunk ) <EOL> data = b'<STR_LIT>' . join ( chunks ) <EOL> if self . _length is not None : <EOL> self . _length -= len ( data ) <EOL> end_of_request = ( self . _length == <NUM_LIT:0> or <EOL> ( self . _expect_close and len ( data ) < amt ) ) <EOL> if decode_content and self . _decompressobj and data : <EOL> data = self . _decompressobj . decompress ( data ) <EOL> if decode_content and self . _decompressobj and end_of_request : <EOL> data += self . _decompressobj . flush ( ) <EOL> if end_of_request : <EOL> self . close ( socket_close = self . _expect_close ) <EOL> return data <EOL> def read_chunked ( self , decode_content = True ) : <EOL> """<STR_LIT>""" <EOL> if not self . _chunked : <EOL> raise ChunkedDecodeError ( <EOL> "<STR_LIT>" <EOL> ) <EOL> if self . _sock is None : <EOL> return <EOL> while True : <EOL> chunk_length = int ( self . _sock . readline ( ) . tobytes ( ) . strip ( ) , <NUM_LIT:16> ) <EOL> data = b'<STR_LIT>' <EOL> if not chunk_length : <EOL> self . _sock . readline ( ) <EOL> if decode_content and self . _decompressobj : <EOL> yield self . _decompressobj . flush ( ) <EOL> self . close ( socket_close = self . _expect_close ) <EOL> break <EOL> while chunk_length > <NUM_LIT:0> : <EOL> chunk = self . _sock . recv ( chunk_length ) . tobytes ( ) <EOL> data += chunk <EOL> chunk_length -= len ( chunk ) <EOL> assert chunk_length == <NUM_LIT:0> <EOL> self . _sock . readline ( ) <EOL> if decode_content and self . _decompressobj and data : <EOL> data = self . _decompressobj . decompress ( data ) <EOL> yield data <EOL> return <EOL> def close ( self , socket_close = False ) : <EOL> """<STR_LIT>""" <EOL> if socket_close and self . _parent is not None : <EOL> parent = self . _parent ( ) <EOL> if parent is not None : <EOL> parent . close ( ) <EOL> self . _sock = None <EOL> def _read_expect_closed ( self , decode_content ) : <EOL> """<STR_LIT>""" <EOL> chunks = [ ] <EOL> while True : <EOL> try : <EOL> chunk = self . _sock . recv ( <NUM_LIT> ) . tobytes ( ) <EOL> if not chunk : <EOL> break <EOL> except ConnectionResetError : <EOL> break <EOL> else : <EOL> chunks . append ( chunk ) <EOL> self . close ( socket_close = True ) <EOL> data = b'<STR_LIT>' . join ( chunks ) <EOL> if decode_content and self . _decompressobj : <EOL> data = self . _decompressobj . decompress ( data ) <EOL> data += self . _decompressobj . flush ( ) <EOL> return data <EOL> def _normal_read_chunked ( self , amt , decode_content ) : <EOL> """<STR_LIT>""" <EOL> if amt is None : <EOL> return self . _buffered_data + b'<STR_LIT>' . join ( self . read_chunked ( ) ) <EOL> if self . _chunker is None : <EOL> self . _chunker = self . read_chunked ( ) <EOL> current_amount = len ( self . _buffered_data ) <EOL> extra_data = [ self . _buffered_data ] <EOL> while current_amount < amt : <EOL> try : <EOL> chunk = next ( self . _chunker ) <EOL> except StopIteration : <EOL> self . close ( socket_close = self . _expect_close ) <EOL> break <EOL> current_amount += len ( chunk ) <EOL> extra_data . append ( chunk ) <EOL> data = b'<STR_LIT>' . join ( extra_data ) <EOL> self . _buffered_data = data [ amt : ] <EOL> return data [ : amt ] <EOL> def __enter__ ( self ) : <EOL> return self <EOL> def __exit__ ( self , * args ) : <EOL> self . close ( ) <EOL> return False </s>
