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 | |
---|