diff --git a/src/httpc.c b/src/httpc.c index 8d38851f400e74f8ea6ad9c5d94abf0064cb600c..be35b045893ca3a08388d95b2db48700f72c275f 100644 --- a/src/httpc.c +++ b/src/httpc.c @@ -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 { diff --git a/test/app-tap/http_client.test.lua b/test/app-tap/http_client.test.lua index b0fc8c093d1acf3e7e9caeac103d9e019e35abff..1d69e245a254a9867241a2ca4b5d51f6b3acaac8 100755 --- a/test/app-tap/http_client.test.lua +++ b/test/app-tap/http_client.test.lua @@ -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