add DELETE, PATCH and OPTIONS http methods #11

This commit is contained in:
2019-07-07 13:06:04 +07:00
parent 36518720d2
commit f9507e73a2
3 changed files with 133 additions and 1 deletions

View File

@@ -43,7 +43,10 @@ namespace curly_hpp
PUT,
GET,
HEAD,
POST
POST,
PATCH,
DELETE,
OPTIONS
};
class upload_handler {

View File

@@ -311,6 +311,22 @@ namespace curly_hpp
curl_easy_setopt(curlh_.get(), CURLOPT_POSTFIELDSIZE_LARGE,
static_cast<curl_off_t>(breq_.uploader()->size()));
break;
case http_method::PATCH:
curl_easy_setopt(curlh_.get(), CURLOPT_CUSTOMREQUEST, "PATCH");
curl_easy_setopt(curlh_.get(), CURLOPT_UPLOAD, 1l);
curl_easy_setopt(curlh_.get(), CURLOPT_INFILESIZE_LARGE,
static_cast<curl_off_t>(breq_.uploader()->size()));
break;
case http_method::DELETE:
curl_easy_setopt(curlh_.get(), CURLOPT_CUSTOMREQUEST, "DELETE");
curl_easy_setopt(curlh_.get(), CURLOPT_POST, 1l);
curl_easy_setopt(curlh_.get(), CURLOPT_POSTFIELDSIZE_LARGE,
static_cast<curl_off_t>(breq_.uploader()->size()));
break;
case http_method::OPTIONS:
curl_easy_setopt(curlh_.get(), CURLOPT_CUSTOMREQUEST, "OPTIONS");
curl_easy_setopt(curlh_.get(), CURLOPT_NOBODY, 1l);
break;
default:
throw exception("curly_hpp: unexpected request method");
}

View File

@@ -205,6 +205,18 @@ TEST_CASE("curly") {
.method(net::http_method::POST)
.send();
REQUIRE(req3.take().http_code() == 405u);
auto req4 = net::request_builder()
.url("https://httpbin.org/put")
.method(net::http_method::PATCH)
.send();
REQUIRE(req4.take().http_code() == 405u);
auto req5 = net::request_builder()
.url("https://httpbin.org/put")
.method(net::http_method::DELETE)
.send();
REQUIRE(req5.take().http_code() == 405u);
}
{
auto req0 = net::request_builder()
@@ -230,6 +242,18 @@ TEST_CASE("curly") {
.method(net::http_method::POST)
.send();
REQUIRE(req3.take().http_code() == 405u);
auto req4 = net::request_builder()
.url("https://httpbin.org/get")
.method(net::http_method::PATCH)
.send();
REQUIRE(req4.take().http_code() == 405u);
auto req5 = net::request_builder()
.url("https://httpbin.org/get")
.method(net::http_method::DELETE)
.send();
REQUIRE(req5.take().http_code() == 405u);
}
{
auto req0 = net::request_builder()
@@ -255,6 +279,33 @@ TEST_CASE("curly") {
.method(net::http_method::POST)
.send();
REQUIRE(req3.take().http_code() == 200u);
auto req4 = net::request_builder()
.url("https://httpbin.org/post")
.method(net::http_method::PATCH)
.send();
REQUIRE(req4.take().http_code() == 405u);
auto req5 = net::request_builder()
.url("https://httpbin.org/post")
.method(net::http_method::DELETE)
.send();
REQUIRE(req5.take().http_code() == 405u);
}
{
auto req1 = net::request_builder()
.url("https://httpbin.org/put")
.method(net::http_method::OPTIONS)
.send();
const auto allow1 = req1.take().headers.at("Allow");
REQUIRE((allow1 == "PUT, OPTIONS" || allow1 == "OPTIONS, PUT"));
auto req2 = net::request_builder()
.url("https://httpbin.org/post")
.method(net::http_method::OPTIONS)
.send();
const auto allow2 = req2.take().headers.at("Allow");
REQUIRE((allow2 == "POST, OPTIONS" || allow2 == "OPTIONS, POST"));
}
}
@@ -287,6 +338,20 @@ TEST_CASE("curly") {
.send();
REQUIRE(req.take().http_code() == 203u);
}
{
auto req = net::request_builder()
.url("https://httpbin.org/status/203")
.method(net::http_method::PATCH)
.send();
REQUIRE(req.take().http_code() == 203u);
}
{
auto req = net::request_builder()
.url("https://httpbin.org/status/203")
.method(net::http_method::DELETE)
.send();
REQUIRE(req.take().http_code() == 203u);
}
}
SECTION("request_inspection") {
@@ -368,6 +433,18 @@ TEST_CASE("curly") {
}
SECTION("binary") {
{
auto resp = net::request_builder()
.url("https://httpbin.org/image/png")
.method(net::http_method::HEAD)
.send().take();
REQUIRE(resp.http_code() == 200u);
REQUIRE(resp.headers.count("Content-Type"));
REQUIRE(resp.headers.count("Content-Length"));
REQUIRE(resp.headers.at("Content-Type") == "image/png");
REQUIRE(resp.headers.at("Content-Length") == std::to_string(untests::png_data_length));
REQUIRE_FALSE(resp.content.size());
}
{
auto resp = net::request_builder()
.url("https://httpbin.org/image/png")
@@ -375,12 +452,26 @@ TEST_CASE("curly") {
.send().take();
REQUIRE(resp.http_code() == 200u);
REQUIRE(resp.headers.count("Content-Type"));
REQUIRE(resp.headers.count("Content-Length"));
REQUIRE(resp.headers.at("Content-Type") == "image/png");
REQUIRE(resp.headers.at("Content-Length") == std::to_string(untests::png_data_length));
REQUIRE(untests::png_data_length == resp.content.size());
REQUIRE(!std::memcmp(
std::move(resp.content).data().data(),
untests::png_data, untests::png_data_length));
}
{
auto resp = net::request_builder()
.url("https://httpbin.org/image/jpeg")
.method(net::http_method::HEAD)
.send().take();
REQUIRE(resp.http_code() == 200u);
REQUIRE(resp.headers.count("Content-Type"));
REQUIRE(resp.headers.count("Content-Length"));
REQUIRE(resp.headers.at("Content-Type") == "image/jpeg");
REQUIRE(resp.headers.at("Content-Length") == std::to_string(untests::jpeg_data_length));
REQUIRE_FALSE(resp.content.size());
}
{
auto resp = net::request_builder()
.url("https://httpbin.org/image/jpeg")
@@ -388,7 +479,9 @@ TEST_CASE("curly") {
.send().take();
REQUIRE(resp.http_code() == 200u);
REQUIRE(resp.headers.count("Content-Type"));
REQUIRE(resp.headers.count("Content-Length"));
REQUIRE(resp.headers.at("Content-Type") == "image/jpeg");
REQUIRE(resp.headers.at("Content-Length") == std::to_string(untests::jpeg_data_length));
REQUIRE(untests::jpeg_data_length == resp.content.size());
REQUIRE(!std::memcmp(
std::as_const(resp.content).data().data(),
@@ -467,6 +560,26 @@ TEST_CASE("curly") {
const auto content_j = json_parse(resp.content.as_string_view());
REQUIRE(content_j["data"] == R"({"hello":"world"})");
}
{
auto resp = net::request_builder()
.url("https://httpbin.org/anything")
.method(net::http_method::PATCH)
.header("Content-Type", "application/json")
.content(R"({"hello":"world"})")
.send().take();
const auto content_j = json_parse(resp.content.as_string_view());
REQUIRE(content_j["data"] == R"({"hello":"world"})");
}
{
auto resp = net::request_builder()
.url("https://httpbin.org/anything")
.method(net::http_method::DELETE)
.header("Content-Type", "application/json")
.content(R"({"hello":"world"})")
.send().take();
const auto content_j = json_parse(resp.content.as_string_view());
REQUIRE(content_j["data"] == R"({"hello":"world"})");
}
{
auto resp = net::request_builder()
.url("https://httpbin.org/anything")