o
    >h(@                     @   s   d dl 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mZ e eZG d
d dejZee	G dd dejZdS )    N)unquote)inlineCallbacksmaybeDeferred)IProtocolNegotiationFactory)ProtocolWrapper)http)implementer   )HEADER_NAME_REparse_x_forwarded_forc                   @   s   e Zd ZdZdddddddddZd	d
 Zedd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd  Zd!S )"
WebRequestz
    Request that either hands off information to channels, or offloads
    to a WebSocket class.

    Does some extra processing over the normal Twisted Web request to separate
    GET and POST out.
    a  
        <html>
            <head>
                <title>%(title)s</title>
                <style>
                    body { font-family: sans-serif; margin: 0; padding: 0; }
                    h1 { padding: 0.6em 0 0.2em 20px; color: #896868; margin: 0; }
                    p { padding: 0 0 0.3em 20px; margin: 0; }
                    footer { padding: 1em 0 0.3em 20px; color: #999; font-size: 80%%; font-style: italic; }
                </style>
            </head>
            <body>
                <h1>%(title)s</h1>
                <p>%(body)s</p>
                <footer>Daphne</footer>
            </body>
        </html>
    
 z     z   z  c                 O   sp   d | _ d | _z"tjj| g|R i | | jjj| _d | _d| _	| j
|  W d S  ty7   tt   w )NF)client_addrserver_addrr   Request__init__channelfactoryserverapplication_queue_response_startedprotocol_connected	Exceptionloggererror	traceback
format_exc)selfargskwargs r"   t/var/www/vedio/testing/chatpythonscript.ninositsolution.com/env/lib/python3.10/site-packages/daphne/http_protocol.pyr   4   s   zWebRequest.__init__c                 c   s(   zt   | _| j D ]\}}t|s!| ddd  W d S qd }| jdr2| jdd }t	| j
drTt	| j
drTt| j
j| j
jg| _t| jj| jjg| _|  rZdnd	| _| jjrwt| j| jj| jj| jj| j| j\| _| _z| jd
 W n ty   d| _| ddd Y W d S w d| _d| jv r| jddd | _z| jd
 W n ty   | ddd Y W d S w |rL| dkrL| jj| j ! }|s| "d t#$d | %  | j|_&| j d }| _ t'|t(r||_)n||_*|+| | j,d | j d }| j D ]}||d d d-|d  d 7 }q|d7 }|| j./ 7 }|0| t#1d| j | j2|  | j3j45  W d S g | _6| jj7| _7| j D ]-\}}d|v rdqY|D ]}	| dkryt8|	d
| _7qf| j69| |	f qfqYt#1d| j,| j | j.:dd t;| jj<| d	| j=dd d
| j,d
t8| jd
| j| j7| j| j| j6| j| jdV | _>| j>d u s| j.j?rW d S | jj@}
	 | j./|
}tA||
k  }d ||d!}| j>B| |sW d S q tCy   t#DtEF  | dd"d# Y d S w )$Ni  s   Bad RequestzInvalid header names   Upgrader   hostporthttpsr   ascii   /zInvalid characters in path       ?r	   zInvalid query strings	   websocket  z!Could not make WebSocket protocol    s    HTTP/1.1
s   :    ,s   
z#Upgraded connection %s to WebSocket   _s   daphne-root-pathzHTTP %s request for %s)typehttp_versionmethodpathraw_path	root_pathschemequery_stringheadersclientr   Tzhttp.request)r0   body	more_body   Internal Server ErrorzDaphne HTTP processing error)Gtimerequest_startrequestHeadersgetAllRawHeadersr
   	fullmatchbasic_error	hasHeadergetRawHeadershasattrr9   strr$   r%   r   r   isSecureclient_schemer   proxy_forwarded_address_headerr   proxy_forwarded_port_headerproxy_forwarded_proto_headerr3   decodeUnicodeDecodeErrorr7   urisplitlower
ws_factorybuildProtocol	transportgetPeersetResponseCoder   warnfinish_raw_query_string
isinstancer   wrappedProtocolprotocolmakeConnectionr2   joincontentreaddataReceiveddebugprotocol_disconnectedr   _networkProducerresumeProducingclean_headersr5   r   appendseekr   create_applicationclientprotor   closedrequest_buffer_sizelen
put_nowaitr   r   r   r   )r   name_upgrade_headerr[   rS   datahvaluesvaluebuffer_sizechunkr;   payloadr"   r"   r#   processD   s   

	




&




zWebRequest.processc                 C   s:   | j r|   td| j tj| | | j	|  dS )3
        Cleans up reply channel on close.
        zHTTP disconnect for %sN)
r   send_disconnectr   ra   r   r   r   connectionLostr   rb   )r   reasonr"   r"   r#   r{      s
   zWebRequest.connectionLostc                 C   s8   | j r|   td| j tj|  | j	|  dS )ry   zHTTP close for %sN)
