o
    LDi)                     @   sf  d dl Z d dlZd dlmZmZ d dl mZ d dlmZmZ d dl	m
Z
mZmZ d dlmZmZmZm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! e
rjd dl"m#Z# dedededdfddZ$de!dej%de&e'e(f fddZ)de!deej%egee f fddZ*G dd deZ+G dd de+Z,G dd  d e+Z-dS )!    N)ABCabstractmethod)	Transport)	AwaitableCallable)TYPE_CHECKINGAnycast)JsonPayloadMultipartWriterPayloadweb)Handler)Application)
middleware)Bot
Dispatcherloggers)TelegramMethod)TelegramType)IPFilter)	InputFileapp
dispatcherkwargsreturnc                   sh   |  d j |dtdtddf fdd}dtdtddf fdd	}| j| | j| dS )
z
    This function helps to configure a startup-shutdown process

    :param app: aiohttp application
    :param dispatcher: aiogram dispatcher
    :param kwargs: additional data
    :return:
    )r   r   akwr   Nc                         j di I d H  d S N )emit_startupr   r   r   workflow_datar    j/var/www/www-root/data/www/77.83.87.30/venv/lib/python3.10/site-packages/aiogram/webhook/aiohttp_server.py
on_startup&      z%setup_application.<locals>.on_startupc                     r   r   )emit_shutdownr"   r#   r    r%   on_shutdown)   r'   z&setup_application.<locals>.on_shutdown)r$   r   r&   appendr)   )r   r   r   r&   r)   r    r#   r%   setup_application   s   
r+   	ip_filterrequestc                 C   s^   |j dd }r|jddd^}}||| v fS tt|jd }r-|\}}||| v fS dS )NzX-Forwarded-For ,   )maxsplitpeername)r.   F)headersgetsplitr	   r   	transportget_extra_info)r,   r-   forwarded_for_	peer_namehostr    r    r%   check_ip0   s   r<   c                    s$   t dtjdtdtf fdd}|S )z)

    :param ip_filter:
    :return:
    r-   handlerr   c                    s:   t  | d\}}|stjd| t || I d H S )N)r,   r-   z,Blocking request from an unauthorized IP: %s)r<   r   webhookwarningr   HTTPUnauthorized)r-   r=   
ip_addressacceptr,   r    r%   _ip_filter_middlewareK   s   z3ip_filter_middleware.<locals>._ip_filter_middleware)r   r   Requestr   r   )r,   rD   r    rC   r%   ip_filter_middlewareB   s   	rF   c                	   @   s$  e Zd Z	d'dedededdfddZd	ed
ededdfddZ	dededdfddZ
ed(ddZedejdefddZedededefddZdedeeef ddfddZdedejdejfddZded ee dB defd!d"Zdedejdejfd#d$Zdejdejfd%d&ZeZdS ))BaseRequestHandlerFr   handle_in_backgrounddatar   Nc                 K   s   || _ || _|| _t | _dS )aZ  
        Base handler that helps to handle incoming request from aiohttp
        and propagate it to the Dispatcher

        :param dispatcher: instance of :class:`aiogram.dispatcher.dispatcher.Dispatcher`
        :param handle_in_background: immediately responds to the Telegram instead of
            a waiting end of a handler process
        N)r   rH   rI   set_background_feed_update_tasks)selfr   rH   rI   r    r    r%   __init__W   s   zBaseRequestHandler.__init__pathr   r   c                K   s,   |j | j |jjd|| jfi | dS )z
        Register route and shutdown callback

        :param app: instance of aiohttp Application
        :param path: route path
        :param kwargs:
        POSTN)r)   r*   _handle_closerouter	add_routehandle)rL   r   rN   r   r    r    r%   registerj   s   zBaseRequestHandler.registerr   r   c                    s   |   I d H  d S N)close)rL   r   r   r    r    r%   rP   u   s   z BaseRequestHandler._handle_closec                    s   d S rU   r    rL   r    r    r%   rV   x   s   zBaseRequestHandler.closer-   c                    s   dS )z
        This method should be implemented in subclasses of this class.

        Resolve Bot instance from request.

        :param request:
        :return: Bot instance
        Nr    rL   r-   r    r    r%   resolve_bot|   s    zBaseRequestHandler.resolve_bottelegram_secret_tokenbotc                 C   s   d S rU   r    rL   rZ   r[   r    r    r%   verify_secret   s   z BaseRequestHandler.verify_secretupdatec                    sJ   | j jd||d| jI d H }t|tr#| j j||dI d H  d S d S )Nr[   r^   r[   resultr    )r   feed_raw_updaterI   
isinstancer   silent_call_request)rL   r[   r^   ra   r    r    r%   _background_feed_update   s
    
z*BaseRequestHandler._background_feed_updatec                    sT   t | j||j|jjdI d H d}| j| || jj	 t
ji |jjdS )Nloadsr_   )dumps)asynciocreate_taskre   jsonsession
json_loadsrK   addadd_done_callbackdiscardr   json_response
json_dumps)rL   r[   r-   feed_update_taskr    r    r%   _handle_request_background   s   z-BaseRequestHandler._handle_request_backgroundra   c                 C   s   |st i S tddtd d}||j}|jddd i }|jdd D ]\}}|j	j
|||d	}|s9q)||}|jd|d q)| D ]\}}|||}|jd||jp^|d
 qJ|S )Nz	form-datawebhookBoundary   )boundarymethod)nameF)warnings)r[   files)ry   filename)r
   r   secretstoken_urlsafer*   __api_method__set_content_disposition
