Comparison

net/http/server.lua @ 7489:d32406f27efd

net.http.server: Add response method for reading response body from a file handle
author Kim Alvefur <zash@zash.se>
date Mon, 11 Jul 2016 11:52:43 +0200
parent 7084:fdbe9ccac17d
child 7541:1d3f9da189b5
comparison
equal deleted inserted replaced
7487:88a0a947e58c 7489:d32406f27efd
11 local xpcall = xpcall; 11 local xpcall = xpcall;
12 local traceback = debug.traceback; 12 local traceback = debug.traceback;
13 local tostring = tostring; 13 local tostring = tostring;
14 local cache = require "util.cache"; 14 local cache = require "util.cache";
15 local codes = require "net.http.codes"; 15 local codes = require "net.http.codes";
16 local blocksize = require "socket".BLOCKSIZE or 2048;
16 17
17 local _M = {}; 18 local _M = {};
18 19
19 local sessions = {}; 20 local sessions = {};
21 local incomplete = {};
20 local listener = {}; 22 local listener = {};
21 local hosts = {}; 23 local hosts = {};
22 local default_host; 24 local default_host;
23 25
24 local function is_wildcard_event(event) 26 local function is_wildcard_event(event)
138 local open_response = conn._http_open_response; 140 local open_response = conn._http_open_response;
139 if open_response and open_response.on_destroy then 141 if open_response and open_response.on_destroy then
140 open_response.finished = true; 142 open_response.finished = true;
141 open_response:on_destroy(); 143 open_response:on_destroy();
142 end 144 end
145 incomplete[conn] = nil;
143 sessions[conn] = nil; 146 sessions[conn] = nil;
144 end 147 end
145 148
146 function listener.ondetach(conn) 149 function listener.ondetach(conn)
147 sessions[conn] = nil; 150 sessions[conn] = nil;
151 incomplete[conn] = nil;
148 end 152 end
149 153
150 function listener.onincoming(conn, data) 154 function listener.onincoming(conn, data)
151 sessions[conn]:feed(data); 155 sessions[conn]:feed(data);
156 end
157
158 function listener.ondrain(conn)
159 local response = incomplete[conn];
160 if response and response._send_more then
161 response._send_more();
162 end
152 end 163 end
153 164
154 local headerfix = setmetatable({}, { 165 local headerfix = setmetatable({}, {
155 __index = function(t, k) 166 __index = function(t, k)
156 local v = "\r\n"..k:gsub("_", "-"):gsub("%f[%w].", s_upper)..": "; 167 local v = "\r\n"..k:gsub("_", "-"):gsub("%f[%w].", s_upper)..": ";
188 status_code = 200; 199 status_code = 200;
189 headers = { date = date_header, connection = response_conn_header }; 200 headers = { date = date_header, connection = response_conn_header };
190 persistent = persistent; 201 persistent = persistent;
191 conn = conn; 202 conn = conn;
192 send = _M.send_response; 203 send = _M.send_response;
204 send_file = _M.send_file;
193 done = _M.finish_response; 205 done = _M.finish_response;
194 finish_cb = finish_cb; 206 finish_cb = finish_cb;
195 }; 207 };
196 conn._http_open_response = response; 208 conn._http_open_response = response;
197 209
270 local output = prepare_header(response); 282 local output = prepare_header(response);
271 t_insert(output, body); 283 t_insert(output, body);
272 response.conn:write(t_concat(output)); 284 response.conn:write(t_concat(output));
273 response:done(); 285 response:done();
274 end 286 end
287 function _M.send_file(response, f)
288 if response.finished then return; end
289 local chunked = not response.headers.content_length;
290 if chunked then response.headers.transfer_encoding = "chunked"; end
291 incomplete[response.conn] = response;
292 response._send_more = function ()
293 if response.finished then
294 incomplete[response.conn] = nil;
295 return;
296 end
297 local chunk = f:read(blocksize);
298 if chunk then
299 if chunked then
300 chunk = ("%x\r\n%s\r\n"):format(#chunk, chunk);
301 end
302 -- io.write("."); io.flush();
303 response.conn:write(chunk);
304 else
305 if chunked then
306 response.conn:write("0\r\n\r\n");
307 end
308 -- io.write("\n");
309 if f.close then f:close(); end
310 incomplete[response.conn] = nil;
311 return response:done();
312 end
313 end
314 response.conn:write(t_concat(prepare_header(response)));
315 return true;
316 end
275 function _M.finish_response(response) 317 function _M.finish_response(response)
276 if response.finished then return; end 318 if response.finished then return; end
277 response.finished = true; 319 response.finished = true;
278 response.conn._http_open_response = nil; 320 response.conn._http_open_response = nil;
279 if response.on_destroy then 321 if response.on_destroy then