HEX
Server: LiteSpeed
System: Linux kapuas.iixcp.rumahweb.net 5.14.0-427.42.1.el9_4.x86_64 #1 SMP PREEMPT_DYNAMIC Fri Nov 1 14:58:02 EDT 2024 x86_64
User: mirz4654 (1666)
PHP: 8.1.33
Disabled: system,exec,escapeshellarg,escapeshellcmd,passthru,proc_close,proc_get_status,proc_nice,proc_open,proc_terminate,shell_exec,popen,pclose,dl,pfsockopen,leak,apache_child_terminate,posix_kill,posix_mkfifo,posix_setsid,posix_setuid,posix_setpgid,ini_alter,show_source,define_syslog_variables,symlink,syslog,openlog,openlog,closelog,ocinumcols,listen,chgrp,apache_note,apache_setenv,debugger_on,debugger_off,ftp_exec,dll,ftp,myshellexec,socket_bind,mail,posix_getwpuid
Upload Files
File: //lib/python3.9/site-packages/redis/__pycache__/connection.cpython-39.pyc
a

��b��
@s�ddlZddlZddlZddlZddlZddlZddlZddlmZddl	m
Z
mZmZddl
m
Z
ddlmZmZmZddlmZddlmZddlmZmZmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%dd	l&m'Z'dd
l(m)Z)m*Z*m+Z+zddl,Z,dZ-Wne.�ydZ-Yn0e/ej0iZ1e-�rZe2e,d
��rPde1e,j3<de1e,j4<n
de1e,j5<e6e1�7��Z8e*�r�ddl9Z9ee9j:�Z;e;ed�kZ<e;ed�kZ=e;ed�kZ>dZ?e=�s�dZ?dZ@dZAdZBdZCdZDeE�ZFdZGdZHdZIdZJGdd�d�ZKGdd�d�ZLGdd �d �ZMGd!d"�d"eL�ZNGd#d$�d$eL�ZOe*�r0eOZPneNZPGd%d&�d&�ZQGd'd(�d(eQ�ZRGd)d*�d*eQ�ZSd+ZTd,d-�ZUeVeWeWeUeUeXeVeVeUd.�	ZYd/d0�ZZGd1d2�d2�Z[Gd3d4�d4e[�Z\dS)5�N)�chain)�Empty�Full�	LifoQueue)�time)�parse_qs�unquote�urlparse)�Version)�	NoBackoff)�AuthenticationError�$AuthenticationWrongNumberOfArgsError�BusyLoadingError�ChildDeadlockedError�ConnectionError�	DataError�ExecAbortError�InvalidResponse�ModuleError�NoPermissionError�
NoScriptError�
ReadOnlyError�
RedisError�
ResponseError�TimeoutError)�Retry)�CRYPTOGRAPHY_AVAILABLE�HIREDIS_AVAILABLE�str_if_bytesTF�SSLWantReadError�z0.1.3z0.1.4z1.0.0�*�$s
�zConnection closed by server.z:Error loading the extension. Please check the server logs.z5Error unloading module: no such module with that namez/Error unloading module: operation not possible.z[Error unloading module: the module exports one or more module-side data types, can't unloadc@s*eZdZdZdd�Zdd�Zd
dd�Zd	S)�Encoderz=Encode strings to bytes-like and decode bytes-like to stringscCs||_||_||_dS�N��encoding�encoding_errors�decode_responses)�selfr'r(r)�r+�4/usr/lib/python3.9/site-packages/redis/connection.py�__init__XszEncoder.__init__cCs�t|ttf�r|St|t�r&td��n@t|ttf�rBt|���}n$t|t	�sft
|�j}td|�d���t|t	�r�|�|j|j
�}|S)z=Return a bytestring or bytes-like representation of the valuezNInvalid input of type: 'bool'. Convert to a bytes, string, int or float first.zInvalid input of type: 'z2'. Convert to a bytes, string, int or float first.)�
isinstance�bytes�
memoryview�boolr�int�float�repr�encode�str�type�__name__r'r()r*�value�typenamer+r+r,r5]s 
�


�
zEncoder.encodeFcCs:|js
|r6t|t�r|��}t|t�r6|�|j|j�}|S)z:Return a unicode string from the bytes-like representation)r)r.r0�tobytesr/�decoder'r()r*r9�forcer+r+r,r<ts


zEncoder.decodeN)F)r8�
__module__�__qualname__�__doc__r-r5r<r+r+r+r,r$Usr$c@sLeZdZdededededeeeeee	ee
ei	eee
eeed�Zdd�Zd	S)
�
BaseParserzmax number of clients reachedz(Client sent AUTH, but no password is setzinvalid passwordz,wrong number of arguments for 'auth' commandz,wrong number of arguments for 'AUTH' command)ZERRZ	EXECABORTZLOADINGZNOSCRIPTZREADONLYZNOAUTHZNOPERMcCs\|�d�d}||jvrT|t|�dd�}|j|}t|t�rL|�|t�}||�St|�S)zParse an error response� r�N)�split�EXCEPTION_CLASSES�lenr.�dict�getr)r*�responseZ
error_codeZexception_classr+r+r,�parse_error�s


