ChangeSet 1.1327.2.2, 2005/04/21 14:25:07+01:00, mjw@xxxxxxxxxxxxxxxxxxx
Remove twisted from the HTTP server and replace with a
threaded server. Add classes to provide tcp and unix servers
using threads instead of twisted. Remove use of twisted from
the consoles, event server and HTTP resources
Signed-off-by: Mike Wray <mike.wray@xxxxxx>
b/tools/python/setup.py | 1
b/tools/python/xen/web/SrvBase.py | 160 +++++++
b/tools/python/xen/web/SrvDir.py | 115 +++++
b/tools/python/xen/web/__init__.py | 1
b/tools/python/xen/web/connection.py | 387 ++++++++++++++++++
b/tools/python/xen/web/defer.py | 3
b/tools/python/xen/web/http.py | 516 +++++++++++++++++++++++++
b/tools/python/xen/web/httpserver.py | 144 ++++++
b/tools/python/xen/web/protocol.py | 94 ++++
b/tools/python/xen/web/reactor.py | 9
b/tools/python/xen/web/resource.py | 91 ++++
b/tools/python/xen/web/static.py | 46 ++
b/tools/python/xen/web/tcp.py | 90 ++++
b/tools/python/xen/web/unix.py | 76 +++
b/tools/python/xen/xend/EventServer.py | 99 +++-
b/tools/python/xen/xend/XendDomain.py | 25 -
b/tools/python/xen/xend/XendDomainInfo.py | 84 +---
b/tools/python/xen/xend/scheduler.py | 24 -
b/tools/python/xen/xend/server/SrvBase.py | 185 --------
b/tools/python/xen/xend/server/SrvDaemon.py | 32 -
b/tools/python/xen/xend/server/SrvDir.py | 112 -----
b/tools/python/xen/xend/server/SrvDomain.py | 2
b/tools/python/xen/xend/server/SrvDomainDir.py | 4
b/tools/python/xen/xend/server/SrvRoot.py | 5
b/tools/python/xen/xend/server/SrvServer.py | 27 -
b/tools/python/xen/xend/server/SrvUsbif.py | 2
b/tools/python/xen/xend/server/SrvXendLog.py | 4
b/tools/python/xen/xend/server/blkif.py | 14
b/tools/python/xen/xend/server/console.py | 26 -
b/tools/python/xen/xend/server/controller.py | 10
b/tools/python/xen/xend/server/event.py | 25 -
b/tools/python/xen/xend/server/netif.py | 3
tools/python/xen/xend/server/SrvDeviceDir.py | 9
tools/python/xen/xend/server/domain.py | 58 --
34 files changed, 1931 insertions(+), 552 deletions(-)
diff -Nru a/tools/python/setup.py b/tools/python/setup.py
--- a/tools/python/setup.py 2005-05-13 16:03:38 -04:00
+++ b/tools/python/setup.py 2005-05-13 16:03:38 -04:00
@@ -43,6 +43,7 @@
'xen.xend.server',
'xen.sv',
'xen.xm',
+ 'xen.web',
],
ext_package = "xen.lowlevel",
ext_modules = [ xc, xu ]
diff -Nru a/tools/python/xen/web/SrvBase.py b/tools/python/xen/web/SrvBase.py
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/tools/python/xen/web/SrvBase.py 2005-05-13 16:03:38 -04:00
@@ -0,0 +1,160 @@
+# Copyright (C) 2004 Mike Wray <mike.wray@xxxxxx>
+
+import types
+
+from xen.xend import sxp
+from xen.xend import PrettyPrint
+from xen.xend.Args import ArgError
+from xen.xend.XendError import XendError
+from xen.xend.XendLogging import log
+
+import resource
+import http
+import defer
+
+def uri_pathlist(p):
+ """Split a path into a list.
+ p path
+ return list of path elements
+ """
+ l = []
+ for x in p.split('/'):
+ if x == '': continue
+ l.append(x)
+ return l
+
+class SrvBase(resource.Resource):
+ """Base class for services.
+ """
+
+
+ def use_sxp(self, req):
+ """Determine whether to send an SXP response to a request.
+ Uses SXP if there is no User-Agent, no Accept, or application/sxp is
in Accept.
+
+ req request
+ returns 1 for SXP, 0 otherwise
+ """
+ ok = 0
+ user_agent = req.getHeader('User-Agent')
+ accept = req.getHeader('Accept')
+ if (not user_agent) or (not accept) or (accept.find(sxp.mime_type) >=
0):
+ ok = 1
+ return ok
+
+ def get_op_method(self, op):
+ """Get the method for an operation.
+ For operation 'foo' looks for 'op_foo'.
+
+ op operation name
+ returns method or None
+ """
+ op_method_name = 'op_' + op
+ return getattr(self, op_method_name, None)
+
+ def perform(self, req):
+ """General operation handler for posted operations.
+ For operation 'foo' looks for a method op_foo and calls
+ it with op_foo(op, req). Replies with code 500 if op_foo
+ is not found.
+
+ The method must return a list when req.use_sxp is true
+ and an HTML string otherwise (or list).
+ Methods may also return a Deferred (for incomplete processing).
+
+ req request
+ """
+ op = req.args.get('op')
+ if op is None or len(op) != 1:
+ req.setResponseCode(http.NOT_ACCEPTABLE, "Invalid request")
+ return ''
+ op = op[0]
+ op_method = self.get_op_method(op)
+ if op_method is None:
+ req.setResponseCode(http.NOT_IMPLEMENTED, "Operation not
implemented: " + op)
+ req.setHeader("Content-Type", "text/plain")
+ req.write("Operation not implemented: " + op)
+ return ''
+ else:
+ return self._perform(op, op_method, req)
+
+ def _perform(self, op, op_method, req):
+ try:
+ val = op_method(op, req)
+ except Exception, err:
+ self._perform_err(err, op, req)
+ return ''
+
+ if isinstance(val, defer.Deferred):
+ val.addCallback(self._perform_cb, op, req, dfr=1)
+ val.addErrback(self._perform_err, op, req, dfr=1)
+ return server.NOT_DONE_YET
+ else:
+ self._perform_cb(val, op, req, dfr=0)
+ return ''
+
+ def _perform_cb(self, val, op, req, dfr=0):
+ """Callback to complete the request.
+ May be called from a Deferred.
+
+ @param err: the error
+ @param req: request causing the error
+ @param dfr: deferred flag
+ """
+ if isinstance(val, resource.ErrorPage):
+ req.write(val.render(req))
+ elif self.use_sxp(req):
+ req.setHeader("Content-Type", sxp.mime_type)
+ sxp.show(val, out=req)
+ else:
+ req.write('<html><head></head><body>')
+ self.print_path(req)
+ if isinstance(val, types.ListType):
+ req.write('<code><pre>')
+ PrettyPrint.prettyprint(val, out=req)
+ req.write('</pre></code>')
+ else:
+ req.write(str(val))
+ req.write('</body></html>')
+ if dfr:
+ req.finish()
+
+ def _perform_err(self, err, op, req, dfr=0):
+ """Error callback to complete a request.
+ May be called from a Deferred.
+
+ @param err: the error
+ @param req: request causing the error
+ @param dfr: deferred flag
+ """
+ if not (isinstance(err, ArgError) or
+ isinstance(err, sxp.ParseError) or
+ isinstance(err, XendError)):
+ if dfr:
+ return err
+ else:
+ raise
+ #log.exception("op=%s: %s", op, str(err))
+ if self.use_sxp(req):
+ req.setHeader("Content-Type", sxp.mime_type)
+ sxp.show(['xend.err', str(err)], out=req)
+ else:
+ req.setHeader("Content-Type", "text/plain")
+ req.write('Error ')
+ req.write(': ')
+ req.write(str(err))
+ if dfr:
+ req.finish()
+
+
+ def print_path(self, req):
+ """Print the path with hyperlinks.
+ """
+ pathlist = [x for x in req.prepath if x != '' ]
+ s = "/"
+ req.write('<h1><a href="/">/</a>')
+ for x in pathlist:
+ s += x + "/"
+ req.write(' <a href="%s">%s</a>/' % (s, x))
+ req.write("</h1>")
+
diff -Nru a/tools/python/xen/web/SrvDir.py b/tools/python/xen/web/SrvDir.py
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/tools/python/xen/web/SrvDir.py 2005-05-13 16:03:38 -04:00
@@ -0,0 +1,115 @@
+# Copyright (C) 2004 Mike Wray <mike.wray@xxxxxx>
+
+import types
+
+from xen.xend import sxp
+from xen.xend import PrettyPrint
+from xen.xend.Args import ArgError
+from xen.xend.XendError import XendError
+#from xen.xend.XendLogging import log
+
+import resource
+import http
+
+from xen.web.SrvBase import SrvBase
+
+class SrvConstructor:
+ """Delayed constructor for sub-servers.
+ Does not import the sub-server class or create the object until needed.
+ """
+
+ def __init__(self, klass):
+ """Create a constructor. It is assumed that the class
+ should be imported as 'import klass from klass'.
+
+ klass name of its class
+ """
+ self.klass = klass
+ self.obj = None
+
+ def getobj(self):
+ """Get the sub-server object, importing its class and instantiating it
if
+ necessary.
+ """
+ if not self.obj:
+ exec 'from xen.xend.server.%s import %s' % (self.klass, self.klass)
+ klassobj = eval(self.klass)
+ self.obj = klassobj()
+ return self.obj
+
+class SrvDir(SrvBase):
+ """Base class for directory servlets.
+ """
+ isLeaf = False
+
+ def __init__(self):
+ SrvBase.__init__(self)
+ self.table = {}
+ self.order = []
+
+ def __repr__(self):
+ return "<SrvDir %x %s>" %(id(self), self.table.keys())
+
+ def noChild(self, msg):
+ return resource.ErrorPage(http.NOT_FOUND, msg=msg)
+
+ def getChild(self, x, req):
+ if x == '': return self
+ try:
+ val = self.get(x)
+ except XendError, ex:
+ return self.noChild(str(ex))
+ if val is None:
+ return self.noChild('Not found: ' + str(x))
+ else:
+ return val
+
+ def get(self, x):
+ val = self.table.get(x)
+ if isinstance(val, SrvConstructor):
+ val = val.getobj()
+ return val
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|