
    g                     0   d dl Z d dlZd dlZd dlZd dlmZmZ d dlZd dlm	Z	 d dl
Z
d dlmZ d dl
mZ d dlmZmZ d dlmZmZmZ  G d d	e      Z G d
 de      Zd Zd Zd Zd Zg dZ G d de      Z G d de      Z G d de      Z  G d de      Z!y)    N)SimpleCookieCookieError)consume)ntob)
_cpreqbody)
format_exc
bare_error)httputilreprconfencodingc                   B    e Zd ZdZdZ	 dZ	 dZ	 i Z	 d	dZd Z	d Z
d Zy)
Hookz<A callback and its metadata: failsafe, priority, and kwargs.NF2   c                 x    || _         |t        |dd      }|| _        |t        |dd      }|| _        || _        y )NfailsafeFpriorityr   )callbackgetattrr   r   kwargs)selfr   r   r   r   s        (/opt/Tautulli/lib/cherrypy/_cprequest.py__init__zHook.__init__,   sF     xU;H xR8H     c                 4    | j                   |j                   k  S )zm
        Hooks sort by priority, ascending, such that
        hooks of lower priority are run first.
        )r   )r   others     r   __lt__zHook.__lt__9   s    
 }}u~~--r   c                 :     | j                   di | j                  S )z!Run self.callback(**self.kwargs). )r   r   r   s    r   __call__zHook.__call__@   s    t}}+t{{++r   c                 0   | j                   }|j                  d|j                  d| j                  d| j                  d| j
                  ddj                  | j                  j                         D cg c]  \  }}|d| c}}      dS c c}}w )N.z
(callback=z, failsafe=z, priority=z, =))		__class__
__module____name__r   r   r   joinr   items)r   clskvs       r   __repr__zHook.__repr__D   su    nn>>3<<==$--99*.++*;*;*=?"&!Q *+A. ? @A 	B?s   6BNN)r'   r&   __qualname____doc__r   r   r   r   r   r   r    r-   r   r   r   r   r      sH    FH* H2 H F.,Br   r   c                   L    e Zd ZdZd
dZd ZddZd Zed        Z	d Z
e
Zd	 Zy)HookMapz:A map of call points to lists of callbacks (Hook objects).Nc                 P    t         j                  |       }|xs g D ]  }g ||<   	 |S N)dict__new__)r*   pointsdps       r   r6   zHookMap.__new__P   s1    LL2 	AAaD	r   c                      y r4   r   )r   akws      r   r   zHookMap.__init__V   s    r   c                 D    | |   j                  t        |||fi |       y)z3Append a new Hook made from the supplied arguments.N)appendr   )r   pointr   r   r   r   s         r   attachzHookMap.attachY   s"    U4(HGGHr   c                 P    | j                  t        t        | |                      y)z=Execute all registered Hooks (callbacks) for the given point.N)	run_hooksitersorted)r   r?   s     r   runzHookMap.run]   s    tF4;/01r   c                    t        |t        j                  j                        sJ t        j
                  t        j                  t        j                  f}t        t        j                  d      |      }|D ]
  }	  |         y# |$ r | j                  |        t        $ r* t	        j                  dd       | j                  |        w xY w)a  Execute the indicated hooks, trapping errors.

        Hooks with ``.failsafe == True`` are guaranteed to run
        even if others at the same hookpoint fail. In this case,
        log the failure and proceed on to the next hook. The only
        way to stop all processing from one of these hooks is
        to raise a BaseException like SystemExit or
        KeyboardInterrupt and stop the whole server.
        r   T(   	tracebackseverityN)
isinstancecollectionsabcIteratorcherrypy	HTTPErrorHTTPRedirectInternalRedirectfilteroperator
attrgetterrB   	Exceptionlog)r*   hooksquiet_errorssafehooks        r   rB   zHookMap.run_hooksa   s     %!9!9:::!!%%

 h))*5u= 		D		   d# tb9d#s   ;BA	Cc                 f    | j                         }| j                         D ]  \  }}|d d  ||<    |S r4   )r%   r)   )r   newmapr+   r,   s       r   __copy__zHookMap.__copy__~   s;    ! JJL 	DAq!F1I	r   c                 j    | j                   }|j                  d|j                  dt        |       dS )Nr"   z(points=r$   )r%   r&   r'   list)r   r*   s     r   r-   zHookMap.__repr__   s*    nnNNLLJ
 	
