commit
2fc2c60af1
|
@ -355,7 +355,7 @@ void ApiTest::jsonTest(const HttpRequestPtr &req, const std::function<void(const
|
|||
{
|
||||
auto json = req->getJsonObject();
|
||||
Json::Value ret;
|
||||
if(json)
|
||||
if (json)
|
||||
{
|
||||
ret["result"] = "ok";
|
||||
}
|
||||
|
@ -366,3 +366,19 @@ void ApiTest::jsonTest(const HttpRequestPtr &req, const std::function<void(const
|
|||
auto resp = HttpResponse::newHttpJsonResponse(ret);
|
||||
callback(resp);
|
||||
}
|
||||
|
||||
void ApiTest::formTest(const HttpRequestPtr &req, const std::function<void(const HttpResponsePtr &)> &callback)
|
||||
{
|
||||
auto parameters = req->getParameters();
|
||||
Json::Value ret;
|
||||
if (parameters["k1"] == "1" && parameters["k2"] == "安")
|
||||
{
|
||||
ret["result"] = "ok";
|
||||
}
|
||||
else
|
||||
{
|
||||
ret["result"] = "bad";
|
||||
}
|
||||
auto resp = HttpResponse::newHttpJsonResponse(ret);
|
||||
callback(resp);
|
||||
}
|
|
@ -17,6 +17,7 @@ class ApiTest : public drogon::HttpController<ApiTest>
|
|||
METHOD_ADD(ApiTest::staticApi, "/static", Get, Post);
|
||||
METHOD_ADD(ApiTest::get2, "/get/{1}", Get);
|
||||
METHOD_ADD(ApiTest::jsonTest, "/json", Post);
|
||||
METHOD_ADD(ApiTest::formTest, "/form", Post);
|
||||
METHOD_LIST_END
|
||||
//your declaration of processing function maybe like this:
|
||||
void get(const HttpRequestPtr &req, const std::function<void(const HttpResponsePtr &)> &callback, int p1, std::string &&p2);
|
||||
|
@ -26,6 +27,7 @@ class ApiTest : public drogon::HttpController<ApiTest>
|
|||
void rootGet(const HttpRequestPtr &req, const std::function<void(const HttpResponsePtr &)> &callback);
|
||||
void rootPost(const HttpRequestPtr &req, const std::function<void(const HttpResponsePtr &)> &callback);
|
||||
void jsonTest(const HttpRequestPtr &req, const std::function<void(const HttpResponsePtr &)> &callback);
|
||||
void formTest(const HttpRequestPtr &req, const std::function<void(const HttpResponsePtr &)> &callback);
|
||||
};
|
||||
} // namespace v1
|
||||
} // namespace api
|
||||
|
|
|
@ -489,6 +489,32 @@ void doTest(const HttpClientPtr &client)
|
|||
}
|
||||
});
|
||||
|
||||
/// Test form post
|
||||
req = HttpRequest::newHttpFormPostRequest();
|
||||
req->setPath("/api/v1/apitest/form");
|
||||
req->setParameter("k1", "1");
|
||||
req->setParameter("k2", "安");
|
||||
client->sendRequest(req, [=](ReqResult result, const HttpResponsePtr &resp) {
|
||||
if (result == ReqResult::Ok)
|
||||
{
|
||||
auto ret = resp->getJsonObject();
|
||||
if (ret && (*ret)["result"].asString() == "ok")
|
||||
{
|
||||
outputGood(req);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEBUG << resp->getBody();
|
||||
LOG_ERROR << "Error!";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR << "Error!";
|
||||
exit(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
int main()
|
||||
|
|
|
@ -29,7 +29,6 @@ namespace drogon
|
|||
class HttpRequest;
|
||||
typedef std::shared_ptr<HttpRequest> HttpRequestPtr;
|
||||
|
||||
|
||||
/// Abstract class for webapp developer to get or set the Http request;
|
||||
class HttpRequest
|
||||
{
|
||||
|
@ -114,7 +113,7 @@ class HttpRequest
|
|||
/// Create a request object.
|
||||
static HttpRequestPtr newHttpRequest();
|
||||
static HttpRequestPtr newHttpJsonRequest(const Json::Value &data);
|
||||
|
||||
static HttpRequestPtr newHttpFormPostRequest();
|
||||
virtual ~HttpRequest() {}
|
||||
};
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
namespace drogon
|
||||
{
|
||||
|
||||
|
||||
enum HttpStatusCode
|
||||
{
|
||||
//rfc2616-6.1.1
|
||||
|
@ -73,6 +73,7 @@ enum ContentType
|
|||
CT_APPLICATION_JSON = 0,
|
||||
CT_TEXT_PLAIN,
|
||||
CT_TEXT_HTML,
|
||||
CT_APPLICATION_X_FORM,
|
||||
CT_APPLICATION_X_JAVASCRIPT,
|
||||
CT_TEXT_CSS,
|
||||
CT_TEXT_XML,
|
||||
|
|
|
@ -50,9 +50,10 @@ std::string base64Encode(const unsigned char *bytes_to_encode, unsigned int in_l
|
|||
/// Decode the base64 format string.
|
||||
std::string base64Decode(std::string const &encoded_string);
|
||||
|
||||
/// Decode the URL format string send by web browser.
|
||||
/// Decode from or encode to the URL format string
|
||||
std::string urlDecode(const std::string &szToDecode);
|
||||
std::string urlDecode(const char *begin, const char *end);
|
||||
std::string urlEncode(const std::string &str);
|
||||
|
||||
/// Commpress or decompress data using gzip lib.
|
||||
/**
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
*/
|
||||
|
||||
#include "HttpRequestImpl.h"
|
||||
#include <drogon/utils/Utilities.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace drogon;
|
||||
|
@ -133,7 +134,7 @@ void HttpRequestImpl::appendToBuffer(MsgBuffer *output) const
|
|||
content.append("&");
|
||||
}
|
||||
content.resize(content.length() - 1);
|
||||
///TODO: URL code?
|
||||
content = urlEncode(content);
|
||||
if (_method == Get || _method == Delete)
|
||||
{
|
||||
output->append("?");
|
||||
|
@ -211,7 +212,7 @@ void HttpRequestImpl::appendToBuffer(MsgBuffer *output) const
|
|||
void HttpRequestImpl::addHeader(const char *start, const char *colon, const char *end)
|
||||
{
|
||||
std::string field(start, colon);
|
||||
//field name is case-insensitive.so we transform it to lower;(rfc2616-4.2)
|
||||
//Field name is case-insensitive.so we transform it to lower;(rfc2616-4.2)
|
||||
std::transform(field.begin(), field.end(), field.begin(), ::tolower);
|
||||
++colon;
|
||||
while (colon < end && isspace(*colon))
|
||||
|
@ -274,6 +275,15 @@ HttpRequestPtr HttpRequest::newHttpRequest()
|
|||
return req;
|
||||
}
|
||||
|
||||
HttpRequestPtr HttpRequest::newHttpFormPostRequest()
|
||||
{
|
||||
auto req = std::make_shared<HttpRequestImpl>();
|
||||
req->setMethod(drogon::Post);
|
||||
req->setVersion(drogon::HttpRequest::kHttp11);
|
||||
req->_contentType = CT_APPLICATION_X_FORM;
|
||||
return req;
|
||||
}
|
||||
|
||||
HttpRequestPtr HttpRequest::newHttpJsonRequest(const Json::Value &data)
|
||||
{
|
||||
auto req = std::make_shared<HttpRequestImpl>();
|
||||
|
|
|
@ -24,6 +24,9 @@ std::string webContentTypeAndCharsetToString(ContentType contenttype, const std:
|
|||
case CT_TEXT_HTML:
|
||||
return "text/html; charset=" + charSet;
|
||||
|
||||
case CT_APPLICATION_X_FORM:
|
||||
return "application/x-www-form-urlencoded";
|
||||
|
||||
case CT_APPLICATION_XML:
|
||||
return "application/xml; charset=" + charSet;
|
||||
|
||||
|
@ -94,6 +97,9 @@ std::string webContentTypeToString(ContentType contenttype)
|
|||
case CT_TEXT_HTML:
|
||||
return "text/html; charset=utf-8";
|
||||
|
||||
case CT_APPLICATION_X_FORM:
|
||||
return "application/x-www-form-urlencoded";
|
||||
|
||||
case CT_APPLICATION_XML:
|
||||
return "application/xml; charset=utf-8";
|
||||
|
||||
|
|
|
@ -27,6 +27,10 @@
|
|||
#include <mutex>
|
||||
#include <cstdlib>
|
||||
#include <stack>
|
||||
#include <cctype>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace drogon
|
||||
{
|
||||
|
@ -272,6 +276,121 @@ std::string base64Decode(std::string const &encoded_string)
|
|||
|
||||
return ret;
|
||||
}
|
||||
static std::string charToHex(char c)
|
||||
{
|
||||
std::string result;
|
||||
char first, second;
|
||||
|
||||
first = (c & 0xF0) / 16;
|
||||
first += first > 9 ? 'A' - 10 : '0';
|
||||
second = c & 0x0F;
|
||||
second += second > 9 ? 'A' - 10 : '0';
|
||||
|
||||
result.append(1, first);
|
||||
result.append(1, second);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string urlEncode(const std::string &src)
|
||||
{
|
||||
std::string result;
|
||||
std::string::const_iterator iter;
|
||||
|
||||
for (iter = src.begin(); iter != src.end(); ++iter)
|
||||
{
|
||||
switch (*iter)
|
||||
{
|
||||
case ' ':
|
||||
result.append(1, '+');
|
||||
break;
|
||||
// alnum
|
||||
case 'A':
|
||||
case 'B':
|
||||
case 'C':
|
||||
case 'D':
|
||||
case 'E':
|
||||
case 'F':
|
||||
case 'G':
|
||||
case 'H':
|
||||
case 'I':
|
||||
case 'J':
|
||||
case 'K':
|
||||
case 'L':
|
||||
case 'M':
|
||||
case 'N':
|
||||
case 'O':
|
||||
case 'P':
|
||||
case 'Q':
|
||||
case 'R':
|
||||
case 'S':
|
||||
case 'T':
|
||||
case 'U':
|
||||
case 'V':
|
||||
case 'W':
|
||||
case 'X':
|
||||
case 'Y':
|
||||
case 'Z':
|
||||
case 'a':
|
||||
case 'b':
|
||||
case 'c':
|
||||
case 'd':
|
||||
case 'e':
|
||||
case 'f':
|
||||
case 'g':
|
||||
case 'h':
|
||||
case 'i':
|
||||
case 'j':
|
||||
case 'k':
|
||||
case 'l':
|
||||
case 'm':
|
||||
case 'n':
|
||||
case 'o':
|
||||
case 'p':
|
||||
case 'q':
|
||||
case 'r':
|
||||
case 's':
|
||||
case 't':
|
||||
case 'u':
|
||||
case 'v':
|
||||
case 'w':
|
||||
case 'x':
|
||||
case 'y':
|
||||
case 'z':
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
// mark
|
||||
case '-':
|
||||
case '_':
|
||||
case '.':
|
||||
case '!':
|
||||
case '~':
|
||||
case '*':
|
||||
case '\'':
|
||||
case '(':
|
||||
case ')':
|
||||
case '&':
|
||||
case '=':
|
||||
result.append(1, *iter);
|
||||
break;
|
||||
// escape
|
||||
default:
|
||||
result.append(1, '%');
|
||||
result.append(charToHex(*iter));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string urlDecode(const std::string &szToDecode)
|
||||
{
|
||||
|
|
|
@ -8,4 +8,5 @@ add_executable(sha1_test Sha1Test.cc)
|
|||
add_executable(view_data_test HttpViewDataTest.cc)
|
||||
add_executable(md5_test Md5Test.cc ../src/ssl_funcs/Md5.cc)
|
||||
add_executable(http_full_date_test HttpFullDateTest.cc)
|
||||
add_executable(gzip_test GzipTest.cc)
|
||||
add_executable(gzip_test GzipTest.cc)
|
||||
add_executable(url_codec_test UrlCodecTest.cc)
|
|
@ -0,0 +1,13 @@
|
|||
#include <drogon/utils/Utilities.h>
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
std::string input = "k1=1&k2=安";
|
||||
auto output = drogon::urlEncode(input);
|
||||
std::cout << output << std::endl;
|
||||
auto output2 = drogon::urlDecode(output);
|
||||
std::cout << output2 << std::endl;
|
||||
std::cout << drogon::urlDecode("k2%3D%E5%AE%89&k1%3D1");
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue