
    AҐiI              	           d Z ddlZddlZ G d de      Z G d d      Zddeded	ed
e	fdZ
ddede	d
e	fdZdeded
e	fdZy)a  
Control Socket Protocol

JSON-based protocol with length-prefixed framing for the control interface.

Message Format:
    +----------------+------------------+
    | Length (4B BE) |  JSON Payload    |
    +----------------+------------------+

Request Format:
    {"id": 1, "command": "show", "args": ["workers"]}

Response Format:
    {"id": 1, "status": "ok", "data": {...}}
    {"id": 1, "status": "error", "error": "message"}
    Nc                       e Zd ZdZy)ProtocolErrorzProtocol-level error.N)__name__
__module____qualname____doc__     N/var/www/descvideos/venv/lib/python3.12/site-packages/gunicorn/ctl/protocol.pyr   r      s    r
   r   c                       e Zd ZdZdZededefd       Zededefd       Z	edefd       Z
edefd       Zedefd	       Zedefd
       Zy)ControlProtocolz
    Protocol implementation for control socket communication.

    Uses 4-byte big-endian length prefix followed by JSON payload.
    i   datareturnc                     t        j                  |       j                  d      }t        j                  dt        |            }||z   S )z
        Encode a message for transmission.

        Args:
            data: Dictionary to encode

        Returns:
            Length-prefixed JSON bytes
        utf-8>I)jsondumpsencodestructpacklen)r   payloadlengths      r   encode_messagezControlProtocol.encode_message)   s<     **T"))'2T3w<0r
   c                     t        |       dk  rt        d      t        j                  d| dd       d   }t        |       d|z   k  rt        d      | dd|z    }t	        j
                  |j                  d            S )z
        Decode a message from bytes.

        Args:
            data: Raw bytes (length prefix + JSON payload)

        Returns:
            Decoded dictionary
           zMessage too shortr   Nr   zIncomplete messager   )r   r   r   unpackr   loadsdecode)r   r   r   s      r   decode_messagezControlProtocol.decode_message8   sz     t9q= 344tT"1X.q1t9q6z! 455qV$zz'..122r
   c                 x   d}t        |      dk  rK| j                  dt        |      z
        }|s|st        d      t        d      ||z  }t        |      dk  rKt	        j
                  d|      d   }|t        j                  kD  rt        d|       d}t        |      |k  rH| j                  t        |t        |      z
  d            }|st        d	      ||z  }t        |      |k  rH	 t        j                  |j                  d
            S # t        j                  $ r}t        d|       d}~ww xY w)a  
        Read one message from a socket.

        Args:
            sock: Socket to read from

        Returns:
            Decoded message dictionary

        Raises:
            ProtocolError: If message is malformed
            ConnectionError: If connection is closed
        r
   r   zConnection closedzIncomplete length prefixr   r   Message too large: i   zIncomplete payloadr   Invalid JSON: N)r   recvConnectionErrorr   r   r   r   MAX_MESSAGE_SIZEminr   r   r    JSONDecodeError)socklength_datachunkr   payload_dataes         r   read_messagezControlProtocol.read_messageM   s?     +"IIa#k"223E")*=>>#$>??5 K +" t[1!4O444"5fX >?? ,&(IIc&3|+<"<eDEE#$899E!L	 ,&(	6::l11':;;## 	6. 455	6s   /#D D9&D44D9c                 P    t         j                  |      }| j                  |       y)z
        Write one message to a socket.

        Args:
            sock: Socket to write to
            data: Message dictionary to send
        N)r   r   sendall)r*   r   messages      r   write_messagezControlProtocol.write_messagex   s      "006Wr
   c                   K   | j                  d       d{   }t        j                  d|      d   }|t        j                  kD  rt        d|       | j                  |       d{   }	 t        j                  |j                  d            S 7 |7 +# t        j                  $ r}t        d|       d}~ww xY ww)z
        Read one message from an async reader.

        Args:
            reader: asyncio StreamReader

        Returns:
            Decoded message dictionary
        r   Nr   r   r#   r   r$   )
readexactlyr   r   r   r'   r   r   r   r    r)   )readerr+   r   r-   r.   s        r   read_message_asyncz"ControlProtocol.read_message_async   s      #..q11t[1!4O444"5fX >?? $//77	6::l11':;; 2 8 ## 	6. 455	6sF   CBAC*B+C0#B CCB>+B99B>>Cc                    K   t         j                  |      }| j                  |       | j                          d{    y7 w)z
        Write one message to an async writer.

        Args:
            writer: asyncio StreamWriter
            data: Message dictionary to send
        N)r   r   writedrain)writerr   r2   s      r   write_message_asyncz#ControlProtocol.write_message_async   s3      "006Wllns   :AAAN)r   r   r   r   r'   staticmethoddictbytesr   r!   r/   r3   r7   r<   r	   r
   r   r   r      s     ( T  e     3U 3t 3 3( (6d (6 (6T 	$ 	 	 6D 6 62 
 
 
r
   r   
request_idcommandargsr   c                     | ||xs g dS )z
    Create a request message.

    Args:
        request_id: Unique request identifier
        command: Command name (e.g., "show workers")
        args: Optional list of arguments

    Returns:
        Request dictionary
    )idrA   rB   r	   )r@   rA   rB   s      r   make_requestrE      s     
 r
   r   c                     | d|xs i dS )z
    Create a success response message.

    Args:
        request_id: Request identifier being responded to
        data: Response data

    Returns:
        Response dictionary
    ok)rD   statusr   r	   )r@   r   s     r   make_responserI      s     
 r
   errorc                     | d|dS )z
    Create an error response message.

    Args:
        request_id: Request identifier being responded to
        error: Error message

    Returns:
        Error response dictionary
    rJ   )rD   rH   rJ   r	   )r@   rJ   s     r   make_error_responserL      s      r
   )N)r   r   r   	Exceptionr   r   intstrlistr>   rE   rI   rL   r	   r
   r   <module>rQ      s   
$   I  J JZS 3 d d &c   $C   r
   