U
    nËjßN  ã                   @  sÆ  d dl mZ d dlZd dlZd dlZd dlZ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Zd dl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%m&Z&m'Z' G dd„ dƒZ(G dd„ de(ƒZ)G dd„ de(ƒZ*G dd„ de(ƒZ+G dd„ de(ƒZ,ej-e.e/e0f Z1ej2e1 Z3ej4e1 Z5ej-e5e3f Z6G dd„ de(ƒZ7G dd„ de8ƒZ9G dd„ de8ƒZ:e ;d¡Z<G d d!„ d!e(ƒZ=dS )"é    )ÚannotationsN)Údatetime)Úformat_datetimeÚ
formatdate)Úpartial)Ú
guess_type)Ú	token_hex)Úquote)Úmd5_hexdigest)ÚBackgroundTask)Úiterate_in_threadpool)ÚURLÚHeadersÚMutableHeaders)ÚClientDisconnect)ÚReceiveÚScopeÚSendc                   @  s´   e Zd ZdZdZd-dddddd	d
œdd„Zdddœdd„Zd.dd	dœdd„Zeddœdd„ƒZ	d/ddddddddd d	d!œ
d"d#„Z
d0dddddd d	d$œd%d&„Zd'd(d)d	d*œd+d,„ZdS )1ÚResponseNúutf-8éÈ   ú
typing.AnyÚintútyping.Mapping[str, str] | Noneú
str | NoneúBackgroundTask | NoneÚNone©ÚcontentÚstatus_codeÚheadersÚ
media_typeÚ
backgroundÚreturnc                 C  s4   || _ |d k	r|| _|| _|  |¡| _|  |¡ d S ©N)r   r!   r"   ÚrenderÚbodyÚinit_headers©Úselfr   r   r    r!   r"   © r*   ú7/tmp/pip-unpacked-wheel-pzfrzqh9/starlette/responses.pyÚ__init__    s    zResponse.__init__zbytes | memoryview©r   r#   c                 C  s*   |d krdS t |ttfƒr|S | | j¡S )Nó    )Ú
isinstanceÚbytesÚ
memoryviewÚencodeÚcharset©r)   r   r*   r*   r+   r%   /   s
    zResponse.render)r    r#   c           	      C  sæ   |d krg }d}d}n0dd„ |  ¡ D ƒ}dd„ |D ƒ}d|k}d|k}t| dd ƒ}|d k	r’|r’| jdk s’| jd	ks’tt|ƒƒ}| d| d
¡f¡ | j}|d k	rÜ|rÜ| d¡rÈd| 	¡ krÈ|d| j
 7 }| d| d
¡f¡ || _d S )NTc                 S  s(   g | ] \}}|  ¡  d ¡| d ¡f‘qS )úlatin-1)Úlowerr2   )Ú.0ÚkÚvr*   r*   r+   Ú
<listcomp><   s     z)Response.init_headers.<locals>.<listcomp>c                 S  s   g | ]}|d  ‘qS )r   r*   )r7   Úhr*   r*   r+   r:   =   s     s   content-lengths   content-typer&   r   )éÌ   i0  r5   ztext/zcharset=z
; charset=)ÚitemsÚgetattrr   ÚstrÚlenÚappendr2   r!   Ú
startswithr6   r3   Úraw_headers)	r)   r    rC   Zpopulate_content_lengthZpopulate_content_typeÚkeysr&   Úcontent_lengthÚcontent_typer*   r*   r+   r'   6   s2    ÿþýýzResponse.init_headersr   )r#   c                 C  s   t | dƒst| jd�| _| jS )NÚ_headers)Úraw)Úhasattrr   rC   rG   )r)   r*   r*   r+   r    R   s    
zResponse.headersÚ ú/FÚlaxr?   z
int | Nonezdatetime | str | int | NoneÚboolz0typing.Literal[('lax', 'strict', 'none')] | None)
ÚkeyÚvalueÚmax_ageÚexpiresÚpathÚdomainÚsecureÚhttponlyÚsamesiter#   c
                 C  sô   t j ¡ }
||
|< |d k	r&||
| d< |d k	rZt|tƒrNt|dd�|
| d< n||
| d< |d k	rn||
| d< |d k	r‚||
| d< |r’d|
| d< |r¢d|
| d< |	d k	rÊ|	 ¡ d	ks¾td
ƒ‚|	|
| d< |
jdd� 	¡ }| j
 d| d¡f¡ d S )Nzmax-ageT©ÚusegmtrQ   rR   rS   rT   rU   )ÚstrictrL   Únonez1samesite must be either 'strict', 'lax' or 'none'rV   rJ   )Úheaders
   set-cookier5   )ÚhttpÚcookiesÚSimpleCookier/   r   r   r6   ÚAssertionErrorÚoutputÚstriprC   rA   r2   )r)   rN   rO   rP   rQ   rR   rS   rT   rU   rV   ÚcookieZ
