mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 12:17:07 +00:00
Added gzip and better caching
This commit is contained in:
parent
506496743d
commit
d2a4d67cb0
@ -2,5 +2,9 @@
|
|||||||
# npm install -g bower vulcanize
|
# npm install -g bower vulcanize
|
||||||
cd homeassistant/components/http/www_static/polymer
|
cd homeassistant/components/http/www_static/polymer
|
||||||
bower install
|
bower install
|
||||||
vulcanize -o ../frontend.html --inline home-assistant-main.html
|
cd ..
|
||||||
cp bower_components/platform/platform.js ../polymer_platform.js
|
cp polymer/bower_components/platform/platform.js polymer_platform.js
|
||||||
|
vulcanize -o frontend.html --inline polymer/home-assistant-main.html
|
||||||
|
cd ..
|
||||||
|
echo '""" DO NOT MODIFY. Auto-generated by build_polymer script """' > frontend.py
|
||||||
|
echo 'VERSION = "'`md5 -q www_static/frontend.html`'"' >> frontend.py
|
||||||
|
@ -77,7 +77,8 @@ import logging
|
|||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
import gzip
|
||||||
|
from http.server import SimpleHTTPRequestHandler, HTTPServer
|
||||||
from socketserver import ThreadingMixIn
|
from socketserver import ThreadingMixIn
|
||||||
from urllib.parse import urlparse, parse_qs
|
from urllib.parse import urlparse, parse_qs
|
||||||
|
|
||||||
@ -86,6 +87,8 @@ import homeassistant.remote as rem
|
|||||||
import homeassistant.util as util
|
import homeassistant.util as util
|
||||||
from homeassistant.components import (STATE_ON, STATE_OFF,
|
from homeassistant.components import (STATE_ON, STATE_OFF,
|
||||||
SERVICE_TURN_ON, SERVICE_TURN_OFF)
|
SERVICE_TURN_ON, SERVICE_TURN_OFF)
|
||||||
|
from . import frontend
|
||||||
|
|
||||||
DOMAIN = "http"
|
DOMAIN = "http"
|
||||||
DEPENDENCIES = []
|
DEPENDENCIES = []
|
||||||
|
|
||||||
@ -102,32 +105,12 @@ URL_ROOT = "/"
|
|||||||
|
|
||||||
URL_STATIC = "/static/{}"
|
URL_STATIC = "/static/{}"
|
||||||
|
|
||||||
DOMAIN_ICONS = {
|
|
||||||
"sun": "glyphicon-asterisk",
|
|
||||||
"group": "glyphicon-th-large",
|
|
||||||
"charging": "glyphicon-flash",
|
|
||||||
"light": "glyphicon-hdd",
|
|
||||||
"wemo": "glyphicon-hdd",
|
|
||||||
"device_tracker": "glyphicon-phone",
|
|
||||||
"chromecast": "glyphicon-picture",
|
|
||||||
"process": "glyphicon-barcode",
|
|
||||||
"browser": "glyphicon-globe",
|
|
||||||
"homeassistant": "glyphicon-home",
|
|
||||||
"downloader": "glyphicon-download-alt"
|
|
||||||
}
|
|
||||||
|
|
||||||
CONF_API_PASSWORD = "api_password"
|
CONF_API_PASSWORD = "api_password"
|
||||||
CONF_SERVER_HOST = "server_host"
|
CONF_SERVER_HOST = "server_host"
|
||||||
CONF_SERVER_PORT = "server_port"
|
CONF_SERVER_PORT = "server_port"
|
||||||
CONF_DEVELOPMENT = "development"
|
CONF_DEVELOPMENT = "development"
|
||||||
|
|
||||||
|
|
||||||
def _get_domain_icon(domain):
|
|
||||||
""" Returns HTML that shows domain icon. """
|
|
||||||
return "<span class='glyphicon {}'></span>".format(
|
|
||||||
DOMAIN_ICONS.get(domain, ""))
|
|
||||||
|
|
||||||
|
|
||||||
def setup(hass, config):
|
def setup(hass, config):
|
||||||
""" Sets up the HTTP API and debug interface. """
|
""" Sets up the HTTP API and debug interface. """
|
||||||
|
|
||||||
@ -194,8 +177,15 @@ class HomeAssistantHTTPServer(ThreadingMixIn, HTTPServer):
|
|||||||
|
|
||||||
|
|
||||||
# pylint: disable=too-many-public-methods
|
# pylint: disable=too-many-public-methods
|
||||||
class RequestHandler(BaseHTTPRequestHandler):
|
class RequestHandler(SimpleHTTPRequestHandler):
|
||||||
""" Handles incoming HTTP requests """
|
"""
|
||||||
|
Handles incoming HTTP requests
|
||||||
|
|
||||||
|
We extend from SimpleHTTPRequestHandler instead of Base so we
|
||||||
|
can use the guess content type methods.
|
||||||
|
"""
|
||||||
|
|
||||||
|
server_version = "HomeAssistant/1.0"
|
||||||
|
|
||||||
PATHS = [ # debug interface
|
PATHS = [ # debug interface
|
||||||
('GET', URL_ROOT, '_handle_get_root'),
|
('GET', URL_ROOT, '_handle_get_root'),
|
||||||
@ -323,6 +313,10 @@ class RequestHandler(BaseHTTPRequestHandler):
|
|||||||
else:
|
else:
|
||||||
self.send_response(HTTP_NOT_FOUND)
|
self.send_response(HTTP_NOT_FOUND)
|
||||||
|
|
||||||
|
def do_HEAD(self): # pylint: disable=invalid-name
|
||||||
|
""" HEAD request handler. """
|
||||||
|
self._handle_request('HEAD')
|
||||||
|
|
||||||
def do_GET(self): # pylint: disable=invalid-name
|
def do_GET(self): # pylint: disable=invalid-name
|
||||||
""" GET request handler. """
|
""" GET request handler. """
|
||||||
self._handle_request('GET')
|
self._handle_request('GET')
|
||||||
@ -390,7 +384,7 @@ class RequestHandler(BaseHTTPRequestHandler):
|
|||||||
if self.server.development:
|
if self.server.development:
|
||||||
app_url = "polymer/home-assistant-main.html"
|
app_url = "polymer/home-assistant-main.html"
|
||||||
else:
|
else:
|
||||||
app_url = "frontend.html"
|
app_url = "frontend-{}.html".format(frontend.VERSION)
|
||||||
|
|
||||||
write(("<html>"
|
write(("<html>"
|
||||||
"<head><title>Home Assistant</title>"
|
"<head><title>Home Assistant</title>"
|
||||||
@ -405,7 +399,7 @@ class RequestHandler(BaseHTTPRequestHandler):
|
|||||||
" user-scalable=no, initial-scale=1.0, "
|
" user-scalable=no, initial-scale=1.0, "
|
||||||
" minimum-scale=1.0, maximum-scale=1.0' />"
|
" minimum-scale=1.0, maximum-scale=1.0' />"
|
||||||
"</head>"
|
"</head>"
|
||||||
"<body>"
|
"<body fullbleed>"
|
||||||
"<home-assistant-main auth='{}'></home-assistant-main>"
|
"<home-assistant-main auth='{}'></home-assistant-main>"
|
||||||
"</body></html>").format(app_url, self.server.api_password))
|
"</body></html>").format(app_url, self.server.api_password))
|
||||||
|
|
||||||
@ -579,28 +573,61 @@ class RequestHandler(BaseHTTPRequestHandler):
|
|||||||
""" Returns a static file. """
|
""" Returns a static file. """
|
||||||
req_file = util.sanitize_path(path_match.group('file'))
|
req_file = util.sanitize_path(path_match.group('file'))
|
||||||
|
|
||||||
|
# Strip md5 hash out of frontend filename
|
||||||
|
if re.match(r'^frontend-[A-Za-z0-9]{32}\.html$', req_file):
|
||||||
|
req_file = "frontend.html"
|
||||||
|
|
||||||
path = os.path.join(os.path.dirname(__file__), 'www_static', req_file)
|
path = os.path.join(os.path.dirname(__file__), 'www_static', req_file)
|
||||||
|
|
||||||
if os.path.isfile(path):
|
inp = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
inp = open(path, 'rb')
|
||||||
|
|
||||||
|
do_gzip = 'gzip' in self.headers.get('accept-encoding', '')
|
||||||
|
|
||||||
self.send_response(HTTP_OK)
|
self.send_response(HTTP_OK)
|
||||||
self.send_header("Cache-control", "public, max-age=3600")
|
|
||||||
self.send_header("Expires",
|
|
||||||
self.date_time_string(time.time()+3600))
|
|
||||||
|
|
||||||
self.end_headers()
|
ctype = self.guess_type(path)
|
||||||
|
self.send_header("Content-Type", ctype)
|
||||||
|
|
||||||
with open(path, 'rb') as inp:
|
# Add cache if not development
|
||||||
data = inp.read(1024)
|
if not self.server.development:
|
||||||
|
# 1 year in seconds
|
||||||
|
cache_time = 365 * 86400
|
||||||
|
|
||||||
while data:
|
self.send_header(
|
||||||
self.wfile.write(data)
|
"Cache-Control", "public, max-age={}".format(cache_time))
|
||||||
|
self.send_header(
|
||||||
|
"Expires", self.date_time_string(time.time()+cache_time))
|
||||||
|
|
||||||
data = inp.read(1024)
|
if do_gzip:
|
||||||
|
gzip_data = gzip.compress(inp.read())
|
||||||
|
|
||||||
|
self.send_header("Content-Encoding", "gzip")
|
||||||
|
self.send_header("Vary", "Accept-Encoding")
|
||||||
|
self.send_header("Content-Length", str(len(gzip_data)))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
fs = os.fstat(inp.fileno())
|
||||||
|
self.send_header("Content-Length", str(fs[6]))
|
||||||
|
|
||||||
|
self.end_headers()
|
||||||
|
|
||||||
|
if do_gzip:
|
||||||
|
self.wfile.write(gzip_data)
|
||||||
|
|
||||||
|
else:
|
||||||
|
self.copyfile(inp, self.wfile)
|
||||||
|
|
||||||
|
except IOError:
|
||||||
self.send_response(HTTP_NOT_FOUND)
|
self.send_response(HTTP_NOT_FOUND)
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
|
|
||||||
|
finally:
|
||||||
|
if inp:
|
||||||
|
inp.close()
|
||||||
|
|
||||||
def _message(self, message, status_code=HTTP_OK):
|
def _message(self, message, status_code=HTTP_OK):
|
||||||
""" Helper method to return a message to the caller. """
|
""" Helper method to return a message to the caller. """
|
||||||
if self.use_json:
|
if self.use_json:
|
||||||
|
2
homeassistant/components/http/frontend.py
Normal file
2
homeassistant/components/http/frontend.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
""" DO NOT MODIFY. Auto-generated by build_polymer script """
|
||||||
|
VERSION = "2242f67744e2c8bb92362bbd1489319f"
|
@ -12776,6 +12776,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
-webkit-overflow-scrolling: touch;
|
-webkit-overflow-scrolling: touch;
|
||||||
|
background-color: #E5E5E5;
|
||||||
}
|
}
|
||||||
|
|
||||||
core-toolbar {
|
core-toolbar {
|
||||||
@ -12799,7 +12800,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
|
|
||||||
<home-assistant-api auth="{{auth}}" id="api"></home-assistant-api>
|
<home-assistant-api auth="{{auth}}" id="api"></home-assistant-api>
|
||||||
|
|
||||||
<core-header-panel layout="">
|
<core-header-panel unresolved="" fullbleed="">
|
||||||
|
|
||||||
<core-toolbar>
|
<core-toolbar>
|
||||||
<div flex="">
|
<div flex="">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user