o
    i+C                     @  s  d dl mZ d dlmZ d dlm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Zd dlZd dl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 d dl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Z&dZ'e(e)Z*e+dZ,G dd de-Z.eG dd dZ/G dd de0eZ1e"j2e"j3e"j4e"j5hZ6G dd dZ7G dd de7Z8G dd de7Z9G d d! d!ej:Z;eG d"d# d#Z<G d$d% d%e
j=j>Z?dS )&    )annotations)abstractmethod)	dataclass)EnumN)ParseResult)urlparse)DEFAULT_AGENT_HOSTNAME)DEFAULT_AGENT_PORT)DEFAULT_AGENT_SOCKET_FILEDEFAULT_ENV_NAME)DEFAULT_SITE)
SetupError)	ErrorType)TelemetryAPIRequestMetrics)asboolg      .@   Tc                   @  s   e Zd ZdS )BackendErrorN)__name__
__module____qualname__ r   r   Q/home/ubuntu/.local/lib/python3.10/site-packages/ddtrace/testing/internal/http.pyr   (   s    r   c                   @  sx   e Zd ZU dZded< dZded< dZded< dZded	< dZd
ed< dZ	ded< dZ
ded< dZded< dddZdS )BackendResultNzt.Optional[ErrorType]
error_typet.Optional[str]error_descriptionz$t.Optional[http.client.HTTPResponse]responsezt.Optional[int]response_lengtht.Optional[bytes]response_bodyt.Anyparsed_responseFboolis_gzip_responseg        floatelapsed_secondsreturnNonec                 C  s   | j rt| jd S N)r   r   r   selfr   r   r   on_error_raise_exception7   s   
z&BackendResult.on_error_raise_exceptionr(   r)   )r   r   r   r   __annotations__r   r   r   r!   r#   r%   r'   r-   r   r   r   r   r   ,   s   
 r   c                   @  s   e Zd ZdZdZdZdZdS )	Subdomainapizcitestcycle-intakezcitestcov-intakez	ci-intakeN)r   r   r   APICITESTCYCLE	CITESTCOV
CICOVREPRTr   r   r   r   r0   <   s
    r0   c                   @  sR   e Zd ZdZedddZdd	d
ZedddZedddZ	edddZ
dS )BackendConnectorSetupzi
    Logic for detecting the backend connection mode (agentless or EVP) and creating new connectors.
    	subdomainr0   r(   BackendConnectorc                 C  s   dS )z
        Return a backend connector for the given subdomain (e.g., api, citestcov-intake, citestcycle-intake).

        This method must be implemented for each backend connection mode subclass.
        Nr   r,   r7   r   r   r   get_connector_for_subdomainK   s   z1BackendConnectorSetup.get_connector_for_subdomainstrc                 C  s   t S r*   r   r+   r   r   r   default_envT   s   z!BackendConnectorSetup.default_envc                 C  s4   t tjdrtd |  S td |  S )z}
        Detect which backend connection mode to use and return a configured instance of the corresponding subclass.
        !DD_CIVISIBILITY_AGENTLESS_ENABLEDz'Connecting to backend in agentless modez5Connecting to backend through agent in EVP proxy mode)r   osenvirongetlogdebug_detect_agentless_setup_detect_evp_proxy_setup)clsr   r   r   detect_setupW   s
   

z"BackendConnectorSetup.detect_setupc                 C  s@   t jdpt}t jdpt jd}|stdt||dS )zH
        Detect settings for agentless backend connection mode.
        DD_SITE_CI_DD_API_KEY
DD_API_KEYz*DD_API_KEY environment variable is not setsiteapi_key)r>   r?   r@   r   r   BackendConnectorAgentlessSetup)rE   rK   rL   r   r   r   rC   d   s
   z-BackendConnectorSetup._detect_agentless_setupc           
   
   C  sT  t jdpt jd}|sOt jdpt jd}t jdp%t jd}|s*|r;|p-t}|p1t}d| d| }nt jtrGd	t }ndt dt }zt|}|j	d
dd}|
  W n tyv } z
td| d| d}~ww |jrtd| d|j |jdg }	d|	v rt|dddS d|	v rt|dddS td| d)zM
        Detect settings for EVP proxy mode backend connection mode.
        _CI_DD_AGENT_URLDD_TRACE_AGENT_URLDD_TRACE_AGENT_HOSTNAMEDD_AGENT_HOSTDD_TRACE_AGENT_PORTDD_AGENT_PORTzhttp://:zunix:///info   max_attempts%Error connecting to Datadog agent at : N	endpointsz/evp_proxy/v4/z/evp_proxy/v4Turl	base_pathuse_gzipz/evp_proxy/v2/z/evp_proxy/v2FzDatadog agent at z  does not support EVP proxy mode)r>   r?   r@   r   r	   pathexistsr
   r8   get_jsonclose	Exceptionr   r   r   r#   BackendConnectorEVPProxySetup)
