
    uYf              
       t   d dl 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Zd d
lmZ ej                  dk\  rd dlmZ n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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&m0Z0 dd&l&m1Z1 dd'l&m2Z2 dd(l3m4Z4 dd)l5m6Z6 dd*l5m7Z7 dd+l5m8Z8 dd,l9m:Z: d-d.l;m<Z<  e4e=      Z>d/Z?d0Z@d1ZAd2ZBd3ZCd4ZDd5ZEd6ZFd7ZGd8ZHd9ZId:ZJd;ZKd< ZL eLe@      ZM eLeA      ZN eLeB      ZO eLeC      ZP eQeI e<eI      j                         g      ZS eLeD      ZT eLeE      ZU eLeF      ZV eLeG      ZW eLeH      ZX eLeJ      ZY eLeK      ZZ e j                  d=e j                        Z]dPd>Z^d?ee_e_f   d@efdAZ`dB ZaeaZbdC Zc G dD dE      Zd G dF dG      Ze G dH dI      Zf G dJ dK      Zg G dL dM      Zhe0ede.eee/efe(ege'ehiZi G dN dOej      Zky)Q    N)Any)Dict)	FrozenSet)List)Optional)Text)Tuple)cast)Span)      )Literal)config)SpanLink)Context)!_get_64_highest_order_bits_as_hex) _get_64_lowest_order_bits_as_int)_MetaDictType   )	AUTO_KEEP)AUTO_REJECT)	USER_KEEP)TagsetDecodeError)TagsetEncodeError)TagsetMaxSizeDecodeError)TagsetMaxSizeEncodeError)decode_tagset_string)encode_tagset_valuesensure_text)_PROPAGATION_STYLE_NONE)#_PROPAGATION_STYLE_W3C_TRACECONTEXT)HIGHER_ORDER_TRACE_ID_BITS)LAST_DD_PARENT_ID_KEY)MAX_UINT_64BITS)PROPAGATION_STYLE_B3_MULTI)PROPAGATION_STYLE_B3_SINGLE)PROPAGATION_STYLE_DATADOG)W3C_TRACEPARENT_KEY)W3C_TRACESTATE_KEY)
get_logger)SAMPLING_DECISION_TRACE_TAG_KEY)SamplingMechanism)validate_sampling_decision)w3c_tracestate_add_p   )get_wsgi_headerzot-baggage-zx-datadog-trace-idzx-datadog-parent-idzx-datadog-sampling-priorityzx-datadog-originb3zx-b3-traceidzx-b3-spanidzx-b3-sampledz
x-b3-flagszx-datadog-tagstraceparent
tracestatec                 J    t        | t        |       j                         g      S N)	frozensetr1   lower)headers    X/var/www/highfloat_scraper/venv/lib/python3.12/site-packages/ddtrace/propagation/http.py_possible_headerr;   M   s     fof5;;=>??    aj  
     ^                  # Start of string
     ([a-f0-9]{2})-     # 2 character hex version
     ([a-f0-9]{32})-    # 32 character hex trace id
     ([a-f0-9]{16})-    # 16 character hex span id
     ([a-f0-9]{2})      # 2 character hex sample flag
     (-.+)?             # optional, start of any additional values
     $                  # end of string
     c                 @    | D ]  }||v st        ||   d      c S  |S )Nbackslashreplace)errorsr   )possible_header_namesheadersdefaultr9   s       r:   _extract_header_valuerC   s   s4    ' KWwv7IJJK Nr<   rA   contextc                     |U| j                         D ]A  \  }}|d t        t               t        k(  s |j                  |t        t              d  |       C y y r6   )itemslen_HTTP_BAGGAGE_PREFIX_set_baggage_item)rA   rD   keyvalues       r:   _attach_baggage_to_contextrL   |   s]    !--/ 	SJC.S-./3GG))#c2F.G.I*JER	S r<   c                     t        | d      S )z7Helper to convert hex ids into Datadog compatible ints.   )int)hex_ids    r:   _hex_id_to_dd_idrQ      s     vr?r<   c                 X    | t         kD  rdj                  |       S dj                  |       S )zGHelper to convert Datadog trace/span int ids into lower case hex valuesz{:032x}{:016x})_MAX_UINT_64BITSformat)dd_ids    r:   _dd_id_to_b3_idrW      s1      &&E""r<   c                       e Zd ZdZ edg      Zed        Zed        Zed        Z	ede