r   rz   r   ra   r   r   r   rW   r   rb   r   r"   r"   r#   rW      s
   zWebRequest.finishc                 C   s  | j s| jdu r
dS d|vrtd|d dkrc| jrtdd| _d|vr*td| |d  |d	i D ]\}}| j|| q7| jj	rW| j
d
sW| d| jj	  td|d | j dS |d dkr| jsttd|d  tj| |dd |dds|   td| j z| jd}W n ty   t| j}Y nw z%| jdd|| j| jdd| jrdt| j nd|  | jd W dS  ty   tt !  Y dS w td| j dS td|d  )z1
        Handles a reply from the client
        Nr0   zMessage has no type definedhttp.response.startz&HTTP response has already been startedTstatusz<Specifying a status code is required for a Response message.r8   r   s   serverzHTTP %s response started for %shttp.response.bodyz1HTTP response has not yet been started but got %sr:   r)   r;   FzHTTP response complete for %sr'   r   completereplacez%s:%s)r3   r   r2   r9   
time_takensizezHTTP response chunk for %szCannot handle message type %s!)"finishedr   
ValueErrorr   rU   getresponseHeadersaddRawHeaderr   server_namerC   	setHeaderencoder   ra   r   r   r   writerW   rN   rL   rM   repr
log_actioncoder2   tupleduration
sentLengthr   r   r   r   )r   messageheaderrt   rN   r"   r"   r#   handle_reply   sn   
zWebRequest.handle_replyc                 C   s   |  ddd dS )zF
        Called by the server when our application tracebacks
        r+   r<   zException inside application.N)rB   )r   	exceptionr"   r"   r#   handle_exception1  s   zWebRequest.handle_exceptionc                 C   sN   | j jr#|  | j jkr%| jrtd |   dS | ddd dS dS dS )zK
        Called periodically to see if we should timeout something
        z,Application timed out while sending responsei  s   Service Unavailablez0Application failed to respond within time limit.N)r   http_timeoutr   r   r   warningrW   rB   r}   r"   r"   r#   check_timeouts7  s   
zWebRequest.check_timeoutsc                 C   s   | j r| jddi dS dS )z_
        Sends a http.disconnect message.
        Useful only really for long-polling.
        r0   zhttp.disconnectN)r3   r   rm   r}   r"   r"   r#   rz   I  s   zWebRequest.send_disconnectc                 C   s   t | dsdS t | j S )zB
        Returns the time since the start of the request.
        r>   r   )rE   r=   r>   r}   r"   r"   r#   r   R  s   
zWebRequest.durationc                 C   sL   |  d|dgd |  d| jt|d |d |d dd	 d
S )zF
        Responds with a server-level error page (very basic)
        r~   )s   Content-Types   text/html; charset=utf-8)r0   r   r8   r   r   r'   )titler:   utf8)r0   r:   N)r   error_templaterF   rL   r   )r   r   status_textr:   r"   r"   r#   rB   Z  s    zWebRequest.basic_errorc                 C   s   t t| S N)hashidr}   r"   r"   r#   __hash__r  s   zWebRequest.__hash__c                 C   s   t | t |kS r   )r   )r   otherr"   r"   r#   __eq__u  s   zWebRequest.__eq__N)__name__
__module____qualname____doc__r   r   r   r   rx   r{   rW   r   r   r   rz   r   rB   r   r   r"   r"   r"   r#   r      s0    	
 
F	r   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	HTTPFactoryz
    Factory which takes care of tracking which protocol
    instances or request instances are responsible for which
    named response channels, so incoming messages can be
    routed appropriately.
    c                 C   s   t j|  || _d S r   )r   r   r   r   )r   r   r"   r"   r#   r     s   
zHTTPFactory.__init__c                 C   s>   zt j| |}t|_|W S  ty   tdt	    w )z
        Builds protocol instances. This override is used to ensure we use our
        own Request object instead of the default.
        zCannot build protocol: %s)
r   r   rR   r   requestFactoryr   r   r   r   r   )r   addrr[   r"   r"   r#   rR     s   zHTTPFactory.buildProtocolc                 C   s   dg}t jr|dd |S )a)  
        Protocols this server can speak after ALPN negotiation. Currently that
        is HTTP/1.1 and optionally HTTP/2. Websockets cannot be negotiated
        using ALPN, so that doesn't go here: anyone wanting websockets will
        negotiate HTTP/1.1 and then do the upgrade dance.
        s   http/1.1r   s   h2)r   
H2_ENABLEDinsert)r   baseProtocolsr"   r"   r#   acceptableProtocols  s   zHTTPFactory.acceptableProtocolsN)r   r   r   r   r   rR   r   r"   r"   r"   r#   r   y  s
    r   )loggingr=   r   urllib.parser   twisted.internet.deferr   r   twisted.internet.interfacesr   twisted.protocols.policiesr   twisted.webr   zope.interfacer   utilsr
   r   	getLoggerr   r   r   r   r   r"   r"   r"   r#   <module>   s     
  j