added create_network(), delete_network(), create_subnet(), delete_subnet(), process_t...
[plcapi.git] / Server.py
index 40a68ab..8814190 100755 (executable)
--- a/Server.py
+++ b/Server.py
 #!/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$
-#
 
 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()