rE   	agent_urluser_provided_hostuser_provided_porthostport	connectorresulter[   r   r   r   rD   q   s6   z-BackendConnectorSetup._detect_evp_proxy_setupNr7   r0   r(   r8   r(   r;   )r(   r6   )r   r   r   __doc__r   r:   r<   classmethodrF   rC   rD   r   r   r   r   r6   F   s    
r6   c                   @  s    e Zd ZdddZdddZdS )rM   rK   r;   rL   r(   r)   c                 C  s   || _ || _d S r*   rJ   )r,   rK   rL   r   r   r   __init__   s   
z'BackendConnectorAgentlessSetup.__init__r7   r0   r8   c                 C  s>   t jd }r|}n
d|j d| j }t|d| jiddS )NDD_CIVISIBILITY_AGENTLESS_URLzhttps://.z
dd-api-keyT)r]   default_headersr_   )r>   r?   r@   valuerK   r8   rL   )r,   r7   agentless_urlr]   r   r   r   r:      s   z:BackendConnectorAgentlessSetup.get_connector_for_subdomainN)rK   r;   rL   r;   r(   r)   rn   )r   r   r   rr   r:   r   r   r   r   rM      s    
rM   c                   @  s*   e Zd Zddd	Zdd
dZdddZdS )re   r]   r;   r^   r_   r$   r(   r)   c                 C  s   || _ || _|| _d S r*   r\   )r,   r]   r^   r_   r   r   r   rr      s   
z&BackendConnectorEVPProxySetup.__init__c              
   C  s   zt | j}|jddd}|  W n ty) } ztd| j d| d }~ww |jr9td| j d|j |rH|j	di 	dt
}|S t
S )NrU   rV   rW   rY   rZ   configr<   )r8   r]   rb   rc   rd   r   r   r   r#   r@   r   )r,   rk   rl   rm   r<   r   r   r   r<      s   
z)BackendConnectorEVPProxySetup.default_envr7   r0   r8   c                 C  s   t | j| jd|ji| jdS )NzX-Datadog-EVP-Subdomain)r]   r^   ru   r_   )r8   r]   r^   rv   r_   r9   r   r   r   r:      s   z9BackendConnectorEVPProxySetup.get_connector_for_subdomainN)r]   r;   r^   r;   r_   r$   r(   r)   ro   rn   )r   r   r   rr   r<   r:   r   r   r   r   re      s    

re   c                   @  s   e Zd Zdeddfd1ddZd2ddZd3ddZ				d4d5d d!Zdddddefd6d&d'Z	dddefd7d(d)Z
dddefd8d+d,Zdddefd9d/d0ZdS ):r8   NFr]   r;   ru   t.Optional[dict[str, str]]timeout_secondsr&   r^   r   r_   r$   c                 C  sX   t |}| ||| _|pi | _|d ur|n|jd| _|| _| jr*d| jd< d S d S )N/gzipzAccept-Encoding)r   _make_connectionconnru   r`   rstripr^   r_   )r,   r]   ru   rz   r^   r_   
parsed_urlr   r   r   rr      s   
zBackendConnector.__init__r(   r)   c                 C  s   | j   d S r*   )r~   rc   r+   r   r   r   rc      s   zBackendConnector.closer   r   http.client.HTTPConnectionc                 C  s   |j dkr|jstd|  tjj|j|jpd|dS |j dkr<|js/td|  tjj|j|jp8d|dS |j dkrPt	|jpFt
|jpJd||jdS td	|j  d
|  )NhttpzNo hostname provided in P   )ri   rj   timeouthttpsi  unix)ri   rj   r   r`   zUnknown scheme z in )schemehostnamer   geturlr   clientHTTPConnectionrj   HTTPSConnectionUnixDomainSocketHTTPConnectionr   r`   )r,   r   rz   r   r   r   r}      s(   


z!BackendConnector._make_connectionmethodr`   datar    headers	send_gzipis_json_responser   c              
   C  s  | j |pi B }|r| jr|d urtj|dd}d|d< t }t }	zzu| jj|| j	| ||d | j
 |_t|jjdp@d|_|jjddk|_|jr\t|j  |_}
