| 1 | #============================================================================ |
|---|
| 2 | # This library is free software; you can redistribute it and/or |
|---|
| 3 | # modify it under the terms of version 2.1 of the GNU Lesser General Public |
|---|
| 4 | # License as published by the Free Software Foundation. |
|---|
| 5 | # |
|---|
| 6 | # This library is distributed in the hope that it will be useful, |
|---|
| 7 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 8 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 9 | # Lesser General Public License for more details. |
|---|
| 10 | # |
|---|
| 11 | # You should have received a copy of the GNU Lesser General Public |
|---|
| 12 | # License along with this library; if not, write to the Free Software |
|---|
| 13 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 14 | #============================================================================ |
|---|
| 15 | # Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com> |
|---|
| 16 | #============================================================================ |
|---|
| 17 | |
|---|
| 18 | import types |
|---|
| 19 | |
|---|
| 20 | |
|---|
| 21 | from xen.xend import sxp |
|---|
| 22 | from xen.xend import PrettyPrint |
|---|
| 23 | from xen.xend.Args import ArgError |
|---|
| 24 | from xen.xend.XendError import XendError |
|---|
| 25 | from xen.xend.XendLogging import log |
|---|
| 26 | |
|---|
| 27 | import resource |
|---|
| 28 | import http |
|---|
| 29 | import httpserver |
|---|
| 30 | |
|---|
| 31 | def uri_pathlist(p): |
|---|
| 32 | """Split a path into a list. |
|---|
| 33 | p path |
|---|
| 34 | return list of path elements |
|---|
| 35 | """ |
|---|
| 36 | l = [] |
|---|
| 37 | for x in p.split('/'): |
|---|
| 38 | if x == '': continue |
|---|
| 39 | l.append(x) |
|---|
| 40 | return l |
|---|
| 41 | |
|---|
| 42 | class SrvBase(resource.Resource): |
|---|
| 43 | """Base class for services. |
|---|
| 44 | """ |
|---|
| 45 | |
|---|
| 46 | |
|---|
| 47 | def use_sxp(self, req): |
|---|
| 48 | return req.useSxp() |
|---|
| 49 | |
|---|
| 50 | def get_op_method(self, op): |
|---|
| 51 | """Get the method for an operation. |
|---|
| 52 | For operation 'foo' looks for 'op_foo'. |
|---|
| 53 | |
|---|
| 54 | op operation name |
|---|
| 55 | returns method or None |
|---|
| 56 | """ |
|---|
| 57 | op_method_name = 'op_' + op |
|---|
| 58 | return getattr(self, op_method_name, None) |
|---|
| 59 | |
|---|
| 60 | def perform(self, req): |
|---|
| 61 | """General operation handler for posted operations. |
|---|
| 62 | For operation 'foo' looks for a method op_foo and calls |
|---|
| 63 | it with op_foo(op, req). Replies with code 500 if op_foo |
|---|
| 64 | is not found. |
|---|
| 65 | |
|---|
| 66 | The method must return a list when req.use_sxp is true |
|---|
| 67 | and an HTML string otherwise (or list). |
|---|
| 68 | Methods may also return a ThreadRequest (for incomplete processing). |
|---|
| 69 | |
|---|
| 70 | req request |
|---|
| 71 | """ |
|---|
| 72 | op = req.args.get('op') |
|---|
| 73 | if op is None or len(op) != 1: |
|---|
| 74 | req.setResponseCode(http.NOT_ACCEPTABLE, "Invalid request") |
|---|
| 75 | return '' |
|---|
| 76 | op = op[0] |
|---|
| 77 | op_method = self.get_op_method(op) |
|---|
| 78 | if op_method is None: |
|---|
| 79 | req.setResponseCode(http.NOT_IMPLEMENTED, "Operation not implemented: " + op) |
|---|
| 80 | req.setHeader("Content-Type", "text/plain") |
|---|
| 81 | req.write("Operation not implemented: " + op) |
|---|
| 82 | return '' |
|---|
| 83 | else: |
|---|
| 84 | try: |
|---|
| 85 | return op_method(op, req) |
|---|
| 86 | except Exception, exn: |
|---|
| 87 | req.setResponseCode(http.INTERNAL_SERVER_ERROR, "Request failed: " + op) |
|---|
| 88 | log.exception("Request %s failed.", op) |
|---|
| 89 | if req.useSxp(): |
|---|
| 90 | return ['xend.err', str(exn)] |
|---|
| 91 | else: |
|---|
| 92 | return "<p>%s</p>" % str(exn) |
|---|
| 93 | |
|---|
| 94 | def print_path(self, req): |
|---|
| 95 | """Print the path with hyperlinks. |
|---|
| 96 | """ |
|---|
| 97 | req.printPath() |
|---|
| 98 | |
|---|