dedefd	       Zed
e
defd       Zed        Zed        Zy)_DatadogMultiHeadera  Helper class for injecting/extract Datadog multi header format

    Headers:

      - ``x-datadog-trace-id`` the context trace id as a uint64 integer
      - ``x-datadog-parent-id`` the context current span id as a uint64 integer
      - ``x-datadog-sampling-priority`` integer representing the sampling decision.
        ``<= 0`` (Reject) or ``> 1`` (Keep)
      - ``x-datadog-origin`` optional name of origin Datadog product which initiated the request
      - ``x-datadog-tags`` optional tracer tags

    Restrictions:

      - Trace tag key-value pairs in ``x-datadog-tags`` are extracted from incoming requests.
      - Only trace tags with keys prefixed with ``_dd.p.`` are propagated.
      - The trace tag keys must be printable ASCII characters excluding space, comma, and equals.
      - The trace tag values must be printable ASCII characters excluding comma. Leading and
        trailing spaces are trimmed.
    z_dd.p.upstream_servicesc                 $    | j                  d      S )Nz_dd.p.)
startswith)rJ   s    r:   _is_valid_datadog_trace_tag_keyz3_DatadogMultiHeader._is_valid_datadog_trace_tag_key   s    ~~h''r<   c                 &    t        t        | d      S )N rB   )rC   _POSSIBLE_HTTP_HEADER_TAGSrA   s    r:   _get_tags_valuez#_DatadogMultiHeader._get_tags_value   s     %&
 	
r<   c                 ^   	 t        |       j                         D ci c]/  \  }}|t        j                  vrt        j	                  |      r||1 }}}|S c c}}w # t
        $ r ddi}t        j                  dd       Y |S t        $ r  ddi}t        j                  d| d       Y |S w xY w)N_dd.propagation_errorextract_max_sizezfailed to decode x-datadog-tagsTexc_infodecoding_errorz#failed to decode x-datadog-tags: %r)
r   rF   rY   _X_DATADOG_TAGS_EXTRACT_REJECTr\   r   logwarningr   debug)
tags_valuekvmetas       r:   _extract_metaz!_DatadogMultiHeader._extract_meta   s    	X 3:>DDFQ0OOO+KKAN	 1D $ % ( 	J');D KK9DKI  ! 	X')9D II;ZRVIW	Xs(   A 4AA A $B,$B,+B,trace_id_hob_hexlow_64_bitsreturnc                 >    t        | dj                  |      z   d      S )NrS   rN   )rO   rU   )rr   rs   s     r:   _put_together_trace_idz*_DatadogMultiHeader._put_together_trace_id   s"     #i&6&6{&CCRHHr<   upper_64_bitsc                     	 t        |       dk7  st        | d      s| j                         st        y# t        $ r Y yw xY w)NrN   FT)rG   rO   islower
ValueError)rw   s    r:   _higher_order_is_validz*_DatadogMultiHeader._higher_order_is_valid   sG    	=!R'M20F=K`K`Kb     		s   03 	??c                 \   | j                   | j                  t        j                  d|        y | j                   t        kD  rLt        t        | j                               |t        <   t        | j                         | j                  t        <   nt        | j                         |t        <   t        | j                        |t        <   | j                  }|t        | j                        |t        <   | j                  t        | j                        |t         <   t"        j$                  sd| j                  d<   y d| j                  v ry | j                  j'                         D ci c]/  \  }}t(        j+                  |      rt        |      t        |      1 }}}|r$	 t-        |t"        j.                        |t0        <   y y c c}}w # t2        $ r) d| j                  d<   t        j5                  dd       Y y t6        $ r) d	| j                  d<   t        j5                  dd       Y y w xY w)
N"tried to inject invalid context %rdisabledrd   )max_sizeinject_max_sizezfailed to encode x-datadog-tagsTrf   encoding_error)trace_idspan_idrj   rl   rT   strr   HTTP_HEADER_TRACE_IDr   _meta_HIGHER_ORDER_TRACE_ID_BITSHTTP_HEADER_PARENT_IDsampling_priorityHTTP_HEADER_SAMPLING_PRIORITY	dd_originr    HTTP_HEADER_ORIGINr   _x_datadog_tags_enabledrF   rY   r\   r   _x_datadog_tags_max_length_HTTP_HEADER_TAGSr   rk   r   )span_contextrA   r   rn   ro   tags_to_encodes         r:   _injectz_DatadogMultiHeader._inject   s       (L,@,@,HII:LI  #33 -00PQ]QfQf0g,hG() ?``l`u`u>vL:;,/0E0E,FG()),\-A-A)B%&(::(589W9W5XG12!!-*5l6L6L*MG&'--:DL67 #l&8&88 %**002
 1"BB1E NKN*
 
 N-A"V-N-N.)* 
 , N>O""#:;=M$ N>N""#:;=MNs   %4G"G	 	/H+:.H+*H+c           
         t        t        |       }|y 	 t        |      }|dk  s	|t        kD  rt
        j                  d|       y t        t        | d      }t        t        | t              }t        t        |       }d }t        j                  |       }|rt        j                  |      }|r~t        |v rv|t           }t        j                  |      r't         j"                  rHt        j%                  ||      }n1dj'                  |      |d<   |t        = t
        j                  d|       |si }|j)                  t*              sdt,        j.                   |t*        <   	 |t        |      }n|}|rt1        |      }t3        |xs d t        |      xs d ||t5        t6        |      	      S # t        $ r d}Y w xY w# t8        t        f$ r t
        j;                  d