zBaseParser.parse_errorN)r8r>r?rrr
�MODULE_LOAD_ERRORr�MODULE_EXPORTS_DATA_TYPES_ERROR�NO_SUCH_MODULE_ERROR� MODULE_UNLOAD_NOT_POSSIBLE_ERRORrrrrrrErJr+r+r+r,rA~s(��rAc@sXeZdZdd�Zedd��Zdedfdd�Zd	d
�Zdd�Z	d
d�Z
dd�Zdd�ZdS)�SocketBuffercCs,||_||_||_t��|_d|_d|_dS�Nr)�_sock�socket_read_size�socket_timeout�io�BytesIO�_buffer�
bytes_written�
bytes_read)r*�socketrRrSr+r+r,r-�s
zSocketBuffer.__init__cCs|j|jSr%)rWrX�r*r+r+r,�length�szSocketBuffer.lengthNTc

Cs�|j}|j}|j}|�|j�d}|tu}�zLz�|r>|�|�|j�|�}	t|	t	�rht
|	�dkrhtt��|�
|	�t
|	�}
|j|
7_||
7}|dur�||kr�q>WW|r�|�|j�dStjy�|r�td��YW|r�|�|j�dSt�yb}z^t�|jd�}|�s>|j|k�r>WYd}~W|�r:|�|j�dStd|j����WYd}~n
d}~00W|�r�|�|j�n|�r�|�|j�0dS�NrTzTimeout reading from socketF���z!Error while reading from socket: )rQrRrV�seekrW�SENTINEL�
settimeout�recvr.r/rFr�SERVER_CLOSED_CONNECTION_ERROR�writerSrY�timeoutr�NONBLOCKING_EXCEPTIONS�#NONBLOCKING_EXCEPTION_ERROR_NUMBERSrH�	__class__�errno�args)
r*r[rd�raise_on_timeout�sockrR�bufZmarker�custom_timeout�dataZdata_length�ex�allowedr+r+r,�_read_from_socket�sR

���(�zSocketBuffer._read_from_socketcCst|j�p|j|dd�S)NF�rdrj)r1r[rq�r*rdr+r+r,�can_read�s�zSocketBuffer.can_readcCsn|d}||jkr"|�||j�|j�|j�|j�|�}|jt|�7_|j|jkrb|��|dd�S)Nr ���)	r[rqrVr^rX�readrFrW�purge)r*r[rnr+r+r,rv�s
zSocketBuffer.readcCst|j}|�|j�|��}|�t�sB|��|�|j�|��}q|jt|�7_|j|jkrh|�	�|dd�S)Nru)
rVr^rX�readline�endswith�SYM_CRLFrqrFrWrw)r*rlrnr+r+r,rx�s

zSocketBuffer.readlinecCs&|j�d�|j��d|_d|_dSrP)rVr^�truncaterWrXrZr+r+r,rws
zSocketBuffer.purgecCs:z|��|j��Wnty(Yn0d|_d|_dSr%)rwrV�close�	ExceptionrQrZr+r+r,r|szSocketBuffer.close)
r8r>r?r-�propertyr[r_rqrtrvrxrwr|r+r+r+r,rO�s

)rOc@sBeZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
d�Z	dS)�PythonParserzPlain Python parsing classcCs||_d|_d|_d|_dSr%)rR�encoderrQrV�r*rRr+r+r,r-szPythonParser.__init__cCs$z|��WntyYn0dSr%��
on_disconnectr}rZr+r+r,�__del__$szPythonParser.__del__cCs(|j|_t|j|j|j�|_|j|_dS)zCalled when the socket connectsN)rQrOrRrSrVr��r*�
connectionr+r+r,�
on_connect*s
�zPythonParser.on_connectcCs*d|_|jdur |j��d|_d|_dS)z"Called when the socket disconnectsN)rQrVr|r�rZr+r+r,r�2s


