mirror of
https://gitee.com/an-tao/drogon.git
synced 2024-12-02 19:57:43 +08:00
Merge pull request #40 from an-tao/dev
Support http request in json format
This commit is contained in:
commit
4e7714e5e9
@ -22,6 +22,6 @@ void {{className}}::doFilter(const HttpRequestPtr &req,
|
||||
}
|
||||
//Check failed
|
||||
auto res = drogon::HttpResponse::newHttpResponse();
|
||||
res->setStatusCode(HttpResponse::k500InternalServerError);
|
||||
res->setStatusCode(k500InternalServerError);
|
||||
fcb(res);
|
||||
}
|
||||
|
@ -32,6 +32,6 @@ void Attachment::upload(const HttpRequestPtr &req,
|
||||
file.saveAs("../xxx");
|
||||
}
|
||||
auto resp = HttpResponse::newHttpResponse();
|
||||
resp->setStatusCode(HttpResponse::k200OK);
|
||||
resp->setStatusCode(k200OK);
|
||||
callback(resp);
|
||||
}
|
||||
|
@ -350,3 +350,19 @@ void ApiTest::get2(const HttpRequestPtr &req, const std::function<void(const Htt
|
||||
res->setExpiredTime(0);
|
||||
callback(res);
|
||||
}
|
||||
|
||||
void ApiTest::jsonTest(const HttpRequestPtr &req, const std::function<void(const HttpResponsePtr &)> &callback)
|
||||
{
|
||||
auto json = req->getJsonObject();
|
||||
Json::Value ret;
|
||||
if(json)
|
||||
{
|
||||
ret["result"] = "ok";
|
||||
}
|
||||
else
|
||||
{
|
||||
ret["result"] = "bad";
|
||||
}
|
||||
auto resp = HttpResponse::newHttpJsonResponse(ret);
|
||||
callback(resp);
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ class ApiTest : public drogon::HttpController<ApiTest>
|
||||
METHOD_ADD(ApiTest::your_method_name, "/{1}/List?P2={2}", Get); //path will be /api/v1/apitest/{arg1}/list
|
||||
METHOD_ADD(ApiTest::staticApi, "/static", Get, Post);
|
||||
METHOD_ADD(ApiTest::get2, "/get/{1}", Get);
|
||||
METHOD_ADD(ApiTest::jsonTest, "/json", 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);
|
||||
@ -24,6 +25,7 @@ class ApiTest : public drogon::HttpController<ApiTest>
|
||||
void get2(const HttpRequestPtr &req, const std::function<void(const HttpResponsePtr &)> &callback, std::string &&p1);
|
||||
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);
|
||||
};
|
||||
} // namespace v1
|
||||
} // namespace api
|
||||
|
@ -35,8 +35,35 @@ void outputGood(const HttpRequestPtr &req)
|
||||
}
|
||||
void doTest(const HttpClientPtr &client)
|
||||
{
|
||||
/// Post json
|
||||
Json::Value json;
|
||||
json["request"] = "json";
|
||||
auto req = HttpRequest::newHttpJsonRequest(json);
|
||||
req->setMethod(drogon::Post);
|
||||
req->setPath("/api/v1/apitest/json");
|
||||
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);
|
||||
}
|
||||
});
|
||||
/// 1 Get /
|
||||
auto req = HttpRequest::newHttpRequest();
|
||||
req = HttpRequest::newHttpRequest();
|
||||
req->setMethod(drogon::Get);
|
||||
req->setPath("/");
|
||||
client->sendRequest(req, [=](ReqResult result, const HttpResponsePtr &resp) {
|
||||
@ -91,7 +118,7 @@ void doTest(const HttpClientPtr &client)
|
||||
if (result == ReqResult::Ok)
|
||||
{
|
||||
//LOG_DEBUG << resp->getBody();
|
||||
if (resp->statusCode() == HttpResponse::k405MethodNotAllowed)
|
||||
if (resp->statusCode() == k405MethodNotAllowed)
|
||||
{
|
||||
outputGood(req);
|
||||
}
|
||||
@ -444,7 +471,7 @@ void doTest(const HttpClientPtr &client)
|
||||
client->sendRequest(req, [=](ReqResult result, const HttpResponsePtr &resp) {
|
||||
if (result == ReqResult::Ok)
|
||||
{
|
||||
if (resp->statusCode() == HttpResponse::k403Forbidden)
|
||||
if (resp->statusCode() == k403Forbidden)
|
||||
{
|
||||
outputGood(req);
|
||||
}
|
||||
@ -461,6 +488,7 @@ void doTest(const HttpClientPtr &client)
|
||||
exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
int main()
|
||||
@ -468,7 +496,7 @@ int main()
|
||||
trantor::EventLoopThread loop[2];
|
||||
loop[0].run();
|
||||
loop[1].run();
|
||||
// for (int i = 0; i < 100;i++)
|
||||
// for (int i = 0; i < 100;i++)
|
||||
{
|
||||
auto client = HttpClient::newHttpClient("http://127.0.0.1:8848", loop[0].getLoop());
|
||||
doTest(client);
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <drogon/HttpTypes.h>
|
||||
#include <drogon/Session.h>
|
||||
#include <trantor/net/InetAddress.h>
|
||||
#include <trantor/utils/Date.h>
|
||||
@ -21,19 +22,13 @@
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
namespace drogon
|
||||
{
|
||||
|
||||
class HttpRequest;
|
||||
typedef std::shared_ptr<HttpRequest> HttpRequestPtr;
|
||||
enum HttpMethod
|
||||
{
|
||||
Get = 0,
|
||||
Post,
|
||||
Head,
|
||||
Put,
|
||||
Delete,
|
||||
Invalid
|
||||
};
|
||||
|
||||
|
||||
/// Abstract class for webapp developer to get or set the Http request;
|
||||
class HttpRequest
|
||||
@ -111,8 +106,14 @@ class HttpRequest
|
||||
/// Set the parameter of the request
|
||||
virtual void setParameter(const std::string &key, const std::string &value) = 0;
|
||||
|
||||
/// Set or get the content type
|
||||
virtual void setContentTypeCode(ContentType type) = 0;
|
||||
virtual void setContentTypeCodeAndCharacterSet(ContentType type, const std::string &charSet = "utf-8") = 0;
|
||||
virtual ContentType getContentTypeCode() = 0;
|
||||
|
||||
/// Create a request object.
|
||||
static HttpRequestPtr newHttpRequest();
|
||||
static HttpRequestPtr newHttpJsonRequest(const Json::Value &data);
|
||||
|
||||
virtual ~HttpRequest() {}
|
||||
};
|
||||
|
@ -15,33 +15,11 @@
|
||||
|
||||
#include <drogon/HttpViewData.h>
|
||||
#include <drogon/Cookie.h>
|
||||
#include <drogon/HttpTypes.h>
|
||||
#include <json/json.h>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
using std::string;
|
||||
#define CT_APPLICATION_JSON 1
|
||||
#define CT_TEXT_PLAIN 2
|
||||
#define CT_TEXT_HTML 3
|
||||
#define CT_APPLICATION_X_JAVASCRIPT 4
|
||||
#define CT_TEXT_CSS 5
|
||||
#define CT_TEXT_XML 6
|
||||
#define CT_APPLICATION_XML 7
|
||||
#define CT_TEXT_XSL 8
|
||||
#define CT_APPLICATION_OCTET_STREAM 9
|
||||
#define CT_APPLICATION_X_FONT_TRUETYPE 10
|
||||
#define CT_APPLICATION_X_FONT_OPENTYPE 11
|
||||
#define CT_APPLICATION_FONT_WOFF 12
|
||||
#define CT_APPLICATION_FONT_WOFF2 13
|
||||
#define CT_APPLICATION_VND_MS_FONTOBJ 14
|
||||
#define CT_IMAGE_SVG_XML 15
|
||||
#define CT_IMAGE_PNG 16
|
||||
#define CT_IMAGE_JPG 17
|
||||
#define CT_IMAGE_GIF 18
|
||||
#define CT_IMAGE_XICON 19
|
||||
#define CT_IMAGE_ICNS 20
|
||||
#define CT_IMAGE_BMP 21
|
||||
|
||||
namespace drogon
|
||||
{
|
||||
/// Abstract class for webapp developer to get or set the Http response;
|
||||
@ -50,58 +28,6 @@ typedef std::shared_ptr<HttpResponse> HttpResponsePtr;
|
||||
class HttpResponse
|
||||
{
|
||||
public:
|
||||
enum HttpStatusCode
|
||||
{
|
||||
//rfc2616-6.1.1
|
||||
kUnknown = 0,
|
||||
k100Continue = 100,
|
||||
k101SwitchingProtocols = 101,
|
||||
k200OK = 200,
|
||||
k201Created = 201,
|
||||
k202Accepted = 202,
|
||||
k203NonAuthoritativeInformation = 203,
|
||||
k204NoContent = 204,
|
||||
k205ResetContent = 205,
|
||||
k206PartialContent = 206,
|
||||
k300MultipleChoices = 300,
|
||||
k301MovedPermanently = 301,
|
||||
k302Found = 302,
|
||||
k303SeeOther = 303,
|
||||
k304NotModified = 304,
|
||||
k305UseProxy = 305,
|
||||
k307TemporaryRedirect = 307,
|
||||
k400BadRequest = 400,
|
||||
k401Unauthorized = 401,
|
||||
k402PaymentRequired = 402,
|
||||
k403Forbidden = 403,
|
||||
k404NotFound = 404,
|
||||
k405MethodNotAllowed = 405,
|
||||
k406NotAcceptable = 406,
|
||||
k407ProxyAuthenticationRequired = 407,
|
||||
k408RequestTimeout = 408,
|
||||
k409Conflict = 409,
|
||||
k410Gone = 410,
|
||||
k411LengthRequired = 411,
|
||||
k412PreconditionFailed = 412,
|
||||
k413RequestEntityTooLarge = 413,
|
||||
k414RequestURITooLarge = 414,
|
||||
k415UnsupportedMediaType = 415,
|
||||
k416Requestedrangenotsatisfiable = 416,
|
||||
k417ExpectationFailed = 417,
|
||||
k500InternalServerError = 500,
|
||||
k501NotImplemented = 501,
|
||||
k502BadGateway = 502,
|
||||
k503ServiceUnavailable = 503,
|
||||
k504GatewayTimeout = 504,
|
||||
k505HTTPVersionnotsupported = 505,
|
||||
};
|
||||
|
||||
enum Version
|
||||
{
|
||||
kHttp10,
|
||||
kHttp11
|
||||
};
|
||||
|
||||
explicit HttpResponse()
|
||||
{
|
||||
}
|
||||
@ -120,11 +46,11 @@ class HttpResponse
|
||||
|
||||
virtual bool closeConnection() const = 0;
|
||||
|
||||
virtual void setContentTypeCode(uint8_t type) = 0;
|
||||
virtual void setContentTypeCode(ContentType type) = 0;
|
||||
|
||||
virtual void setContentTypeCodeAndCharacterSet(uint8_t type, const std::string &charSet = "utf-8") = 0;
|
||||
virtual void setContentTypeCodeAndCharacterSet(ContentType type, const std::string &charSet = "utf-8") = 0;
|
||||
|
||||
virtual uint8_t getContentTypeCode() = 0;
|
||||
virtual ContentType getContentTypeCode() = 0;
|
||||
|
||||
virtual const std::string &getHeader(const std::string &key, const std::string &defaultVal = std::string()) const = 0;
|
||||
|
||||
|
106
lib/inc/drogon/HttpTypes.h
Normal file
106
lib/inc/drogon/HttpTypes.h
Normal file
@ -0,0 +1,106 @@
|
||||
/**
|
||||
* HttpTypes.h
|
||||
* An Tao
|
||||
*
|
||||
* Copyright 2018, An Tao. All rights reserved.
|
||||
* https://github.com/an-tao/drogon
|
||||
* Use of this source code is governed by a MIT license
|
||||
* that can be found in the License file.
|
||||
*
|
||||
* Drogon
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace drogon
|
||||
{
|
||||
|
||||
enum HttpStatusCode
|
||||
{
|
||||
//rfc2616-6.1.1
|
||||
kUnknown = 0,
|
||||
k100Continue = 100,
|
||||
k101SwitchingProtocols = 101,
|
||||
k200OK = 200,
|
||||
k201Created = 201,
|
||||
k202Accepted = 202,
|
||||
k203NonAuthoritativeInformation = 203,
|
||||
k204NoContent = 204,
|
||||
k205ResetContent = 205,
|
||||
k206PartialContent = 206,
|
||||
k300MultipleChoices = 300,
|
||||
k301MovedPermanently = 301,
|
||||
k302Found = 302,
|
||||
k303SeeOther = 303,
|
||||
k304NotModified = 304,
|
||||
k305UseProxy = 305,
|
||||
k307TemporaryRedirect = 307,
|
||||
k400BadRequest = 400,
|
||||
k401Unauthorized = 401,
|
||||
k402PaymentRequired = 402,
|
||||
k403Forbidden = 403,
|
||||
k404NotFound = 404,
|
||||
k405MethodNotAllowed = 405,
|
||||
k406NotAcceptable = 406,
|
||||
k407ProxyAuthenticationRequired = 407,
|
||||
k408RequestTimeout = 408,
|
||||
k409Conflict = 409,
|
||||
k410Gone = 410,
|
||||
k411LengthRequired = 411,
|
||||
k412PreconditionFailed = 412,
|
||||
k413RequestEntityTooLarge = 413,
|
||||
k414RequestURITooLarge = 414,
|
||||
k415UnsupportedMediaType = 415,
|
||||
k416Requestedrangenotsatisfiable = 416,
|
||||
k417ExpectationFailed = 417,
|
||||
k500InternalServerError = 500,
|
||||
k501NotImplemented = 501,
|
||||
k502BadGateway = 502,
|
||||
k503ServiceUnavailable = 503,
|
||||
k504GatewayTimeout = 504,
|
||||
k505HTTPVersionnotsupported = 505,
|
||||
};
|
||||
|
||||
enum Version
|
||||
{
|
||||
kHttp10,
|
||||
kHttp11
|
||||
};
|
||||
|
||||
enum ContentType
|
||||
{
|
||||
CT_APPLICATION_JSON = 0,
|
||||
CT_TEXT_PLAIN,
|
||||
CT_TEXT_HTML,
|
||||
CT_APPLICATION_X_JAVASCRIPT,
|
||||
CT_TEXT_CSS,
|
||||
CT_TEXT_XML,
|
||||
CT_APPLICATION_XML,
|
||||
CT_TEXT_XSL,
|
||||
CT_APPLICATION_OCTET_STREAM,
|
||||
CT_APPLICATION_X_FONT_TRUETYPE,
|
||||
CT_APPLICATION_X_FONT_OPENTYPE,
|
||||
CT_APPLICATION_FONT_WOFF,
|
||||
CT_APPLICATION_FONT_WOFF2,
|
||||
CT_APPLICATION_VND_MS_FONTOBJ,
|
||||
CT_IMAGE_SVG_XML,
|
||||
CT_IMAGE_PNG,
|
||||
CT_IMAGE_JPG,
|
||||
CT_IMAGE_GIF,
|
||||
CT_IMAGE_XICON,
|
||||
CT_IMAGE_ICNS,
|
||||
CT_IMAGE_BMP
|
||||
};
|
||||
|
||||
enum HttpMethod
|
||||
{
|
||||
Get = 0,
|
||||
Post,
|
||||
Head,
|
||||
Put,
|
||||
Delete,
|
||||
Invalid
|
||||
};
|
||||
|
||||
} // namespace drogon
|
@ -13,6 +13,7 @@
|
||||
*/
|
||||
|
||||
#include "HttpRequestImpl.h"
|
||||
#include "HttpUtils.h"
|
||||
#include <drogon/utils/Utilities.h>
|
||||
#include <drogon/FileUpload.h>
|
||||
#include <drogon/HttpAppFramework.h>
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "HttpAppFrameworkImpl.h"
|
||||
#include "ConfigLoader.h"
|
||||
#include "HttpServer.h"
|
||||
#include <drogon/HttpTypes.h>
|
||||
#include <drogon/utils/Utilities.h>
|
||||
#include <drogon/DrClassMap.h>
|
||||
#include <drogon/HttpRequest.h>
|
||||
@ -642,7 +643,7 @@ void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequestImplPtr &req, std::fu
|
||||
{
|
||||
//Downloading files from the parent folder is forbidden.
|
||||
auto resp = HttpResponse::newHttpResponse();
|
||||
resp->setStatusCode(HttpResponse::k403Forbidden);
|
||||
resp->setStatusCode(k403Forbidden);
|
||||
callback(resp);
|
||||
return;
|
||||
}
|
||||
@ -670,7 +671,7 @@ void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequestImplPtr &req, std::fu
|
||||
{
|
||||
if (std::dynamic_pointer_cast<HttpResponseImpl>(cachedResp)->getHeaderBy("last-modified") == req->getHeaderBy("if-modified-since"))
|
||||
{
|
||||
resp->setStatusCode(HttpResponse::k304NotModified);
|
||||
resp->setStatusCode(k304NotModified);
|
||||
if (needSetJsessionid)
|
||||
{
|
||||
resp->addCookie("JSESSIONID", sessionId);
|
||||
@ -696,7 +697,7 @@ void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequestImplPtr &req, std::fu
|
||||
if (modiStr == timeStr && !modiStr.empty())
|
||||
{
|
||||
LOG_TRACE << "not Modified!";
|
||||
resp->setStatusCode(HttpResponse::k304NotModified);
|
||||
resp->setStatusCode(k304NotModified);
|
||||
if (needSetJsessionid)
|
||||
{
|
||||
resp->addCookie("JSESSIONID", sessionId);
|
||||
@ -798,7 +799,7 @@ void HttpAppFrameworkImpl::readSendFile(const std::string &filePath, const HttpR
|
||||
if (!infile)
|
||||
{
|
||||
|
||||
resp->setStatusCode(HttpResponse::k404NotFound);
|
||||
resp->setStatusCode(k404NotFound);
|
||||
resp->setCloseConnection(true);
|
||||
return;
|
||||
}
|
||||
@ -822,7 +823,7 @@ void HttpAppFrameworkImpl::readSendFile(const std::string &filePath, const HttpR
|
||||
resp->setBody(std::move(str));
|
||||
}
|
||||
|
||||
resp->setStatusCode(HttpResponse::k200OK);
|
||||
resp->setStatusCode(k200OK);
|
||||
|
||||
//cache the response for 5 seconds by default
|
||||
|
||||
|
@ -103,6 +103,13 @@ void HttpClientImpl::sendRequestInLoop(const drogon::HttpRequestPtr &req,
|
||||
const drogon::HttpReqCallback &callback)
|
||||
{
|
||||
_loop->assertInLoopThread();
|
||||
req->addHeader("Connection", "Keep-Alive");
|
||||
// req->addHeader("Accept", "*/*");
|
||||
if (!_domain.empty())
|
||||
{
|
||||
req->addHeader("Host", _domain);
|
||||
}
|
||||
req->addHeader("User-Agent", "DrogonClient");
|
||||
|
||||
if (!_tcpClient)
|
||||
{
|
||||
@ -230,7 +237,7 @@ void HttpClientImpl::onRecvMessage(const trantor::TcpConnectionPtr &connPtr, tra
|
||||
resp->parseJson();
|
||||
}
|
||||
|
||||
if (resp->getHeaderBy("content-encoding")=="gzip")
|
||||
if (resp->getHeaderBy("content-encoding") == "gzip")
|
||||
{
|
||||
resp->gunzip();
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ void HttpControllersRouter::route(const HttpRequestImplPtr &req,
|
||||
{
|
||||
//Invalid Http Method
|
||||
auto res = drogon::HttpResponse::newHttpResponse();
|
||||
res->setStatusCode(HttpResponse::k405MethodNotAllowed);
|
||||
res->setStatusCode(k405MethodNotAllowed);
|
||||
callback(res);
|
||||
return;
|
||||
}
|
||||
|
@ -13,14 +13,14 @@
|
||||
*/
|
||||
|
||||
#include "HttpRequestImpl.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace drogon;
|
||||
|
||||
void HttpRequestImpl::parseParameter()
|
||||
{
|
||||
const std::string &input = query();
|
||||
if(input.empty())
|
||||
if (input.empty())
|
||||
return;
|
||||
std::string type = getHeaderBy("content-type");
|
||||
std::transform(type.begin(), type.end(), type.begin(), tolower);
|
||||
@ -113,7 +113,7 @@ void HttpRequestImpl::appendToBuffer(MsgBuffer *output) const
|
||||
return;
|
||||
}
|
||||
|
||||
if (_path.size() != 0)
|
||||
if (!_path.empty())
|
||||
{
|
||||
output->append(_path);
|
||||
}
|
||||
@ -122,17 +122,31 @@ void HttpRequestImpl::appendToBuffer(MsgBuffer *output) const
|
||||
output->append("/");
|
||||
}
|
||||
|
||||
if (_parameters.size() != 0)
|
||||
std::string content;
|
||||
if (!_parameters.empty())
|
||||
{
|
||||
output->append("?");
|
||||
for (auto const &p : _parameters)
|
||||
{
|
||||
output->append(p.first);
|
||||
output->append("=");
|
||||
output->append(p.second);
|
||||
output->append("&");
|
||||
content.append(p.first);
|
||||
content.append("=");
|
||||
content.append(p.second);
|
||||
content.append("&");
|
||||
}
|
||||
content.resize(content.length() - 1);
|
||||
///TODO: URL code?
|
||||
if (_method == Get || _method == Delete)
|
||||
{
|
||||
output->append("?");
|
||||
output->append(content);
|
||||
content.clear();
|
||||
}
|
||||
else if (_contentType == CT_APPLICATION_JSON)
|
||||
{
|
||||
///Can't set parameters in content in this case
|
||||
LOG_ERROR << "You can't set parameters in the query string when the request content type is JSON and http method is POST or PUT";
|
||||
LOG_ERROR << "Please put these parameters in the path or the json string";
|
||||
content.clear();
|
||||
}
|
||||
output->unwrite(1);
|
||||
}
|
||||
|
||||
output->append(" ");
|
||||
@ -150,6 +164,20 @@ void HttpRequestImpl::appendToBuffer(MsgBuffer *output) const
|
||||
}
|
||||
output->append("\r\n");
|
||||
|
||||
assert(!(!content.empty() && !_content.empty()));
|
||||
if (!content.empty() || !_content.empty())
|
||||
{
|
||||
char buf[64];
|
||||
snprintf(buf, sizeof buf, "Content-Length: %lu\r\n", static_cast<long unsigned int>(content.length() + _content.length()));
|
||||
output->append(buf);
|
||||
if (_headers.find("Content-Type") == _headers.end())
|
||||
{
|
||||
output->append("Content-Type: ");
|
||||
output->append(webContentTypeToString(_contentType));
|
||||
output->append("\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
for (auto it = _headers.begin(); it != _headers.end(); ++it)
|
||||
{
|
||||
output->append(it->first);
|
||||
@ -172,9 +200,70 @@ void HttpRequestImpl::appendToBuffer(MsgBuffer *output) const
|
||||
}
|
||||
|
||||
output->append("\r\n");
|
||||
|
||||
//LOG_INFO<<"request(no body):"<<output->peek();
|
||||
output->append(_content);
|
||||
if (!content.empty())
|
||||
output->append(content);
|
||||
if (!_content.empty())
|
||||
output->append(_content);
|
||||
//LOG_INFO << output->peek();
|
||||
}
|
||||
|
||||
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)
|
||||
std::transform(field.begin(), field.end(), field.begin(), ::tolower);
|
||||
++colon;
|
||||
while (colon < end && isspace(*colon))
|
||||
{
|
||||
++colon;
|
||||
}
|
||||
std::string value(colon, end);
|
||||
while (!value.empty() && isspace(value[value.size() - 1]))
|
||||
{
|
||||
value.resize(value.size() - 1);
|
||||
}
|
||||
|
||||
if (field == "cookie")
|
||||
{
|
||||
LOG_TRACE << "cookies!!!:" << value;
|
||||
std::string::size_type pos;
|
||||
while ((pos = value.find(";")) != std::string::npos)
|
||||
{
|
||||
std::string coo = value.substr(0, pos);
|
||||
auto epos = coo.find("=");
|
||||
if (epos != std::string::npos)
|
||||
{
|
||||
std::string cookie_name = coo.substr(0, epos);
|
||||
std::string::size_type cpos = 0;
|
||||
while (cpos < cookie_name.length() && isspace(cookie_name[cpos]))
|
||||
cpos++;
|
||||
cookie_name = cookie_name.substr(cpos);
|
||||
std::string cookie_value = coo.substr(epos + 1);
|
||||
_cookies[std::move(cookie_name)] = std::move(cookie_value);
|
||||
}
|
||||
value = value.substr(pos + 1);
|
||||
}
|
||||
if (value.length() > 0)
|
||||
{
|
||||
std::string &coo = value;
|
||||
auto epos = coo.find("=");
|
||||
if (epos != std::string::npos)
|
||||
{
|
||||
std::string cookie_name = coo.substr(0, epos);
|
||||
std::string::size_type cpos = 0;
|
||||
while (cpos < cookie_name.length() && isspace(cookie_name[cpos]))
|
||||
cpos++;
|
||||
cookie_name = cookie_name.substr(cpos);
|
||||
std::string cookie_value = coo.substr(epos + 1);
|
||||
_cookies[std::move(cookie_name)] = std::move(cookie_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_headers[std::move(field)] = std::move(value);
|
||||
}
|
||||
}
|
||||
|
||||
HttpRequestPtr HttpRequest::newHttpRequest()
|
||||
@ -184,3 +273,16 @@ HttpRequestPtr HttpRequest::newHttpRequest()
|
||||
req->setVersion(drogon::HttpRequest::kHttp11);
|
||||
return req;
|
||||
}
|
||||
|
||||
HttpRequestPtr HttpRequest::newHttpJsonRequest(const Json::Value &data)
|
||||
{
|
||||
auto req = std::make_shared<HttpRequestImpl>();
|
||||
req->setMethod(drogon::Get);
|
||||
req->setVersion(drogon::HttpRequest::kHttp11);
|
||||
req->_contentType = CT_APPLICATION_JSON;
|
||||
Json::StreamWriterBuilder builder;
|
||||
builder["commentStyle"] = "None";
|
||||
builder["indentation"] = "";
|
||||
req->setContent(writeString(builder, data));
|
||||
return req;
|
||||
}
|
||||
|
@ -14,8 +14,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "HttpUtils.h"
|
||||
#include <drogon/utils/Utilities.h>
|
||||
#include <drogon/HttpRequest.h>
|
||||
#include <drogon/HttpResponse.h>
|
||||
|
||||
#include <trantor/utils/NonCopyable.h>
|
||||
#include <trantor/utils/Logger.h>
|
||||
@ -26,14 +28,18 @@
|
||||
#include <stdio.h>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
using std::string;
|
||||
using namespace trantor;
|
||||
|
||||
namespace drogon
|
||||
{
|
||||
|
||||
class HttpRequestImpl : public HttpRequest
|
||||
{
|
||||
public:
|
||||
friend class HttpRequestParser;
|
||||
|
||||
HttpRequestImpl()
|
||||
: _method(Invalid),
|
||||
_version(kUnknown),
|
||||
@ -50,7 +56,9 @@ class HttpRequestImpl : public HttpRequest
|
||||
{
|
||||
return _version;
|
||||
}
|
||||
|
||||
void parseParameter();
|
||||
|
||||
bool setMethod(const char *start, const char *end)
|
||||
{
|
||||
|
||||
@ -137,6 +145,7 @@ class HttpRequestImpl : public HttpRequest
|
||||
{
|
||||
_path = urlDecode(start, end);
|
||||
}
|
||||
|
||||
virtual void setPath(const std::string &path) override
|
||||
{
|
||||
_path = path;
|
||||
@ -146,6 +155,7 @@ class HttpRequestImpl : public HttpRequest
|
||||
{
|
||||
return _parameters;
|
||||
}
|
||||
|
||||
const std::string &path() const override
|
||||
{
|
||||
return _path;
|
||||
@ -155,6 +165,7 @@ class HttpRequestImpl : public HttpRequest
|
||||
{
|
||||
_query.assign(start, end);
|
||||
}
|
||||
|
||||
void setQuery(const std::string &query)
|
||||
{
|
||||
_query = query;
|
||||
@ -182,84 +193,33 @@ class HttpRequestImpl : public HttpRequest
|
||||
{
|
||||
return _peer;
|
||||
}
|
||||
|
||||
virtual const trantor::InetAddress &localAddr() const override
|
||||
{
|
||||
return _local;
|
||||
}
|
||||
|
||||
virtual const trantor::Date &receiveDate() const override
|
||||
{
|
||||
return _date;
|
||||
}
|
||||
|
||||
void setReceiveDate(const trantor::Date &date)
|
||||
{
|
||||
_date = date;
|
||||
}
|
||||
|
||||
void setPeerAddr(const trantor::InetAddress &peer)
|
||||
{
|
||||
_peer = peer;
|
||||
}
|
||||
|
||||
void setLocalAddr(const trantor::InetAddress &local)
|
||||
{
|
||||
_local = local;
|
||||
}
|
||||
|
||||
void 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)
|
||||
std::transform(field.begin(), field.end(), field.begin(), ::tolower);
|
||||
++colon;
|
||||
while (colon < end && isspace(*colon))
|
||||
{
|
||||
++colon;
|
||||
}
|
||||
std::string value(colon, end);
|
||||
while (!value.empty() && isspace(value[value.size() - 1]))
|
||||
{
|
||||
value.resize(value.size() - 1);
|
||||
}
|
||||
|
||||
if (field == "cookie")
|
||||
{
|
||||
LOG_TRACE << "cookies!!!:" << value;
|
||||
std::string::size_type pos;
|
||||
while ((pos = value.find(";")) != std::string::npos)
|
||||
{
|
||||
std::string coo = value.substr(0, pos);
|
||||
auto epos = coo.find("=");
|
||||
if (epos != std::string::npos)
|
||||
{
|
||||
std::string cookie_name = coo.substr(0, epos);
|
||||
std::string::size_type cpos = 0;
|
||||
while (cpos < cookie_name.length() && isspace(cookie_name[cpos]))
|
||||
cpos++;
|
||||
cookie_name = cookie_name.substr(cpos);
|
||||
std::string cookie_value = coo.substr(epos + 1);
|
||||
_cookies[std::move(cookie_name)] = std::move(cookie_value);
|
||||
}
|
||||
value = value.substr(pos + 1);
|
||||
}
|
||||
if (value.length() > 0)
|
||||
{
|
||||
std::string &coo = value;
|
||||
auto epos = coo.find("=");
|
||||
if (epos != std::string::npos)
|
||||
{
|
||||
std::string cookie_name = coo.substr(0, epos);
|
||||
std::string::size_type cpos = 0;
|
||||
while (cpos < cookie_name.length() && isspace(cookie_name[cpos]))
|
||||
cpos++;
|
||||
cookie_name = cookie_name.substr(cpos);
|
||||
std::string cookie_value = coo.substr(epos + 1);
|
||||
_cookies[std::move(cookie_name)] = std::move(cookie_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_headers[std::move(field)] = std::move(value);
|
||||
}
|
||||
}
|
||||
void addHeader(const char *start, const char *colon, const char *end);
|
||||
|
||||
const std::string &getHeader(const std::string &field, const std::string &defaultVal = std::string()) const override
|
||||
{
|
||||
@ -293,6 +253,7 @@ class HttpRequestImpl : public HttpRequest
|
||||
}
|
||||
return defaultVal;
|
||||
}
|
||||
|
||||
const std::unordered_map<std::string, std::string> &headers() const override
|
||||
{
|
||||
return _headers;
|
||||
@ -302,14 +263,17 @@ class HttpRequestImpl : public HttpRequest
|
||||
{
|
||||
return _cookies;
|
||||
}
|
||||
|
||||
virtual void setParameter(const std::string &key, const std::string &value) override
|
||||
{
|
||||
_parameters[key] = value;
|
||||
}
|
||||
|
||||
const std::string &getContent() const
|
||||
{
|
||||
return _content;
|
||||
}
|
||||
|
||||
void swap(HttpRequestImpl &that)
|
||||
{
|
||||
std::swap(_method, that._method);
|
||||
@ -334,10 +298,12 @@ class HttpRequestImpl : public HttpRequest
|
||||
{
|
||||
_content = content;
|
||||
}
|
||||
|
||||
virtual void addHeader(const std::string &key, const std::string &value) override
|
||||
{
|
||||
_headers[key] = value;
|
||||
}
|
||||
|
||||
void addCookie(const std::string &key, const std::string &value)
|
||||
{
|
||||
_cookies[key] = value;
|
||||
@ -360,7 +326,35 @@ class HttpRequestImpl : public HttpRequest
|
||||
return _jsonPtr;
|
||||
}
|
||||
|
||||
virtual void setContentTypeCode(ContentType type) override
|
||||
{
|
||||
_contentType = type;
|
||||
setContentType(webContentTypeToString(type));
|
||||
}
|
||||
|
||||
virtual void setContentTypeCodeAndCharacterSet(ContentType type, const std::string &charSet = "utf-8") override
|
||||
{
|
||||
_contentType = type;
|
||||
setContentType(webContentTypeAndCharsetToString(type, charSet));
|
||||
}
|
||||
|
||||
virtual ContentType getContentTypeCode() override
|
||||
{
|
||||
return _contentType;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
friend class HttpRequest;
|
||||
void setContentType(const std::string &contentType)
|
||||
{
|
||||
addHeader("Content-Type", contentType);
|
||||
}
|
||||
void setContentType(std::string &&contentType)
|
||||
{
|
||||
addHeader("Content-Type", std::move(contentType));
|
||||
}
|
||||
|
||||
HttpMethod _method;
|
||||
Version _version;
|
||||
std::string _path;
|
||||
@ -375,6 +369,7 @@ class HttpRequestImpl : public HttpRequest
|
||||
trantor::InetAddress _peer;
|
||||
trantor::InetAddress _local;
|
||||
trantor::Date _date;
|
||||
ContentType _contentType = CT_TEXT_PLAIN;
|
||||
|
||||
protected:
|
||||
std::string _content;
|
||||
@ -382,4 +377,5 @@ class HttpRequestImpl : public HttpRequest
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<HttpRequestImpl> HttpRequestImplPtr;
|
||||
|
||||
} // namespace drogon
|
||||
|
@ -12,6 +12,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <drogon/HttpTypes.h>
|
||||
#include <trantor/utils/MsgBuffer.h>
|
||||
#include <trantor/utils/Logger.h>
|
||||
#include "HttpRequestParser.h"
|
||||
@ -130,7 +131,7 @@ bool HttpRequestParser::parseRequest(MsgBuffer *buf)
|
||||
if (connPtr)
|
||||
{
|
||||
auto resp = HttpResponse::newHttpResponse();
|
||||
resp->setStatusCode(HttpResponse::k100Continue);
|
||||
resp->setStatusCode(k100Continue);
|
||||
auto httpString = std::dynamic_pointer_cast<HttpResponseImpl>(resp)->renderToString();
|
||||
connPtr->send(httpString);
|
||||
}
|
||||
@ -142,7 +143,7 @@ bool HttpRequestParser::parseRequest(MsgBuffer *buf)
|
||||
if (connPtr)
|
||||
{
|
||||
auto resp = HttpResponse::newHttpResponse();
|
||||
resp->setStatusCode(HttpResponse::k417ExpectationFailed);
|
||||
resp->setStatusCode(k417ExpectationFailed);
|
||||
MsgBuffer buffer;
|
||||
auto httpString = std::dynamic_pointer_cast<HttpResponseImpl>(resp)->renderToString();
|
||||
connPtr->send(httpString);
|
||||
|
@ -28,7 +28,7 @@ using namespace drogon;
|
||||
HttpResponsePtr HttpResponse::newHttpResponse()
|
||||
{
|
||||
auto res = std::make_shared<HttpResponseImpl>();
|
||||
res->setStatusCode(HttpResponse::k200OK);
|
||||
res->setStatusCode(k200OK);
|
||||
res->setContentTypeCode(CT_TEXT_HTML);
|
||||
return res;
|
||||
}
|
||||
@ -36,7 +36,7 @@ HttpResponsePtr HttpResponse::newHttpResponse()
|
||||
HttpResponsePtr HttpResponse::newHttpJsonResponse(const Json::Value &data)
|
||||
{
|
||||
auto res = std::make_shared<HttpResponseImpl>();
|
||||
res->setStatusCode(HttpResponse::k200OK);
|
||||
res->setStatusCode(k200OK);
|
||||
res->setContentTypeCode(CT_APPLICATION_JSON);
|
||||
Json::StreamWriterBuilder builder;
|
||||
builder["commentStyle"] = "None";
|
||||
@ -49,7 +49,7 @@ HttpResponsePtr HttpResponse::newNotFoundResponse()
|
||||
HttpViewData data;
|
||||
data.insert("version", getVersion());
|
||||
auto res = HttpResponse::newHttpViewResponse("NotFound", data);
|
||||
res->setStatusCode(HttpResponse::k404NotFound);
|
||||
res->setStatusCode(k404NotFound);
|
||||
//res->setCloseConnection(true);
|
||||
|
||||
return res;
|
||||
@ -57,7 +57,7 @@ HttpResponsePtr HttpResponse::newNotFoundResponse()
|
||||
HttpResponsePtr HttpResponse::newLocationRedirectResponse(const std::string &path)
|
||||
{
|
||||
auto res = std::make_shared<HttpResponseImpl>();
|
||||
res->setStatusCode(HttpResponse::k302Found);
|
||||
res->setStatusCode(k302Found);
|
||||
res->redirect(path.c_str());
|
||||
return res;
|
||||
}
|
||||
@ -66,144 +66,6 @@ HttpResponsePtr HttpResponse::newHttpViewResponse(const std::string &viewName, c
|
||||
{
|
||||
return HttpViewBase::genHttpResponse(viewName, data);
|
||||
}
|
||||
const std::string HttpResponseImpl::web_content_type_and_charset_to_string(uint8_t contenttype, const std::string &charSet)
|
||||
{
|
||||
switch (contenttype)
|
||||
{
|
||||
case CT_TEXT_HTML:
|
||||
return "text/html; charset=" + charSet;
|
||||
|
||||
case CT_APPLICATION_XML:
|
||||
return "application/xml; charset=" + charSet;
|
||||
|
||||
case CT_APPLICATION_JSON:
|
||||
return "application/json; charset=" + charSet;
|
||||
|
||||
case CT_APPLICATION_X_JAVASCRIPT:
|
||||
return "application/x-javascript; charset=" + charSet;
|
||||
|
||||
case CT_TEXT_CSS:
|
||||
return "text/css; charset=" + charSet;
|
||||
|
||||
case CT_TEXT_XML:
|
||||
return "text/xml; charset=" + charSet;
|
||||
|
||||
case CT_TEXT_XSL:
|
||||
return "text/xsl; charset=" + charSet;
|
||||
|
||||
case CT_APPLICATION_OCTET_STREAM:
|
||||
return "application/octet-stream";
|
||||
|
||||
case CT_IMAGE_SVG_XML:
|
||||
return "image/svg+xml";
|
||||
|
||||
case CT_APPLICATION_X_FONT_TRUETYPE:
|
||||
return "application/x-font-truetype";
|
||||
|
||||
case CT_APPLICATION_X_FONT_OPENTYPE:
|
||||
return "application/x-font-opentype";
|
||||
|
||||
case CT_APPLICATION_FONT_WOFF:
|
||||
return "application/font-woff";
|
||||
|
||||
case CT_APPLICATION_FONT_WOFF2:
|
||||
return "application/font-woff2";
|
||||
|
||||
case CT_APPLICATION_VND_MS_FONTOBJ:
|
||||
return "application/vnd.ms-fontobject";
|
||||
|
||||
case CT_IMAGE_PNG:
|
||||
return "image/png";
|
||||
|
||||
case CT_IMAGE_JPG:
|
||||
return "image/jpeg";
|
||||
|
||||
case CT_IMAGE_GIF:
|
||||
return "image/gif";
|
||||
|
||||
case CT_IMAGE_XICON:
|
||||
return "image/x-icon";
|
||||
|
||||
case CT_IMAGE_BMP:
|
||||
return "image/bmp";
|
||||
|
||||
case CT_IMAGE_ICNS:
|
||||
return "image/icns";
|
||||
|
||||
default:
|
||||
case CT_TEXT_PLAIN:
|
||||
return "text/plain; charset=" + charSet;
|
||||
}
|
||||
}
|
||||
std::string HttpResponseImpl::web_content_type_to_string(uint8_t contenttype)
|
||||
{
|
||||
switch (contenttype)
|
||||
{
|
||||
case CT_TEXT_HTML:
|
||||
return "text/html; charset=utf-8";
|
||||
|
||||
case CT_APPLICATION_XML:
|
||||
return "application/xml; charset=utf-8";
|
||||
|
||||
case CT_APPLICATION_JSON:
|
||||
return "application/json; charset=utf-8";
|
||||
|
||||
case CT_APPLICATION_X_JAVASCRIPT:
|
||||
return "application/x-javascript; charset=utf-8";
|
||||
|
||||
case CT_TEXT_CSS:
|
||||
return "text/css; charset=utf-8";
|
||||
|
||||
case CT_TEXT_XML:
|
||||
return "text/xml; charset=utf-8";
|
||||
|
||||
case CT_TEXT_XSL:
|
||||
return "text/xsl; charset=utf-8";
|
||||
|
||||
case CT_APPLICATION_OCTET_STREAM:
|
||||
return "application/octet-stream";
|
||||
|
||||
case CT_IMAGE_SVG_XML:
|
||||
return "image/svg+xml";
|
||||
|
||||
case CT_APPLICATION_X_FONT_TRUETYPE:
|
||||
return "application/x-font-truetype";
|
||||
|
||||
case CT_APPLICATION_X_FONT_OPENTYPE:
|
||||
return "application/x-font-opentype";
|
||||
|
||||
case CT_APPLICATION_FONT_WOFF:
|
||||
return "application/font-woff";
|
||||
|
||||
case CT_APPLICATION_FONT_WOFF2:
|
||||
return "application/font-woff2";
|
||||
|
||||
case CT_APPLICATION_VND_MS_FONTOBJ:
|
||||
return "application/vnd.ms-fontobject";
|
||||
|
||||
case CT_IMAGE_PNG:
|
||||
return "image/png";
|
||||
|
||||
case CT_IMAGE_JPG:
|
||||
return "image/jpeg";
|
||||
|
||||
case CT_IMAGE_GIF:
|
||||
return "image/gif";
|
||||
|
||||
case CT_IMAGE_XICON:
|
||||
return "image/x-icon";
|
||||
|
||||
case CT_IMAGE_BMP:
|
||||
return "image/bmp";
|
||||
|
||||
case CT_IMAGE_ICNS:
|
||||
return "image/icns";
|
||||
|
||||
default:
|
||||
case CT_TEXT_PLAIN:
|
||||
return "text/plain; charset=utf-8";
|
||||
}
|
||||
}
|
||||
|
||||
std::string HttpResponseImpl::web_response_code_to_string(int code)
|
||||
{
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "HttpUtils.h"
|
||||
#include <drogon/HttpResponse.h>
|
||||
#include <trantor/utils/MsgBuffer.h>
|
||||
#include <trantor/net/InetAddress.h>
|
||||
@ -79,19 +80,19 @@ class HttpResponseImpl : public HttpResponse
|
||||
return _closeConnection;
|
||||
}
|
||||
|
||||
virtual void setContentTypeCode(uint8_t type) override
|
||||
virtual void setContentTypeCode(ContentType type) override
|
||||
{
|
||||
_contentType = type;
|
||||
setContentType(web_content_type_to_string(type));
|
||||
setContentType(webContentTypeToString(type));
|
||||
}
|
||||
|
||||
virtual void setContentTypeCodeAndCharacterSet(uint8_t type, const std::string &charSet = "utf-8") override
|
||||
virtual void setContentTypeCodeAndCharacterSet(ContentType type, const std::string &charSet = "utf-8") override
|
||||
{
|
||||
_contentType = type;
|
||||
setContentType(web_content_type_and_charset_to_string(type, charSet));
|
||||
setContentType(webContentTypeAndCharsetToString(type, charSet));
|
||||
}
|
||||
|
||||
virtual uint8_t getContentTypeCode() override
|
||||
virtual ContentType getContentTypeCode() override
|
||||
{
|
||||
return _contentType;
|
||||
}
|
||||
@ -360,12 +361,8 @@ class HttpResponseImpl : public HttpResponse
|
||||
}
|
||||
|
||||
protected:
|
||||
static std::string web_content_type_to_string(uint8_t contenttype);
|
||||
static const std::string web_content_type_and_charset_to_string(uint8_t contenttype,
|
||||
const std::string &charSet);
|
||||
|
||||
static std::string web_response_code_to_string(int code);
|
||||
|
||||
void makeHeaderString(const std::shared_ptr<std::string> &headerStringPtr) const;
|
||||
|
||||
private:
|
||||
@ -381,7 +378,7 @@ class HttpResponseImpl : public HttpResponse
|
||||
size_t _currentChunkLength;
|
||||
std::shared_ptr<std::string> _bodyPtr;
|
||||
|
||||
uint8_t _contentType = CT_TEXT_HTML;
|
||||
ContentType _contentType = CT_TEXT_HTML;
|
||||
|
||||
ssize_t _expriedTime = -1;
|
||||
std::string _sendfileName;
|
||||
|
@ -33,11 +33,11 @@ bool HttpResponseParser::processResponseLine(const char *begin, const char *end)
|
||||
LOG_TRACE << *(space - 1);
|
||||
if (*(space - 1) == '1')
|
||||
{
|
||||
_response->setVersion(HttpResponse::kHttp11);
|
||||
_response->setVersion(kHttp11);
|
||||
}
|
||||
else if (*(space - 1) == '0')
|
||||
{
|
||||
_response->setVersion(HttpResponse::kHttp10);
|
||||
_response->setVersion(kHttp10);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -53,7 +53,7 @@ bool HttpResponseParser::processResponseLine(const char *begin, const char *end)
|
||||
std::string status_message(space + 1, end - space - 1);
|
||||
LOG_TRACE << status_code << " " << status_message;
|
||||
auto code = atoi(status_code.c_str());
|
||||
_response->setStatusCode(HttpResponse::HttpStatusCode(code), status_message);
|
||||
_response->setStatusCode(HttpStatusCode(code), status_message);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ void HttpServer::onMessage(const TcpConnectionPtr &conn,
|
||||
auto wsConn = std::make_shared<WebSocketConnectionImpl>(conn);
|
||||
_newWebsocketCallback(requestParser->request(),
|
||||
[=](const HttpResponsePtr &resp) mutable {
|
||||
if (resp->statusCode() == HttpResponse::k101SwitchingProtocols)
|
||||
if (resp->statusCode() == k101SwitchingProtocols)
|
||||
{
|
||||
requestParser->setWebsockConnection(wsConn);
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ void HttpSimpleControllersRouter::route(const HttpRequestImplPtr &req,
|
||||
{
|
||||
//Invalid Http Method
|
||||
auto res = drogon::HttpResponse::newHttpResponse();
|
||||
res->setStatusCode(HttpResponse::k405MethodNotAllowed);
|
||||
res->setStatusCode(k405MethodNotAllowed);
|
||||
callback(res);
|
||||
return;
|
||||
}
|
||||
|
160
lib/src/HttpUtils.cc
Normal file
160
lib/src/HttpUtils.cc
Normal file
@ -0,0 +1,160 @@
|
||||
/**
|
||||
*
|
||||
* HttpUtils.h
|
||||
* An Tao
|
||||
*
|
||||
* Copyright 2018, An Tao. All rights reserved.
|
||||
* https://github.com/an-tao/drogon
|
||||
* Use of this source code is governed by a MIT license
|
||||
* that can be found in the License file.
|
||||
*
|
||||
* Drogon
|
||||
*
|
||||
*/
|
||||
|
||||
#include "HttpUtils.h"
|
||||
|
||||
namespace drogon
|
||||
{
|
||||
|
||||
std::string webContentTypeAndCharsetToString(ContentType contenttype, const std::string &charSet)
|
||||
{
|
||||
switch (contenttype)
|
||||
{
|
||||
case CT_TEXT_HTML:
|
||||
return "text/html; charset=" + charSet;
|
||||
|
||||
case CT_APPLICATION_XML:
|
||||
return "application/xml; charset=" + charSet;
|
||||
|
||||
case CT_APPLICATION_JSON:
|
||||
return "application/json; charset=" + charSet;
|
||||
|
||||
case CT_APPLICATION_X_JAVASCRIPT:
|
||||
return "application/x-javascript; charset=" + charSet;
|
||||
|
||||
case CT_TEXT_CSS:
|
||||
return "text/css; charset=" + charSet;
|
||||
|
||||
case CT_TEXT_XML:
|
||||
return "text/xml; charset=" + charSet;
|
||||
|
||||
case CT_TEXT_XSL:
|
||||
return "text/xsl; charset=" + charSet;
|
||||
|
||||
case CT_APPLICATION_OCTET_STREAM:
|
||||
return "application/octet-stream";
|
||||
|
||||
case CT_IMAGE_SVG_XML:
|
||||
return "image/svg+xml";
|
||||
|
||||
case CT_APPLICATION_X_FONT_TRUETYPE:
|
||||
return "application/x-font-truetype";
|
||||
|
||||
case CT_APPLICATION_X_FONT_OPENTYPE:
|
||||
return "application/x-font-opentype";
|
||||
|
||||
case CT_APPLICATION_FONT_WOFF:
|
||||
return "application/font-woff";
|
||||
|
||||
case CT_APPLICATION_FONT_WOFF2:
|
||||
return "application/font-woff2";
|
||||
|
||||
case CT_APPLICATION_VND_MS_FONTOBJ:
|
||||
return "application/vnd.ms-fontobject";
|
||||
|
||||
case CT_IMAGE_PNG:
|
||||
return "image/png";
|
||||
|
||||
case CT_IMAGE_JPG:
|
||||
return "image/jpeg";
|
||||
|
||||
case CT_IMAGE_GIF:
|
||||
return "image/gif";
|
||||
|
||||
case CT_IMAGE_XICON:
|
||||
return "image/x-icon";
|
||||
|
||||
case CT_IMAGE_BMP:
|
||||
return "image/bmp";
|
||||
|
||||
case CT_IMAGE_ICNS:
|
||||
return "image/icns";
|
||||
|
||||
default:
|
||||
case CT_TEXT_PLAIN:
|
||||
return "text/plain; charset=" + charSet;
|
||||
}
|
||||
}
|
||||
|
||||
std::string webContentTypeToString(ContentType contenttype)
|
||||
{
|
||||
switch (contenttype)
|
||||
{
|
||||
case CT_TEXT_HTML:
|
||||
return "text/html; charset=utf-8";
|
||||
|
||||
case CT_APPLICATION_XML:
|
||||
return "application/xml; charset=utf-8";
|
||||
|
||||
case CT_APPLICATION_JSON:
|
||||
return "application/json; charset=utf-8";
|
||||
|
||||
case CT_APPLICATION_X_JAVASCRIPT:
|
||||
return "application/x-javascript; charset=utf-8";
|
||||
|
||||
case CT_TEXT_CSS:
|
||||
return "text/css; charset=utf-8";
|
||||
|
||||
case CT_TEXT_XML:
|
||||
return "text/xml; charset=utf-8";
|
||||
|
||||
case CT_TEXT_XSL:
|
||||
return "text/xsl; charset=utf-8";
|
||||
|
||||
case CT_APPLICATION_OCTET_STREAM:
|
||||
return "application/octet-stream";
|
||||
|
||||
case CT_IMAGE_SVG_XML:
|
||||
return "image/svg+xml";
|
||||
|
||||
case CT_APPLICATION_X_FONT_TRUETYPE:
|
||||
return "application/x-font-truetype";
|
||||
|
||||
case CT_APPLICATION_X_FONT_OPENTYPE:
|
||||
return "application/x-font-opentype";
|
||||
|
||||
case CT_APPLICATION_FONT_WOFF:
|
||||
return "application/font-woff";
|
||||
|
||||
case CT_APPLICATION_FONT_WOFF2:
|
||||
return "application/font-woff2";
|
||||
|
||||
case CT_APPLICATION_VND_MS_FONTOBJ:
|
||||
return "application/vnd.ms-fontobject";
|
||||
|
||||
case CT_IMAGE_PNG:
|
||||
return "image/png";
|
||||
|
||||
case CT_IMAGE_JPG:
|
||||
return "image/jpeg";
|
||||
|
||||
case CT_IMAGE_GIF:
|
||||
return "image/gif";
|
||||
|
||||
case CT_IMAGE_XICON:
|
||||
return "image/x-icon";
|
||||
|
||||
case CT_IMAGE_BMP:
|
||||
return "image/bmp";
|
||||
|
||||
case CT_IMAGE_ICNS:
|
||||
return "image/icns";
|
||||
|
||||
default:
|
||||
case CT_TEXT_PLAIN:
|
||||
return "text/plain; charset=utf-8";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
25
lib/src/HttpUtils.h
Normal file
25
lib/src/HttpUtils.h
Normal file
@ -0,0 +1,25 @@
|
||||
/**
|
||||
*
|
||||
* HttpUtils.h
|
||||
* An Tao
|
||||
*
|
||||
* Copyright 2018, An Tao. All rights reserved.
|
||||
* https://github.com/an-tao/drogon
|
||||
* Use of this source code is governed by a MIT license
|
||||
* that can be found in the License file.
|
||||
*
|
||||
* Drogon
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <drogon/HttpTypes.h>
|
||||
|
||||
namespace drogon
|
||||
{
|
||||
|
||||
std::string webContentTypeToString(ContentType contenttype);
|
||||
std::string webContentTypeAndCharsetToString(ContentType contenttype, const std::string &charSet);
|
||||
|
||||
} // namespace drogon
|
@ -35,7 +35,7 @@ HttpResponsePtr HttpViewBase::genHttpResponse(std::string viewName, const HttpVi
|
||||
if (templ)
|
||||
{
|
||||
auto res = HttpResponse::newHttpResponse();
|
||||
res->setStatusCode(HttpResponse::k200OK);
|
||||
res->setStatusCode(k200OK);
|
||||
res->setContentTypeCode(CT_TEXT_HTML);
|
||||
res->setBody(templ->genText(data));
|
||||
return res;
|
||||
|
@ -90,7 +90,7 @@ void WebsocketControllersRouter::doControllerHandler(const WebSocketControllerBa
|
||||
SHA1(reinterpret_cast<const unsigned char *>(wsKey.c_str()), wsKey.length(), accKey);
|
||||
auto base64Key = base64Encode(accKey, SHA_DIGEST_LENGTH);
|
||||
auto resp = HttpResponse::newHttpResponse();
|
||||
resp->setStatusCode(HttpResponse::k101SwitchingProtocols);
|
||||
resp->setStatusCode(k101SwitchingProtocols);
|
||||
resp->addHeader("Upgrade", "websocket");
|
||||
resp->addHeader("Connection", "Upgrade");
|
||||
resp->addHeader("Sec-WebSocket-Accept", base64Key);
|
||||
|
Loading…
Reference in New Issue
Block a user