
    g	?                     x   d Z ddlZddlZddlmZ ddlmZ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mZmZmZmZmZmZmZmZ ej4                  rddlmZ  G d deee	j8                        Z G d de	j<                        Z G d de       Z! G d de	j<                        Z"e	jF                  Z$y)a  A non-blocking, single-threaded HTTP server.

Typical applications have little direct interaction with the `HTTPServer`
class except to start a server at the beginning of the process
(and even that is often done indirectly via `tornado.web.Application.listen`).

.. versionchanged:: 4.0

   The ``HTTPRequest`` class that used to live in this module has been moved
   to `tornado.httputil.HTTPServerRequest`.  The old name remains as an alias.
    N)
native_str)HTTP1ServerConnectionHTTP1ConnectionParameters)httputil)iostream)netutil)	TCPServer)Configurable)	UnionAnyDictCallableListTypeTupleOptional	Awaitable)Setc                      e Zd ZdZdededdfdZ	 	 	 	 	 	 	 	 	 	 	 	 ddeej                  e	ej                  gdf   f   ded	ed
eeeeef   ej                   f      dee   dedee   dee   dee   dee   dee   dee   deee      ddfdZedee   fd       Zedee   fd       Zd dZdej8                  deddfdZdedej@                  dejB                  fdZ"deddfdZ#y)!
HTTPServera  A non-blocking, single-threaded HTTP server.

    A server is defined by a subclass of `.HTTPServerConnectionDelegate`,
    or, for backwards compatibility, a callback that takes an
    `.HTTPServerRequest` as an argument. The delegate is usually a
    `tornado.web.Application`.

    `HTTPServer` supports keep-alive connections by default
    (automatically for HTTP/1.1, or for HTTP/1.0 when the client
    requests ``Connection: keep-alive``).

    If ``xheaders`` is ``True``, we support the
    ``X-Real-Ip``/``X-Forwarded-For`` and
    ``X-Scheme``/``X-Forwarded-Proto`` headers, which override the
    remote IP and URI scheme/protocol for all requests.  These headers
    are useful when running Tornado behind a reverse proxy or load
    balancer.  The ``protocol`` argument can also be set to ``https``
    if Tornado is run behind an SSL-decoding proxy that does not set one of
    the supported ``xheaders``.

    By default, when parsing the ``X-Forwarded-For`` header, Tornado will
    select the last (i.e., the closest) address on the list of hosts as the
    remote host IP address.  To select the next server in the chain, a list of
    trusted downstream hosts may be passed as the ``trusted_downstream``
    argument.  These hosts will be skipped when parsing the ``X-Forwarded-For``
    header.

    To make this server serve SSL traffic, send the ``ssl_options`` keyword
    argument with an `ssl.SSLContext` object. For compatibility with older
    versions of Python ``ssl_options`` may also be a dictionary of keyword
    arguments for the `ssl.SSLContext.wrap_socket` method.::

       ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
       ssl_ctx.load_cert_chain(os.path.join(data_dir, "mydomain.crt"),
                               os.path.join(data_dir, "mydomain.key"))
       HTTPServer(application, ssl_options=ssl_ctx)

    `HTTPServer` initialization follows one of three patterns (the
    initialization methods are defined on `tornado.tcpserver.TCPServer`):

    1. `~tornado.tcpserver.TCPServer.listen`: single-process::

            async def main():
                server = HTTPServer()
                server.listen(8888)
                await asyncio.Event.wait()

            asyncio.run(main())

       In many cases, `tornado.web.Application.listen` can be used to avoid
       the need to explicitly create the `HTTPServer`.

       While this example does not create multiple processes on its own, when
       the ``reuse_port=True`` argument is passed to ``listen()`` you can run
       the program multiple times to create a multi-process service.

    2. `~tornado.tcpserver.TCPServer.add_sockets`: multi-process::

            sockets = bind_sockets(8888)
            tornado.process.fork_processes(0)
            async def post_fork_main():
                server = HTTPServer()
                server.add_sockets(sockets)
                await asyncio.Event().wait()
            asyncio.run(post_fork_main())

       The ``add_sockets`` interface is more complicated, but it can be used with
       `tornado.process.fork_processes` to run a multi-process service with all
       worker processes forked from a single parent.  ``add_sockets`` can also be
       used in single-process servers if you want to create your listening
       sockets in some way other than `~tornado.netutil.bind_sockets`.

       Note that when using this pattern, nothing that touches the event loop
       can be run before ``fork_processes``.

    3. `~tornado.tcpserver.TCPServer.bind`/`~tornado.tcpserver.TCPServer.start`:
       simple **deprecated** multi-process::

            server = HTTPServer()
            server.bind(8888)
            server.start(0)  # Forks multiple sub-processes
            IOLoop.current().start()

       This pattern is deprecated because it requires interfaces in the
       `asyncio` module that have been deprecated since Python 3.10. Support for
       creating multiple processes in the ``start`` method will be removed in a
       future version of Tornado.

    .. versionchanged:: 4.0
       Added ``decompress_request``, ``chunk_size``, ``max_header_size``,
       ``idle_connection_timeout``, ``body_timeout``, ``max_body_size``
       arguments.  Added support for `.HTTPServerConnectionDelegate`
       instances as ``request_callback``.

    .. versionchanged:: 4.1
       `.HTTPServerConnectionDelegate.start_request` is now called with
       two arguments ``(server_conn, request_conn)`` (in accordance with the
       documentation) instead of one ``(request_conn)``.

    .. versionchanged:: 4.2
       `HTTPServer` is now a subclass of `tornado.util.Configurable`.

    .. versionchanged:: 4.5
       Added the ``trusted_downstream`` argument.

    .. versionchanged:: 5.0
       The ``io_loop`` argument has been removed.
    argskwargsreturnNc                      y N )selfr   r   s      G/var/www/openai/venv/lib/python3.12/site-packages/tornado/httpserver.py__init__zHTTPServer.__init__   s     	    request_callbackno_keep_alivexheadersssl_optionsprotocoldecompress_request