zPythonParser.on_disconnectcCs|jo|j�|�Sr%)rVrtrsr+r+r,rt:szPythonParser.can_readFcs�j��}|stt��|dd�|dd�}}|dvrFtd|����|dkrx|jddd�}��|�}t|t�rt|�|S|dkr�np|d	kr�t|�}n^|d
kr�t|�}|dkr�dS�j�	|�}n4|dkr�t|�}|dkr�dS��fd
d�t
|�D�}t|t��r�du�r�j�|�}|S)NrC)�-�+�:r"r!zProtocol Error: r��utf-8�replace)�errorsr�r�r"r]r!csg|]}�j�d��qS)��disable_decoding)�
read_response)�.0�i�r�r*r+r,�
<listcomp>es�z.PythonParser.read_response.<locals>.<listcomp>F)
rVrxrrbrr<rJr.r2rv�ranger/r�)r*r��rawZbyterI�errorr[r+r�r,r�=s>



�zPythonParser.read_responseN)F)
r8r>r?r@r-r�r�r�rtr�r+r+r+r,rsrc@sPeZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Ze	dfd
d�Z
ddd�ZdS)�
HiredisParserz*Parser class for connections using HirediscCs$tstd��||_tr t|�|_dS)NzHiredis is not installed)rrrR�HIREDIS_USE_BYTE_BUFFER�	bytearrayrVr�r+r+r,r-qs
zHiredisParser.__init__cCs$z|��WntyYn0dSr%r�rZr+r+r,r�yszHiredisParser.__del__cKsh|j|_|j|_t|jd�}ts(t|d<|jjr<|jj	|d<t
rL|jj|d<tj
fi|��|_d|_dS)N)Z
protocolError�
replyErrorr�r'r�F)rQrS�_socket_timeoutrrJ� HIREDIS_SUPPORTS_CALLABLE_ERRORSrr�r)r'� HIREDIS_SUPPORTS_ENCODING_ERRORSr(�hiredis�Reader�_reader�_next_response)r*r��kwargsr+r+r,r�szHiredisParser.on_connectcCsd|_d|_d|_dS)NF)rQr�r�rZr+r+r,r��szHiredisParser.on_disconnectcCs@|jstt��|jdur<|j��|_|jdur<|j|dd�SdS)NFrrT)r�rrbr��gets�read_from_socketrsr+r+r,rt�s

