+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