
FTc           @   s8  d  Z  d Z d 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 Z d d l Z y" d d l Z d d l Z e Z Wn/ e k
 r d d l Z d d l Z e Z n Xe e
 d  s d e
 _ n  d g Z d Z d	 Z d Z d Z d
 Z d Z d Z d Z d Z  d Z! d	 Z" d Z# d Z$ d Z% e% Z& d Z' d Z( d Z) d
 Z* d Z+ d Z, d Z- d
 Z. d Z/ d Z0 d Z1 d Z2 d Z3 d Z4 d Z5 d Z6 e j7 e5  Z8 e j7 e6  Z9 d d l: Z: d Z; d Z< d   Z= d e> f d     YZ? d e? f d     YZ@ d  e> f d!     YZA d" e> f d#     YZB d$ e> f d%     YZC d d&  ZD d'   ZE d( e> f d)     YZF d* e> f d+     YZG d, eG f d-     YZH d. e> f d/     YZI d0 eI f d1     YZJ d2 e> f d3     YZK d eK f d4     YZL eM d5 k r4d6   ZN eL eN  jO   n  d S(7   s  
fcgi - a FastCGI/WSGI gateway.

For more information about FastCGI, see <http://www.fastcgi.com/>.

For more information about the Web Server Gateway Interface, see
<http://www.python.org/peps/pep-0333.html>.

Example usage:

  #!/usr/bin/env python
  from myapplication import app # Assume app is your WSGI application object
  from fcgi import WSGIServer
  WSGIServer(app).run()

See the documentation for WSGIServer/Server for more information.