zHiredisParser.can_readTc	
Cs�|j}|tu}�zVz�|r"|�|�trX|j�|j�}|dkrDtt��|j�	|jd|�n8|j�
|j�}t|t
�r|t|�dkr�tt��|j�	|�WW|r�|�|j�dStjy�|r�td��YW|r�|�|j�dSt�yP}z^t�|jd�}|�s,|j|k�r,WYd}~W|�r(|�|j�dStd|j����WYd}~n
d}~00W|�r||�|j�n|�rz|�|j�0dSr\)rQr_r`r�Z	recv_intorVrrbr�ZfeedrarRr.r/rFr�rYrdrrerfrHrgrhri)	r*rdrjrkrmZbufflen�bufferrorpr+r+r,r��sJ
���(�zHiredisParser.read_from_socketFcCs�|jstt��|jdur(|j}d|_|S|r:|j�d�}n
|j��}|durr|��|rf|j�d�}qD|j��}qDts�t|t�r�|�	|j
d�}n4t|t�r�|r�t|dt�r�|�	|dj
d�|d<t|t�r�|�n$t|t�r�|r�t|dt�r�|d�|S)NFr)r�rrbr�r�r�r�r.rrJri�list)r*r�rIr+r+r,r��sD


���
���zHiredisParser.read_responseN)F)r8r>r?r@r-r�r�r�rtr_r�r�r+r+r+r,r�ns
%r�c@s�eZdZdZddddddddddgddded	dddddfd
d�Zdd
�Zdd�Zdd�Zdd�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zd d!�Zd"d#�Zd$d%�Zd&d'�Zd5d)d*�Zd+d,�Zd6d-d.�Zd7d/d0�Zd1d2�Zd3d4�ZdS)8�
Connectionz4Manages TCP communication to and from a Redis serverZ	localhosti�rNFr��strict�cCs�t��|_||_t|�|_||_||_||_||_	||_
|p>||_||_|pNi|_
|	|_|
|_|
rl|�t�||_|r�|dur�tt�d�|_nt�|�|_|j�|�ntt�d�|_||_d|_||_t||
|�|_d|_||_|� |�g|_!d|_"dS)a2
        Initialize a new Connection.
        To specify a retry policy for specific errors, first set
        `retry_on_error` to a list of the error/s to retry on, then set
        `retry` to a valid `Retry` object.
        To retry on TimeoutError, `retry_on_timeout` can also be set to `True`.
        NrCr�p)#�os�getpid�pid�hostr2�port�db�username�client_name�passwordrS�socket_connect_timeout�socket_keepalive�socket_keepalive_options�socket_type�retry_on_timeout�appendr�retry_on_errorrr�retry�copy�deepcopy�update_supported_errors�health_check_interval�next_health_check�redis_connect_funcr$r�rQ�_socket_read_size�
set_parser�_connect_callbacks�_buffer_cutoff)r*r�r�r�r�rSr�r�r�r�r�r�r'r(r)�parser_classrRr�r�r�r�r�r+r+r,r-�s>





zConnection.__init__cCs,d�dd�|��D��}|jj�d|�d�S)N�,cSsg|]\}}|�d|���qS)�=r+)r��k�vr+r+r,r�?r#z'Connection.__repr__.<locals>.<listcomp>�<�>)�join�repr_piecesrgr8)r*Z	repr_argsr+r+r,�__repr__>szConnection.__repr__cCs6d|jfd|jfd|jfg}|jr2|�d|jf�|S)Nr�r�r�r�)r�r�r�r�r��r*�piecesr+r+r,r�BszConnection.repr_piecescCs$z|��WntyYn0dSr%)�
disconnectr}rZr+r+r,r�HszConnection.__del__cCs|j�t�|��dSr%)r�r��weakref�
WeakMethod)r*�callbackr+r+r,�register_connect_callbackNsz$Connection.register_connect_callbackcCs
g|_dSr%)r�rZr+r+r,�clear_connect_callbacksQsz"Connection.clear_connect_callbackscCs||jd�|_dS)z�
        Creates a new instance of parser_class with socket size:
        _socket_read_size and assigns it to the parser for the connection
        :param parser_class: The required parser class
        )rRN)r��_parser)r*r�r+r+r,r�TszConnection.set_parserc
s��jr
dSz"�j��fdd��fdd��}WnLtjyHtd��Yn2tyx}zt��|���WYd}~n
d}~00|�_z"�j	dur���
�n
��	��Wnty�����Yn0�j
D]}|�}|r�|��q�dS)z5Connects to the Redis server if not already connectedNcs���Sr%)�_connectr+rZr+r,�<lambda>br#z$Connection.connect.<locals>.<lambda>cs
��|�Sr%�r�)r�rZr+r,r�br#zTimeout connecting to server)rQr��call_with_retryrYrdr�OSErrorr�_error_messager�r�rr�r�)r*rk�e�refr�r+rZr,�connect\s,�$


zConnection.connectcCsd}t�|j|j|jtj�D]�}|\}}}}}d}z�t�|||�}|�tjtjd�|j	r�|�tj
tjd�|j�
�D]\}	}
|�tj|	|
�qv|�|j�|�|�|�|j�|WSty�}z |}|dur�|��WYd}~qd}~00q|du�r|�td��dS)zCreate a TCP socket connectionNrCz)socket.getaddrinfo returned an empty list)rYZgetaddrinfor�r�r��SOCK_STREAMZ
setsockoptZIPPROTO_TCPZTCP_NODELAYr�Z
SOL_SOCKETZSO_KEEPALIVEr��itemsr`r�r�rSr�r|)r*�err�resZfamilyZsocktype�protoZ	canonnameZsocket_addressrkr�r��_r+r+r,r�}s0�

 
zConnection._connectc	Cs�t|j�dkrXz$d|j�d|j�d|jd�d�WStyTd|jd��YS0nTz0d|jd�d	|j�d|j�d
|jd�d�	WSty�d|jd��YS0dS)NrCzError connecting to �:z.                         r�.zConnection Error: �Error z connecting to �. )rFrir�r��AttributeError�r*�	exceptionr+r+r,r��s$�
����zConnection._error_messagecCs�|j�|�|js|jr�|jr0|j|jp*df}n|jf}|jdg|�Rddi�z|��}Wn,ty�|jd|jdd�|��}Yn0t|�dkr�td��|j	r�|�dd	|j	�t|���dkr�t
d
��|jr�|�d|j�t|���dkr�t
d��d
S)z=Initialize the connection, authenticate and select a database�ZAUTH�check_healthF�r�ZOKzInvalid Username or PasswordZCLIENTZSETNAMEzError setting client nameZSELECTzInvalid DatabaseN)r�r�r�r��send_commandr�r
rrr�rr�)r*Z	auth_argsZ
auth_responser+r+r,r��s*zConnection.on_connectcGsx|j��|jdurdSt��|jkrLz|j�tj�Wnt	yJYn0z|j�
�Wnt	ylYn0d|_dS)z!Disconnects from the Redis serverN)r�r�rQr�r�r��shutdownrYZ	SHUT_RDWRr�r|)r*rir+r+r,r��s

zConnection.disconnectcCs*|jddd�t|���dkr&td��dS)z Send PING, expect PONG in returnZPINGFr�ZPONGz#Bad response from PING health checkN)r�rr�rrZr+r+r,�
_send_ping�szConnection._send_pingcCs|��dS)z Function to call when PING failsNr�)r*r�r+r+r,�_ping_failed�szConnection._ping_failedcCs(|jr$t�|jkr$|j�|j|j�dS)z3Check the health of the connection with a PING/PONGN)r�rr�r�r�r�r�rZr+r+r,r��szConnection.check_healthTc
Cs�|js|��|r|��z*t|t�r,|g}|D]}|j�|�q0Wn�tjyh|��t	d��Yn�t
y�}z^|��t|j�dkr�d|jd}}n|jd}|jd}t
d|�d|�d���WYd}~n$d}~0ty�|���Yn0dS)	z2Send an already packed command to the Redis serverzTimeout writing to socketrCZUNKNOWNrr�z while writing to socket. r�N)rQr�r�r.r6ZsendallrYrdr�rr�rFrir�
BaseException)r*Zcommandr��itemr�rh�errmsgr+r+r,�send_packed_commands,


