1

I've added this to my .htacces:

RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.
RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]

but then trying to reach www.example.com redirects me to:

http://example.com/example/wsgi.py/

because i have WSGIScriptAlias / home/www/example.com/example/wsgi.py directive in my httpd.conf and of course i get 404 error.

Eventually, i've managed to fix this by adding next line in my urls.py:

url(r'^example/wsgi.py/$', index), (so it redirects to home page)

but i'm not quite sure that this is the right way to do it (because when i try to reach example.com i see that web browser changes address quickly to www.example.com and then again to example.com)

If anyone would ask, yes i've seen this but this didn't help me either, because browser gets url recursive problem (example.com/example.com/example.com/example.com/example.com...)

EDIT : FOLDER STRUCTURE

This is my folder structure:

\mysite\ static\ media\ .htaccess manage.py mysite\ templates templatetags tinymce static urls.py settigs.py views.py wsgi.py models.py forms.py __init__.py

Ljubisa Livac
  • 819
  • 3
  • 13
  • 38

4 Answers4

3

I know this has been answered some time back but to add to the answer given above use

host.startswith('www.')

its more readable and also you should use permanent redirect to give the browser correct response header.

from django import http

class NoWWWRedirectMiddleware(object):
    def process_request(self, request):
        host = request.get_host()
        if host.startswith('www.'):
            if request.method == 'GET':  # if wanna be a prefect REST citizen, consider HEAD and OPTIONS here as well
                no_www_host = host[4:]
                url = request.build_absolute_uri().replace(host, no_www_host, 1)
                return http.HttpResponsePermanentRedirect(url)
user1940979
  • 895
  • 1
  • 13
  • 29
2

I find it much simpler to accomplish no-www redirects with middleware that with with Apache mod_rewrite config.

The middleware that you linked to looks like it does the trick. I'm guessing your problems came from Apache config - make sure you remove all mod_rewrite commands (Rewrite* stuff) and then restart the apache server (ref. Apache docs but check for your OS, might be specific).

There is only one additional tweak that you should to: make sure you don't redirect any POST requests, because that might result in lost data (tangent ref: Why doesn't HTTP have POST redirect?).

Anyways, this is what I use, worked quite well for me:

from django.http import HttpResponseRedirect

class NoWWWRedirectMiddleware(object):
    def process_request(self, request):

    if request.method == 'GET':  # if wanna be a prefect REST citizen, consider HEAD and OPTIONS here as well
        host = request.get_host()
        if host.lower().find('www.') == 0:
            no_www_host = host[4:]
            url = request.build_absolute_uri().replace(host, no_www_host, 1)
            return HttpResponseRedirect(url)

To use it, put in a file somewhere, maybe mysite/mysite/middleware.py. Then make sure it's run, in your settings.py:

MIDDLEWARE_CLASSES = (
    'mysite.middleware.NoWWWRedirectMiddleware',
    # ... other middleware ...

If there is no MIDDLEWARE_CLASSES in your settings.py then copy the defaults from here in the Django docs but make you're looking at the correct version of Django, there are some changes in 1.7!

Community
  • 1
  • 1
frnhr
  • 12,354
  • 9
  • 63
  • 90
  • Thank you for your thorough answer and explanations! I've tried as you suggested but i still have problems: with this middleware i'm able to open my site when I hit 'www.example.com', but just 'example.com' returns this error: `Traceback (most recent call last): File "/usr/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 90, in get_response response = middleware_method(request) TypeError: process_request() takes exactly 5 arguments (2 given) ` – Ljubisa Livac Oct 19 '14 at 20:15
  • @frnhr: Coming from a different angle, would it be better (performance wise) to do this in the middleware as compared to doing it at the web server level? – Hassan Baig Jul 25 '17 at 21:20
  • Performance-wise it is better to do it earlier in the server stack (on Apache, nginx or what have you). Also make sure it is a permanent redirect, thanks user1940979 for pointing that out, see his answer below. – frnhr Jul 27 '17 at 09:56
1

Modified version that works with Django 1.11+ style middleware:

from django.http import HttpResponsePermanentRedirect

class NoWWWRedirectMiddleware:
    def __init__(self, get_response=None):
        self.get_response = get_response

    def __call__(self, request):
        response = self.process_request(request)
        return response or self.get_response(request)

    def process_request(self, request):
        host = request.get_host()
        if host.startswith('www.'):
            if request.method == 'GET':
                no_www = host[4:]
                url = request.build_absolute_uri().replace(host, no_www, 1)
                    return HttpResponsePermanentRedirect(url)
drpancake
  • 11
  • 1
  • 2
0

This Apache configuration works for me:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.example.com$ [NC]
RewriteRule ^(.*)$ http://example.com$1 [R=301,L]

WSGIScriptAlias / /home/www/example.com/example/wsgi.py
WSGIPythonPath /home/www/example.com/example

<Directory /home/www/example.com/example>
  <Files wsgi.py>
    Require all granted
  </Files>
</Directory>
Reto Aebersold
  • 16,306
  • 5
  • 55
  • 74
  • I'm unable to restart Apache server with `WSGIPythonPath /home/www/example.com/example`. Second, i had to `Require all granted` change to `Order deny,allow Allow from all` because im running 2.2 apache. Third, if i remove `WSGIPythonPath /home/www/example.com/example` apache is able to restart, but hitting www.example.com still gives me example.com/example/wsgi.py :( – Ljubisa Livac Oct 16 '14 at 17:01
  • What errors do you get if you use the WSGIPythonPath in the confid? Can you please describe your folder structure of your app in your question? – Reto Aebersold Oct 16 '14 at 17:37
  • Unfortunately, i don't know what type of error is because i restart services through Webuzo control panel. It says only 'Service was unable to restart.' How can i check what type of error is? Sorry, i'm noob for apache. I've added my folder structure. – Ljubisa Livac Oct 17 '14 at 09:42