o
    j^V                  
   @   s  d Z ddlZeeZddlZddlZddlmZ ddl	m
Z
 ddlmZmZmZ ddlmZ ddl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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l'm)Z) ddl'm*Z* zddl+m,Z, W n e-y Z. ze.Z/dd Z,W Y dZ.[.ndZ.[.ww zddl0m1Z1 W n e-y Z2 ze2Z3dd Z1W Y dZ2[2ndZ2[2ww 		d)ddZ4dd Z5dd  Z6d!d" Z7G d#d$ d$eZ8G d%d& d&eZ9G d'd( d(eZ:dS )*zU
A server that uses http as transport via wsgi. It doesn't contain any server
logic.
    N)isgenerator)chain)AddressFileFault)SimpleCookie)unquotequote)get_fault_string_from_exception)process_contexts)RequestTooLongError)HttpRpc)HttpBaseHttpMethodContextHttpTransportContext)odict)address_parser)LIGHT_GREEN)	END_COLOR)HTTP_200)HTTP_404)HTTP_500)
apply_mtomc                  O      t N)_local_import_error_1argskwargs r   Q/var/www/html/LicenciasMiG/venv/lib/python3.10/site-packages/spyne/server/wsgi.pyr   ;      r   )parse_form_datac                  O   r   r   )_local_import_error_2r   r   r   r    r"   C   r!   r"   Tc                 C   s8  d}|r
| d d }|rA|  dr|| d 7 }n)|| d 7 }| d dkr3| d dkr2|d	| d  7 }n| d d
krA|d	| d  7 }|rt|  dddkrZt|  ddd dkrZn't|  dddd dkrw|t|  dddd 7 }n
|t|  dd7 }|t|  dd7 }|r|  dr|d| d  7 }|S )zRebuilds the calling url from values found in the
    environment.

    This algorithm was found via PEP 333, the wsgi spec and
    contributed by Ian Bicking.
     zwsgi.url_schemez://	HTTP_HOSTSERVER_NAMEhttpsSERVER_PORT443:80SCRIPT_NAME/	PATH_INFOr      z//   NQUERY_STRING?)getr	   )environprotocolserver_namepathquery_stringurlr   r   r    _reconstruct_urlG   s2   	

r:   c                 C   s   dd |  dD }t }|D ]O}|d u st|dkrq| dd}t|dkr-|d  t|d dd	}d }|d d urIt|d dd	}||d }|d u rYg  }||< || q|S )
Nc                 s   s$    | ]}| d D ]}|V  q	qdS );N)split).0s1s2r   r   r    	<genexpr>y   s   " z_parse_qs.<locals>.<genexpr>&r   =r0   r/   + )r<   r   lenappendr   replacer3   )qspairsretval
name_valuenvnamevaluelr   r   r    	_parse_qsx   s"   
rP   c                 C   sP   i }|   D ]\}}|dr%|dd   }|g}|||< td|| q|S )NHTTP_   zAdd http header %r = %r)items
startswithlowerloggerdebug)req_envrJ   kvkeyvalr   r   r    _get_http_headers   s   
r]   c                 C   sP   g }|   D ]\}}t|ttfr|D ]	}|||f qq|||f q|S r   )rS   
isinstancelisttuplerF   )headersrJ   rY   rZ   v2r   r   r    _gen_http_headers   s   rc   c                       sX   e Zd ZdZ fddZdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Z  ZS )WsgiTransportContextz^The class that is used in the transport attribute of the
    :class:`WsgiMethodContext` class.c                    s@   t t| |||| | j| _	 |dd | _	 t| j| _d S NREQUEST_METHOD)	superrd   __init__reqrX   r3   
req_methodr]   ra   )selfparent	transportrX   content_type	__class__r   r    rh      s   zWsgiTransportContext.__init__c                 C   s
   t | jS r   )r:   rX   rk   r   r   r    get_url      
zWsgiTransportContext.get_urlc                 C   s
   | j d S )Nr.   )rX   rq   r   r   r    get_path   rs   zWsgiTransportContext.get_pathc                 C   s8   t | jdd}| jdd }|d ur|d| 7 }|S )Nr.   r$   r1   r2   )r	   rX   r3   )rk   rJ   rH   r   r   r    get_path_and_qs   s
   z$WsgiTransportContext.get_path_and_qsc                 C   s8   | j dd }|d u rd S t }|| ||d jS )NHTTP_COOKIE)rX   r3   r   loadrN   )rk   r[   cookie_stringcookier   r   r    
get_cookie   s   
zWsgiTransportContext.get_cookiec                 C   s   | j d  S re   )ri   upperrq   r   r   r    get_request_method      z'WsgiTransportContext.get_request_methodc                 C   s   | j dd S )NCONTENT_TYPE)ri   r3   rq   r   r   r    get_request_content_type   r}   z-WsgiTransportContext.get_request_content_typec                 C   sR   t | jt | j}}t |rttj||dS t |r'ttj||dS d S )N)typehostport)	r   get_ipri   get_portis_valid_ipv4r   TCP4is_valid_ipv6TCP6)rk   addrr   r   r   r    get_peer   s   



