
 XRe                 @   s  d  Z  d d l m Z d d l Z d d l Z d d l Z d d l Z d d l m Z d d l	 m
 Z
 m Z m Z d d l m Z m Z m Z d d l m Z d d l m Z d d	 l m Z d d
 l m Z d d l m Z d d d f Z Gd d   d e  Z Gd d   d e  Z d Z d Z  d Z! e j" r:e# n e j$ Z% Gd d   d e&  Z' Gd d   d e j(  Z) Gd d   d e j(  Z* Gd d   d e j(  Z+ Gd d   d e j(  Z, d d   Z- d d    Z. Gd! d"   d" e&  Z/ d# d$   Z0 d% d&   Z1 d S)'z
Multi-part parsing for file uploads.

Exposes one class, ``MultiPartParser``, which feeds chunks of uploaded data to
file upload handlers for processing.
    )unicode_literalsN)settings)RequestDataTooBigSuspiciousMultipartFormTooManyFieldsSent)SkipFileStopFutureHandlers
StopUpload)six)MultiValueDict)
force_text)unquote)unescape_entitiesMultiPartParserMultiPartParserErrorInputStreamExhaustedc               @   s   e  Z d  Z d S)r   N)__name__
__module____qualname__ r   r   I/home/ubuntu/projects/ifolica/build/django/django/http/multipartparser.pyr      s   c               @   s   e  Z d  Z d Z d S)r   z5
    No more reads are allowed from this device.
    N)r   r   r   __doc__r   r   r   r   r   "   s   rawfilefieldc               @   sU   e  Z d  Z d Z d d d  Z d d   Z d d   Z d	 d
   Z d d   Z d S)r   z
    A rfc2388 multipart/form-data parser.

    ``MultiValueDict.parse()`` reads the input stream in ``chunk_size`` chunks
    and returns a tuple of ``(MultiValueDict(POST), MultiValueDict(FILES))``.
    Nc             C   st  | j  d d  } | j d  s4 t d |   n  t | j d   \ } } | j  d  } | su t j |  r t d |   n  y t | j  d d	   }	 Wn t t	 f k
 r d	 }	 Yn X|	 d	 k  r t d
 |	   n  t
 | t j  r| j d  } n  | |  _ | |  _ d d   | D }
 t d g |
  |  _ | |  _ | pXt j |  _ |	 |  _ | |  _ d S)a  
        Initialize the MultiPartParser object.

        :META:
            The standard ``META`` dictionary in Django request objects.
        :input_data:
            The raw post data, as a file-like object.
        :upload_handlers:
            A list of UploadHandler instances that perform operations on the uploaded
            data.
        :encoding:
            The encoding with which to treat the incoming data.
        CONTENT_TYPE z
multipart/zInvalid Content-Type: %sasciiboundaryz!Invalid boundary in multipart: %sCONTENT_LENGTHr   zInvalid content length: %rc             S   s"   g  |  ] } | j  r | j   q Sr   )
chunk_size).0xr   r   r   
<listcomp>e   s   	 z,MultiPartParser.__init__.<locals>.<listcomp>         Nl        i)get
startswithr   parse_headerencodecgivalid_boundaryint
ValueError	TypeError
isinstancer
   	text_type	_boundary_input_datamin_chunk_size_metar   DEFAULT_CHARSET	_encoding_content_length_upload_handlers)selfZMETAZ
