|
@@ -20,6 +20,7 @@ class BatcaveHttpRequestHandler(BaseHTTPRequestHandler):
|
|
|
BaseHTTPRequestHandler.__init__(self, request, client_address, server)
|
|
|
|
|
|
def parse_url_pathquery(self):
|
|
|
+ """Extracts the query parameters from the request path."""
|
|
|
url = re.match(r'^/(?P<path>.*?)(\?(?P<query>.+))?$', self.path.strip())
|
|
|
if url is None:
|
|
|
logging.warn('Failed to parse URL \'' + str(self.path) + '\'.')
|
|
@@ -33,23 +34,30 @@ class BatcaveHttpRequestHandler(BaseHTTPRequestHandler):
|
|
|
return ( path, query )
|
|
|
|
|
|
def do_GET(self):
|
|
|
+ """Handles all HTTP GET requests."""
|
|
|
+
|
|
|
path, query = self.parse_url_pathquery()
|
|
|
if path is None:
|
|
|
self.send_error(400, 'Could not parse URL (' + str(self.path) + ')')
|
|
|
return
|
|
|
|
|
|
+ # / - index page, shows generic help
|
|
|
if path == '':
|
|
|
self.respond_index(query)
|
|
|
return
|
|
|
|
|
|
+ # /list - list stored nodes
|
|
|
if path == 'list':
|
|
|
self.respond_list(query)
|
|
|
return
|
|
|
|
|
|
+ # /vpn - notification endpoint for gateway's VPN connections
|
|
|
if path == 'vpn':
|
|
|
self.respond_vpn(query)
|
|
|
return
|
|
|
|
|
|
+ # /node/<id>.json - node's data
|
|
|
+ # /node/<id>/field - return specific field from node's data
|
|
|
m = re.match(r'node/([a-f0-9]{12})(?P<cmd>\.json|/[a-zA-Z0-9_\-]+)$', path)
|
|
|
if m != None:
|
|
|
cmd = m.group('cmd')
|
|
@@ -59,20 +67,28 @@ class BatcaveHttpRequestHandler(BaseHTTPRequestHandler):
|
|
|
self.respond_nodedetail(m.group(1), cmd[1:])
|
|
|
return
|
|
|
|
|
|
+ # no match -> 404
|
|
|
self.send_error(404, 'The URL \'{0}\' was not found here.'.format(path))
|
|
|
|
|
|
def send_nocache_headers(self):
|
|
|
+ """Sets HTTP headers indicating that this response shall not be cached."""
|
|
|
+
|
|
|
self.send_header('Cache-Control', 'no-cache, no-store, must-revalidate')
|
|
|
self.send_header('Pragma', 'no-cache')
|
|
|
self.send_header('Expires', '0')
|
|
|
|
|
|
def send_headers(self, content_type='text/html; charset=utf-8', nocache=True):
|
|
|
+ """Send HTTP 200 Response header with the given Content-Type.
|
|
|
+ Optionally send no-caching headers, too."""
|
|
|
+
|
|
|
self.send_response(200)
|
|
|
self.send_header('Content-Type', content_type)
|
|
|
if nocache: self.send_nocache_headers()
|
|
|
self.end_headers()
|
|
|
|
|
|
def respond_index(self, query):
|
|
|
+ """Display the index page."""
|
|
|
+
|
|
|
storage = self.server.storage
|
|
|
self.send_headers()
|
|
|
|
|
@@ -98,6 +114,8 @@ class BatcaveHttpRequestHandler(BaseHTTPRequestHandler):
|
|
|
self.wfile.write('</body></html>')
|
|
|
|
|
|
def respond_list(self, query):
|
|
|
+ """List stored data."""
|
|
|
+
|
|
|
storage = self.server.storage
|
|
|
self.send_headers()
|
|
|
|
|
@@ -127,6 +145,8 @@ class BatcaveHttpRequestHandler(BaseHTTPRequestHandler):
|
|
|
self.wfile.write('</table>\n')
|
|
|
|
|
|
def respond_node(self, nodeid):
|
|
|
+ """Display node data."""
|
|
|
+
|
|
|
storage = self.server.storage
|
|
|
|
|
|
if nodeid == 'ff00ff00ff00':
|
|
@@ -138,10 +158,12 @@ class BatcaveHttpRequestHandler(BaseHTTPRequestHandler):
|
|
|
}))
|
|
|
return
|
|
|
|
|
|
+ # handle unknown nodes
|
|
|
if not nodeid in storage.data:
|
|
|
self.send_error(404, 'No node with id \'' + nodeid + '\' present.')
|
|
|
return
|
|
|
|
|
|
+ # dump node data as JSON
|
|
|
self.send_headers('text/json')
|
|
|
self.wfile.write(json.dumps(storage.data[nodeid]))
|
|
|
|