
v^                 @   s   d  d l  Z  d  d l m Z d  d l m Z d  d l m Z d  d l m Z d  d l	 m
 Z
 d  d l m Z d  d l m Z d  d	 l m Z Gd
 d   d e  Z Gd d   d e  Z d S)    N)urlparse)settings)PermissionDenied)mail_managers)HttpResponsePermanentRedirect)is_valid_path)MiddlewareMixin)escape_leading_slashesc               @   sL   e  Z d  Z d Z e Z d d   Z d d   Z d d   Z d d	   Z	 d
 S)CommonMiddlewarea  
    "Common" middleware for taking care of some basic operations:

        - Forbid access to User-Agents in settings.DISALLOWED_USER_AGENTS

        - URL rewriting: Based on the APPEND_SLASH and PREPEND_WWW settings,
          append missing slashes and/or prepends missing "www."s.

            - If APPEND_SLASH is set and the initial URL doesn't end with a
              slash, and it is not found in urlpatterns, form a new URL by
              appending a slash at the end. If this new URL is found in
              urlpatterns, return an HTTP redirect to this new URL; otherwise
              process the initial URL as usual.

          This behavior can be customized by subclassing CommonMiddleware and
          overriding the response_redirect_class attribute.
    c             C   s   | j  j d  } | d k	 rM x, t j D]! } | j |  r( t d   q( W| j   } t j ou | ou | j d  } | r d | j	 | f n d } |  j
 |  r |  j |  } n | j   } | s | | j   k r | | 7} |  j |  Sd S)z
        Check for denied User-Agents and rewrite the URL based on
        settings.APPEND_SLASH and settings.PREPEND_WWW
        HTTP_USER_AGENTNzForbidden user agentzwww.z%s://www.%s )METAgetr   ZDISALLOWED_USER_AGENTSsearchr   get_hostZPREPEND_WWW
startswithschemeshould_redirect_with_slashget_full_path_with_slashget_full_pathresponse_redirect_class)selfrequest
user_agentZuser_agent_regexhostZmust_prependZredirect_urlpath r   :/tmp/pip-build-8lau8j11/django/django/middleware/common.pyprocess_request"   s    
z CommonMiddleware.process_requestc             C   sY   t  j rU | j j d  rU t | d d  } t | j |  oT t d | j |  Sd S)z
        Return True if settings.APPEND_SLASH is True and appending a slash to
        the request path turns an invalid path into a valid one.
        /urlconfNz%s/F)r   APPEND_SLASHZ	path_infoendswithgetattrr   )r   r   r    r   r   r   r   ?   s
    z+CommonMiddleware.should_redirect_with_slashc             C   sc   | j  d d  } t |  } t j r_ | j d	 k r_ t d d | j d | j   | i   | S)
z
        Return the full path of the request with a trailing slash appended.

        Raise a RuntimeError if settings.DEBUG is True and request.method is
        POST, PUT, or PATCH.
        Zforce_append_slashTPOSTPUTPATCHa"  You called this URL via %(method)s, but the URL doesn't end in a slash and you have APPEND_SLASH set. Django can't redirect to the slash URL while maintaining %(method)s data. Change your form to point to %(url)s (note the trailing slash), or set APPEND_SLASH=False in your Django settings.methodurl)zPOSTzPUTzPATCH)r   r	   r   DEBUGr'   RuntimeErrorr   )r   r   new_pathr   r   r   r   L   s    	z)CommonMiddleware.get_full_path_with_slashc             C   sk   | j  d k r4 |  j |  r4 |  j |  j |   S| j rg | j d  rg t t | j   | d <| S)z
        When the status code of the response is 404, it may redirect to a path
        with an appended slash if should_redirect_with_slash() returns True.
        i  zContent-Length)	status_coder   r   r   Z	streaming
has_headerstrlencontent)r   r   responser   r   r   process_responsec   s    z!CommonMiddleware.process_responseN)
__name__
__module____qualname____doc__r   r   r   r   r   r2   r   r   r   r   r
      s   r
   c               @   s4   e  Z d  Z d d   Z d d   Z d d   Z d S)BrokenLinkEmailsMiddlewarec             C   s   | j  d k r t j r | j   } | j   } | j j d d  } |  j | | | |  s | j j d d  } | j j d d  } t d |  j	 | |  r d n d | f d	 | | | | f d
 d | S)z=Send broken link emails for relevant 404 NOT FOUND responses.i  ZHTTP_REFERERr   r   z<none>ZREMOTE_ADDRzBroken %slink on %sz	INTERNAL z=Referrer: %s
Requested URL: %s
User agent: %s
IP address: %s
Zfail_silentlyT)
r,   r   r)   r   r   r   r   is_ignorable_requestr   is_internal_request)r   r   r1   domainr   refererZuaipr   r   r   r2   x   s    z+BrokenLinkEmailsMiddleware.process_responsec             C   s#   t  t j d t j |  |   S)ze
        Return True if the referring URL is the same domain as the current
        request.
        z^https?://%s/)boolrematchescape)r   r:   r;   r   r   r   r9      s    z.BrokenLinkEmailsMiddleware.is_internal_requestc                s   | s
 d St  j r<   j d  r< |   d d	  k r< d S|  j | |  r_ d | k r_ d St |  } | j d | g k r | j   k r d St   f d d   t  j D  S)
z
        Return True if the given request *shouldn't* notify the site managers
        according to project settings or in situations outlined by the inline
        comments.
        Tr   N   ?r   c             3   s   |  ] } | j     Vq d  S)N)r   ).0pattern)urir   r   	<genexpr>   s    zBBrokenLinkEmailsMiddleware.is_ignorable_request.<locals>.<genexpr>)	r   r!   r"   r9   r   netlocr   anyZIGNORABLE_404_URLS)r   r   rE   r:   r;   Zparsed_refererr   )rE   r   r8      s    .$z/BrokenLinkEmailsMiddleware.is_ignorable_requestN)r3   r4   r5   r2   r9   r8   r   r   r   r   r7   v   s   r7   )r>   urllib.parser   Zdjango.confr   Zdjango.core.exceptionsr   Zdjango.core.mailr   Zdjango.httpr   Zdjango.urlsr   Zdjango.utils.deprecationr   Zdjango.utils.httpr	   r
   r7   r   r   r   r   <module>   s   i