# HG changeset patch # User Kim Alvefur # Date 1468398352 -7200 # Node ID f82356adcd716a12eb3178ba6e395be506efa6cc # Parent cdabf81999031290db313081b21259eae9480397# Parent f67b7509ee2843fcf229300acd9e359eeb940044 Merge 0.10->trunk diff -r cdabf8199903 -r f82356adcd71 .luacheckrc --- a/.luacheckrc Sat Jul 09 22:33:04 2016 +0200 +++ b/.luacheckrc Wed Jul 13 10:25:52 2016 +0200 @@ -8,16 +8,18 @@ ignore = { "411/err", "421/err", "411/ok", "421/ok", "211/_ENV" } files["plugins/"] = { - ignore = { "122/module" }; + globals = { "module" }; } files["tests/"] = { - ignore = { - "113/assert_equal", - "113/assert_table", - "113/assert_function", - "113/assert_string", - "113/assert_boolean", - "113/assert_is", - "113/assert_is_not", + read_globals = { + "testlib_new_env", + "assert_equal", + "assert_table", + "assert_function", + "assert_string", + "assert_boolean", + "assert_is", + "assert_is_not", + "runtest", }; } diff -r cdabf8199903 -r f82356adcd71 net/dns.lua --- a/net/dns.lua Sat Jul 09 22:33:04 2016 +0200 +++ b/net/dns.lua Wed Jul 13 10:25:52 2016 +0200 @@ -1011,7 +1011,7 @@ function resolver.print(response) -- - - - - - - - - - - - - resolver.print - for s,s in pairs { 'id', 'qr', 'opcode', 'aa', 'tc', 'rd', 'ra', 'z', + for _, s in pairs { 'id', 'qr', 'opcode', 'aa', 'tc', 'rd', 'ra', 'z', 'rcode', 'qdcount', 'ancount', 'nscount', 'arcount' } do print( string.format('%-30s', 'header.'..s), response.header[s], hint(response.header, s) ); end @@ -1024,7 +1024,7 @@ local common = { name=1, type=1, class=1, ttl=1, rdlength=1, rdata=1 }; local tmp; - for s,s in pairs({'answer', 'authority', 'additional'}) do + for _, s in pairs({'answer', 'authority', 'additional'}) do for i,rr in pairs(response[s]) do for j,t in pairs({ 'name', 'type', 'class', 'ttl', 'rdlength' }) do tmp = string.format('%s[%i].%s', s, i, t); diff -r cdabf8199903 -r f82356adcd71 net/http/server.lua --- a/net/http/server.lua Sat Jul 09 22:33:04 2016 +0200 +++ b/net/http/server.lua Wed Jul 13 10:25:52 2016 +0200 @@ -13,10 +13,12 @@ local tostring = tostring; local cache = require "util.cache"; local codes = require "net.http.codes"; +local blocksize = require "socket".BLOCKSIZE or 2048; local _M = {}; local sessions = {}; +local incomplete = {}; local listener = {}; local hosts = {}; local default_host; @@ -140,17 +142,26 @@ open_response.finished = true; open_response:on_destroy(); end + incomplete[conn] = nil; sessions[conn] = nil; end function listener.ondetach(conn) sessions[conn] = nil; + incomplete[conn] = nil; end function listener.onincoming(conn, data) sessions[conn]:feed(data); end +function listener.ondrain(conn) + local response = incomplete[conn]; + if response and response._send_more then + response._send_more(); + end +end + local headerfix = setmetatable({}, { __index = function(t, k) local v = "\r\n"..k:gsub("_", "-"):gsub("%f[%w].", s_upper)..": "; @@ -190,6 +201,7 @@ persistent = persistent; conn = conn; send = _M.send_response; + send_file = _M.send_file; done = _M.finish_response; finish_cb = finish_cb; }; @@ -272,6 +284,36 @@ response.conn:write(t_concat(output)); response:done(); end +function _M.send_file(response, f) + if response.finished then return; end + local chunked = not response.headers.content_length; + if chunked then response.headers.transfer_encoding = "chunked"; end + incomplete[response.conn] = response; + response._send_more = function () + if response.finished then + incomplete[response.conn] = nil; + return; + end + local chunk = f:read(blocksize); + if chunk then + if chunked then + chunk = ("%x\r\n%s\r\n"):format(#chunk, chunk); + end + -- io.write("."); io.flush(); + response.conn:write(chunk); + else + if chunked then + response.conn:write("0\r\n\r\n"); + end + -- io.write("\n"); + if f.close then f:close(); end + incomplete[response.conn] = nil; + return response:done(); + end + end + response.conn:write(t_concat(prepare_header(response))); + return true; +end function _M.finish_response(response) if response.finished then return; end response.finished = true; diff -r cdabf8199903 -r f82356adcd71 plugins/mod_http_errors.lua --- a/plugins/mod_http_errors.lua Sat Jul 09 22:33:04 2016 +0200 +++ b/plugins/mod_http_errors.lua Wed Jul 13 10:25:52 2016 +0200 @@ -43,7 +43,8 @@

