o
    NK&h9                     @   s>  d dl mZ d dlm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 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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' d dl(m)Z) d dl*m+Z+ d dl,m-Z-m.Z.m/Z/m0Z0 G dd de'edZ1G dd dedZ2dS )    )Sequence)
formatdate)partialwraps)
guess_type)PathLikepath)PathPurePath)OptionalUnion)unquote)Route)	SanicMeta)
stat_async)DEFAULT_HTTP_CONTENT_TYPE)FileNotFoundHeaderNotFoundRangeNotSatisfiable)ContentRangeHandler)DirectoryHandler)error_logger)	BaseMixin)FutureStatic)Request)HTTPResponsefilefile_streamvalidate_filec                    @   s   e Zd ZdddZdedefddZ				
	
									
	ddedee	ef dede
de
dee
ef dedee dee
 dee de
dee deeeee f  de
dee fddZdS )StaticMixinreturnNc                 O   s   t  | _d S N)set_future_statics)selfargskwargs r'   F/var/www/html/venv/lib/python3.10/site-packages/sanic/mixins/static.py__init__   s   zStaticMixin.__init__staticc                 C   s   t r!   )NotImplementedErrorr$   r*   r'   r'   r(   _apply_static   s   zStaticMixin._apply_static/?.+TFurifile_or_directorypatternuse_modified_sinceuse_content_rangestream_large_filesnamehoststrict_slashescontent_typeapplyresource_typeindexdirectory_viewdirectory_handlerc                 C   s   |  |}|	du r| jdur| j}	t|tttfs td| zt| }W n t	y3   t	dw |r>|s:|r>td|sHt
||||d}t|||||||||	|
||}| j| |rf| | dS dS )a$  Register a root to serve files from. The input can either be a file or a directory.

        This method provides an easy and simple way to set up the route necessary to serve static files.

        Args:
            uri (str): URL path to be used for serving static content.
            file_or_directory (Union[PathLike, str]): Path to the static file
                or directory with static files.
            pattern (str, optional): Regex pattern identifying the valid
                static files. Defaults to `r"/?.+"`.
            use_modified_since (bool, optional): If true, send file modified
                time, and return not modified if the browser's matches the
                server's. Defaults to `True`.
            use_content_range (bool, optional): If true, process header for
                range requests and sends  the file part that is requested.
                Defaults to `False`.
            stream_large_files (Union[bool, int], optional): If `True`, use
                the `StreamingHTTPResponse.file_stream` handler rather than
                the `HTTPResponse.file handler` to send the file. If this
                is an integer, it represents the threshold size to switch
                to `StreamingHTTPResponse.file_stream`. Defaults to `False`,
                which means that the response will not be streamed.
            name (str, optional): User-defined name used for url_for.
                Defaults to `"static"`.
            host (Optional[str], optional): Host IP or FQDN for the
                service to use.
            strict_slashes (Optional[bool], optional): Instruct Sanic to
                check if the request URLs need to terminate with a slash.
            content_type (Optional[str], optional): User-defined content type
                for header.
            apply (bool, optional): If true, will register the route
                immediately. Defaults to `True`.
            resource_type (Optional[str], optional): Explicitly declare a
                resource to be a `"file"` or a `"dir"`.
            index (Optional[Union[str, Sequence[str]]], optional): When
                exposing against a directory, index is  the name that will
                be served as the default file. When multiple file names are
                passed, then they will be tried in order.
            directory_view (bool, optional): Whether to fallback to showing
                the directory viewer when exposing a directory. Defaults
                to `False`.
            directory_handler (Optional[DirectoryHandler], optional): An
                instance of DirectoryHandler that can be used for explicitly
                controlling and subclassing the behavior of the default
                directory handler.

        Returns:
            List[sanic.router.Route]: Routes registered on the router.

        Examples:
            Serving a single file:
            ```python
            app.static('/foo', 'path/to/static/file.txt')
            ```

            Serving all files from a directory:
            ```python
            app.static('/static', 'path/to/static/directory')
            ```

            Serving large files with a specific threshold:
            ```python
            app.static('/static', 'path/to/large/files', stream_large_files=1000000)
            ```
        Nz'Static route must be a valid path, not z=Static file or directory must be a path-like object or stringzWhen explicitly setting directory_handler, you cannot set either directory_view or index. Instead, pass these arguments to your DirectoryHandler instance.)r/   	directoryr<   r;   )generate_namer7   
isinstancestrbytesr
   