r   r4   r.   )r'   r&   r/   r0   r6   r   r@   rE   classmethodrB   r^   copyr-   r   r   r   r2   r2   M   s?    DI2  8 D
r   r2   c                 B   | j                  dd      d   }t        |t              r)t        j                  j
                  j                  |      }t        |t              st        |      }t        j                  j                  j                  |   j                  |       y)z%Attach bare hooks declared in config.r"      r   N)splitrK   strrO   libr   
attributesr   servingrequestrX   r>   )r+   r,   	hookpoints      r   hooks_namespacerl      st    
 Q"I!SLL!!,,Q/aG""9-44Q7r   c                     | dd dk(  r3t        t        j                  j                  j                  | dd |       yt        t        j                  j                  | |       y)z-Attach request attributes declared in config.N   zbody.)setattrrO   ri   rj   bodyr+   r,   s     r   request_namespacerr      sN     	!u  ((--qua8  ((!Q/r   c                     | dd dk(  r;|t         j                  j                  j                  | j	                  dd      d   <   yt        t         j                  j                  | |       y)z.Attach response attributes declared in config.N   zheaders.r"   rd   )rO   ri   responseheadersre   ro   rq   s     r   response_namespacerw      sU     	!u
@A!!))!''#q/!*<=  ))1a0r   c                 r    | dk7  rt        |       } |t        j                  j                  j                  | <   y)z&Attach error pages declared in config.defaultN)intrO   ri   rj   
error_pagerq   s     r   error_page_namespacer|      s.    I~F-.H''*r   )on_start_resourcebefore_request_bodybefore_handlerbefore_finalizeon_end_resourceon_end_requestbefore_error_responseafter_error_responsec            
       j   e Zd ZdZdZ	  ej                  dd      Z	  ej                  dd      Z	 dZ		 dZ
	 dZ	 dZ	 d	Z	 dZ	 d
Z	 dZ	 i Z	 g Z	  ej&                         Z	  e       Z	 dZ	 dZ	 dZ	 dZ	 ej8                  j;                         Z	 dZ	 dZ	 dZ 	 dZ!	 dZ"	 i Z#	 dZ$	 dZ%	  e&e'      Z(	  ejR                  d      jT                  Z+	 i Z,	 dZ-	 dZ.	 e/e0ejb                  fZ2	 dZ3	 dZ4	 dZ5	 dZ6	  e7jp                  di e9e:e;e<ejz                  dZ>	 	 ddZ?d Z@d ZAd ZBd ZCd ZDd ZEd ZFd ZGy)Requesta,  An HTTP request.

    This object represents the metadata of an HTTP request message; that
    is, it contains attributes which describe the environment in which
    the request URL, headers, and body were sent (if you want tools to
    interpret the headers and body, those are elsewhere, mostly in
    Tools). This 'metadata' consists of socket data, transport
    characteristics, and the Request-Line. This object also contains
    data regarding the configuration in effect for the given URL, and
    the execution plan for generating a response.
    Nz	127.0.0.1P   iW  httpHTTP/1.1 GETutf8rd   rd   T)POSTPUTPATCH/  F)rX   rj   ru   r{   toolsc                     || _         || _        || _        || _        d| _        | j
                  j                         | _        | j                  j                         | _        d| _        t               | _
        y)a  Populate a new Request object.

        local_host should be an httputil.Host object with the server
        info. remote_host should be an httputil.Host object with the
        client info. scheme should be a string, either "http" or
        "https".
        FN)localremoteschemeserver_protocolclosedr{   rb   
namespacesstage	LazyUUID4	unique_id)r   
local_hostremote_hostr   r   s        r   r   zRequest.__init__  sd      
!. //..0 //..0
"r   c                 ~    | j                   s1d| _         d| _        | j                  j                  d       d| _        yy)z*Run cleanup code.

        (Core)
        Tr   closeN)r   r   rX   rE   r   s    r   r   zRequest.close  s6    
 {{DK)DJJJNN+, DJ	 r   c                    t         j                  j                  }d| _        	 t        j                  d      j
                  | _        || _        |xs d}|xs d| _        i | _	        t        |d         t        |d         f}t        | j                  d         t        | j                  d         f}	t        ||	      | _        | j                  |j                  _        |}
