o <&ßaX¬ã@szdZddlZddlZddlZddlZddlmZmZmZddl m Z m Z ddl m Z mZmZmZe e¡Ze ZGdd„deƒZdd „Zd d „ZGd d „d eƒZGdd„deƒZGdd„deƒZGdd„deƒZGdd„deƒZGdd„deƒZGdd„deƒZ Gdd„de eƒZ!Gdd„de eƒZ"Gdd„deƒZ#Gd d!„d!eƒZ$Gd"d#„d#e$eƒZ%Gd$d%„d%e$eƒZ&eee#e%e&d&œZ'dS)'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": } } Error response { "ResponseMetadata": {"RequestId": } "Error": { "Code": , "Message": , "Type": , } } éN)ÚsixÚETreeÚ XMLParseError)Ú EventStreamÚNoInitialResponseError)Úparse_timestampÚ merge_dictsÚis_json_value_headerÚlowercase_dictc@s$eZdZdd„Zdd„Zdd„ZdS)ÚResponseParserFactorycCs i|_dS©N)Ú _defaults)Úself©rú2/usr/lib/python3/dist-packages/botocore/parsers.pyÚ__init__†ó zResponseParserFactory.__init__cKs|j |¡dS)aOSet 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ÚkwargsrrrÚset_parser_defaults‰s z)ResponseParserFactory.set_parser_defaultscCst|}|di|j¤ŽS)Nr)ÚPROTOCOL_PARSERSr )rÚ protocol_nameÚ parser_clsrrrÚ create_parser•sz#ResponseParserFactory.create_parserN)Ú__name__Ú __module__Ú __qualname__rrrrrrrr …s r cCs tƒ |¡Sr )r r)Úprotocolrrrršó rcs‡fdd„}|S)Ncs.t|dƒr|j}|durd}n|}ˆ|||ƒS)NÚtextÚ)Úhasattrr)rÚshapeÚnode_or_stringr©ÚfuncrrÚ_get_text_content¤s € z(_text_content.._get_text_contentr)r%r&rr$rÚ _text_contentžs  r'c@s eZdZdS)ÚResponseParserErrorN)rrrrrrrr(²sr(c@sšeZdZdZdZdZd$dd„Zdd„Zdd „Zd d „Z d d „Z dd„Z dd„Z dd„Z dd„Zdd„Zdd„Zdd„Zdd„Zdd„Zd d!„Zd"d#„ZdS)%ÚResponseParseraoBase 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. zutf-8NcCsL|durt}||_|dur|j}||_d|_|jdur$| ||¡|_dSdSr )ÚDEFAULT_TIMESTAMP_PARSERÚ_timestamp_parserÚ_default_blob_parserÚ _blob_parserÚ_event_stream_parserÚEVENT_STREAM_PARSER_CLS©rÚtimestamp_parserÚ blob_parserrrrrÆs  ÿÿzResponseParser.__init__cCs t |¡Sr )Úbase64Ú b64decode©rÚvaluerrrr,Òs z#ResponseParser._default_blob_parsercCsÌt d|d¡t d|d¡|ddkr5| |¡r!| |¡}n| |¡r.| ||¡}|S| ||¡}n| ||¡}|rE|j  d¡rE|St |t ƒrd|  di¡}|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. zResponse headers: %sÚheaderszResponse body: %sÚbodyÚ status_codei-Ú eventstreamÚResponseMetadataÚHTTPStatusCodeÚ 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 )rÚresponser"ÚparsedÚresponse_metadatar7rrrÚparseØs&          zResponseParser.parsecCs|duo |j dd¡S)NÚ exceptionF)ÚmetadatarG)rr"rrrrBsz&ResponseParser._is_modeled_error_shapecCsD|ddkr d|vs|ddurdS|d ¡}| d¡p| SdS)Nr9iôr8Ts)ÚstripÚ startswith)rrJr8rrrr@ s  ûz)ResponseParser._is_generic_error_responsecCs4t d¡t|dƒtjjj |dd¡dœidœS)NzlReceived a non protocol specific error response from the service, unable to populate error code and message.r9r ©ÚCodeÚMessage©ÚErrorr;)r>r?ÚstrrÚmovesÚ http_clientÚ responsesrG©rrJrrrrAs   ÿÿüz&ResponseParser._do_generic_error_parsecCótd|jjƒ‚)Nz %s._do_parse©ÚNotImplementedErrorÚ __class__r©rrJr"rrrrE*ózResponseParser._do_parsecCr\)Nz%s._do_error_parser]r`rrrrD-ó ÿzResponseParser._do_error_parsecCr\)Nz%s._do_modeled_error_parser])rrJr"rKrrrrC1rbz&ResponseParser._do_modeled_error_parsecCst|d|j|jƒ}|||ƒS)Nz _handle_%s)ÚgetattrÚ type_nameÚ_default_handle)rr"ÚnodeÚhandlerrrrÚ _parse_shape5s ÿ zResponseParser._parse_shapecCs*g}|j}|D] }| | ||¡¡q|Sr )ÚmemberÚappendrh)rr"rfrKÚ member_shapeÚitemrrrÚ _handle_list:s zResponseParser._handle_listcCó|Sr r©rr"r6rrrreCszResponseParser._default_handlecCs&|j}|d d¡}t|d|||ƒS)NÚcontextÚoperation_namer8)r.rGr)rrJr"ÚparserÚnamerrrÚ_create_event_streamFsz#ResponseParser._create_event_streamcCs t|ƒdS©Nr)Úlistr5rrrÚ_get_first_keyKrzResponseParser._get_first_keycCsR|jr't|ƒdkrd}t||jƒ‚| |¡}||jvr'd}t ||¡dSdS)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)Úis_tagged_unionÚlenr(rsrwÚmembersr>Úinfo)rr"r6Ú error_msgÚtagÚmsgrrrÚ _has_unknown_tagged_union_memberNs ÿ  ÿz/ResponseParser._has_unknown_tagged_union_membercCs dd|iiS)NÚSDK_UNKNOWN_MEMBERrsr)rr~rrrÚ#_handle_unknown_tagged_union_memberarz2ResponseParser._handle_unknown_tagged_union_member©NN)rrrÚ__doc__ÚDEFAULT_ENCODINGr/rr,rMrBr@rArErDrCrhrmrertrwr€r‚rrrrr)¶s(   0   r)cs¾eZdZd"‡fdd„ Zdd„Zdd„Z‡fdd „Zd d „Zd d „Zdd„Z dd„Z dd„Z dd„Z e dd„ƒZe dd„ƒZe dd„ƒZe dd„ƒZe dd„ƒZe d d!„ƒZeZeZeZ‡ZS)#ÚBaseXMLResponseParserNcs"tt|ƒ ||¡t d¡|_dS)Nz{.*})Úsuperr†rÚreÚcompileÚ _namespace_rer0©r_rrrfs ÿzBaseXMLResponseParser.__init__c Cs¬i}|j}|j}|j d¡pd}|j d¡pd}|j d¡r&t|tƒs&|g}|D]+}|D]"} | | ¡} | |kr>| || ¡} q,| |krI| || ¡} q,td| ƒ‚| || <q(|S)NrsÚkeyr6Ú flattenedzUnknown tag: %s) rŒr6rFrGrHrvÚ _node_tagrhr() rr"rfrKÚ key_shapeÚ value_shapeÚkey_location_nameÚvalue_location_nameÚ keyval_nodeÚ single_pairÚtag_nameÚkey_nameÚval_namerrrÚ _handle_mapks"   z!BaseXMLResponseParser._handle_mapcCs|j d|j¡S©Nr )rŠÚsubr~)rrfrrrrŽ€razBaseXMLResponseParser._node_tagcs.|j d¡rt|tƒs|g}tt|ƒ ||¡S)Nr)rFrGrHrvr‡r†rm)rr"rfr‹rrrmƒsz"BaseXMLResponseParser._handle_listcCsi}|j}|j dd¡r| |¡}| |¡}| ||¡r&| |¡}| |¡S|D]]}||}d|jvs9|j d¡r:q(|  ||¡} | | ¡} | durR|  || ¡||<q(|j d¡r…i} |jd} |j   ¡D]\} }|j  |  d¡dd| ¡}|| |<qd| | vr…| | ||<q(|S) NrNFÚlocationÚ eventheaderÚ xmlAttributersú:r)r{rOrGÚ_get_error_rootÚ_build_name_to_xml_noder€rwr‚rFÚ_member_key_namerhÚattribÚitemsrŠršÚsplit)rr"rfrKr{Úxml_dictr~Ú member_namerkÚxml_nameÚ member_nodeÚattribsÚ location_namerŒr6Únew_keyrrrÚ_handle_structures@       ÿ   ÿ  ÿ  €z'BaseXMLResponseParser._handle_structurecCs2| |¡dkr|D] }| |¡dkr|Sq |S)NÚ ErrorResponserV©rŽ)rÚ original_rootÚchildrrrrŸ­s ÿz%BaseXMLResponseParser._get_error_rootcCsL|jdkr|j d¡r|jj d¡}|dur|S|j d¡}|dur$|S|S)Nrvrrs)rdrFrGri)rr"r¦Úlist_member_serialized_nameÚserialized_namerrrr¡´sÿ z&BaseXMLResponseParser._member_key_namecCstt|tƒr | |d¡Si}|D]'}| |¡}||vr3t||tƒr*|| |¡q|||g||<q|||<q|Sru)rHrvr rŽrj)rÚ parent_noder¥rlrŒrrrr Ãs   z-BaseXMLResponseParser._build_name_to_xml_nodec CsVztjt ¡|jd}| |¡| ¡}W|Sty*}ztd||fƒ‚d}~ww)N)ÚtargetÚencodingzTUnable to parse response (%s), invalid XML received. Further retries may succeed: %s)rÚ XMLParserÚ TreeBuilderr…ÚfeedÚcloserr()rÚ xml_stringrrÚrootÚerrrÚ_parse_xml_string_to_domÚs þ  ûþÿ€ÿz.BaseXMLResponseParser._parse_xml_string_to_domcCsB| ¡D]\}}t|ƒr| |¡}| |¡||<q|j||<q|Sr )r£rvr Ú_replace_nodesr)rrKrŒr6Úsub_dictrrrr¾ès   z$BaseXMLResponseParser._replace_nodescCs|dkrdSdS)NÚtrueTFr©rr"rrrrÚ_handle_booleanñsz%BaseXMLResponseParser._handle_booleancCót|ƒSr )ÚfloatrÁrrrÚ _handle_floatøóz#BaseXMLResponseParser._handle_floatcCó | |¡Sr ©r+rÁrrrÚ_handle_timestampüó z'BaseXMLResponseParser._handle_timestampcCrÃr )ÚintrÁrrrÚ_handle_integerrÆz%BaseXMLResponseParser._handle_integercCrnr rrÁrrrÚ_handle_stringsz$BaseXMLResponseParser._handle_stringcCrÇr ©r-rÁrrrÚ _handle_blobrÊz"BaseXMLResponseParser._handle_blobrƒ)rrrrr˜rŽrmr¬rŸr¡r r½r¾r'rÂrÅrÉrÌrÍrÏÚ_handle_characterÚ_handle_doubleÚ _handle_longÚ __classcell__rrr‹rr†es4          r†c@s>eZdZdd„Zdd„Zdd„Zddd „Zd d „Zd d „ZdS)Ú QueryParsercCs\|d}| |¡}| |¡}| |¡d|vr| | d¡¡d|vr,d| d¡i|d<|S)Nr8ÚErrorsÚ RequestIdr;)r½r r¾rÚpop)rrJr"Ú xml_contentsr»rKrrrrDs   zQueryParser._do_error_parsecCó|j||ddS)NF©Úinject_metadata©Ú_parse_body_as_xmlr`rrrrC#raz#QueryParser._do_modeled_error_parsecCrÙ)NTrÚrÜr`rrrrE&razQueryParser._do_parseTcCs^|d}| |¡}i}|dur%|}d|jvr| |jd|¡}| ||¡}|r-| ||¡|S)Nr8Ú resultWrapper)r½rFÚ_find_result_wrapped_shaperhÚ_inject_response_metadata)rrJr"rÛrØr»rKÚstartrrrrÝ)s  þ  zQueryParser._parse_body_as_xmlcCs| |¡}||Sr )r )rÚ element_nameÚ xml_root_nodeÚmappingrrrrß8s z&QueryParser._find_result_wrapped_shapecCsR| |¡}| d¡}|dur'| |¡}| ¡D] \}}|j||<q||d<dSdS©Nr;)r rGr£r)rrfÚ inject_intoräÚ child_nodeÚ sub_mappingrŒr6rrrrà<s     üz%QueryParser._inject_response_metadataN)T) rrrrDrCrErÝrßràrrrrrÔs  rÔcs,eZdZdd„Z‡fdd„Zdd„Z‡ZS)ÚEC2QueryParsercCs2| |¡}| d¡}|durd|ji|d<dSdS)NÚ requestIdrÖr;)r rGr)rrfrærärçrrrràHs  ÿz(EC2QueryParser._inject_response_metadatacs0tt|ƒ ||¡}d|vrd| d¡i|d<|S)NÚ RequestIDrÖr;)r‡rérDr×)rrJr"Úoriginalr‹rrrDNs   ÿzEC2QueryParser._do_error_parsecCs@|D]}| |¡dkr|D]}| |¡dkr|Sq q|S)NrÕrVr®)rr¯r°Ú errors_childrrrrŸbs ÿ€zEC2QueryParser._get_error_root)rrrràrDrŸrÓrrr‹rréFs réc@sDeZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd d„Z dS)ÚBaseJSONParserc Cs’i}|jr |}|S|j}|durdSi}| ||¡r$| |¡}| |¡S|D] }||}|j d|¡}| |¡} | durF| ||| ¡||<q&|S)Nrs)Úis_document_typer{r€rwr‚rFrGrh) rr"r6Ú final_parsedÚ member_shapesr~r¦rkÚ json_nameÚ raw_valuerrrr¬ms,î    þ€z BaseJSONParser._handle_structurec CsFi}|j}|j}| ¡D]\}}| ||¡}| ||¡}|||<q |Sr )rŒr6r£rh) rr"r6rKrrrŒÚ actual_keyÚ actual_valuerrrr˜†s   zBaseJSONParser._handle_mapcCrÇr rÎrorrrrÏrzBaseJSONParser._handle_blobcCrÇr rÈrorrrrÉ“rz BaseJSONParser._handle_timestampcCs˜| |d¡}dddœidœ}| d| dd¡¡|dd<| d¡}| d |o*t|ƒ¡}|durBd |vr<| d d ¡d }||dd <| ||d ¡|S)Nr8r ©rTrSrUÚmessagerTrVr9Ú__typeú#rxrSr7)Ú_parse_body_as_jsonrGrWÚrsplitrà)rrJr"r8ÚerrorÚ response_codeÚcoderrrrD–s  ÿ  zBaseJSONParser._do_error_parsecCs$d|vr|d| di¡d<dSdS)Núx-amzn-requestidr;rÖ)Ú setdefault)rrKr7rrrrà±sÿÿz(BaseJSONParser._inject_response_metadatacCs@|siS| |j¡}zt |¡}|WStyd|iYSw)Nr÷)Údecoder…ÚjsonÚloadsÚ ValueError)rÚ body_contentsr8Úoriginal_parsedrrrrú¶s    ýz"BaseJSONParser._parse_body_as_jsonN) rrrr¬r˜rÏrÉrDràrúrrrrrîks  rîc@s4eZdZdd„Zdd„Zdd„Zdd„Zd d „Zd S) ÚBaseEventStreamParsercCsji}|j d¡r!|d d¡}|j |¡}|r| ||¡||<|S| |||j|¡| |||j|¡|S)Nr:r7z :event-type)rFrGr{rEÚ_parse_non_payload_attrsÚ_parse_payload)rrJr"rðÚ event_typeÚ event_shaperrrrEÅs  ýÿzBaseEventStreamParser._do_parsec Csˆ|d d¡}|j |¡}|dur/| |d¡}| ||¡}d|| d| dd¡¡dœi}|Sd|d d d¡|d d d¡dœi}|S) Nr7z:exception-typer8rVrTr÷r rRz :error-codez:error-message)rGr{Ú_initial_body_parserh)rrJr"Úexception_typeÚexception_shaperr8rürrrrDÒs"  þÿ ûþÿz%BaseEventStreamParser._do_error_parsec Csª|j d¡rS|D]6}||}|j d¡r>|d}|jdkr |}n|jdkr,| |j¡}n | |¡} | || ¡}|||<dSq| |d¡} | || ¡} | | ¡dSdS)NÚeventÚ eventpayloadr8ÚblobÚstring)rFrGrdrr…r rhr) rrJr"rñrðrsrkr8Ú parsed_bodyÚ raw_parserÚ body_parsedrrrr çs$      ö ïz$BaseEventStreamParser._parse_payloadc CsZ|d}|D]$}||}|j d¡r*||vr*||}|jdkr&| |d¡}|||<qdS)Nr7rœÚ timestampg@@)rFrGrdr+) rrJr"rñrðr7rsrkr6rrrrûs  €÷z.BaseEventStreamParser._parse_non_payload_attrscCótdƒ‚©Nr ©r^©rrrrrr  óz)BaseEventStreamParser._initial_body_parseN)rrrrErDr rr rrrrrÃs   rc@óeZdZdd„ZdS)ÚEventStreamJSONParsercCó | |¡Sr ©rúrrrrr rz)EventStreamJSONParser._initial_body_parseN©rrrr rrrrró rc@r)ÚEventStreamXMLParsercCó|st d¡S| |¡Sr™©rÚElementr½©rrºrrrr ó  z(EventStreamXMLParser._initial_body_parseNr rrrrr"r!r"c@s2eZdZeZ dd„Zdd„Zdd„Zdd„Zd S) Ú JSONParsercCsJi}|dur|j}|r| |||¡}n| |d|¡}| ||d¡|S)Nr8r7)Úevent_stream_nameÚ_handle_event_streamÚ_handle_json_bodyrà)rrJr"rKÚ event_namerrrrE$szJSONParser._do_parsecCs| |d|¡S)Nr8)r+r`rrrrC/raz"JSONParser._do_modeled_error_parsec CsX|j|}| ||¡}z| ¡}Wn tyd}t|ƒ‚w| |j|¡}|||<|S)Nz,First event was not of type initial-response)r{rtÚget_initial_responserr(r+Úpayload) rrJr"r,Úevent_stream_shapeÚ event_streamrr}rKrrrr*2s    þzJSONParser._handle_event_streamcCs| |¡}| ||¡Sr )rúrh)rÚraw_bodyr"Ú parsed_jsonrrrr+>s  zJSONParser._handle_json_bodyN) rrrrr/rErCr*r+rrrrr(s  r(csdeZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd d„Z dd„Z dd„Z ‡fdd„Z ‡Z S)ÚBaseRestParsercCs$i}| |¡|d<| |||¡|Srå)Ú_populate_response_metadataÚ_add_modeled_parse©rrJr"rðrrrrEHs ÿzBaseRestParser._do_parsecCs6|dur|S|j}| ||||¡| ||||¡dSr )r{rr )rrJr"rðrñrrrr5Osÿz!BaseRestParser._add_modeled_parsecCsi}| |||¡|Sr )r5r6rrrrCWsz&BaseRestParser._do_modeled_error_parsecCsLi}|d}d|vr|d|d<|Sd|vr$|d|d<| dd¡|d<|S)Nr7rÿrÖúx-amz-request-idú x-amz-id-2r ÚHostId)rG)rrJrOr7rrrr4\s ú z*BaseRestParser._populate_response_metadatac Cs¾d|jvrK|jd}||}|j d¡r | ||¡}|||<dS|jdvr:|d}t|tƒr4| |j¡}|||<dS| |d¡}|  ||¡||<dS| |d¡}|  ||¡} |  | ¡dS)Nr.r:)rrr8) rFrGrtrdrHÚbytesrr…r rhr) rrJr"rñrðÚpayload_member_nameÚ body_shaper8rrrrrr is$          ÿ zBaseRestParser._parse_payloadc Csž|d}|D]F}||}|j d¡}|durq|dkr&| ||d¡||<q|dkr3| ||¡||<q|dkrL|j d|¡} | |vrL| ||| ¡||<qdS)Nr7r›Ú statusCoder9Úheaderrs)rFrGrhÚ_parse_header_map) rrJr"rñrðr7rsrkr›Ú header_namerrrrs,  ÿ ÿÿ€òz'BaseRestParser._parse_non_payload_attrscCsNi}|j dd¡ ¡}|D]}| ¡ |¡r$|t|ƒd…}||||<q |S)Nrsr )rFrGÚlowerrQrz)rr"r7rKÚprefixr@rsrrrr?•s €z BaseRestParser._parse_header_mapcCrrrrrrrr ¢rz"BaseRestParser._initial_body_parsecCs,|}t|ƒrt |¡ |j¡}t |¡}|Sr )r r3r4rr…rr)rr"r6rKÚdecodedrrrrÍ©s  zBaseRestParser._handle_stringcsD|j d¡}|dkrt|tƒsdd„| d¡Dƒ}tt|ƒ ||¡S)Nr›r>cSsg|]}| ¡‘qSr)rP)Ú.0r¼rrrÚ ´sz/BaseRestParser._handle_list..ú,)rFrGrHrvr¤r‡r3rm)rr"rfr›r‹rrrm°s zBaseRestParser._handle_list)rrrrEr5rCr4r rr?r rÍrmrÓrrr‹rr3Fs  r3cs0eZdZeZdd„Z‡fdd„Zdd„Z‡ZS)ÚRestJSONParsercCrr rrrrrr ¼rz"RestJSONParser._initial_body_parsecs"tt|ƒ ||¡}| ||¡|Sr )r‡rGrDÚ_inject_error_code)rrJr"rür‹rrrD¿s zRestJSONParser._do_error_parsecCsx| |d¡}d|dvr"|dd}| d¡d}||dd<dSd|vs*d|vr:| d| dd ¡¡|dd<dSdS) Nr8zx-amzn-errortyper7ržrrVrSrþr )r r¤rG)rrürJr8rþrrrrHÄs   ÿÿz!RestJSONParser._inject_error_code) rrrrr/r rDrHrÓrrr‹rrG¸s  rGcsDeZdZeZdd„Zdd„Zdd„Zdd„Ze ‡fd d „ƒZ ‡Z S) Ú RestXMLParsercCr#r™r$r&rrrr ×r'z!RestXMLParser._initial_body_parsecCs@|drz| |¡WStytjdddYnw| |¡S)Nr8z2Exception caught when parsing error response body:T)Úexc_info)Ú_parse_error_from_bodyr(r>r?Ú_parse_error_from_http_statusr`rrrrDÜs   þÿ zRestXMLParser._do_error_parsecCsHt|dƒtjjj |dd¡dœ|d dd¡|d dd¡dœdœS) Nr9r rRr7r7r8)rÖr9rU)rWrrXrYrZrGr[rrrrLös  ÿþþúz+RestXMLParser._parse_error_from_http_statuscCs’|d}| |¡}| |¡}| |¡|jdkr.| |¡}| dd¡| dd¡||dœSd|vr;d| d¡i|d<ddddœi}t||ƒ|S) Nr8rVrÖr r9rUr;rö)r½r r¾r~r4r×r)rrJrØr»rKrOÚdefaultrrrrKs         z$RestXMLParser._parse_error_from_bodycstt|ƒ ||¡}|Sr )r‡rIrÍrÁr‹rrrÍszRestXMLParser._handle_string) rrrr"r/r rDrLrKr'rÍrÓrrr‹rrIÓs rI)Úec2Úqueryrz rest-jsonzrest-xml)(r„rˆr3rÚloggingÚbotocore.compatrrrÚbotocore.eventstreamrrÚbotocore.utilsrrr r Ú getLoggerrr>r*Úobjectr rr'Ú Exceptionr(r)r†rÔrérîrrr"r(r3rGrIrrrrrÚsD h 0-5%XN'rN û