
2\c           @   s  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	 d d l
 Z
 d d l Z y$ d d l m Z d d l m Z Wn1 e k
 r d d l m Z d d l m Z n Xy d d l m Z Wn! e k
 rd d l m Z n Xd d l m Z d d l m Z m Z m Z m 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$ d d l% m& Z& m' Z' d d l( Z( d d l) m* Z* d d l+ m, Z, d d l- m. Z. m/ Z/ m0 Z0 m1 Z1 d d l2 m3 Z3 e j4 d  Z5 e6 a7 d   Z8 d   Z9 d e j: f d     YZ; d e; f d     YZ< d e< f d     YZ= d e< f d     YZ> d e< e j? f d     YZ@ d   ZA e jB ZB d e< e j? f d      YZC d! e= f d"     YZD d# e j: f d$     YZE d% e< f d&     YZF d' e j: f d(     YZG d) e< f d*     YZH d+ ZI d, eE f d- eD f d. e j? f d/ eH f g ZJ d S(0   s.   Base Tornado handlers for the notebook server.iN(   t	   responses(   t   Morsel(   t   urlparse(   t   TemplateNotFound(   t   webt   gent   escapet   httputil(   t   app_log(   t   get_sys_info(   t   Application(   t   filefind(   t   string_typest   PY3(   t   utcnow(   t   combine_translations(   t	   is_hiddent   url_path_joint   url_is_absolutet
   url_escape(   t   csp_report_uris   [^A-Za-z0-9]c           C   s%   t  d  k r! t j t    a  n  t  S(   N(   t   _sys_info_cachet   Nonet   jsont   dumpsR	   (    (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyt   json_sys_info4   s    c           C   s!   t  j   r t  j   j St Sd  S(   N(   R
   t   initializedt   instancet   logR   (    (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR   :   s    t   AuthenticatedHandlerc           B   s   e  Z d  Z e d    Z d   Z d d d  Z d   Z d   Z	 d   Z
 e d    Z e d	    Z e d
    Z e d    Z e d    Z e d    Z RS(   s,   A RequestHandler with an authenticated user.c         C   s\   d |  j  j d i   k r* |  j  d d Sd j d d |  j  j d t |  j t   g  S(   s   The default Content-Security-Policy header
        
        Can be overridden by defining Content-Security-Policy in settings['headers']
        s   Content-Security-Policyt   headerss   ; s   frame-ancestors 'self's   report-uri R   (   t   settingst   gett   joinR   t   base_urlR   (   t   self(    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyt   content_security_policyC   s
    c         C   s   i  } d | d <| j  |  j j d i    |  j | d <xT | j   D]F \ } } y |  j | |  WqF t k
 r } |  j j |  qF XqF Wd  S(   Nt   nosniffs   X-Content-Type-OptionsR   s   Content-Security-Policy(	   t   updateR   R    R$   t   itemst
   set_headert	   ExceptionR   t   debug(   R#   R   t   header_namet   valuet   e(    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyt   set_default_headersS   s    
t   /c         C   s   t  j |  } t j j   t j d d  } t   } | j | d d  t j |  | d <| | d <| rz | | d <n  |  j	 d | j
    d	 S(
   s  Deletes the cookie with the given name.

        Tornado's cookie handling currently (Jan 2018) stores cookies in a dict
        keyed by name, so it can only modify one cookie with a given name per
        response. The browser can store multiple cookies with the same name
        but different domains and/or paths. This method lets us clear multiple
        cookies with the same name.

        Due to limitations of the cookie protocol, you must pass the same
        path and domain to clear a cookie as were used when that cookie
        was set (but there is no way to find out on the server side
        which values were used for a given cookie).
        t   daysim  t    s   ""t   expirest   patht   domains
   Set-CookieN(   R   t
   native_strt   datetimeR   t	   timedeltaR   t   setR   t   format_timestampt
   add_headert   OutputString(   R#   t   nameR3   R4   R2   t   morsel(    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyt   force_clear_cookied   s    	
c         C   si   |  j  j d i   } | j d |  j  } |  j |  j d | | re | d k re |  j |  j  n  d  S(   Nt   cookie_optionsR3   R/   (   R   R    t
   setdefaultR"   t   clear_cookiet   cookie_nameR>   (   R#   R?   R3   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyt   clear_login_cookie}   s
    c         C   s#   |  j  d  k r d S|  j  j |   S(   Nt	   anonymous(   t   login_handlerR   t   get_user(   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyt   get_current_user   s    c         C   sM   |  j  j d k r t S|  j d k s8 t |  j d  r< t S|  j j |   S(   s   Ask my login_handler if I should skip the origin_check
        
        For example: in the default LoginHandler, if a request is token-authenticated,
        origin checking should be skipped.
        t   OPTIONSt   should_check_originN(   t   requestt   methodt   TrueRE   R   t   hasattrt   FalseRI   (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyt   skip_check_origin   s
    "c         C   s6   |  j  d k s" t |  j  d  r& t S|  j  j |   S(   s'   Have I been authenticated with a token?t   is_token_authenticatedN(   RE   R   RM   RN   RP   (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyt   token_authenticated   s    "c         C   s4   t  j d d j |  j j   } |  j j d |  S(   Nt   -s   username-{}RB   (   t   non_alphanumt   subt   formatRJ   t   hostR   R    (   R#   t   default_cookie_name(    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyRB      s    c         C   s   |  j    } | o | d k S(   s   Is a user currently logged in?RD   (   RG   (   R#   t   user(    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyt	   logged_in   s    c         C   s   |  j  j d d  S(   s6   Return the login handler for this application, if any.t   login_handler_classN(   R   R    R   (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyRE      s    c         C   s   |  j  j d d  S(   s4   Return the login token for this application, if any.t   tokenN(   R   R    R   (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR[      s    c         C   s,   |  j  d k r t St |  j  j |  j   S(   s   May a user proceed to log in?

        This returns True if login capability is available, irrespective of
        whether the user is already logged in or not.

        N(   RE   R   RN   t   boolt   get_login_availableR   (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyt   login_available   s    N(   t   __name__t
   __module__t   __doc__t   propertyR$   R.   R   R>   RC   RG   RO   RQ   RB   RY   RE   R[   R^   (    (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR   @   s   				t   IPythonHandlerc           B   s  e  Z d  Z e d    Z e d    Z e d    Z e d    Z e d    Z e d    Z	 e d    Z
 e d    Z e d	    Z e d
    Z e d    Z e d    Z e d    Z e d    Z e d    Z e d    Z e d    Z e d    Z e d    Z e d    Z d   Z d   Z d   Z d d  Z d   Z d   Z d   Z d   Z d   Z  d   Z! e d     Z" d!   Z# d"   Z$ RS(#   s{   IPython-specific extensions to authenticated handling
    
    Mostly property shortcuts to IPython-specific settings.
    c         C   s   |  j  j d t  S(   s   Wether to user bundle in template. (*.min files)
        
        Mainly use for development and avoid file recompilation
        t   ignore_minified_js(   R   R    RN   (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyRd      s    c         C   s   |  j  j d d   S(   Nt   config(   R   R    R   (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyRe      s    c         C   s   t    S(   s@   use the IPython log by default, falling back on tornado's logger(   R   (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR      s    c         C   s   |  j  j d i   S(   s2   User-supplied values to supply to jinja templates.t   jinja_template_vars(   R   R    (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyRf      s    c         C   s   |  j  j d d  S(   s8   The version hash to use for cache hints for static filest   version_hashR1   (   R   R    (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyRg      s    c         C   s<   |  j  j d d  } | s( t |  r, | St |  j |  S(   Nt   mathjax_urlR1   (   R   R    R   R   R"   (   R#   t   url(    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyRh      s    c         C   s   |  j  j d d  S(   Nt   mathjax_configs   TeX-AMS-MML_HTMLorMML-full,Safe(   R   R    (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyRj      s    c         C   s   |  j  j d d  S(   NR"   R/   (   R   R    (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR"      s    c         C   s   |  j  j d d  S(   Nt   default_urlR1   (   R   R    (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyRk      s    c         C   s   |  j  j d d  S(   Nt   websocket_urlR1   (   R   R    (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyt   ws_url   s    c         C   s5   |  j  j d |  j j d d   |  j j d d  S(   Ns   Using contents: %st   contents_js_sources   services/contents(   R   R*   R   R    (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyRn     s    
c         C   s   |  j  d S(   Nt   kernel_manager(   R   (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyRo     s    c         C   s   |  j  d S(   Nt   contents_manager(   R   (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyRp     s    c         C   s   |  j  d S(   Nt   session_manager(   R   (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyRq     s    c         C   s   |  j  d S(   Nt   terminal_manager(   R   (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyRr     s    c         C   s   |  j  d S(   Nt   kernel_spec_manager(   R   (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyRs     s    c         C   s   |  j  d S(   Nt   config_manager(   R   (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyRt     s    c         C   s   |  j  j d d  S(   s"   Normal Access-Control-Allow-Origint   allow_originR1   (   R   R    (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyRu   '  s    c         C   s   |  j  j d d  S(   s*   Regular expression version of allow_origint   allow_origin_patN(   R   R    R   (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyRv   ,  s    c         C   s   |  j  j d t  S(   s/   Whether to set Access-Control-Allow-Credentialst   allow_credentials(   R   R    RN   (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyRw   1  s    c         C   s   t  t |   j   |  j r2 |  j d |  j  n |  j ru |  j   } | r |  j j |  r |  j d |  q nI |  j r d |  j	 j
 d i   k r |  j d |  j j j
 d d   n  |  j r |  j d d  n  d S(   s   Add CORS headers, if defineds   Access-Control-Allow-OriginR   t   OriginR1   s    Access-Control-Allow-Credentialst   trueN(   t   superRc   R.   Ru   R(   Rv   t
   get_origint   matchRQ   R   R    RJ   R   Rw   (   R#   t   origin(    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR.   6  s    					c         C   s,   t  |  } |  j d d j d |   d S(   sp   Set Content-Disposition: attachment header

        As a method to ensure handling of filename encoding
        s   Content-Dispositions#   attachment; filename*=utf-8''{utf8}t   utf8N(   R   R(   RU   (   R#   t   filenamet   escaped_filename(    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyt   set_attachment_headerL  s    		c         C   sF   d |  j  j k r* |  j  j j d  } n |  j  j j d d   } | S(   NRx   s   Sec-Websocket-Origin(   RJ   R   R    R   (   R#   R}   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR{   Z  s    R1   c         C   s  |  j  d k s |  j   r t S|  j j j d  } |  j j j d  } | d k sa | d k re t S| j   } t |  j	 } | | k r t S|  j  r |  j  | k } n* |  j
 r t |  j
 j |   } n t } | s |  j j d |  j j | |  n  | S(   s   Check Origin for cross-site API requests, including websockets

        Copied from WebSocket with changes:

        - allow unspecified host/origin (e.g. scripts)
        - allow token-authenticated requests
        t   *t   HostRx   s?   Blocking Cross Origin API request for %s.  Origin: %s, Host: %sN(   Ru   RO   RL   RJ   R   R    R   t   lowerR   t   netlocRv   R\   R|   RN   R   t   warningR3   (   R#   t   origin_to_satisfy_tornadoRV   R}   t   origin_hostt   allow(    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyt   check_origing  s&    		c         C   s  |  j  j j d  } |  j  j j d  } | sD |  j j d  t S| s^ |  j j d  t St |  } | j } | | k r t Sd j	 | j
 | j  } |  j r |  j | k } n* |  j r t |  j j |   } n t } | s|  j j d |  j  j | |  n  | S(   s^  Check Referer for cross-site requests.

        Disables requests to certain endpoints with
        external or missing Referer.

        If set, allow_origin settings are applied to the Referer
        to whitelist specific cross-origin sites.

        Used on GET for api endpoints and /files/
        to block cross-site inclusion (XSSI).
        R   t   Referers   Blocking request with no hosts    Blocking request with no referers   {}://{}s<   Blocking Cross Origin request for %s.  Referer: %s, Host: %s(   RJ   R   R    R   R   RN   R   R   RL   RU   t   schemeRu   Rv   R\   R|   R3   (   R#   RV   t   referert   referer_urlt   referer_hostR}   R   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyt   check_referer  s,    			c         C   s   |  j  s |  j j d t  r" d Sy t t |   j   SWn t j k
 r } |  j	 j
 d d h k r |  j   s |  j	 j j d  } | r d j |  } n d } t j d |   q q   n Xd S(	   s2   Bypass xsrf cookie checks when token-authenticatedt   disable_check_xsrfNt   GETt   HEADR   s&   Blocking Cross Origin request from {}.s$   Blocking request from unknown origini  (   RQ   R   R    RN   Rz   Rc   t   check_xsrf_cookieR   t	   HTTPErrorRJ   RK   R   R   RU   (   R#   R-   R   t   msg(    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR     s    c         C   s   |  j  j d t  r t St j d |  j j  j d  } | j	 d  rh | j
 d  rh | d d !} n  t s | j d d  } n  y t j |  } Wn/ t k
 r | |  j  j d	 d
 g  k } n
 X| j } | s |  j j d | |  j j  n  | S(   s   Check the host header if remote access disallowed.

        Returns True if the request should continue, False otherwise.
        t   allow_remote_accesss   ^(.*?)(:\d+)?$i   t   [t   ]iR~   t   replacet   local_hostnamest	   localhosts   Blocking request with non-local 'Host' %s (%s). If the notebook should be accessible at that name, set NotebookApp.allow_remote_access to disable the check.(   R   R    RN   RL   t   reR|   RJ   RV   t   groupt
   startswitht   endswithR   t   decodet	   ipaddresst
   ip_addresst
   ValueErrort   is_loopbackR   R   (   R#   RV   t   addrR   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyt
   check_host  s"    !"		c         C   s1   |  j    s t j d   n  t t |   j   S(   Ni  (   R   R   R   Rz   Rc   t   prepare(   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR     s    c         C   s   |  j  d j |  S(   s1   Return the jinja template object for a given namet
   jinja2_env(   R   t   get_template(   R#   R<   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR      s    c         K   s,   | j  |  j  |  j |  } | j |   S(   N(   R&   t   template_namespaceR   t   render(   R#   R<   t   nst   template(    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyt   render_template  s    c      %   C   s   t  d |  j d |  j d |  j d |  j d |  j j d  d |  j d t |  j	  d |  j
 d	 t   d
 |  j d |  j d |  j d |  j d |  j	 d |  j j d  d t j t |  j j j d d    |  j  S(   NR"   Rk   Rm   RY   t   allow_password_changeR^   t   token_availablet
   static_urlt   sys_infoRn   Rg   Rd   t   xsrf_form_htmlR[   t
   xsrf_tokenR~   t   nbjs_translationss   Accept-LanguageR1   (   t   dictR"   Rk   Rm   RY   R   R    R^   R\   R[   R   R   Rn   Rg   Rd   R   R   R   R   R   R   RJ   R   Rf   (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR   	  s&    													c         C   s   |  j  j s d S|  j  j j   j d  } y t j |  } WnL t k
 r |  j j	 d |  |  j j
 d d t t j d d   n X| S(   s,   Return the body of the request as JSON data.u   utf-8s   Bad JSON: %rs   Couldn't parse JSONt   exc_infoi  u   Invalid JSON in body of requestN(   RJ   t   bodyR   t   stripR   R   t   loadsR)   R   R*   t   errorRL   R   R   (   R#   R   t   model(    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyt   get_json_body   s    c   
   	   K   s  | j  d  } d } t j  | d  } d } | r | d } y | j | j } Wn t k
 rd n Xt | d d  } | r | } q n  t d | d | d	 | d
 |  } |  j d d  y |  j d | |  }	 Wn# t	 k
 r |  j d |  }	 n X|  j
 |	  d S(   s   render custom error pagesR   R1   s   Unknown HTTP Errors	   (unknown)i   t   reasont   status_codet   status_messaget   messaget	   exceptions   Content-Types	   text/htmls   %s.htmls
   error.htmlN(   R    R    t   log_messaget   argsR)   t   getattrR   R(   R   R   t   write(
   R#   R   t   kwargsR   R   R   R   R   R   t   html(    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyt   write_error.  s0    
	(%   R_   R`   Ra   Rb   Rd   Re   R   Rf   Rg   Rh   Rj   R"   Rk   Rm   Rn   Ro   Rp   Rq   Rr   Rs   Rt   Ru   Rv   Rw   R.   R   R{   R   R   R   R   R   R   R   R   R   R   (    (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyRc      sD   	
			,	+		$					t
   APIHandlerc           B   sb   e  Z d  Z d   Z d   Z d   Z d   Z e d    Z e	 Z
 d   Z d   Z d   Z RS(	   s   Base class for API handlersc         C   s1   |  j    s t j d   n  t t |   j   S(   Ni  (   R   R   R   Rz   R   R   (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR   V  s    c         K   s   |  j  d d  t j | d  } i | d 6} | j d  } | r | d } t | t  r | j pi | | d <| j | d <q d | d <d | d <d	 j t	 j
 |    | d
 <n  |  j j | d  |  j t j |   d S(   s+   APIHandler errors are JSON, not human pagess   Content-Types   application/jsons   Unknown HTTP ErrorR   R   i   R   s   Unhandled errorR1   t	   tracebackN(   R(   R    R    t
   isinstanceR   R   R   R   R!   R   t   format_exceptionR   R   t   finishR   R   (   R#   R   R   R   t   replyR   R-   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR   [  s    



c         C   s6   t  |  d  r |  j St t |   j   |  _ } | S(   sD   Raise 403 on API handlers instead of redirecting to human login paget   _user_cache(   RM   R   Rz   R   RG   (   R#   RX   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyRG   o  s    c         C   s.   |  j  s t j d   n  t t |   j   S(   Ni  (   t   current_userR   R   Rz   R   t   get_login_url(   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR   w  s    	c         C   s%   d j  t t |   j d g  } | S(   Ns   ; s   default-src 'none'(   R!   Rz   R   R$   (   R#   t   csp(    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR$     s    c         C   s2   |  j  r. t |  d d  r. t   |  j d <n  d S(   s$   Update last_activity of API requestsR   t   api_last_activityN(   t   _track_activityR   R   R   R   (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyt   update_api_activity  s    c         O   s3   |  j    |  j d d  t t |   j | |   S(   Ns   Content-Types   application/json(   R   R(   Rz   R   R   (   R#   R   R   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR     s    
c         O   s   d |  j  j d i   k r9 |  j d |  j  d d  n |  j d d  |  j d d  |  j j j d d  j d  } | r t d	   | D  r |  j r |  j s |  j	 s d
 |  j  j d i   k r |  j d
 |  j j j d d   n  d  S(   Ns   Access-Control-Allow-HeadersR   s0   accept, content-type, authorization, x-xsrftokens   Access-Control-Allow-Methodss&   GET, PUT, POST, PATCH, DELETE, OPTIONSs   Access-Control-Request-HeadersR1   t   ,c         s   s'   |  ] } | j    j   d  k Vq d S(   t   authorizationN(   R   R   (   t   .0t   h(    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pys	   <genexpr>  s   s   Access-Control-Allow-OriginRx   (
   R   R    R(   RJ   R   t   splitt   anyR^   Ru   Rv   (   R#   R   R   t   requested_headers(    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyt   options  s     		!					(   R_   R`   Ra   R   R   RG   R   Rb   R$   RL   R   R   R   R   (    (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR   S  s   							t   Template404c           B   s   e  Z d  Z d   Z RS(   s   Render our 404 templatec         C   s   t  j d   d  S(   Ni  (   R   R   (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR     s    (   R_   R`   Ra   R   (    (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR     s   t   AuthenticatedFileHandlerc           B   se   e  Z d  Z e d    Z e j d    Z e j d    Z d   Z	 d   Z
 d   Z d   Z RS(   s5   static files should only be accessible when logged inc         C   s   t  t |   j d S(   Ns   ; sandbox allow-scripts(   Rz   R   R$   (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR$     s    c         C   s    |  j    t t |   j |  S(   N(   R   Rz   R   t   head(   R#   R3   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR     s    
c         C   sq   |  j    t j j |  d d k s8 |  j d t  r^ | j d d  d } |  j |  n  t j	 j
 |  |  S(   Ni   s   .ipynbt   downloadR/   i(   R   t   osR3   t   splitextt   get_argumentRN   t   rsplitR   R   t   StaticFileHandlerR    (   R#   R3   R<   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR      s
    
.c         C   s   |  j  j d  } d | k r9 | j d d  \ } } n | } | j d  rR d St j |  d } | d k ru d St t |   j   Sd  S(   NR/   i   s   .ipynbs   application/x-ipynb+jsoni    s
   text/plains   text/plain; charset=UTF-8(	   t   absolute_pathR   R   R   t	   mimetypest
   guess_typeRz   R   t   get_content_type(   R#   R3   t   _R<   t   cur_mime(    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR     s    c         C   s<   t  t |   j   d |  j j k r8 |  j d d  n  d  S(   Nt   vs   Cache-Controls   no-cache(   Rz   R   t   set_headersRJ   t	   argumentsR:   (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR     s    c         C   s   d  S(   N(   R   (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyt   compute_etag  s    c         C   so   t  t |   j | |  } t j j |  } t | |  rk |  j j rk |  j	 j
 d  t j d   n  | S(   s   Validate and return the absolute path.
        
        Requires tornado 3.1
        
        Adding to tornado's own handling, forbids the serving of hidden files.
        s_   Refusing to serve hidden file, via 404 Error, use flag 'ContentsManager.allow_hidden' to enablei  (   Rz   R   t   validate_absolute_pathR   R3   t   abspathR   Rp   t   allow_hiddenR   t   infoR   R   (   R#   t   rootR   t   abs_patht   abs_root(    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR     s    (   R_   R`   Ra   Rb   R$   R   t   authenticatedR   R    R   R   R   R   (    (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR     s   
			c            s8   t  j d t d d t j      f d    } | S(   s  Decorate methods with this to return GitHub style JSON errors.
    
    This should be used on any JSON API on any handler method that can raise HTTPErrors.
    
    This will grab the latest HTTPError exception using sys.exc_info
    and then:
    
    1. Set the HTTP status code based on the HTTPError
    2. Create and return a JSON body with a message field describing
       the error in a human readable form.
    sJ   @json_errors is deprecated in notebook 5.2.0. Subclass APIHandler instead.t
   stackleveli   c            s(   t  j t j |   |  _   |  | |  S(   N(   t   typest
   MethodTypeR   R   (   R#   R   R   (   RK   (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyt   wrapper  s    (   t   warningst   warnt   DeprecationWarningt	   functoolst   wraps(   RK   R   (    (   RK   s5   lib/python2.7/site-packages/notebook/base/handlers.pyt   json_errors  s
    	t   FileFindHandlerc           B   sM   e  Z d  Z i  Z d   Z d d d  Z d   Z e d    Z	 d   Z
 RS(   sB   subclass of StaticFileHandler for serving files from a search pathc            s[   t  t    j   d   j j k sD t   f d     j D  rW   j d d  n  d  S(   NR   c         3   s$   |  ] }   j  j j |  Vq d  S(   N(   RJ   R3   R   (   R   R3   (   R#   (    s5   lib/python2.7/site-packages/notebook/base/handlers.pys	   <genexpr>$  s    s   Cache-Controls   no-cache(   Rz   R  R   RJ   R   R   t   no_cache_pathsR(   (   R#   (    (   R#   s5   lib/python2.7/site-packages/notebook/base/handlers.pyR      s    c         C   sP   | p	 g  |  _  t | t  r* | g } n  t d   | D  |  _ | |  _ d  S(   Nc         s   s4   |  ]* } t  j j t  j j |   t  j Vq d  S(   N(   R   R3   R   t
   expandusert   sep(   R   t   p(    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pys	   <genexpr>.  s    (   R  R   R   t   tupleR   t   default_filename(   R#   R3   R  R  (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyt
   initialize'  s    c         C   s   d  S(   N(   R   (   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR   2  s    c      	   C   s   |  j  ~ | |  j k r$ |  j | Sy t j j t | |   } Wn t k
 rW d SX| |  j | <t   j d | | f  | SWd QXd S(   s5   locate a file to serve on our static file search pathR1   s   Path %s served from %sN(	   t   _lockt   _static_pathsR   R3   R   R   t   IOErrorR   R*   (   t   clst   rootsR3   R   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyt   get_absolute_path5  s    
c         C   se   | d k r t  j d   n  x+ |  j D]  } | t j j |  r( Pq( q( Wt t |   j | |  S(   s:   check if the file should be served (raises 404, 403, etc.)R1   i  (	   R   R   R   R   R  R   Rz   R  R   (   R#   R   R   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR   G  s    N(   R_   R`   Ra   R  R   R   R  R   t   classmethodR  R   (    (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR    s   		t   APIVersionHandlerc           B   s   e  Z d    Z RS(   c         C   s$   |  j  t j i t j d 6  d  S(   Nt   version(   R   R   R   t   notebookt   __version__(   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR    U  s    (   R_   R`   R    (    (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR  S  s   t   TrailingSlashHandlerc           B   s!   e  Z d  Z d   Z e Z Z RS(   sv   Simple redirect handler that strips trailing slashes
    
    This should be the first, highest priority handler.
    c         C   s    |  j  |  j j j d   d  S(   NR/   (   t   redirectRJ   t   urit   rstrip(   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR    `  s    (   R_   R`   Ra   R    t   postt   put(    (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR  Z  s   	t   FilesRedirectHandlerc           B   s)   e  Z d  Z e d    Z d d  Z RS(   s<   Handler for redirecting relative URLs to the /files/ handlerc         C   s  |  j  } | j |  r6 t |  j d t |   } n | } | j d  } | j d |  r d | k r |  j j d |  | j	 d  d j
 |  } n  | j d |  s t j d   n  t |  j d t |   } |  j j d |  j j |  |  j |  d S(	   so   make redirect logic a reusable static method
        
        so it can be called from other handlers.
        t   treeR/   R3   t   filess   Deprecated files/ URL: %si  s   Redirecting %s to %sN(   Rp   t
   dir_existsR   R"   R   R   t   file_existsR   R   t   removeR!   R   R   R*   RJ   R3   R  (   R#   R3   t   cmRi   t	   orig_patht   parts(    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyt   redirect_to_filesi  s    	R1   c         C   s   |  j  |  |  S(   N(   R'  (   R#   R3   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR      s    (   R_   R`   Ra   t   staticmethodR'  R    (    (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR  f  s   t   RedirectWithParamsc           B   s#   e  Z d  Z e d  Z d   Z RS(   s8   Sam as web.RedirectHandler, but preserves URL parametersc         C   s   | |  _  | |  _ d  S(   N(   t   _urlt
   _permanent(   R#   Ri   t	   permanent(    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR    s    	c         C   sS   d |  j  k r d n d } | j |  j  |  j j g  } |  j | d |  j d  S(   Nt   ?t   &R,  (   R*  R!   RJ   t   queryR  R+  (   R#   R  Ri   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR      s    (   R_   R`   Ra   RL   R  R    (    (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR)    s   t   PrometheusMetricsHandlerc           B   s    e  Z d  Z e j d    Z RS(   s<   
    Return prometheus metrics for this notebook server
    c         C   s0   |  j  d t j  |  j t j t j   d  S(   Ns   Content-Type(   R(   t   prometheus_clientt   CONTENT_TYPE_LATESTR   t   generate_latestt   REGISTRY(   R#   (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR      s    (   R_   R`   Ra   R   R   R    (    (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyR0    s   s   (?P<path>(?:(?:/[^/]+)+|/?))s   .*/t   apis   /(robots\.txt|favicon\.ico)s   /metrics(K   Ra   R6   R  R   R   R   R   R   t   sysR   R   R   t   http.clientR    t   http.cookiesR   t   ImportErrort   httplibt   Cookiet   urllib.parseR   t   jinja2R   t   tornadoR   R   R   R   t   tornado.logR   R1  t   notebook._sysinfoR	   t   traitlets.configR
   t   ipython_genutils.pathR   t   ipython_genutils.py3compatR   R   R  t   notebook._tzR   t   notebook.i18nR   t   notebook.utilsR   R   R   R   t   notebook.services.securityR   t   compileRS   R   R   R   R   t   RequestHandlerR   Rc   R   R   R   R   R  R   R  R  R  R  R)  R0  t
   path_regext   default_handlers(    (    (    s5   lib/python2.7/site-packages/notebook/base/handlers.pyt   <module>   sr   ""		 b@		9$		