|r|
d|z   z  }
|d|
d|| _        t!        |      | _        t%        j&                         | _        || _        d	| _        t-               | _        d	| _        | j2                  j4                  | _        |t7        | j4                        d	 x| _        }d
| _        | j;                  |       | j                  dk(  rg |_        	 t         jB                  jM                          |S # | j<                  $ r  t>        $ r` | j@                  r t        jB                  dd       | jD                  rtG               }nd}tI        |      }|\  |_%        |_        |_        Y w xY w# t>        $ r$ t         jB                  jO                  d       Y |S w xY w)a  Process the Request. (Core)

        method, path, query_string, and req_protocol should be pulled directly
        from the Request-Line (e.g. "GET /path?key=val HTTP/1.0").

        path
            This should be %XX-unquoted, but query_string should not be.

            When using Python 2, they both MUST be byte strings,
            not unicode strings.

            When using Python 3, they both MUST be unicode strings,
            not byte strings, and preferably not bytes \x00-\xFF
            disguised as unicode.

        headers
            A list of (name, value) tuples.

        rfile
            A file-like object containing the HTTP request entity.

        When run() is done, the returned object should have 3 attributes:

          * status, e.g. "200 OK"
          * header_list, a list of (name, value) tuples
          * body, an iterable yielding strings

        Consumer code (HTTP servers) should then access these response
        attributes to build the outbound stream.
        rE   r   r   r   rn      ? NrespondTrG   rH   HEAD)rI   )(rO   ri   ru   r   rP   set_responseerror_responsemethodquery_stringparamsrz   r   minprotocolrv   request_liner`   header_listr
   	HeaderMaprfilerp   r   cookiehandlerappscript_namelen	path_infor   throwsrV   throw_errorsrW   show_tracebacksr   r	   output_statusaccesserror)r   r   pathr   req_protocolrv   r   ru   rpspurlpirp   rs                 r   rE   zRequest.run  s:   > ##,,
>	P"*"4"4S"9"F"FD DK;3D , 2DDK \!_%s<?';;BT))!,-s43G3G3J/KKBBKDM(,H% Cs\)).4c< HD#G}D#--/DLDJDI&.DKDL  $xx33D"&s4+;+;'<'=">>DNR"DJLL$ ;;& HM	/LL! 3 {{ 	 	P   tb9''%<DDt$NOK&(<hm	P(  	/LL.	/s%   E5G /I
 A5II
)I76I7c                 h   	 	 	 | j                  |       d| _        | j                  j                  d       y# t        j                  t        j                  f$ rt t	        j
                         d   }|j                          d| _        | j                  j                  d       t        j                  j                  j                          Y w xY w# d| _        | j                  j                  d       w xY w# | j                  $ r  t        $ r  | j                  r | j!                          Y yw xY w)zPGenerate a response for the resource at self.path_info.

        (Core)
        rd   zbefore_finalize (HTTPError)r   r   N)_do_respondrO   rQ   rP   sysexc_infor   r   rX   rE   ri   ru   finalizer   rV   r   handle_error)r   r   insts      r   r   zRequest.respond  s    
	 29$$Y/ /


01 !--x/A/AB 9<<>!,D%%'!>DJJJNN#45$$--6689 /


01{{ 	 	   	 s9   8 "C9 BCC CC $C66C9 95D10D1c                 2   t         j                  j                  }| j                  t        j                         | j
                  j                  j                         | _        i | _        d| _	        | j                          d| _	        | j                  |       t        j                  | j                  | j                  | j                         | _        | j%                  | j&                         d| _	        | j                  j)                  d       d| _	        | j+                          | j,                  r| j.                  | j0                  vrd| _        d| _	        | j                  j)                  d       | j,                  r| j"                  j3                          d| _	        | j                  j)                  d       | j4                  rd	| _	        | j5                         |_        d
| _	        | j                  j)                  d
       |j7                          y )Nprocess_headersget_resource)request_paramsr}   process_query_stringFr~   r   r   r   )rO   ri   ru   r   NotFoundr%   rX   rb   toolmapsr   r   r   r   RequestBodyr   rv   r   rp   r   configrE   r   process_request_bodyr   methods_with_bodiesprocessr   r   )r   r   ru   s      r   r   zRequest._do_respond  s   ##,,88##%%^^))..0
 '
#
)$**JJT[[B	 	$(


*+ ,
!!# $${{$":"::,1)*


,-$$II &


'(<<"DJ LLNHM '


()r   c                     	 t        j                  | j                  | j                        }| j                  j                  |       y# t        $ r$ t        j                  dd| j                  z        w xY w)zGParse the query string into Python structures.

        (Core)
        )r   i  zgThe given query string could not be processed. Query strings for this resource must be encoded with %r.N)	r
   parse_query_stringr   query_string_encodingUnicodeDecodeErrorrO   rP   r   update)r   r9   s     r   r   zRequest.process_query_string  sx    
	,++!!D,F,FHA 	1 " 	,$$ E**+, ,	,s   +A	 	-A6c                    | j                   }| j                  D ]_  \  }}|j                         }|j                         }t	        j
                  |      ||<   |dk(  sD	 | j                  j                  |       a t        j                  |d      s'| j                  dk\  rDd}t        j                  d|      t	        j                  t        j!                  |d            |d<   t        j!                  |d      }|s.| j"                  j$                  xs | j"                  j&                  }| j(                  d|| _        y# t        $ r$}t        j                  dt        |            d}~ww xY w)zGParse HTTP header data into Python structures.

        (Core)
        Cookiei  NHostr   z*HTTP/1.1 requires a 'Host' request header.z://)rv   r   titlestripr
   decode_TEXT_mayber   loadr   rO   rP   rf   r5   __contains__r   SanitizedHostgetr   nameipr   base)r   rv   r   valueexcmsghosts          r   r   zRequest.process_headers  s0    ,,++ 	<KD% ::<DKKME$66u=GDM
 x<KK$$U+	<"   &1 }}&B((c22&44TXXgv5NOGFOxx(::??3djjmmD!%d3	! # <",,S#c(;;<s   E	E.
E))E.c                 b    | j                   j                  |d| j                        } ||       y)zQCall a dispatcher (which sets self.handler and .config).

        (Core)
        zrequest.dispatchN)r   find_configdispatch)r   r   r   s      r   r   zRequest.get_resource  s-     88''$dmm5 	r   c                    	 | j                   j                  d       | j                  r| j                          | j                   j                  d       t        j                  j
                  j                          y# t        j                  $ rR t        j                         d   }|j                          t        j                  j
                  j                          Y yw xY w)zAHandle the last unanticipated exception.

        (Core)
        r   r   rd   N)rX   rE   r   rO   ri   ru   r   rQ   r   r   r   )r   r   s     r   r   zRequest.handle_error  s    
		1JJNN23""##%JJNN12%%..0$$ 	1<<>!$D%%..0	1s   A:A= =A"C"!C"r   )r   r   )Hr'   r&   r/   r0   prevr
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rv   r   r   r   r   r   rp   rO   r   
Dispatcherr   r   loginr   r   r   r   is_indexr2   
hookpointsrX   rP   r   r   r{   r   show_mismatched_paramsKeyboardInterrupt
SystemExitrR   r   r   r   r   r   r   NamespaceSetrl   rr   rw   r|   r   r   r   r   rE   r   r   r   r   r   r   r   r   r   r   r      s   
 D HMM+r*EHX]];-FHF
 !O  D L F L # HB F K
 !h  "G ^FE&  B 3 D   ++-H
 K I EC CIGC HC F	 H> JE (X'',99N) J, O1 "9  X-F-FGFELL FFE
 IL&&& #')-NN	J 8>!+%4	!jX 2/b %4N1r   r   c                   "    e Zd ZdZdZddZd Zy)ResponseBodyz4The body of the HTTP response (the response entity).zPPage handlers MUST return bytes. Use tools.encode if you wish to return unicode.Nc                 "    || S |j                   S r4   )_body)r   objobjclasss      r   __get__zResponseBody.__get__1  s    ;K99r   c                     t        |t              rt        | j                        t        |t              r't        d |D              rt        | j                        t        j                  |      |_        y )Nc              3   <   K   | ]  }t        |t                y wr4   )rK   rf   ).0items     r   	<genexpr>z'ResponseBody.__set__.<locals>.<genexpr>>  s     ;T:dC(;s   )	rK   rf   
ValueErrorunicode_errr`   anyr   prepare_iterr   )r   r   r   s      r   __set__zResponseBody.__set__8  sX    eS!T--..t$;U;; !1!122))%0	r   r4   )r'   r&   r/   r0   r	  r  r  r   r   r   r   r   +  s    >4K	1r   r   c                       e Zd ZdZdZ	 g Z	  ej                         Z	  e	       Z
	  e       Z	 dZ	 dZ	 d Zd Zd Zd Zy)	Responsez6An HTTP Response, including status, headers, and body.r   NFc                 T   d | _         d | _        g | _        t        j                         | _        t	        j
                         | _        t        j                  | j                  ddt        j                  z   t	        j                  | j                        d       t               | _        y )Nz	text/htmlz	CherryPy/)zContent-TypeServerDate)statusr   r   timer
   r   rv   r5   r   rO   __version__HTTPDater   r   r   s    r   r   zResponse.__init__l  s|    
