
    3                       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m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mZmZ d dlmZ d d	lmZ d d
lmZ 	 	 d	 	 	 	 	 	 	 ddZ G d d      Z G d de      Z G d d      Z G d de      Z G d d      Z e
jB                  jE                  e d       G d de             Z#e
jB                  jE                  e d       G d de              Z$ G d d      Z%y)     )annotationsN)LONG_TIMEOUT)hypercorn_app)ProxyApp)run_hypercorn_in_thread)DEFAULT_CERTSHAS_IPV6SocketServerThread)HTTPConnection)SSLTransport)	parse_urlc                &   t               }| j                  t               	 |r|j                         r	 |S 	 | j	                  |      }t        |t              sJ ||z  }|j                  d      r	 |S S# t
        t        j                  f$ r Y ow xY w)Ns   

)	bytearray
settimeoutr   is_setrecvTimeoutErrorsockettimeout
isinstancebytesendswith)sockchunks
quit_eventconsumedbs        ;platform/gsutil/third_party/urllib3/dummyserver/testcase.pyconsume_socketr      s    
 {HOOL!
*++- O			&!A !U###A::k"O 
 fnn- 		s   A4 4BBc                  4   e Zd ZU dZdZdZded<   ded<   ded	<   ded
<   ded<   ded<   ded<   ded<   ded<   ded<   ded<   e	 d	 	 	 	 	 dd       Ze	 	 d	 	 	 	 	 	 	 dd       Z	e	 d	 	 	 	 	 d d       Z
ed!d       Zed"d       Zd"dZ	 d	 	 	 	 	 	 	 d#dZy)$SocketDummyServerTestCasezj
    A simple socket-based server is created for this class that is good for
    exactly one request.
    http	localhostz#typing.ClassVar[SocketServerThread]server_threadtyping.ClassVar[int]porttyping.ClassVar[str]tmpdirca_pathcert_combined_path	cert_pathkey_pathpassword_key_pathztyping.ClassVar[ssl.SSLContext]server_contextclient_contextz*typing.ClassVar[SocketDummyServerTestCase]proxy_serverNc                *   t        j                         }t        ||| j                  |      | _        | j                  j                          |j                  d       |j                         st        d      | j                  j                  | _	        y )Nsocket_handlerready_eventhostr      "most likely failed to start server)
	threadingEventr
   r5   r$   startwaitr   	Exceptionr&   clsr3   r   r4   s       r   _start_serverz'SocketDummyServerTestCase._start_serverC   sz      oo'.)#!	
 	!!!#@AA$$))    c                    t        j                         t        j                         dfd}| j                  |       S )Nc                ^   t              D ]  }j                          | j                  t               	 j	                         r y 	 | j                         d   }	 t        |       j	                         r|j                           y r]j                  t              s8j	                         r|j                           y j                  t              s8j                          |j                         |j                           y # t        t        j                  f$ r Y w xY w)Nr   r   )rangesetr   r   r   acceptr   r   r   r   closer;   clearsend)listener_r   
block_sendnumr   r4   responses      r   r3   zHSocketDummyServerTestCase.start_response_handler.<locals>.socket_handler`   s    3Z!##L1!((*!'03 t
;$$&JJL(ool;%,,. JJL" )ool; $$&		(#

/   )&..9 ! !s   	DD,+D,rC   )rJ   socket.socketreturnNone)r8   r9   r?   )r>   rN   rM   rL   r3   r   r4   s    ``` @@r   start_response_handlerz0SocketDummyServerTestCase.start_response_handlerV   sB      oo'__&
	 	4 	.Z@r@   c                (    | j                  d||      S )Ns&   HTTP/1.1 200 OK
Content-Length: 0

)rR   )r>   rM   rL   s      r   start_basic_handlerz-SocketDummyServerTestCase.start_basic_handler}   s      ));
 	
r@   c                    | j                   r| j                   j                          | j                  t        dz  dz          | j	                         rt        d      y )N   g      @zserver_thread did not exit)r   rE   joinr   is_aliver<   )r$   s    r   quit_server_threadz,SocketDummyServerTestCase.quit_server_thread   sT    ##$$((* 	<!+c12!!#899 $r@   c                T    t        | d      r| j                  | j                         y y Nr$   hasattrrY   r$   r>   s    r   teardown_classz(SocketDummyServerTestCase.teardown_class   s%    3(""3#4#45 )r@   c                T    t        | d      r| j                  | j                         y y r[   r\   )selfs    r   teardown_methodz)SocketDummyServerTestCase.teardown_method   s%    4)##D$6$67 *r@   c                    |j                  d      }|d }n|j                  d      }g }|D ]7  }|j                  d      \  }}	|j                  |       ||k(  s.|1|	|k(  r7J  ||v sJ y )Nasciis   : )encodesplitappend)
ra   received_headersheader_nameexpected_valueheader_name_bytesexpected_value_bytesheader_titlesheaderkeyvalues
             r   assert_header_receivedz0SocketDummyServerTestCase.assert_header_received   s     (..w7!#' #1#8#8#A &Fe,JC  %'',@,L 4444	 '
 !M111r@   Nr3   z&typing.Callable[[socket.socket], None]r   threading.Event | NonerP   rQ   )   N)rN   r   rM   intrL   rt   rP   threading.Event)rM   rv   rL   rt   rP   rw   )r$   r
   rP   rQ   rP   rQ   )rh   ztyping.Iterable[bytes]ri   strrj   z
