|
1 collectgarbage("setpause", 110); |
|
2 |
|
3 assert(arg[1], "Please supply upstream URL"); |
|
4 |
|
5 local server = require "net.server_select"; |
|
6 local http = require "net.http"; |
|
7 local logger = require "util.logger"; |
|
8 events = require "util.events".new(); |
|
9 |
|
10 require "clients"; |
|
11 |
|
12 local function printf(source, level, fmt, ...) return print(source, level, fmt:format(...)); end |
|
13 for _, level in ipairs{"debug", "info", "warn", "error"} do |
|
14 logger.add_level_sink(level, printf); |
|
15 end |
|
16 |
|
17 local request; |
|
18 |
|
19 events.add_handler("have-clients", function () |
|
20 request = http.request(arg[1], {success_on_chunk=true}, function (data, code, response) |
|
21 local boundary = response.headers["content-type"]:match("; boundary=(.+)$").."\r\n"; |
|
22 if #data > #boundary and data:sub(1, #boundary) ~= boundary then |
|
23 print(string.format(("%02X "):rep(6), data:byte(1,6))); |
|
24 error("bad format"); |
|
25 end |
|
26 local img_header, header_len = data:sub(#boundary-1):match("(\r\n.-\r\n)\r\n()"); |
|
27 if not img_header then return; end |
|
28 local img_size = tonumber(img_header:match("\r\nContent%-Length:%s*(%d+)\r\n")); |
|
29 local start_idx, end_idx = #boundary-2+header_len, #boundary-2+header_len+img_size-1; |
|
30 if end_idx + 2 > #data then return; end |
|
31 local img = data:sub(start_idx, end_idx); |
|
32 assert(#img == img_size, "incorrect image size: actual:"..#img.." vs expected: "..img_size.." data: "..#data) |
|
33 response.body = data:sub(end_idx+3); |
|
34 events.fire_event("image-changed", { image = img }); |
|
35 end); |
|
36 end); |
|
37 |
|
38 events.add_handler("no-clients", function () |
|
39 request.conn:close(); |
|
40 end); |
|
41 |
|
42 server.loop(); |