chunk_sizemax_header_sizeidle_connection_timeoutbody_timeoutmax_body_sizemax_buffer_sizetrusted_downstreamc           	          || _         || _        || _        t        ||||	xs d||
|      | _        t        j                  | |||       t               | _        || _	        y )Ni  )
decompressr'   r(   header_timeoutr+   r*   r"   )r$   r,   read_chunk_size)
r!   r#   r%   r   conn_paramsr	   r   set_connectionsr-   )r   r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   s                 r   
initializezHTTPServer.initialize   sq    . !1  4)!+2:d'%'
 	#+&		
  E"4r    c                     t         S r   r   clss    r   configurable_basezHTTPServer.configurable_base       r    c                     t         S r   r7   r8   s    r   configurable_defaultzHTTPServer.configurable_default   r;   r    c                    K   | j                   rDt        t        | j                               }|j                          d{    | j                   rCyy7 w)a&  Close all open connections and asynchronously wait for them to finish.

        This method is used in combination with `~.TCPServer.stop` to
        support clean shutdowns (especially for unittests). Typical
        usage would call ``stop()`` first to stop accepting new
        connections, then ``await close_all_connections()`` to wait for
        existing connections to finish.

        This method does not currently close open websocket connections.

        Note that this method is a coroutine and must be called with ``await``.

        N)r4   nextiterclose)r   conns     r   close_all_connectionsz HTTPServer.close_all_connections   sE      T../0D**,  s   >A AAAstreamaddressc                     t        ||| j                  | j                        }t        || j                  |      }| j
                  j                  |       |j                  |        y r   )_HTTPRequestContextr%   r-   r   r2   r4   addstart_serving)r   rD   rE   contextrB   s        r   handle_streamzHTTPServer.handle_stream   sW    %GT]]D,C,C
 %VT-=-=wGd#4 r    server_connrequest_connc                     t        | j                  t        j                        r| j                  j	                  ||      }nt        | j                  |      }| j                  rt        ||      }|S r   )
