diff --git a/README.md b/README.md
index 4b1f13e8d7f..c4a4944d4f0 100644
--- a/README.md
+++ b/README.md
@@ -331,7 +331,7 @@ optional parameter: attributes - JSON encoded object
**/api/events/<event_type>** - POST
Fires an event with event_type
-optional parameter: event_data - JSON encoded object
+optional body: JSON encoded object that represents event_data
```json
{
@@ -341,7 +341,7 @@ optional parameter: event_data - JSON encoded object
**/api/services/<domain>/<service>** - POST
Calls a service within a specific domain.
-optional parameter: service_data - JSON encoded object
+optional body: JSON encoded object that represents service_data
```json
{
diff --git a/homeassistant/components/http/__init__.py b/homeassistant/components/http/__init__.py
index d8dd382d41e..6c06283a336 100644
--- a/homeassistant/components/http/__init__.py
+++ b/homeassistant/components/http/__init__.py
@@ -383,7 +383,7 @@ class RequestHandler(BaseHTTPRequestHandler):
""
""
+ "src='/static/javascripts/require.js'>"
""
"
"
""
@@ -637,9 +637,11 @@ class RequestHandler(BaseHTTPRequestHandler):
def _handle_get_api_events(self, path_match, data):
""" Handles getting overview of event listeners. """
- self._write_json(self.server.hass.bus.listeners)
+ self._write_json([{"event": key, "listener_count": value}
+ for key, value
+ in self.server.hass.bus.listeners.items()])
- def _handle_api_post_events_event(self, path_match, data):
+ def _handle_api_post_events_event(self, path_match, event_data):
""" Handles firing of an event.
This handles the following paths:
@@ -648,7 +650,6 @@ class RequestHandler(BaseHTTPRequestHandler):
Events from /api are threated as remote events.
"""
event_type = path_match.group('event_type')
- event_data = data.get('event_data')
if event_data is not None and not isinstance(event_data, dict):
self._message("event_data should be an object",
@@ -671,7 +672,10 @@ class RequestHandler(BaseHTTPRequestHandler):
def _handle_get_api_services(self, path_match, data):
""" Handles getting overview of services. """
- self._write_json(self.server.hass.services.services)
+ self._write_json(
+ [{"domain": key, "services": value}
+ for key, value
+ in self.server.hass.services.services.items()])
# pylint: disable=invalid-name
def _handle_post_api_services_domain_service(self, path_match, data):
@@ -742,9 +746,7 @@ class RequestHandler(BaseHTTPRequestHandler):
def _handle_get_static(self, path_match, data):
""" Returns a static file. """
- # req_file = util.sanitize_filename(path_match.group('file'))
- # TODO make safe
- req_file = path_match.group('file')
+ req_file = util.sanitize_path(path_match.group('file'))
path = os.path.join(os.path.dirname(__file__), 'www_static', req_file)
diff --git a/homeassistant/util.py b/homeassistant/util.py
index 2de31ce12dc..9c8a15e89ed 100644
--- a/homeassistant/util.py
+++ b/homeassistant/util.py
@@ -12,6 +12,7 @@ import enum
import socket
RE_SANITIZE_FILENAME = re.compile(r'(~|\.\.|/|\\)')
+RE_SANITIZE_PATH = re.compile(r'(~|\.(\.)+)')
RE_SLUGIFY = re.compile(r'[^A-Za-z0-9_]+')
DATE_STR_FORMAT = "%H:%M:%S %d-%m-%Y"
@@ -22,6 +23,11 @@ def sanitize_filename(filename):
return RE_SANITIZE_FILENAME.sub("", filename)
+def sanitize_path(path):
+ """ Sanitizes a path by removing .. / and \\. """
+ return RE_SANITIZE_PATH.sub("", path)
+
+
def slugify(text):
""" Slugifies a given text. """
text = text.strip().replace(" ", "_")