Add sending customized http requests to drogon_ctl (#2186)
This commit is contained in:
parent
3fce70b535
commit
ca2210331d
|
@ -19,6 +19,10 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <json/json.h>
|
||||||
|
#include <fstream>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -33,9 +37,10 @@ std::string press::detail()
|
||||||
" -t num number of threads(default : 1)\n"
|
" -t num number of threads(default : 1)\n"
|
||||||
" -c num concurrent connections(default : 1)\n"
|
" -c num concurrent connections(default : 1)\n"
|
||||||
" -k disable SSL certificate validation(default: enable)\n"
|
" -k disable SSL certificate validation(default: enable)\n"
|
||||||
|
" -f customize http request json file(default: disenable)\n"
|
||||||
" -q no progress indication(default: show)\n\n"
|
" -q no progress indication(default: show)\n\n"
|
||||||
"example: drogon_ctl press -n 10000 -c 100 -t 4 -q "
|
"example: drogon_ctl press -n 10000 -c 100 -t 4 -q "
|
||||||
"http://localhost:8080/index.html\n";
|
"http://localhost:8080/index.html -f ./http_request.json\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void outputErrorAndExit(const std::string_view &err)
|
void outputErrorAndExit(const std::string_view &err)
|
||||||
|
@ -151,6 +156,24 @@ void press::handleCommand(std::vector<std::string> ¶meters)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (param.find("-f") == 0)
|
||||||
|
{
|
||||||
|
if (param == "-f")
|
||||||
|
{
|
||||||
|
++iter;
|
||||||
|
if (iter == parameters.end())
|
||||||
|
{
|
||||||
|
outputErrorAndExit("No http request json file!");
|
||||||
|
}
|
||||||
|
httpRequestJsonFile_ = *iter;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
httpRequestJsonFile_ = param.substr(2);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (param == "-k")
|
else if (param == "-k")
|
||||||
{
|
{
|
||||||
certValidation_ = false;
|
certValidation_ = false;
|
||||||
|
@ -190,6 +213,118 @@ void press::handleCommand(std::vector<std::string> ¶meters)
|
||||||
path_ = url_.substr(posOfPath);
|
path_ = url_.substr(posOfPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
http_request.json
|
||||||
|
{
|
||||||
|
"method": "POST",
|
||||||
|
"header": {
|
||||||
|
"token": "e2e9d0fe-dd14-4eaf-8ac1-0997730a805d"
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"passwd": "123456",
|
||||||
|
"account": "10001"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
if (!httpRequestJsonFile_.empty())
|
||||||
|
{
|
||||||
|
Json::Value httpRequestJson;
|
||||||
|
std::ifstream httpRequestFile(httpRequestJsonFile_,
|
||||||
|
std::ifstream::binary);
|
||||||
|
if (!httpRequestFile.is_open())
|
||||||
|
{
|
||||||
|
outputErrorAndExit(std::string{"No "} + httpRequestJsonFile_);
|
||||||
|
}
|
||||||
|
httpRequestFile >> httpRequestJson;
|
||||||
|
|
||||||
|
if (!httpRequestJson.isMember("method"))
|
||||||
|
{
|
||||||
|
outputErrorAndExit("No contain method");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto methodStr = httpRequestJson["method"].asString();
|
||||||
|
std::transform(methodStr.begin(),
|
||||||
|
methodStr.end(),
|
||||||
|
methodStr.begin(),
|
||||||
|
::toupper);
|
||||||
|
|
||||||
|
auto toHttpMethod = [&]() -> drogon::HttpMethod {
|
||||||
|
if (methodStr == "GET")
|
||||||
|
{
|
||||||
|
return drogon::HttpMethod::Get;
|
||||||
|
}
|
||||||
|
else if (methodStr == "POST")
|
||||||
|
{
|
||||||
|
return drogon::HttpMethod::Post;
|
||||||
|
}
|
||||||
|
else if (methodStr == "HEAD")
|
||||||
|
{
|
||||||
|
return drogon::HttpMethod::Head;
|
||||||
|
}
|
||||||
|
else if (methodStr == "PUT")
|
||||||
|
{
|
||||||
|
return drogon::HttpMethod::Put;
|
||||||
|
}
|
||||||
|
else if (methodStr == "DELETE")
|
||||||
|
{
|
||||||
|
return drogon::HttpMethod::Delete;
|
||||||
|
}
|
||||||
|
else if (methodStr == "OPTIONS")
|
||||||
|
{
|
||||||
|
return drogon::HttpMethod::Options;
|
||||||
|
}
|
||||||
|
else if (methodStr == "PATCH")
|
||||||
|
{
|
||||||
|
return drogon::HttpMethod::Patch;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
outputErrorAndExit("invalid method");
|
||||||
|
}
|
||||||
|
return drogon::HttpMethod::Get;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unordered_map<std::string, std::string> header;
|
||||||
|
if (httpRequestJson.isMember("header"))
|
||||||
|
{
|
||||||
|
auto &jsonValue = httpRequestJson["header"];
|
||||||
|
for (const auto &key : jsonValue.getMemberNames())
|
||||||
|
{
|
||||||
|
if (jsonValue[key].isString())
|
||||||
|
{
|
||||||
|
header[key] = jsonValue[key].asString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
header[key] = jsonValue[key].toStyledString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string body;
|
||||||
|
if (httpRequestJson.isMember("body"))
|
||||||
|
{
|
||||||
|
Json::FastWriter fastWriter;
|
||||||
|
body = fastWriter.write(httpRequestJson["body"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
createHttpRequestFunc_ = [this,
|
||||||
|
method = toHttpMethod(),
|
||||||
|
body = std::move(body),
|
||||||
|
header =
|
||||||
|
std::move(header)]() -> HttpRequestPtr {
|
||||||
|
auto request = HttpRequest::newHttpRequest();
|
||||||
|
request->setPath(path_);
|
||||||
|
request->setMethod(method);
|
||||||
|
for (const auto &[field, val] : header)
|
||||||
|
request->addHeader(field, val);
|
||||||
|
if (!body.empty())
|
||||||
|
request->setBody(body);
|
||||||
|
return request;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// std::cout << "host=" << host_ << std::endl;
|
// std::cout << "host=" << host_ << std::endl;
|
||||||
// std::cout << "path=" << path_ << std::endl;
|
// std::cout << "path=" << path_ << std::endl;
|
||||||
doTesting();
|
doTesting();
|
||||||
|
@ -232,9 +367,19 @@ void press::sendRequest(const HttpClientPtr &client)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto request = HttpRequest::newHttpRequest();
|
|
||||||
|
HttpRequestPtr request;
|
||||||
|
if (createHttpRequestFunc_)
|
||||||
|
{
|
||||||
|
request = createHttpRequestFunc_();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
request = HttpRequest::newHttpRequest();
|
||||||
request->setPath(path_);
|
request->setPath(path_);
|
||||||
request->setMethod(Get);
|
request->setMethod(Get);
|
||||||
|
}
|
||||||
|
|
||||||
// std::cout << "send!" << std::endl;
|
// std::cout << "send!" << std::endl;
|
||||||
client->sendRequest(
|
client->sendRequest(
|
||||||
request,
|
request,
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <drogon/HttpClient.h>
|
#include <drogon/HttpClient.h>
|
||||||
#include <trantor/utils/Date.h>
|
#include <trantor/utils/Date.h>
|
||||||
#include <trantor/net/EventLoopThreadPool.h>
|
#include <trantor/net/EventLoopThreadPool.h>
|
||||||
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -62,6 +63,8 @@ class press : public DrObject<press>, public CommandHandler
|
||||||
size_t numOfThreads_{1};
|
size_t numOfThreads_{1};
|
||||||
size_t numOfRequests_{1};
|
size_t numOfRequests_{1};
|
||||||
size_t numOfConnections_{1};
|
size_t numOfConnections_{1};
|
||||||
|
std::string httpRequestJsonFile_;
|
||||||
|
std::function<HttpRequestPtr()> createHttpRequestFunc_;
|
||||||
bool certValidation_{true};
|
bool certValidation_{true};
|
||||||
bool processIndication_{true};
|
bool processIndication_{true};
|
||||||
std::string url_;
|
std::string url_;
|
||||||
|
|
Loading…
Reference in New Issue