Example #1
0
    def process_request(self, request):
        old_path = request.path
        if not old_path.endswith("/") or old_path == "/":
            return

        urlconf = getattr(request, "urlconf", None)

        if urlresolvers.is_valid_path(request.path_info, urlconf):
            return

        if not urlresolvers.is_valid_path(request.path_info.rstrip("/"), urlconf):
            return

        new_path = request.path.rstrip("/")

        if s.DEBUG and request.method == 'POST':
            raise RuntimeError((
                "You called this URL via POST, but the URL should not end "
                "in a slash and RemoveTrailingSlashMiddleware is active. "
                "I can't redirect to the slash URL while maintaining POST data. "
                "Change your form to point to %s (no trailing slash)."
            ) %(new_path, ))

        query = request.environ.get("QUERY_STRING")
        if query:
            new_path += "?" + query
        return HttpResponsePermanentRedirect(new_path)
Example #2
0
    def process_response(self, request, response):
        language = translation.get_language()
        language_from_path = translation.get_language_from_path(request.path_info, supported=self._supported_languages)
        if response.status_code == 404 and not language_from_path and self.is_language_prefix_patterns_used():
            urlconf = getattr(request, "urlconf", None)
            language_path = "/%s%s" % (language, request.path_info)
            path_valid = is_valid_path(language_path, urlconf)
            if not path_valid and settings.APPEND_SLASH and not language_path.endswith("/"):
                path_valid = is_valid_path("%s/" % language_path, urlconf)

            if path_valid:
                language_url = "%s://%s/%s%s" % (
                    "https" if request.is_secure() else "http",
                    request.get_host(),
                    language,
                    request.get_full_path(),
                )
                return HttpResponseRedirect(language_url)

        # Store language back into session if it is not present
        if hasattr(request, "session"):
            request.session.setdefault("django_language", language)

        if not (self.is_language_prefix_patterns_used() and language_from_path):
            patch_vary_headers(response, ("Accept-Language",))
        if "Content-Language" not in response:
            response["Content-Language"] = language
        return response
    def process_response(self, request, response):
        language = get_language(request, self.is_language_prefix_patterns_used())
        supported_languages = supported_languages_for_path(request.path_info)['languages']
        language_from_path = translation.get_language_from_path(
            request.path_info, supported=self._supported_languages
        )
        if path_translation_enabled(request.path_info):
            if not language_from_path:
                return redirect(u'/%s%s' % (language, request.path_info))
            elif language_from_path not in supported_languages:
                response = HttpResponseNotFound()

        if (response.status_code == 404 and not language_from_path
            and self.is_language_prefix_patterns_used()):
            urlconf = getattr(request, 'urlconf', None)
            language_path = '/%s%s' % (language, request.path_info)
            path_valid = is_valid_path(language_path, urlconf)
            if (not path_valid and settings.APPEND_SLASH
                and not language_path.endswith('/')):
                path_valid = is_valid_path("%s/" % language_path, urlconf)

            if path_valid and language in supported_languages:
                language_url = "%s://%s/%s%s" % (
                    'https' if request.is_secure() else 'http',
                    request.get_host(), language, request.get_full_path())
                return HttpResponseRedirect(language_url)

        if not (self.is_language_prefix_patterns_used()
                and language_from_path):
            patch_vary_headers(response, ('Accept-Language',))
        if 'Content-Language' not in response:
            response['Content-Language'] = language
        return response
Example #4
0
    def process_request(self, request):

        old_url = request.build_absolute_uri()
        # match any / followed by ? (query string present)
        # OR match / at the end of the string (no query string)
        trailing_slash_regexp = r'(\/(?=\?))|(\/$)'
        new_url = old_url

        if getattr(settings, 'APPEND_SLASH') and getattr(settings, 'REMOVE_SLASH'):
            raise ImproperlyConfigured("APPEND_SLASH and REMOVE_SLASH may not both be True.")

        # Remove slash if REMOVE_SLASH is set and the URL has a trailing slash
        # and there is no pattern for the current path
        if getattr(settings, 'REMOVE_SLASH', False) and re.search(trailing_slash_regexp, old_url):
            urlconf = getattr(request, 'urlconf', None)
            if (not urlresolvers.is_valid_path(request.path_info, urlconf)) and urlresolvers.is_valid_path(request.path_info[:-1], urlconf):
                new_url = re.sub(trailing_slash_regexp, '', old_url)
                if settings.DEBUG and request.method == 'POST':
                    raise RuntimeError((""
                    "You called this URL via POST, but the URL ends in a "
                    "slash and you have REMOVE_SLASH set. Django can't "
                    "redirect to the non-slash URL while maintaining POST "
                    "data. Change your form to point to %s (without a "
                    "trailing slash), or set REMOVE_SLASH=False in your "
                    "Django settings.") % (new_url))

        if new_url == old_url:
            # No redirects required.
            return
        return http.HttpResponsePermanentRedirect(new_url)
    def process_response(self, request, response):
        language = translation.get_language()
        if (response.status_code == 404 and
                not translation.get_language_from_path(request.path_info)
                    and self.is_language_prefix_patterns_used()):
            urlconf = getattr(request, 'urlconf', None)
            language_path = '/%s%s' % (language, request.path_info)
            path_valid = is_valid_path(language_path, urlconf)
            if (not path_valid and settings.APPEND_SLASH
                    and not language_path.endswith('/')):
                path_valid = is_valid_path("%s/" % language_path, urlconf)

            if path_valid:
                path = request.get_full_path()
                script_mount = request.META.get("SCRIPT_NAME", "")
                
                if path.startswith(script_mount):
                    path = path.replace(script_mount, ("%s/%s" % (script_mount, language)), 1)
                
                language_url = "%s://%s%s" % (
                    request.is_secure() and 'https' or 'http',
                    request.get_host(), path)
                return HttpResponseRedirect(language_url)
        translation.deactivate()

        patch_vary_headers(response, ('Accept-Language',))
        if 'Content-Language' not in response:
            response['Content-Language'] = language
        return response
Example #6
0
    def process_response(self, request, response):
        language = translation.get_language()
        language_from_path = translation.get_language_from_path(
                request.path_info, supported=self._supported_languages
        )
        if (response.status_code == 404 and not language_from_path
                and self.is_language_prefix_patterns_used()):
            urlconf = getattr(request, 'urlconf', None)
            language_path = '/%s%s' % (language, request.path_info)
            path_valid = is_valid_path(language_path, urlconf)
            if (not path_valid and settings.APPEND_SLASH
                    and not language_path.endswith('/')):
                path_valid = is_valid_path("%s/" % language_path, urlconf)

            if path_valid:
                language_url = "%s://%s/%s%s" % (
                    request.scheme, request.get_host(), language,
                    request.get_full_path())
                return self.response_redirect_class(language_url)

        # Store language back into session if it is not present
        if hasattr(request, 'session'):
            request.session.setdefault('django_language', language)

        if not (self.is_language_prefix_patterns_used()
                and language_from_path):
            patch_vary_headers(response, ('Accept-Language',))
        if 'Content-Language' not in response:
            response['Content-Language'] = language
        return response
Example #7
0
    def process_response(self, request, response):
        language = translation.get_language()
        language_from_path = translation.get_language_from_path(
                request.path_info, supported=self._supported_languages
        )
        if (response.status_code == 404 and not language_from_path
                and self.is_language_prefix_patterns_used()):
            urlconf = getattr(request, 'urlconf', None)
            language_path = '/%s%s' % (language, request.path_info)
            path_valid = is_valid_path(language_path, urlconf)
            if (not path_valid and settings.APPEND_SLASH
                    and not language_path.endswith('/')):
                path_valid = is_valid_path("%s/" % language_path, urlconf)

            if path_valid:
                language_url = "%s://%s/%s%s" % (
                    request.is_secure() and 'https' or 'http',
                    request.get_host(), language, request.get_full_path())
                return HttpResponseRedirect(language_url)

        if not (self.is_language_prefix_patterns_used()
                and language_from_path):
            patch_vary_headers(response, ('Accept-Language',))
        if 'Content-Language' not in response:
            response['Content-Language'] = language
        return response
