mod_strict_https/mod_strict_https.lua
changeset 5415 b3158647cb36
parent 863 efa9c1676d1f
child 5419 f8797e3284ff
equal deleted inserted replaced
5414:644b2f2b9b52 5415:b3158647cb36
     1 -- HTTP Strict Transport Security
     1 -- HTTP Strict Transport Security
     2 -- https://tools.ietf.org/html/rfc6797
     2 -- https://www.rfc-editor.org/info/rfc6797
     3 
     3 
     4 module:set_global();
     4 module:set_global();
     5 
     5 
     6 local http_server = require "net.http.server";
     6 local http_server = require "net.http.server";
     7 
     7 
     8 local hsts_header = module:get_option_string("hsts_header", "max-age=31556952"); -- This means "Don't even try to access without HTTPS for a year"
     8 local hsts_header = module:get_option_string("hsts_header", "max-age=31556952"); -- This means "Don't even try to access without HTTPS for a year"
     9 
     9 
    10 local _old_send_response;
    10 module:wrap_object_event(http_server._events, false, function(handlers, event_name, event_data)
    11 local _old_fire_event;
    11 	local request, response = event_data.request, event_data.response;
    12 
    12 	if request and response then
    13 local modules = {};
    13 		if request.secure then
    14 
    14 			response.headers.strict_transport_security = hsts_header;
    15 function module.load()
    15 		else
    16 	_old_send_response = http_server.send_response;
    16 			-- This won't get the port number right
    17 	function http_server.send_response(response, body)
    17 			response.headers.location = "https://" .. request.host .. request.path .. (request.query and "?" .. request.query or "");
    18 		response.headers.strict_transport_security = hsts_header;
       
    19 		return _old_send_response(response, body);
       
    20 	end
       
    21 
       
    22 	_old_fire_event = http_server._events.fire_event;
       
    23 	function http_server._events.fire_event(event, payload)
       
    24 		local request = payload.request;
       
    25 		local host = event:match("^[A-Z]+ ([^/]+)");
       
    26 		local module = modules[host];
       
    27 		if module and not request.secure then
       
    28 			payload.response.headers.location = module:http_url(request.path);
       
    29 			return 301;
    18 			return 301;
    30 		end
    19 		end
    31 		return _old_fire_event(event, payload);
       
    32 	end
    20 	end
    33 end
    21 	return handlers(event_name, event_data);
    34 function module.unload()
    22 end);
    35 	http_server.send_response = _old_send_response;
       
    36 	http_server._events.fire_event = _old_fire_event;
       
    37 end
       
    38 function module.add_host(module)
       
    39 	local http_host = module:get_option_string("http_host", module.host);
       
    40 	modules[http_host] = module;
       
    41 	function module.unload()
       
    42 		modules[http_host] = nil;
       
    43 	end
       
    44 end