zWsgiTransportContext.get_peer)__name__
__module____qualname____doc__rh   rr   rt   ru   rz   r|   r   r   __classcell__r   r   ro   r    rd      s    
rd   c                   @   s   e Zd ZdZdZeZdS )WsgiMethodContextzThe WSGI-Specific method context. WSGI-Specific information is stored in
    the transport attribute using the :class:`WsgiTransportContext` class.
    N)r   r   r   r   TransportContextrd   r   r   r   r   r    r      s    r   c                       sp   e Zd ZdZ		d fd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  ZS )WsgiApplicationa  A `PEP-3333 <http://www.python.org/dev/peps/pep-3333>`_
    compliant callable class.

    If you want to have a hard-coded URL in the wsdl document, this is how to do
    it: ::

        wsgi_app = WsgiApplication(...)
        wsgi_app.doc.wsdl11.build_interface_document("http://example.com")

    This is not strictly necessary -- if you don't do this, Spyne will get the
    URL from the first request, build the wsdl on-the-fly and cache it as a
    string in memory for later requests. However, if you want to make sure
    you only have this url on the WSDL, this is how to do it. Note that if
    your client takes the information in the Wsdl document seriously (not all
    do), all requests will go to the designated url above even when you get the
    Wsdl from another location, which can make testing a bit difficult. Use in
    moderation.

    Supported events:
        * ``wsdl``
            Called right before the wsdl data is returned to the client.

        * ``wsdl_exception``
            Called right after an exception is thrown during wsdl generation.
            The exception object is stored in ctx.transport.wsdl_error
            attribute.

        * ``wsgi_call``
            Called first when the incoming http request is identified as a rpc
            request.

        * ``wsgi_return``
            Called right before the output stream is returned to the WSGI
            handler.

        * ``wsgi_exception``
            Called right before returning the exception to the client.

        * ``wsgi_close``
            Called after the whole data has been returned to the client. It's
            called both from success and error cases.
    T        c                    sH   t t| |||| t | _d | _| jjd ur"| jj	 | _d S d S r   )
rg   r   rh   	threadingLock_mtx_build_interface_document_wsdldocwsdl11get_interface_document)rk   appchunkedmax_content_lengthblock_lengthro   r   r    rh     s   
zWsgiApplication.__init__Nc                 C   sZ   |}|du rt |dd }| |r'|dd dd }| |||S | ||S )a+  This method conforms to the WSGI spec for callable wsgi applications
        (PEP 333). It looks in environ['wsgi.input'] for a fully formed rpc
        message envelope, will deserialize the request parameters and call the
        method on the object returned by the get_handler() method.
        N.wsdlr   r2   )r:   r<   is_wsdl_requesthandle_wsdl_request
handle_rpc)rk   rX   start_responsewsgi_urlr9   r   r   r    __call__%  s   
zWsgiApplication.__call__c                 C   s@   |d   dkod|v o|d dd  dkp|d dS )	Nrf   GETr1   rB   r   wsdlr.   r   )r{   r<   rU   endswith)rk   rX   r   r   r    r   8  s   zWsgiApplication.is_wsdl_requestc              
   C   sz  t | |d}| jjd u r|tt|jj tgS | jd u r$| jj | _| j|j_	|jj	d u rz`z$| j
  | j|j_	|jj	d u rS| jj| | jj  |j_	| _W n4 ty } z(t| ||j_| jd| |tt|jj tgW  Y d }~W | j
  S d }~ww W | j
  n| j
  w | jd| tt|jj	|jjd< |tt|jj |jj	}|  |gS )Nztext/xml; charset=utf-8wsdl_exceptionr   Content-Length)r   r   r   r   rc   rm   resp_headersr   r   r   r   acquirebuild_interface_document	ExceptionrV   	exception
wsdl_errorevent_manager
fire_eventr   releasestrrE   r   close)rk   rX   r   r9   ctxerJ   r   r   r    r   H  sL   








z#WsgiApplication.handle_wsdl_requestc              
   C   s   |j jdu r|j||j _| | t|j|_ttdd |jD |j j	d< | j
d| ||j jt|j j	 z
t| |||d W n ty\ } zt| W Y d}~nd}~ww t|j| |S )a)  Serialize errors to an iterable of strings and return them.

        :param p_ctx: Primary (non-aux) context.
        :param others: List if auxiliary contexts (can be empty).
        :param error: One of ctx.{in,out}_error.
        :param start_response: See the WSGI spec for more info.
        Nc                 s   s    | ]}t |V  qd S r   rE   )r=   sr   r   r    r@     s    z/WsgiApplication.handle_error.<locals>.<genexpr>r   wsgi_exceptionerror)rm   	resp_codeout_protocolfault_to_http_response_codeget_out_stringr_   
out_stringr   sumr   r   r   rc   r   r   rV   r   r   _WsgiApplication__finalize)rk   p_ctxothersr   r   r   r   r   r    handle_errorz  s$   	



zWsgiApplication.handle_errorc              
   C   s  t | || jjj}| jd| | |\|_}| ||}|d |dd  }}d|_	|j
r8| |||j
|S | | |j
rOt|j
 | |||j
|S | | |jr`| |||j|S |jd usgJ tt|j}t|jdkoxt|}	|	rt|}
t|
f|f|_|jjd u rt|j_z| | W n( ty } zt| tdt||_| |||j|W  Y d }~S d }~ww t|jt r|j!d ur|jj"#|j! |j$r|j$j%r|j$j&j'}t|dkr|jg|_t(|jj"|j)|j$j&j'* |j\|j_"|_)| jd| | j+rd|jj"v r|jj"d= nd,|j)g|_)zt|j) t-t.d	d
 |j)D |jj"d< W n
 t/yC   Y nw ||jjt0|jj" t|j)| 1|}zt2| ||d d W |S  ty| } zt| W Y d }~|S d }~ww )N	wsgi_callr   r0   TServerwsgi_returnr   r$   c                 S   s   g | ]}t |qS r   r   )r=   ar   r   r    
