#!/usr/bin/python
#
-# Simple standalone HTTP server for testing PLCAPI
+# Standalone WSGI PLCAPI Server
#
-# Mark Huang <mlhuang@cs.princeton.edu>
+# Tony Mack <tmack@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id: Server.py,v 1.3 2006/10/25 20:33:07 mlhuang Exp $
-#
import os
import sys
-import getopt
import traceback
-import BaseHTTPServer
-
+from optparse import OptionParser
+from gevent import pywsgi
# Append PLC to the system path
sys.path.append(os.path.dirname(os.path.realpath(sys.argv[0])))
-
from PLC.API import PLCAPI
+from PLC.Config import Config
+from PLC.Logger import logger
-class PLCAPIRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
- """
- Simple standalone HTTP request handler for testing PLCAPI.
- """
-
- def do_POST(self):
- try:
- # Read request
- request = self.rfile.read(int(self.headers["Content-length"]))
- # Handle request
- response = self.server.api.handle(self.client_address, request)
+class App:
- # Write response
- self.send_response(200)
- self.send_header("Content-type", "text/xml")
- self.send_header("Content-length", str(len(response)))
- self.end_headers()
- self.wfile.write(response)
+ def __init__(self, api=None):
+ if not api:
+ api = PLCAPI()
+ self.api = api
- self.wfile.flush()
- self.connection.shutdown(1)
+ def __call__(self, *args, **kwds):
+ return self.handle(*args, **kwds)
- except Exception, e:
- # Log error
- sys.stderr.write(traceback.format_exc())
- sys.stderr.flush()
-
- def do_GET(self):
- self.send_response(200)
- self.send_header("Content-type", 'text/html')
- self.end_headers()
- self.wfile.write("""
+ def handle(self, env, start_response):
+ if env['REQUEST_METHOD'] == 'POST':
+ return self.do_post(env, start_response)
+ else:
+ return self.do_get(env, start_response)
+
+ def do_get(self, env, start_response):
+ response = """
<html><head>
-<title>PLCAPI XML-RPC/SOAP Interface</title>
+<title>PLCAPI Nova XML-RPC/SOAP Interface</title>
</head><body>
<h1>PLCAPI XML-RPC/SOAP Interface</h1>
<p>Please use XML-RPC or SOAP to access the PLCAPI.</p>
</body></html>
-""")
-
-class PLCAPIServer(BaseHTTPServer.HTTPServer):
- """
- Simple standalone HTTP server for testing PLCAPI.
- """
+"""
+ status = '200 OK'
+ headers = [('Content-Type', 'text/html')]
+ start_response(status, headers)
+ return [response]
+
+ def do_post(self, env, start_response):
+ try:
+ request_size = int(env.get('CONTENT_LENGTH', 0))
+ except (ValueError):
+ request_size = 0
+ request = env['wsgi.input'].read(request_size)
+ client_address = env['REMOTE_ADDR']
+
+ try:
+ response = self.api.handle(client_address, request)
+ status = '200 OK'
+ headers = [('Content-Type', 'text/html')]
+ except:
+ response = "'<h1>Internal Server Error</h1>"
+ status = '500 Internal Server Error'
+ headers = [('Content-Type', 'text/html')]
+ logger.log_exc(status)
+
+ start_response(status, headers)
+ return [response]
- def __init__(self, addr, config):
- self.api = PLCAPI(config)
- self.allow_reuse_address = 1
- BaseHTTPServer.HTTPServer.__init__(self, addr, PLCAPIRequestHandler)
# Defaults
addr = "0.0.0.0"
port = 8000
-config = "/etc/planetlab/plc_config"
+config_file = '/etc/planetlab/plcapi_config'
+keyfile=None
+certfile=None
+
-def usage():
+# Get options
+parser = OptionParser()
+parser.add_option('-p', '--port', dest='port', metavar='<port>', help='TCP port number to listen on')
+parser.add_option('-f', '--config', dest='config', metavar='<config>', help='PLCAPI configuration file')
+options = None
+args = None
+try:
+ (options, args) = parser.parse_args()
+except:
print "Usage: %s [OPTION]..." % sys.argv[0]
print "Options:"
print " -p PORT, --port=PORT TCP port number to listen on (default: %d)" % port
print " -f FILE, --config=FILE PLC configuration file (default: %s)" % config
print " -h, --help This message"
- sys.exit(1)
-
-# Get options
-try:
- (opts, argv) = getopt.getopt(sys.argv[1:], "p:f:h", ["port=", "config=", "help"])
-except getopt.GetoptError, err:
- print "Error: " + err.msg
- usage()
-
-for (opt, optval) in opts:
- if opt == "-p" or opt == "--port":
- try:
- port = int(optval)
- except ValueError:
- usage()
- elif opt == "-f" or opt == "--config":
- config = optval
- elif opt == "-h" or opt == "--help":
- usage()
-
-# Start server
-PLCAPIServer((addr, port), config).serve_forever()
+ sys.exit(1)
+
+if options.config:
+ config = Config(options.config)
+ addr = config.api_host
+ keyfile = config.api_ssl_key
+ certfile = config.api_ssl_cert
+
+if options.port:
+ port = int(options.port)
+
+if keyfile and certfile:
+ server = pywsgi.WSGIServer((addr, port), App(), keyfile=keyfile, certfile=certfile)
+else:
+ server = pywsgi.WSGIServer((addr, port), App())
+
+server.serve_forever()