Example #8
0
    def process_response(self, request, response):
        language = translation.get_language()
        # Check if app has i18n_patterns urlconf
        is_i18n_pattern = hasattr(request, 'resolver_match') and getattr(request.resolver_match, 'app_name', None) in ('account',)
        # If path is '/', resolver_match is errored and not provided
        if request.path == '/' and request.user.is_anonymous():
            # On home, if not anonymous -> tenant_root
            is_i18n_pattern = True
        if (response.status_code == 404 and
                is_i18n_pattern
           and not translation.get_language_from_path(request.path_info)
           and self.is_language_prefix_patterns_used()):
            urlconf = getattr(request, 'urlconf', None)
            language_path = '/%s%s' % (language, request.path_info)
            path_valid = is_valid_path(language_path, urlconf)
            if (not path_valid and settings.APPEND_SLASH
                    and not language_path.endswith('/')):
                path_valid = is_valid_path("%s/" % language_path, urlconf)

            if path_valid:
                language_url = "%s://%s/%s%s" % (
                    request.is_secure() and 'https' or 'http',
                    request.get_host(), language, request.get_full_path())
                return HttpResponseRedirect(language_url)
        translation.deactivate()

        patch_vary_headers(response, ('Accept-Language',))
        if 'Content-Language' not in response:
            response['Content-Language'] = language
        return response
Example #9
0
    def process_response(self, request, response):
        language = translation.get_language()
        if (response.status_code == 404 and
                not translation.get_language_from_path(request.path_info)
                    and self.is_language_prefix_patterns_used()):
            urlconf = getattr(request, 'urlconf', None)
            language_path = '/%s%s' % (language, request.path_info)
            valid_language_path = language_path
            path_valid = is_valid_path(language_path, urlconf)
            if (not path_valid and settings.APPEND_SLASH
                    and not language_path.endswith('/')):
                path_valid = is_valid_path("%s/" % language_path, urlconf)
                if path_valid:
                    valid_language_path = "%s/" % language_path

            if path_valid and is_valid_path(request.path_info):
                # If the language path is valid and the request's original path
                # is also valid, make sure we're not redirecting to a different view
                path_valid = self._resolves_to_same_view(request.path_info, valid_language_path, urlconf)

            if path_valid:
                language_url = "%s://%s/%s%s" % (
                    request.is_secure() and 'https' or 'http',
                    request.get_host(), language, request.get_full_path())
                return HttpResponseRedirect(language_url)
        translation.deactivate()

        patch_vary_headers(response, ('Accept-Language',))
        if 'Content-Language' not in response:
            response['Content-Language'] = language
        return response
Example #10
0
    def process_response(self, request, response):
        language = translation.get_language()
        if self.use_redirects:
            kwargs = {}
            if django_root_version >= 16:
                kwargs['supported'] = self._supported_languages
            language_from_path = translation.get_language_from_path(
                request.path_info, **kwargs)
            if (response.status_code == 404 and not language_from_path
                    and self.is_language_prefix_patterns_used()
                    and language != self.default_lang):
                urlconf = getattr(request, 'urlconf', None)
                language_path = '/%s%s' % (language, request.path_info)
                path_valid = is_valid_path(language_path, urlconf)
                if (not path_valid and settings.APPEND_SLASH
                        and not language_path.endswith('/')):
                    path_valid = is_valid_path("%s/" % language_path, urlconf)

                if path_valid:
                    language_url = "%s://%s/%s%s" % (
                        'https' if request.is_secure() else 'http',
                        request.get_host(), language, request.get_full_path())
                    return HttpResponseRedirect(language_url)

            if not (self.is_language_prefix_patterns_used()
                    and language_from_path):
                patch_vary_headers(response, ('Accept-Language', ))
            if django_root_version < 16:
                translation.deactivate()
        if 'Content-Language' not in response:
            response['Content-Language'] = language
        return response
Example #11
0
    def process_response(self, request, response):
        language = translation.get_language()
        language_from_path = translation.get_language_from_path(
                request.path_info, supported=self._supported_languages
        )
        if (response.status_code == 404 and not language_from_path
                and self.is_language_prefix_patterns_used()):
            urlconf = getattr(request, 'urlconf', None)
            language_path = '/%s%s' % (language, request.path_info)
            path_valid = is_valid_path(language_path, urlconf)
            if (not path_valid and settings.APPEND_SLASH
                    and not language_path.endswith('/')):
                path_valid = is_valid_path("%s/" % language_path, urlconf)

            if path_valid:
                language_url = "%s://%s/%s%s" % (
                    'https' if request.is_secure() else 'http',
                    request.get_host(), language, request.get_full_path())
                return HttpResponseRedirect(language_url)

        # Store language back into session if it is not present
        if hasattr(request, 'session'):
            request.session.setdefault('django_language', language)

        if not (self.is_language_prefix_patterns_used()
                and language_from_path):
            patch_vary_headers(response, ('Accept-Language',))
        if 'Content-Language' not in response:
            response['Content-Language'] = language
        return response
Example #12
0
    def process_request(self, request):
        old_path = request.path
        if not old_path.endswith("/") or old_path == "/":
            return

        urlconf = getattr(request, "urlconf", None)

        if urlresolvers.is_valid_path(request.path_info, urlconf):
            return

        if not urlresolvers.is_valid_path(request.path_info.rstrip("/"),
                                          urlconf):
            return

        new_path = request.path.rstrip("/")

        if s.DEBUG and request.method == 'POST':
            raise RuntimeError((
                "You called this URL via POST, but the URL should not end "
                "in a slash and RemoveTrailingSlashMiddleware is active. "
                "I can't redirect to the slash URL while maintaining POST data. "
                "Change your form to point to %s (no trailing slash).") %
                               (new_path, ))

        query = request.environ.get("QUERY_STRING")
        if query:
            new_path += "?" + query
        return HttpResponsePermanentRedirect(new_path)
Example #13
0
    def process_response(self, request, response):
        language = translation.get_language()
        language_from_path = translation.get_language_from_path(
            request.path_info)
        urlconf = getattr(request, 'urlconf', settings.ROOT_URLCONF)
        ret = is_language_prefix_patterns_used(urlconf)
        i18n_patterns_used, prefixed_default_language = ret

        if (response.status_code == 404 and not language_from_path
                and i18n_patterns_used):
            language_path = '/%s%s' % (language, request.path_info)
            path_valid = is_valid_path(language_path, urlconf)
            path_needs_slash = (
                not path_valid
                and (settings.APPEND_SLASH and not language_path.endswith('/')
                     and is_valid_path('%s/' % language_path, urlconf)))

            if path_valid or path_needs_slash:
                script_prefix = get_script_prefix()
                language_url = backported_get_full_path(
                    request, force_append_slash=path_needs_slash).replace(
                        script_prefix, '%s%s/' % (script_prefix, language), 1)
                return self.response_redirect_class(language_url)

        if not (i18n_patterns_used and language_from_path):
            patch_vary_headers(response, ('Accept-Language', ))
        if 'Content-Language' not in response:
            response['Content-Language'] = language
        return response
Example #14
0
    def process_response(self, request, response):
        language = translation.get_language()
        if self.use_redirects:
            kwargs = {}
            if django_root_version == 16:
                kwargs['supported'] = self._supported_languages
            language_from_path = translation.get_language_from_path(
                request.path_info, **kwargs)
            if (response.status_code == 404 and not language_from_path
                    and self.is_language_prefix_patterns_used()
                    and language != self.default_lang):
                urlconf = getattr(request, 'urlconf', None)
                language_path = '/%s%s' % (language, request.path_info)
                path_valid = is_valid_path(language_path, urlconf)
                if (not path_valid and settings.APPEND_SLASH
                        and not language_path.endswith('/')):
                    path_valid = is_valid_path("%s/" % language_path, urlconf)

                if path_valid:
                    language_url = "%s://%s/%s%s" % (
                        'https' if request.is_secure() else 'http',
                        request.get_host(), language, request.get_full_path())
                    return HttpResponseRedirect(language_url)

            if not (self.is_language_prefix_patterns_used()
                    and language_from_path):
                patch_vary_headers(response, ('Accept-Language',))
            if django_root_version < 16:
                translation.deactivate()
        if 'Content-Language' not in response:
            response['Content-Language'] = language
        return response