cookie_valr*   r*   r+   Ú
set_cookieX   s.    

üzResponse.set_cookie)rN   rR   rS   rT   rU   rV   r#   c              
   C  s   | j |dd|||||d� d S )Nr   )rP   rQ   rR   rS   rT   rU   rV   )rc   )r)   rN   rR   rS   rT   rU   rV   r*   r*   r+   Údelete_cookie   s    	øzResponse.delete_cookier   r   r   ©ÚscopeÚreceiveÚsendr#   c                 Ã  sh   |d dkrdnd}||d | j | jdœƒI d H  ||d | jdœƒI d H  | jd k	rd|  ¡ I d H  d S )	NÚtypeZ	websocketz
websocket.rJ   úhttp.response.start©ri   Ústatusr    úhttp.response.body)ri   r&   )r   rC   r&   r"   )r)   rf   rg   rh   Úprefixr*   r*   r+   Ú__call__“   s    ýÿ

zResponse.__call__)Nr   NNN)N)rJ   NNrK   NFFrL   )rK   NFFrL   )Ú__name__Ú
__module__Ú__qualname__r!   r3   r,   r%   r'   Úpropertyr    rc   rd   ro   r*   r*   r*   r+   r      s8        ú        ö"*     ùr   c                   @  s   e Zd ZdZdS )ÚHTMLResponsez	text/htmlN©rp   rq   rr   r!   r*   r*   r*   r+   rt   ¢   s   rt   c                   @  s   e Zd ZdZdS )ÚPlainTextResponseú
text/plainNru   r*   r*   r*   r+   rv   ¦   s   rv   c                      sB   e Zd ZdZddddddd	d
œ‡ fdd„Zdddœdd„Z‡  ZS )ÚJSONResponsezapplication/jsonr   Nr   r   r   r   r   r   r   c                   s   t ƒ  |||||¡ d S r$   )Úsuperr,   r(   ©Ú	__class__r*   r+   r,   ­   s    zJSONResponse.__init__r0   r-   c                 C  s   t j|ddd dd� d¡S )NF)ú,ú:)Úensure_asciiÚ	allow_nanÚindentÚ
separatorsr   )ÚjsonÚdumpsr2   r4   r*   r*   r+   r%   ·   s    ûúzJSONResponse.render)r   NNN)rp   rq   rr   r!   r,   r%   Ú__classcell__r*   r*   rz   r+   rx   ª   s       ú
rx   c                      s,   e Zd Zdddddddœ‡ fd	d
„Z‡  ZS )ÚRedirectResponseé3  Nz	str | URLr   r   r   r   )Úurlr   r    r"   r#   c                   s.   t ƒ jd|||d� tt|ƒdd�| jd< d S )Nr.   )r   r   r    r"   z:/%#?=@[]!$&'()*+,;)ÚsafeÚlocation)ry   r,   r	   r?   r    )r)   r‡   r   r    r"   rz   r*   r+   r,   Â   s    zRedirectResponse.__init__)r†   NN)rp   rq   rr   r,   r„   r*   r*   rz   r+   r…   Á   s      ûr…   c                   @  sd   e Zd ZU ded< dddddd	d
dœdd„Zdd
dœdd„Zdd
dœdd„Zdddd
dœdd„ZdS )ÚStreamingResponseÚAsyncContentStreamÚbody_iteratorr   NÚContentStreamr   r   r   r   r   r   c                 C  sL   t |tjƒr|| _n
t|ƒ| _|| _|d kr2| jn|| _|| _|  |¡ d S r$   )	r/   ÚtypingÚAsyncIterablerŒ   r   r   r!   r"   r'   r(   r*   r*   r+   r,   Ö   s    
zStreamingResponse.__init__r   )rg   r#   c                 Ã  s    |ƒ I d H }|d dkr qq d S )Nri   zhttp.disconnectr*   )r)   rg   Úmessager*   r*   r+   Úlisten_for_disconnectç   s    z'StreamingResponse.listen_for_disconnectr   )rh   r#   c                 Ã  sz   |d| j | jdœƒI d H  | j2 z<3 d H W }t|ttfƒsF| | j¡}|d|ddœƒI d H  q 6 |ddddœƒI d H  d S )Nrj   rk   rm   T©ri   r&   Ú	more_bodyr.   F)r   rC   rŒ   r/   r0   r1   r2   r3   )r)   rh   Úchunkr*   r*   r+   Ústream_responseí   s    ýÿ
z!StreamingResponse.stream_responser   re   c              
   ƒ  sÚ   t tt| di ¡ dd¡ d¡ƒƒ}|dkr^z|  |¡I d H  W q¾ tk