*zConnection.send_packed_commandcOs |j|j|�|�dd�d�dS)z+Pack and send a command to the Redis serverr�Tr�N)r��pack_commandrH)r*rir�r+r+r,r�s�zConnection.send_commandc
Csr|j}|s|��z|j�|�WStyl}z4|��td|j�d|j�d|j	����WYd}~n
d}~00dS)z8Poll the socket to see if there's data that can be read.�Error while reading from r�z: N)
rQr�r�rtr�r�rr�r�ri)r*rdrkr�r+r+r,rt!s�zConnection.can_readc
Cs�z|j�d|j��}Wnty,d}Yn0z|jj|d�}Wn�tjyj|��td|����Yn\t	y�}z*|��t
d|�d|j����WYd}~n$d}~0ty�|���Yn0|j
r�t�|j
|_t|t�r�|�|S)z0Read the response from a previously sent commandr�r�r�zTimeout reading from r�z : N)r�r�r�r�r�rYrdr�rr�rrir�r�rr�r.r)r*r�ZhosterrrIr�r+r+r,r�.s(
*
zConnection.read_responsec	Gsg}t|dt�r4t|d�����|dd�}n(d|dvr\t|d���|dd�}t�ttt|����t	f�}|j
}t|jj|�D]|}t|�}t|�|ks�||ks�t|t
�r�t�|tt|���t	f�}|�|�|�|�t	}q�t�|tt|���t	|t	f�}q�|�|�|S)z2Pack a series of arguments into the Redis protocolrrCN� )r.r6�tupler5rD�	SYM_EMPTYr��SYM_STARrFrzr��mapr�r0�
SYM_DOLLARr�)r*ri�outputZbuff�
buffer_cutoff�argZ
arg_lengthr+r+r,r�Hs@"
����


��

zConnection.pack_commandc	Cs�g}g}d}|j}|D]~}|j|�D]n}t|�}||ksJ||ksJt|t�rb|�t�|��d}g}||kstt|t�r�|�|�q$|�|�||7}q$q|r�|�t�|��|S)z.Pack multiple commands into the Redis protocolr)r�r�rFr.r0r�r�r�)	r*Zcommandsrr�Z
buffer_lengthr�cmd�chunkZchunklenr+r+r,�
pack_commandsus.���
zConnection.pack_commands)T)r)F)r8r>r?r@�
DefaultParserr-r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rtr�r�rr+r+r+r,r��sV�
D!)'


-r�cs.eZdZdZd	�fdd�	Z�fdd�Z�ZS)
�
SSLConnectionz�Manages SSL connections to and from the Redis server(s).
    This class extends the Connection class, adding SSL functionality, and making
    use of ssl.SSLContext (https://docs.python.org/3/library/ssl.html#ssl.SSLContext)
    N�requiredFc
s�tstd��t�jfi|
��||_||_|dur:tj}n:t|t	�rttjtj
tjd�}||vrltd|����||}||_||_
||_||_||_||_|	|_|
|_||_||_dS)aeConstructor

        Args:
            ssl_keyfile: Path to an ssl private key. Defaults to None.
            ssl_certfile: Path to an ssl certificate. Defaults to None.
            ssl_cert_reqs: The string value for the SSLContext.verify_mode (none, optional, required). Defaults to "required".
            ssl_ca_certs: The path to a file of concatenated CA certificates in PEM format. Defaults to None.
            ssl_ca_data: Either an ASCII string of one or more PEM-encoded certificates or a bytes-like object of DER-encoded certificates.
            ssl_check_hostname: If set, match the hostname during the SSL handshake. Defaults to False.
            ssl_ca_path: The path to a directory containing several CA certificates in PEM format. Defaults to None.
            ssl_password: Password for unlocking an encrypted private key. Defaults to None.

            ssl_validate_ocsp: If set, perform a full ocsp validation (i.e not a stapled verification)
            ssl_validate_ocsp_stapled: If set, perform a validation on a stapled ocsp response
            ssl_ocsp_context: A fully initialized OpenSSL.SSL.Context object to be used in verifying the ssl_ocsp_expected_cert
            ssl_ocsp_expected_cert: A PEM armoured string containing the expected certificate to be returned from the ocsp verification service.

        Raises:
            RedisError
        z$Python wasn't built with SSL supportN)ZnoneZoptionalrz+Invalid SSL Certificate Requirements Flag: )�
ssl_availabler�superr-�keyfile�certfile�sslZ	CERT_NONEr.r6Z
CERT_OPTIONALZ
CERT_REQUIRED�	cert_reqs�ca_certs�ca_data�ca_path�check_hostname�certificate_password�ssl_validate_ocsp�ssl_validate_ocsp_stapled�ssl_ocsp_context�ssl_ocsp_expected_cert)r*Zssl_keyfileZssl_certfileZ
ssl_cert_reqsZssl_ca_certsZssl_ca_data�ssl_check_hostnameZssl_ca_pathZssl_passwordrrrrr�Z	CERT_REQS�rgr+r,r-�s6$
��zSSLConnection.__init__c
s�t���}t��}|j|_|j|_|js.|jrD|j	|j|j|j
d�|jdusb|jdusb|j
durx|j|j|j|j
d�|j||jd�}|jdur�tdur�td��|jr�|jr�td��|j�r\d	dl}d
dlm}|jdu�r|j�|jj�}|�|j�|�|j�n|j}|�||j�|j� |t!�!��}|�"�|�#|j|j$f�|�%�|�&�|S|jdu�r�t�r�d
dlm'}|||j|j$|j�}	|	�(��r�|St)d
��|S)z Wrap the socket with SSL support)rrr�N)ZcafileZcapathZcadata)Zserver_hostnameTFzcryptography is not installed.zKEither an OCSP staple or pure OCSP connection must be validated - not both.rrC)�ocsp_staple_verifier)�OCSPVerifierzocsp validation error)*r
r�rZcreate_default_contextrrZverify_moderrZload_cert_chainrrrrZload_verify_locationsZwrap_socketr�rrrr�OpenSSLZocsprrZSSLZContextZ
SSLv23_METHODZuse_certificate_fileZuse_privatekey_fileZset_ocsp_client_callbackrr�rYZrequest_ocspr�r�Zdo_handshaker�rZis_validr)
r*rk�contextZsslsockrrZ
staple_ctxZconr�orr+r,r��sd
�������
zSSLConnection._connect)NNrNNFNNFFNN)r8r>r?r@r-r��
__classcell__r+r+rr,r
�s�Cr
c@sNeZdZdddddddddgedddddfdd	�Zd
d�Zdd
�Zdd�ZdS)�UnixDomainSocketConnectionr�rNr�r�Fr�cCs�t��|_||_||_||_||_||_||_|	|_	|	rB|
�
t�|
|_|jr�|durft
t�d�|_nt�|�|_|j�|
�nt
t�d�|_|
|_d|_||_t|||�|_d|_||_|�|�g|_d|_dS)aB
        Initialize a new UnixDomainSocketConnection.
        To specify a retry policy for specific errors, first set
        `retry_on_error` to a list of the error/s to retry on, then set
        `retry` to a valid `Retry` object.
        To retry on TimeoutError, `retry_on_timeout` can also be set to `True`.
        NrCrr�)r�r�r��pathr�r�r�r�rSr�r�rr�rrr�r�r�r�r�r�r�r$r�rQr�r�r�r�)r*r$r�r�r�rSr'r(r)r�r�r�rRr�r�r�r�r+r+r,r-!s4