<listcomp>  s    z.WsgiApplication.handle_rpc.<locals>.<listcomp>r   )3r   r   r   	mime_typer   r   *_WsgiApplication__reconstruct_wsgi_request	in_stringgenerate_contextsactivein_errorr   get_in_objectrV   r   get_out_object	out_error
out_objectnextiterrE   r   r   rm   r   r   r   r   r   r   r
   r^   r   out_header_docr   update
descriptormtomout_message
_type_infor   r   valuesr   joinr   r   	TypeErrorrc   r   r   )rk   rX   r   initial_ctxin_string_charsetcontextsr   r   gis_generator	first_objr   out_type_inforJ   r   r   r    r     s   









zWsgiApplication.handle_rpcc                 C   s   |   | jd| dS )N
wsgi_closer   )r   r   r   )rk   r   r   r   r    
__finalize  s   zWsgiApplication.__finalizec                 C   s>   | d}d}|durt|}|d  dd}| ||fS )z>Reconstruct http payload using information in the http header.r~   Nr0   charset)r3   cgiparse_header(_WsgiApplication__wsgi_input_to_iterable)rk   http_envrn   r   r   r   r    __reconstruct_wsgi_request  s   

z*WsgiApplication.__reconstruct_wsgi_requestc                 c   s    | d}t| d| j}t|dkrd}nt|}|| jkr$t d}||k r\t| j|| }|| | jkr<t ||}|d u sKt|dkrMd S |t|7 }|V  ||k s*d S d S )Nz
wsgi.inputCONTENT_LENGTHr   )	r3   r   r   rE   intr   minr   read)rk   r   istreamlength
bytes_readbytes_to_readdatar   r   r    __wsgi_input_to_iterable  s&   


z(WsgiApplication.__wsgi_input_to_iterablec              	   C   s  i }|j }| jr.|dd}|du r|d }n|dd }| ||dd|dd|}|jdu rEd	|jj |d 	d
d f |_t
dt|jtf  |jj|_t|d |_| D ]\}}||jv rr|j| | q`t||j|< q`|d  }	|	dv rt||jd\}
}}| D ]\}}|j|g }|| ||j|< q| D ]G\}}|j|g }|jdd}t|jdd}|du r|tj|j||j  gd n|j!d |tj|j|||jd ||j|< q|j D ]\}}|dgkr
dg|j|< qdS dS )zThis function is only called by the HttpRpc protocol to have the wsgi
        environment parsed into ``ctx.in_body_doc`` and ``ctx.in_header_doc``.
        r%   Nr&   r*   r   rf   r$   r.   z{%s}%sr-   z%sMethod name: %r%sr1   )POSTPUTPATCH)stream_factoryzContent-Typezapplication/octet-streamrM   )rM   r   r   )rM   r   r7   handle)"in_documenthas_patternsr3   	partitionmatch_patternmethod_request_stringr   	interfaceget_tnsr<   rV   rW   r   r   rm   ra   in_header_docrP   in_body_docrS   extendr_   r{   r"   r   listsgetattrstreamrF   r   Valuefilenamegetvalueseek)rk   protr   messageparamswsgi_envdomainrY   rZ   verbr  formfilesr\   r   r7   r   r   r    decompose_incoming_envelope4  sp   










z+WsgiApplication.decompose_incoming_envelope)Tr   r   r   )r   r   r   r   rh   r   r   r   r   r   r   r   r   r  r   r   r   ro   r    r      s    +
2!jr   )TTTT);r   logging	getLoggerr   rV   r   r   inspectr   	itertoolsr   spyner   r   r   !spyne.util.six.moves.http_cookiesr   !spyne.util.six.moves.urllib.parser   r	   spyne.applicationr
   spyne.auxprocr   spyne.errorr   spyne.protocol.httpr   spyne.server.httpr   r   r   spyne.util.odictr   spyne.util.addressr   spyne.const.ansi_colorr   r   spyne.const.httpr   r   r   spyne.protocol.soap.mimer   ImportError_import_error_1r   werkzeug.formparserr"   _import_error_2r#   r:   rP   r]   rc   rd   r   r   r   r   r   r    <module>   sZ   

18	