o
    îó·i(@  ã                   @   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_startedZprotocol_connectedÚ	ExceptionÚloggerÚerrorÚ	tracebackÚ
format_exc)ÚselfÚargsÚkwargs© r!   úZC:\Users\psant\Downloads\PAF backend\school\venv\Lib\site-packages\daphne/http_protocol.pyr   4   s   þzWebRequest.__init__c                 c   s(  � �zøt   ¡ | _| 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| ¡ | j3j4 5¡  W d S g | _6| jj7| _7| j ¡ D ]-\}}d|v �rd�qY|D ]}	| ¡ dk�ryt8|	 d
¡ƒ| _7�qf| j6 9| ¡ |	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?�rÕW d S | jj@}
	 | j. /|
¡}tA|ƒ|
k  }d ||d!œ}| j> B|¡ |�sùW d S �qÚ tC�y   t# DtE F¡ ¡ |  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)r/   ÚbodyÚ	more_bodyó   Internal Server ErrorzDaphne HTTP processing error)GÚtimeÚrequest_startZrequestHeadersZgetAllRawHeadersr
   Ú	fullmatchÚbasic_errorÚ	hasHeaderZgetRawHeadersÚhasattrr8   Ústrr#   r$   r   r   ZisSecureZclient_schemer   Zproxy_forwarded_address_headerr   Zproxy_forwarded_port_headerZproxy_forwarded_proto_headerr2   ÚdecodeÚUnicodeDecodeErrorr6   ÚuriÚsplitÚlowerZ
ws_factoryÚbuildProtocolÚ	transportZgetPeerÚsetResponseCoder   ÚwarnÚfinishZ_raw_query_stringÚ
isinstancer   ZwrappedProtocolÚprotocolZmakeConnectionr1   ÚjoinÚcontentÚreadZdataReceivedÚdebugÚprotocol_disconnectedr   Z_networkProducerZresumeProducingZclean_headersr4   r   ÚappendÚseekr   Zcreate_applicationZclientprotor   ÚclosedZrequest_buffer_sizeÚlenÚ
put_nowaitr   r   r   r   )r   ÚnameÚ_Zupgrade_headerrN   rI   Ú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   rR   r   r   r   ÚconnectionLostr   rS   )r   Úreasonr!   r!   r"   re   Õ   s
   zWebRequest.connectionLostc                 C   s8   | j r|  ¡  t d| j¡ tj | ¡ | j 	| ¡ dS )rc   zHTTP close for %sN)
r   rd   r   rR   r   r   r   rL   r   rS   ©r   r!   r!   r"   rL   ß   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rÀd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
        Nr/   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.r7   r   s   serverzHTTP %s response started for %súhttp.response.bodyz1HTTP response has not yet been started but got %sr9   r(   r:   FzHTTP response complete for %sr&   r   ZcompleteÚreplacez%s:%s)r2   ri   r1   r8   Z
time_takenÚsizezHTTP response chunk for %szCannot handle message type %s!)"Úfinishedr   Ú
ValueErrorr   rJ   ÚgetZresponseHeadersZaddRawHeaderr   Zserver_namer@   Z	setHeaderÚencoder   rR   r   r   r   ÚwriterL   rE   rC   rD   ÚreprZ
log_actionÚcoder1   ÚtupleÚdurationZ
sentLengthr   r   r   r   )r   ÚmessageÚheaderr^   rE   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)r?   )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   Zhttp_timeoutru   r   r   ÚwarningrL   r?   rg   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.
        r/   zhttp.disconnectN)r2   r   rX   rg   r!   r!   r"   rd   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   N)rA   r<   r=   rg   r!   r!   r"   ru   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)
        rh   )s   Content-Types   text/html; charset=utf-8)r/   ri   r7   rj   r   r&   )Útitler9   Úutf8)r/   r9   N)rx   Úerror_templaterB   rC   rp   )r   ri   Zstatus_textr9   r!   r!   r"   r?   Z  s    ýÿþÿøÿzWebRequest.basic_errorc                 C   s   t t| ƒƒS ©N)ÚhashÚidrg   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__rk   r   r   r   rb   re   rL   rx   rz   r|   rd   ru   r?   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: %sN)
r   rŠ   rH   r   ZrequestFactoryr   r   r   r   r   )r   ÚaddrrN   r!   r!   r"   rH   †  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   h2N)r   Z
H2_ENABLEDÚinsert)r   ZbaseProtocolsr!   r!   r"   ÚacceptableProtocols”  s   zHTTPFactory.acceptableProtocolsN)r†   r‡   rˆ   r‰   r   rH   r�   r!   r!   r!   r"   rŠ   y  s
    rŠ   )Úloggingr<   r   Úurllib.parser   Ztwisted.internet.deferr   r   Ztwisted.internet.interfacesr   Ztwisted.protocols.policiesr   Ztwisted.webr   Zzope.interfacer   Úutilsr
   r   Ú	getLoggerr†   r   r   r   rŠ   r!   r!   r!   r"   Ú<module>   s     
  j