isinstancer!   r   HTTPServerConnectionDelegatestart_request_CallableAdapterr#   _ProxyAdapter)r   rL   rM   delegates       r   rQ   zHTTPServer.start_request   s\     d++X-R-RS,,::;UH'(=(=|LH==$X|<Hr    c                 j    | j                   j                  t        j                  t        |             y r   )r4   removetypingcastr   )r   rL   s     r   on_closezHTTPServer.on_close   s"      -BK!PQr    )FFNNFNNNNNNNr   N)$__name__
__module____qualname____doc__r   r   r   r   rP   r   HTTPServerRequestboolr   r   strssl
SSLContextintfloatr   r5   classmethodr   r
   r:   r=   rC   r   IOStreamr   rK   objectHTTPConnectionHTTPMessageDelegaterQ   rY   r   r    r   r   r   .   s   kZc S T  $GK"&#($()-37(,'+)-26#*511h001478:
*5 *5 *5 eDcNCNN$BCD*5 3-*5 !*5 SM*5 "#*5 "*%*5 uo*5  }*5  "#!*5" %T#Y/#*5$ 
%*5X $|"4   T,%7  &!H$5$5 ! !$ !!191H1H		%	%RF Rt Rr    r   c                       e Zd Zdeej
                  gdf   dej                  ddfdZdeej                  ej                  f   dej                  deed      fdZd	edeed      fd
