Added gzip and better caching

This commit is contained in:
Paulus Schoutsen 2014-10-26 18:10:01 -07:00
parent 506496743d
commit d2a4d67cb0
4 changed files with 73 additions and 39 deletions

View File

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

View File

@ -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", ctype = self.guess_type(path)
self.date_time_string(time.time()+3600)) self.send_header("Content-Type", ctype)
# Add cache if not development
if not self.server.development:
# 1 year in seconds
cache_time = 365 * 86400
self.send_header(
"Cache-Control", "public, max-age={}".format(cache_time))
self.send_header(
"Expires", self.date_time_string(time.time()+cache_time))
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:
fs = os.fstat(inp.fileno())
self.send_header("Content-Length", str(fs[6]))
self.end_headers() self.end_headers()
with open(path, 'rb') as inp: if do_gzip:
data = inp.read(1024) self.wfile.write(gzip_data)
while data: else:
self.wfile.write(data) self.copyfile(inp, self.wfile)
data = inp.read(1024) except IOError:
else:
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:

View File

@ -0,0 +1,2 @@
""" DO NOT MODIFY. Auto-generated by build_polymer script """
VERSION = "2242f67744e2c8bb92362bbd1489319f"

View File

@ -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="">