IIK	))+ 	DLL'!H$8$88%%dii0#
 	
 #nr   c                 J    dj                  | j                        }|| _        |S )z@Collapse self.body to a single string; replace it and return it.r   )r(   rp   )r   new_bodys     r   collapse_bodyzResponse.collapse_body|  s     88DII&	r   c                 @    t        t        | j                               y)zDiscard self.body but consume any generator such that any
        finalization can occur, such as is required by caching.tee_output().N)r   rC   rp   r   s    r   _flush_bodyzResponse._flush_body  s     	TYY r   c                 <   	 t        j                  | j                        \  }}}| j                  }|d|| _        t        t        |      d      dz   |j                  |      z   | _        | j                  r.t        j!                  |d      t        j#                  |dd       n~|d	k  s|d
v r/t        j#                  |dd       | j%                          d| _        nFt        j!                  |d      0| j)                         }t        j+                  |dt-        |             |j/                         x| _        }| j2                  j/                         }|r|j5                  d      D ]l  }|j5                  dd      \  }	}
t7        |	t              r|	j                  d      }	t7        |
t              r|j                  |
      }
|j9                  |	|
f       n yy# t        $ r9 t	        j
                  dt        j                         d   j                  d         w xY w)zOTransform headers (and cookies) into self.header_list.

        (Core)
        r   rd   r   r   ascii    zContent-LengthN   )      i0  r   z