input_dataZupload_handlersencodingcontent_typectypesoptsr   content_lengthZpossible_sizesr   r   r   __init__6   s.    				zMultiPartParser.__init__c       "   1   C   sr  d d l  m } |  j } |  j } |  j d k rJ | d |  j  t   f SxS | D]K } | j |  j |  j |  j |  j	 |  } | d k	 rQ | d | d f SqQ W| d d  |  _
 t   |  _ t t |  j |  j   } d } d g t |  } d }	 d }
 d } yxt | |  j	  D]\ } } } | rH|  j | |  d } n  y" | d d } | d	 j   } Wn t t t f k
 rwYn X| j d
  } | d k	 r| d j   } n  t | | d d } | t k r|
 d 7}
 t j d k	 rt j |
 k  rt d   n  t j d k	 r0t j |	 } n  | d k r| j d |  } |	 t |  7}	 y t j |  } Wqt  k
 r| } YqXn" | j d |  } |	 t |  7}	 |	 t |  d 7}	 t j d k	 r|	 t j k rt! d   n  |  j
 j" | t | | d d  q| t# k r| j d  } | ret | | d d } |  j$ t% |   } n  | sqqn  | j d d i  f  \ } } | j   } | j d  } y t& | j d  d  } Wn! t t' t( f k
 rd } Yn Xd g t |  } yxD | D]< } y  | j) | | | | | |  Wqt* k
 rCPYqXqWxV| D]N} | d k r@d j+ | j,    } t |  d } xL | d k r| j d |  } | d j+ | j,    7} t |  d } qWy t j |  } Wq@t- k
 r<} z2 d | } t. j/ t0 t0 |  t1 j2   d  WYd d } ~ Xq@Xn  xZ t3 |  D]L \ } } t |  }  | j4 | | |  } | | |  7<| d k rMPqMqMWqOWWn& t5 k
 r|  j6   t7 |  YqX| } qt7 |  qWWnH t8 k
 r-} z( |  j6   | j9 st7 |  j  n  WYd d } ~ Xn Xt7 |  j  x$ | D] } | j:   }! |! rBPqBqBW|  j
 |  j f S)z
        Parse the POST data and break it into a FILES MultiValueDict and a POST
        MultiValueDict.

        Returns a tuple containing the POST and FILES dictionary, respectively.
        r   )	QueryDictr<   N   ZmutableTzcontent-dispositionnamezcontent-transfer-encodingerrorsreplacezRThe number of GET/POST parameters exceeded settings.DATA_UPLOAD_MAX_NUMBER_FIELDS.base64sizer$   z;Request body exceeded settings.DATA_UPLOAD_MAX_MEMORY_SIZE.filenamezcontent-typer   charsetzcontent-length    r&   z Could not decode base64 data: %r);Zdjango.httprB   r8   r:   r9   r   Zhandle_raw_inputr3   r6   r2   Z_post_files
LazyStream	ChunkIterr5   lenParserhandle_file_completestripKeyError
IndexErrorAttributeErrorr'   r   FIELDr   ZDATA_UPLOAD_MAX_NUMBER_FIELDSr   ZDATA_UPLOAD_MAX_MEMORY_SIZEreadrG   	b64decode_BASE64_DECODE_ERRORr   
appendlistFILEIE_sanitizer   r-   r/   r.   Znew_filer   joinsplit	Exceptionr
   reraiser   sysexc_info	enumerateZreceive_data_chunkr   _close_filesexhaustr	   Zconnection_resetZupload_complete)"r;   rB   r<   handlershandlerresultstreamold_field_namecountersZnum_bytes_readZnum_post_keysZ	read_sizeZ	item_typeZ	meta_dataZfield_streamdisposition
field_nameZtransfer_encodingZraw_datadata	file_namer=   Zcontent_type_extrarJ   r@   chunkZstripped_chunk	remainingZ
over_chunkemsgiZchunk_lengthretvalr   r   r   parsem   s    			"	


