
    Dfk9                     *   d Z ddlZddlZddlZddlZddlmZ dZdZ	dZ
dZdZd	Z G d
 dej                  Zd<dZej        d             Zej        d             Zej        d             Zej        d             Zd Zd Zd Zej                            ddd dj         eej        j        d           f          d             Zd Z d Z!ej                            dd          d             Z"d Z#d  Z$d! Z%d" Z&d# Z'ej        (                    d$d%&          d'             Z)ej                            d(d)ed*fd+ed,fd-ed.fd/ed0ff          d1             Z*d2 Z+d3 Z,d4 Z-d5 Z. G d6 d7          Z/ G d8 d9          Z0ej        d:             Z1d; Z2dS )=z9Tests for managing HTTP issues (malformed requests, etc).    N)helperi  i  i  i     i  c                   x    e Zd ZdZd Zd Zd Zd Zd Zdeded	ed
e ed          e ed          ededeiZ	dS )HelloControllerz!Controller for serving WSGI apps.c                     dS )zRender Hello world.Hello world! reqresps     E/var/www/media/lib/python3.11/site-packages/cheroot/test/test_core.pyhellozHelloController.hello   s    ~    c                 N    | j                             dd          	d|_        dS dS )zRender Hello world or set 411.Content-LengthNz411 Length Requiredr   )environgetstatusr
   s     r   body_requiredzHelloController.body_required   s*    ;??+T22:/DKF~r   c                 8    | j                             dd          S )zRender QUERY_STRING value.QUERY_STRING )r   r   r
   s     r   query_stringzHelloController.query_string"   s    {~r222r   c                 n    | j                             dd          }d} |j        di t                      S )zRender request method value.REQUEST_METHODzNO METHOD FOUNDz*Got asterisk URI path with {method} methodr	   )r   r   formatlocals)r   r   methodtmpls       r   asteriskzHelloController.asterisk&   s<     !13DEE;t{&&VXX&&&r   c                 R    |                      d                              d          S )zEncode PATH_INFO correctly depending on Python version.

        WSGI 1.0 is a mess around unicode. Create endpoints
        that match the PATH_INFO that it produces.
        utf-8latin-1)encodedecode)strings    r   _mungezHelloController._munge-   s$     }}W%%,,Y777r   /hello/no_body/body_requiredz/query_stringu   /привітu   /Юххууу   / Ðblah key 0 900 4 dataz/*N)
__name__
__module____qualname____doc__r   r   r   r    r'   handlersr	   r   r   r   r      s        ++    3 3 3' ' '8 8 8 	%E- 	&hHHHr   r   GETc                 :    |                      | j        |          S )Nr   )response_classsock)
connectionr   s     r   _get_http_responser7   G   s    $$Z_V$DDDr   c                 V    | j         }t                      |_        d|_        | |_        |S :Attach a WSGI app to the given server and preconfigure it.i)server_instancer   wsgi_appmax_request_body_sizeserver_clientwsgi_server_clientwsgi_servers     r   testing_serverrB   K   0     %4K*,,K(0K% 2Kr   c                     | j         S z5Get and return a test client out of the given server.r>   )rB   s    r   test_clientrG   U   s     ''r   c                 H    | j         }t                      |_        | |_        |S )r:   )r;   r   r<   r>   r?   s     r   testing_server_with_defaultsrI   [   s(     %4K*,,K 2Kr   c                     | j         S rE   rF   )rI   s    r   test_client_with_defaultsrK   d   s     (55r   c                 z    |                      d          d         }t          |dd                   }|dk    sJ dS )z>Check that CONNECT query results in Method Not Allowed status.z	/anythingr   N   i  )connectint)rG   status_lineactual_statuss      r   test_http_connect_requestrR   j   sF    %%k2215KBQB((MCr   c                     |                      d          \  }}}t          |dd                   }|t          k    sJ |dk    sJ dS )z%Check that normal GET query succeeds.r(   NrM      Hello world!r   rO   HTTP_OKrG   rP   _actual_resp_bodyrQ   s        r   test_normal_requestrZ   q   sX    '2x'@'@$K$BQB((MG####......r   c                     |                      d          \  }}}t          |dd                   }|t          k    sJ |dk    sJ dS )z$Check that GET param is parsed well./query_string?test=TrueNrM   s	   test=TruerU   rW   s        r   test_query_string_requestr]   y   s_    '2!( ($K$ BQB((MG####|++++++r   urir(   r\   z/{0}?{1}={2})u   Юххуууu   їu   йоc                     |                      |          d         }t          |dd                   }|t          k    sJ dS )z8Check that server responds with OK to valid GET queries.r   NrM   rU   )rG   r^   rP   rQ   s       r   test_parse_acceptable_urir`      sF     //#&&q)KBQB((MG######r   c                    |                                  }d                    d          }t          j                            |          }|dk    sJ  dj        di t                      }|                    |                    d                     |                                 t          |d          }|
                                 |j        t          k    sJ |                    d          d	k    sJ |                                 d
S )a#  Test that malicious URI does not allow HTTP injection.

    This effectively checks that sending GET request with URL

    /%A0%D0blah%20key%200%20900%204%20data

    is not converted into

    GET /
    blah key 0 900 4 data
    HTTP/1.1

    which would be a security issue otherwise.
    r+   r#   z&/%A0%D0blah%20key%200%20900%204%20datazGET {quoted} HTTP/1.1r"   r1   r3      rT   Nr	   )get_connectionr$   urllibparsequoter   r   _output_send_outputr7   beginr   rV   readclose)rG   cresourcequotedrequestresponses         r   test_parse_uri_unsafe_urirq      s     	""$$A-44Y??H\))F=====,%,88vxx88GIIgnnW%%&&&NN!!E222HNN?g%%%%==////GGIIIIIr   c                 r   |                                  }|                    d                    d                     |                                 t	          |d          }|                                 |j        t          k    sJ |                    d          dk    sJ |	                                 dS )zCheck that server responds with Bad Request to invalid GET queries.

    Invalid request line test case: it should only contain US-ASCII.
    u   GET /йопта! HTTP/1.1r"   r1   r3      s   Malformed Request-URIN)
rc   rg   r$   rh   r7   ri   r   HTTP_BAD_REQUESTrj   rk   )rG   rl   rp   s      r   test_parse_uri_invalid_uriru      s    
 	""$$AII*11'::;;;NN!!E222HNN?.....== 88888GGIIIIIr   )r   u   привітc                     |                      t          j                            |                    \  }}}t	          |dd                   }|t
          k    sJ d|v sJ dS )zCheck that server responds with Bad Request to invalid GET queries.

    Invalid request line test case: it should have leading slash (be absolute).
    NrM   s   starting with a slash)r   rd   re   rf   rO   rt   )rG   r^   rP   rX   rY   rQ   s         r   #test_parse_no_leading_slash_invalidrw      ss     (33( ($K$ BQB((M,,,,,#'7777777r   c                     |                      d          \  }}}t          |dd                   }|t          k    sJ d}||k    sJ dS )zlCheck that server responds with Bad Request to Absolute URI.

    Only proxy servers should allow this.
    zhttp://google.com/NrM   s2   Absolute URI not allowed if server is not a proxy.r   rO   rt   rG   rP   rX   rY   rQ   expected_bodys         r   test_parse_uri_absolute_urir|      sa    
 (37K'L'L$K$BQB((M,,,,,IM},,,,,,r   c                     |                      d          \  }}}t          |dd                   }|t          k    sJ d}||k    sJ dS )zDCheck that server responds with OK to OPTIONS with "*" Absolute URI.*NrM   s)   Got asterisk URI path with OPTIONS method)optionsrO   rV   rz   s         r   test_parse_uri_asterisk_urir      s_    '2':':3'?'?$K$BQB((MG####@M},,,,,,r   c                     |                      d          \  }}}t          |dd                   }|t          k    sJ d}||k    sJ dS )zACheck that server responds with Bad Request to URI with fragment.z/hello?test=something#fakeNrM   s!   Illegal #fragment in Request-URI.ry   rz   s         r   test_parse_uri_fragment_urir      se    '2$( ($K$ BQB((M,,,,,8M},,,,,,r   c                 
   |                                  }|                    dd           |                                }|                                }|j        }|t
          k    sJ |dk    sJ |                                 dS )z4Test POST query with an empty body being successful.POSTr)   rT   N)rc   ro   getresponserj   r   rV   rk   )rG   rl   rp   rY   rQ   s        r   test_no_content_lengthr      s~     	""$$AIIfj!!!}}H}}OMG####....GGIIIIIr   c                     |                                  }|                    dd           |                                }|                                 |j        }|t
          k    sJ |                                 dS )zDTest POST query with body failing because of missing Content-Length.r   r*   N)rc   ro   r   rj   r   HTTP_LENGTH_REQUIREDrk   )rG   rl   rp   rQ   s       r   test_content_length_requiredr     sn     	""$$AIIf&'''}}HMMOOOOM00000GGIIIIIr   z.https://github.com/cherrypy/cheroot/issues/106F)reasonstrictc                    |                                  }|                    dd           |                    dt          d                     |                                 |                                }|j        }|t          k    sJ dS )z5Test GET query with maliciously large Content-Length.r1   r(   r   l            N)rc   
putrequest	putheaderstr
endheadersr   r   HTTP_REQUEST_ENTITY_TOO_LARGE)rK   rl   rp   rQ   s       r   test_large_requestr     s}     	"0022ALL!!!KK #e**---LLNNN}}HOM9999999r   )request_linestatus_coder{   s   GET /   Malformed Request-Lines   GET / HTTPS/1.1s$   Malformed Request-Line: bad protocols   GET / HTTP/1s#   Malformed Request-Line: bad versions   GET / HTTP/2.15s   Cannot fulfill requestc                 \   |                                  }|                    |           |                                 t          |d          }|                                 |j        |k    sJ |                    t          |                    |k    sJ |                                 dS )z5Test missing or invalid HTTP version in Request-Line.r1   r3   N)	rc   rg   rh   r7   ri   r   rj   lenrk   )rG   r   r   r{   rl   rp   s         r   test_malformed_request_liner   -  s    4 	""$$AIIlNN!!E222HNN?k))))==]++,,====GGIIIIIr   c                 `   |                                  }|                    dd           |                    dd           |                                 |                                }|j        }|t          k    sJ |                    d          }|dk    sJ |                                 dS )zTest non-uppercase HTTP method.GeTz/malformed_method_caseContent-Type
text/plainrs   s   Malformed method nameN)	rc   r   r   r   r   r   rt   rj   rk   rG   rl   rp   rQ   rY   s        r   test_malformed_http_methodr   Q  s    ""$$ALL0111KK---LLNNN}}HOM,,,,,}}R((77777GGIIIIIr   c                    |                                  }|                    dd           |                    dd           |                    d           |                                 |                                }|j        }|t          k    sJ |                    d          }|dk    sJ |	                                 dS )	z5Check that broken HTTP header results in Bad Request.r1   /r   r   s   Re, 1.2.3.4#015#012   s   Illegal header line.N)
rc   r   r   rg   r   r   r   rt   rj   rk   r   s        r   test_malformed_headerr   a  s    ""$$ALLKK---II$%%%LLNNN}}HOM,,,,,}}R((66666GGIIIIIr   c                     d}t          d|z            dk    sJ |                     |          d         }|dk    sJ dS )z?Check that HTTP request line of exactly 256 chars length is OK.z/hello?intervenant-entreprise-evenement_classaction=evenement-mailremerciements&_path=intervenant-entreprise-evenement&intervenant-entreprise-evenement_action-id=19404&intervenant-entreprise-evenement_id=19404&intervenant-entreprise_id=28092zGET %s HTTP/1.1
      rT   N)r   r   )rG   Request_URIrY   s      r   "test_request_line_split_issue_1220r   s  s[    	+  ${233s::::"{33A6......r   c                    |                                  }|                    d           |                                 |                    |j        d          }	 |                                 |j        }|t          k    sJ |                    d          }|dk    sJ |	                                 dS # t          j        $ r!}|j        t          j        k    r Y d}~dS d}~ww xY w)z>Test that server sends an error for garbage received over TCP.s   gjkgjklsgjklsgjkljklsgr1   r3      r   N)rc   rg   rh   r4   r5   ri   r   rt   rj   rk   socketerrorerrno
ECONNRESET)rG   rl   rp   rQ   rY   exs         r   test_garbage_inr     s     	""$$AII'(((NNu55H
  00000#==,,#<<<<<						<   8u''' ('''''s   AB6 6C&C!!C&c                       e Zd ZdZd Zd ZdS )CloseControllerz*Controller for testing the close callback.c                     |j         j        | _        t          | j                  } ||j        |j                                                   |S )z'Get the req to know header sent status.)__self__r   CloseResponserk   r   headersitems)selfr   start_responser   s       r   __call__zCloseController.__call__  sE    !*.TZ((t{DL$6$6$8$8999r   c                 :    | j                             d           dS )zClose, writing hello.   helloN)r   writer   s    r   rk   zCloseController.close  s    x     r   N)r,   r-   r.   r/   r   rk   r	   r   r   r   r     s8        44  ! ! ! ! !r   r   c                   $    e Zd ZdZd Zd Zd ZdS )r   z3Dummy empty response to trigger the no body status.c                 4    d| _         ddi| _        || _        dS )z-Use some defaults to ensure we have a header.z200 OKr   z	text/htmlN)r   r   rk   )r   rk   s     r   __init__zCloseResponse.__init__  s     &4


r   c                     t                      )zEnsure we don't have a body.)
IndexError)r   indexs     r   __getitem__zCloseResponse.__getitem__  s    llr   c                     | S )z%Return self to hook the close method.r	   r   s    r   outputzCloseResponse.output  s    r   N)r,   r-   r.   r/   r   r   r   r	   r   r   r   r     sG        ==        r   r   c                 V    | j         }t                      |_        d|_        | |_        |S r9   )r;   r   r<   r=   r>   r?   s     r   testing_server_closer     rC   r   c                 R    | j                             d          \  }}}|dk    sJ dS )z@Test we are actually sending the headers before calling 'close'.r   r   N)r>   r   )r   rX   	resp_bodys      r   test_send_header_before_closingr     s5    *8<<SAAOAq)      r   )r1   )3r/   r   r   urllib.parserd   pytestcheroot.testr   rt   r   HTTP_NOT_FOUNDr   rV   HTTP_VERSION_NOT_SUPPORTED
Controllerr   r7   fixturerB   rG   rI   rK   rR   rZ   r]   markparametrizer   mapre   rf   r`   rq   ru   rw   r|   r   r   r   r   xfailr   r   r   r   r   r   r   r   r   r   r	   r   r   <module>r      s   ? ?                 # 
  0 0 0 0 0f' 0 0 0fE E E E    ( ( (
    6 6 6
     / / /, , , 	!S#%CDD	
	 	$ $	 	$  :   	 
8 
8 
8	- 	- 	-- - -- - -  $  " ;   : :	 :$ 4 7	

 E	

 D	

 &(A	
 * + *     $/ / /"  *! ! ! ! ! ! ! !       $   ! ! ! ! !r   