o
    i:                     @   s   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	m
Z
 d dlmZmZ d dlmZ dZedZeeZG dd	 d	ZG d
d de jZdd Zdd Zdd Zdd Zdd ZG dd dZdS )    N)TOKEN_RE)ConfigurationProblemInvalidHeaderInvalidHeaderName)SERVER_SOFTWARESERVER)utili?z[ \t\x21-\x7e\x80-\xff]*c                   @   s   e Zd ZdddZdd ZdS )FileWrapper    c                 C   s&   || _ || _t|dr|j| _d S d S )Nclose)filelikeblksizehasattrr   )selfr   r    r   F/home/ubuntu/.local/lib/python3.10/site-packages/gunicorn/http/wsgi.py__init__   s
   
zFileWrapper.__init__c                 C   s   | j | j}|r|S tN)r   readr   
IndexError)r   keydatar   r   r   __getitem__#   s   zFileWrapper.__getitem__N)r
   )__name__
__module____qualname__r   r   r   r   r   r   r	      s    
r	   c                   @   s   e Zd Zdd Zdd ZdS )WSGIErrorsWrapperc                 C   s`   t d}|j}g | _|jdkr| jtj |dd  }|D ]}t|dr-| j|j	 qd S )Nzgunicorn.error-   stream)
logging	getLoggerhandlersstreamserrorlogappendsysstderrr   r   )r   cfgr$   r"   hr   r   r   r   ,   s   


zWSGIErrorsWrapper.__init__c              	   C   sJ   | j D ]}z|| W n ty   ||d Y nw |  qd S )NzUTF-8)r#   writeUnicodeErrorencodeflush)r   r   r   r   r   r   r*   <   s   

zWSGIErrorsWrapper.writeN)r   r   r   r   r*   r   r   r   r   r   *   s    r   c              	   C   s    t | dd| jdkdtdtdS )Nr   r   Fr   T)zwsgi.errorszwsgi.versionzwsgi.multithreadzwsgi.multiprocesszwsgi.run_oncezwsgi.file_wrapperzwsgi.input_terminatedr   )r   workersr	   r   )r(   r   r   r   base_environE   s   r0   c                 C   sB   t |}|| j|| j| j| jdddd | jD  d |S )NzHTTP/%s.c                 S   s   g | ]}t |qS r   )str).0vr   r   r   
<listcomp>Z   s    z#default_environ.<locals>.<listcomp>)z
wsgi.inputzgunicorn.socketREQUEST_METHODQUERY_STRINGRAW_URISERVER_PROTOCOL)r0   updatebodymethodqueryurijoinversion)reqsockr(   envr   r   r   default_environR   s   rD   c                 C   s:   | j }|si S |d |d t|d |d t|d dS )Nproxy_protocolclient_addrclient_port
proxy_addr
proxy_port)PROXY_PROTOCOLREMOTE_ADDRREMOTE_PORT
PROXY_ADDR
PROXY_PORT)proxy_protocol_infor2   )rA   infor   r   r   proxy_environ_   s   

rQ   c                    s    fdd}|S )a   Create a wsgi.early_hints callback for sending 103 Early Hints.

    This allows WSGI applications to send 103 Early Hints responses
    before the final response, enabling browsers to preload resources.

    Args:
        req: The request object
        sock: The socket to write to
        resp: The Response object to check if headers have been sent

    Returns:
        A callback function that accepts a list of (name, value) header tuples
        and sends a 103 Early Hints response.

    Note:
        - Early hints are only sent for HTTP/1.1 or later clients
        - HTTP/1.0 clients will silently ignore the callback
        - Multiple calls are allowed (sending multiple 103 responses)
        - Calls after response has started are silently ignored
    c                    s   j rdS  jdk rdS d}| D ]%\}}t|tr|d}t|tr(|d}|| d| dd7 }q|d7 }t| dS )zSend 103 Early Hints response.

        Args:
            headers: List of (name, value) header tuples, typically Link headers
                     Example: [('Link', '</style.css>; rel=preload; as=style')]
        N)r   r   s   HTTP/1.1 103 Early Hints
latin-1z: z
   
)headers_sentr@   
isinstancebytesdecoder,   r   r*   )headersresponsenamevaluerA   resprB   r   r   send_early_hints   s   




z4_make_early_hints_callback.<locals>.send_early_hintsr   )rA   rB   r]   r^   r   r\   r   _make_early_hints_callbackn   s   r_   c                 C   s4  t | ||}t| ||}d }tjdd}| jr|d | jD ]<\}	}
|	dkr+|
}n|	dkr2|
}n|	dkr;|
|d< q |	dkrD|
|d< q d	|	d
d }||v rXd|| |
f }
|
||< q | j	|d< t
|trl||d< nt
|trx| |d< n|d |d< t|d |d< t
|tr|d}t|dkr|r|d}t|dkr| j	dkr|d n| j	dkr|d n|d n|d |d |d< t|d |d< | j}|r||std||f |t|d  }t||d< ||d< |t|  t| |||d< t| dr| j|d< | j|d< ||fS )NSCRIPT_NAME s   HTTP/1.1 100 Continue

HOSTzCONTENT-TYPECONTENT_TYPEzCONTENT-LENGTHCONTENT_LENGTHHTTP_r   _z%s,%szwsgi.url_schemerK   r   r   rL   :httpP   httpsi  SERVER_NAMESERVER_PORTz2Request path %r does not start with SCRIPT_NAME %r	PATH_INFOzwsgi.early_hintspriority_weightzgunicorn.http2.priority_weightz"gunicorn.http2.priority_depends_on)ResponserD   osenvironget_expected_100_continuesendrX   replaceschemerU   r2   rV   rW   splitlenr%   path
startswithr   r   unquote_to_wsgi_strr:   rQ   r_   r   rn   priority_depends_on)rA   rB   clientserverr(   r]   rq   hostscript_namehdr_name	hdr_valuer   	path_infor   r   r   create   sx   















r   c                   @   sv   e Zd Zdd Zdd Zdd Zd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 )ro   c                 C   sL   || _ || _t| _d | _d| _d| _g | _d| _d | _	d| _
d| _|| _d S )NFr   )rA   rB   r   r@   statuschunked
must_closerX   rT   response_lengthsentupgrader(   )r   rA   rB   r(   r   r   r   r     s   
zResponse.__init__c                 C   s
   d| _ d S )NT)r   r   r   r   r   force_close  s   
zResponse.force_closec                 C   sT   | j s| j r
dS | jd us| jrdS | jjdkrdS | jdk s&| jdv r(dS dS )NTFHEAD      i0  )r   rA   should_closer   r   r<   status_coder   r   r   r   r     s   zResponse.should_closeNc                 C   s   |rz| j r| jrt|d |d |d  W d }nd }w | j d ur&td|| _ zt| j  d | _W n tyA   d | _Y nw | 	| | 
 | _| jS )Nr   r      zResponse headers already set!)r   rT   r   reraiseAssertionErrorintrw   r   
ValueErrorprocess_headers
is_chunkedr   r*   )r   r   rX   exc_infor   r   r   start_response#  s"   



zResponse.start_responsec                 C   s   |D ]q\}}t |tstd| t|std| t |ts'td| t|s2td| |d}|	 }|dkrEt
|| _n&t|rk|dkrX|	 dkrWd| _n|dkrj|	 dkrj| j||f q| j||f qd S )	Nz%r is not a stringz%rz 	zcontent-length
connectionr   T	websocket)rU   r2   	TypeErrorr   	fullmatchr   HEADER_VALUE_REr   striplowerr   r   r   
is_hoppishr   rX   r%   )r   rX   rZ   r[   lnamer   r   r   r   ;  s0   





zResponse.process_headersc                 C   s@   | j d urdS | jjdkrdS | jjdkrdS | jdv rdS dS )NFr.   r   r   T)r   rA   r@   r<   r   r   r   r   r   r   [  s   

zResponse.is_chunkedc                 C   sl   | j rd}n	|  rd}nd}d| jjd | jjd | jf d| j dt  d	| g}| jr4|d
 |S )Nr   r   z
keep-alivezHTTP/%s.%s %s
r   r   zServer: %s
z
Date: %s
zConnection: %s
zTransfer-Encoding: chunked
)	r   r   rA   r@   r   r   	http_dater   r%   )r   r   rX   r   r   r   default_headersl  s   

zResponse.default_headersc                 C   sV   | j rd S |  }|dd | jD  dd| }t| jt|d d| _ d S )Nc                 S   s   g | ]
\}}d ||f qS )z%s: %s
r   )r3   kr4   r   r   r   r5     s    z)Response.send_headers.<locals>.<listcomp>z%s
ra   rR   T)	rT   r   extendrX   r?   r   r*   rB   to_bytestring)r   tosend
header_strr   r   r   send_headers  s   
zResponse.send_headersc                 C   s   |    t|tstd| t|}|}| jd ur5| j| jkr"d S t| j| j |}||k r5|d | }| jr>|dkr>d S |  j|7  _t	
| j|| j d S )Nz%r is not a byter   )r   rU   rV   r   rx   r   r   minr   r   r*   rB   )r   argarglenr   r   r   r   r*     s   

zResponse.writec                 C   s   | j jduS )NF)r(   sendfiler   r   r   r   can_sendfile  s   zResponse.can_sendfilec              	   C   s   | j js|  s
dS t|jsdS |j }zt|dtj	}| j
d u r0t|j}|| }n| j
}W n ttjfyA   Y dS w |   |  rWd| }| j|d |dkre| jj|j||d |  ro| jd t||tj dS )NFr   z%X
zutf-8)offsetcountrS   T)r(   is_sslr   r   
has_filenor   filenorp   lseekSEEK_CURr   fstatst_sizeOSErrorioUnsupportedOperationr   r   rB   sendallr,   r   SEEK_SET)r   respiterr   r   filesizenbytes
chunk_sizer   r   r   r     s2   


zResponse.sendfilec                 C   s&   |  |s|D ]	}| | qd S d S r   )r   r*   )r   r   itemr   r   r   
write_file  s
   
zResponse.write_filec                 C   s*   | j s|   | jrt| jd d S d S )N    )rT   r   r   r   write_chunkrB   r   r   r   r   r     s
   zResponse.closer   )r   r   r   r   r   r   r   r   r   r   r   r*   r   r   r   r   r   r   r   r   ro     s    
 
!ro   )r   r    rp   rer&   gunicorn.http.messager   gunicorn.http.errorsr   r   r   gunicornr   r   r   BLKSIZEcompiler   r!   r   logr	   	RawIOBaser   r0   rD   rQ   r_   r   ro   r   r   r   r   <module>   s(   

3d