Example #15
0
    def process_response(self, request, response):
        language = translation.get_language()
        # Check if app has i18n_patterns urlconf
        is_i18n_pattern = hasattr(request, 'resolver_match') and getattr(
            request.resolver_match, 'app_name', None) in ('account', )
        # If path is '/', resolver_match is errored and not provided
        if request.path == '/' and request.user.is_anonymous():
            # On home, if not anonymous -> tenant_root
            is_i18n_pattern = True
        if (response.status_code == 404 and is_i18n_pattern
                and not translation.get_language_from_path(request.path_info)
                and self.is_language_prefix_patterns_used()):
            urlconf = getattr(request, 'urlconf', None)
            language_path = '/%s%s' % (language, request.path_info)
            path_valid = is_valid_path(language_path, urlconf)
            if (not path_valid and settings.APPEND_SLASH
                    and not language_path.endswith('/')):
                path_valid = is_valid_path("%s/" % language_path, urlconf)

            if path_valid:
                language_url = "%s://%s/%s%s" % (
                    request.is_secure() and 'https' or 'http',
                    request.get_host(), language, request.get_full_path())
                return HttpResponseRedirect(language_url)
        translation.deactivate()

        patch_vary_headers(response, ('Accept-Language', ))
        if 'Content-Language' not in response:
            response['Content-Language'] = language
        return response
Example #16
0
    def process_response(self, request, response):
        language = translation.get_language()
        language_from_path = translation.get_language_from_path(request.path_info)
        if (response.status_code == 404 and not language_from_path
                and self.is_language_prefix_patterns_used()):
            urlconf = getattr(request, 'urlconf', None)
            language_path = '/%s%s' % (language, request.path_info)
            path_valid = is_valid_path(language_path, urlconf)
            if (not path_valid and settings.APPEND_SLASH
                    and not language_path.endswith('/')):
                path_valid = is_valid_path("%s/" % language_path, urlconf)

            if path_valid:
                script_prefix = get_script_prefix()
                language_url = "%s://%s%s" % (
                    request.scheme,
                    request.get_host(),
                    # insert language after the script prefix and before the
                    # rest of the URL
                    request.get_full_path().replace(
                        script_prefix,
                        '%s%s/' % (script_prefix, language),
                        1
                    )
                )
                return self.response_redirect_class(language_url)

        if not (self.is_language_prefix_patterns_used()
                and language_from_path):
            patch_vary_headers(response, ('Accept-Language',))
        if 'Content-Language' not in response:
            response['Content-Language'] = language
        return response
Example #17
0
    def process_response(self, request, response):
        language = translation.get_language()
        language_from_path = translation.get_language_from_path(request.path_info)
        if (response.status_code == 404 and not language_from_path
                and self.is_language_prefix_patterns_used):
            urlconf = getattr(request, 'urlconf', None)
            language_path = '/%s%s' % (language, request.path_info)
            path_valid = is_valid_path(language_path, urlconf)
            path_needs_slash = (
                not path_valid and (
                    settings.APPEND_SLASH and not language_path.endswith('/')
                    and is_valid_path('%s/' % language_path, urlconf)
                )
            )

            if path_valid or path_needs_slash:
                script_prefix = get_script_prefix()
                # Insert language after the script prefix and before the
                # rest of the URL
                language_url = request.get_full_path(force_append_slash=path_needs_slash).replace(
                    script_prefix,
                    '%s%s/' % (script_prefix, language),
                    1
                )
                return self.response_redirect_class(language_url)

        if not (self.is_language_prefix_patterns_used
                and language_from_path):
            patch_vary_headers(response, ('Accept-Language',))
        if 'Content-Language' not in response:
            response['Content-Language'] = language
        return response
Example #18
0
    def perform_redirect(self, request, language, is_permanent=False):
        # language can be empty string (in case of default language)
        path_info = request.path_info
        if not language:
            path_info = self.remove_lang_from_path(path_info)
        urlconf = getattr(request, 'urlconf', None)
        language_path = '%s%s' % (language, path_info)
        if not language_path.startswith('/'):
            language_path = '/' + language_path
        path_valid = is_valid_path(language_path, urlconf)
        path_needs_slash = (
            not path_valid
            and (settings.APPEND_SLASH and not language_path.endswith('/')
                 and is_valid_path('%s/' % language_path, urlconf)))

        if path_valid or path_needs_slash:
            script_prefix = get_script_prefix()
            if DJANGO_VERSION < (1, 9):
                full_path = get_full_path(request,
                                          force_append_slash=path_needs_slash)
            else:
                full_path = request.get_full_path(
                    force_append_slash=path_needs_slash)
            if not language:
                full_path = self.remove_lang_from_path(full_path)
            language_url = full_path.replace(
                script_prefix, '%s%s/' %
                (script_prefix, language) if language else script_prefix, 1)

            # return a 301 permanent redirect if on default language
            if (is_permanent):
                return self.response_default_language_redirect_class(
                    language_url)
            else:
                return self.response_redirect_class(language_url)
Example #19
0
def redirectold(request, exception):
    path = request.path_info.lower()
    if path.endswith('index.html'):
        path = path[:-10]
    elif path.endswith('.html'):
        path = path[:-5]
    path = re.sub('^/fa-', '/fa/', path)
    path = re.sub('__+', '_', path).replace('-', '')
    path = settings.FORWARDS.get(path, path)
    if path.startswith('/who/'):
        nameslug = path[5:]
        for n in ALIASES.keys():
            from django.utils.text import slugify
            if nameslug == slugify(n):
                match = name_alias(n)
                path = Creator.objects.get(name=match[0]).get_absolute_url()
    urlconf = getattr(request, 'urlconf', None)
    if (path != request.path_info and
        urlresolvers.is_valid_path(path, urlconf)):
        return HttpResponsePermanentRedirect("%s://%s%s" % (
            'https' if request.is_secure() else 'http',
            request.get_host(), path))
    path = path + '/'
    if (path != request.path_info and
        urlresolvers.is_valid_path(path, urlconf)):
        return HttpResponsePermanentRedirect("%s://%s%s" % (
            'https' if request.is_secure() else 'http',
            request.get_host(), path))
    return page_not_found(request, exception)
Example #20
0
    def process_response(self, request, response):
        language = translation.get_language()
        language_from_path = translation.get_language_from_path(
            request.path_info)
        if (response.status_code == 404 and not language_from_path
                and self.is_language_prefix_patterns_used):
            urlconf = getattr(request, 'urlconf', None)
            language_path = '/%s%s' % (language, request.path_info)
            path_valid = is_valid_path(language_path, urlconf)
            if (not path_valid and settings.APPEND_SLASH
                    and not language_path.endswith('/')):
                path_valid = is_valid_path("%s/" % language_path, urlconf)

            if path_valid:
                script_prefix = get_script_prefix()
                language_url = "%s://%s%s" % (
                    request.scheme,
                    request.get_host(),
                    # insert language after the script prefix and before the
                    # rest of the URL
                    request.get_full_path().replace(
                        script_prefix, '%s%s/' % (script_prefix, language), 1))
                return self.response_redirect_class(language_url)

        if not (self.is_language_prefix_patterns_used and language_from_path):
            patch_vary_headers(response, ('Accept-Language', ))
        if 'Content-Language' not in response:
            response['Content-Language'] = language
        return response