n|j  |_}
d|jj  krpd	ksn |jj d
|jj |_|jjdkrtj|_n|jjdkrtj|_ntj|_W n] ttjfy } ztj|_t ||_W Y d }~nDd }~w t!t"j#j$fy } ztj|_t ||_W Y d }~n&d }~w t%y } ztj&|_t ||_t'(d|| W Y d }~nd }~ww W t |	 |_)nt |	 |_)w |jsX|rXzt*+|
|_,W nA t*j-t.fy5 } ztj/|_t ||_W Y d }~n'd }~w t%yW } zt'(d|| tj&|_t ||_W Y d }~nd }~ww |jra| j0  |S )N   )compresslevelr|   zContent-Encoding)bodyr   zContent-Length0   i+   i  i  zError requesting %s %sz Error parsing response for %s %s)1ru   r_   r|   compressr   timeperf_counterr~   requestr^   getresponser   intr   r@   r   r%   openreadr!   statusreasonr   r   CODE_5XXr   CODE_4XXNETWORKTimeoutErrorsocketr   TIMEOUTr;   ConnectionErrorr   r   HTTPExceptionrd   UNKNOWNrA   warningr'   jsonloadsr#   JSONDecodeErrorUnicodeDecodeErrorBAD_JSONrc   )r,   r   r`   r   r   r   r   full_headersrl   
start_timer!   rm   r   r   r   _do_single_request  sl   	


 
z#BackendConnector._do_single_request	telemetry&t.Optional[TelemetryAPIRequestMetrics]rX   r   c	                 C  s   d}		 |	d7 }	| j ||||||d}
|r!|j|
j|
j|
j|
jd |
jrF|
jtv rF|	|k rFtdd|	d  }t	
d||||	 t| n	 |
S q)Nr   T   )r   r`   r   r   r   r   )secondsresponse_bytescompressed_responseerrorgS?z3Retrying %s %s in %.3f seconds (%d attempts so far))r   record_requestr'   r   r%   r   RETRIABLE_ERRORSrandomuniformrA   rB   r   sleep)r,   r   r`   r   r   r   r   r   rX   attempts_so_farrl   delay_secondsr   r   r   r   B  s6   	
zBackendConnector.requestc              	   C  s(   ddi|pi B }| j d|||d||dS )NContent-Typeapplication/jsonGETT)r`   r   r   r   r   rX   )r   )r,   r`   r   r   r   rX   r   r   r   rb   m  s   zBackendConnector.get_jsonr"   c              
   C  s:   ddi|pi B }t |d}| jd||||d||dS )Nr   r   utf-8POSTT)r`   r   r   r   r   r   rX   )r   dumpsencoder   )r,   r`   r   r   r   r   rX   encoded_datar   r   r   	post_json  s   	zBackendConnector.post_jsonfileslist[FileAttachment]c              	   C  s   t  j}|d}dd| i|pi B }t }	|D ]B}
|	d|  |	d|
jd  |
jr=|	d|
jd  |	d |	d|
j	d  |	d |	|
j
 |	d q|	d	|  | jd
||	 ||||dS )Nr   r   zmultipart/form-data; boundary=s   --%s
s)   Content-Disposition: form-data; name="%s"s   ; filename="%s"s   
s   Content-Type: %s
s   --%s--
r   )r`   r   r   r   r   rX   )uuiduuid4hexr   ioBytesIOwritenamefilenamecontent_typer   r   getvalue)r,   r`   r   r   r   r   rX   boundaryboundary_bytesr   
attachmentr   r   r   
post_files  s0   
	


zBackendConnector.post_files)
r]   r;   ru   ry   rz   r&   r^   r   r_   r$   r.   )r   r   rz   r&   r(   r   )NNFF)r   r;   r`   r;   r   r    r   ry   r   r$   r   r$   r(   r   )r   r;   r`   r;   r   r    r   ry   r   r$   r   r$   r   r   rX   r   r(   r   )r`   r;   r   ry   r   r$   r   r   rX   r   r(   r   )r`   r;   r   r"   r   ry   r   r$   r   r   rX   r   r(   r   )r`   r;   r   r   r   ry   r   r$   r   r   rX   r   r(   r   )r   r   r   DEFAULT_TIMEOUT_SECONDSrr   rc   r}   r   MAX_ATTEMPTSr   rb   r   r   r   r   r   r   r8      sF    

#E.r8   c                   @  s.   e Zd ZU ded< ded< ded< ded< dS )	FileAttachmentr;   r   r   r   r   bytesr   N)r   r   r   r/   r   r   r   r   r     s
   
 r   c                      s,   e Zd ZdZd fd	d
ZdddZ  ZS )r   z9An HTTP connection established over a Unix Domain Socket.r`   r;   argsr"   kwargsr(   r)   c                   s   t  j|i | || _d S r*   )superrr   r`   )r,   r`   r   r   	__class__r   r   rr     s   
z'UnixDomainSocketHTTPConnection.__init__c                 C  s&   t  t jt j}|| j || _d S r*   )r   AF_UNIXSOCK_STREAMconnectr`   sock)r,   r   r   r   r   r     s   
z&UnixDomainSocketHTTPConnection.connect)r`   r;   r   r"   r   r"   r(   r)   r.   )r   r   r   rp   rr   r   __classcell__r   r   r   r   r     s    r   )@
__future__r   abcr   dataclassesr   enumr   r|   http.clientr   r   r   loggingr>   r   r   	threadingr   typingturllib.parser   r   r   "ddtrace.testing.internal.constantsr   r	   r
   r   r   ddtrace.testing.internal.errorsr   "ddtrace.testing.internal.telemetryr   r   ddtrace.testing.internal.utilsr   r   r   	getLoggerr   rA   TypeVarr   rd   r   r   r;   r0   r   r   r   r   r   r6   rM   re   localr8   r   r   r   r   r   r   r   r   <module>   sX    

V  o