z: z
ISO-8859-1)r
   valid_statusr  r  rO   rP   r   r   argsrv   r   rf   encoder   streamr5   r   popr  rp   r  __setitem__r   outputr   r   re   rK   r>   )r   codereason_rv   contenthr   liner   r   s              r   r   zResponse.finalize  s   
	E&33DKK@OD&! ,,!%v.!#d)W5>>&)* ;; xx!12:"2D9CZ4?2 HHW.5DI xx!12:,,.  *:CLI  '~~//1##%V, ("jjq1edC(;;|4DeS)#NN51E$'( C  	E$$S#,,.*;*@*@*CDD	Es   #G AH)r'   r&   r/   r0   r  r   r
   r   rv   r   r   r   rp   r  r$  r   r  r  r   r   r   r   r  r  D  sl    @F1K !h  "G ^F>D1D
 F-% !
/(r   r  c                   "    e Zd Zd Zed        Zy)r   c                 ,    t        | j                        S )z*Return UUID4 and keep it for future calls.)rf   uuid4r   s    r   __str__zLazyUUID4.__str__  s    4::r   c                     	 | j                    | j                   S # t        $ r' t        j                         | _         Y | j                   S w xY w)zfProvide unique id on per-request basis using UUID4.

        It's evaluated lazily on render.
        )_uuid4AttributeErroruuidr0  r   s    r   r0  zLazyUUID4.uuid4  sB    	'KK
 {{	  	'**,DK{{		's    "A
	A
N)r'   r&   r/   r1  propertyr0  r   r   r   r   r     s      r   r   )"r   r  rL   rT   http.cookiesr   r   r5  more_itertoolsr   rO   cherrypy._cpcompatr   r   cherrypy._cperrorr   r	   cherrypy.libr
   r   r   objectr   r5   r2   rl   rr   rw   r|   r   r   r   r  r   r   r   r   <module>r=     s    
    2  "  #  4 5 58B6 8Bv@
d @
J
801/?
h	1f h	1V16 12r(v r(j r   