1919#include < memory>
2020#include < iomanip>
2121#include < cstdlib>
22+ #include < json/json.h>
23+ #include < fstream>
24+ #include < string>
25+ #include < unordered_map>
2226#ifndef _WIN32
2327#include < unistd.h>
2428#endif
@@ -33,9 +37,10 @@ std::string press::detail()
3337 " -t num number of threads(default : 1)\n "
3438 " -c num concurrent connections(default : 1)\n "
3539 " -k disable SSL certificate validation(default: enable)\n "
40+ " -f customize http request json file(default: disenable)\n "
3641 " -q no progress indication(default: show)\n\n "
3742 " example: drogon_ctl press -n 10000 -c 100 -t 4 -q "
38- " http://localhost:8080/index.html\n " ;
43+ " http://localhost:8080/index.html -f ./http_request.json \n " ;
3944}
4045
4146void outputErrorAndExit (const std::string_view &err)
@@ -151,6 +156,24 @@ void press::handleCommand(std::vector<std::string> ¶meters)
151156 continue ;
152157 }
153158 }
159+ else if (param.find (" -f" ) == 0 )
160+ {
161+ if (param == " -f" )
162+ {
163+ ++iter;
164+ if (iter == parameters.end ())
165+ {
166+ outputErrorAndExit (" No http request json file!" );
167+ }
168+ httpRequestJsonFile_ = *iter;
169+ continue ;
170+ }
171+ else
172+ {
173+ httpRequestJsonFile_ = param.substr (2 );
174+ continue ;
175+ }
176+ }
154177 else if (param == " -k" )
155178 {
156179 certValidation_ = false ;
@@ -190,6 +213,118 @@ void press::handleCommand(std::vector<std::string> ¶meters)
190213 path_ = url_.substr (posOfPath);
191214 }
192215 }
216+
217+ /*
218+ http_request.json
219+ {
220+ "method": "POST",
221+ "header": {
222+ "token": "e2e9d0fe-dd14-4eaf-8ac1-0997730a805d"
223+ },
224+ "body": {
225+ "passwd": "123456",
226+ "account": "10001"
227+ }
228+ }
229+ */
230+ if (!httpRequestJsonFile_.empty ())
231+ {
232+ Json::Value httpRequestJson;
233+ std::ifstream httpRequestFile (httpRequestJsonFile_,
234+ std::ifstream::binary);
235+ if (!httpRequestFile.is_open ())
236+ {
237+ outputErrorAndExit (std::string{" No " } + httpRequestJsonFile_);
238+ }
239+ httpRequestFile >> httpRequestJson;
240+
241+ if (!httpRequestJson.isMember (" method" ))
242+ {
243+ outputErrorAndExit (" No contain method" );
244+ }
245+
246+ auto methodStr = httpRequestJson[" method" ].asString ();
247+ std::transform (methodStr.begin (),
248+ methodStr.end (),
249+ methodStr.begin (),
250+ ::toupper);
251+
252+ auto toHttpMethod = [&]() -> drogon::HttpMethod {
253+ if (methodStr == " GET" )
254+ {
255+ return drogon::HttpMethod::Get;
256+ }
257+ else if (methodStr == " POST" )
258+ {
259+ return drogon::HttpMethod::Post;
260+ }
261+ else if (methodStr == " HEAD" )
262+ {
263+ return drogon::HttpMethod::Head;
264+ }
265+ else if (methodStr == " PUT" )
266+ {
267+ return drogon::HttpMethod::Put;
268+ }
269+ else if (methodStr == " DELETE" )
270+ {
271+ return drogon::HttpMethod::Delete;
272+ }
273+ else if (methodStr == " OPTIONS" )
274+ {
275+ return drogon::HttpMethod::Options;
276+ }
277+ else if (methodStr == " PATCH" )
278+ {
279+ return drogon::HttpMethod::Patch;
280+ }
281+ else
282+ {
283+ outputErrorAndExit (" invalid method" );
284+ }
285+ return drogon::HttpMethod::Get;
286+ };
287+
288+ std::unordered_map<std::string, std::string> header;
289+ if (httpRequestJson.isMember (" header" ))
290+ {
291+ auto &jsonValue = httpRequestJson[" header" ];
292+ for (const auto &key : jsonValue.getMemberNames ())
293+ {
294+ if (jsonValue[key].isString ())
295+ {
296+ header[key] = jsonValue[key].asString ();
297+ }
298+ else
299+ {
300+ header[key] = jsonValue[key].toStyledString ();
301+ }
302+ }
303+ }
304+
305+ std::string body;
306+ if (httpRequestJson.isMember (" body" ))
307+ {
308+ Json::FastWriter fastWriter;
309+ body = fastWriter.write (httpRequestJson[" body" ]);
310+ }
311+
312+ createHttpRequestFunc_ = [this ,
313+ method = toHttpMethod (),
314+ body = std::move (body),
315+ header =
316+ std::move (header)]() -> HttpRequestPtr {
317+ auto request = HttpRequest::newHttpRequest ();
318+ request->setPath (path_);
319+ request->setMethod (method);
320+ for (const auto &[field, val] : header)
321+ request->addHeader (field, val);
322+ if (!body.empty ())
323+ request->setBody (body);
324+ return request;
325+ };
326+ }
327+
193328 // std::cout << "host=" << host_ << std::endl;
194329 // std::cout << "path=" << path_ << std::endl;
195330 doTesting ();
@@ -232,9 +367,19 @@ void press::sendRequest(const HttpClientPtr &client)
232367 {
233368 return ;
234369 }
235- auto request = HttpRequest::newHttpRequest ();
236- request->setPath (path_);
237- request->setMethod (Get);
370+
371+ HttpRequestPtr request;
372+ if (createHttpRequestFunc_)
373+ {
374+ request = createHttpRequestFunc_ ();
375+ }
376+ else
377+ {
378+ request = HttpRequest::newHttpRequest ();
379+ request->setPath (path_);
380+ request->setMethod (Get);
381+ }
382+
238383 // std::cout << "send!" << std::endl;
239384 client->sendRequest (
240385 request,
0 commit comments