Skip to content

Commit

Permalink
bugfix: read the request body from the temporary file if it was cache…
Browse files Browse the repository at this point in the history
…d. (#1863)
  • Loading branch information
membphis authored Jul 29, 2020
1 parent 3947f06 commit 20207c8
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 5 deletions.
8 changes: 6 additions & 2 deletions apisix/admin/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ local require = require
local reload_event = "/apisix/admin/plugins/reload"
local ipairs = ipairs
local events
local MAX_REQ_BODY = 1024 * 1024 * 1.5 -- 1.5 MiB


local viewer_methods = {
Expand Down Expand Up @@ -117,8 +118,11 @@ local function run()
core.response.exit(404)
end

ngx.req.read_body()
local req_body = ngx.req.get_body_data()
local req_body, err = core.request.get_body(MAX_REQ_BODY)
if err then
core.log.error("failed to read request body: ", err)
core.response.exit(400, {error_msg = "invalid request body: " .. err})
end

if req_body then
local data, err = core.json.decode(req_body)
Expand Down
53 changes: 51 additions & 2 deletions apisix/core/request.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,21 @@
-- See the License for the specific language governing permissions and
-- limitations under the License.
--

local lfs = require("lfs")
local ngx = ngx
local get_headers = ngx.req.get_headers
local tonumber = tonumber
local error = error
local type = type
local str_fmt = string.format
local io_open = io.open
local req_read_body = ngx.req.read_body
local req_get_body_data = ngx.req.get_body_data
local req_get_body_file = ngx.req.get_body_file


local _M = {version = 0.1}
local _M = {}


local function _headers(ctx)
Expand Down Expand Up @@ -94,7 +101,49 @@ function _M.get_remote_client_port(ctx)
ctx = ngx.ctx.api_ctx
end
return tonumber(ctx.var.remote_port)
end
end


local function get_file(file_name)
local f, err = io_open(file_name, 'r')
if not f then
return nil, err
end

local req_body = f:read("*all")
f:close()
return req_body
end


function _M.get_body(max_size)
req_read_body()

local req_body = req_get_body_data()
if req_body then
return req_body
end

local file_name = req_get_body_file()
if not file_name then
return nil
end

if max_size then
local size, err = lfs.attributes (file_name, "size")
if not size then
return nil, err
end

if size > max_size then
return nil, "request size " .. size .. " is greater than the "
.. "maximum size " .. max_size .. " allowed"
end
end

local req_body, err = get_file(file_name)
return req_body, err
end


return _M
75 changes: 74 additions & 1 deletion t/admin/routes.t
Original file line number Diff line number Diff line change
Expand Up @@ -1882,6 +1882,79 @@ GET /t
}
}
--- request
GET /t
GET /t
--- response_headers
Content-Type: application/json



=== TEST 52: set route with size 36k (temporary file to store request body)
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test

local core = require("apisix.core")
local s = string.rep("a", 1024 * 35)
local req_body = [[{
"upstream": {
"nodes": {
"]] .. s .. [[": 1
},
"type": "roundrobin"
},
"uri": "/index.html"
}]]

local code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT, req_body)

if code >= 300 then
ngx.status = code
end

ngx.say("req size: ", #req_body)
ngx.say(body)
}
}
--- request
GET /t
--- response_body
req size: 36066
passed
--- error_log
a client request body is buffered to a temporary file



=== TEST 53: route size more than 1.5 MiB
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local s = string.rep( "a", 1024 * 1024 * 1.6 )
local code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT,
[[{
"upstream": {
"nodes": {
"127.0.0.1:8080": 1
},
"type": "roundrobin"
},
"desc": "]] .. s .. [[",
"uri": "/index.html"
}]]
)

ngx.status = code
ngx.print(body)
}
}
--- request
GET /t
--- error_code: 400
--- response_body
{"error_msg":"invalid request body: request size 1678025 is greater than the maximum size 1572864 allowed"}
--- error_log
failed to read request body: request size 1678025 is greater than the maximum size 1572864 allowed

0 comments on commit 20207c8

Please sign in to comment.