z#UnixDomainSocketConnection.__init__cCs.d|jfd|jfg}|jr*|�d|jf�|S)Nr$r�r�)r$r�r�r�r�r+r+r,r�[sz&UnixDomainSocketConnection.repr_piecescCs,t�tjtj�}|�|j�|�|j�|S)z&Create a Unix domain socket connection)rYZAF_UNIXr�r`rSr�r$)r*rkr+r+r,r�asz#UnixDomainSocketConnection._connectcCsRt|j�dkr(d|j�d|jd�d�Sd|jd�d|j�d|jd�d�SdS)NrCz!Error connecting to unix socket: r�rr�r�z connecting to unix socket: )rFrir$r�r+r+r,r�hs���z)UnixDomainSocketConnection._error_message)r8r>r?r	r-r�r�r�r+r+r+r,r# s(�
:r#)�0�FZFALSE�NZNOcCs6|dus|dkrdSt|t�r.|��tvr.dSt|�S)Nr�F)r.r6�upper�
FALSE_STRINGSr1)r9r+r+r,�to_boolws
r*)	r�rSr�r�r�r��max_connectionsr�rc
Cs�t|�}i}t|j���D]t\}}|rt|�dkrt|d�}t�|�}|r�z||�||<Wq�tt	fy�t	d|�d���Yq�0q|||<q|j
r�t|j
�|d<|jr�t|j�|d<|jdkr�|j
r�t|j
�|d<t|d<n�|jd	v�rx|j�rt|j�|d
<|j�rt|j�|d<|j
�rbd|v�rbztt|j
��d
d��|d<Wntt	f�y`Yn0|jdk�r�t|d<nt	d��|S)NrzInvalid value for `z` in connection URL.r�r�Zunixr$�connection_class)Zredis�redissr�r�r��/r�r-zRRedis URL must specify one of the following schemes (redis://, rediss://, unix://))r	r�queryr�rFr�URL_QUERY_ARGUMENT_PARSERSrH�	TypeError�
ValueErrorr�r��schemer$r#�hostnamer�r2r�r�r
)�urlr��namer9�parserr+r+r,�	parse_url�sH




�r8c@steZdZdZedd��Zedfdd�Zdd�Zd	d
�Z	dd�Z
d
d�Zdd�Zdd�Z
dd�Zdd�Zddd�ZdS)�ConnectionPoola�
    Create a connection pool. ``If max_connections`` is set, then this
    object raises :py:class:`~redis.exceptions.ConnectionError` when the pool's
    limit is reached.

    By default, TCP connections are created unless ``connection_class``
    is specified. Use class:`.UnixDomainSocketConnection` for
    unix sockets.

    Any additional keyword arguments are passed to the constructor of
    ``connection_class``.
    cKs4t|�}d|vr|d|d<|�|�|fi|��S)a
        Return a connection pool configured from the given URL.

        For example::

            redis://[[username]:[password]]@localhost:6379/0
            rediss://[[username]:[password]]@localhost:6379/0
            unix://[[username]:[password]]@/path/to/socket.sock?db=0

        Three URL schemes are supported:

        - `redis://` creates a TCP socket connection. See more at:
          <https://www.iana.org/assignments/uri-schemes/prov/redis>
        - `rediss://` creates a SSL wrapped TCP socket connection. See more at:
          <https://www.iana.org/assignments/uri-schemes/prov/rediss>
        - ``unix://``: creates a Unix Domain Socket connection.

        The username, password, hostname, path and all querystring values
        are passed through urllib.parse.unquote in order to replace any
        percent-encoded values with their corresponding characters.

        There are several ways to specify a database number. The first value
        found will be used:

            1. A ``db`` querystring option, e.g. redis://localhost?db=0
            2. If using the redis:// or rediss:// schemes, the path argument
               of the url, e.g. redis://localhost/0
            3. A ``db`` keyword argument to this function.

        If none of these options are specified, the default db=0 is used.

        All querystring options are cast to their appropriate Python types.
        Boolean arguments can be specified with string values "True"/"False"
        or "Yes"/"No". Values that cannot be properly cast cause a
        ``ValueError`` to be raised. Once parsed, the querystring arguments
        and keyword arguments are passed to the ``ConnectionPool``'s
        class initializer. In the case of conflicting arguments, querystring
        arguments always win.
        r,)r8�update)�clsr5r�Zurl_optionsr+r+r,�from_url�s
)
zConnectionPool.from_urlNcKsJ|pd}t|t�r|dkr"td��||_||_||_t��|_|�	�dS)Nlrz,"max_connections" must be a positive integer)
r.r2r2r,�connection_kwargsr+�	threading�Lock�
_fork_lock�reset)r*r,r+r=r+r+r,r-�s

zConnectionPool.__init__cCs(t|�j�dt|jfi|j����d�S)Nr�r�)r7r8r4r,r=rZr+r+r,r�s��zConnectionPool.__repr__cCs,t��|_d|_g|_t�|_t��|_	dSrP)
r>r?�_lock�_created_connections�_available_connections�set�_in_use_connectionsr�r�r�rZr+r+r,rAs

zConnectionPool.resetcCsZ|jt��krV|jjdd�}|s$t�z$|jt��kr<|��W|j��n|j��0dS)N�)rd)r�r�r�r@�acquirerrA�release)r*Zacquiredr+r+r,�	_checkpid,s#
zConnectionPool._checkpidc	Os�|��|j�Fz|j��}Wnty8|��}Yn0|j�|�Wd�n1sZ0YzX|��z|�	�r�t
d��Wn6t
tfy�|��|��|�	�r�t
d��Yn0Wnt
y�|�|��Yn0|S)zGet a connection from the poolN�Connection has data�Connection not ready)rJrBrD�pop�
IndexError�make_connectionrF�addr�rtrr�r�r�rI�r*Zcommand_name�keys�optionsr�r+r+r,�get_connection[s**
zConnectionPool.get_connectioncCs,|j}t|�dd�|�dd�|�dd�d�S)z,Return an encoder based on encoding settingsr'r�r(r�r)Fr&)r=r$rH)r*r�r+r+r,�get_encoder|s


