<s> """<STR_LIT>""" <EOL> __all__ = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> import hmac <EOL> from hashlib import sha1 <EOL> from time import time <EOL> from six . moves . urllib . parse import quote <EOL> from swift . common . exceptions import MimeInvalid <EOL> from swift . common . middleware . tempurl import get_tempurl_keys_from_metadata <EOL> from swift . common . utils import streq_const_time , register_swift_info , parse_content_disposition , parse_mime_headers , iter_multipart_mime_documents <EOL> from swift . common . wsgi import make_pre_authed_env <EOL> from swift . common . swob import HTTPUnauthorized <EOL> from swift . proxy . controllers . base import get_account_info , get_container_info <EOL> READ_CHUNK_SIZE = <NUM_LIT> <EOL> MAX_VALUE_LENGTH = <NUM_LIT> <EOL> class FormInvalid ( Exception ) : <EOL> pass <EOL> class FormUnauthorized ( Exception ) : <EOL> pass <EOL> class _CappedFileLikeObject ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , fp , max_file_size ) : <EOL> self . fp = fp <EOL> self . max_file_size = max_file_size <EOL> self . amount_read = <NUM_LIT:0> <EOL> self . file_size_exceeded = False <EOL> def read ( self , size = None ) : <EOL> ret = self . fp . read ( size ) <EOL> self . amount_read += len ( ret ) <EOL> if self . amount_read > self . max_file_size : <EOL> self . file_size_exceeded = True <EOL> raise EOFError ( '<STR_LIT>' ) <EOL> return ret <EOL> def readline ( self ) : <EOL> ret = self . fp . readline ( ) <EOL> self . amount_read += len ( ret ) <EOL> if self . amount_read > self . max_file_size : <EOL> self . file_size_exceeded = True <EOL> raise EOFError ( '<STR_LIT>' ) <EOL> return ret <EOL> class FormPost ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , app , conf ) : <EOL> self . app = app <EOL> self . conf = conf <EOL> def __call__ ( self , env , start_response ) : <EOL> """<STR_LIT>""" <EOL> if env [ '<STR_LIT>' ] == '<STR_LIT:POST>' : <EOL> try : <EOL> content_type , attrs = parse_content_disposition ( env . get ( '<STR_LIT>' ) or '<STR_LIT>' ) <EOL> if content_type == '<STR_LIT>' and '<STR_LIT>' in attrs : <EOL> http_user_agent = "<STR_LIT>" % ( <EOL> env . get ( '<STR_LIT>' , '<STR_LIT>' ) ) <EOL> env [ '<STR_LIT>' ] = http_user_agent . strip ( ) <EOL> status , headers , body = self . _translate_form ( <EOL> env , attrs [ '<STR_LIT>' ] ) <EOL> start_response ( status , headers ) <EOL> return [ body ] <EOL> except MimeInvalid : <EOL> body = '<STR_LIT>' <EOL> start_response ( <EOL> '<STR_LIT>' , <EOL> ( ( '<STR_LIT:Content-Type>' , '<STR_LIT>' ) , <EOL> ( '<STR_LIT>' , str ( len ( body ) ) ) ) ) <EOL> return [ body ] <EOL> except ( FormInvalid , EOFError ) as err : <EOL> body = '<STR_LIT>' % err <EOL> start_response ( <EOL> '<STR_LIT>' , <EOL> ( ( '<STR_LIT:Content-Type>' , '<STR_LIT>' ) , <EOL> ( '<STR_LIT>' , str ( len ( body ) ) ) ) ) <EOL> return [ body ] <EOL> except FormUnauthorized as err : <EOL> message = '<STR_LIT>' % str ( err ) . title ( ) <EOL> return HTTPUnauthorized ( body = message ) ( <EOL> env , start_response ) <EOL> return self . app ( env , start_response ) <EOL> def _translate_form ( self , env , boundary ) : <EOL> """<STR_LIT>""" <EOL> keys = self . _get_keys ( env ) <EOL> status = message = '<STR_LIT>' <EOL> attributes = { } <EOL> subheaders = [ ] <EOL> file_count = <NUM_LIT:0> <EOL> for fp in iter_multipart_mime_documents ( <EOL> env [ '<STR_LIT>' ] , boundary , read_chunk_size = READ_CHUNK_SIZE ) : <EOL> hdrs = parse_mime_headers ( fp ) <EOL> disp , attrs = parse_content_disposition ( <EOL> hdrs . get ( '<STR_LIT>' , '<STR_LIT>' ) ) <EOL> if disp == '<STR_LIT>' and attrs . get ( '<STR_LIT:filename>' ) : <EOL> file_count += <NUM_LIT:1> <EOL> try : <EOL> if file_count > int ( attributes . get ( '<STR_LIT>' ) or <NUM_LIT:0> ) : <EOL> status = '<STR_LIT>' <EOL> message = '<STR_LIT>' <EOL> break <EOL> except ValueError : <EOL> raise FormInvalid ( '<STR_LIT>' ) <EOL> attributes [ '<STR_LIT:filename>' ] = attrs [ '<STR_LIT:filename>' ] or '<STR_LIT:filename>' <EOL> if '<STR_LIT>' not in attributes and '<STR_LIT>' in hdrs : <EOL> attributes [ '<STR_LIT>' ] = hdrs [ '<STR_LIT:Content-Type>' ] or '<STR_LIT>' <EOL> status , subheaders , message = self . _perform_subrequest ( env , attributes , fp , keys ) <EOL> if not status . startswith ( '<STR_LIT:2>' ) : <EOL> break <EOL> else : <EOL> data = '<STR_LIT>' <EOL> mxln = MAX_VALUE_LENGTH <EOL> while mxln : <EOL> chunk = fp . read ( mxln ) <EOL> if not chunk : <EOL> break <EOL> mxln -= len ( chunk ) <EOL> data += chunk <EOL> while fp . read ( READ_CHUNK_SIZE ) : <EOL> pass <EOL> if '<STR_LIT:name>' in attrs : <EOL> attributes [ attrs [ '<STR_LIT:name>' ] . lower ( ) ] = data . rstrip ( '<STR_LIT>' ) <EOL> if not status : <EOL> status = '<STR_LIT>' <EOL> message = '<STR_LIT>' <EOL> headers = [ ( k , v ) for k , v in subheaders <EOL> if k . lower ( ) . startswith ( '<STR_LIT>' ) ] <EOL> redirect = attributes . get ( '<STR_LIT>' ) <EOL> if not redirect : <EOL> body = status <EOL> if message : <EOL> body = status + '<STR_LIT>' + message . title ( ) <EOL> headers . extend ( [ ( '<STR_LIT:Content-Type>' , '<STR_LIT>' ) , <EOL> ( '<STR_LIT>' , len ( body ) ) ] ) <EOL> return status , headers , body <EOL> status = status . split ( '<STR_LIT:U+0020>' , <NUM_LIT:1> ) [ <NUM_LIT:0> ] <EOL> if '<STR_LIT:?>' in redirect : <EOL> redirect += '<STR_LIT:&>' <EOL> else : <EOL> redirect += '<STR_LIT:?>' <EOL> redirect += '<STR_LIT>' % ( quote ( status ) , quote ( message ) ) <EOL> body = '<STR_LIT>' '<STR_LIT>' % redirect <EOL> headers . extend ( <EOL> [ ( '<STR_LIT>' , redirect ) , ( '<STR_LIT>' , str ( len ( body ) ) ) ] ) <EOL> return '<STR_LIT>' , headers , body <EOL> def _perform_subrequest ( self , orig_env , attributes , fp , keys ) : <EOL> """<STR_LIT>""" <EOL> if not keys : <EOL> raise FormUnauthorized ( '<STR_LIT>' ) <EOL> try : <EOL> max_file_size = int ( attributes . get ( '<STR_LIT>' ) or <NUM_LIT:0> ) <EOL> except ValueError : <EOL> raise FormInvalid ( '<STR_LIT>' ) <EOL> subenv = make_pre_authed_env ( orig_env , '<STR_LIT>' , agent = None , <EOL> swift_source = '<STR_LIT>' ) <EOL> if '<STR_LIT>' in subenv : <EOL> del subenv [ '<STR_LIT>' ] <EOL> subenv [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> subenv [ '<STR_LIT>' ] = _CappedFileLikeObject ( fp , max_file_size ) <EOL> if not subenv [ '<STR_LIT>' ] . endswith ( '<STR_LIT:/>' ) and subenv [ '<STR_LIT>' ] . count ( '<STR_LIT:/>' ) < <NUM_LIT:4> : <EOL> subenv [ '<STR_LIT>' ] += '<STR_LIT:/>' <EOL> subenv [ '<STR_LIT>' ] += attributes [ '<STR_LIT:filename>' ] or '<STR_LIT:filename>' <EOL> if '<STR_LIT>' in attributes : <EOL> try : <EOL> subenv [ '<STR_LIT>' ] = int ( attributes [ '<STR_LIT>' ] ) <EOL> except ValueError : <EOL> raise FormInvalid ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> if '<STR_LIT>' in attributes : <EOL> try : <EOL> subenv [ '<STR_LIT>' ] = int ( <EOL> attributes [ '<STR_LIT>' ] ) <EOL> except ValueError : <EOL> raise FormInvalid ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> if '<STR_LIT>' in attributes : <EOL> subenv [ '<STR_LIT>' ] = attributes [ '<STR_LIT>' ] or '<STR_LIT>' <EOL> elif '<STR_LIT>' in subenv : <EOL> del subenv [ '<STR_LIT>' ] <EOL> try : <EOL> if int ( attributes . get ( '<STR_LIT>' ) or <NUM_LIT:0> ) < time ( ) : <EOL> raise FormUnauthorized ( '<STR_LIT>' ) <EOL> except ValueError : <EOL> raise FormInvalid ( '<STR_LIT>' ) <EOL> hmac_body = '<STR_LIT>' % ( <EOL> orig_env [ '<STR_LIT>' ] , <EOL> attributes . get ( '<STR_LIT>' ) or '<STR_LIT>' , <EOL> attributes . get ( '<STR_LIT>' ) or '<STR_LIT:0>' , <EOL> attributes . get ( '<STR_LIT>' ) or '<STR_LIT:0>' , <EOL> attributes . get ( '<STR_LIT>' ) or '<STR_LIT:0>' ) <EOL> has_valid_sig = False <EOL> for key in keys : <EOL> sig = hmac . new ( key , hmac_body , sha1 ) . hexdigest ( ) <EOL> if streq_const_time ( sig , ( attributes . get ( '<STR_LIT>' ) or <EOL> '<STR_LIT>' ) ) : <EOL> has_valid_sig = True <EOL> if not has_valid_sig : <EOL> raise FormUnauthorized ( '<STR_LIT>' ) <EOL> substatus = [ None ] <EOL> subheaders = [ None ] <EOL> wsgi_input = subenv [ '<STR_LIT>' ] <EOL> def _start_response ( status , headers , exc_info = None ) : <EOL> if wsgi_input . file_size_exceeded : <EOL> raise EOFError ( "<STR_LIT>" ) <EOL> substatus [ <NUM_LIT:0> ] = status <EOL> subheaders [ <NUM_LIT:0> ] = headers <EOL> i = iter ( self . app ( subenv , _start_response ) ) <EOL> try : <EOL> next ( i ) <EOL> except StopIteration : <EOL> pass <EOL> return substatus [ <NUM_LIT:0> ] , subheaders [ <NUM_LIT:0> ] , '<STR_LIT>' <EOL> def _get_keys ( self , env ) : <EOL> """<STR_LIT>""" <EOL> parts = env [ '<STR_LIT>' ] . split ( '<STR_LIT:/>' , <NUM_LIT:4> ) <EOL> if len ( parts ) < <NUM_LIT:4> or parts [ <NUM_LIT:0> ] or parts [ <NUM_LIT:1> ] != '<STR_LIT>' or not parts [ <NUM_LIT:2> ] or not parts [ <NUM_LIT:3> ] : <EOL> return [ ] <EOL> account_info = get_account_info ( env , self . app , swift_source = '<STR_LIT>' ) <EOL> account_keys = get_tempurl_keys_from_metadata ( account_info [ '<STR_LIT>' ] ) <EOL> container_info = get_container_info ( env , self . app , swift_source = '<STR_LIT>' ) <EOL> container_keys = get_tempurl_keys_from_metadata ( <EOL> container_info . get ( '<STR_LIT>' , [ ] ) ) <EOL> return account_keys + container_keys <EOL> def filter_factory ( global_conf , ** local_conf ) : <EOL> """<STR_LIT>""" <EOL> conf = global_conf . copy ( ) <EOL> conf . update ( local_conf ) <EOL> register_swift_info ( '<STR_LIT>' ) <EOL> return lambda app : FormPost ( app , conf ) </s>
