o
    i!                     @   s   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 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 ddlmZ dd Zdd Zdd Zdd Zdd Z dS )    )deque)	HTTPError)config)trace_utils)	SpanTypes)core)BlockingException)schematize_url_operation)SpanDirection)ArgumentError)get_argument_value)tracer   )
CONFIG_KEY)REQUEST_SPAN_KEY)TracerStackContextc                    s   j t }|d }|d }t Z tjdtddtjdtj	|i  j
jtjd|dd
&}|j} j
}	t|	dd	}
t|	d
d}t|	dd	}t|	dd	}| d| | }t|	dd	}t|	drc|	jnt|	di }dd t|	di  D } fdd j D }|dd |d| td|tjf t jjj j
\}}|durt|tr|d| t|	t | t!j"|tj|
||||||	j#|d||d t$dd fj%}|r|j&dur|j&I dH W  d   W  d   S z| |i |I dH W W  d   W  d   S  t'yK } z6t$dd |j(d fj%}|rA|j&durA|j&I dH W  Y d}~W  d   W  d   S W Y d}~nd}~ww W d   n1 sWw   Y  W d   dS W d   dS 1 spw   Y  dS )z
    Wrap the handler execute method so that the entire request is within the same
    ``TracerStackContext``. This simplifies users code when the automatic ``Context``
    retrieval is used via ``Tracer.trace()`` method.
    default_servicedistributed_tracingztornado.requesthttp)protocol	directionT)		span_name	span_typeservicetagsdistributed_headersintegration_configactivate_distributed_headers#distributed_headers_config_overrideheaders_case_sensitivemethod r   hosturiz://query	argumentsquery_argumentsc                 S   s   i | ]	\}}|  |qS  )lower).0kvr'   r'   ]/home/ubuntu/.local/lib/python3.10/site-packages/ddtrace/contrib/internal/tornado/handlers.py
<dictcomp>8   s    zexecute.<locals>.<dictcomp>headersc                    s   i | ]}|  |qS r'   )
get_cookie)r)   r*   handlerr'   r,   r-   9   s    cookieNreq_spanzweb.request.startz
http.route)r    urlr$   request_headersraw_uriparsed_querypeer_iprouteheaders_are_case_sensitiverequest_cookiesrequest_path_paramsztornado.start_requesttornadoztornado.block_requestr   ))settingsr   r   r   context_with_datar	   r
   INBOUNDr   WEBrequestr.   r   r=   spangetattrhasattrr%   itemscookieskeyspopset_itemdispatch_find_routeapplicationdefault_routerrules
isinstancestr_set_tag_strsetattrr   r   set_http_meta	remote_ipdispatch_with_resultstornado_futurevaluer   args)funcr1   rY   kwargsr>   r   r   ctxr3   rB   r    r   r"   r#   full_urlquery_stringquery_parametersr.   rG   
http_routepath_paramsdispatch_resbr'   r0   r,   execute   s   


688 $rd   c                 C   s   t  }| D ]}|| qt|dkrJ| }|j| }durDt|jdr7|jj|dg p5|di fS t|j	drD|
|j	j t|dksdi fS )zd
    We have to walk through the same chain of rules that tornado does to find a matching rule.
    r   N_path	path_argspath_kwargsrO   z^$)r   appendlenpopleftmatchermatchrE   re   gettarget
extendleftrO   )initial_rule_setrB   rO   rulemr'   r'   r,   rL   `   s    rL   c                 C   s   t dd|f | |i |S )z3
    Wrap the ``RequestHandler.flush`` method.
    ztornado.send_responser=   )r   rK   )rZ   r1   rY   r[   r'   r'   r,   	_on_flusht   s   rs   c                 C   sv   |j }t|td}|r4|j}d|j|j|_t	d|t
j|j| ddd | |jddddf
 | |i |S )z
    Wrap the ``RequestHandler.on_finish`` method. This is the last executed method
    after the response has been sent, and it's used to retrieve and close the
    current request span (if available).
    Nz{}.{}zweb.request.finish?r   r   T)rB   rD   r   	__class__format
__module____name__resourcer   rK   r   r=   r    r]   rsplit
get_statusr$   )rZ   r1   rY   r[   rB   request_spanklassr'   r'   r,   	on_finish}   s(   r~   c                 C   s   z	t ||dd}W n ty   d}Y nw |s| |i |S t }|s+| |i |S t|tr=tj|j	r<|j
|  n|j
|  | |i |S )a@  
    Wrap the ``RequestHandler.log_exception``. This method is called when an
    Exception is not handled in the user code. In this case, we save the exception
    in the current active span. If the Tornado ``Finish`` exception is raised, this wrapper
    will not be called because ``Finish`` is not an exception.
    r   rX   N)r   r   r   current_spanrP   r   r   _http_serveris_error_codestatus_codeset_exc_info)rZ   r1   rY   r[   rX   r   r'   r'   r,   log_exception   s    


r   N)!collectionsr   tornado.webr   ddtracer   ddtrace.contrib.internalr   ddtrace.extr   ddtrace.internalr   ddtrace.internal._exceptionsr   ddtrace.internal.schemar	   -ddtrace.internal.schema.span_attribute_schemar
   ddtrace.internal.utilsr   r   ddtrace.tracer   	constantsr   r   stack_contextr   rd   rL   rs   r~   r   r'   r'   r'   r,   <module>   s(    K	 