@@ -3,6 +3,11 @@ local str_lower = string.lower
33local insert = table.insert
44local concat = table.concat
55
6+ local ngx = ngx
7+ local ngx_print = ngx .print
8+ local ngx_flush = ngx .flush
9+ local ngx_header = ngx .header
10+
611local _M = {
712}
813
@@ -22,13 +27,31 @@ local HOP_BY_HOP_HEADERS = {
2227 -- with this (may send chunked for example).
2328}
2429
25- local function send (socket , data )
26- if not data or data == ' ' then
27- ngx .log (ngx .DEBUG , ' skipping sending nil' )
28- return
30+ -- forward_body reads chunks from a body_reader and passes them to the callback
31+ -- function cb.
32+ -- cb(chunk) should return a true on success, or nil/false, err on failure.
33+ local function forward_body (reader , cb , chunksize )
34+ if not reader then
35+ return nil , " no body reader"
36+ end
37+
38+ repeat
39+ local chunk , read_err = reader (chunksize )
40+
41+ if read_err then
42+ return nil , " failed to read response body: " .. read_err
2943 end
3044
31- return socket :send (data )
45+ if chunk then
46+ local ok , send_err = cb (chunk )
47+
48+ if not ok then
49+ return nil , " failed to send response body: " .. (send_err or " unknown" )
50+ end
51+ end
52+ until not chunk
53+
54+ return true
3255end
3356
3457-- write_response writes response body reader to sock in the HTTP/1.x server response format,
@@ -65,25 +88,40 @@ function _M.send_response(sock, response, chunksize)
6588 return nil , " failed to send headers, err: " .. (err or " unknown" )
6689 end
6790
68- -- Write body
69- local reader = response . body_reader
70- repeat
71- local chunk , read_err
91+ return forward_body ( response . body_reader , function ( chunk )
92+ return sock : send ( chunk )
93+ end , chunksize )
94+ end
7295
73- chunk , read_err = reader (chunksize )
74- if read_err then
75- return nil , " failed to read response body, err: " .. (err or " unknown" )
76- end
96+ local function ngx_send_and_flush (chunk )
97+ local ok , err = ngx_print (chunk )
98+ if not ok then
99+ return nil , " output response failed: " .. (err or " " )
100+ end
77101
78- if chunk then
79- bytes , err = send (sock , chunk )
80- if not bytes then
81- return nil , " failed to send response body, err: " .. (err or " unknown" )
82- end
102+ ok , err = ngx_flush (true )
103+ if not ok then
104+ ngx .log (ngx .WARN , " flush response failed: " , err )
105+ end
106+
107+ return true
108+ end
109+
110+ function _M .proxy_response (res , chunksize )
111+ if not res then
112+ ngx .log (ngx .ERR , " no response provided" )
113+ return
114+ end
115+
116+ ngx .status = res .status
117+
118+ for k , v in pairs (res .headers ) do
119+ if not HOP_BY_HOP_HEADERS [str_lower (k )] then
120+ ngx_header [k ] = v
83121 end
84- until not chunk
122+ end
85123
86- return true , nil
124+ return forward_body ( res . body_reader , ngx_send_and_flush , chunksize )
87125end
88126
89127return _M
0 commit comments