³ò
,e|Mc           @   s§   d  Z  d d k Z d d k Z d d k Z d d k l Z d d k l Z d Z d e	 f d „  ƒ  YZ
 d d d „ Z d e	 f d „  ƒ  YZ d „  Z d d d „ Z d S(   sæ  
An application that proxies WSGI requests to a remote server.

TODO:

* Send ``Via`` header?  It's not clear to me this is a Via in the
  style of a typical proxy.

* Other headers or metadata?  I put in X-Forwarded-For, but that's it.

* Signed data of non-HTTP keys?  This would be for things like
  REMOTE_USER.

* Something to indicate what the original URL was?  The original host,
  scheme, and base path.

* Rewriting ``Location`` headers?  mod_proxy does this.

* Rewriting body?  (Probably not on this one -- that can be done with
  a different middleware that wraps this middleware)

* Example::  
    
    use = egg:Paste#proxy
    address = http://server3:8680/exist/rest/db/orgs/sch/config/
    allowed_request_methods = GET
  
iÿÿÿÿN(   t   httpexceptions(   t   aslists   transfer-encodingt
   connections
   keep-alives   proxy-authenticates   proxy-authorizationt   tet   trailerst   upgradet   Proxyc           B   s    e  Z d d d  „ Z d „  Z RS(   c         C   s¿   | |  _  t i | ƒ |  _ |  i d i ƒ  |  _ |  i d |  _ |  i d |  _ g  } | D] } | o | | i ƒ  q\ q\ ~ |  _ g  } | D] } | o | | i ƒ  q‘ q‘ ~ |  _	 d  S(   Ni    i   i   (
   t   addresst   urlparset   urlsplitt   parsedt   lowert   schemet   hostt   patht   allowed_request_methodst   suppress_http_headers(   t   selfR   R   R   t   _[1]t   xt   _[2](    (    sZ   /afs/athena.mit.edu/user/x/a/xavid/Public/bazki/lib/Paste-1.7.5.1-py2.5.egg/paste/proxy.pyt   __init__6   s    	5c         C   s3  |  i  o4 | d i ƒ  |  i  j o t i d ƒ | | ƒ Sn |  i d j o t i } n: |  i d j o t i } n t d |  i	 |  i f ƒ ‚ | |  i
 ƒ } h  } xx | i ƒ  D]j \ } } | i d ƒ oN | d i ƒ  i d d	 ƒ } | d
 j p | |  i j o q¶ n | | | <q¶ q¶ W|  i
 | d
 <d | j o | d | d <n | i d ƒ o | d | d <n | i d ƒ os | d d j o- | d i d ƒ } t t | ƒ ƒ | d <qû| d | d <t | d ƒ }	 | d i |	 ƒ } n d } t i | d ƒ }
 |  i oE |
 } | o | d d j o | d } n t i |  i | ƒ } n |
 } | i d ƒ o | d | d 7} n | i | d | | | ƒ | i ƒ  } t | i ƒ } d | i | i f } | | | ƒ | i d ƒ }	 |	 d  j	 o | i t |	 ƒ ƒ } n | i ƒ  } | i! ƒ  | g S(   Nt   REQUEST_METHODt
   Disallowedt   httpt   httpss   Unknown scheme for %r: %rt   HTTP_i   t   _t   -R   t   REMOTE_ADDRs   x-forwarded-fort   CONTENT_TYPEs   content-typet   CONTENT_LENGTHs   -1s
   wsgi.inputiÿÿÿÿs   content-lengtht    t	   PATH_INFOi    t   /i   t   QUERY_STRINGt   ?s   %s %s("   R   R   R    t   HTTPBadRequestR   t   httplibt   HTTPConnectiont   HTTPSConnectiont
   ValueErrorR   R   t   itemst
   startswitht   replaceR   t   gett   readt   strt   lent   intt   urllibt   quoteR   R   t   urljoint   requestt   getresponset   parse_headerst   msgt   statust   reasont	   getheadert   Nonet   close(   R   t   environt   start_responset	   ConnClasst   connt   headerst   keyt   valuet   bodyt   lengtht	   path_infot   request_pathR   t   rest   headers_outR9   (    (    sZ   /afs/athena.mit.edu/user/x/a/xavid/Public/bazki/lib/Paste-1.7.5.1-py2.5.egg/paste/proxy.pyt   __call__C   sj    
 


(    (    (   t   __name__t
   __module__R   RK   (    (    (    sZ   /afs/athena.mit.edu/user/x/a/xavid/Public/bazki/lib/Paste-1.7.5.1-py2.5.egg/paste/proxy.pyR   4   s   R    c         C   s.   t  | ƒ } t  | ƒ } t | d | d | ƒS(   s¸  
    Make a WSGI application that proxies to another address:
    
    ``address``
        the full URL ending with a trailing ``/``
        
    ``allowed_request_methods``:
        a space seperated list of request methods (e.g., ``GET POST``)
        
    ``suppress_http_headers``
        a space seperated list of http headers (lower case, without
        the leading ``http_``) that should not be passed on to target
        host
    R   R   (   R   R   (   t   global_confR   R   R   (    (    sZ   /afs/athena.mit.edu/user/x/a/xavid/Public/bazki/lib/Paste-1.7.5.1-py2.5.egg/paste/proxy.pyt
   make_proxy…   s    t   TransparentProxyc           B   s/   e  Z d  Z d d d „ Z d „  Z d „  Z RS(   s$  
    A proxy that sends the request just as it was given, including
    respecting HTTP_HOST, wsgi.url_scheme, etc.

    This is a way of translating WSGI requests directly to real HTTP
    requests.  All information goes in the environment; modify it to
    modify the way the request is made.

    If you specify ``force_host`` (and optionally ``force_scheme``)
    then HTTP_HOST won't be used to determine where to connect to;
    instead a specific host will be connected to, but the ``Host``
    header in the request will remain intact.
    R   c         C   s   | |  _  | |  _ d  S(   N(   t
   force_hostt   force_scheme(   R   RQ   RR   (    (    sZ   /afs/athena.mit.edu/user/x/a/xavid/Public/bazki/lib/Paste-1.7.5.1-py2.5.egg/paste/proxy.pyR   ­   s    	c         C   s,   d |  i  i t t |  ƒ ƒ |  i |  i f S(   Ns%   <%s %s force_host=%r force_scheme=%r>(   t	   __class__RL   t   hext   idRQ   RR   (   R   (    (    sZ   /afs/athena.mit.edu/user/x/a/xavid/Public/bazki/lib/Paste-1.7.5.1-py2.5.egg/paste/proxy.pyt   __repr__²   s    	c         C   s  | d } |  i  d  j o
 | } n
 |  i } | d j o t i } n+ | d j o t i } n t d | ƒ ‚ d | j o t d ƒ ‚ n | d } |  i  d  j o
 | } n
 |  i  } | | ƒ } h  }	 xT | i ƒ  D]F \ }
 } |
 i d ƒ o* |
 d i	 ƒ  i
 d	 d
 ƒ }
 | |	 |
 <qÚ qÚ W| |	 d <d | j o d | j o | d |	 d <n | i d ƒ o | d |	 d <n | i d ƒ oN t | d ƒ } | d i | ƒ } | d j o t t | ƒ ƒ | d <qn* d | j o d } d } n d } d } | i d d ƒ | i d d ƒ } t i | ƒ } d | j o | d | d 7} n | i | d | | |	 ƒ | i ƒ  } t | i ƒ } d | i | i f } | | | ƒ | i d ƒ } | d  j	 o | i t | ƒ ƒ } n | i ƒ  } | i ƒ  | g S(   Ns   wsgi.url_schemeR   R   s   Unknown scheme %rt	   HTTP_HOSTs*   WSGI environ must contain an HTTP_HOST keyR   i   R   R   R   R   t   HTTP_X_FORWARDED_FORs   x-forwarded-forR   s   content-typeR   s
   wsgi.inputiÿÿÿÿR    i    t   SCRIPT_NAMER!   R#   R$   R   s   %s %ss   content-length(   RQ   R<   RR   R&   R'   R(   R)   R*   R+   R   R,   R-   R1   R.   R/   R0   R2   R3   R5   R6   R7   R8   R9   R:   R;   R=   (   R   R>   R?   R   t   conn_schemeR@   R   t	   conn_hostRA   RB   RC   RD   RF   RE   R   RI   RJ   R9   (    (    sZ   /afs/athena.mit.edu/user/x/a/xavid/Public/bazki/lib/Paste-1.7.5.1-py2.5.egg/paste/proxy.pyRK   ¸   sp    

	

	 


N(   RL   RM   t   __doc__R<   R   RV   RK   (    (    (    sZ   /afs/athena.mit.edu/user/x/a/xavid/Public/bazki/lib/Paste-1.7.5.1-py2.5.egg/paste/proxy.pyRP      s
   	c         C   s  g  } x÷ |  i  D]ì } | p q n | d i ƒ  o[ | p t d | ƒ ‚ n | i ƒ  \ } } | d | i ƒ  } | i | | f ƒ q n y | i d d ƒ \ } } Wn t d | ƒ ‚ n X| i ƒ  } | i ƒ  t j o | i | | f ƒ q q W| S(   sB   
    Turn a Message object into a list of WSGI-style headers.
    i    s%   First header starts with a space (%r)t    t   :i   s   Invalid header: %r(	   RB   t   isspaceR)   t   popt   stript   appendt   splitR   t   filtered_headers(   t   messageRJ   t   full_headert   last_headert
   last_valueRD   t   header(    (    sZ   /afs/athena.mit.edu/user/x/a/xavid/Public/bazki/lib/Paste-1.7.5.1-py2.5.egg/paste/proxy.pyR7   ù   s*    
 R   c         C   s   t  d | d | ƒ S(   s   
    Create a proxy that connects to a specific host, but does
    absolutely no other filtering, including the Host header.
    RQ   RR   (   RP   (   RN   RQ   RR   (    (    sZ   /afs/athena.mit.edu/user/x/a/xavid/Public/bazki/lib/Paste-1.7.5.1-py2.5.egg/paste/proxy.pyt   make_transparent_proxy  s    (   s   transfer-encodings
   connections
   keep-alives   proxy-authenticates   proxy-authorizationR   R   s   upgrade(   R\   R&   R   R2   t   pasteR    t   paste.util.convertersR   Rd   t   objectR   RO   RP   R7   R<   Rj   (    (    (    sZ   /afs/athena.mit.edu/user/x/a/xavid/Public/bazki/lib/Paste-1.7.5.1-py2.5.egg/paste/proxy.pys   <module>   s&          Q\	