|||||       Y y w xY w)Nr   zXInvalid trace id: %r. `x-datadog-trace-id` must be greater than zero and less than 2**640r_   zmalformed_tid {}rd   z>malformed_tid: %s. Failed to decode trace id from http headers-r   r   r   r   rp   zdreceived invalid x-datadog-* headers, trace-id: %r, parent-id: %r, priority: %r, origin: %r, tags:%r)rC   POSSIBLE_HTTP_HEADER_TRACE_IDSrO   rz   rT   rj   rk   POSSIBLE_HTTP_HEADER_PARENT_IDS(POSSIBLE_HTTP_HEADER_SAMPLING_PRIORITIESr   POSSIBLE_HTTP_HEADER_ORIGINrY   rb   rq   r   r{   r   _128_bit_trace_id_enabledrv   rU   getr,   r-   TRACE_SAMPLING_RULEr.   r   r
   r   	TypeErrorrl   )	rA   trace_id_strr   parent_span_idr   originrp   rm   rr   s	            r:   _extractz_DatadogMultiHeader._extract  s	    --KWU	<(H q=H'77KKjlx .+

 22Z\cmvw&'

 (88A
&44Z@D
 /47#$?@"99:JK332IIJZ\deH0B0I0IJZ0[,-45\^noDxx78678I8]8]7^4_D01	 ,$'(9$:!$5!1$7!)TN+3t"3  -.
 
o  	H	D :& 	IIU !
 	s$   F+ AF= +F:9F:=)G)(G)N)__name__
__module____qualname____doc__r7   ri   staticmethodr\   rb   rq   r   rO   rv   boolr{   r   r    r<   r:   rY   rY      s    ( &/0I/J%K"( ( 
 
  . I I3 I3 I I c d   6N 6Np U Ur<   rY   c                   0    e Zd ZdZed        Zed        Zy)_B3MultiHeadera  Helper class to inject/extract B3 Multi-Headers

    https://github.com/openzipkin/b3-propagation/blob/3e54cda11620a773d53c7f64d2ebb10d3a01794c/README.md#multiple-headers

    Example::

        X-B3-TraceId: 80f198ee56343ba864fe8b2a57d3eff7
        X-B3-ParentSpanId: 05e3ac9a4f6e3b90
        X-B3-SpanId: e457b5a2e4d86bd1
        X-B3-Sampled: 1


    Headers:

      - ``X-B3-TraceId`` header is encoded as 32 or 16 lower-hex characters.
      - ``X-B3-SpanId`` header is encoded as 16 lower-hex characters.
      - ``X-B3-Sampled`` header value of ``0`` means Deny, ``1`` means Accept, and absent means to defer.
      - ``X-B3-Flags`` header is used to set ``1`` meaning Debug or an Accept.

    Restrictions:

      - ``X-B3-Sampled`` and ``X-B3-Flags`` should never both be set

    Implementation details:

      - Sampling priority gets encoded as:
        - ``sampling_priority <= 0`` -> ``X-B3-Sampled: 0``
        - ``sampling_priority == 1`` -> ``X-B3-Sampled: 1``
        - ``sampling_priority > 1`` -> ``X-B3-Flags: 1``
      - Sampling priority gets decoded as:
        - ``X-B3-Sampled: 0`` -> ``sampling_priority = 0``
        - ``X-B3-Sampled: 1`` -> ``sampling_priority = 1``
        - ``X-B3-Flags: 1`` -> ``sampling_priority = 2``
      - ``X-B3-TraceId`` is not required, will use ``None`` when not present
      - ``X-B3-SpanId`` is not required, will use ``None`` when not present
    c                 J   | j                   | j                  t        j                  d|        y t	        | j                         |t
        <   t	        | j                        |t        <   | j                  }|.|dk  r