ZddZddZy)rR   r!   NrM   r   c                 J    || _         || _        d | _        d | _        g | _        y r   )
connectionr!   requestrT   _chunks)r   r!   rM   s      r   r   z_CallableAdapter.__init__  s(    
 ' 0r    
start_lineheadersc                     t        j                  | j                  t        j                  t         j
                  |      |      | _        y )N)rm   rp   rq   )r   r_   rm   rW   rX   RequestStartLinern   r   rp   rq   s      r   headers_receivedz!_CallableAdapter.headers_received  s9    
  11{{8#<#<jI

 r    chunkc                 :    | j                   j                  |       y r   )ro   appendr   rv   s     r   data_receivedz_CallableAdapter.data_received  s    E"r    c                     | j                   J dj                  | j                        | j                   _        | j                   j	                          | j                  | j                          y )Nr    )rn   joinro   body_parse_bodyr!   r   s    r   finishz_CallableAdapter.finish   sM    ||'''HHT\\2  "dll+r    c                     | ` y r   )ro   r   s    r   on_connection_closez$_CallableAdapter.on_connection_close&  s    Lr    rZ   )r[   r\   r]   r   r   r_   ri   r   r   rs   ResponseStartLineHTTPHeadersr   r   ru   bytesrz   r   r   r   r    r   rR   rR     s    	"H$>$>#?#EF	 --	 
		
(33X5O5OOP
 %%
 
)D/	"	
5 Xio-F ,r    rR   c                       e Zd Z	 ddej                  dedee   deee      ddf
dZ	defdZ
d	ej                  ddfd
ZddZy)rG   NrD   rE   r%   r-   r   c                    || _         |j                  |j                  j                  | _        nd | _        | j                  t        j                  t        j
                  fv r||d   | _        nd| _        |r|| _        n)t        |t        j                        rd| _        nd| _        | j                  | _        | j                  | _        t        |xs g       | _        y )Nr   z0.0.0.0httpshttp)rE   socketfamilyaddress_familyAF_INETAF_INET6	remote_ipr%   rO   r   SSLIOStream_orig_remote_ip_orig_protocolr3   r-   )r   rD   rE   r%   r-   s        r   r   z_HTTPRequestContext.__init__+  s      ==$"(--"6"6D"&D FNNFOO#DD#$QZDN 'DN$DM 4 45#DM"DM#~~"mm"%&8&>B"?r    c                     | j                   t        j                  t        j                  fv r| j                  S t        | j                  t              rt        | j                        S t        | j                        S r   )
r   r   r   r   r   rO   rE   r   r   ra   r   s    r   __str__z_HTTPRequestContext.__str__M  sU    6>>6??"CC>>!e, dll++t||$$r    rq   c                    |j                  d| j                        }d t        |j                  d            D        D ]  }|| j                  vs n |j                  d|      }t        j                  |      r|| _        |j                  d|j                  d| j                              }|r"|j                  d      d   j                         }|dv r|| _        y	y	)
z2Rewrite the ``remote_ip`` and ``protocol`` fields.zX-Forwarded-Forc              3   <   K   | ]  }|j                           y wr   )strip).0cands     r   	<genexpr>z6_HTTPRequestContext._apply_xheaders.<locals>.<genexpr>]  s     D,CD4::<,Cs   ,z	X-Real-IpzX-SchemezX-Forwarded-Proto)r   r   N)	getr   reversedsplitr-   r   is_valid_ipr%   r   )r   rq   ipproto_headers       r   _apply_xheadersz#_HTTPRequestContext._apply_xheadersX  s     [[*DNN;DHRXXc],CDB000 E [[b)r"DN{{$7G
  (--c226<<>L,,(DM -r    c                 H    | j                   | _        | j                  | _        y)zUndo changes from `_apply_xheaders`.

        Xheaders are per-request so they should not leak to the next
        request on the same connection.
        N)r   r   r   r%   r   s    r   _unapply_xheadersz%_HTTPRequestContext._unapply_xheadersn  s     --++r    r   rZ   )r[   r\   r]   r   rg   r   r   ra   r   r   r   r   r   r   r   r   r    r   rG   rG   *  s     37 @!! @  @ 3-	 @
 %T#Y/ @ 
 @D	% 	%)x';'; ) ),,r    rG   c                       e Zd Zdej                  dej
                  ddfdZdeej                  ej                  f   dej                  deed      fdZd	edeed      fd
ZddZddZddZy)rS   rT   rM   r   Nc                      || _         || _        y r   )rm   rT   )r   rT   rM   s      r   r   z_ProxyAdapter.__init__y  s    
 ' r    rp   rq   c                     | j                   j                  j                  |       | j                  j	                  ||      S r   )rm   rJ   r   rT   ru   rt   s      r   ru   z_ProxyAdapter.headers_received  s3     	//8}}--j'BBr    rv   c                 8    | j                   j                  |      S r   )rT   rz   ry   s     r   rz   z_ProxyAdapter.data_received  s    }}**511r    c                 X    | j                   j                          | j                          y r   )rT   r   _cleanupr   s    r   r   z_ProxyAdapter.finish  s    r    c                 X    | j                   j                          | j                          y r   )rT   r   r   r   s    r   r   z!_ProxyAdapter.on_connection_close  s    ))+r    c                 L    | j                   j                  j                          y r   )rm   rJ   r   r   s    r   r   z_ProxyAdapter._cleanup  s    113r    rZ   )r[   r\   r]   r   rj   ri   r   r   rs   r   r   r   r   ru   r   rz   r   r   r   r   r    r   rS   rS   x  s    !..! --! 
	!C(33X5O5OOPC %%C 
)D/	"	C25 2Xio-F 24r    rS   )%r^   r   rb   tornado.escaper   tornado.http1connectionr   r   tornador   r   r   tornado.tcpserverr	   tornado.utilr
   rW   r   r   r   r   r   r   r   r   r   TYPE_CHECKINGr   rP   r   rj   rR   rh   rG   rS   r_   HTTPRequestr   r    r   <module>r      s    
  
 % T    ' %  U U U	SRL(*O*O SRl#x33 #LK,& K,\4H00 4D ((r    