model_dumpitemsrl   prepare_valuereadr|   )rL   r[   ra   writerpayloadr{   keyvaluer    r    r%   _build_response_writer   s.   
z)BaseRequestHandler._build_response_writerc                    sH   | j j||j|jjdI d H fi | jI d H }tj| j||ddS )Nrf   r`   )body)	r   feed_webhook_updaterk   rl   rm   rI   r   Responser   )rL   r[   r-   ra   r    r    r%   _handle_request   s   z"BaseRequestHandler._handle_requestc                    sd   |  |I d H }| |jdd|stjdddS | jr(| j||dI d H S | j||dI d H S )NzX-Telegram-Bot-Api-Secret-Tokenr.   Unauthorizedi  )r   status)r[   r-   )	rY   r]   r3   r4   r   r   rH   rt   r   )rL   r-   r[   r    r    r%   rS      s   zBaseRequestHandler.handle)Fr   N)__name__
__module____qualname__r   boolr   rM   strr   rT   rP   r   rV   r   rE   r   rY   r]   dictre   r   rt   r   r   r   r   r   rS   __call__r    r    r    r%   rG   V   s>    



%rG   c                       st   e Zd Z		ddededededB deddf fd	d
ZdededefddZ	dddZ
dejdefddZ  ZS )SimpleRequestHandlerTNr   r[   rH   secret_tokenrI   r   c                    s(   t  jd||d| || _|| _dS )aM  
        Handler for single Bot instance

        :param dispatcher: instance of :class:`aiogram.dispatcher.dispatcher.Dispatcher`
        :param handle_in_background: immediately responds to the Telegram instead of
            a waiting end of handler process
        :param bot: instance of :class:`aiogram.client.bot.Bot`
        r   rH   Nr    )superrM   r[   r   )rL   r   r[   rH   r   rI   	__class__r    r%   rM      s   
zSimpleRequestHandler.__init__rZ   c                 C   s   | j r
t|| j S dS NT)r   r}   compare_digestr\   r    r    r%   r]      s   z"SimpleRequestHandler.verify_secretc                    s   | j j I dH  dS )z#
        Close bot session
        N)r[   rl   rV   rW   r    r    r%   rV      s   zSimpleRequestHandler.closer-   c                    s   | j S rU   )r[   rX   r    r    r%   rY      s   z SimpleRequestHandler.resolve_botTNr   )r   r   r   r   r   r   r   r   rM   r]   rV   r   rE   rY   __classcell__r    r    r   r%   r      s&    
r   c                       s   e Zd Z		ddededeeef dB deddf
 fdd	Zd
ede	defddZ
dddZdedededdf fddZdejde	fddZ  ZS )TokenBasedRequestHandlerTNr   rH   bot_settingsrI   r   c                    s4   t  jd||d| |du ri }|| _i | _dS )aP  
        Handler that supports multiple bots the context will be resolved
        from path variable 'bot_token'

        .. note::

            This handler is not recommended in due to token is available in URL
            and can be logged by reverse proxy server or other middleware.

        :param dispatcher: instance of :class:`aiogram.dispatcher.dispatcher.Dispatcher`
        :param handle_in_background: immediately responds to the Telegram instead of
            a waiting end of handler process
        :param bot_settings: kwargs that will be passed to new Bot instance
        r   Nr    )r   rM   r   bots)rL   r   rH   r   rI   r   r    r%   rM      s
   
z!TokenBasedRequestHandler.__init__rZ   r[   c                 C   s   dS r   r    r\   r    r    r%   r]     s   z&TokenBasedRequestHandler.verify_secretc                    s&   | j  D ]
}|j I d H  qd S rU   )r   valuesrl   rV   )rL   r[   r    r    r%   rV     s   zTokenBasedRequestHandler.closerN   r   r   c                   s0   d|vr
d}t |t j|fd|i| dS )z
        Validate path, register route and shutdown callback

        :param app: instance of aiohttp Application
        :param path: route path
        :param kwargs:
        z{bot_token}z,Path should contains '{bot_token}' substringrN   N)
ValueErrorr   rT   )rL   r   rN   r   msgr   r    r%   rT     s   z!TokenBasedRequestHandler.registerr-   c                    s:   |j d }|| jvrtdd|i| j| j|< | j| S )z
        Get bot token from a path and create or get from cache Bot instance

        :param request:
        :return:
        	bot_tokentokenNr    )
match_infor   r   r   )rL   r-   r   r    r    r%   rY   '  s
   


z$TokenBasedRequestHandler.resolve_botr   r   )r   r   r   r   r   r   r   r   rM   r   r]   rV   r   rT   r   rE   rY   r   r    r    r   r%   r      s$    
r   ).ri   r}   abcr   r   r   collections.abcr   r   typingr   r   r	   aiohttpr
   r   r   r   aiohttp.typedefsr   aiohttp.web_appr   aiohttp.web_middlewaresr   aiogramr   r   r   aiogram.methodsr   aiogram.methods.baser   aiogram.webhook.securityr   aiogram.typesr   r+   rE   tupler   r   r<   rF   rG   r   r   r    r    r    r%   <module>   s4     
}$