str | NonerP   rQ   )__name__
__module____qualname____doc__schemer5   __annotations__classmethodr?   rR   rT   staticmethodrY   r_   rb   rq    r@   r   r!   r!   +   sW   
 FD66
  !!,,##""++3333<< .2*>* +* 
	* *$  -1	$$ $ +	$
 
$ $L @D

'=
	
 
 : : 6 68 &*	202 2 #	2
 
2r@   r!   c                  ,    e Zd Ze	 d	 	 	 	 	 dd       Zy)IPV4SocketDummyServerTestCaseNc                L   t        j                         }t        ||| j                  |      | _        d| j                  _        | j                  j                          |j                  d       |j                         st        d      | j                  j                  | _
        y )Nr2   Fr6   r7   )r8   r9   r
   r5   r$   USE_IPV6r:   r;   r   r<   r&   r=   s       r   r?   z+IPV4SocketDummyServerTestCase._start_server   s      oo'.)#!	
 &+"!!!#@AA$$))r@   rr   rs   )rz   r{   r|   r   r?   r   r@   r   r   r      s5     .2*>* +* 
	* *r@   r   c                  p    e Zd ZU dZdZded<   ded<   ded<   i Zded	<   d
ed<   edd       Zedd       Z	y)HypercornDummyServerTestCaser#   	127.0.0.1r%   r&   r'   base_urlbase_url_alt&typing.ClassVar[dict[str, typing.Any]]certs%typing.ClassVar[contextlib.ExitStack]_stackc                n   t        j                         5 }t        j                         }| j                  rd| j                  d   |_        | j                  d   |_        | j                  d   |_        | j                  d   |_        | j                  d   |_	        | j                   dg|_        |j                  t        |t                     |j                         | _        t#        j$                  t&        t)        |j                  d         j*                        | _        d d d        y # 1 sw Y   y xY w)Ncertfilekeyfile	cert_reqsca_certsalpn_protocols:0r   )
contextlib	ExitStack	hypercornConfigr   r   r   verify_moder   r   r5   bindenter_contextr   r   pop_allr   typingcastrv   r   r&   )r>   stackconfigs      r   setup_classz(HypercornDummyServerTestCase.setup_class   s    !!#u%%'Fyy"%))J"7!$9!5%(YY{%;""%))J"7(+		2B(C%!hhZr?+FK 7 NOCJ{{3	&++a.(A(F(FGCH $##s   DD++D4c                8    | j                   j                          y rr   r   rG   r^   s    r   r_   z+HypercornDummyServerTestCase.teardown_class       

r@   Nrx   )
rz   r{   r|   r5   host_altr   r   r   r   r_   r   r@   r   r   r      sW    DH
""&&46E1611H H  r@   r   c                       e Zd ZdZdZeZdZdZy)!HTTPSHypercornDummyServerTestCasehttpsr#    N)	rz   r{   r|   r~   r5   r   r   	certs_dirbad_ca_pathr   r@   r   r   r      s    FDEIKr@   r   c                  2   e Zd ZU dZded<   dZded<   ded<   ded<   ded	<   dZded
<   dZded<   eZ	ded<   ded<   ded<   ded<   ded<   dZ
ded<   dZded<   ded<   ded<   ded<   ded<   dZded<   dZded<   ded<   ded<   ed"d       Zed"d        Zy!)#HypercornDummyProxyTestCaser#   r'   	http_hostr   http_host_altr%   	http_porthttp_urlhttp_url_alt
https_hosthttps_host_altr   https_certs
https_port	https_urlhttps_url_althttps_url_fqdn
proxy_hostproxy_host_alt
proxy_port	proxy_urlhttps_proxy_porthttps_proxy_urlr   r   r   z!typing.ClassVar[threading.Thread]r$   r   r   c           	        t        j                         5 }t        j                         }| j                   dg|_        |j                  t        |t                     t        j                  t        t        |j
                  d         j                        | _        t        j                         }| j                  d   |_        | j                  d   |_        | j                  d   |_        | j                  d   |_        | j                  d   |_        | j*                   dg|_        |j                  t        |t                     t        j                  t        t        |j
                  d         j                        | _        t        j                         }| j.                   dg|_        |j                  t        |t1                            t        j                  t        t        |j
                  d         j                        | _        t        j                         }| j                  d   |_        | j                  d   |_        | j                  d   |_        | j                  d   |_        | j                  d   |_        | j.                   dg|_        | j                  j5                  d      }|j                  t        |t1        |                   t        j                  t        t        |j
                  d         j                        | _        |j9                         | _        d d d        y # 1 sw Y   y xY w)Nr   r   r   r   r   r   r   )r   r   r   r   r   r   r   r   r   r   r   rv   r   r&   r   r   r   r   r   r   r   r   r   r   r   r   getr   r   r   )r>   r   http_server_confighttps_server_confighttp_proxy_confighttps_proxy_configupstream_ca_certss          r   r   z'HypercornDummyProxyTestCase.setup_class  s   !!#u!*!1!1!3*---';&<#'(:MJ #KKY7I7N7Nq7Q-R-W-WXCM"+"2"2"4+.??:+F(*-//)*D'.1ook.J++.??:+F(14AQ1R.+.>>*:"(='>$'(;]K $[[Y277:;@@CN !* 0 0 2),(8&;%<" 78I8: VW#[[i8I8N8Nq8Q.R.W.WXCN!*!1!1!3*-//**E'),)C&-0__[-I**-//**E'03@P0Q-*-..)9'<&=# # 3 3J ?'(:HEV<WX $*;;Y166q9:??$C  CJU $##s   LL<<Mc                8    | j                   j                          y rr   r   r^   s    r   r_   z*HypercornDummyProxyTestCase.teardown_class5  r   r@   Nrx   )rz   r{   r|   r   r   r   r   r   r   r   r   r   r   r   r   r   r_   r   r@   r   r   r      s    &1I#1*5M'5##""&&'2J$2+6N(6:GK7G$$##''(('2J$2+6N(6$$##**))&(I#((*K%*4411+) +)Z  r@   r   zIPv6 not available)reasonc                      e Zd ZdZy) IPv6HypercornDummyServerTestCase::1N)rz   r{   r|   r5   r   r@   r   r   r   :  s    Dr@   r   c                  (    e Zd ZdZdZdZdZeZdZ	dZ
