-
Notifications
You must be signed in to change notification settings - Fork 170
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support chunked requests when talking to proxy servers with request b…
…uffering disabled
- Loading branch information
Showing
7 changed files
with
1,439 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
local httpc = require "resty.resolver.http" | ||
|
||
local _M = { | ||
} | ||
|
||
local cr_lf = "\r\n" | ||
|
||
-- chunked_reader return a body reader that translates the data read from | ||
-- lua-resty-http client_body_reader to HTTP "chunked" format before returning it | ||
-- | ||
-- The chunked reader return nil when the final 0-length chunk is read | ||
local function chunked_reader(sock, chunksize) | ||
chunksize = chunksize or 65536 | ||
local eof = false | ||
local reader = httpc:get_client_body_reader(chunksize, sock) | ||
if not reader then | ||
return nil | ||
end | ||
|
||
return function() | ||
if eof then | ||
return nil | ||
end | ||
|
||
local buffer, err = reader() | ||
if err then | ||
return nil, err | ||
end | ||
if buffer then | ||
local chunk = string.format("%x\r\n", #buffer) .. buffer .. cr_lf | ||
return chunk | ||
else | ||
eof = true | ||
return "0\r\n\r\n" | ||
end | ||
end | ||
end | ||
|
||
function _M.get_client_body_reader(sock, chunksize, is_chunked) | ||
if is_chunked then | ||
return chunked_reader(sock, chunksize) | ||
else | ||
return httpc:get_client_body_reader(chunksize, sock) | ||
end | ||
end | ||
|
||
return _M |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
local _M = { | ||
} | ||
|
||
local cr_lf = "\r\n" | ||
|
||
local function send(socket, data) | ||
if not data or data == '' then | ||
ngx.log(ngx.DEBUG, 'skipping sending nil') | ||
return | ||
end | ||
|
||
return socket:send(data) | ||
end | ||
|
||
-- write_response writes response body reader to sock in the HTTP/1.x server response format, | ||
-- The connection is closed if send() fails or when returning a non-zero | ||
function _M.send_response(sock, response, chunksize) | ||
local bytes, err | ||
chunksize = chunksize or 65536 | ||
|
||
if not response then | ||
ngx.log(ngx.ERR, "no response provided") | ||
return | ||
end | ||
|
||
if not sock then | ||
return nil, "socket not initialized yet" | ||
end | ||
|
||
-- Status line | ||
local status = "HTTP/1.1 " .. response.status .. " " .. response.reason .. cr_lf | ||
bytes, err = send(sock, status) | ||
if not bytes then | ||
return nil, "failed to send status line, err: " .. (err or "unknown") | ||
end | ||
|
||
-- Write body | ||
local reader = response.body_reader | ||
repeat | ||
local chunk, read_err | ||
|
||
chunk, read_err = reader(chunksize) | ||
if read_err then | ||
return nil, "failed to read response body, err: " .. (err or "unknown") | ||
end | ||
|
||
if chunk then | ||
bytes, err = send(sock, chunk) | ||
if not bytes then | ||
return nil, "failed to send response body, err: " .. (err or "unknown") | ||
end | ||
end | ||
until not chunk | ||
|
||
return true, nil | ||
end | ||
|
||
return _M |
Oops, something went wrong.