d|t        <   y |dk(  r
d|t        <   y |dkD  r
d|t        <   y y y )Nr}   r   r   r0   1)
r   r   rj   rl   rW   _HTTP_HEADER_B3_TRACE_ID_HTTP_HEADER_B3_SPAN_IDr   _HTTP_HEADER_B3_SAMPLED_HTTP_HEADER_B3_FLAGS)r   rA   r   s      r:   r   z_B3MultiHeader._inject  s       (L,@,@,HII:LI,;L<Q<Q,R()+:<;O;O+P'((::( A%36/0"a'36/0"Q&14-. ' )r<   c                    t        t        |       }|y t        t        |       }t        t        |       }t        t        |       }	 d }d }|t        |      xs d }|t        |      xs d }d }||dk(  rt        }n|dk(  rt        }|dk(  rt        }t        |||      S # t        t        f$ r t        j                  d||||       Y y w xY w)Nr   r   r   r   r   zRreceived invalid x-b3-* headers, trace-id: %r, span-id: %r, sampled: %r, flags: %r)rC   "_POSSIBLE_HTTP_HEADER_B3_TRACE_IDS!_POSSIBLE_HTTP_HEADER_B3_SPAN_IDS!_POSSIBLE_HTTP_HEADER_B3_SAMPLEDS_POSSIBLE_HTTP_HEADER_B3_FLAGS_b3_id_to_dd_idr   r   r   r   r   rz   rj   rl   )rA   trace_id_valspan_id_valsampledflagsr   r   r   s           r:   r   z_B3MultiHeader._extract  s    -.
 +-
 (-
 &*
	 HG'*<8@D&)+6>$ $"c>(3%^(1%|$-!!"3 
 :& 	IIg 	s   AB (C
	C
Nr   r   r   r   r   r   r   r   r<   r:   r   r   s  s0    #J 5 5$ 7 7r<   r   c                   0    e Zd ZdZed        Zed        Zy)_B3SingleHeaderaG  Helper class to inject/extract B3 Single Header

    https://github.com/openzipkin/b3-propagation/blob/3e54cda11620a773d53c7f64d2ebb10d3a01794c/README.md#single-header

    Format::

        b3={TraceId}-{SpanId}-{SamplingState}-{ParentSpanId}

    Example::

        b3: 80f198ee56343ba864fe8b2a57d3eff7-e457b5a2e4d86bd1-1-05e3ac9a4f6e3b90


    Values:

      - ``TraceId`` header is encoded as 32 or 16 lower-hex characters.
      - ``SpanId`` header is encoded as 16 lower-hex characters.
      - ``SamplingState`` header value of ``0`` means Deny, ``1`` means Accept, and ``d`` means Debug
      - ``ParentSpanId`` header is not used/ignored if sent

    Restrictions:

      - ``ParentSpanId`` value is ignored/not used

    Implementation details:

      - Sampling priority gets encoded as:
        - ``sampling_priority <= 0`` -> ``SamplingState: 0``
        - ``sampling_priority == 1`` -> ``SamplingState: 1``
        - ``sampling_priority > 1`` -> ``SamplingState: d``
      - Sampling priority gets decoded as:
        - ``SamplingState: 0`` -> ``sampling_priority = 0``
        - ``SamplingState: 1`` -> ``sampling_priority = 1``
        - ``SamplingState: d`` -> ``sampling_priority = 2``
      - ``TraceId`` is not required, will use ``None`` when not present
      - ``SpanId`` is not required, will use ``None`` when not present
    c                 @   | j                   | j                  t        j                  d|        y dj	                  t        | j                         t        | j                              }| j                  }| |dk  r|dz  }n|dk(  r|dz  }n