Example #21
0
def translate_url(context, language):
    request = context.get('request')
    is_valid_path = urlresolvers.is_valid_path(request.path_info)
    request_language = translation.get_language()
    url = None
    if is_valid_path:
        view = resolve(
            request.path_info)
        translation.activate(language)
        url = reverse(view.url_name, args=view.args, kwargs=view.kwargs)
        translation.activate(request_language)
    else:
        is_valid_path = urlresolvers.is_valid_path(
            request.path_info, 'static_pages.urls_i18n')
        if is_valid_path:
            view = resolve(
                request.path_info, urlconf='static_pages.urls_i18n')
            translation.activate(language)
            url = reverse(
                view.url_name,
                args=view.args,
                kwargs=view.kwargs,
                urlconf='static_pages.urls_i18n')
            translation.activate(request_language)
    return url
    def process_response(self, request, response):
        country_code = get_country()
        country_from_path = get_country_from_path(request.path_info)
        if (response.status_code == 404 and not country_from_path
                and self.is_language_prefix_patterns_used):
            urlconf = getattr(request, 'urlconf', None)
            country_path = '/%s%s' % (country_code, request.path_info)
            path_valid = is_valid_path(country_path, urlconf)
            path_needs_slash = (
                not path_valid and (
                    settings.APPEND_SLASH and not country_path.endswith('/')
                    and is_valid_path('%s/' % country_path, urlconf)
                )
            )

            if path_valid or path_needs_slash:
                script_prefix = get_script_prefix()
                language_url = request.get_full_path(force_append_slash=path_needs_slash).replace(
                    script_prefix,
                    '%s%s/' % (script_prefix, country_code),
                    1
                )
                return self.response_redirect_class(language_url)

        return response
    def perform_redirect(self, request, language):
        # language can be empty string (in case of default language)
        path_info = request.path_info
        full_path = request.get_full_path()
        if not language:
            path_info = self.remove_lang_from_path(path_info)
            full_path = self.remove_lang_from_path(full_path)
        urlconf = getattr(request, 'urlconf', None)
        language_path = '%s%s' % (language, path_info)
        if not language_path.startswith('/'):
            language_path = '/' + language_path
        path_valid = is_valid_path(language_path, urlconf)
        if (not path_valid and settings.APPEND_SLASH
                and not language_path.endswith('/')):
            path_valid = is_valid_path("%s/" % language_path, urlconf)

        if path_valid:
            if DJANGO_VERSION >= (1, 7):
                scheme = request.scheme
            else:
                scheme = 'https' if request.is_secure() else 'http'
            script_prefix = get_script_prefix()
            language_url = "%s://%s%s" % (
                scheme,
                request.get_host(),
                # insert language after the script prefix and before the
                # rest of the URL
                full_path.replace(
                    script_prefix,
                    '%s%s/' % (script_prefix, language) if language else script_prefix,
                    1
                )
            )
            return self.response_redirect_class(language_url)
Example #24
0
    def process_response(self, request, response):
        language = translation.get_language()
        if (
            response.status_code == 404
            and not translation.get_language_from_path(request.path_info)
            and self.is_language_prefix_patterns_used()
        ):
            urlconf = getattr(request, "urlconf", None)
            language_path = "/%s%s" % (language, request.path_info)
            valid_language_path = language_path
            path_valid = is_valid_path(language_path, urlconf)
            if not path_valid and settings.APPEND_SLASH and not language_path.endswith("/"):
                path_valid = is_valid_path("%s/" % language_path, urlconf)
                if path_valid:
                    valid_language_path = "%s/" % language_path

            if path_valid and is_valid_path(request.path_info):
                # If the language path is valid and the request's original path
                # is also valid, make sure we're not redirecting to a different view
                path_valid = self._resolves_to_same_view(request.path_info, valid_language_path, urlconf)

            if path_valid:
                language_url = "%s://%s/%s%s" % (
                    request.is_secure() and "https" or "http",
                    request.get_host(),
                    language,
                    request.get_full_path(),
                )
                return HttpResponseRedirect(language_url)
        translation.deactivate()

        patch_vary_headers(response, ("Accept-Language",))
        if "Content-Language" not in response:
            response["Content-Language"] = language
        return response
Example #25
0
    def process_response(self, request, response):
        language = translation.get_language()
        language_from_path = translation.get_language_from_path(
            request.path_info, supported=self._supported_languages)
        if (response.status_code == 404 and not language_from_path
                and self.is_language_prefix_patterns_used()):
            urlconf = getattr(request, 'urlconf', None)
            language_path = '/%s%s' % (language, request.path_info)
            path_valid = is_valid_path(language_path, urlconf)
            if (not path_valid and settings.APPEND_SLASH
                    and not language_path.endswith('/')):
                path_valid = is_valid_path("%s/" % language_path, urlconf)

            if path_valid:
                language_url = "%s://%s/%s%s" % (request.scheme,
                                                 request.get_host(), language,
                                                 request.get_full_path())
                return self.response_redirect_class(language_url)

        if not (self.is_language_prefix_patterns_used()
                and language_from_path):
            patch_vary_headers(response, ('Accept-Language', ))
        if 'Content-Language' not in response:
            response['Content-Language'] = language
        return response
Example #26
0
    def process_request(self, request):
        """
        Check for denied User-Agents and rewrite the URL based on
        settings.APPEND_SLASH and settings.PREPEND_WWW
        """

        # Check for denied User-Agents
        if 'HTTP_USER_AGENT' in request.META:
            for user_agent_regex in settings.DISALLOWED_USER_AGENTS:
                if user_agent_regex.search(request.META['HTTP_USER_AGENT']):
                    logger.warning('Forbidden (User agent): %s',
                                   request.path,
                                   extra={
                                       'status_code': 403,
                                       'request': request
                                   })
                    return http.HttpResponseForbidden('<h1>Forbidden</h1>')

        # Check for a redirect based on settings.APPEND_SLASH
        # and settings.PREPEND_WWW
        host = request.get_host()
        old_url = [host, request.get_full_path()]
        new_url = old_url[:]

        if (settings.PREPEND_WWW and old_url[0]
                and not old_url[0].startswith('www.')):
            new_url[0] = 'www.' + old_url[0]

        # Append a slash if APPEND_SLASH is set and the URL doesn't have a
        # trailing slash and there is no pattern for the current path
        if settings.APPEND_SLASH and (not old_url[1].endswith('/')):
            urlconf = getattr(request, 'urlconf', None)
            if (not urlresolvers.is_valid_path(request.path_info, urlconf)
                    and urlresolvers.is_valid_path("%s/" % request.path_info,
                                                   urlconf)):
                new_url[1] = request.get_full_path(force_append_slash=True)
                if settings.DEBUG and request.method in ('POST', 'PUT',
                                                         'PATCH'):
                    raise RuntimeError((
                        ""
                        "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': request.method,
                            'url': ''.join(new_url)
                        })

        if new_url == old_url:
            # No redirects required.
            return
        if new_url[0] != old_url[0]:
            newurl = "%s://%s%s" % (request.scheme, new_url[0], new_url[1])
        else:
            newurl = new_url[1]
        return self.response_redirect_class(newurl)
Example #27
0
    def process_request(self, request):
        """
        Check for denied User-Agents and rewrite the URL based on
        settings.APPEND_SLASH and settings.PREPEND_WWW
        """

        # Check for denied User-Agents
        if 'HTTP_USER_AGENT' in request.META:
            for user_agent_regex in settings.DISALLOWED_USER_AGENTS:
                if user_agent_regex.search(request.META['HTTP_USER_AGENT']):
                    logger.warning('Forbidden (User agent): %s',
                                   request.path,
                                   extra={
                                       'status_code': 403,
                                       'request': request
                                   })
                    return http.HttpResponseForbidden('<h1>Forbidden</h1>')

        # Check for a redirect based on settings.APPEND_SLASH
        # and settings.PREPEND_WWW
        host = request.get_host()
        old_url = [host, request.path]
        new_url = old_url[:]

        if (settings.PREPEND_WWW and old_url[0]
                and not old_url[0].startswith('www.')):
            new_url[0] = 'www.' + old_url[0]

        # Append a slash if APPEND_SLASH is set and the URL doesn't have a
        # trailing slash and there is no pattern for the current path
        if settings.APPEND_SLASH and (not old_url[1].endswith('/')):
            urlconf = getattr(request, 'urlconf', None)
            if (not urlresolvers.is_valid_path(request.path_info, urlconf)
                    and urlresolvers.is_valid_path("%s/" % request.path_info,
                                                   urlconf)):
                new_url[1] = new_url[1] + '/'
                if settings.DEBUG and request.method == 'POST':
                    raise RuntimeError((
                        ""
                        "You called this URL via POST, 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 POST data. "
                        "Change your form to point to %s%s (note the trailing "
                        "slash), or set APPEND_SLASH=False in your Django "
                        "settings.") % (new_url[0], new_url[1]))

        if new_url == old_url:
            # No redirects required.
            return
        if new_url[0]:
            newurl = "%s://%s%s" % (request.is_secure() and 'https' or 'http',
                                    new_url[0], urlquote(new_url[1]))
        else:
            newurl = urlquote(new_url[1])
        if request.META.get('QUERY_STRING', ''):
            newurl += '?' + request.META['QUERY_STRING']
        return http.HttpResponsePermanentRedirect(newurl)
