<s> """<STR_LIT>""" <EOL> from __future__ import absolute_import , division , print_function , with_statement <EOL> import calendar <EOL> import collections <EOL> import copy <EOL> import datetime <EOL> import email . utils <EOL> import numbers <EOL> import re <EOL> import time <EOL> from tornado . escape import native_str , parse_qs_bytes , utf8 <EOL> from tornado . log import gen_log <EOL> from tornado . util import ObjectDict , bytes_type <EOL> try : <EOL> import Cookie <EOL> except ImportError : <EOL> import http . cookies as Cookie <EOL> try : <EOL> from httplib import responses <EOL> except ImportError : <EOL> from http . client import responses <EOL> responses <EOL> try : <EOL> from urllib import urlencode <EOL> except ImportError : <EOL> from urllib . parse import urlencode <EOL> try : <EOL> from ssl import SSLError <EOL> except ImportError : <EOL> class SSLError ( Exception ) : <EOL> pass <EOL> class _NormalizedHeaderCache ( dict ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , size ) : <EOL> super ( _NormalizedHeaderCache , self ) . __init__ ( ) <EOL> self . size = size <EOL> self . queue = collections . deque ( ) <EOL> def __missing__ ( self , key ) : <EOL> normalized = "<STR_LIT:->" . join ( [ w . capitalize ( ) for w in key . split ( "<STR_LIT:->" ) ] ) <EOL> self [ key ] = normalized <EOL> self . queue . append ( key ) <EOL> if len ( self . queue ) > self . size : <EOL> old_key = self . queue . popleft ( ) <EOL> del self [ old_key ] <EOL> return normalized <EOL> _normalized_headers = _NormalizedHeaderCache ( <NUM_LIT:1000> ) <EOL> class HTTPHeaders ( dict ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> dict . __init__ ( self ) <EOL> self . _as_list = { } <EOL> self . _last_key = None <EOL> if ( len ( args ) == <NUM_LIT:1> and len ( kwargs ) == <NUM_LIT:0> and <EOL> isinstance ( args [ <NUM_LIT:0> ] , HTTPHeaders ) ) : <EOL> for k , v in args [ <NUM_LIT:0> ] . get_all ( ) : <EOL> self . add ( k , v ) <EOL> else : <EOL> self . update ( * args , ** kwargs ) <EOL> def add ( self , name , value ) : <EOL> """<STR_LIT>""" <EOL> norm_name = _normalized_headers [ name ] <EOL> self . _last_key = norm_name <EOL> if norm_name in self : <EOL> dict . __setitem__ ( self , norm_name , <EOL> native_str ( self [ norm_name ] ) + '<STR_LIT:U+002C>' + <EOL> native_str ( value ) ) <EOL> self . _as_list [ norm_name ] . append ( value ) <EOL> else : <EOL> self [ norm_name ] = value <EOL> def get_list ( self , name ) : <EOL> """<STR_LIT>""" <EOL> norm_name = _normalized_headers [ name ] <EOL> return self . _as_list . get ( norm_name , [ ] ) <EOL> def get_all ( self ) : <EOL> """<STR_LIT>""" <EOL> for name , values in self . _as_list . items ( ) : <EOL> for value in values : <EOL> yield ( name , value ) <EOL> def parse_line ( self , line ) : <EOL> """<STR_LIT>""" <EOL> if line [ <NUM_LIT:0> ] . isspace ( ) : <EOL> new_part = '<STR_LIT:U+0020>' + line . lstrip ( ) <EOL> self . _as_list [ self . _last_key ] [ - <NUM_LIT:1> ] += new_part <EOL> dict . __setitem__ ( self , self . _last_key , <EOL> self [ self . _last_key ] + new_part ) <EOL> else : <EOL> name , value = line . split ( "<STR_LIT::>" , <NUM_LIT:1> ) <EOL> self . add ( name , value . strip ( ) ) <EOL> @ classmethod <EOL> def parse ( cls , headers ) : <EOL> """<STR_LIT>""" <EOL> h = cls ( ) <EOL> for line in headers . splitlines ( ) : <EOL> if line : <EOL> h . parse_line ( line ) <EOL> return h <EOL> def __setitem__ ( self , name , value ) : <EOL> norm_name = _normalized_headers [ name ] <EOL> dict . __setitem__ ( self , norm_name , value ) <EOL> self . _as_list [ norm_name ] = [ value ] <EOL> def __getitem__ ( self , name ) : <EOL> return dict . __getitem__ ( self , _normalized_headers [ name ] ) <EOL> def __delitem__ ( self , name ) : <EOL> norm_name = _normalized_headers [ name ] <EOL> dict . __delitem__ ( self , norm_name ) <EOL> del self . _as_list [ norm_name ] <EOL> def __contains__ ( self , name ) : <EOL> norm_name = _normalized_headers [ name ] <EOL> return dict . __contains__ ( self , norm_name ) <EOL> def get ( self , name , default = None ) : <EOL> return dict . get ( self , _normalized_headers [ name ] , default ) <EOL> def update ( self , * args , ** kwargs ) : <EOL> for k , v in dict ( * args , ** kwargs ) . items ( ) : <EOL> self [ k ] = v <EOL> def copy ( self ) : <EOL> return HTTPHeaders ( self ) <EOL> class HTTPServerRequest ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , method = None , uri = None , version = "<STR_LIT>" , headers = None , <EOL> body = None , host = None , files = None , connection = None , <EOL> start_line = None ) : <EOL> if start_line is not None : <EOL> method , uri , version = start_line <EOL> self . method = method <EOL> self . uri = uri <EOL> self . version = version <EOL> self . headers = headers or HTTPHeaders ( ) <EOL> self . body = body or "<STR_LIT>" <EOL> context = getattr ( connection , '<STR_LIT>' , None ) <EOL> self . remote_ip = getattr ( context , '<STR_LIT>' ) <EOL> self . protocol = getattr ( context , '<STR_LIT>' , "<STR_LIT:http>" ) <EOL> self . host = host or self . headers . get ( "<STR_LIT>" ) or "<STR_LIT:127.0.0.1>" <EOL> self . files = files or { } <EOL> self . connection = connection <EOL> self . _start_time = time . time ( ) <EOL> self . _finish_time = None <EOL> self . path , sep , self . query = uri . partition ( '<STR_LIT:?>' ) <EOL> self . arguments = parse_qs_bytes ( self . query , keep_blank_values = True ) <EOL> self . query_arguments = copy . deepcopy ( self . arguments ) <EOL> self . body_arguments = { } <EOL> def supports_http_1_1 ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . version == "<STR_LIT>" <EOL> @ property <EOL> def cookies ( self ) : <EOL> """<STR_LIT>""" <EOL> if not hasattr ( self , "<STR_LIT>" ) : <EOL> self . _cookies = Cookie . SimpleCookie ( ) <EOL> if "<STR_LIT>" in self . headers : <EOL> try : <EOL> self . _cookies . load ( <EOL> native_str ( self . headers [ "<STR_LIT>" ] ) ) <EOL> except Exception : <EOL> self . _cookies = { } <EOL> return self . _cookies <EOL> def write ( self , chunk , callback = None ) : <EOL> """<STR_LIT>""" <EOL> assert isinstance ( chunk , bytes_type ) <EOL> self . connection . write ( chunk , callback = callback ) <EOL> def finish ( self ) : <EOL> """<STR_LIT>""" <EOL> self . connection . finish ( ) <EOL> self . _finish_time = time . time ( ) <EOL> def full_url ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . protocol + "<STR_LIT>" + self . host + self . uri <EOL> def request_time ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . _finish_time is None : <EOL> return time . time ( ) - self . _start_time <EOL> else : <EOL> return self . _finish_time - self . _start_time <EOL> def get_ssl_certificate ( self , binary_form = False ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> return self . connection . stream . socket . getpeercert ( <EOL> binary_form = binary_form ) <EOL> except SSLError : <EOL> return None <EOL> def _parse_body ( self ) : <EOL> parse_body_arguments ( <EOL> self . headers . get ( "<STR_LIT:Content-Type>" , "<STR_LIT>" ) , self . body , <EOL> self . body_arguments , self . files , <EOL> self . headers ) <EOL> for k , v in self . body_arguments . items ( ) : <EOL> self . arguments . setdefault ( k , [ ] ) . extend ( v ) <EOL> def __repr__ ( self ) : <EOL> attrs = ( "<STR_LIT>" , "<STR_LIT:host>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT:version>" , "<STR_LIT>" ) <EOL> args = "<STR_LIT:U+002CU+0020>" . join ( [ "<STR_LIT>" % ( n , getattr ( self , n ) ) for n in attrs ] ) <EOL> return "<STR_LIT>" % ( <EOL> self . __class__ . __name__ , args , dict ( self . headers ) ) <EOL> class HTTPInputError ( Exception ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> class HTTPOutputError ( Exception ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> class HTTPServerConnectionDelegate ( object ) : <EOL> """<STR_LIT>""" <EOL> def start_request ( self , server_conn , request_conn ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError ( ) <EOL> def on_close ( self , server_conn ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> class HTTPMessageDelegate ( object ) : <EOL> """<STR_LIT>""" <EOL> def headers_received ( self , start_line , headers ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def data_received ( self , chunk ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def finish ( self ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def on_connection_close ( self ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> class HTTPConnection ( object ) : <EOL> """<STR_LIT>""" <EOL> def write_headers ( self , start_line , headers , chunk = None , callback = None ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError ( ) <EOL> def write ( self , chunk , callback = None ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError ( ) <EOL> def finish ( self ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError ( ) <EOL> def url_concat ( url , args ) : <EOL> """<STR_LIT>""" <EOL> if not args : <EOL> return url <EOL> if url [ - <NUM_LIT:1> ] not in ( '<STR_LIT:?>' , '<STR_LIT:&>' ) : <EOL> url += '<STR_LIT:&>' if ( '<STR_LIT:?>' in url ) else '<STR_LIT:?>' <EOL> return url + urlencode ( args ) <EOL> class HTTPFile ( ObjectDict ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def _parse_request_range ( range_header ) : <EOL> """<STR_LIT>""" <EOL> unit , _ , value = range_header . partition ( "<STR_LIT:=>" ) <EOL> unit , value = unit . strip ( ) , value . strip ( ) <EOL> if unit != "<STR_LIT>" : <EOL> return None <EOL> start_b , _ , end_b = value . partition ( "<STR_LIT:->" ) <EOL> try : <EOL> start = _int_or_none ( start_b ) <EOL> end = _int_or_none ( end_b ) <EOL> except ValueError : <EOL> return None <EOL> if end is not None : <EOL> if start is None : <EOL> if end != <NUM_LIT:0> : <EOL> start = - end <EOL> end = None <EOL> else : <EOL> end += <NUM_LIT:1> <EOL> return ( start , end ) <EOL> def _get_content_range ( start , end , total ) : <EOL> """<STR_LIT>""" <EOL> start = start or <NUM_LIT:0> <EOL> end = ( end or total ) - <NUM_LIT:1> <EOL> return "<STR_LIT>" % ( start , end , total ) <EOL> def _int_or_none ( val ) : <EOL> val = val . strip ( ) <EOL> if val == "<STR_LIT>" : <EOL> return None <EOL> return int ( val ) <EOL> def parse_body_arguments ( content_type , body , arguments , files , headers = None ) : <EOL> """<STR_LIT>""" <EOL> if headers and '<STR_LIT>' in headers : <EOL> gen_log . warning ( "<STR_LIT>" , <EOL> headers [ '<STR_LIT>' ] ) <EOL> return <EOL> if content_type . startswith ( "<STR_LIT>" ) : <EOL> try : <EOL> uri_arguments = parse_qs_bytes ( native_str ( body ) , keep_blank_values = True ) <EOL> except Exception as e : <EOL> gen_log . warning ( '<STR_LIT>' , e ) <EOL> uri_arguments = { } <EOL> for name , values in uri_arguments . items ( ) : <EOL> if values : <EOL> arguments . setdefault ( name , [ ] ) . extend ( values ) <EOL> elif content_type . startswith ( "<STR_LIT>" ) : <EOL> fields = content_type . split ( "<STR_LIT:;>" ) <EOL> for field in fields : <EOL> k , sep , v = field . strip ( ) . partition ( "<STR_LIT:=>" ) <EOL> if k == "<STR_LIT>" and v : <EOL> parse_multipart_form_data ( utf8 ( v ) , body , arguments , files ) <EOL> break <EOL> else : <EOL> gen_log . warning ( "<STR_LIT>" ) <EOL> def parse_multipart_form_data ( boundary , data , arguments , files ) : <EOL> """<STR_LIT>""" <EOL> if boundary . startswith ( b'<STR_LIT:">' ) and boundary . endswith ( b'<STR_LIT:">' ) : <EOL> boundary = boundary [ <NUM_LIT:1> : - <NUM_LIT:1> ] <EOL> final_boundary_index = data . rfind ( b"<STR_LIT>" + boundary + b"<STR_LIT>" ) <EOL> if final_boundary_index == - <NUM_LIT:1> : <EOL> gen_log . warning ( "<STR_LIT>" ) <EOL> return <EOL> parts = data [ : final_boundary_index ] . split ( b"<STR_LIT>" + boundary + b"<STR_LIT:\r\n>" ) <EOL> for part in parts : <EOL> if not part : <EOL> continue <EOL> eoh = part . find ( b"<STR_LIT>" ) <EOL> if eoh == - <NUM_LIT:1> : <EOL> gen_log . warning ( "<STR_LIT>" ) <EOL> continue <EOL> headers = HTTPHeaders . parse ( part [ : eoh ] . decode ( "<STR_LIT:utf-8>" ) ) <EOL> disp_header = headers . get ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> disposition , disp_params = _parse_header ( disp_header ) <EOL> if disposition != "<STR_LIT>" or not part . endswith ( b"<STR_LIT:\r\n>" ) : <EOL> gen_log . warning ( "<STR_LIT>" ) <EOL> continue <EOL> value = part [ eoh + <NUM_LIT:4> : - <NUM_LIT:2> ] <EOL> if not disp_params . get ( "<STR_LIT:name>" ) : <EOL> gen_log . warning ( "<STR_LIT>" ) <EOL> continue <EOL> name = disp_params [ "<STR_LIT:name>" ] <EOL> if disp_params . get ( "<STR_LIT:filename>" ) : <EOL> ctype = headers . get ( "<STR_LIT:Content-Type>" , "<STR_LIT>" ) <EOL> files . setdefault ( name , [ ] ) . append ( HTTPFile ( <EOL> filename = disp_params [ "<STR_LIT:filename>" ] , body = value , <EOL> content_type = ctype ) ) <EOL> else : <EOL> arguments . setdefault ( name , [ ] ) . append ( value ) <EOL> def format_timestamp ( ts ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( ts , numbers . Real ) : <EOL> pass <EOL> elif isinstance ( ts , ( tuple , time . struct_time ) ) : <EOL> ts = calendar . timegm ( ts ) <EOL> elif isinstance ( ts , datetime . datetime ) : <EOL> ts = calendar . timegm ( ts . utctimetuple ( ) ) <EOL> else : <EOL> raise TypeError ( "<STR_LIT>" % ts ) <EOL> return email . utils . formatdate ( ts , usegmt = True ) <EOL> RequestStartLine = collections . namedtuple ( <EOL> '<STR_LIT>' , [ '<STR_LIT>' , '<STR_LIT:path>' , '<STR_LIT:version>' ] ) <EOL> def parse_request_start_line ( line ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> method , path , version = line . split ( "<STR_LIT:U+0020>" ) <EOL> except ValueError : <EOL> raise HTTPInputError ( "<STR_LIT>" ) <EOL> if not version . startswith ( "<STR_LIT>" ) : <EOL> raise HTTPInputError ( <EOL> "<STR_LIT>" % version ) <EOL> return RequestStartLine ( method , path , version ) <EOL> ResponseStartLine = collections . namedtuple ( <EOL> '<STR_LIT>' , [ '<STR_LIT:version>' , '<STR_LIT:code>' , '<STR_LIT>' ] ) <EOL> def parse_response_start_line ( line ) : <EOL> """<STR_LIT>""" <EOL> line = native_str ( line ) <EOL> match = re . match ( "<STR_LIT>" , line ) <EOL> if not match : <EOL> raise HTTPInputError ( "<STR_LIT>" ) <EOL> return ResponseStartLine ( match . group ( <NUM_LIT:1> ) , int ( match . group ( <NUM_LIT:2> ) ) , <EOL> match . group ( <NUM_LIT:3> ) ) <EOL> def _parseparam ( s ) : <EOL> while s [ : <NUM_LIT:1> ] == '<STR_LIT:;>' : <EOL> s = s [ <NUM_LIT:1> : ] <EOL> end = s . find ( '<STR_LIT:;>' ) <EOL> while end > <NUM_LIT:0> and ( s . count ( '<STR_LIT:">' , <NUM_LIT:0> , end ) - s . count ( '<STR_LIT>' , <NUM_LIT:0> , end ) ) % <NUM_LIT:2> : <EOL> end = s . find ( '<STR_LIT:;>' , end + <NUM_LIT:1> ) <EOL> if end < <NUM_LIT:0> : <EOL> end = len ( s ) <EOL> f = s [ : end ] <EOL> yield f . strip ( ) <EOL> s = s [ end : ] <EOL> def _parse_header ( line ) : <EOL> """<STR_LIT>""" <EOL> parts = _parseparam ( '<STR_LIT:;>' + line ) <EOL> key = next ( parts ) <EOL> pdict = { } <EOL> for p in parts : <EOL> i = p . find ( '<STR_LIT:=>' ) <EOL> if i >= <NUM_LIT:0> : <EOL> name = p [ : i ] . strip ( ) . lower ( ) <EOL> value = p [ i + <NUM_LIT:1> : ] . strip ( ) <EOL> if len ( value ) >= <NUM_LIT:2> and value [ <NUM_LIT:0> ] == value [ - <NUM_LIT:1> ] == '<STR_LIT:">' : <EOL> value = value [ <NUM_LIT:1> : - <NUM_LIT:1> ] <EOL> value = value . replace ( '<STR_LIT>' , '<STR_LIT:\\>' ) . replace ( '<STR_LIT>' , '<STR_LIT:">' ) <EOL> pdict [ name ] = value <EOL> return key , pdict <EOL> def doctests ( ) : <EOL> import doctest <EOL> return doctest . DocTestSuite ( ) </s>