�zConnectionPool.get_encodercCs4|j|jkrtd��|jd7_|jfi|j��S)zCreate a new connectionzToo many connectionsrC)rCr+rr,r=rZr+r+r,rO�szConnectionPool.make_connectionc	Cs�|��|j�rz|j�|�Wnty2Yn0|�|�rL|j�|�n&|jd8_|�	�Wd�dSWd�n1s�0YdS)z(Releases the connection back to the poolrCN)
rJrBrF�remove�KeyError�owns_connectionrDr�rCr�r�r+r+r,rI�s
zConnectionPool.releasecCs|j|jkSr%)r�r�r+r+r,rX�szConnectionPool.owns_connectionTcCs^|��|j�<|r$t|j|j�}n|j}|D]}|��q.Wd�n1sP0YdS)z�
        Disconnects connections in the pool

        If ``inuse_connections`` is True, disconnect connections that are
        current in use, potentially by other threads. Otherwise only disconnect
        connections that are idle in the pool.
        N)rJrBrrDrFr�)r*Zinuse_connectionsZconnectionsr�r+r+r,r��s�zConnectionPool.disconnect)T)r8r>r?r@�classmethodr<r�r-r�rArJrTrUrOrIrXr�r+r+r+r,r9�s

1�
/!	r9csReZdZdZddeef�fdd�	Zdd�Zdd	�Zd
d�Z	dd
�Z
dd�Z�ZS)�BlockingConnectionPoola
    Thread-safe blocking connection pool::

        >>> from redis.client import Redis
        >>> client = Redis(connection_pool=BlockingConnectionPool())

    It performs the same function as the default
    :py:class:`~redis.ConnectionPool` implementation, in that,
    it maintains a pool of reusable connections that can be shared by
    multiple redis clients (safely across threads if required).

    The difference is that, in the event that a client tries to get a
    connection from the pool when all of connections are in use, rather than
    raising a :py:class:`~redis.ConnectionError` (as the default
    :py:class:`~redis.ConnectionPool` implementation does), it
    makes the client wait ("blocks") for a specified number of seconds until
    a connection becomes available.

    Use ``max_connections`` to increase / decrease the pool size::

        >>> pool = BlockingConnectionPool(max_connections=10)

    Use ``timeout`` to tell it either how many seconds to wait for a connection
    to become available, or to block forever:

        >>> # Block forever.
        >>> pool = BlockingConnectionPool(timeout=None)

        >>> # Raise a ``ConnectionError`` after five seconds if a connection is
        >>> # not available.
        >>> pool = BlockingConnectionPool(timeout=5)
    �2�cs(||_||_t�jf||d�|��dS)N)r,r+)�queue_classrdr
r-)r*r+rdr,r]r=rr+r,r-�s	��zBlockingConnectionPool.__init__cCsL|�|j�|_z|j�d�Wqty4Yq8Yq0qg|_t��|_dSr%)	r]r+�pool�
put_nowaitr�_connectionsr�r�r�rZr+r+r,rA�szBlockingConnectionPool.resetcCs"|jfi|j��}|j�|�|S)zMake a fresh connection.)r,r=r`r�r�r+r+r,rOsz&BlockingConnectionPool.make_connectionc	Os�|��d}z|jjd|jd�}Wnty<td��Yn0|durN|��}zX|��z|��rjtd��Wn6tt	fy�|�
�|��|��r�td��Yn0Wnty�|�|��Yn0|S)a7
        Get a connection, blocking for ``self.timeout`` until a connection
        is available from the pool.

        If the connection returned is ``None`` then creates a new connection.
        Because we use a last-in first-out queue, the existing connections
        (having been returned to the pool after the initial ``None`` values
        were added) will be returned before ``None`` values. This means we only
        create new connections when we need to, i.e.: the actual number of
        connections will only increase in response to demand.
        NT)�blockrdzNo connection available.rKrL)
rJr^rHrdrrrOr�rtr�r�r�rIrQr+r+r,rT
s,

z%BlockingConnectionPool.get_connectioncCsR|��|�|�s*|��|j�d�dSz|j�|�WntyLYn0dS)z)Releases the connection back to the pool.N)rJrXr�r^r_rr�r+r+r,rI>s
zBlockingConnectionPool.releasecCs |��|jD]}|��qdS)z(Disconnects all connections in the pool.N)rJr`r�r�r+r+r,r�Ss
z!BlockingConnectionPool.disconnect)
r8r>r?r@r�rr-rArOrTrIr�r"r+r+rr,rZ�s#�4rZ)]r�rhrTr�rYr>r��	itertoolsrZqueuerrrr�urllib.parserrr	Zpackaging.versionr
Z
redis.backoffrZredis.exceptionsrr
rrrrrrrrrrrrrZredis.retryrZredis.utilsrrrrr�ImportError�BlockingIOErrorZEWOULDBLOCKrf�hasattrrZSSLWantWriteErrorZSSLErrorr�rRrer��__version__Zhiredis_versionr�ZHIREDIS_SUPPORTS_BYTE_BUFFERr�r�rrrzr�rb�objectr_rKrMrNrLr$rArOrr�r	r�r
r#r)r*r2r3r�r0r8r9rZr+r+r+r,�<module>s�D




�)'vST	�
4z