Example #28
0
    def process_request(self, request):
        """
        Check for denied User-Agents and rewrite the URL based on
        settings.APPEND_SLASH and settings.PREPEND_WWW
        """

        # Check for denied User-Agents
        if 'HTTP_USER_AGENT' in request.META:
            for user_agent_regex in settings.DISALLOWED_USER_AGENTS:
                if user_agent_regex.search(request.META['HTTP_USER_AGENT']):
                    logger.warning('Forbidden (User agent): %s', request.path,
                        extra={
                            'status_code': 403,
                            'request': request
                        }
                    )
                    return http.HttpResponseForbidden('<h1>Forbidden</h1>')

        # Check for a redirect based on settings.APPEND_SLASH
        # and settings.PREPEND_WWW
        host = request.get_host()
        old_url = [host, request.path]
        new_url = old_url[:]

        if (settings.PREPEND_WWW and old_url[0] and
                not old_url[0].startswith('www.')):
            new_url[0] = 'www.' + old_url[0]

        # Append a slash if APPEND_SLASH is set and the URL doesn't have a
        # trailing slash and there is no pattern for the current path
        if settings.APPEND_SLASH and (not old_url[1].endswith('/')):
            urlconf = getattr(request, 'urlconf', None)
            if (not urlresolvers.is_valid_path(request.path_info, urlconf) and
                    urlresolvers.is_valid_path("%s/" % request.path_info, urlconf)):
                new_url[1] = new_url[1] + '/'
                if settings.DEBUG and request.method == 'POST':
                    raise RuntimeError((""
                    "You called this URL via POST, 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 POST data. "
                    "Change your form to point to %s%s (note the trailing "
                    "slash), or set APPEND_SLASH=False in your Django "
                    "settings.") % (new_url[0], new_url[1]))

        if new_url == old_url:
            # No redirects required.
            return
        if new_url[0]:
            newurl = "%s://%s%s" % (
                request.is_secure() and 'https' or 'http',
                new_url[0], urlquote(new_url[1]))
        else:
            newurl = urlquote(new_url[1])
        if request.META.get('QUERY_STRING', ''):
            newurl += '?' + request.META['QUERY_STRING']
        return http.HttpResponsePermanentRedirect(newurl)
Example #29
0
 def should_redirect_without_slash(self, request):
     """
     Return True if settings.APPEND_SLASH is True and appending a slash to
     the request path turns an invalid path into a valid one.
     """
     if getattr(settings, 'REMOVE_SLASH', False) and trailing_slash_regexp.search(request.get_full_path()):
         urlconf = getattr(request, 'urlconf', None)
         return (not urlresolvers.is_valid_path(request.path_info, urlconf) and urlresolvers.is_valid_path(
             request.path_info[:-1], urlconf))
     return False
Example #30
0
 def should_redirect_without_slash(self, request):
     """
     Return True if settings.APPEND_SLASH is True and appending a slash to
     the request path turns an invalid path into a valid one.
     """
     if getattr(settings, 'REMOVE_SLASH', False) and trailing_slash_regexp.search(request.get_full_path()):
         urlconf = getattr(request, 'urlconf', None)
         return (not urlresolvers.is_valid_path(request.path_info, urlconf) and urlresolvers.is_valid_path(
             request.path_info[:-1], urlconf))
     return False