|dkD  r|dz  }||t        <   y )Nr}   z{}-{}r   z-0r0   z-1z-d)r   r   rj   rl   rU   rW   r   _HTTP_HEADER_B3_SINGLE)r   rA   single_headerr   s       r:   r   z_B3SingleHeader._inject  s       (L,@,@,HII:LI|7L7L'M_k_s_sOtu(::( A%%"a'%"Q&%*7&'r<   c                    t        t        |       }|sy d }d }d }|j                  d      }d }d }t        |      dk(  r|\  }n+t        |      dk(  r|\  }}nt        |      dk\  r	|d d \  }}}	 |t	        |      xs d }|t	        |      xs d }d }|#|dk(  rt
        }n|dk(  rt        }n|dk(  rt        }t        |||      S # t        t        f$ r t        j                  d	|       Y y w xY w)
Nr   r0   r   r   r   r   dr   z"received invalid b3 header, b3: %r)rC   &_POSSIBLE_HTTP_HEADER_B3_SINGLE_HEADERsplitrG   r   r   r   r   r   r   rz   rj   rl   )	rA   r   r   r   r   partsr   r   r   s	            r:   r   z_B3SingleHeader._extract   s2    ..TV]^##C( u:?JW Z1_(-%L+ Z1_16r.L+w	 '*<8@D&)+6>$ $"c>(3%^(1%^(1%!"3 
 :& 	II4 	s   .AC %C-,C-Nr   r   r<   r:   r   r     s0    $L 8 8" 6 6r<   r   c            	           e Zd ZdZed        Zed        Zed        Ze	 ddede	e   de	e
   fd	       Zed
        Zedd       Zed        Zy)_TraceContexta	  Helper class to inject/extract W3C Trace Context
    https://www.w3.org/TR/trace-context/
    Overview:
      - ``traceparent`` header describes the position of the incoming request in its
        trace graph in a portable, fixed-length format. Its design focuses on
        fast parsing. Every tracing tool MUST properly set traceparent even when
        it only relies on vendor-specific information in tracestate
      - ``tracestate`` header extends traceparent with vendor-specific data represented
        by a set of name/value pairs. Storing information in tracestate is
        optional.

    The format for ``traceparent`` is::
      HEXDIGLC        = DIGIT / "a" / "b" / "c" / "d" / "e" / "f"
      value           = version "-" version-format
      version         = 2HEXDIGLC
      version-format  = trace-id "-" parent-id "-" trace-flags
      trace-id        = 32HEXDIGLC
      parent-id       = 16HEXDIGLC
      trace-flags     = 2HEXDIGLC

    Example value of HTTP ``traceparent`` header::
        value = 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
        base16(version) = 00
        base16(trace-id) = 4bf92f3577b34da6a3ce929d0e0e4736
        base16(parent-id) = 00f067aa0ba902b7
        base16(trace-flags) = 01  // sampled

    The format for ``tracestate`` is key value pairs with each entry limited to 256 characters.
    An example of the ``dd`` list member we would add is::
    "dd=s:2;o:rum;t.dm:-4;t.usr.id:baz64"

    Implementation details:
      - Datadog Trace and Span IDs are 64-bit unsigned integers.
      - The W3C Trace Context Trace ID is a 16-byte hexadecimal string.
      - If the incoming traceparent is invalid we DO NOT use the tracecontext headers.
        Otherwise, the trace-id value is set to the hex-encoded value of the trace-id.
        If the trace-id is a 64-bit value (i.e. a Datadog trace-id),
        then the upper half of the hex-encoded value will be all zeroes.

      - The tracestate header will have one list member added to it, ``dd``, which contains
        values that would be in x-datadog-tags as well as those needed for propagation information.
        The keys to the ``dd`` values have been shortened as follows to save space:
        ``sampling_priority`` = ``s``
        ``origin`` = ``o``
        ``_dd.p.`` prefix = ``t.``
    c                 &    | j                  dd      S )N~=)replace)tag_vals    r:   decode_tag_valz_TraceContext.decode_tag_val  s     sC((r<   c                    t         j                  | j                               }|t        d| z        |j	                         \  }}}}}|dk(  rt        d| z        |dk7  rt
        j                  d|       n|dk(  r|t        d| z        t        |      }t        |      }|dk(  rt        d      |dk(  rt        d	      t        |      }	|	d
z  rd
nd}
|||
fS )zIf there is no traceparent, or if the traceparent value is invalid raise a ValueError.
        Otherwise we extract the trace-id, span-id, and sampling priority from the
        traceparent header.
        zInvalid traceparent version: %sffz(ff is an invalid traceparent version: %s00z=unsupported traceparent version:%r, still attempting to parsezRTraceparents with the version `00` should contain 4 values delimited by a dash: %sr   z0 value for trace_id is invalidz0 value for span_id is invalidr0   )_TRACEPARENT_HEX_REGEXmatchstriprz   groupsrj   rk   rQ   )tpvalid_tp_valuesversiontrace_id_hexspan_id_hextrace_flags_hexfuture_valsr   r   trace_flagsr   s              r:   _get_traceparent_valuesz%_TraceContext._get_traceparent_values  s    166rxxzB">CDD ""$	
 d?G"LMM_KKWY`a_!8qtvvww#L1";/ q=>??a<=>>&7
 "-s!2A"333r<   c                    d }| D ]:  }|j                  d      s|dd  }t        d |j                  d      D              }< |r|j                  d      }|t	        |      }nd }|j                  d      }|rt
        j                  |      }|j                  dd      }|j                         D ci c]3  \  }}|j                  d	      sd