$message

$extra

-]]; + +]]; html = html:gsub("%s%s+", ""); local entities = { diff -r cdabf8199903 -r f82356adcd71 plugins/mod_http_files.lua --- a/plugins/mod_http_files.lua Sat Jul 09 22:33:04 2016 +0200 +++ b/plugins/mod_http_files.lua Wed Jul 13 10:25:52 2016 +0200 @@ -17,6 +17,8 @@ local path_sep = package.config:sub(1,1); local base_path = module:get_option_string("http_files_dir", module:get_option_string("http_path")); +local cache_size = module:get_option_number("http_files_cache_size", 128); +local cache_max_file_size = module:get_option_number("http_files_cache_max_file_size", 4096); local dir_indices = module:get_option("http_index_files", { "index.html", "index.htm" }); local directory_index = module:get_option_boolean("http_dir_listing"); @@ -81,7 +83,7 @@ return "/"..table.concat(out, "/"); end -local cache = setmetatable({}, { __mode = "kv" }); -- Let the garbage collector have it if it wants to. +local cache = require "util.cache".new(cache_size); function serve(opts) if type(opts) ~= "table" then -- assume path string @@ -109,7 +111,7 @@ local last_modified = os_date('!%a, %d %b %Y %H:%M:%S GMT', attr.modification); response_headers.last_modified = last_modified; - local etag = ("%02x-%x-%x-%x"):format(attr.dev or 0, attr.ino or 0, attr.size or 0, attr.modification or 0); + local etag = ('"%02x-%x-%x-%x"'):format(attr.dev or 0, attr.ino or 0, attr.size or 0, attr.modification or 0); response_headers.etag = etag; local if_none_match = request_headers.if_none_match @@ -119,7 +121,7 @@ return 304; end - local data = cache[orig_path]; + local data = cache:get(orig_path); if data and data.etag == etag then response_headers.content_type = data.content_type; data = data.data; @@ -147,18 +149,22 @@ else local f, err = open(full_path, "rb"); - if f then - data, err = f:read("*a"); - f:close(); - end - if not data then - module:log("debug", "Could not open or read %s. Error was %s", full_path, err); + if not f then + module:log("debug", "Could not open %s. Error was %s", full_path, err); return 403; end local ext = full_path:match("%.([^./]+)$"); local content_type = ext and mime_map[ext]; - cache[orig_path] = { data = data; content_type = content_type; etag = etag }; response_headers.content_type = content_type; + if attr.size > cache_max_file_size then + response_headers.content_length = attr.size; + module:log("debug", "%d > cache_max_file_size", attr.size); + return response:send_file(f); + else + data = f:read("*a"); + f:close(); + end + cache:set(orig_path, { data = data; content_type = content_type; etag = etag }); end return response:send(data); diff -r cdabf8199903 -r f82356adcd71 prosodyctl --- a/prosodyctl Sat Jul 09 22:33:04 2016 +0200 +++ b/prosodyctl Wed Jul 13 10:25:52 2016 +0200 @@ -717,7 +717,7 @@ else show_message("Please provide details to include in the certificate config file."); show_message("Leave the field empty to use the default value or '.' to exclude the field.") - for i, k in ipairs(openssl._DN_order) do + for _, k in ipairs(openssl._DN_order) do local v = conf.distinguished_name[k]; if v then local nv; diff -r cdabf8199903 -r f82356adcd71 tests/test.lua --- a/tests/test.lua Sat Jul 09 22:33:04 2016 +0200 +++ b/tests/test.lua Wed Jul 13 10:25:52 2016 +0200 @@ -28,6 +28,7 @@ dotest "util.random" dotest "util.xml" dotest "util.xmppstream" + dotest "net.http.parser" dosingletest("test_sasl.lua", "latin1toutf8"); dosingletest("test_utf8.lua", "valid"); diff -r cdabf8199903 -r f82356adcd71 tests/test_net_http_parser.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test_net_http_parser.lua Wed Jul 13 10:25:52 2016 +0200 @@ -0,0 +1,47 @@ +local httpstreams = { [[ +GET / HTTP/1.1 +Host: example.com + +]], [[ +HTTP/1.1 200 OK +Content-Length: 0 + +]], [[ +HTTP/1.1 200 OK +Content-Length: 7 + +Hello +HTTP/1.1 200 OK +Transfer-Encoding: chunked + +1 +H +1 +e +2 +ll +1 +o +0 + + +]] +} + +function new(new) + + for _, stream in ipairs(httpstreams) do + local success; + local function success_cb(packet) + success = true; + end + stream = stream:gsub("\n", "\r\n"); + local parser = new(success_cb, error, stream:sub(1,4) == "HTTP" and "client" or "server") + for chunk in stream:gmatch("..?.?") do + parser:feed(chunk); + end + + assert_is(success); + end + +end diff -r cdabf8199903 -r f82356adcd71 tests/test_util_cache.lua --- a/tests/test_util_cache.lua Sat Jul 09 22:33:04 2016 +0200 +++ b/tests/test_util_cache.lua Wed Jul 13 10:25:52 2016 +0200 @@ -196,12 +196,12 @@ assert_equal(i, 4); local evicted_key, evicted_value; - local c = new(3, function (_key, _value) + local c2 = new(3, function (_key, _value) evicted_key, evicted_value = _key, _value; end); local function set(k, v, should_evict_key, should_evict_value) evicted_key, evicted_value = nil, nil; - c:set(k, v); + c2:set(k, v); assert_equal(evicted_key, should_evict_key); assert_equal(evicted_value, should_evict_value); end @@ -219,7 +219,7 @@ local evicted_key, evicted_value; - local c3 = new(1, function (_key, _value, c3) + local c3 = new(1, function (_key, _value) evicted_key, evicted_value = _key, _value; if _key == "a" then -- Sanity check for what we're evicting diff -r cdabf8199903 -r f82356adcd71 util/ip.lua --- a/util/ip.lua Sat Jul 09 22:33:04 2016 +0200 +++ b/util/ip.lua Wed Jul 13 10:25:52 2016 +0200 @@ -51,15 +51,15 @@ if not ip:match(":$") then fields[#fields] = nil; end for i, field in ipairs(fields) do if field:len() == 0 and i ~= 1 and i ~= #fields then - for i = 1, 16 * (9 - #fields) do + for _ = 1, 16 * (9 - #fields) do result = result .. "0"; end else - for i = 1, 4 - field:len() do + for _ = 1, 4 - field:len() do result = result .. "0000"; end - for i = 1, field:len() do - result = result .. hex2bits[field:sub(i,i)]; + for j = 1, field:len() do + result = result .. hex2bits[field:sub(j, j)]; end end end diff -r cdabf8199903 -r f82356adcd71 util/openssl.lua --- a/util/openssl.lua Sat Jul 09 22:33:04 2016 +0200 +++ b/util/openssl.lua Wed Jul 13 10:25:52 2016 +0200 @@ -70,7 +70,7 @@ end end elseif k == "distinguished_name" then - for i, k in ipairs(t[1] and t or DN_order) do + for _, k in ipairs(t[1] and t or DN_order) do local v = t[k]; if v then s = s .. ("%s = %s\n"):format(k, v);