Example #31
0
    def process_request(self, request):
        """
        Check for denied User-Agents and rewrite the URL based on
        settings.APPEND_SLASH and settings.PREPEND_WWW
        """

        # Check for denied User-Agents
        if 'HTTP_USER_AGENT' in request.META:
            for user_agent_regex in settings.DISALLOWED_USER_AGENTS:
                if user_agent_regex.search(request.META['HTTP_USER_AGENT']):
                    logger.warning('Forbidden (User agent): %s', request.path,
                        extra={
                            'status_code': 403,
                            'request': request
                        }
                    )
                    return http.HttpResponseForbidden('<h1>Forbidden</h1>')

        # Check for a redirect based on settings.APPEND_SLASH
        # and settings.PREPEND_WWW
        host = request.get_host()
        old_url = [host, request.get_full_path()]
        new_url = old_url[:]

        if (settings.PREPEND_WWW and old_url[0] and
                not old_url[0].startswith('www.')):
            new_url[0] = 'www.' + old_url[0]

        # Append a slash if APPEND_SLASH is set and the URL doesn't have a
        # trailing slash and there is no pattern for the current path
        if settings.APPEND_SLASH and (not old_url[1].endswith('/')):
            urlconf = getattr(request, 'urlconf', None)
            if (not urlresolvers.is_valid_path(request.path_info, urlconf) and
                    urlresolvers.is_valid_path("%s/" % request.path_info, urlconf)):
                new_url[1] = request.get_full_path(force_append_slash=True)
                if settings.DEBUG and request.method in ('POST', 'PUT', 'PATCH'):
                    raise RuntimeError((""
                    "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': request.method, 'url': ''.join(new_url)})

        if new_url == old_url:
            # No redirects required.
            return
        if new_url[0] != old_url[0]:
            newurl = "%s://%s%s" % (
                request.scheme,
                new_url[0], new_url[1])
        else:
            newurl = new_url[1]
        return self.response_redirect_class(newurl)
Example #32
0
 def should_redirect_with_slash(self, request):
     """
     Return True if settings.APPEND_SLASH is True and appending a slash to
     the request path turns an invalid path into a valid one.
     """
     if settings.APPEND_SLASH and not request.get_full_path().endswith('/'):
         urlconf = getattr(request, 'urlconf', None)
         return (not urlresolvers.is_valid_path(request.path_info, urlconf)
                 and urlresolvers.is_valid_path('%s/' % request.path_info,
                                                urlconf))
     return False
Example #33
0
 def should_redirect_with_slash(self, request):
     """
     Return True if settings.APPEND_SLASH is True and appending a slash to
     the request path turns an invalid path into a valid one.
     """
     if settings.APPEND_SLASH and not request.get_full_path().endswith("/"):
         urlconf = getattr(request, "urlconf", None)
         return not urlresolvers.is_valid_path(request.path_info, urlconf) and urlresolvers.is_valid_path(
             "%s/" % request.path_info, urlconf
         )
     return False
Example #34
0
 def process_response(self, request, response):
     if (response.status_code == 404 and request.path_info.endswith('/')
             and not is_valid_path(request.path_info)
             and is_valid_path(request.path_info[:-1])):
         # Use request.path because we munged app/locale in path_info.
         newurl = request.path[:-1]
         if request.GET:
             with safe_query_string(request):
                 newurl += '?' + request.META['QUERY_STRING']
         return HttpResponsePermanentRedirect(newurl)
     return response
Example #35
0
 def process_response(self, request, response):
     if (response.status_code == 404
         and request.path_info.endswith('/')
         and not is_valid_path(request.path_info)
         and is_valid_path(request.path_info[:-1])):
         # Use request.path because we munged app/locale in path_info.
         newurl = request.path[:-1]
         if request.GET:
             with safe_query_string(request):
                 newurl += '?' + request.META['QUERY_STRING']
         return HttpResponsePermanentRedirect(newurl)
     return response
Example #36
0
    def process_request(self, request):

        # Check for a redirect based on settings.APPEND_SLASH
        # and settings.PREPEND_WWW
        host = request.get_host()
        old_url = [host, request.path]
        new_url = old_url[:]

        if getattr(settings, 'APPEND_SLASH') and getattr(
                settings, 'REMOVE_SLASH'):
            raise ImproperlyConfigured(
                "APPEND_SLASH and REMOVE_SLASH may not both be True.")

        # Remove slash if REMOVE_SLASH is set and the URL has a trailing slash
        # and there is no pattern for the current path
        if getattr(settings, 'REMOVE_SLASH',
                   False) and old_url[1].endswith('/'):
            urlconf = getattr(request, 'urlconf', None)
            if (not urlresolvers.is_valid_path(request.path_info, urlconf)
                ) and urlresolvers.is_valid_path(request.path_info[:-1],
                                                 urlconf):
                new_url[1] = new_url[1][:-1]
                if settings.DEBUG and request.method == 'POST':
                    raise RuntimeError((
                        ""
                        "You called this URL via POST, but the URL ends in a "
                        "slash and you have REMOVE_SLASH set. Django can't "
                        "redirect to the non-slash URL while maintaining POST "
                        "data. Change your form to point to %s%s (without a "
                        "trailing slash), or set REMOVE_SLASH=False in your "
                        "Django settings.") % (new_url[0], new_url[1]))

        if new_url == old_url:
            # No redirects required.
            return
        if new_url[0]:
            newurl = "%s://%s%s" % ('https' if request.is_secure() else 'http',
                                    new_url[0], urlquote(new_url[1]))
        else:
            newurl = urlquote(new_url[1])
        if request.META.get('QUERY_STRING', ''):
            if six.PY3:
                newurl += '?' + request.META['QUERY_STRING']
            else:
                # `query_string` is a bytestring. Appending it to the unicode
                # string `newurl` will fail if it isn't ASCII-only. This isn't
                # allowed; only broken software generates such query strings.
                # Better drop the invalid query string than crash (#15152).
                try:
                    newurl += '?' + request.META['QUERY_STRING'].decode()
                except UnicodeDecodeError:
                    pass
        return http.HttpResponsePermanentRedirect(newurl)
Example #37
0
    def process_request(self, request):

        # Check for a redirect based on settings.APPEND_SLASH
        # and settings.PREPEND_WWW
        host = request.get_host()
        old_url = [host, request.path]
        new_url = old_url[:]

        if getattr(settings, 'APPEND_SLASH') and getattr(settings, 'REMOVE_SLASH'):
            raise ImproperlyConfigured("APPEND_SLASH and REMOVE_SLASH may not both be True.")

        # Remove slash if REMOVE_SLASH is set and the URL has a trailing slash
        # and there is no pattern for the current path
        if getattr(settings, 'REMOVE_SLASH', False) and old_url[1].endswith('/'):
            urlconf = getattr(request, 'urlconf', None)
            if (not urlresolvers.is_valid_path(request.path_info, urlconf)) and urlresolvers.is_valid_path(request.path_info[:-1], urlconf):
                new_url[1] = new_url[1][:-1]
                if settings.DEBUG and request.method == 'POST':
                    raise RuntimeError((""
                    "You called this URL via POST, but the URL ends in a "
                    "slash and you have REMOVE_SLASH set. Django can't "
                    "redirect to the non-slash URL while maintaining POST "
                    "data. Change your form to point to %s%s (without a "
                    "trailing slash), or set REMOVE_SLASH=False in your "
                    "Django settings.") % (new_url[0], new_url[1]))

        if new_url == old_url:
            # No redirects required.
            return
        if new_url[0]:
            newurl = "%s://%s%s" % (
                'https' if request.is_secure() else 'http', 
                new_url[0], urlquote(new_url[1]))
        else:
            newurl = urlquote(new_url[1])
        if request.META.get('QUERY_STRING', ''):
            if six.PY3:
                newurl += '?' + request.META['QUERY_STRING']
            else:
                # `query_string` is a bytestring. Appending it to the unicode
                # string `newurl` will fail if it isn't ASCII-only. This isn't
                # allowed; only broken software generates such query strings.
                # Better drop the invalid query string than crash (#15152).
                try:
                    newurl += '?' + request.META['QUERY_STRING'].decode()
                except UnicodeDecodeError:
                    pass
        return http.HttpResponsePermanentRedirect(newurl)
Example #38
0
    def process_response(self, request, response):
        """."""
        # First set the default language, this will be used if there is none
        # in the path
        default_language = getattr(request, 'default_language', '')
        if default_language:
            translation.activate(default_language)

        language = translation.get_language()
        if (response.status_code == 404
                and not translation.get_language_from_path(request.path_info)
                and self.is_language_prefix_patterns_used(request)):
            language_path = '/%s%s' % (language, request.path_info)
            if settings.APPEND_SLASH and not language_path.endswith('/'):
                language_path += '/'

            if is_valid_path(language_path, settings.ROOT_URLCONF):
                language_url = "%s://%s/%s%s" % (
                    request.is_secure() and 'https' or 'http',
                    request.get_host(), language, request.get_full_path())
                return HttpResponseRedirect(language_url)
        translation.deactivate()

        patch_vary_headers(response, ('Accept-Language', ))
        if 'Content-Language' not in response:
            response['Content-Language'] = language
        return response
Example #39
0
    def process_response(self, request, response):
        # First set the default language, this will be used if there is none
        # in the path
        default_language = getattr(request, 'default_language', '')
        if default_language:
            translation.activate(default_language)

        language = translation.get_language()
        if (response.status_code == 404 and
                not translation.get_language_from_path(request.path_info) and
                self.is_language_prefix_patterns_used(request)):
            urlconf = getattr(request, 'urlconf', None)
            language_path = '/%s%s' % (language, request.path_info)
            if settings.APPEND_SLASH and not language_path.endswith('/'):
                language_path += '/'

            if is_valid_path(language_path, urlconf):
                language_url = "%s://%s/%s%s" % (
                    request.is_secure() and 'https' or 'http',
                    request.get_host(), language, request.get_full_path())
                return HttpResponseRedirect(language_url)
        translation.deactivate()

        patch_vary_headers(response, ('Accept-Language',))
        if 'Content-Language' not in response:
            response['Content-Language'] = language
        return response
Example #40
0
def test_urls(client):
    assert settings.ROOT_URLCONF == 'tests.urls_overridden'
    assert is_valid_path('/overridden_url/')

    response = client.get('/overridden_url/')

    assert response.content == 'Overridden urlconf works!'
    def process_response(self, request, response):
        """
        Override the original method to redirect permanently and facilitate 
        the :func.`translations.urls.translation_patterns` URL redirection
        logic.
        """
        language = translation.get_language()
        default = get_default_language()
        
        #redirect to the original default language URL
        #if language prefix is used
        if (response.status_code == 404 and
            self.is_language_prefix_patterns_used() and default == language and 
            request.path_info.startswith('/%s/' % default)):
            
            urlconf = getattr(request, 'urlconf', None)
            language_path = re.sub(r'^/%s/' % default, '/', request.path_info)
            if settings.APPEND_SLASH and not language_path.endswith('/'):
                language_path = language_path + '/'

            if is_valid_path(language_path, urlconf):
                #we use a permanent redirect here.
                #when changing the default language we need to let the world know
                #that our links have permanently changed and transfer our seo juice 
                #to the new url
                #http://blog.yawd.eu/2012/impact-django-page-redirects-seo/
                return  HttpResponsePermanentRedirect("%s://%s/%s" % (
                    request.is_secure() and 'https' or 'http',
                    request.get_host(), re.sub(r'^/%s/' % default, '', request.get_full_path())))
        
        patch_vary_headers(response, ('Accept-Language',))
        if 'Content-Language' not in response:
            response['Content-Language'] = language
        return response
Example #42
0
    def process_request(self, req):
        scheme = 'http:' if settings.DEBUG else 'https:'
        path = req.get_full_path()
        if path.endswith('/') and is_valid_path(path[:-1]):
            hostname = req.META.get('HTTP_HOST')
            return HttpResponsePermanentRedirect('%s//%s%s' %
                                                 (scheme, hostname, path[:-1]))

        return None
Example #43
0
    def process_request(self, req):
        scheme = 'http:' if settings.DEBUG else 'https:'
        path = req.get_full_path()
        if path.endswith('/') and is_valid_path(path[:-1]):
            hostname = req.META.get('HTTP_HOST')
            return HttpResponsePermanentRedirect(
                '%s//%s%s' % (scheme, hostname, path[:-1]))

        return None
Example #44
0
    def process_response(self, request, response):
        language = translation.get_language()
        language_from_path = translation.get_language_from_path(
                                request.path_info)
        urlconf = getattr(request, 'urlconf', settings.ROOT_URLCONF)
        i18n_patterns_used, prefixed_default_language \
                = backported_is_language_prefix_patterns_used(urlconf)

        if (response.status_code == 404 and not language_from_path
                and i18n_patterns_used):
            language_path = '/%s%s' % (language, request.path_info)
            path_valid = is_valid_path(language_path, urlconf)
            path_needs_slash = (
                not path_valid and (
                    settings.APPEND_SLASH and not language_path.endswith('/')
                    and is_valid_path('%s/' % language_path, urlconf)
                )
            )

            if path_valid or path_needs_slash:
                script_prefix = get_script_prefix()
                language_url = backported_get_full_path(request,
                        force_append_slash=path_needs_slash).replace(
                    script_prefix,
                    '%s%s/' % (script_prefix, language),
                    1
                )
                return self.response_redirect_class(language_url)

        # NOTE In Django 1.10 this is taken care of in other middleware
        #      and that is why this session update is not in the 1.10
        #      locale middleware.
        if hasattr(request, 'session') and language_from_path:
            request.session['_language'] = language
            # NOTE customization 3:
            if (hasattr(request, 'user') and request.user.is_authenticated()
                    and language != request.user.preferred_language):
                request.user.set_preferred_language(language)

        if not (i18n_patterns_used and language_from_path):
            patch_vary_headers(response, ('Accept-Language',))
        if 'Content-Language' not in response:
            response['Content-Language'] = language
        return response
Example #45
0
    def process_request(self, request):
        host = request.get_host()
        old_url = [host, request.path]
        new_url = old_url[:]
        if not settings.APPEND_SLASH and old_url[1].endswith("/"):
            urlconf = getattr(request, "urlconf", None)
            if not urlresolvers.is_valid_path(request.path_info, urlconf) and urlresolvers.is_valid_path(
                request.path_info[:-1], urlconf
            ):
                new_url[1] = new_url[1][:-1]
                if settings.DEBUG and request.method == "POST":
                    raise RuntimeError(
                        (
                            ""
                            "You called this URL via POST, but the URL ends "
                            "in a slash and you don't have APPEND_SLASH set. Django can't "
                            "redirect to the non-slash URL while maintaining POST data. "
                            "Change your form to point to %s%s (note no trailing "
                            "slash), or set APPEND_SLASH=True in your Django "
                            "settings."
                        )
                        % (new_url[0], new_url[1])
                    )

        if new_url == old_url:
            # No redirects required.
            return
        if new_url[0]:
            newurl = "%s://%s%s" % (request.is_secure() and "https" or "http", new_url[0], urlquote(new_url[1]))
        else:
            newurl = urlquote(new_url[1])
        if request.META.get("QUERY_STRING", ""):
            if six.PY3:
                newurl += "?" + request.META["QUERY_STRING"]
            else:
                # `query_string` is a bytestring. Appending it to the unicode
                # string `newurl` will fail if it isn't ASCII-only. This isn't
                # allowed; only broken software generates such query strings.
                # Better drop the invalid query string than crash (#15152).
                try:
                    newurl += "?" + request.META["QUERY_STRING"].decode()
                except UnicodeDecodeError:
                    pass
        return http.HttpResponsePermanentRedirect(newurl)
    def append_slash(self, request, host):
        old_url = [host, request.path]
        new_url = old_url[:]

        if not old_url[1].endswith('/'):
            urlconf = getattr(request, 'urlconf', None)
            if (not urlresolvers.is_valid_path(request.path_info, urlconf) and
                    urlresolvers.is_valid_path("%s/" % request.path_info, urlconf)):
                new_url[1] = new_url[1] + '/'
                if settings.DEBUG and request.method == 'POST':
                    raise RuntimeError((""
                    "You called this URL via POST, 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 POST data. "
                    "Change your form to point to %s%s (note the trailing "
                    "slash), or set APPEND_SLASH=False in your Django "
                    "settings.") % (new_url[0], new_url[1]))

        if new_url == old_url:
            # No redirects required.
            return
        

        if new_url[0]:
            newurl = "%s://%s%s" % (
                request.is_secure() and 'https' or 'http',
                new_url[0], urlquote(new_url[1]))
        else:
            newurl = urlquote(new_url[1])
        if request.META.get('QUERY_STRING', ''):
            if six.PY3:
                newurl += '?' + request.META['QUERY_STRING']
            else:
                # `query_string` is a bytestring. Appending it to the unicode
                # string `newurl` will fail if it isn't ASCII-only. This isn't
                # allowed; only broken software generates such query strings.
                # Better drop the invalid query string than crash (#15152).
                try:
                    newurl += '?' + request.META['QUERY_STRING'].decode()
                except UnicodeDecodeError:
                    pass
        return http.HttpResponsePermanentRedirect(newurl)
Example #47
0
    def process_request(self, request):
        # Bail if we already have trailing slash.
        if request.path.endswith('/'):
            return

        urlconf = getattr(request, 'urlconf', None)
        old_is_valid = lambda: urlresolvers.is_valid_path(request.path_info, urlconf)
        new_is_valid = lambda: urlresolvers.is_valid_path('%s/' % request.path_info, urlconf)

        # Bail for valid urls or slash version not being valid.
        if (old_is_valid() or not new_is_valid()):
            return

        if settings.DEBUG and request.method == 'POST':
            raise RuntimeError("Can't redirect POST in AppendSlashMiddleware.")

        # Redirect rest:
        url = http_utils.urlquote('%s/' % request.path_info)
        if request.META.get('QUERY_STRING', ''):
            url += '?' + request.META['QUERY_STRING']
        return http.HttpResponsePermanentRedirect(url)
Example #48
0
 def process_response(self, request, response):
     if response.status_code == 404:
         if settings.APPEND_SLASH and not request.path_info.endswith('/'):
             return HttpResponseRedirect(f'{request.path_info}/')
         is_valid_path = urlresolvers.is_valid_path(
             request.path_info, 'static_pages.urls_i18n')
         if is_valid_path:
             view, args, kwargs = resolve(request.path_info,
                                          urlconf='static_pages.urls_i18n')
             kwargs['request'] = request
             return view(*args, **kwargs)
     return response
Example #49
0
    def process_response(self, request, response):
        if (response.status_code == 404
            and not request.path_info.startswith('/u/')
            and not is_valid_path(request.path_info)
            and User.objects.filter(
                username__iexact=request.path_info[1:].strip('/')).exists()):

            newurl = '/u' + request.path_info
            if request.GET:
                with safe_query_string(request):
                    newurl += '?' + request.META['QUERY_STRING']
            return HttpResponseRedirect(newurl)
        return response
    def perform_redirect(self, request, language, is_permanent=False):
        # language can be empty string (in case of default language)
        path_info = request.path_info
        if not language:
            path_info = self.remove_lang_from_path(path_info)
        urlconf = getattr(request, 'urlconf', None)
        language_path = '%s%s' % (language, path_info)
        if not language_path.startswith('/'):
            language_path = '/' + language_path
        path_valid = is_valid_path(language_path, urlconf)
        path_needs_slash = (
            not path_valid and (
                settings.APPEND_SLASH and not language_path.endswith('/')
                and is_valid_path('%s/' % language_path, urlconf)
            )
        )

        if path_valid or path_needs_slash:
            script_prefix = get_script_prefix()
            if DJANGO_VERSION < (1, 9):
                full_path = get_full_path(request, force_append_slash=path_needs_slash)
            else:
                full_path = request.get_full_path(force_append_slash=path_needs_slash)
            if not language:
                full_path = self.remove_lang_from_path(full_path)
            language_url = full_path.replace(
                script_prefix,
                '%s%s/' % (script_prefix, language) if language else script_prefix,
                1
            )
            # set 301 permanent redirect for baidu spider
            if request.META.get('HTTP_USER_AGENT') and 'baiduspider' in request.META['HTTP_USER_AGENT'].lower():
                is_permanent = True

            # return a 301 permanent redirect if on default language
            if (is_permanent):
                return self.response_default_language_redirect_class(language_url)
            else:
                return self.response_redirect_class(language_url)
Example #51
0
    def process_response(self, request, response):
        if (response.status_code == 404
                and not request.path_info.startswith('/u/')
                and not is_valid_path(request.path_info)
                and User.objects.filter(username__iexact=request.path_info[1:].
                                        strip('/')).exists()):

            newurl = '/u' + request.path_info
            if request.GET:
                with safe_query_string(request):
                    newurl += '?' + request.META['QUERY_STRING']
            return HttpResponseRedirect(newurl)
        return response
Example #52
0
    def process_request(request):
        # Проверяем запрет авторедиректа через GET-параметр
        if request.GET.get(options.MULTILANGUAGE_GET_PARAM):
            request.disable_autoredirect = True

            # Проверяем, что на текущем сайте есть такая страница,
            # иначе, редиректим на MULTILANGUAGE_FALLBACK_URL
            urlconf = getattr(request, 'urlconf', None)
            if not is_valid_path(request.path_info, urlconf):
                return redirect(options.MULTILANGUAGE_FALLBACK_URL)

            return

        # Проверяем запрет авторедиректа через куку
        if request.COOKIES.get(options.MULTILANGUAGE_COOKIE_KEY, None):
            return

        # Проверяем запрет авторедиректа для определенных User-Agent
        ua_string = request.META.get('HTTP_USER_AGENT', '').lower()
        for pattern in options.ROBOTS_UA:
            if pattern in ua_string:
                return

        # Получение информации о IP
        ip = get_client_ip(request)
        ip_info = info(ip, detailed=True)
        if not ip_info:
            request.disable_autoredirect = True
            return

        # Определение кода языка, на который нужно редиректить
        current_code = settings.LANGUAGE_CODE
        redirect_code = current_code
        try:
            ip_iso = ip_info.get('country').get('iso')
        except AttributeError:
            pass
        else:
            for code, opts in options.MULTILANGUAGE_SITES.items():
                iso = opts.get('iso')
                if iso and ip_iso in iso:
                    redirect_code = code
                    break

        if current_code != redirect_code:
            request.disable_autoredirect = True
            language = options.MULTILANGUAGE_SITES.get(redirect_code)
            if language:
                redirect_url = noredirect_url(language['url'],
                                              forced_path=request.path)
                return redirect(redirect_url)
Example #53
0
    def process_request(self, request):
        if getattr(settings, 'APPEND_SLASH') and getattr(
                settings, 'REMOVE_SLASH'):
            raise ImproperlyConfigured(
                "APPEND_SLASH and REMOVE_SLASH may not both be True.")

        old_url = request.path_info  # path_info only includes path, query information
        if getattr(settings, 'REMOVE_SLASH', False) and old_url[-1] == "/":
            urlconf = getattr(request, 'urlconf', None)

            new_url = old_url[:-1]

            # If the url with a / would 404 and without a slash wouldn't
            if (not urlresolvers.is_valid_path(
                    old_url, urlconf)) and urlresolvers.is_valid_path(
                        new_url, urlconf):
                if settings.DEBUG and request.method == 'POST':
                    if old_url.startswith("/api/"):
                        return api.error(
                            "You made a POST request to a URL ending with a slash. Please repeat your request without the slash."
                        )

                    raise RuntimeError((
                        ""
                        "You called this URL via POST, but the URL ends in a "
                        "slash and you have REMOVE_SLASH set. Django can't "
                        "redirect to the non-slash URL while maintaining POST "
                        "data. Change your form to point to %s (without a "
                        "trailing slash), or set REMOVE_SLASH=False in your "
                        "Django settings.") % (new_url))

                # The ? and everything after
                query_data = re.match(
                    r'^[^?]*(\?.*)?$',
                    request.build_absolute_uri()).group(1) or ""

                return http.HttpResponsePermanentRedirect(new_url + query_data)
    def perform_redirect(self, request, language, is_permanent=False):
        # language can be empty string (in case of default language)
        path_info = request.path_info
        full_path = request.get_full_path()
        if not language:
            path_info = self.remove_lang_from_path(path_info)
            full_path = self.remove_lang_from_path(full_path)
        urlconf = getattr(request, 'urlconf', None)
        language_path = '%s%s' % (language, path_info)
        if not language_path.startswith('/'):
            language_path = '/' + language_path
        path_valid = is_valid_path(language_path, urlconf)
        if (not path_valid and settings.APPEND_SLASH
                and not language_path.endswith('/')):
            path_valid = is_valid_path("%s/" % language_path, urlconf)

        if path_valid:
            if DJANGO_VERSION >= (1, 7):
                scheme = request.scheme
            else:
                scheme = 'https' if request.is_secure() else 'http'
            script_prefix = get_script_prefix()
            language_url = "%s://%s%s" % (
                scheme,
                request.get_host(),
                # insert language after the script prefix and before the
                # rest of the URL
                full_path.replace(
                    script_prefix, '%s%s/' %
                    (script_prefix, language) if language else script_prefix,
                    1))
            # return a 301 permanent redirect if on default language
            if (is_permanent):
                return self.response_default_language_redirect_class(
                    language_url)
            else:
                return self.response_redirect_class(language_url)
Example #55
0
    def process_response(self, request, response):
        language = translation.get_language()
        language_from_path = translation.get_language_from_path(
            request.path_info, supported=self._supported_languages)
        if (response.status_code == 404 and not language_from_path
                and self.is_language_prefix_patterns_used()):
            urlconf = getattr(request, 'urlconf', None)
            language_path = '/%s%s' % (language, request.path_info)
            path_valid = is_valid_path(language_path, urlconf)
            if (not path_valid and settings.APPEND_SLASH
                    and not language_path.endswith('/')):
                path_valid = is_valid_path("%s/" % language_path, urlconf)

            if path_valid:
                language_url = "%s://%s/%s%s" % (request.scheme,
                                                 request.get_host(), language,
                                                 request.get_full_path())
                return self.response_redirect_class(language_url)

        # Store language back into session if it is not present
        if hasattr(request, 'session') and '_language' not in request.session:
            # Backwards compatibility check on django_language (remove in 1.8);
            # revert to: `request.session.setdefault('_language', language)`.
            if 'django_language' in request.session:
                request.session['_language'] = request.session[
                    'django_language']
                del request.session['django_language']
            else:
                request.session['_language'] = language

        if not (self.is_language_prefix_patterns_used()
                and language_from_path):
            patch_vary_headers(response, ('Accept-Language', ))
        if 'Content-Language' not in response:
            response['Content-Language'] = language
        return response
Example #56
0
    def process_request(self, request):

        old_url = request.build_absolute_uri()
        # match any / followed by ? (query string present)
        # OR match / at the end of the string (no query string)
        trailing_slash_regexp = r'(\/(?=\?))|(\/$)'
        new_url = old_url

        if getattr(settings, 'APPEND_SLASH') and getattr(
                settings, 'REMOVE_SLASH'):
            raise ImproperlyConfigured(
                "APPEND_SLASH and REMOVE_SLASH may not both be True.")

        # Remove slash if REMOVE_SLASH is set and the URL has a trailing slash
        # and there is no pattern for the current path
        if getattr(settings, 'REMOVE_SLASH', False) and re.search(
                trailing_slash_regexp, old_url):
            urlconf = getattr(request, 'urlconf', None)
            if (not urlresolvers.is_valid_path(request.path_info, urlconf)
                ) and urlresolvers.is_valid_path(request.path_info[:-1],
                                                 urlconf):
                new_url = re.sub(trailing_slash_regexp, '', old_url)
                if settings.DEBUG and request.method == 'POST':
                    raise RuntimeError((
                        ""
                        "You called this URL via POST, but the URL ends in a "
                        "slash and you have REMOVE_SLASH set. Django can't "
                        "redirect to the non-slash URL while maintaining POST "
                        "data. Change your form to point to %s (without a "
                        "trailing slash), or set REMOVE_SLASH=False in your "
                        "Django settings.") % (new_url))

        if new_url == old_url:
            # No redirects required.
            return
        return http.HttpResponsePermanentRedirect(new_url)
Example #57
0
    def process_response(self, request, response):
        language_from_path = get_language_from_path(request.path_info)

        if response.status_code == 404 and language_from_path == settings.LANGUAGE_CODE:
            urlconf = getattr(request, 'urlconf', None)
            new_path = self.strip_language(request.path_info)
            path_valid = is_valid_path(new_path, urlconf)

            if (not path_valid and settings.APPEND_SLASH
                    and not new_path.endswith('/')):
                path_valid = is_valid_path("%s/" % new_path, urlconf)

            if path_valid:
                script_prefix = get_script_prefix()
                old_path = get_script_prefix() + language_from_path + '/'
                language_url = "%s://%s%s" % (
                    request.scheme,
                    request.get_host(),
                    # replace the old path which contains language code
                    # to the script prefix without language code
                    request.get_full_path().replace(old_path, script_prefix,
                                                    1))
                return self.response_redirect_class(language_url)
        return response