9	
	
	#zMultiPartParser.parsec             C   sf   x_ t  |  j  D]N \ } } | j | |  } | r |  j j t | |  j d d |  Pq q Wd S)zT
        Handle all the signaling that takes place when a file is complete.
        rE   rF   N)rc   r:   Zfile_completerL   rZ   r   r8   )r;   rj   rk   rt   rg   Zfile_objr   r   r   rQ   (  s    	z$MultiPartParser.handle_file_completec             C   s'   | o& | | j  d  d d  j   S)z3Cleanup filename from Internet Explorer full paths.\rC   N)rfindrR   )r;   rI   r   r   r   r\   5  s    zMultiPartParser.IE_sanitizec             C   s7   x0 |  j  D]% } t | d  r
 | j j   q
 q
 Wd  S)Nr   )r:   hasattrr   close)r;   rg   r   r   r   rd   9  s    zMultiPartParser._close_files)	r   r   r   r   rA   rv   rQ   r\   rd   r   r   r   r   r   /   s   7c               @   s|   e  Z d  Z d Z d d d  Z d d   Z d d d  Z d	 d
   Z d d   Z d d   Z	 d d   Z
 d d   Z d S)rM   a!  
    The LazyStream wrapper allows one to get and "unget" bytes from a stream.

    Given a producer object (an iterator that yields bytestrings), the
    LazyStream object will support iteration, reading, and keeping a "look-back"
    variable in case you need to "unget" some bytes.
    Nc             C   sC   | |  _  d |  _ d |  _ | |  _ d |  _ | |  _ g  |  _ d S)z
        Every LazyStream must have a producer when instantiated.

        A producer is an iterable that returns a string each time it
        is called.
        FrK   r   N)	_producerZ_empty	_leftoverlengthposition