rZ   tƒ ‚Y q¾X n`t 	¡ 4 I d H šD‰ dddœ‡ fd	d
„}ˆ  
|t| j|ƒ¡ |t| j|ƒƒI d H  W 5 Q I d H R X | jd k	rÖ|  ¡ I d H  d S )NZasgiÚspec_versionz2.0Ú.)é   é   z+typing.Callable[[], typing.Awaitable[None]]r   )Úfuncr#   c                 “  s   | ƒ I d H  ˆ j  ¡  d S r$   )Zcancel_scopeÚcancel)rš   ©Z
task_groupr*   r+   Úwrap  s    z(StreamingResponse.__call__.<locals>.wrap)ÚtupleÚmapr   ÚgetÚsplitr•   ÚOSErrorr   ÚanyioZcreate_task_groupZ
start_soonr   r‘   r"   )r)   rf   rg   rh   r–   r�   r*   rœ   r+   ro   ü   s    $&
zStreamingResponse.__call__)r   NNN)rp   rq   rr   Ú__annotations__r,   r‘   r•   ro   r*   r*   r*   r+   rŠ   Ó   s   
    úrŠ   c                   @  s   e Zd Zddddœdd„ZdS )	ÚMalformedRangeHeaderúMalformed range header.r?   r   r-   c                 C  s
   || _ d S r$   )r   r4   r*   r*   r+   r,     s    zMalformedRangeHeader.__init__N)r¦   ©rp   rq   rr   r,   r*   r*   r*   r+   r¥     s   r¥   c                   @  s   e Zd Zdddœdd„ZdS )ÚRangeNotSatisfiabler   r   )Úmax_sizer#   c                 C  s
   || _ d S r$   )r©   )r)   r©   r*   r*   r+   r,     s    zRangeNotSatisfiable.__init__Nr§   r*   r*   r*   r+   r¨     s   r¨   z(\d*)-(\d*)c                   @  sÒ   e Zd ZdZd0ddddd	dd
ddddœ
dd„Zdddœdd„Zdddddœdd„Zddddœdd„Zdddddddœdd „Zdd!dddd"œd#d$„Z	ddd%œd&d'„Z
eddd!d(œd)d*„ƒZd+dddd,d-œd.d/„ZdS )1ÚFileResponsei   r   NÚ
attachmentzstr | os.PathLike[str]r   r   r   r   zos.stat_result | Noner?   r   )
rR   r   r    r!   r"   ÚfilenameÚstat_resultÚmethodÚcontent_disposition_typer#   c
                 C  sÐ   || _ || _|| _|d k	r&t dt¡ |d krBt|p6|ƒd p@d}|| _|| _|  	|¡ | j
 dd¡ | jd k	r´t| jƒ}
|
| jkr”|	› d|
› �}n|	› d| j› d�}| j
 d	|¡ || _|d k	rÌ|  |¡ d S )
Nz;The 'method' parameter is not used, and it will be removed.r   rw   zaccept-rangesr0   z; filename*=utf-8''z; filename="ú"zcontent-disposition)rR   r   r¬   ÚwarningsÚwarnÚDeprecationWarningr   r!   r"   r'   r    Ú
setdefaultr	   r­   Úset_stat_headers)r)   rR   r   r    r!   r"   r¬   r­   r®   r¯   Zcontent_disposition_filenameÚcontent_dispositionr*   r*   r+   r,   "  s.    þ



zFileResponse.__init__zos.stat_result)r­   r#   c                 C  sv   t |jƒ}t|jdd�}t |jƒd t |jƒ }dt| ¡ dd�› d�}| j d|¡ | j d|¡ | j d	|¡ d S )
NTrW   ú-r°   F)Zusedforsecurityúcontent-lengthúlast-modifiedÚetag)r?   Úst_sizer   Úst_mtimer
   r2   r    r´   )r)   r­   rE   Zlast_modifiedZ	etag_baserº   r*   r*   r+   rµ   G  s    
zFileResponse.set_stat_headersr   r   r   re   c              
   Ã  sò  |d   ¡ dk}| jd krŒz&tj tj| j¡I d H }|  |¡ W n& t	k
rf   t
d| j› d�ƒ‚Y q’X |j}t |¡s’t
d| j› d�ƒ‚n| j}t|d�}| d¡}| d¡}	|d ksÊ|	d k	rÞ|  |	¡sÞ|  ||¡I d H  nöz|  ||j¡}
W n” tk
�r4 } z$t|jd	d
�|||ƒI d H  W Y ¢S d }~X Y nR tk
�r„ } z2tddd|j› �id�}||||ƒI d H  W Y ¢S d }~X Y nX t|
ƒdk�r¼|
d \}}|  ||||j|¡I d H  n|  ||
|j|¡I d H  | jd k	�rî|  ¡ I d H  d S )Nr®   ÚHEADzFile at path z does not exist.z is not a file.)rf   Úrangezif-rangei�  )r   i   zContent-Rangez*/)r   r    é   r   )Úupperr­   r£   Z	to_threadZrun_syncÚosÚstatrR   rµ   ÚFileNotFoundErrorÚRuntimeErrorÚst_modeÚS_ISREGr   r    Ú_should_use_rangeÚ_handle_simpleÚ_parse_range_headerr»   r¥   rv   r   r¨   r©   r@   Ú_handle_single_rangeÚ_handle_multiple_rangesr"   )r)   rf   rg   rh   Úsend_header_onlyr­   Úmoder    Ú
http_rangeÚhttp_if_rangeÚrangesÚexcÚresponseÚstartÚendr*   r*   r+   ro   Q  s:    




0(zFileResponse.__call__rM   )rh   rÌ   r#   c              
   Ã  sª   |d| j | jdœƒI d H  |r6|ddddœƒI d H  nptj| jdd�I d H 4 I d H šF}d	}|r–| | j¡I d H }t|ƒ| jk}|d||dœƒI d H  qZW 5 Q I d H R X d S )
Nrj   rk   rm   r.   Fr’   Úrb©rÍ   T)r   rC   r£   Ú	open_filerR   ÚreadÚ
chunk_sizer@   )r)   rh   rÌ   Úfiler“   r”   r*   r*   r+   rÈ   x  s     zFileResponse._handle_simple)rh   rÓ   rÔ   Ú	file_sizerÌ   r#   c           	   
   Ã  s  d|› d|d › d|› �| j d< t|| ƒ| j d< |dd| jd	œƒI d H  |rf|d
dddœƒI d H  nžtj| jdd�I d H 4 I d H št}| |¡I d H  d}|rô| t| j	|| ƒ¡I d H }|t
|ƒ7 }t
|ƒ| j	koÚ||k }|d
||dœƒI d H  qšW 5 Q I d H R X d S )Nzbytes r·   r¿   rK   úcontent-ranger¸   rj   éÎ   rk   rm   r.   Fr’   rÕ   rÖ   T)r    r?   rC   r£   r×   rR   ÚseekrØ   ÚminrÙ   r@   )	r)   rh   rÓ   rÔ   rÛ   rÌ   rÚ   r“   r”   r*   r*   r+   rÊ   „  s      z!FileResponse._handle_single_rangezlist[tuple[int, int]])rh   rÐ   rÛ   rÌ   r#   c              
   Ã  sf  t dƒ}|  |||| jd ¡\}}d|› �| jd< t|ƒ| jd< |dd| jdœƒI d H  |rt|d	d
ddœƒI d H  nîtj| jdd�I d H 4 I d H šÄ}|D ]”\}	}
|d	||	|
ƒddœƒI d H  | |	¡I d H  |	|
k �r| 	t
| j|
|	 ƒ¡I d H }|	t|ƒ7 }	|d	|ddœƒI d H  qÌ|d	dddœƒI d H  q˜|d	d|› d� d¡ddœƒI d H  W 5 Q I d H R X d S )Né   zcontent-typezmultipart/byteranges; boundary=rÜ   r¸   rj   rÝ   rk   rm   r.   Fr’   rÕ   rÖ   Tó   
z
--z--
r5   )r   Úgenerate_multipartr    r?   rC   r£   r×   rR   rÞ   rØ   rß   rÙ   r@   r2   )r)   rh   rÐ   rÛ   rÌ   ÚboundaryrE   Zheader_generatorrÚ   rÓ   rÔ   r”   r*   r*   r+   rË   –  s6       ÿ 
ýÿz$FileResponse._handle_multiple_ranges)rÏ   r#   c                 C  s   || j d kp|| j d kS )Nr¹   rº   )r    )r)   rÏ   r*   r*   r+   rÇ   ¹  s    zFileResponse._should_use_range)rÎ   rÛ   r#   c                   sN  g }z|   dd¡\}}W n tk
r2   tƒ ‚Y nX | ¡  ¡ }|dkrPtdƒ‚‡ fdd„t |¡D ƒ}t|ƒdkr|tdƒ‚t‡ fd	d
„|D ƒƒršt	ˆ ƒ‚tdd
„ |D ƒƒr´tdƒ‚t|ƒdkrÄ|S g }|D ]|\}}t
t|ƒƒD ]X}|| \}	}
||
krüqàqà||	k �r| |||f¡  qÌqàt||	ƒt||
ƒf||<  qÌqà| ||f¡ qÌ|S )Nú=r¿   r0   zOnly support bytes rangec                   sl   g | ]d}|d kr|d r$t |d ƒnˆ t |d ƒ |d rb|d rbt |d ƒˆ k rbt |d ƒd nˆ f‘qS ))rJ   rJ   r   r¿   )r   )r7   Ú_©rÛ   r*   r+   r:   É  s
   ü"2þz4FileResponse._parse_range_header.<locals>.<listcomp>r   z%Range header: range must be requestedc                 3  s,   | ]$\}}d |  koˆ k n   V  qdS )r   Nr*   )r7   rÓ   rå   ræ   r*   r+   Ú	<genexpr>Õ  s     z3FileResponse._parse_range_header.<locals>.<genexpr>c                 s  s   | ]\}}||kV  qd S r$   r*   ©r7   rÓ   rÔ   r*   r*   r+   rç   Ø  s     z)Range header: start must be less than end)r¡   Ú
ValueErrorr¥   ra   r6   Ú_RANGE_PATTERNÚfindallr@   Úanyr¨   r¾   Úinsertrß   ÚmaxrA   )rÎ   rÛ   rÐ   ZunitsZrange_ÚresultrÓ   rÔ   ÚpZp_startZp_endr*   ræ   r+   rÉ   ¼  s@    
û	
z FileResponse._parse_range_headerz typing.Sequence[tuple[int, int]]z.tuple[int, typing.Callable[[int, int], bytes]])rÐ   rã   r©   rF   r#   c                   sV   t ˆ ƒ}d| t ˆƒ t tˆƒƒ ‰t‡fdd„|D ƒƒd|  }|‡ ‡‡fdd„fS )a½  
        Multipart response headers generator.

        ```
        --{boundary}\n
        Content-Type: {content_type}\n
        Content-Range: bytes {start}-{end-1}/{max_size}\n
        \n
        ..........content...........\n
        --{boundary}\n
        Content-Type: {content_type}\n
        Content-Range: bytes {start}-{end-1}/{max_size}\n
        \n
        ..........content...........\n
        --{boundary}--\n
        ```
        é,   c                 3  s:   | ]2\}}t t|ƒƒt t|d  ƒƒ ˆ  ||  V  qdS )r¿   N)r@   r?   rè   )Ústatic_header_part_lenr*   r+   rç   
  s   þÿz2FileResponse.generate_multipart.<locals>.<genexpr>é   c                   s.   dˆ › dˆ› d| › d|d › dˆ› d�  d¡S )	Nz--z
Content-Type: z
Content-Range: bytes r·   r¿   rK   z

r5   )r2   )rÓ   rÔ   )rã   rF   r©   r*   r+   Ú<lambda>  s    &ÿûz1FileResponse.generate_multipart.<locals>.<lambda>)r@   r?   Úsum)r)   rÐ   rã   r©   rF   Zboundary_lenrE   r*   )rã   rF   r©   rò   r+   râ   ð  s    ýûþzFileResponse.generate_multipart)r   NNNNNNr«   )rp   rq   rr   rÙ   r,   rµ   ro   rÈ   rÊ   rË   rÇ   ÚstaticmethodrÉ   râ   r*   r*   r*   r+   rª     s&           ö"%
'#3rª   )>Ú
__future__r   Úhttp.cookiesr\   r‚   rÁ   ÚrerÂ   rŽ   r±   r   Úemail.utilsr   r   Ú	functoolsr   Ú	mimetypesr   Zsecretsr   Úurllib.parser	   r£   Zanyio.to_threadZstarlette._compatr
   Zstarlette.backgroundr   Zstarlette.concurrencyr   Zstarlette.datastructuresr   r   r   Zstarlette.requestsr   Zstarlette.typesr   r   r   r   rt   rv   rx   r…   ÚUnionr?   r0   r1   ZContentÚIterableZSyncContentStreamr�   r‹   r�   rŠ   Ú	Exceptionr¥   r¨   Úcompilerê   rª   r*   r*   r*   r+   Ú<module>   sH    

?
