Skip to content
Snippets Groups Projects
Commit 12bab610 authored by Roman Tsisyk's avatar Roman Tsisyk
Browse files

curl: fix POST request with empty body

CURLOPT_POST option without explicitly set CURLOPT_POSTFIELDS caused
libcurl to use some internal implementation of CURLOPT_READFUNCTION,
which reads body from stdin by default.

Provided test case only covers argument handling because there is no
repetable way to check reads from stdin from our test suite.

Closes #2530
parent f728e8ee
No related branches found
No related tags found
No related merge requests found
......@@ -327,13 +327,19 @@ httpc_request_new(struct httpc_env *env, const char *method,
curl_easy_setopt(req->easy, CURLOPT_HTTPGET, 1L);
} else if (strcmp(method, "HEAD") == 0) {
curl_easy_setopt(req->easy, CURLOPT_NOBODY, 1L);
} else if (strcmp(method, "POST") == 0) {
} else if (strcmp(method, "POST") == 0 ||
strcmp(method, "PUT") == 0 ||
strcmp(method, "PATCH")) {
/*
* Set CURLOPT_POSTFIELDS to "" and CURLOPT_POSTFIELDSSIZE 0
* to avoid the read callback in any cases even if user
* forgot to call httpc_set_body() for POST request.
* @see https://curl.haxx.se/libcurl/c/CURLOPT_POSTFIELDS.html
*/
curl_easy_setopt(req->easy, CURLOPT_POST, 1L);
if (httpc_set_header(req, "Accept: */*") < 0)
goto error;
} else if (strcmp(method, "PUT") == 0 || strcmp(method, "PATCH") == 0) {
curl_easy_setopt(req->easy, CURLOPT_POSTFIELDS, "");
curl_easy_setopt(req->easy, CURLOPT_POSTFIELDSIZE, 0);
curl_easy_setopt(req->easy, CURLOPT_CUSTOMREQUEST, method);
curl_easy_setopt(req->easy, CURLOPT_POST, 1L);
if (httpc_set_header(req, "Accept: */*") < 0)
goto error;
} else {
......
......@@ -78,7 +78,7 @@ test:test("cancel and timeout", function(test)
end)
test:test("basic http post/get", function(test)
test:plan(16)
test:plan(19)
local http = client.new()
test:ok(http ~= nil, "client is created")
......@@ -89,7 +89,7 @@ test:test("basic http post/get", function(test)
local responses = {}
local data = {a = 'b'}
headers['Content-Type'] = 'application/json'
local fibers = 6
local fibers = 7
local ch = fiber.channel(fibers)
local _
fiber.create(function()
......@@ -104,6 +104,10 @@ test:test("basic http post/get", function(test)
responses.good_post = http:post(URL, json_body, {headers = headers})
ch:put(1)
end)
fiber.create(function()
responses.empty_post = http:post(URL, nil, {headers = headers})
ch:put(1)
end)
fiber.create(function()
responses.good_put = http:put(URL, json_body, {headers = headers})
ch:put(1)
......@@ -133,6 +137,12 @@ test:test("basic http post/get", function(test)
test:is(r.status, 500, "GET: absent method http code page exists")
test:is(r.body, "No such method", "GET: absent method right body")
r = responses.empty_post
test:is(r.status, 200, "POST: good status")
test:ok(r.headers['header1'] == headers.header1 and
r.headers['header2'] == headers.header2, "POST: good headers")
test:isnil(r.body, "POST: empty body")
r = responses.good_post
test:is(r.status, 200, "POST: good status")
test:ok(r.headers['header1'] == headers.header1 and
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment