Skip to content

Commit

Permalink
Add initial pass at proxy server.
Browse files Browse the repository at this point in the history
See __doc__ on run_server, or do "script/tsapp help".

The goal here is to be able to work on local files that are
currently formatted for use on the remote server without having
to change them, and then once those files are "good" being able to
get them to the server without changes.

In order to be fully effective the proxy will need to proxy PUT
as well as GET, but this just does GET for now.
  • Loading branch information
cdent committed Jul 22, 2012
1 parent 0dd9ec7 commit 0ff15f3
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 1 deletion.
13 changes: 13 additions & 0 deletions script/tsapp
@@ -0,0 +1,13 @@
#!/usr/bin/env python

import sys, os

# extend module search path for dev access and use
cwd = os.getcwd()
sys.path.insert(0, cwd)

from tsapp import handle

if __name__ == '__main__':
args = [unicode(arg, 'UTF-8') for arg in sys.argv[1:]]
handle(args)
80 changes: 79 additions & 1 deletion tsapp/__init__.py
@@ -1,3 +1,81 @@
"""
holder
Basic starting point for tsapp commands.
"""

import sys

def error_exit(code, message=""):
"""
Exit with code and provided message.
"""
if message:
sys.stderr.write("%s\n" % message)
sys.exit(code)


def read_config():
"""
Read the local config to manage options.
TODO: Get local overrides for things like target server.
"""
pass


def run_server(args):
"""
Run a wsgi server at :8080 which will look locally for content
and if not found there, look remotely. A path which takes the
form /bags/something/tiddlers/filename will look in the local
dir called "assets" for "filename". If the file is not found, the
full path will be looked up at tiddlyspace.com.
If the path is a single file or begins with "/" then the file
will be looked for in the local dir without failover to the
remote server.
At the moment only GET is handled. PUT is recognized, but not
yet proxied. When it is implemented it will only proxy, no
local handing will be done.
"""
read_config()

from wsgiref.simple_server import make_server
from tsapp.proxy import app

httpd = make_server('', 8080, app)

print "Serving on http://0.0.0.0:8080/index.html"

try:
httpd.serve_forever()
except KeyboardInterrupt:
sys.exit(0)


def show_help(args):
"""
Display this help.
"""
for command in COMMANDS:
print '%s%s' % (command, COMMANDS[command].__doc__)


COMMANDS = {
'serve': run_server,
'help': show_help
}

def handle(args):
"""
Process command line arguments to call commands.
"""
try:
command = args.pop(0)
functor = COMMANDS[command]
functor(args)
except IndexError:
error_exit(1, "command required")
except KeyError:
error_exit(1, "command unknown")
# let others raise themselves, for now
57 changes: 57 additions & 0 deletions tsapp/proxy.py
@@ -0,0 +1,57 @@
"""
WSGI app that provides a proxy to tiddlyspace as needed.
"""

import os
import mimetypes
import urllib2


def app(environ, start_response):
if environ['REQUEST_METHOD'].upper() == 'PUT':
return handle_put(environ, start_response)
else:
return handle_get(environ, start_response)

def handle_put(environ, start_response):
pass

def handle_get(environ, start_response):
path = environ['PATH_INFO']

path = path.lstrip('/')
path_parts = path.split('/')

if len(path_parts) == 1:
try:
filehandle = open(path)
mime_type = mimetypes.guess_type(path)[0]
except IOError:
start_response('404 Not Found', [])
return []
else:
local_path = path_parts[-1]
try:
filehandle = in_assets(local_path)
mime_type = mimetypes.guess_type(local_path)[0]
except IOError:
try:
filehandle = at_server(path)
mime_type = filehandle.info().gettype()
except IOError, exc:
code = exc.getcode()
start_response(str(code) + ' error', [])
return []

start_response('200 OK', [('Content-Type', mime_type)])
return filehandle


def in_assets(path):
return open(os.path.join('.', 'assets', path))

def at_server(path):
if not path.startswith('/'):
path = '/%s' % path
return urllib2.urlopen('http://tiddlyspace.com' + path)

0 comments on commit 0ff15f3

Please sign in to comment.