y)IPv6HypercornDummyProxyTestCaser#   r   r   N)rz   r{   r|   r   r   r   r   r   r   r   r   r   r@   r   r   r   ?  s%    IMJ NKJ Nr@   r   c                  r    e Zd ZdZdZeej                  	 	 	 	 dd              Zedd	d       Z	ed
d       Z
y)ConnectionMarkerz
    Marks an HTTP(S)Connection's socket after a request was made.

    Helps a test server understand when a client finished a request,
    without implementing a complete HTTP server.
    s   $#MARK%04x*!c              #      K   t         j                  }	 	 	 	 d fd}|j                         5 }|j                  t         d ||             d ddd       y# 1 sw Y   yxY ww)z9
        Mark connections under in that context.
        c                (     	 	 	 	 	 	 	 	 d fd}|S )Nc                     | g|i | | j                   j                  j                  | j                   d             y )NF)r   sendall_get_socket_mark)ra   argskwargsr>   targets      r   partz:ConnectionMarker.mark.<locals>.call_and_mark.<locals>.partd  s:     t-d-f-		!!#"6"6tyy%"HIr@   )ra   r   r   
typing.Anyr   r   rP   rQ   r   )r   r   r>   s   ` r   call_and_markz,ConnectionMarker.mark.<locals>.call_and_marka  s4    J$J-7JCMJJ Kr@   requestN)r   typing.Callable[..., None]rP   r   )r   r   contextsetattr)r>   monkeypatchorig_requestr   ms   `    r   markzConnectionMarker.markV  s\      &--		.		'		   "aIIni|1LM #""s   +A%"A	A%A"A%c                    t               }| j                  |d      }	 |j                  |      }|s	 |S ||z  }|j                  |      r	 |S 0)zH
        Consume a socket until after the HTTP request is sent.
        T)r   r   r   r   )r>   r   r   r   r   r   s         r   consume_requestz ConnectionMarker.consume_requestp  sa    
 ;##D$/		&!A  MH  & r@   c                t    |r|j                         d   }n|j                         d   }| j                  |fz  S )Nru   )getpeernamegetsocknameMARK_FORMAT)r>   r   serverr&   s       r   r   z!ConnectionMarker._get_socket_mark  s<    ##%a(D##%a(D$((r@   N)r   zpytest.MonkeyPatchrP   z"typing.Generator[None, None, None])   )r   rO   r   rv   rP   r   )r   rO   r   boolrP   r   )rz   r{   r|   r}   r   r   r   contextmanagerr   r   r   r   r@   r   r   r   L  sf     "K,	+  0   ) )r@   r   )r   N)r   zSSLTransport | socket.socketr   rv   r   rt   rP   r   )&
__future__r   r   r   sslr8   r   testr   r   pytestdummyserver.appr   dummyserver.asgi_proxyr   dummyserver.hypercornserverr   dummyserver.socketserverr   r	   r
   urllib3.connectionr   urllib3.util.ssltransportr   urllib3.util.urlr   r   r!   r   r   r   r   r   skipifr   r   r   r   r@   r   <module>r      s   "   
      ) + ? P P - 2 &
 )-
& ' 	*A2 A2H*$= *, <(D L L^ L)=>'C  ? L)=>	!&A 	! ?	!:) :)r@   