|dd  z  t
        j                  |      5 }	}}||	||fS d i d d fS c c}}w )Nzdd=r   c              3   @   K   | ]  }|j                  d d        yw):r0   N)r   ).0items     r:   	<genexpr>z7_TraceContext._get_tracestate_values.<locals>.<genexpr>  s     M$**S!,Ms   ;sop0000000000000000zt.z_dd.p.%sr   )r[   dictr   r   rO   r   r   rF   )
ts_lddlist_memsampling_priority_tssampling_priority_ts_intr   lpidrn   ro   other_propagated_tagss
             r:   _get_tracestate_valuesz$_TraceContext._get_tracestate_values  s&     	NH""5)#AB<M9LMM	N #%66#; #/+./C+D(+/(VVC[F&55f= 66#12D SURZRZR\%HNA`a`l`lmq`r
QqrU"M$@$@$CC%! % ,-BFDPPT4''%s   2C9C9Ntraceparent_sampledtracestate_sampling_priorityr   c                 f    | xr |dk(  }|s| dk(  r|r|dk\  rd}|S |s| dk(  r|r|dk  rd}|S |}|S )a  
        When the traceparent sampled flag is set, the Datadog sampling priority is either
        1 or a positive value of sampling priority if propagated in tracestate.

        When the traceparent sampled flag is not set, the Datadog sampling priority is either
        0 or a negative value of sampling priority if propagated in tracestate.

        When origin is "rum" and there is no sampling priority propagated in tracestate, the above rules do not apply.
        rumr   r0   r   )r   r   r   from_rum_wo_priorityr   s        r:   _get_sampling_priorityz$_TraceContext._get_sampling_priority  ss     $@?SFeO %#q(15QUV5V ! !  %#q(15QTU5U ! !  !=  r<   c                 >   	 t        t        |       }|t        j                  d       y t        j                  |      \  }}}t        |i}t        t        |       }t        j                  |||||      S # t        t        f$ r t        j                  d       Y y w xY w)Nzno traceparent headerz%received invalid w3c traceparent: %s )rC   !_POSSIBLE_HTTP_HEADER_TRACEPARENTrj   rl   r   r   rz   AssertionError	exceptionr)    _POSSIBLE_HTTP_HEADER_TRACESTATE_get_context)rA   r   r   r   
