6

Is there a way to make Python SimpleHTTPServer supports mod_rewrite?

I'm trying things with Ember.js with leveraging History API as the location API, and to make it work, I have to :

1) add some vhosts config in WAMP (not simple), or
2) run python -m simpleHTTPServer (very simple)

So when I opened it in the browser, localhost:3000 and clicked around the navigation (about and users for example), it worked well. The URLs are changed by Ember.js to localhost:3000/about and localhost:3000/users respectively.

But when I tried to open localhost:3000/about directly in new tab, the python web server simply returns 404.

I had my .htaccess redirecting everything to index.html, but I suspect python simple web server doesn't really read the htaccess file (am I right on this?)

I've tried downloading PHP 5.4.12 and run the built in web server, the url and htaccess mod_rewrite works well. But I'm still reluctant to upgrade from stable 5.3 to (probably still unstable enough) 5.4.12, so if there's a way to support mod_rewrite in python simple web server, that would be preferrable.

Thanks for the answer.

Henson
  • 5,563
  • 12
  • 46
  • 60

4 Answers4

9

By modifying pd40's answer, I came up with this which doesn't redirect, it does your traditional "send index.html instead of 404". Not at all optimized, but it works for testing and development which is all I needed.

import SimpleHTTPServer, SocketServer
import urlparse, os

PORT = 3456

class MyHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
   def do_GET(self):

       # Parse query data to find out what was requested
       parsedParams = urlparse.urlparse(self.path)

       # See if the file requested exists
       if os.access('.' + os.sep + parsedParams.path, os.R_OK):
          # File exists, serve it up
          SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self);
       else:
          # send index.hmtl
          self.send_response(200)
          self.send_header('Content-Type', 'text/html')
          self.end_headers()
          with open('index.html', 'r') as fin:
            self.copyfile(fin, self.wfile)

Handler = MyHandler

httpd = SocketServer.TCPServer(("", PORT), Handler)

print "serving at port", PORT
httpd.serve_forever()
Brigand
  • 84,529
  • 20
  • 165
  • 173
7

SimpleHTTPServer does not support apache modules and does not respect .htaccess, because it isn't apache. it won't work with php either.

thkang
  • 11,215
  • 14
  • 67
  • 83
  • 1
    In fact, `SimpleHTTPServer` doesn't do much more than serve static files and html. – mvanveen Mar 14 '13 at 05:34
  • yeah, i guess so too. So anyway or any recommended simple web server that is simple to use and at least supports mod_rewrite? – Henson Mar 14 '13 at 05:59
  • 1
    It wouldn't be a "simple" web server if it supported all that stuff. – LtWorf Mar 14 '13 at 07:46
  • It can be freely extended, though. You could make it support almost anything. – XTL Dec 17 '14 at 16:00
  • I was able to get SimpleHTTPServer to serve an html file with a linked JavaScript library only while that library file and the html file were both stored in the same directory. – noobninja Apr 02 '16 at 07:57
7

If you know the cases you need to redirect you can subclass SimpleHTTPRequestHandler and do a redirect. This redirects any missing file requests to /index.html

import SimpleHTTPServer, SocketServer
import urlparse, os

PORT = 3000

class MyHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
   def do_GET(self):

       # Parse query data to find out what was requested
       parsedParams = urlparse.urlparse(self.path)

       # See if the file requested exists
       if os.access('.' + os.sep + parsedParams.path, os.R_OK):
          # File exists, serve it up
          SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self);
       else:
          # redirect to index.html
          self.send_response(302)
          self.send_header('Content-Type', 'text/html')  
          self.send_header('location', '/index.html')  
          self.end_headers()

Handler = MyHandler

httpd = SocketServer.TCPServer(("", PORT), Handler)

print "serving at port", PORT
httpd.serve_forever()
pd40
  • 3,187
  • 3
  • 20
  • 29
2

No mod_rewrite in Python servers I am afraid, unless you run python scripts behind an Apache server, a resource-costly solution.

Try Cherrypy (http://www.cherrypy.org/), which allows you to manage your page handlers, and very simply makes clean URLs.

Benoit
  • 163
  • 7