From 7404d97b33f8e0434cdb798fe6224adeba3844d4 Mon Sep 17 00:00:00 2001 From: Ri Shen Chen Date: Thu, 10 Jul 2025 14:51:52 +0800 Subject: [PATCH] fix: http: send_request: Amend EXPECTING_BODY nil Update the behavior of the HTTP library to handle cases where the request body is nil for methods that expect a body (e.g., POST, PUT, PATCH). Introduce an error message for such cases and adjust the corresponding tests to align with the new behavior. References: * https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods/POST * https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods/PUT * https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods/PATCH [sparschauer: extended commit description, wrapped a too long line, updated t/15-instance-reuse.t as well] Co-authored-by: Sebastian Parschauer --- lib/resty/http.lua | 3 ++- t/06-simpleinterface.t | 37 +++++++++++++++++++++++++++++++++++-- t/15-instance-reuse.t | 6 +++--- 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/lib/resty/http.lua b/lib/resty/http.lua index c31bb9a0..6c6ad429 100644 --- a/lib/resty/http.lua +++ b/lib/resty/http.lua @@ -706,7 +706,8 @@ function _M.send_request(self, params) headers["Content-Length"] = length elseif body == nil and EXPECTING_BODY[str_upper(params.method)] then - headers["Content-Length"] = 0 + return nil, "Request body is nil but " .. str_upper(params.method) + .. " method expects a body. Use an empty string \"\" if you want to send an empty body." elseif body ~= nil then headers["Content-Length"] = #tostring(body) diff --git a/t/06-simpleinterface.t b/t/06-simpleinterface.t index c828c2d5..9647a1f4 100644 --- a/t/06-simpleinterface.t +++ b/t/06-simpleinterface.t @@ -269,7 +269,7 @@ nil closed lua tcp socket read timed out -=== TEST 7: Content-Length is set on POST/PUT/PATCH requests when body is absent +=== TEST 7: Content-Length is set on POST/PUT/PATCH requests when body is explicitly empty --- http_config eval: $::HttpConfig --- config location = /a { @@ -277,7 +277,7 @@ lua tcp socket read timed out for i, method in ipairs({ "POST", "PUT", "PATCH" }) do local http = require "resty.http" local httpc = http.new() - local res, err = httpc:request_uri("http://127.0.0.1:"..ngx.var.server_port.."/b", { method = method }) + local res, err = httpc:request_uri("http://127.0.0.1:"..ngx.var.server_port.."/b", { method = method, body = "" }) if not res then ngx.log(ngx.ERR, err) @@ -336,3 +336,36 @@ Content-Length: nil [error] [warn] + +=== TEST 9: Error when body is nil for POST/PUT/PATCH requests +--- http_config eval: $::HttpConfig +--- config + location = /a { + content_by_lua ' + for i, method in ipairs({ "POST", "PUT", "PATCH" }) do + local http = require "resty.http" + local httpc = http.new() + local res, err = httpc:request_uri("http://127.0.0.1:"..ngx.var.server_port.."/b", { method = method }) + + if not res then + ngx.say(method, ": ", err) + else + ngx.say(method, ": success") + end + end + '; + } + location = /b { + content_by_lua ' + ngx.say("Should not reach here") + '; + } +--- request +GET /a +--- response_body +POST: Request body is nil but POST method expects a body. Use an empty string "" if you want to send an empty body. +PUT: Request body is nil but PUT method expects a body. Use an empty string "" if you want to send an empty body. +PATCH: Request body is nil but PATCH method expects a body. Use an empty string "" if you want to send an empty body. +--- no_error_log +[error] +[warn] diff --git a/t/15-instance-reuse.t b/t/15-instance-reuse.t index 414e2cb2..5c0e41ba 100644 --- a/t/15-instance-reuse.t +++ b/t/15-instance-reuse.t @@ -101,13 +101,13 @@ location /a { } local res, err = httpc:request(params) - assert(res, "request should return positvely") + assert(res, "request should return positively") assert(not params.headers, "params table should not be modified") local res, err = httpc:request_uri("http://127.0.0.1:"..ngx.var.server_port, params) - assert(res, "request_uri should return positvely") + assert(res, "request_uri should return positively") assert(not params.headers, "params table should not be modified") @@ -116,7 +116,7 @@ location /a { "connect should return positively") local pipeline_params = { - { path = "/b", method = "POST" }, + { path = "/b", method = "POST", body = "" }, { path = "/b", method = "HEAD" }, }