U
    ô×cc+°  ã                   @   sv  d Z ddlZddlZddlZddlZddlmZmZmZ ddl	m
Z
mZ ddlmZmZmZmZ e e¡ZeZG dd„ dƒZdd	„ Zd
d„ ZG dd„ deƒZG dd„ dƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deeƒZ G dd„ deeƒZ!G dd„ deƒZ"G d d!„ d!eƒZ#G d"d#„ d#e#eƒZ$G d$d%„ d%e#eƒZ%eee"e$e%d&œZ&dS )'a­  Response parsers for the various protocol types.

The module contains classes that can take an HTTP response, and given
an output shape, parse the response into a dict according to the
rules in the output shape.

There are many similarities amongst the different protocols with regard
to response parsing, and the code is structured in a way to avoid
code duplication when possible.  The diagram below is a diagram
showing the inheritance hierarchy of the response classes.

::



                                 +--------------+
                                 |ResponseParser|
                                 +--------------+
                                    ^    ^    ^
               +--------------------+    |    +-------------------+
               |                         |                        |
    +----------+----------+       +------+-------+        +-------+------+
    |BaseXMLResponseParser|       |BaseRestParser|        |BaseJSONParser|
    +---------------------+       +--------------+        +--------------+
              ^         ^          ^           ^           ^        ^
              |         |          |           |           |        |
              |         |          |           |           |        |
              |        ++----------+-+       +-+-----------++       |
              |        |RestXMLParser|       |RestJSONParser|       |
        +-----+-----+  +-------------+       +--------------+  +----+-----+
        |QueryParser|                                          |JSONParser|
        +-----------+                                          +----------+


The diagram above shows that there is a base class, ``ResponseParser`` that
contains logic that is similar amongst all the different protocols (``query``,
``json``, ``rest-json``, ``rest-xml``).  Amongst the various services there
is shared logic that can be grouped several ways:

* The ``query`` and ``rest-xml`` both have XML bodies that are parsed in the
  same way.
* The ``json`` and ``rest-json`` protocols both have JSON bodies that are
  parsed in the same way.
* The ``rest-json`` and ``rest-xml`` protocols have additional attributes
  besides body parameters that are parsed the same (headers, query string,
  status code).

This is reflected in the class diagram above.  The ``BaseXMLResponseParser``
and the BaseJSONParser contain logic for parsing the XML/JSON body,
and the BaseRestParser contains logic for parsing out attributes that
come from other parts of the HTTP response.  Classes like the
``RestXMLParser`` inherit from the ``BaseXMLResponseParser`` to get the
XML body parsing logic and the ``BaseRestParser`` to get the HTTP
header/status code/query string parsing.

Additionally, there are event stream parsers that are used by the other parsers
to wrap streaming bodies that represent a stream of events. The
BaseEventStreamParser extends from ResponseParser and defines the logic for
parsing values from the headers and payload of a message from the underlying
binary encoding protocol. Currently, event streams support parsing bodies
encoded as JSON and XML through the following hierarchy.


                                  +--------------+
                                  |ResponseParser|
                                  +--------------+
                                    ^    ^    ^
               +--------------------+    |    +------------------+
               |                         |                       |
    +----------+----------+   +----------+----------+    +-------+------+
    |BaseXMLResponseParser|   |BaseEventStreamParser|    |BaseJSONParser|
    +---------------------+   +---------------------+    +--------------+
                     ^                ^        ^                 ^
                     |                |        |                 |
                     |                |        |                 |
                   +-+----------------+-+    +-+-----------------+-+
                   |EventStreamXMLParser|    |EventStreamJSONParser|
                   +--------------------+    +---------------------+

Return Values
=============

Each call to ``parse()`` returns a dict has this form::

    Standard Response

    {
      "ResponseMetadata": {"RequestId": <requestid>}
      <response keys>
    }

    Error response

    {
      "ResponseMetadata": {"RequestId": <requestid>}
      "Error": {
        "Code": <string>,
        "Message": <string>,
        "Type": <string>,
        <additional keys>
      }
    }

é    N)ÚETreeÚXMLParseErrorÚsix)ÚEventStreamÚNoInitialResponseError)Úis_json_value_headerÚlowercase_dictÚmerge_dictsÚparse_timestampc                   @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )ÚResponseParserFactoryc                 C   s
   i | _ d S ©N)Ú	_defaults)Úself© r   ú4/tmp/pip-unpacked-wheel-wt8t2h3j/botocore/parsers.pyÚ__init__‰   s    zResponseParserFactory.__init__c                 K   s   | j  |¡ dS )aO  Set default arguments when a parser instance is created.

        You can specify any kwargs that are allowed by a ResponseParser
        class.  There are currently two arguments:

            * timestamp_parser - A callable that can parse a timestamp string
            * blob_parser - A callable that can parse a blob type

        N)r   Úupdate)r   Úkwargsr   r   r   Úset_parser_defaultsŒ   s    
z)ResponseParserFactory.set_parser_defaultsc                 C   s   t | }|f | jŽS r   )ÚPROTOCOL_PARSERSr   )r   Zprotocol_nameZ
parser_clsr   r   r   Úcreate_parser˜   s    z#ResponseParserFactory.create_parserN)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r   r   r   ˆ   s   r   c                 C   s   t ƒ  | ¡S r   )r   r   )Úprotocolr   r   r   r      s    r   c                    s   ‡ fdd„}|S )Nc                    s.   t |dƒr|j}|d kr"d}n|}ˆ | ||ƒS )NÚtextÚ )Úhasattrr   )r   ÚshapeZnode_or_stringr   ©Úfuncr   r   Ú_get_text_content§   s    
z(_text_content.<locals>._get_text_contentr   )r    r!   r   r   r   Ú_text_content¡   s    r"   c                   @   s   e Zd ZdS )ÚResponseParserErrorN)r   r   r   r   r   r   r   r#   ¶   s   r#   c                   @   s¢   e Zd ZdZdZdZd&dd„Zdd„ Zdd	„ Zd
d„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd$d%„ ZdS )'ÚResponseParserao  Base class for response parsing.

    This class represents the interface that all ResponseParsers for the
    various protocols must implement.

    This class will take an HTTP response and a model shape and parse the
    HTTP response into a dictionary.

    There is a single public method exposed: ``parse``.  See the ``parse``
    docstring for more info.

    zutf-8Nc                 C   sH   |d krt }|| _|d kr | j}|| _d | _| jd k	rD|  ||¡| _d S r   )ÚDEFAULT_TIMESTAMP_PARSERÚ_timestamp_parserÚ_default_blob_parserÚ_blob_parserÚ_event_stream_parserÚEVENT_STREAM_PARSER_CLS©r   Ztimestamp_parserZblob_parserr   r   r   r   Ë   s    
 ÿzResponseParser.__init__c                 C   s
   t  |¡S r   )Úbase64Ú	b64decode©r   Úvaluer   r   r   r'   Ø   s    z#ResponseParser._default_blob_parserc                 C   sØ   t  d|d ¡ t  d|d ¡ |d dkrj|  |¡rB|  |¡}qv|  |¡r\|  ||¡}|S |  ||¡}n|  ||¡}|rŠ|j 	d¡rŠ|S t
|tƒrÔ| 	di ¡}|d |d	< |d }t|ƒ|d
< ||d< |  ||¡ |S )a>  Parse the HTTP response given a shape.

        :param response: The HTTP response dictionary.  This is a dictionary
            that represents the HTTP request.  The dictionary must have the
            following keys, ``body``, ``headers``, and ``status_code``.

        :param shape: The model shape describing the expected output.
        :return: Returns a dictionary representing the parsed response
            described by the model.  In addition to the shape described from
            the model, each response will also have a ``ResponseMetadata``
            which contains metadata about the response, which contains at least
            two keys containing ``RequestId`` and ``HTTPStatusCode``.  Some
            responses may populate additional keys, but ``RequestId`` will
            always be present.

        zResponse headers: %sÚheaderszResponse body:
%sÚbodyÚstatus_codei-  ÚeventstreamÚResponseMetadataZHTTPStatusCodeZHTTPHeaders)ÚLOGÚdebugÚ_is_generic_error_responseÚ_do_generic_error_parseÚ_is_modeled_error_shapeÚ_do_modeled_error_parseÚ_do_error_parseÚ	_do_parseÚserializationÚgetÚ
isinstanceÚdictr   Ú_add_checksum_response_metadata)r   Úresponser   ÚparsedÚresponse_metadatar0   r   r   r   ÚparseÞ   s(    


zResponseParser.parsec                 C   s.   |  di ¡  di ¡}|  d¡}|r*||d< d S )NÚcontextZchecksumZresponse_algorithmZChecksumAlgorithm©r>   )r   rB   rD   Zchecksum_contextÚ	algorithmr   r   r   rA     s    
z.ResponseParser._add_checksum_response_metadatac                 C   s   |d k	o|j  dd¡S )NÚ	exceptionF)Úmetadatar>   )r   r   r   r   r   r9     s    z&ResponseParser._is_modeled_error_shapec                 C   sD   |d dkr@d|ks |d d kr$dS |d   ¡ }| d¡p>| S d S )Nr2   iô  r1   Ts   <html>)ÚstripÚ
startswith)r   rB   r1   r   r   r   r7     s
    z)ResponseParser._is_generic_error_responsec                 C   s4   t  d¡ t|d ƒtjjj |d d¡dœi dœS )NzlReceived a non protocol specific error response from the service, unable to populate error code and message.r2   r   ©ÚCodeÚMessage©ÚErrorr4   )r5   r6   Ústrr   ÚmovesÚhttp_clientÚ	responsesr>   ©r   rB   r   r   r   r8   +  s    ÿ

 ÿþùz&ResponseParser._do_generic_error_parsec                 C   s   t d| jj ƒ‚d S )Nz%s._do_parse©ÚNotImplementedErrorÚ	__class__r   ©r   rB   r   r   r   r   r<   <  s    zResponseParser._do_parsec                 C   s   t | jj› dƒ‚d S )Nz._do_error_parserW   rZ   r   r   r   r;   ?  s    zResponseParser._do_error_parsec                 C   s   t | jj› dƒ‚d S )Nz._do_modeled_error_parserW   )r   rB   r   rC   r   r   r   r:   B  s    ÿz&ResponseParser._do_modeled_error_parsec                 C   s    t | d|j› | jƒ}|||ƒS )NZ_handle_)ÚgetattrÚ	type_nameÚ_default_handle)r   r   ÚnodeÚhandlerr   r   r   Ú_parse_shapeG  s     
 ÿzResponseParser._parse_shapec                 C   s*   g }|j }|D ]}| |  ||¡¡ q|S r   )ÚmemberÚappendr`   )r   r   r^   rC   Úmember_shapeÚitemr   r   r   Ú_handle_listM  s
    zResponseParser._handle_listc                 C   s   |S r   r   ©r   r   r/   r   r   r   r]   V  s    zResponseParser._default_handlec                 C   s&   | j }|d  d¡}t|d |||ƒS )NrF   Zoperation_namer1   )r)   r>   r   )r   rB   r   ÚparserÚnamer   r   r   Ú_create_event_streamY  s    z#ResponseParser._create_event_streamc                 C   s   t |ƒd S ©Nr   )Úlistr.   r   r   r   Ú_get_first_key^  s    zResponseParser._get_first_keyc                 C   sR   |j rNt|ƒdkr$d}t||j ƒ‚|  |¡}||jkrNd}t || ¡ dS dS )Né   zCInvalid service response: %s must have one and only one member set.zqReceived a tagged union response with member unknown to client: %s. Please upgrade SDK for full response support.TF)Zis_tagged_unionÚlenr#   rh   rl   Úmembersr5   Úinfo)r   r   r/   Ú	error_msgÚtagÚmsgr   r   r   Ú _has_unknown_tagged_union_membera  s    ÿ

ÿz/ResponseParser._has_unknown_tagged_union_memberc                 C   s   dd|iiS )NZSDK_UNKNOWN_MEMBERrh   r   )r   rr   r   r   r   Ú#_handle_unknown_tagged_union_membert  s    z2ResponseParser._handle_unknown_tagged_union_member)NN)r   r   r   Ú__doc__ÚDEFAULT_ENCODINGr*   r   r'   rE   rA   r9   r7   r8   r<   r;   r:   r`   re   r]   ri   rl   rt   ru   r   r   r   r   r$   º   s(   
1	r$   c                       s¾   e Zd Zd"‡ fdd„	Zdd„ Zdd„ Z‡ fdd	„Zd
d„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZed d!„ ƒZeZeZeZ‡  ZS )#ÚBaseXMLResponseParserNc                    s   t ƒ  ||¡ t d¡| _d S )Nz{.*})Úsuperr   ÚreÚcompileÚ_namespace_rer+   ©rY   r   r   r   y  s    zBaseXMLResponseParser.__init__c                 C   s®   i }|j }|j}|j d¡pd}|j d¡p.d}|j d¡rLt|tƒsL|g}|D ]X}|D ]F}	|  |	¡}
|
|kr||  ||	¡}qX|
|kr’|  ||	¡}qXtd|
 ƒ‚qX|||< qP|S )Nrh   Úkeyr/   Ú	flattenedzUnknown tag: %s)	r~   r/   r=   r>   r?   rk   Ú	_node_tagr`   r#   )r   r   r^   rC   Ú	key_shapeÚvalue_shapeZkey_location_nameZvalue_location_nameZkeyval_nodeZsingle_pairZtag_nameZkey_nameZval_namer   r   r   Ú_handle_map}  s"    

z!BaseXMLResponseParser._handle_mapc                 C   s   | j  d|j¡S ©Nr   )r|   Úsubrr   )r   r^   r   r   r   r€   ’  s    zBaseXMLResponseParser._node_tagc                    s*   |j  d¡rt|tƒs|g}tƒ  ||¡S )Nr   )r=   r>   r?   rk   ry   re   )r   r   r^   r}   r   r   re   •  s    z"BaseXMLResponseParser._handle_listc                 C   s  i }|j }|j dd¡r"|  |¡}|  |¡}|  ||¡rL|  |¡}|  |¡S |D ]º}|| }d|jksP|j d¡rtqP|  	||¡}	| |	¡}
|
d k	r¤|  
||
¡||< qP|j d¡rPi }|jd }|j ¡ D ],\}}| j | d¡d d |¡}|||< qÈ||krP|| ||< qP|S )	NrI   FÚlocationÚeventheaderZxmlAttributerh   ú:r   )ro   rJ   r>   Ú_get_error_rootÚ_build_name_to_xml_nodert   rl   ru   r=   Ú_member_key_namer`   ÚattribÚitemsr|   r…   Úsplit)r   r   r^   rC   ro   Úxml_dictrr   Úmember_namerc   Zxml_nameZmember_nodeZattribsZlocation_namer~   r/   Znew_keyr   r   r   Ú_handle_structureŸ  sD    



ÿ
þ
 ÿ

 ÿ
z'BaseXMLResponseParser._handle_structurec                 C   s2   |   |¡dkr.|D ]}|   |¡dkr|  S q|S )NZErrorResponserQ   ©r€   )r   Úoriginal_rootÚchildr   r   r   r‰   Ã  s
    
z%BaseXMLResponseParser._get_error_rootc                 C   sL   |j dkr0|j d¡r0|jj d¡}|d k	r0|S |j d¡}|d k	rH|S |S )Nrk   r   rh   )r\   r=   r>   ra   )r   r   r   Zlist_member_serialized_nameZserialized_namer   r   r   r‹   Ê  s    ÿz&BaseXMLResponseParser._member_key_namec                 C   st   t |tƒr|  |d ¡S i }|D ]N}|  |¡}||krft || tƒrT||  |¡ qn|| |g||< q |||< q |S rj   )r?   rk   rŠ   r€   rb   )r   Zparent_noder   rd   r~   r   r   r   rŠ   Ú  s    


z-BaseXMLResponseParser._build_name_to_xml_nodec              
   C   sb   z*t jt  ¡ | jd}| |¡ | ¡ }W n2 tk
r\ } ztd||f ƒ‚W 5 d }~X Y nX |S )N)ÚtargetÚencodingzTUnable to parse response (%s), invalid XML received. Further retries may succeed:
%s)r   Ú	XMLParserÚTreeBuilderrw   ÚfeedÚcloser   r#   )r   Ú
xml_stringrg   ÚrootÚer   r   r   Ú_parse_xml_string_to_domñ  s     ÿ
þÿz.BaseXMLResponseParser._parse_xml_string_to_domc                 C   sB   |  ¡ D ]4\}}t|ƒr2|  |¡}|  |¡||< q|j||< q|S r   )r   rk   rŠ   Ú_replace_nodesr   )r   rC   r~   r/   Zsub_dictr   r   r   rŸ      s    
z$BaseXMLResponseParser._replace_nodesc                 C   s   |dkrdS dS d S )NÚtrueTFr   ©r   r   r   r   r   r   Ú_handle_boolean	  s    z%BaseXMLResponseParser._handle_booleanc                 C   s   t |ƒS r   )Úfloatr¡   r   r   r   Ú_handle_float  s    z#BaseXMLResponseParser._handle_floatc                 C   s
   |   |¡S r   ©r&   r¡   r   r   r   Ú_handle_timestamp  s    z'BaseXMLResponseParser._handle_timestampc                 C   s   t |ƒS r   ©Úintr¡   r   r   r   Ú_handle_integer  s    z%BaseXMLResponseParser._handle_integerc                 C   s   |S r   r   r¡   r   r   r   Ú_handle_string  s    z$BaseXMLResponseParser._handle_stringc                 C   s
   |   |¡S r   ©r(   r¡   r   r   r   Ú_handle_blob   s    z"BaseXMLResponseParser._handle_blob)NN)r   r   r   r   rƒ   r€   re   r‘   r‰   r‹   rŠ   rž   rŸ   r"   r¢   r¤   r¦   r©   rª   r¬   Z_handle_characterZ_handle_doubleÚ_handle_longÚ__classcell__r   r   r}   r   rx   x  s2   
$	





rx   c                   @   s>   e Zd Zdd„ Zdd„ Zdd„ Zddd	„Zd
d„ Zdd„ ZdS )ÚQueryParserc                 C   s\   |d }|   |¡}|  |¡}|  |¡ d|kr>| | d¡¡ d|krXd| d¡i|d< |S )Nr1   ÚErrorsÚ	RequestIdr4   )rž   rŠ   rŸ   r   Úpop)r   rB   r   Úxml_contentsrœ   rC   r   r   r   r;   *  s    


zQueryParser._do_error_parsec                 C   s   | j ||ddS )NF©Úinject_metadata©Ú_parse_body_as_xmlrZ   r   r   r   r:   :  s    z#QueryParser._do_modeled_error_parsec                 C   s   | j ||ddS )NTr´   r¶   rZ   r   r   r   r<   =  s    zQueryParser._do_parseTc                 C   s^   |d }|   |¡}i }|d k	rJ|}d|jkr>|  |jd |¡}|  ||¡}|rZ|  ||¡ |S )Nr1   ZresultWrapper)rž   r=   Ú_find_result_wrapped_shaper`   Ú_inject_response_metadata)r   rB   r   rµ   r³   rœ   rC   Ústartr   r   r   r·   @  s    

 ÿzQueryParser._parse_body_as_xmlc                 C   s   |   |¡}|| S r   )rŠ   )r   Zelement_nameZxml_root_nodeÚmappingr   r   r   r¸   O  s    
z&QueryParser._find_result_wrapped_shapec                 C   sN   |   |¡}| d¡}|d k	rJ|   |¡}| ¡ D ]\}}|j||< q.||d< d S ©Nr4   )rŠ   r>   r   r   )r   r^   Úinject_intor»   Ú
child_nodeZsub_mappingr~   r/   r   r   r   r¹   S  s    


z%QueryParser._inject_response_metadataN)T)	r   r   r   r;   r:   r<   r·   r¸   r¹   r   r   r   r   r¯   )  s   
r¯   c                       s,   e Zd Zdd„ Z‡ fdd„Zdd„ Z‡  ZS )ÚEC2QueryParserc                 C   s.   |   |¡}| d¡}|d k	r*d|ji|d< d S )NZ	requestIdr±   r4   )rŠ   r>   r   )r   r^   r½   r»   r¾   r   r   r   r¹   ^  s    

z(EC2QueryParser._inject_response_metadatac                    s,   t ƒ  ||¡}d|kr(d| d¡i|d< |S )NZ	RequestIDr±   r4   )ry   r;   r²   )r   rB   r   Úoriginalr}   r   r   r;   d  s     ÿzEC2QueryParser._do_error_parsec                 C   s@   |D ]6}|   |¡dkr|D ]}|   |¡dkr|    S qq|S )Nr°   rQ   r’   )r   r“   r”   Zerrors_childr   r   r   r‰   x  s    zEC2QueryParser._get_error_root)r   r   r   r¹   r;   r‰   r®   r   r   r}   r   r¿   ]  s   r¿   c                   @   sD   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dS )ÚBaseJSONParserc           
      C   s   i }|j r|}n||j}|d kr"d S i }|  ||¡rF|  |¡}|  |¡S |D ]@}|| }|j d|¡}| |¡}	|	d k	rJ|  || |	¡||< qJ|S )Nrh   )Zis_document_typero   rt   rl   ru   r=   r>   r`   )
r   r   r/   Úfinal_parsedÚmember_shapesrr   r   rc   Z	json_nameZ	raw_valuer   r   r   r‘   ‚  s(    


 ÿ
z BaseJSONParser._handle_structurec           	      C   sF   i }|j }|j}| ¡ D ](\}}|  ||¡}|  ||¡}|||< q|S r   )r~   r/   r   r`   )	r   r   r/   rC   r   r‚   r~   Z
actual_keyZactual_valuer   r   r   rƒ   ›  s    
zBaseJSONParser._handle_mapc                 C   s
   |   |¡S r   r«   rf   r   r   r   r¬   ¥  s    zBaseJSONParser._handle_blobc                 C   s
   |   |¡S r   r¥   rf   r   r   r   r¦   ¨  s    z BaseJSONParser._handle_timestampc           
      C   sÞ   |   |d ¡}dddœi dœ}|d }| d| dd¡¡|d d< | d	¡}| d
d¡}| d¡}d }	t|ƒdkr‚|d r‚|d }	|	d krž| d|ošt|ƒ¡}	|	d k	rÊd|	kr¾|	 dd¡d }	|	|d d< |  ||d ¡ |S )Nr1   r   ©rO   rN   rP   r0   ÚmessagerO   rQ   r2   zx-amzn-query-errorú;é   r   Z__typeú#rm   rN   )Ú_parse_body_as_jsonr>   rŽ   rn   rR   Úrsplitr¹   )
r   rB   r   r1   Úerrorr0   Zresponse_codeZquery_errorZquery_error_componentsÚcoder   r   r   r;   «  s*    	 
ÿ

zBaseJSONParser._do_error_parsec                 C   s    d|kr|d |  di ¡d< d S )Núx-amzn-requestidr4   r±   )Ú
setdefault)r   rC   r0   r   r   r   r¹   Ð  s    ÿz(BaseJSONParser._inject_response_metadatac                 C   sF   |si S |  | j¡}zt |¡}|W S  tk
r@   d|i Y S X d S )NrÅ   )Údecoderw   ÚjsonÚloadsÚ
ValueError)r   Úbody_contentsr1   Úoriginal_parsedr   r   r   rÉ   Ö  s    
z"BaseJSONParser._parse_body_as_jsonN)
r   r   r   r‘   rƒ   r¬   r¦   r;   r¹   rÉ   r   r   r   r   rÁ     s   
%rÁ   c                   @   s4   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ ZdS )ÚBaseEventStreamParserc                 C   sh   i }|j  d¡r@|d  d¡}|j |¡}|rd|  ||¡||< n$|  |||j|¡ |  |||j|¡ |S )Nr3   r0   z:event-type)r=   r>   ro   r<   Ú_parse_non_payload_attrsÚ_parse_payload)r   rB   r   rÂ   Z
event_typeZevent_shaper   r   r   r<   ä  s"     ÿ
   ÿzBaseEventStreamParser._do_parsec              	   C   s†   |d   d¡}|j  |¡}|d k	r\|  |d ¡}|  ||¡}d||  d|  dd¡¡dœi}n&d|d   d	d¡|d   d
d¡dœi}|S )Nr0   z:exception-typer1   rQ   rO   rÅ   r   rM   z:error-codez:error-message)r>   ro   Ú_initial_body_parser`   )r   rB   r   Zexception_typeZexception_shaperÔ   r1   rË   r   r   r   r;   ô  s     þÿþÿz%BaseEventStreamParser._do_error_parsec                 C   s¦   |j  d¡r¢|D ]l}|| }|j  d¡r|d }|jdkr@|}n.|jdkrX| | j¡}n|  |¡}	|  ||	¡}|||<  d S q|  |d ¡}
|  ||
¡}| |¡ d S )NÚeventZeventpayloadr1   ÚblobÚstring)r=   r>   r\   rÏ   rw   rØ   r`   r   )r   rB   r   rÃ   rÂ   rh   rc   r1   Zparsed_bodyZ	raw_parserÔ   Úbody_parsedr   r   r   r×   	  s&    


 ÿz$BaseEventStreamParser._parse_payloadc           	      C   sZ   |d }|D ]H}|| }|j  d¡r||kr|| }|jdkrL|  |d ¡}|||< qd S )Nr0   r‡   Ú	timestampg     @@)r=   r>   r\   r&   )	r   rB   r   rÃ   rÂ   r0   rh   rc   r/   r   r   r   rÖ     s    
z.BaseEventStreamParser._parse_non_payload_attrsc                 C   s   t dƒ‚d S ©NrØ   ©rX   ©r   rÓ   r   r   r   rØ   .  s    z)BaseEventStreamParser._initial_body_parseN)r   r   r   r<   r;   r×   rÖ   rØ   r   r   r   r   rÕ   ã  s
   rÕ   c                   @   s   e Zd Zdd„ ZdS )ÚEventStreamJSONParserc                 C   s
   |   |¡S r   ©rÉ   rà   r   r   r   rØ   7  s    z)EventStreamJSONParser._initial_body_parseN©r   r   r   rØ   r   r   r   r   rá   6  s   rá   c                   @   s   e Zd Zdd„ ZdS )ÚEventStreamXMLParserc                 C   s   |st  d¡S |  |¡S r„   ©r   ÚElementrž   ©r   r›   r   r   r   rØ   <  s    
z(EventStreamXMLParser._initial_body_parseNrã   r   r   r   r   rä   ;  s   rä   c                   @   s0   e Zd ZeZdd„ Zdd„ Zdd„ Zdd„ Zd	S )
Ú
JSONParserc                 C   sJ   i }|d k	r6|j }|r&|  |||¡}n|  |d |¡}|  ||d ¡ |S )Nr1   r0   )Zevent_stream_nameÚ_handle_event_streamÚ_handle_json_bodyr¹   )r   rB   r   rC   Ú
event_namer   r   r   r<   H  s    zJSONParser._do_parsec                 C   s   |   |d |¡S )Nr1   )rê   rZ   r   r   r   r:   S  s    z"JSONParser._do_modeled_error_parsec           	      C   s^   |j | }|  ||¡}z| ¡ }W n  tk
rB   d}t|ƒ‚Y nX |  |j|¡}|||< |S )Nz,First event was not of type initial-response)ro   ri   Zget_initial_responser   r#   rê   Úpayload)	r   rB   r   rë   Zevent_stream_shapeZevent_streamrÙ   rq   rC   r   r   r   ré   V  s    
zJSONParser._handle_event_streamc                 C   s   |   |¡}|  ||¡S r   )rÉ   r`   )r   Zraw_bodyr   Zparsed_jsonr   r   r   rê   b  s    
zJSONParser._handle_json_bodyN)	r   r   r   rá   r*   r<   r:   ré   rê   r   r   r   r   rè   B  s
   rè   c                       sd   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dd„ Z‡ fdd„Z‡  ZS )ÚBaseRestParserc                 C   s$   i }|   |¡|d< |  |||¡ |S r¼   )Ú_populate_response_metadataÚ_add_modeled_parse©r   rB   r   rÂ   r   r   r   r<   k  s    ÿzBaseRestParser._do_parsec                 C   s6   |d kr|S |j }|  ||||¡ |  ||||¡ d S r   )ro   rÖ   r×   )r   rB   r   rÂ   rÃ   r   r   r   rï   s  s       ÿz!BaseRestParser._add_modeled_parsec                 C   s   i }|   |||¡ |S r   )rï   rð   r   r   r   r:   |  s    z&BaseRestParser._do_modeled_error_parsec                 C   sJ   i }|d }d|kr"|d |d< n$d|krF|d |d< |  dd¡|d< |S )Nr0   rÍ   r±   úx-amz-request-idú
x-amz-id-2r   ÚHostIdrG   )r   rB   rJ   r0   r   r   r   rî     s    z*BaseRestParser._populate_response_metadatac           
      C   s¸   d|j kr|j d }|| }|j  d¡r>|  ||¡}|||< q´|jdkrp|d }t|tƒrf| | j¡}|||< q´|  |d ¡}|  	||¡||< n$|  |d ¡}|  	||¡}	| 
|	¡ d S )Nrì   r3   )rÛ   rÚ   r1   )r=   r>   ri   r\   r?   ÚbytesrÏ   rw   rØ   r`   r   )
r   rB   r   rÃ   rÂ   Zpayload_member_nameZ
body_shaper1   rÔ   rÜ   r   r   r   r×   Ž  s&    





 ÿ
zBaseRestParser._parse_payloadc           
      C   s    |d }|D ]Ž}|| }|j  d¡}|d kr0qq|dkrN|  ||d ¡||< q|dkrh|  ||¡||< q|dkr|j  d|¡}	|	|kr|  |||	 ¡||< qd S )Nr0   r†   Z
statusCoder2   Úheaderrh   )r=   r>   r`   Ú_parse_header_map)
r   rB   r   rÃ   rÂ   r0   rh   rc   r†   Úheader_namer   r   r   rÖ   §  s.     ÿ
 ÿ
 ÿz'BaseRestParser._parse_non_payload_attrsc                 C   sN   i }|j  dd¡ ¡ }|D ].}| ¡  |¡r|t|ƒd … }|| ||< q|S )Nrh   r   )r=   r>   ÚlowerrL   rn   )r   r   r0   rC   Úprefixr÷   rh   r   r   r   rö   ¿  s    z BaseRestParser._parse_header_mapc                 C   s   t dƒ‚d S rÞ   rß   rà   r   r   r   rØ   Ì  s    z"BaseRestParser._initial_body_parsec                 C   s,   |}t |ƒr(t |¡ | j¡}t |¡}|S r   )r   r,   r-   rÏ   rw   rÐ   rÑ   )r   r   r/   rC   Údecodedr   r   r   rª   Ó  s
    