trace_flagrp   tss          r:   r   z_TraceContext._extract  s    	&'H'RBz		12,9,Q,QRT,U)Hgz
 $R("#CWM))(GZTRR N+ 	MMA2F	s   'A4 A4 4%BBc                 n   |i }d }|}|r|j                  d      D cg c]  }|j                          }}dj                  |      }t        j                  d|      rt
        j                  d|       n||t        <   	 t        j                  |      }	|	rI|	\  }
}}}|j                  |j                                |r	||t        <   t        j                  ||
|      }nt
        j                  d|       t!        | ||||      S c c}w # t        t        f$ r t
        j                  d|       d }	Y w xY w)N,z[^\x20-\x7E]+z&received invalid tracestate header: %rz3received invalid dd header value in tracestate: %r z9no dd list member in tracestate from incoming request: %rr   )r   r   joinresearchrj   rl   r*   r   r   r   rz   updaterF   r$   r   r   )r   r   r   r  rp   r   r   memberr   tracestate_valuesr   r   r   s                r:   r   z_TraceContext._get_context  s=    <D& 24#?vFLLN?D?$B yy)2.		BBG ,.'(-(5(L(LT(R%
 %PaM(*?KK 5 ; ; =>6:23(5(L(LZYmou(v%IIY[]^/
 	
3 @ ":. -IISUWX(,%-s   D?D
 
'D43D4c                 h   | j                   }|r||t        <   | j                  du r,t        | j                  | j
                  xs d      |t        <   y t        | j                  v r;t        | j                  t           d      }t        | j                  |      |t        <   y | j                  |t        <   y y )NFr   rN   )
_traceparent_HTTP_HEADER_TRACEPARENT
_is_remoter/   _tracestater   _HTTP_HEADER_TRACESTATEr$   r   rO   )r   rA   r   r   s       r:   r   z_TraceContext._injectF  s     &&02G,-&&%/3G ,,l.B.B.Ga4/0 ',*<*<<l001FGL3GH`H`bi3j/03?3K3K/0 r<   r6   )r   r   r   r   r   r   r   r   rO   r   r   r   r   r   r   r   r<   r:   r   r   Z  s    -^ ) ) +4 +4Z %( %(N gk !  !@H !W_`cWd !  !D S S$ (
 (
T L Lr<   r   c                   ,    e Zd Zed        Zed        Zy)_NOP_Propagatorc                      y r6   r   ra   s    r:   r   z_NOP_Propagator._extractZ  s     r<   c                     |S r6   r   )r   rA   s     r:   r   z_NOP_Propagator._injecta  s	     r<   N)r   r   r   r   r   r   r   r<   r:   r  r  Y  s(       r<   r  c                   R    e Zd ZdZed        Zed        Zedd       Zed        Zy)HTTPPropagatorz0A HTTP Propagator using HTTP headers as carrier.c                     g }g }t         j                  D ]A  }t        |   }|j                  |       }|s |j	                  |       |j	                  |       C ||fS r6   )r   _propagation_style_extract_PROP_STYLESr   append)normalized_headerscontextsstyles_w_ctx
prop_style
propagatorrD   s         r:   "_extract_configured_contexts_availz1HTTPPropagator._extract_configured_contexts_avails  sf     ;; 	0J%j1J ))*<=G(##J/	0 %%r<   c                    | d   }g }| dd  D ]  }|| j                  |         }|j                  r|j                  r|j                  |j                  k7  rn|j                  t	        |j                  |j                  |j
                  rdnd|t        k(  r |j                  j                  t        d      nd d|d             |t        k(  st        t        |      }|s||j                  t        <    ||_        |S )Nr   r0   r^   terminated_context)reasoncontext_headers)r   r4   
