11local fmt = string.format
22local str_lower = string.lower
3+ local insert = table.insert
4+ local concat = table.concat
35
46local _M = {
57}
3234-- write_response writes response body reader to sock in the HTTP/1.x server response format,
3335-- The connection is closed if send() fails or when returning a non-zero
3436function _M .send_response (sock , response , chunksize )
35- local bytes , err
3637 chunksize = chunksize or 65536
3738
3839 if not response then
@@ -44,29 +45,24 @@ function _M.send_response(sock, response, chunksize)
4445 return nil , " socket not initialized yet"
4546 end
4647
47- -- Status line
48- -- TODO: get HTTP version from request
49- local status = fmt (" HTTP/%d.%d %03d %s\r\n " , 1 , 1 , response .status , response .reason )
50- bytes , err = send (sock , status )
51- if not bytes then
52- return nil , " failed to send status line, err: " .. (err or " unknown" )
53- end
48+ -- Build status line + headers into a single buffer to minimize send() calls
49+ local buf = {
50+ fmt (" HTTP/1.1 %03d %s\r\n " , response .status , response .reason )
51+ }
5452
5553 -- Filter out hop-by-hop headeres
5654 for k , v in pairs (response .headers ) do
5755 if not HOP_BY_HOP_HEADERS [str_lower (k )] then
58- local header = fmt (" %s: %s\r\n " , k , v )
59- bytes , err = sock :send (header )
60- if not bytes then
61- return nil , " failed to send status line, err: " .. (err or " unknown" )
62- end
56+ insert (buf , k .. " : " .. v .. cr_lf )
6357 end
6458 end
6559
6660 -- End-of-header
67- bytes , err = send (sock , cr_lf )
61+ insert (buf , cr_lf )
62+
63+ local bytes , err = sock :send (concat (buf ))
6864 if not bytes then
69- return nil , " failed to send status line , err: " .. (err or " unknown" )
65+ return nil , " failed to send headers , err: " .. (err or " unknown" )
7066 end
7167
7268 -- Write body
0 commit comments