
    kj).                     &   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mZ d dlmZ d dl	m
Z
 d dl	mZ d Zd	 Z	 dd
ededz  dedz  fdZdeddfdZdedeeeeeeeef   fdZdedeeeef   fdZdee   defdZdee   defdZdee   defdZy)    N)Iterable)Headers)Request)Response)url)validatec                 |    || vrg S | |   j                  d      }|D cg c]  }|j                          c}S c c}w )z
    Retrieve all tokens for a header key. A number of different headers
    follow a pattern where each header line can containe comma-separated
    tokens, and headers can be set multiple times.
    ,)splitstrip)headerskeytokenstokens       f/home/ubuntu/.cache/pipx/cdb5059130eadca/lib/python3.12/site-packages/mitmproxy/net/http/http1/read.pyget_header_tokensr      s?     '	S\$F'-.eEKKM...s   9c                 >    d|v rt        |d      }d|v ryd|v ry| dvS )z
    Checks the message to see if the client connection should be closed
    according to RFC 2616 Section 8.1.
    If we don't have a Connection header, HTTP 1.1 connections are assumed
    to be persistent.
    
connectioncloseTz
keep-aliveF)zHTTP/1.1s   HTTP/1.1zHTTP/2.0s   HTTP/2.0)r   )http_versionr   r   s      r   connection_closer      s@     w"7L9fV#        requestresponsereturnc                    |s| j                   }n|j                   }| j                  j                         dk(  ryd|j                  cxk  rdk  ry |j                  dv ryd|j                  cxk  rdk  r!n n| j                  j                         dk(  ry|j	                  d	      x}rzt        j                  |      }|xxd
k(  r  yxdk(  r  yxdk(  r  yxdk(  r  y xxdk(  rnxdk(  rnxdk(  rnxdk(  rn n  |ry|dk(  sd|v rn	 y}t        j                  |       |j	                  d      x}rt        j                  |      S |syy)aS  
    Returns:
        The expected body length:
        - a positive integer, if the size is known in advance
        - None, if the size in unknown in advance (chunked encoding)
        - -1, if all data should be read until end of stream.

    Raises:
        ValueError, if the content-length or transfer-encoding header is invalid
    HEADr   d      )   i0     i+  CONNECTztransfer-encodingchunkedzcompress,chunkedzdeflate,chunkedzgzip,chunkedNcompressdeflategzipidentityzcontent-length)
r   methodupperstatus_codegetr   parse_transfer_encodingtypingassert_neverparse_content_length)r   r   r   te_strteothercls          r   expected_http_body_sizer5   /   sg    //"" >>!V+(&&-#- .:- (&&-#-'..2F2F2HI2U0 011v1--f5TT 0T 3DT GUT U=i&:= #'77'B  ##E** [[)**r*,,R00  r   r   c                 L    t        j                  d|       st        d|       y )Ns   ^HTTP/\d\.\d$zUnknown HTTP version: )rematch
ValueError)r   s    r   raise_if_http_version_unknownr:      s*    88%|41,1ABCC 5r   linec                 R   	 | j                         \  }}}|dk(  s|j                  d      rdd|}}}d\  }}n|dk(  r(d|d}}}t        j                  |d      \  }}|st        |j                  dd	
      \  }}	|j                         }|	j                  d      \  }}
}d|z   }t        j                  |d      \  }}|xs t        j                  |      }|st        t        j                  |       t        |       |||||||fS # t        $ r}t	        d|       |d }~ww xY w)N   *   /r   ) r   s   CONNECTT)checks   ://   )maxsplitzBad HTTP request line: )
r   
startswithr   parse_authorityr9   lower	partitiondefault_portparser:   )r;   r)   targetr   scheme	authoritypathhostportrest_path_es                r   _read_request_linerS      sC   D'+zz|$ T>V..t4&)3tIFJD$z!&)63tIF,,YdCJD$  !<<<;LFD
 \\^F"&.."6Iq%%<D,,YdCJD$33++F3D  IIf%l3 vvy$DD  D24(;<!CDs   C>D	 		D&D!!D&c                     	 | j                  d d      }t        |      dk(  r|j                  d       |\  }}}t        |      }t	        |       |||fS # t
        $ r}t        d|       |d }~ww xY w)N   r   zBad HTTP response line: )r   lenappendintr:   r9   )r;   partsr   status_code_strreasonr+   rR   s          r   _read_response_liner\      s    	E

4#u:?LL05-ov/*%l3 f,,  E3D8<=1DEs   AA 	A1A,,A1linesc                 b   g }| D ]  }|d   dv r5|st        d      |d   d   |d   d   dz   |j                         z   f|d<   ?	 |j                  dd      \  }}|j                         }|s
t               |j                  ||f        t	        |      S # t         $ r t        d|      w xY w)	z
    Read a set of headers.
    Stop once a blank line is reached.

    Returns:
        A headers object

    Raises:
        exceptions.HttpSyntaxException
    r   s    	zInvalid headersr(   rA   s   
    :zInvalid header line: )r9   r   r   rW   r   )r]   retr;   namevalues        r   _read_headersrc      s     &(C C7f !2332wqz3r71:#84::<#GHCGC"jjq1e$,&

D%=)C 3<  C #8!ABBCs   ABB.c                     t        | d         \  }}}}}}}t        | dd       }t        ||||||||ddt        j                         d      S )z
    Parse an HTTP request head (request line + headers) from an iterable of lines

    Args:
        lines: The input lines

    Returns:
        The HTTP request object (without body)

    Raises:
        ValueError: The input is malformed.
    r   rA   N)rM   rN   r)   rJ   rK   rL   r   r   contenttrailerstimestamp_starttimestamp_end)rS   rc   r   time)	r]   rM   rN   r)   rJ   rK   rL   r   r   s	            r   read_request_headrj      sp     ASaA=D$	4 E!"I&G!		 r   c           
          t        | d         \  }}}t        | dd       }t        ||||ddt        j                         d      S )z
    Parse an HTTP response head (response line + headers) from an iterable of lines

    Args:
        lines: The input lines

    Returns:
        The HTTP response object (without body)

    Raises:
        ValueError: The input is malformed.
    r   rA   N)r   r+   r[   r   re   rf   rg   rh   )r\   rc   r   ri   )r]   r   r+   r[   r   s        r   read_response_headrl     sT     )<E!H(E%L+vE!"I&G!			 	r   )N)r7   ri   r.   collections.abcr   mitmproxy.httpr   r   r   mitmproxy.net.httpr   r   r   r   rX   r5   bytesr:   tuplestrrS   r\   rc   listrj   rl    r   r   <module>ru      s   	   $ " " # " '	/. 37oo (4o4ZodD D$ D
#E
#E
3UE5%67#EL-e -eS%.?(@ -% W <T%[ W Dd5k h r   