ValueErrorr	   resolve	TypeErrorr   r   r#   addr-   )r$   r/   r0   r1   r2   r3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r=   r*   r'   r'   r(   r*       sV   
TzStaticMixin.static)r    N)r.   TFFr*   NNNTNNFN)__name__
__module____qualname__r)   r   r   r-   rA   r   r   boolintr   r   r   r*   r'   r'   r'   r(   r      s^    


	
r   )	metaclassc                   @   sv   e Zd ZdedefddZdefddZdddd	ed
ede	de	de
e	ef dedee dee fddZdd ZdS )StaticHandleMixinr*   r    c                 C   s
   |  |S r!   )_register_staticr,   r'   r'   r(   r-      s   
zStaticHandleMixin._apply_staticc              
   C   sJ  t |jtrt|jd}nt |jtr|j}nt |jtr%t|j}ntd|j}|j	}|j
sAt|s@|d}|d7 }n7|j
dkr]t|rStd| d|d}|d7 }n|j
dkrot|sotd	| d|j
dkrxtd
t| jt| jt||j|j|j|j|jd}| j|ddg||j|jdd|\}}|S )z
        Register a static directory handler with Sanic by adding a route to the
        router and registering a handler.
        zutf-8zInvalid file path string./z/<__file_uri__:path>dirz3Resource type improperly identified as directory. ''r   z.Resource type improperly identified as file. 'z2The resource_type should be set to 'file' or 'dir')r0   r2   r3   r4   r8   r=   GETHEADT)r/   methodsr5   r6   r7   r*   )r@   r0   rB   r	   decoder
   rA   rC   r/   r5   r:   r   isfilerstriprE   r   _static_request_handlerr   r2   r3   r4   r8   r=   router6   r7   )r$   r*   r0   r/   r5   _handlerrY   _r'   r'   r(   rN      sr   






	z"StaticHandleMixin._register_staticN)r8   __file_uri__requestr0   r2   r3   r4   r=   r8   r\   c             	      s  t dt||d}	| |||	I d H }
zi }d }|r;t|
I d H }|j}t|j|I d H }|r3|W S t|dd|d< d }|rtd }|sJt|
I d H }d|d< t|j	|d< |j
d	krtzt||}W n	 tyj   Y n
w |d= ||j d
|vr|pt|
d pt}d|vr|ds|dkr|d7 }||d< |j
d	krt|dW S |rt|trd}n|}|st|
I d H }|j	|krt|
||dI d H W S t|
||dI d H W S  ttfy   |||jI d H  Y S  ty     ty   |	 ty   td| d|   w )NzFile not found)r   relative_urlT)usegmtzLast-ModifiedrB   zAccept-RangeszContent-LengthrS   zcontent-typer   zcharset=ztext/zapplication/javascriptz; charset=utf-8zContent-Type)headersi   )r`   _rangez*Exception in static request handler: path=, relative_url=)r   r	   _get_file_pathr   st_mtimer   r`   r   rA   st_sizemethodr   r   updater   r   
startswithr   r@   rJ   r   r   IsADirectoryErrorPermissionErrorhandler   r   FileNotFoundError	Exceptionr   	exception)r$   r]   r0   r2   r3   r4   r=   r8   r\   	not_found	file_pathr`   statsmodified_sinceresponsera   	thresholdr'   r'   r(   rX      s   






z)StaticHandleMixin._static_request_handlerc              	      s   t t|}|  }}|r9t|d}t ||}| }||k r'| r,d|jv r9td| d|  |z|| W |S  t	y\   | sYtd| d|  |Y |S w )NrO   z..zFile not found: path=rb   )
r	   r   rD   lstrip
is_symlinkpartsr   rn   relative_torC   )r$   r0   r\   ro   file_path_raw	root_pathrp   unquoted_file_urir'   r'   r(   rc   [  s:   

z StaticHandleMixin._get_file_path)rG   rH   rI   r   r   r-   rN   r   rA   rJ   r   rK   r   r   rX   rc   r'   r'   r'   r(   rM      s2    
V
	

brM   N)3collections.abcr   email.utilsr   	functoolsr   r   	mimetypesr   osr   r   pathlibr	   r
   typingr   r   urllib.parser   sanic_routing.router   sanic.base.metar   sanic.compatr   sanic.constantsr   sanic.exceptionsr   r   r   sanic.handlersr   sanic.handlers.directoryr   	sanic.logr   sanic.mixins.baser   sanic.models.futuresr   sanic.requestr   sanic.responser   r   r   r   r   rM   r'   r'   r'   r(   <module>   s.     