_remaining_unget_history)r;   Zproducerr}   r   r   r   rA   J  s    						zLazyStream.__init__c             C   s   |  j  S)N)r~   )r;   r   r   r   tellY  s    zLazyStream.tellc                s+      f d d   } d j  |    } | S)Nc              3   s    d  k r   j  n  }  |  d  k r9 d j    Vd  Sx |  d k r |  d k s` t d   y t    } Wn t k
 r d  SYq< X| d  |   }   j | |  d    |  t |  8}  | Vq< Wd  S)NrK   r   z0remaining bytes to read should never go negative)r   r]   AssertionErrornextStopIterationungetrO   )rq   rp   Zemitting)r;   rH   r   r   parts]  s    	zLazyStream.read.<locals>.partsrK   )r]   )r;   rH   r   outr   )r;   rH   r   rW   \  s    zLazyStream.readc             C   sO   |  j  r |  j  } d |  _  n t |  j  } g  |  _ |  j t |  7_ | S)a  
        Used when the exact number of bytes to read is unimportant.

        This procedure just returns whatever is chunk is conveniently returned
        from the iterator instead. Useful to avoid unnecessary bookkeeping if
        performance is an issue.
        rK   )r|   r   r{   r   r~   rO   )r;   outputr   r   r   __next__w  s    			zLazyStream.__next__c             C   s   g  |  _  d S)z
        Used to invalidate/disable this lazy stream.

        Replaces the producer with an empty list. Any leftover bytes that have
        already been read will still be reported upon read() and/or next().
        N)r{   )r;   r   r   r   rz     s    zLazyStream.closec             C   s   |  S)Nr   )r;   r   r   r   __iter__  s    zLazyStream.__iter__c             C   sQ   | s
 d S|  j  t |   |  j t |  8_ d j | |  j g  |  _ d S)z
        Places bytes back onto the front of the lazy stream.

        Future calls to read() will return those bytes first. The
        stream position and thus tell() will be rewound.
        NrK   )_update_unget_historyrO   r~   r]   r|   )r;   bytesr   r   r   r     s
    zLazyStream.ungetc                s^     g |  j  d d  |  _  t   f d d   |  j  D  } | d k rZ t d   n  d S)a[  
        Updates the unget history as a sanity check to see if we've pushed
        back the same number of bytes in one chunk. If we keep ungetting the
        same number of bytes many times (here, 50), we're mostly likely in an
        infinite loop of some sort. This is usually caused by a
        maliciously-malformed MIME request.
        N1   c                s"   g  |  ] } |   k r |  q Sr   r   )r!   Zcurrent_number)	num_bytesr   r   r#     s   	 z4LazyStream._update_unget_history.<locals>.<listcomp>(   zThe multipart parser got stuck, which shouldn't happen with normal uploaded files. Check for malicious upload activity; if there is none, report this to the Django developers.)r   rO   r   )r;   r   Znumber_equalr   )r   r   r     s
    "z LazyStream._update_unget_history)r   r   r   r   rA   r   rW   r   rz   r   r   r   r   r   r   r   rM   B  s   	rM   c               @   s=   e  Z d  Z d Z d d d  Z d d   Z d d	   Z d
 S)rN   z
    An iterable that will yield chunks of data. Given a file-like object as the
    constructor, this object will yield chunks of read operations from that
    object.
    @   i   c             C   s   | |  _  | |  _ d  S)N)flor    )r;   r   r    r   r   r   rA     s    	zChunkIter.__init__c             C   sN   y |  j  j |  j  } Wn t k
 r6 t    Yn X| rA | St    d  S)N)r   rW   r    r   r   )r;   rn   r   r   r   r     s    zChunkIter.__next__c             C   s   |  S)Nr   )r;   r   r   r   r     s    zChunkIter.__iter__Ni   )r   r   r   r   rA   r   r   r   r   r   r   rN     s   
rN   c               @   s:   e  Z d  Z d Z d d   Z d d   Z d d   Z d S)	InterBoundaryIterz7
    A Producer that will iterate over boundaries.
    c             C   s   | |  _  | |  _ d  S)N)_streamr2   )r;   ri   r   r   r   r   rA     s    	zInterBoundaryIter.__init__c             C   s   |  S)Nr   )r;   r   r   r   r     s    zInterBoundaryIter.__iter__c             C   s?   y t  t |  j |  j   SWn t k
 r: t    Yn Xd  S)N)rM   BoundaryIterr   r2   r   r   )r;   r   r   r   r     s    zInterBoundaryIter.__next__N)r   r   r   r   rA   r   r   r   r   r   r   r     s   r   c               @   sI   e  Z d  Z d Z d d   Z d d   Z d d   Z d d	 d
  Z d S)r   ae  
    A Producer that is sensitive to boundaries.

    Will happily yield bytes until a boundary is found. Will yield the bytes
    before the boundary, throw away the boundary bytes themselves, and push the
    post-boundary bytes back on the stream.

    The future calls to next() after locating the boundary will raise a
    StopIteration exception.
    c             C   sf   | |  _  | |  _ d |  _ t |  d |  _ |  j  j d  } | sR t    n  |  j  j |  d  S)NF   rC   )r   r2   _donerO   	_rollbackrW   r   r   )r;   ri   r   Zunused_charr   r   r   rA     s    			zBoundaryIter.__init__c             C   s   |  S)Nr   )r;   r   r   r   r     s    zBoundaryIter.__iter__c       
      C   sO  |  j  r t    n  |  j } |  j } d } g  } xN | D]= } | t |  7} | j |  | | k rm Pn  | s: Pq: q: Wd |  _  | s t    n  d j |  } |  j | t |  |  j k   } | r| \ } }	 | j | |	 d    d |  _  | d  |  S| d  |  s$d |  _  | S| j | | d    | d  |  Sd  S)Nr   TrK   )	r   r   r   r   rO   appendr]   _find_boundaryr   )
r;   ri   rollback
bytes_readchunksr   rp   r   endr   r   r   r   r     s8    				!		zBoundaryIter.__next__Fc             C   s   | j  |  j  } | d k  r" d S| } | t |  j  } t d | d  } | | | d  d k ru | d 8} n  t d | d  } | | | d  d k r | d 8} n  | | f Sd S)a)  
        Finds a multipart boundary in data.

        Should no boundary exist in the data None is returned instead. Otherwise
        a tuple containing the indices of the following are returned:

         * the end of current encapsulation
         * the start of the next encapsulation
        r   NrC   s   
s   )findr2   rO   max)r;   rn   eofindexr   r   lastr   r   r   r   &  s    
zBoundaryIter._find_boundaryN)r   r   r   r   rA   r   r   r   r   r   r   r   r     s
   
)r   c             C   sj   d } y t  |   } Wn! t k
 r9 t |  d  } Yn X| d k rU t d   n  x | D] } q\ Wd S)z
    Completely exhausts an iterator or stream.

    Raise a MultiPartParserError if the argument is not a stream or an iterable.
    Ni @  zGmultipartparser.exhaust() was passed a non-iterable or stream parameter)iterr/   rN   r   )Zstream_or_iterableiterator__r   r   r   re   @  s    re   c             C   s;  |  j  |  } | j d  } d d   } | d
 k rP |  j |  t i  |  f S| d |  } |  j | | d d   t } i  } x | j d  D]w } y | |  \ }	 \ }
 } Wn t k
 r w Yn X|	 d k r t } | j d	  r t } q n  |
 | f | |	 <q W| t k r.|  j |  n  | | |  f S)zI
    Parses one and exactly one stream that encapsulates a boundary.
    s   

c             S   sc   t  |   \ } } y | j d d  \ } } Wn" t k
 rR t d |    Yn X| | | f f S)N:rC   zInvalid header: %r)r)   r^   r.   )lineZmain_value_pairparamsrD   valuer   r   r   _parse_headera  s    z,parse_boundary_stream.<locals>._parse_headerrC   Nr&   s   
zcontent-dispositionrI   )	rW   r   r   RAWr^   r.   rV   r'   r[   )ri   Zmax_header_sizerp   Z
header_endr   headerZTYPEZoutdictr   rD   r   r   r   r   r   parse_boundary_streamS  s.    r   c               @   s(   e  Z d  Z d d   Z d d   Z d S)rP   c             C   s   | |  _  d | |  _ d  S)Ns   --)r   
_separator)r;   ri   r   r   r   r   rA     s    	zParser.__init__c             c   s8   t  |  j |  j  } x | D] } t | d  Vq Wd  S)Ni   )r   r   r   r   )r;   ZboundarystreamZ
sub_streamr   r   r   r     s    zParser.__iter__N)r   r   r   rA   r   r   r   r   r   rP     s   rP   c             C   s  t  d |   } | j d  j   j d  } i  } x| D]} | j d  } | d k r; d } | d |  j   j   j d  } | j d  r | d d  } | j d	  d
 k r d } q n  | | d d  j   } | rA| j d	  \ }	 }
 } t	 j
 r)t | j   d |	 j   } qAt |  j |	  } n  t |  d
 k r| d d  | d d  k o~d k n r| d d  } | j d d  j d d  } n  | | | <q; q; W| | f S)z Parse the header into a key-value.
        Input (line): bytes, output: unicode for key/name, bytes for value which
        will be decoded later
       ;r   r      =FN*rC      'r$   Tr<      "s   \\s   \s   \"r   r   r   )_parse_header_paramspoplowerdecoder   rR   endswithcountr^   r
   PY3r   rO   rF   )r   plistkeypdictprt   Zhas_encodingrD   r   r<   langr   r   r   r)     s.    %	!B!r)   c             C   s   g  } x |  d  d  d k r |  d d   }  |  j  d  } x? | d k r |  j d d |  d r |  j  d | d  } qA W| d k  r t |   } n  |  d  |  } | j | j    |  | d   }  q	 W| S)NrC   r   r   r   r$   )r   r   rO   r   rR   )sr   r   fr   r   r   r     s    (r   )2r   
__future__r   rG   binasciir+   ra   Zdjango.confr   Zdjango.core.exceptionsr   r   r   Zdjango.core.files.uploadhandlerr   r   r	   Zdjango.utilsr
   Zdjango.utils.datastructuresr   Zdjango.utils.encodingr   Z#django.utils.six.moves.urllib.parser   Zdjango.utils.textr   __all__r_   r   r   r   r[   rV   PY2r/   ErrorrY   objectr   IteratorrM   rN   r   r   re   r   rP   r)   r   r   r   r   r   <module>   s>    sa;!