Modify HttpAppFrameworkImpl

This commit is contained in:
antao 2018-10-11 19:11:49 +08:00
parent d5202f11fa
commit 5317982625
3 changed files with 117 additions and 70 deletions

View File

@ -770,9 +770,21 @@ void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequestPtr& req,const std::f
if(controller) {
if(responsePtr&&!needSetJsessionid)
if(responsePtr)
{
callback(responsePtr);
//use cached response!
LOG_TRACE<<"Use cached response";
if(!needSetJsessionid)
callback(responsePtr);
else
{
auto newResp=std::make_shared<HttpResponseImpl>
(*std::dynamic_pointer_cast<HttpResponseImpl>(responsePtr));
newResp->addCookie("JSESSIONID",session_id);
newResp->setExpiredTime(-1);
callback(newResp);
}
return;
}
else
{
@ -780,9 +792,14 @@ void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequestPtr& req,const std::f
if(needSetJsessionid)
resp->addCookie("JSESSIONID",session_id);
callback(resp);
if(resp->expiredTime()>=0&&!needSetJsessionid)
if(resp->expiredTime()>=0)
{
//cache the response;
if(needSetJsessionid)
{
resp->removeCookie("JSESSIONID");
std::dynamic_pointer_cast<HttpResponseImpl>(resp)->makeHeaderString();
}
std::lock_guard<std::mutex> guard(_simpCtrlMap[pathLower]._mutex);
_responseCacheMap->insert(pathLower,resp,resp->expiredTime());
_simpCtrlMap[pathLower].responsePtr=resp;
@ -818,21 +835,29 @@ void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequestPtr& req,const std::f
doFilters(filters,req,callback,needSetJsessionid,session_id,[=](){
auto &binder=_apiCtrlVector[ctlIndex];
if(!needSetJsessionid)
HttpResponsePtr responsePtr;
{
HttpResponsePtr responsePtr;
{
std::lock_guard<std::mutex> guard(*(binder.binderMtx));
responsePtr=binder.responsePtr.lock();
}
if(responsePtr)
{
//use cached response!
LOG_TRACE<<"Use cached response";
callback(responsePtr);
return;
}
std::lock_guard<std::mutex> guard(*(binder.binderMtx));
responsePtr=binder.responsePtr.lock();
}
if(responsePtr)
{
//use cached response!
LOG_TRACE<<"Use cached response";
if(!needSetJsessionid)
callback(responsePtr);
else
{
auto newResp=std::make_shared<HttpResponseImpl>
(*std::dynamic_pointer_cast<HttpResponseImpl>(responsePtr));
newResp->addCookie("JSESSIONID",session_id);
newResp->setExpiredTime(-1);
callback(newResp);
}
return;
}
std::vector<std::string> params(binder.parameterPlaces.size());
std::smatch r;
if(std::regex_match(req->path(),r,std::regex(binder.pathParameterPattern)))
@ -873,9 +898,14 @@ void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequestPtr& req,const std::f
if(needSetJsessionid)
resp->addCookie("JSESSIONID",session_id);
callback(resp);
if(resp->expiredTime()>=0&&!needSetJsessionid)
if(resp->expiredTime()>=0)
{
//cache the response;
if(needSetJsessionid)
{
resp->removeCookie("JSESSIONID");
std::dynamic_pointer_cast<HttpResponseImpl>(resp)->makeHeaderString();
}
std::lock_guard<std::mutex> guard(*(_apiCtrlVector[ctlIndex].binderMtx));
_responseCacheMap->insert(_apiCtrlVector[ctlIndex].pathParameterPattern,resp,resp->expiredTime());
_apiCtrlVector[ctlIndex].responsePtr=resp;

View File

@ -312,62 +312,72 @@ std::string HttpResponseImpl::web_response_code_to_string(int code)
return "Undefined Error";
}
}
void HttpResponseImpl::makeHeaderString(MsgBuffer* output) const
{
char buf[64];
snprintf(buf, sizeof buf, "HTTP/1.1 %d ", _statusCode);
output->append(buf);
output->append(_statusMessage);
output->append("\r\n");
if (_sendfileName.empty()) {
snprintf(buf, sizeof buf, "Content-Length: %lu\r\n", _body.size());
} else {
struct stat filestat;
if (stat(_sendfileName.c_str(), &filestat) < 0) {
LOG_SYSERR << _sendfileName << " stat error";
return;
}
#ifdef __linux__
snprintf(buf, sizeof buf, "Content-Length: %ld\r\n",filestat.st_size);
#else
snprintf(buf, sizeof buf, "Content-Length: %lld\r\n", filestat.st_size);
#endif
}
output->append(buf);
if (_headers.find("Connection") == _headers.end()) {
if (_closeConnection) {
output->append("Connection: close\r\n");
} else {
//output->append("Connection: Keep-Alive\r\n");
}
}
for (auto it = _headers.begin();
it != _headers.end();
++it) {
output->append(it->first);
output->append(": ");
output->append(it->second);
output->append("\r\n");
}
output->append("Server: drogon/");
output->append(drogon::getVersion());
output->append("\r\n");
if(_cookies.size() > 0) {
for(auto it = _cookies.begin(); it != _cookies.end(); it++) {
output->append(it->second.cookieString());
}
}
if(_expriedTime>=0)
_fullHeaderString=std::string(output->peek(),output->readableBytes());
}
void HttpResponseImpl::makeHeaderString() const
{
assert(_expriedTime>=0);
MsgBuffer buffer;
makeHeaderString(&buffer);
}
void HttpResponseImpl::appendToBuffer(MsgBuffer* output) const {
if(_fullHeaderString.empty())
{
char buf[64];
snprintf(buf, sizeof buf, "HTTP/1.1 %d ", _statusCode);
output->append(buf);
output->append(_statusMessage);
output->append("\r\n");
if (_sendfileName.empty()) {
snprintf(buf, sizeof buf, "Content-Length: %lu\r\n", _body.size());
} else {
struct stat filestat;
if (stat(_sendfileName.c_str(), &filestat) < 0) {
LOG_SYSERR << _sendfileName << " stat error";
return;
}
#ifdef __linux__
snprintf(buf, sizeof buf, "Content-Length: %ld\r\n",filestat.st_size);
#else
snprintf(buf, sizeof buf, "Content-Length: %lld\r\n", filestat.st_size);
#endif
}
output->append(buf);
if (_headers.find("Connection") == _headers.end()) {
if (_closeConnection) {
output->append("Connection: close\r\n");
} else {
//output->append("Connection: Keep-Alive\r\n");
}
}
for (auto it = _headers.begin();
it != _headers.end();
++it) {
output->append(it->first);
output->append(": ");
output->append(it->second);
output->append("\r\n");
}
output->append("Server: drogon/");
output->append(drogon::getVersion());
output->append("\r\n");
if(_cookies.size() > 0) {
for(auto it = _cookies.begin(); it != _cookies.end(); it++) {
output->append(it->second.cookieString());
}
}
if(_expriedTime>=0)
_fullHeaderString=std::string(output->peek(),output->readableBytes());
makeHeaderString(output);
}
else
{

View File

@ -186,16 +186,19 @@ namespace drogon
virtual void addCookie(const std::string& key, const std::string& value) override
{
_cookies.insert(std::make_pair(key,Cookie(key,value)));
_fullHeaderString.clear();
}
virtual void addCookie(const Cookie &cookie) override
{
_cookies.insert(std::make_pair(cookie.key(),cookie));
_fullHeaderString.clear();
}
virtual void removeCookie(const std::string& key) override
{
_cookies.erase(key);
_fullHeaderString.clear();
}
virtual void setBody(const std::string& body) override
@ -218,6 +221,7 @@ namespace drogon
_statusCode = kUnknown;
_v = kHttp11;
_statusMessage.clear();
_fullHeaderString.clear();
_headers.clear();
_cookies.clear();
_body.clear();
@ -286,6 +290,7 @@ namespace drogon
void setSendfile(const std::string &filename){
_sendfileName=filename;
}
void makeHeaderString() const;
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,
@ -293,6 +298,8 @@ namespace drogon
static std::string web_response_code_to_string(int code);
void makeHeaderString(MsgBuffer* output) const;
private:
std::map<std::string, std::string> _headers;
std::map<std::string, Cookie> _cookies;