main.lua

Mon, 04 Jan 2016 16:27:00 +0000

author
Matthew Wild <mwild1@gmail.com>
date
Mon, 04 Jan 2016 16:27:00 +0000
changeset 16
d35376a53644
parent 4
ae185012e7ba
child 25
f018f5a759b1
permissions
-rw-r--r--

main, geoip: Add GeoIP lookup support for watcher info

collectgarbage("setpause", 110);

assert(arg[1], "Please supply upstream URL");

local server = require "net.server_select";
local http = require "net.http";
local logger = require "util.logger";
local log = logger.init("main");
events = require "util.events".new();

require "clients";
require "geoip";

local function printf(source, level, fmt, ...) return print(source, level, fmt:format(...)); end
for _, level in ipairs{"debug", "info", "warn", "error"} do
	logger.add_level_sink(level, printf);
end

local request;

events.add_handler("have-clients", function ()
	request = http.request(arg[1], {success_on_chunk=true}, function (data, code, response)
		if code ~= 200 then
			log("error", "Error from upstream: %s", tostring(code));
			return;
		end
		local boundary = response.headers["content-type"]:match("; boundary=(.+)$").."\r\n";
		if #data > #boundary and data:sub(1, #boundary) ~= boundary then
			print(string.format(("%02X "):rep(6), data:byte(1,6)));
			error("bad format");
		end
		local img_header, header_len = data:sub(#boundary-1):match("(\r\n.-\r\n)\r\n()");
		if not img_header then return; end
		local img_size = tonumber(img_header:match("\r\nContent%-Length:%s*(%d+)\r\n"));
		local start_idx, end_idx = #boundary-2+header_len, #boundary-2+header_len+img_size-1;
		if end_idx + 2 > #data then return; end
		local img = data:sub(start_idx, end_idx);
		assert(#img == img_size, "incorrect image size: actual:"..#img.." vs expected: "..img_size.." data: "..#data)
		response.body = data:sub(end_idx+3);
		events.fire_event("image-changed", { image = img });
		if not response.partial then
			log("warn", "connection to upstream lost");
			events.fire_event("connection-lost");
		end
	end);
end);

events.add_handler("no-clients", function ()
	request.conn:close();
	request = nil;
end);

server.loop();

mercurial