clockwerk-opensim – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | vero | 1 | #!/usr/bin/env python |
2 | # -*- encoding: utf-8 -*- |
||
3 | # |
||
4 | # Copyright (c) Contributors, http://opensimulator.org/ |
||
5 | # See CONTRIBUTORS.TXT for a full list of copyright holders. |
||
6 | # |
||
7 | # Redistribution and use in source and binary forms, with or without |
||
8 | # modification, are permitted provided that the following conditions are met: |
||
9 | # * Redistributions of source code must retain the above copyright |
||
10 | # notice, this list of conditions and the following disclaimer. |
||
11 | # * Redistributions in binary form must reproduce the above copyright |
||
12 | # notice, this list of conditions and the following disclaimer in the |
||
13 | # documentation and/or other materials provided with the distribution. |
||
14 | # * Neither the name of the OpenSim Project nor the |
||
15 | # names of its contributors may be used to endorse or promote products |
||
16 | # derived from this software without specific prior written permission. |
||
17 | # |
||
18 | # THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
||
19 | # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
||
20 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
||
21 | # DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
||
22 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||
23 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||
24 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||
25 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||
26 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||
27 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||
28 | # |
||
29 | |||
30 | import logging |
||
31 | import BaseHTTPServer |
||
32 | import optparse |
||
33 | import xml.etree.ElementTree as ET |
||
34 | import xml.parsers.expat |
||
35 | |||
36 | |||
37 | # enable debug level logging |
||
38 | logging.basicConfig(level = logging.DEBUG, |
||
39 | format='%(asctime)s %(levelname)s %(message)s') |
||
40 | |||
41 | options = None |
||
42 | |||
43 | # subclassed HTTPRequestHandler |
||
44 | class ConciergeHandler(BaseHTTPServer.BaseHTTPRequestHandler): |
||
45 | def logRequest(self): |
||
46 | logging.info('[ConciergeHandler] %(command)s request: %(host)s:%(port)d --- %(path)s', |
||
47 | dict(command = self.command, |
||
48 | host = self.client_address[0], |
||
49 | port = self.client_address[1], |
||
50 | path = self.path)) |
||
51 | |||
52 | def logResponse(self, status): |
||
53 | logging.info('[ConciergeHandler] %(command)s returned %(status)d', |
||
54 | dict(command = self.command, |
||
55 | status = status)) |
||
56 | |||
57 | |||
58 | def do_HEAD(self): |
||
59 | self.logRequest() |
||
60 | |||
61 | self.send_response(200) |
||
62 | self.send_header('Content-type', 'text/html') |
||
63 | self.end_headers() |
||
64 | |||
65 | self.logResponse(200) |
||
66 | |||
67 | def dumpXml(self, xml): |
||
68 | logging.debug('[ConciergeHandler] %s', xml.tag) |
||
69 | for attr in xml.attrib: |
||
70 | logging.debug('[ConciergeHandler] %s [%s] %s', xml.tag, attr, xml.attrib[attr]) |
||
71 | for kid in xml.getchildren(): |
||
72 | self.dumpXml(kid) |
||
73 | |||
74 | def do_POST(self): |
||
75 | self.logRequest() |
||
76 | hdrs = {} |
||
77 | for hdr in self.headers.headers: |
||
78 | logging.debug('[ConciergeHandler] POST: header: %s', hdr.rstrip()) |
||
79 | |||
80 | length = int(self.headers.getheader('Content-Length')) |
||
81 | content = self.rfile.read(length) |
||
82 | self.rfile.close() |
||
83 | |||
84 | logging.debug('[ConciergeHandler] POST: content: %s', content) |
||
85 | try: |
||
86 | postXml = ET.fromstring(content) |
||
87 | self.dumpXml(postXml) |
||
88 | except xml.parsers.expat.ExpatError, xmlError: |
||
89 | logging.error('[ConciergeHandler] POST illformed:%s', xmlError) |
||
90 | self.send_response(500) |
||
91 | return |
||
92 | |||
93 | if not options.fail: |
||
94 | self.send_response(200) |
||
95 | self.send_header('Content-Type', 'text/html') |
||
96 | self.send_header('Content-Length', len('<success/>')) |
||
97 | self.end_headers() |
||
98 | self.logResponse(200) |
||
99 | self.wfile.write('<success/>') |
||
100 | self.wfile.close() |
||
101 | else: |
||
102 | self.send_response(500) |
||
103 | self.send_header('Content-Type', 'text/html') |
||
104 | self.send_header('Content-Length', len('<error>gotcha!</error>')) |
||
105 | self.end_headers() |
||
106 | self.wfile.write('<error>gotcha!</error>') |
||
107 | self.wfile.close() |
||
108 | |||
109 | self.logResponse(500) |
||
110 | |||
111 | def log_request(code, size): |
||
112 | pass |
||
113 | |||
114 | if __name__ == '__main__': |
||
115 | |||
116 | logging.info('[ConciergeServer] Concierge Broker Test Server starting') |
||
117 | |||
118 | parser = optparse.OptionParser() |
||
119 | parser.add_option('-p', '--port', dest = 'port', help = 'port to listen on', metavar = 'PORT') |
||
120 | parser.add_option('-f', '--fail', dest = 'fail', action = 'store_true', help = 'always fail POST requests') |
||
121 | |||
122 | (options, args) = parser.parse_args() |
||
123 | |||
124 | httpServer = BaseHTTPServer.HTTPServer(('', 8080), ConciergeHandler) |
||
125 | try: |
||
126 | httpServer.serve_forever() |
||
127 | except KeyboardInterrupt: |
||
128 | logging.info('[ConciergeServer] terminating') |
||
129 | |||
130 | httpServer.server_close() |