On most platforms, fcgi will fallback to regular CGI behavior if run in a
non-FastCGI context. If you want to force CGI behavior, set the environment
variable FCGI_FORCE_CGI to "Y" or "y".
s   Allan Saddi <allan@saddi.com>s
   $Revision$iNt   SHUT_WRi   t
   WSGIServeri    i   i   i   i   i   i   i   i	   i
   i   t   FCGI_MAX_CONNSt   FCGI_MAX_REQSt   FCGI_MPXS_CONNSs   !BBHHBxs   !HB5xs   !LB3xs   !B7xs   /tmp/fcgi.logc         C   s_   t  |  k  r d  SyA t t d  } | j d t j   d d !| f  | j   Wn n Xd  S(   Nt   as   %sfcgi: %s
i   i(   t   DEBUGt   opent   DEBUGLOGt   writet   timet   ctimet   close(   t   levelt   msgt   f(    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt   _debug   s    $t   InputStreamc           B   sh   e  Z d  Z d   Z d   Z d   Z d d  Z d d  Z d d  Z	 d	   Z
 d
   Z d   Z RS(   s   
    File-like object representing FastCGI input streams (FCGI_STDIN and
    FCGI_DATA). Supports the minimum methods required by WSGI spec.
    c         C   sI   | |  _  | j j |  _ d |  _ g  |  _ d |  _ d |  _ t |  _	 d  S(   Nt    i    (
   t   _connt   servert   inputStreamShrinkThresholdt   _shrinkThresholdt   _buft   _bufListt   _post   _availt   Falset   _eof(   t   selft   conn(    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt   __init__   s    					c         C   s\   |  j  |  j k rX |  j |  j  |  _ |  j |  j  8_ d |  _  |  j d k sX t  n  d S(   s6   Gets rid of already read data (since we can't rewind).i    N(   R   R   R   R   t   AssertionError(   R   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt   _shrinkBuffer   s
    	c         C   s   |  j  j   d S(   s(   Waits for more data to become available.N(   R   t   process_input(   R   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt   _waitForData   s    ic         C   s   |  j  |  j k r |  j r d Sx` t r | d k  sJ |  j |  j  | k  rp |  j r` |  j } Pq~ |  j   q" q" |  j  | } Pq" W|  j r |  j d j |  j  7_ g  |  _ n  |  j |  j  | !} | |  _  |  j   | S(   NR   i    (	   R   R   R   t   TrueR#   R   R   t   joinR!   (   R   t   nt   newPost   r(    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt   read   s$    	"		
		
c         C   s  |  j  |  j k r |  j r d Sx t r |  j rX |  j d j |  j  7_ g  |  _ n  |  j j d |  j   } | d k  r |  j r |  j } Pq |  j   q" q" | d } Pq" W| d  k	 r |  j  | | k  r |  j  | } q n  |  j |  j  | !} | |  _  |  j
   | S(   NR   s   
i    i   (   R   R   R   R$   R   R   R%   t   findR#   t   NoneR!   (   R   t   lengtht   iR'   R(   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt   readline   s,    				

	
i    c         C   sr   d } g  } |  j    } xS | rm | j |  | t |  7} d | k  oU | k n r^ Pn  |  j    } q W| S(   Ni    (   R.   t   appendt   len(   R   t   sizehintt   totalt   linest   line(    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt	   readlines   s    	c         C   s   |  S(   N(    (   R   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt   __iter__   s    c         C   s   |  j    } | s t  n  | S(   N(   R.   t   StopIteration(   R   R(   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt   next   s    	c         C   s;   | s t  |  _ n% |  j j |  |  j t |  7_ d  S(   N(   R$   R   R   R/   R   R0   (   R   t   data(    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt   add_data   s    N(   t   __name__t
   __module__t   __doc__R   R!   R#   R)   R+   R.   R5   R6   R8   R:   (    (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR      s   						t   MultiplexedInputStreamc           B   sA   e  Z d  Z d   Z d   Z d d  Z d d  Z d   Z RS(   s   
    A version of InputStream meant to be used with MultiplexedConnections.
    Assumes the MultiplexedConnection (the producer) and the Request
    (the consumer) are running in different threads.
    c         C   s8   t  t |   j |  t j   } t j |  |  _ d  S(   N(   t   superR>   R   t	   threadingt   RLockt	   Conditiont   _lock(   R   R   t   lock(    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR     s    c         C   s   |  j  j   d  S(   N(   RC   t   wait(   R   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR#     s    ic         C   s<   |  j  j   z t t |   j |  SWd  |  j  j   Xd  S(   N(   RC   t   acquireR?   R>   R)   t   release(   R   R&   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR)     s    c         C   s<   |  j  j   z t t |   j |  SWd  |  j  j   Xd  S(   N(   RC   RF   R?   R>   R.   RG   (   R   R,   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR.     s    c         C   sI   |  j  j   z' t t |   j |  |  j  j   Wd  |  j  j   Xd  S(   N(   RC   RF   R?   R>   R:   t   notifyRG   (   R   R9   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR:   "  s
    N(	   R;   R<   R=   R   R#   R)   R+   R.   R:   (    (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR>      s   	
	t   OutputStreamc           B   sG   e  Z d  Z e d  Z d   Z d   Z d   Z d   Z d   Z	 RS(   s   
    FastCGI output stream (FCGI_STDOUT/FCGI_STDERR). By default, calls to
    write() or writelines() immediately result in Records being sent back
    to the server. Buffering should be done in a higher level!
    c         C   sC   | |  _  | |  _ | |  _ | |  _ g  |  _ t |  _ t |  _ d  S(   N(   R   t   _reqt   _typet	   _bufferedR   R   t   dataWrittent   closed(   R   R   t   reqt   typet   buffered(    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR   0  s    						c         C   s   t  |  } xx | r t | |  j j j t  } t |  j |  j j  } | | _	 | |  | _
 |  j j |  | | } | | 8} q Wd  S(   N(   R0   t   minRJ   R   t   maxwritet   FCGI_HEADER_LENt   RecordRK   t	   requestIdt   contentLengtht   contentDataR   t   writeRecord(   R   R9   R,   t   toWritet   rec(    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt   _write9  s    		
c         C   sP   |  j  s t  | s d  St |  _ |  j r? |  j j |  n |  j |  d  S(   N(   RN   R    R$   RM   RL   R   R/   R\   (   R   R9   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR	   F  s    		c         C   s2   |  j  s t  x | D] } |  j |  q Wd  S(   N(   RN   R    R	   (   R   R3   R4   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt
   writelinesS  s    c         C   s8   |  j  r4 d j |  j  } g  |  _ |  j |  n  d  S(   NR   (   RL   R%   R   R\   (   R   R9   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt   flushY  s    		c         C   sU   |  j  rQ |  j rQ |  j   t |  j |  j j  } |  j j |  t	 |  _  n  d S(   s/   Sends end-of-stream notification, if necessary.N(
   RN   RM   R^   RU   RK   RJ   RV   R   RY   R$   (   R   R[   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR   a  s
    
(
   R;   R<   R=   R   R   R\   R	   R]   R^   R   (    (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyRI   *  s   					t   TeeOutputStreamc           B   s2   e  Z d  Z d   Z d   Z d   Z d   Z RS(   sq   
    Simple wrapper around two or more output file-like objects that copies
    written data to all streams.
    c         C   s   | |  _  d  S(   N(   t   _streamList(   R   t
   streamList(    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR   n  s    c         C   s%   x |  j  D] } | j |  q
 Wd  S(   N(   R`   R	   (   R   R9   R   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR	   q  s    c         C   s"   x | D] } |  j  |  q Wd  S(   N(   R	   (   R   R3   R4   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR]   u  s    c         C   s"   x |  j  D] } | j   q
 Wd  S(   N(   R`   R^   (   R   R   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR^   y  s    (   R;   R<   R=   R   R	   R]   R^   (    (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR_   i  s
   			t   StdoutWrapperc           B   s2   e  Z d  Z d   Z d   Z d   Z d   Z RS(   sN   
    Wrapper for sys.stdout so we know if data has actually been written.
    c         C   s   | |  _  t |  _ d  S(   N(   t   _fileR   RM   (   R   t   stdout(    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR     s    	c         C   s&   | r t  |  _ n  |  j j |  d  S(   N(   R$   RM   Rc   R	   (   R   R9   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR	     s    c         C   s"   x | D] } |  j  |  q Wd  S(   N(   R	   (   R   R3   R4   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR]     s    c         C   s   t  |  j |  S(   N(   t   getattrRc   (   R   t   name(    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt   __getattr__  s    (   R;   R<   R=   R   R	   R]   Rg   (    (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyRb   }  s
   			c         C   s   t  |  |  } | d @rL t j d |  | | d ! d d @} | d 7} n
 | d 7} t  |  |  } | d @r t j d |  | | d ! d d @} | d 7} n
 | d 7} |  | | | !} | | 7} |  | | | !} | | 7} | | | f f S(   sv   
    Decodes a name/value pair.

    The number of bytes decoded as well as the name/value pair
    are returned.
    i   s   !Li   i    ii   (   t   ordt   structt   unpack(   t   st   post
   nameLengtht   valueLengthRf   t   value(    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt   decode_pair  s    
%

%


c         C   s   t  |   } | d k  r' t |  } n t j d | d B } t  |  } | d k  rh | t |  7} n | t j d | d B 7} | |  | S(   sI   
    Encodes a name/value pair.

    The encoded string is returned.
    i   s   !Ll        (   R0   t   chrRi   t   pack(   Rf   Ro   Rm   Rk   Rn   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt   encode_pair  s    RU   c           B   se   e  Z d  Z d d  Z e e d  Z d   Z e e  Z d   Z	 d   Z
 e e
  Z
 d   Z RS(   sD   
    A FastCGI Record.

    Used for encoding/decoding records.
    i   c         C   sh   t  j   \ } } } | j } y | j d } Wn t k
 rH d } n Xt j | |   } | | | f S(   Nt   argss	   <no args>(   t   syst   exc_infoR;   t   __dict__t   KeyErrort	   tracebackt	   format_tb(   t
   maxTBlevelt   clat   exct   trbkt   excNamet   excArgst   excTb(    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt   formatExceptionInfo  s    	
c         C   s:   t  |  _ | |  _ | |  _ d |  _ d |  _ d |  _ d  S(   Ni    R   (   t   FCGI_VERSION_1t   versionRP   RV   RW   t   paddingLengthRX   (   R   RP   RV   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR     s    					c         C   s   g  } d } x | r y |  j  |  } WnH t j k
 rr } | d t j k rl t j |  g g  g   q qs   n X| s} Pn  | j |  t |  } | | 7} | | 8} q Wd j |  | f S(   s   
        Attempts to receive length bytes from a socket, blocking if necessary.
        (Socket may be blocking or non-blocking.)
        i    R   (	   t   recvt   sockett   errort   errnot   EAGAINt   selectR/   R0   R%   (   t   sockR,   t   dataListt   recvLenR9   t   et   dataLen(    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt   _recvall  s"    	
c         C   s*  y |  j  | t  \ } } Wn t  n X| t k  rA t  n  t j t |  \ |  _ |  _ |  _ |  _	 |  _
 t d d | j   |  j |  j |  j	 f  |  j	 r y" |  j  | |  j	  \ |  _ } Wn t  n X| |  j	 k  r t  q n  |  j
 r&y |  j  | |  j
  Wq&t  q&Xn  d S(   s'   Read and decode a Record from a socket.i	   s<   read: fd = %d, type = %d, requestId = %d, contentLength = %dN(   R   RT   t   EOFErrorRi   Rj   t   FCGI_HeaderR   RP   RV   RW   R   R   t   filenoRX   (   R   R   t   headerR,   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR)     s.    
	0			
	c         C   s   t  |  } x | r y |  j |  } Wno t j k
 r } | d t j k rl t j g  |  g g   q n  | d t j k r d GH  Pq t   GH  n X| | } | | 8} q Wd S(   sY   
        Writes data to a socket and does not return until all the data is sent.
        i    sX   
Remote peer disconnected the requested information has been cancelled. Connection Lost.N(	   R0   t   sendR   R   R   R   R   t   EPIPER   (   R   R9   R,   t   sentR   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt   _sendall  s     	
c         C   s   |  j  d @|  _ t d d | j   |  j |  j |  j  f  t j t |  j	 |  j |  j |  j  |  j  } |  j
 | |  |  j  r |  j
 | |  j  n  |  j r |  j
 | d |  j  n  d S(   s&   Encode and write a Record to a socket.i   i	   s=   write: fd = %d, type = %d, requestId = %d, contentLength = %dt    N(   RW   R   R   R   RP   RV   Ri   Rr   R   R   R   RX   (   R   R   R   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR	   -  s    			(   R;   R<   R=   R   t   FCGI_UNKNOWN_TYPEt   FCGI_NULL_REQUEST_IDR   R   t   staticmethodR)   R   R	   (    (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyRU     s   
		"	t   Requestc           B   s8   e  Z d  Z d   Z d   Z d e d  Z d   Z RS(   s8  
    Represents a single FastCGI request.

    These objects are passed to your handler and is the main interface
    between your handler and the fcgi module. The methods should not
    be called by your handler. However, server, params, stdin, stdout,
    stderr, and data are free for your handler's use.
    c         C   sp   | |  _  | j |  _ i  |  _ | |  |  _ t | |  t  |  _ t | |  t d t |  _	 | |  |  _
 d  S(   NRQ   (   R   R   t   paramst   stdinRI   t   FCGI_STDOUTRd   t   FCGI_STDERRR$   t   stderrR9   (   R   R   t   inputStreamClass(    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR   H  s    		c         C   s   y |  j  j |   \ } } WnS t j d |  j  |  j j   |  j j sa |  j  j |   n  t	 d } } n Xt
 d d | | f  |  j   |  j | |  d S(   s<   Runs the handler, flushes the streams, and ends the request.t   filei    i   s#   protocolStatus = %d, appStatus = %dN(   R   t   handlerRy   t	   print_excR   R^   Rd   RM   R   t   FCGI_REQUEST_COMPLETER   t   _flusht   _end(   R   t   protocolStatust	   appStatus(    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt   runR  s    	
l    c         C   s   |  j  j |  | |  d  S(   N(   R   t   end_request(   R   R   R   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR   d  s    c         C   s   |  j  j   |  j j   d  S(   N(   Rd   R   R   (   R   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR   g  s    (   R;   R<   R=   R   R   R   R   R   (    (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR   ?  s
   	
	t
   CGIRequestc           B   s/   e  Z d  Z d   Z d e d  Z d   Z RS(   s4   A normal CGI request disguised as a FastCGI request.c         C   s|   d |  _  t |  _ d |  _ t |  _ | |  _ t t j	  |  _
 t j |  _ t t j  |  _ t j |  _ t j   |  _ d  S(   Ni   i    (   RV   t   FCGI_RESPONDERt   rolet   flagsR   t   abortedR   t   dictt   ost   environR   Ru   R   Rb   Rd   R   t   StringIOR9   (   R   R   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR   m  s    					l    c         C   s   t  j |  d  S(   N(   Ru   t   exit(   R   R   R   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR   {  s    c         C   s   d  S(   N(    (   R   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR   ~  s    (   R;   R<   R=   R   R   R   R   (    (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR   k  s   	t
   Connectionc           B   s   e  Z d  Z e Z e Z d   Z d   Z d   Z	 d   Z
 d   Z d e e d  Z d   Z d	   Z d
   Z d   Z d   Z d   Z d   Z d   Z RS(   s   
    A Connection with the web server.

    Each Connection is associated with a single socket (which is
    connected to the web server) and is responsible for handling all
    the FastCGI message processing for that socket.
    c         C   s(   | |  _  | |  _ | |  _ i  |  _ d  S(   N(   t   _sockt   _addrR   t	   _requests(   R   R   t   addrR   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR     s    			c         C   s   y |  j  j t j  Wn d SXyS xL t rs t j |  j  g g  g   \ } } } | sl |  j  j d  r( Pq( q( WWn n X|  j  j   d S(   s   Close the Connection's socket.Ni   (   R   t   shutdownR   R    R$   R   R   R   (   R   R(   t   wR   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt   _cleanupSocket  s    	$c         C   s   t  |  _ xh |  j rs y |  j   Wq t k
 r7 Pq t j t j f k
 ro } | d t j k ri Pn    q Xq W|  j	   d S(   s&   Begin processing data from the socket.i    N(
   R$   t
   _keepGoingR"   R   R   R   R   R   t   EBADFR   (   R   R   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR     s    	c         C   sb  x\ |  j  r^ y+ t j |  j g g  g  d  \ } } } Wn t k
 rP t  n X| r Pq q W|  j  sl d St   } | j |  j  | j t k r |  j	 |  n | j t
 k r |  j |  n | j t k r |  j |  n| | j t k r|  j |  n] | j t k r |  j |  n> | j t k r?|  j |  n | j t k r^|  j |  n  d S(   s?   Attempt to read a single Record from the socket and process it.g      ?N(   R   R   R   t
   ValueErrorR   RU   R)   RP   t   FCGI_GET_VALUESt   _do_get_valuest   FCGI_BEGIN_REQUESTt   _do_begin_requestt   FCGI_ABORT_REQUESTt   _do_abort_requestt   FCGI_PARAMSt
   _do_paramst
   FCGI_STDINt	   _do_stdint	   FCGI_DATAt   _do_dataRV   R   t   _do_unknown_type(   R   R(   R   R   R[   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR"     s4    +
 		c         C   s   | j  |  j  d S(   s/   
        Write a Record to the socket.
        N(   R	   R   (   R   R[   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyRY     s    l    c         C   s   t  t | j  } t j t | |  | _ t | _ |  j	 |  | rV |  j
 | j =n  t d d | j  | j t @r |  j
 r |  j   t |  _ n  d S(   s  
        End a Request.

        Called by Request objects. An FCGI_END_REQUEST Record is
        sent to the web server. If the web server no longer requires
        the connection, the socket is closed, thereby ending this
        Connection (run() returns).
        i   s   end_request: flags = %dN(   RU   t   FCGI_END_REQUESTRV   Ri   Rr   t   FCGI_EndRequestBodyRX   t   FCGI_EndRequestBody_LENRW   RY   R   R   R   t   FCGI_KEEP_CONNR   R   R   (   R   RO   R   R   t   removeR[   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR     s    
	
c         C   s   t  t  } d } xs | | j k  r t | j |  \ } \ } } |  j j j |  } | d k	 r | j t	 | t
 |   7_ q q Wt | j  | _ |  j |  d S(   s6   Handle an FCGI_GET_VALUES request from the web server.i    N(   RU   t   FCGI_GET_VALUES_RESULTRW   Rp   RX   R   t
   capabilityt   getR+   Rs   t   strR0   RY   (   R   t   inrect   outrecRl   Rf   Ro   t   cap(    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR     s    %c         C   s   t  j t | j  \ } } |  j j |  |  j  } | j | | | _ | _ | _	 t
 | _ |  j r |  j r |  j | d t d t
 n | |  j | j <d S(   s1   Handle an FCGI_BEGIN_REQUEST from the web server.l    R   N(   Ri   Rj   t   FCGI_BeginRequestBodyRX   R   t   request_classt   _inputStreamClassRV   R   R   R   R   t   _multiplexedR   R   t   FCGI_CANT_MPX_CONN(   R   R   R   R   RO   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR     s     	c         C   s1   |  j  j | j  } | d k	 r- t | _ n  d S(   s{   
        Handle an FCGI_ABORT_REQUEST from the web server.

        We just mark a flag in the associated Request.
        N(   R   R   RV   R+   R$   R   (   R   R   RO   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR     s    c         C   s   | j    d S(   s   Run the request.N(   R   (   R   RO   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt   _start_request  s    c         C   s   |  j  j | j  } | d k	 r | j rt d } xN | | j k  rp t | j |  \ } \ } } | | j | <q3 Wq |  j |  n  d S(   sw   
        Handle an FCGI_PARAMS Record.

        If the last FCGI_PARAMS Record is received, start the request.
        i    N(	   R   R   RV   R+   RW   Rp   RX   R   R   (   R   R   RO   Rl   Rf   Ro   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR   "  s    	c         C   s;   |  j  j | j  } | d k	 r7 | j j | j  n  d S(   s   Handle the FCGI_STDIN stream.N(   R   R   RV   R+   R   R:   RX   (   R   R   RO   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR   2  s    c         C   s;   |  j  j | j  } | d k	 r7 | j j | j  n  d S(   s   Handle the FCGI_DATA stream.N(   R   R   RV   R+   R9   R:   RX   (   R   R   RO   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR   8  s    c         C   s>   t  t  } t j t | j  | _ t | _ |  j	 t
  d S(   s4   Handle an unknown request type. Respond accordingly.N(   RU   R   Ri   Rr   t   FCGI_UnknownTypeBodyRP   RX   t   FCGI_UnknownTypeBody_LENRW   RY   R[   (   R   R   R   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR   >  s    	(   R;   R<   R=   R   R   R   R   R   R   R   R"   RY   R   R$   R   R   R   R   R   R   R   R   R   (    (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR     s$   				%				
				t   MultiplexedConnectionc           B   s}   e  Z d  Z e Z e Z d   Z d   Z d   Z	 d e
 e d  Z d   Z d   Z d   Z d	   Z d
   Z d   Z RS(   s[   
    A version of Connection capable of handling multiple requests
    simultaneously.
    c         C   s>   t  t |   j | | |  t j   } t j |  |  _ d  S(   N(   R?   R   R   R@   RA   RB   RC   (   R   R   R   R   RD   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR   M  s    c         C   sN   |  j  j   x |  j r) |  j  j   q W|  j  j   t t |   j   d  S(   N(   RC   RF   R   RE   RG   R?   R   R   (   R   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR   W  s
    c         C   s6   |  j  j   z | j |  j  Wd  |  j  j   Xd  S(   N(   RC   RF   R	   R   RG   (   R   R[   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyRY   `  s    l    c         C   sR   |  j  j   z0 t t |   j | | | |  |  j  j   Wd  |  j  j   Xd  S(   N(   RC   RF   R?   R   R   RH   RG   (   R   RO   R   R   R   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR   j  s    c         C   s<   |  j  j   z t t |   j |  Wd  |  j  j   Xd  S(   N(   RC   RF   R?   R   R   RG   (   R   R   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR   u  s    c         C   s<   |  j  j   z t t |   j |  Wd  |  j  j   Xd  S(   N(   RC   RF   R?   R   R   RG   (   R   R   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR   |  s    c         C   s   t  j | j d  d  S(   N(    (   t   threadt   start_new_threadR   (   R   RO   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR     s    c         C   s<   |  j  j   z t t |   j |  Wd  |  j  j   Xd  S(   N(   RC   RF   R?   R   R   RG   (   R   R   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR     s    c         C   s<   |  j  j   z t t |   j |  Wd  |  j  j   Xd  S(   N(   RC   RF   R?   R   R   RG   (   R   R   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR     s    c         C   s<   |  j  j   z t t |   j |  Wd  |  j  j   Xd  S(   N(   RC   RF   R?   R   R   RG   (   R   R   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR     s    (   R;   R<   R=   R$   R   R>   R   R   R   RY   R   R   R   R   R   R   R   R   (    (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR   E  s   	
			

					t   Serverc           B   s   e  Z d  Z e Z e Z d Z d d d d e	 d  Z
 d   Z d   Z d   Z d   Z d   Z d	   Z d
 d  Z d   Z e	 d  Z d   Z d   Z RS(   s   
    The FastCGI server.

    Waits for connections from the web server, processing each
    request.

    If run in a normal CGI context, it will instead instantiate a
    CGIRequest and run the handler through there.
    i  i    c   	      C   s   | d k	 r | |  _ n  | |  _ t r y& d d l } | j | j  d } Wn t k
 rf d } n X| } | r t |  _	 | d 9} n	 t
 |  _	 i | t 6| t 6| r d p d t 6|  _ n' t
 |  _	 i d t 6d t 6d t 6|  _ | |  _ | |  _ d S(   s^  
        handler, if present, must reference a function or method that
        takes one argument: a Request object. If handler is not
        specified at creation time, Server *must* be subclassed.
        (The handler method below is abstract.)

        maxwrite is the maximum number of bytes (per Record) to write
        to the server. I've noticed mod_fastcgi has a relatively small
        receive buffer (8K or so).

        bindAddress, if present, must either be a string or a 2-tuple. If
        present, run() will open its own listening socket. You would use
        this if you wanted to run your application as an 'external' FastCGI
        app. (i.e. the webserver would no longer be responsible for starting
        your app) If a string, it will be interpreted as a filename and a UNIX
        socket will be opened. If a tuple, the first element, a string,
        is the interface name/IP to bind to, and the second element (an int)
        is the port number.

        Set multiplexed to True if you want to handle multiple requests
        per connection. Some FastCGI backends (namely mod_fastcgi) don't
        multiplex requests at all, so by default this is off (which saves
        on thread creation/locking overhead). If threads aren't available,
        this keyword is ignored; it's not possible to multiplex requests
        at all.
        iNi    id   i   i   (   R+   R   RS   t   thread_availablet   resourcet	   getrlimitt   RLIMIT_NOFILEt   ImportErrorR   t   _connectionClassR   R   R   R   R   t   _bindAddresst   _umask(	   R   R   RS   t   bindAddresst   umaskt   multiplexedR   t   maxConnst   maxReqs(    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR     s2    	
				c         C   s  |  j  d  k r t } t j t t j t j  } y | j   WnK t j	 k
 r } | d t
 j k ro t } q | d t
 j k r   q n X| s t j j d d  j   j d  r|  j |   } | j   t j d  qn%d  } t |  j   t k ret j t j t j  } y t j |  j   Wn t k
 r=n X|  j d  k	 rt j |  j  } qng t |  j   t k st  t  |  j   d k st  t j t j t j  } | j! t j" t j# d  | j$ |  j   | j% t j&  | d  k	 rt j |  n  | S(   Ni    t   FCGI_FORCE_CGIt   Nt   Yi   i   ('   R   R+   R$   R   t   fromfdt   FCGI_LISTENSOCK_FILENOt   AF_INETt   SOCK_STREAMt   getpeernameR   R   t   ENOTSOCKR   t   ENOTCONNR   R   R   t   uppert
   startswitht   cgirequest_classR   Ru   R   RP   R   t   AF_UNIXt   unlinkt   OSErrorR   R   t   tupleR    R0   t
   setsockoptt
   SOL_SOCKETt   SO_REUSEADDRt   bindt   listent	   SOMAXCONN(   R   t   isFCGIR   R   RO   t   oldUmask(    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt   _setupSocket  sD    	
$
c         C   s   | j    d S(   s   Closes the main socket.N(   R   (   R   R   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR     s    c         C   s   g  t  j t  j t  j f D] } | t  j |  f ^ q |  _ t  j  t  j |  j  t  j  t  j |  j  t  j  t  j |  j  d  S(   N(   t   signalt   SIGHUPt   SIGINTt   SIGTERMt	   getsignalt   _oldSIGst   _hupHandlert   _intHandler(   R   t   x(    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt   _installSignalHandlers"  s
    :c         C   s.   x' |  j  D] \ } } t j | |  q
 Wd  S(   N(   R  R  (   R   t   signumR   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt   _restoreSignalHandlers)  s    c         C   s   t  |  _ t |  _ d  S(   N(   R$   t   _hupReceivedR   R   (   R   R  t   frame(    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR  -  s    	c         C   s   t  |  _ d  S(   N(   R   R   (   R   R  R  (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR  1  s    g      ?c   
      C   s  t  j j d  } | d k	 r< t d   | j d   } n  |  j   } t |  _ t	 |  _
 |  j   x1|  j ry( t j | g g  g  |  \ } } } Wn2 t j k
 r } | d t j k r qg n    n X| ry | j   \ } } Wn; t j k
 r&} | d t j t j f k r qg n    n X| r_t |  d k sO| d | k r_| j   qg n  |  j | | |   }	 t j |	 j d  n  |  j   qg W|  j   |  j |  |  j
 S(   s   
        The main loop. Exits on SIGHUP, SIGINT, SIGTERM. Returns True if
        SIGHUP was received, False otherwise.
        t   FCGI_WEB_SERVER_ADDRSc         S   s
   |  j    S(   N(   t   strip(   R  (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt   <lambda>;  s    t   ,i    i   N(    (   R   R   R   R+   t   mapt   splitR  R$   R   R   R  R  R   R   R   t   EINTRt   acceptR   R   R0   R   R   R   R   R   t   _mainloopPeriodicR  R   (
   R   t   timeoutt   web_server_addrsR   R(   R   R   t
   clientSockR   R   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR   4  s@    			
("

c         C   s   d S(   si   
        Called with just about each iteration of the main loop. Meant to
        be overridden.
        N(    (   R   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR&  i  s    c         C   s"   |  j  r t |  _  | |  _ n  d S(   s   
        Protected convenience method for subclasses to force an exit. Not
        really thread-safe, which is why it isn't public.
        N(   R   R   R  (   R   t   reload(    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt   _exitp  s    		c         C   s   t  |  j j d  d S(   s   
        Default handler, which just raises an exception. Unless a handler
        is passed at initialization time, this must be implemented by
        a subclass.
        s   .handlerN(   t   NotImplementedErrort	   __class__R;   (   R   RO   (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR   y  s    c         C   s3   d d l  } | j j d | j t j     d S(   st   
        Called by Request if an exception occurs within the handler. May and
        should be overridden.
        iNs   Content-Type: text/html

(   t   cgitbRd   R	   t   htmlRu   Rv   (   R   RO   R.  (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR     s    i p N(   R;   R<   R=   R   R   R   R  R   R+   R   R   R  R   R  R  R  R  R   R&  R+  R   R   (    (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR     s"   		<	4					5			c           B   s2   e  Z d  Z d d e d  Z d   Z d   Z RS(   s|   
    FastCGI server that supports the Web Server Gateway Interface. See
    <http://www.python.org/peps/pep-0333.html>.
    c         K   sr   | j  d  r | d =n  t t |   j |   | d k rD i  } n  | |  _ | |  _ | |  _ t j	   |  _
 d S(   s  
        environ, if present, must be a dictionary-like object. Its
        contents will be copied into application's environ. Useful
        for passing application-specific variables.

        Set multithreaded to False if your application is not MT-safe.
        R   N(   t   has_keyR?   R   R   R+   t   applicationR   t   multithreadedR   t   allocate_lockt	   _app_lock(   R   R1  R   R   R2  t   kw(    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR     s    	
				c            s+   j  t k r t d f S j } | j |  j  d | d < j | d <|  j d k rd  j	 } n t
 t j	  j	 f  } | | d <t  t  o t o |  j | d <t | d <t  t  | d <| j d	 d
  d k r d | d <n
 d | d <|  j |  g   g    d       f d    d     f d  } |  j s]|  j j   n  z yq |  j | |   z; x!  D] } | r |  qqW  s d  n  Wd t  d  r j   n  XWn/ t j k
 r} | d t j k r  qn XWd |  j s |  j j   n  Xt d f S(   s   Special handler for WSGI.i    i   s   wsgi.versions
   wsgi.inputs   wsgi.errorss   wsgi.multithreads   wsgi.multiprocesss   wsgi.run_oncet   HTTPSt   offt   ont   1t   httpss   wsgi.url_schemet   httpc            s?  t  |   t k s t d    s0 t d     s \ } }   (t } x0 | D]( \ } } | j   d k rT t } PqT qT W| r  d  k	 r y8 t   d k r | j d t t |    f  n  Wq q Xn  d | } x | D] } | d | 7} q W| d 7}  j	 j
 |  n   j	 j
 |    j	 j   d  S(	   Ns   write() argument must be strings   write() before start_response()s   content-lengthi   s   Content-Lengths   Status: %s
s   %s: %s
s   
(   RP   R   R    R   t   lowerR$   R+   R0   R/   Rd   R	   R^   (   R9   t   statust   responseHeaderst   foundR   Ro   Rk   (   t   headers_sentt   headers_setRO   t   result(    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR	     s.    	

c            sA  | r8 z%   r* | d | d | d  n  Wd  d  } Xn  sK t d   t |   t k si t d   t |   d k s t d   t |  d   s t d	   |  d d
 k s t d   t |  t k s t d   xP | D]H \ } } t |  t k st d   t |  t k s t d   q W|  | g  ( S(   Ni    i   i   s   Headers already set!s   Status must be a stringi   s$   Status must be at least 4 charactersi   s#   Status must begin with 3-digit codet    s#   Status must have a space after codes   Headers must be a lists   Header names must be stringss   Header values must be strings(   R+   R    RP   R   R0   t   intt   list(   R=  t   response_headersRv   Rf   t   val(   R@  RA  R	   (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt   start_response  s     
"R   NR   (   i   i    (   R8  R9  (   R   R   t   FCGI_UNKNOWN_ROLER   t   updateR   R   R   R+   R   R_   Ru   t
   isinstanceR   R   R2  R$   R   t   _sanitizeEnvR4  RF   R1  t   hasattrR   R   R   R   R   RG   R   (   R   RO   R   R   RH  R9   R   (    (   R@  RA  RO   RB  R	   sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR     sT    
	



		c         C   s   | j  d  s d | d <n  | j  d  s8 d | d <n  x] d d d d g D]I \ } } | j  |  sK | d j d |  j j | f  | | | <qK qK Wd S(   s7   Ensure certain values are present, if required by WSGI.t   SCRIPT_NAMER   t	   PATH_INFOt   REQUEST_METHODt   GETt   SERVER_NAMEt	   localhostt   SERVER_PORTt   80t   SERVER_PROTOCOLs   HTTP/1.0s   wsgi.errorss/   %s: missing FastCGI param %s required by WSGI!
N(   s   REQUEST_METHODs   GET(   RR  s	   localhost(   RT  RU  (   RV  s   HTTP/1.0(   R0  R	   R-  R;   (   R   R   Rf   t   default(    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyRL    s    N(   R;   R<   R=   R+   R$   R   R   RL  (    (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyR     s
   	pt   __main__c         c   s   d d l  } | d d g  d V|  j   } | j   x+ | D]# } d | | j |  |  f Vq> W| j d |  d	 d
 |  d d  } | j r d Vn  x& | j D] } d | j | j f Vq Wd Vd S(   s(   Probably not the most efficient example.iNs   200 OKs   Content-Types	   text/htmls\   <html><head><title>Hello World!</title></head>
<body>
<p>Hello World!</p>
<table border="1">s    <tr><td>%s</td><td>%s</td></tr>
t   fps
   wsgi.inputR   t   keep_blank_valuesi   s'   <tr><th colspan="2">Form data</th></tr>s   </table>
</body></html>
(   s   Content-Types	   text/html(   t   cgit   keyst   sortt   escapet   FieldStorageRE  Rf   Ro   (   R   RH  R[  t   namesRf   t   formt   field(    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt   test_app*  s     
		(P   R=   t
   __author__t   __version__Ru   R   R  Ri   t	   cStringIOR   R   R   R   Ry   R   R@   R$   R   R   t   dummy_threadt   dummy_threadingR   RM  R    t   __all__R   RT   R   R   R   R   R   R   R   R   R   R   R   R   t   FCGI_MAXTYPER   R   R   t   FCGI_AUTHORIZERt   FCGI_FILTERR   R   t   FCGI_OVERLOADEDRI  R   R   R   R   R   R   R   t   calcsizeR   R   R
   R   R   R   t   objectR   R>   RI   R_   Rb   Rp   Rs   RU   R   R   R   R   R   R   R;   Rc  R   (    (    (    sE   /mnt/ebs/frostwire-files/frostwire-cloud/com/frostwire/doctor/fcgi.pyt   <module>/   s   

		t*?	~,V	