zBaseRestParser._handle_stringc                    s@   |j  d¡}|dkr2t|tƒs2dd„ | d¡D ƒ}tƒ  ||¡S )Nr†   rõ   c                 S   s   g | ]}|  ¡ ‘qS r   )rK   )Ú.0r   r   r   r   Ú
<listcomp>Þ  s     z/BaseRestParser._handle_list.<locals>.<listcomp>ú,)r=   r>   r?   rk   rŽ   ry   re   )r   r   r^   r†   r}   r   r   re   Ú  s    zBaseRestParser._handle_list)r   r   r   r<   rï   r:   rî   r×   rÖ   rö   rØ   rª   re   r®   r   r   r}   r   rí   j  s   	rí   c                       s<   e Zd ZeZdd„ Z‡ fdd„Zdd„ Zdd„ ZeZ	‡  Z
S )	ÚRestJSONParserc                 C   s
   |   |¡S r   râ   rà   r   r   r   rØ   æ  s    z"RestJSONParser._initial_body_parsec                    s   t ƒ  ||¡}|  ||¡ |S r   )ry   r;   Ú_inject_error_code)r   rB   r   rË   r}   r   r   r;   é  s    zRestJSONParser._do_error_parsec                 C   sr   |   |d ¡}d|d krB|d d }| d¡d }||d d< n,d|ksRd|krn| d| dd	¡¡|d d< d S )
Nr1   zx-amzn-errortyper0   rˆ   r   rQ   rN   rÌ   r   )rØ   rŽ   r>   )r   rË   rB   r1   rÌ   r   r   r   rÿ   î  s    z!RestJSONParser._inject_error_codec                 C   s   t |ƒS r   r§   rf   r   r   r   r©   û  s    zRestJSONParser._handle_integer)r   r   r   rá   r*   rØ   r;   rÿ   r©   r­   r®   r   r   r}   r   rþ   â  s   rþ   c                       sD   e Zd ZeZdd„ Zdd„ Zdd„ Zdd„ Ze	‡ fd	d
„ƒZ
‡  ZS )ÚRestXMLParserc                 C   s   |st  d¡S |  |¡S r„   rå   rç   r   r   r   rØ     s    
z!RestXMLParser._initial_body_parsec                 C   sB   |d r8z|   |¡W S  tk
r6   tjddd Y nX |  |¡S )Nr1   z2Exception caught when parsing error response body:T)Úexc_info)Ú_parse_error_from_bodyr#   r5   r6   Ú_parse_error_from_http_statusrZ   r   r   r   r;   
  s    þzRestXMLParser._do_error_parsec                 C   sH   t |d ƒtjjj |d d¡dœ|d  dd¡|d  dd¡dœdœS )	Nr2   r   rM   r0   rñ   rò   )r±   ró   rP   )rR   r   rS   rT   rU   r>   rV   r   r   r   r  %  s    

 ÿþþùz+RestXMLParser._parse_error_from_http_statusc                 C   s’   |d }|   |¡}|  |¡}|  |¡ |jdkr\|  |¡}| dd¡ | dd¡ ||dœS d|krvd| d¡i|d< ddddœi}t||ƒ |S )	Nr1   rQ   r±   r   ró   rP   r4   rÄ   )rž   rŠ   rŸ   rr   rî   r²   r	   )r   rB   r³   rœ   rC   rJ   Údefaultr   r   r   r  3  s    






z$RestXMLParser._parse_error_from_bodyc                    s   t ƒ  ||¡}|S r   )ry   rª   r¡   r}   r   r   rª   J  s    zRestXMLParser._handle_string)r   r   r   rä   r*   rØ   r;   r  r  r"   rª   r®   r   r   r}   r   r     s   r   )Zec2ÚqueryrÐ   z	rest-jsonzrest-xml)'rv   r,   rÐ   Úloggingrz   Zbotocore.compatr   r   r   Zbotocore.eventstreamr   r   Zbotocore.utilsr   r   r	   r
   Ú	getLoggerr   r5   r%   r   r   r"   Ú	Exceptionr#   r$   rx   r¯   r¿   rÁ   rÕ   rá   rä   rè   rí   rþ   r   r   r   r   r   r   Ú<module>   sB   h
 ? 24$bS(xPû