attributes)indexr   r   r  r   r   r"   r   r   r*   rC   r   _span_links)r  r  r  primary_contextlinksrD   style_w_ctxr  s           r:   _resolve_contextsz HTTPPropagator._resolve_contexts  s    "1+| 	CG&x~~g'>?K7#3#38H8HOLdLd8d((#*#<#<a!&*MM $+==#4#45G#L!&:/:$   CC*+KM_`@BO))*<=1	C2 ',#r<   Nc                    |;|j                   | ur-t        j                  d| |j                          |j                   } t        t        d      rt        t        j
                  d      re||j                  }nt        j
                  j                         }|K|j                   j                  5t        j
                  j                  |       nt        j                  d       | j                  | j                  t        j                  d|        yt        j                  du r6| j                  *| j                  D ]  }| j                  |   |t         |z   <    t"        t        j$                  v rt&        j)                  | |       t*        t        j$                  v rt,        j)                  | |       t.        t        j$                  v rt0        j)                  | |       t2        t        j$                  v rt4        j)                  | |       yy)a  Inject Context attributes that have to be propagated as HTTP headers.

        Here is an example using `requests`::

            import requests

            from ddtrace.propagation.http import HTTPPropagator

            def parent_call():
                with tracer.trace('parent_span') as span:
                    headers = {}
                    HTTPPropagator.inject(span.context, headers)
                    url = '<some RPC endpoint>'
                    r = requests.get(url, headers=headers)

        :param Context span_context: Span context to propagate.
        :param dict headers: HTTP headers to extend with tracing attributes.
        :param Span non_active_span: Only to be used if injecting a non-active span.
        Nzspan_context and non_active_span.context are not the same, but should be. non_active_span.context will be used to generate distributed tracing headers. span_context: {}, non_active_span.context: {}tracersamplez>ddtrace.tracer.sample is not available, unable to sample span.r}   T)rD   rj   errorhasattrddtracer,  _local_rootcurrent_root_spanr   r-  r   r   rl   r    propagation_http_baggage_enabled_baggagerH   r(   _propagation_style_injectrY   r   r&   r   r'   r   r"   r   )r   rA   non_active_span	root_spanrJ   s        r:   injectzHTTPPropagator.inject  s   , &?+B+B,+VIIv''	 +22L7H%''..(*K*+77	#NN<<>	$):):)L)L)T%%i0IIVW   (L,@,@,HII:LI22d:|?T?T?`#,, Q6B6K6KC6P,s23Q %(H(HH''g>%)I)II""<9&&*J*JJ##L':.&2R2RR!!,8 Sr<   c                 v   | s
t               S 	 | j                         D ci c]  \  }}|j                         | }}}t        j                  r[t        j
                  D ]=  }t        |   }|j                  |      }t        j                  du rt        ||       |c S  	 t               S t        j                  |      \  }}|r7t        j                  |||      }t        j                  du rt        ||       |S 	 t               S c c}}w # t        $ r# t        j                  dd       Y t               S w xY w)a  Extract a Context from HTTP headers into a new Context.
        For tracecontext propagation we extract tracestate headers for
        propagation even if another propagation style is specified before tracecontext,
        so as to always propagate other vendor's tracestate values by default.
        This is skipped if the tracer is configured to take the first style it matches.

        Here is an example from a web endpoint::

            from ddtrace.propagation.http import HTTPPropagator

            def my_controller(url, headers):
                context = HTTPPropagator.extract(headers)
                if context:
                    tracer.context_provider.activate(context)

                with tracer.trace('my_controller') as span:
                    span.set_tag('http.url', url)

        :param dict headers: HTTP headers to extract tracing attributes.
        :return: New `Context` with propagated attributes.
        Tz2error while extracting context propagation headersrf   )r   rF   r8   r   _propagation_extract_firstr  r  r   r3  rL   r  r  r*  	Exceptionrj   rl   )	rA   namero   r  r  r  rD   r  r  s	            r:   extractzHTTPPropagator.extract  s0   0 9	[AH!QgdA$**,/!Q!Q 00"("C"C #J!-j!9J(112DEG>>$F23EwO"N#$ y *8)Z)Z[m)n&,,>>xWijG>>$F23EwO"N	  y/ "R*  	[IIJUYIZy	[s/   D DA!D D *AD D  D87D8r6   )	r   r   r   r   r   r  r*  r8  r=  r   r<   r:   r  r  p  sT    :	& 	&  > :9 :9x 1 1r<   r  r6   )lr  systypingr   r   r   r   r   r   r	   r
   r0  ddtrace._trace.spanr   version_infor   typing_extensionsr   ddtrace._trace._span_linkr   ddtrace._trace.contextr   r   r   r   	constantsr   r   r   internal._tagsetr   r   r   r   r   r   internal.compatr    internal.constantsr!   r"   r#   r   r$   r%   rT   r&   r'   r(   r)   r*   internal.loggerr+   internal.samplingr,   r-   r.   internal.utils.httpr/   _utilsr1   r   rj   rH   r   r   r   r   r   r   r   r   r   r   r  r  r;   r   r   r   r   r7   r8   r`   r   r   r   r   r   r   r   compileVERBOSEr   rC   r   rL   rQ   r   rW   rY   r   r   r   r  r  objectr  r   r<   r:   <module>rP     so   	 
          $ v)  . * A @ - ! # ! 0 0 7 7 3 3 ) 8 D Z 6 D ; < : 4 3 ( ? 1 : 6 # 
 % + -  = '  ) ' ( $ $ ( & @ "22F!G "23H"I +;<Y+Z (./AB &(9?K\;];c;c;e'fg )9:P)Q &%56N%O "$45L$M !$45L$M !!12G!H $45M$N !#34K#L   $	 JJ SS#X S S ##Z Zzq qhp pf|L |L~  2'_^V ^r<   