2018-05-14 16:40:03 +08:00
|
|
|
// Copyright 2010, Shuo Chen. All rights reserved.
|
|
|
|
// http://code.google.com/p/muduo/
|
|
|
|
//
|
|
|
|
// Use of this source code is governed by a BSD-style license
|
|
|
|
// that can be found in the License file.
|
|
|
|
|
|
|
|
// Author: Shuo Chen (chenshuo at chenshuo dot com)
|
|
|
|
//
|
|
|
|
// This is a public header file, it must only include public header files.
|
|
|
|
|
|
|
|
|
|
|
|
//taken from muduo and modified
|
2018-05-31 17:00:31 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @file
|
|
|
|
* @author An Tao
|
|
|
|
* @section LICENSE
|
|
|
|
*
|
|
|
|
* Copyright 2018, An Tao. All rights reserved.
|
|
|
|
* Use of this source code is governed by a MIT license
|
|
|
|
* that can be found in the License file.
|
|
|
|
*
|
|
|
|
* @section DESCRIPTION
|
|
|
|
*
|
|
|
|
*/
|
2018-05-14 16:40:03 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <drogon/HttpResponse.h>
|
|
|
|
#include <trantor/utils/MsgBuffer.h>
|
|
|
|
#include <map>
|
|
|
|
|
|
|
|
#include <string>
|
|
|
|
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
|
|
|
|
#include <trantor/utils/MsgBuffer.h>
|
|
|
|
using namespace trantor;
|
|
|
|
namespace drogon
|
|
|
|
{
|
|
|
|
class HttpResponseImpl:public HttpResponse
|
|
|
|
{
|
|
|
|
friend class HttpContext;
|
|
|
|
public:
|
|
|
|
|
|
|
|
explicit HttpResponseImpl()
|
2018-06-21 15:39:11 +08:00
|
|
|
: _statusCode(kUnknown),
|
|
|
|
_closeConnection(false),
|
|
|
|
_left_body_length(0),
|
|
|
|
_current_chunk_length(0)
|
2018-05-14 16:40:03 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void setStatusCode(HttpStatusCode code) override
|
|
|
|
{
|
2018-06-21 15:39:11 +08:00
|
|
|
_statusCode = code;
|
2018-05-14 16:40:03 +08:00
|
|
|
setStatusMessage(web_response_code_to_string(code));
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void setStatusCode(HttpStatusCode code, const std::string& status_message) override
|
|
|
|
{
|
2018-06-21 15:39:11 +08:00
|
|
|
_statusCode = code;
|
2018-05-14 16:40:03 +08:00
|
|
|
setStatusMessage(status_message);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void setVersion(const Version v) override
|
|
|
|
{
|
2018-06-21 15:39:11 +08:00
|
|
|
_v = v;
|
2018-05-14 16:40:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
virtual void setCloseConnection(bool on) override
|
|
|
|
{
|
2018-06-21 15:39:11 +08:00
|
|
|
_closeConnection = on;
|
2018-05-14 16:40:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
virtual bool closeConnection() const override
|
|
|
|
{
|
2018-06-21 15:39:11 +08:00
|
|
|
return _closeConnection;
|
2018-05-14 16:40:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
virtual void setContentTypeCode(uint8_t type) override
|
|
|
|
{
|
2018-06-21 15:39:11 +08:00
|
|
|
_contentType=type;
|
2018-05-14 16:40:03 +08:00
|
|
|
setContentType(web_content_type_to_string(type));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
virtual std::string getHeader(const std::string& key) override
|
|
|
|
{
|
2018-06-21 15:39:11 +08:00
|
|
|
if(_headers.find(key) == _headers.end())
|
2018-05-14 16:40:03 +08:00
|
|
|
{
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-06-21 15:39:11 +08:00
|
|
|
return _headers[key];
|
2018-05-14 16:40:03 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
virtual void addHeader(const std::string& key, const std::string& value) override
|
|
|
|
{
|
2018-06-21 15:39:11 +08:00
|
|
|
_headers[key] = value;
|
2018-05-14 16:40:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
virtual void addHeader(const char* start, const char* colon, const char* end) override
|
|
|
|
{
|
|
|
|
std::string field(start, colon);
|
|
|
|
++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);
|
|
|
|
}
|
2018-06-21 15:39:11 +08:00
|
|
|
_headers[field] = value;
|
2018-05-14 16:40:03 +08:00
|
|
|
transform(field.begin(), field.end(), field.begin(), ::tolower);
|
|
|
|
if(field == "cookie") {
|
|
|
|
//LOG_INFO<<"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;
|
2018-06-01 14:07:34 +08:00
|
|
|
while(cpos<cookie_name.length()&&isspace(cookie_name[cpos]))
|
2018-05-14 16:40:03 +08:00
|
|
|
cpos++;
|
|
|
|
cookie_name=cookie_name.substr(cpos);
|
|
|
|
std::string cookie_value = coo.substr(epos + 1);
|
2018-06-21 15:39:11 +08:00
|
|
|
_cookies.insert(std::make_pair(cookie_name,Cookie(cookie_name,cookie_value)));
|
2018-05-14 16:40:03 +08:00
|
|
|
}
|
|
|
|
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;
|
2018-06-01 14:07:34 +08:00
|
|
|
while(cpos<cookie_name.length()&&isspace(cookie_name[cpos]))
|
2018-05-14 16:40:03 +08:00
|
|
|
cpos++;
|
|
|
|
cookie_name=cookie_name.substr(cpos);
|
|
|
|
std::string cookie_value = coo.substr(epos + 1);
|
2018-06-21 15:39:11 +08:00
|
|
|
_cookies.insert(std::make_pair(cookie_name,Cookie(cookie_name,cookie_value)));
|
2018-05-14 16:40:03 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void addCookie(const std::string& key, const std::string& value) override
|
|
|
|
{
|
2018-06-21 15:39:11 +08:00
|
|
|
_cookies.insert(std::make_pair(key,Cookie(key,value)));
|
2018-05-14 16:40:03 +08:00
|
|
|
}
|
2018-06-19 16:55:25 +08:00
|
|
|
|
|
|
|
virtual void addCookie(const Cookie &cookie) override
|
|
|
|
{
|
2018-06-21 15:39:11 +08:00
|
|
|
_cookies.insert(std::make_pair(cookie.key(),cookie));
|
2018-06-19 16:55:25 +08:00
|
|
|
}
|
|
|
|
|
2018-05-14 16:40:03 +08:00
|
|
|
virtual void setBody(const std::string& body) override
|
|
|
|
{
|
2018-06-21 15:39:11 +08:00
|
|
|
_body = body;
|
2018-05-14 16:40:03 +08:00
|
|
|
}
|
|
|
|
virtual void setBody(std::string&& body) override
|
|
|
|
{
|
2018-06-21 15:39:11 +08:00
|
|
|
_body = std::move(body);
|
2018-05-14 16:40:03 +08:00
|
|
|
}
|
|
|
|
virtual void redirect(const std::string& url) override
|
|
|
|
{
|
2018-06-21 15:39:11 +08:00
|
|
|
_headers["Location"] = url;
|
2018-05-14 16:40:03 +08:00
|
|
|
}
|
|
|
|
void appendToBuffer(MsgBuffer* output) const;
|
|
|
|
|
|
|
|
virtual void clear() override
|
|
|
|
{
|
2018-06-21 15:39:11 +08:00
|
|
|
_statusCode = kUnknown;
|
|
|
|
_v = kHttp11;
|
|
|
|
_statusMessage.clear();
|
|
|
|
_headers.clear();
|
|
|
|
_cookies.clear();
|
|
|
|
_body.clear();
|
|
|
|
_left_body_length = 0;
|
|
|
|
_current_chunk_length = 0;
|
2018-05-14 16:40:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// void setReceiveTime(trantor::Date t)
|
|
|
|
// {
|
|
|
|
// receiveTime_ = t;
|
|
|
|
// }
|
|
|
|
|
|
|
|
virtual std::string getBody() const override
|
|
|
|
{
|
2018-06-21 15:39:11 +08:00
|
|
|
return _body;
|
2018-05-14 16:40:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
static const std::string web_content_type_to_string(uint8_t contenttype);
|
|
|
|
static const std::string web_response_code_to_string(int code);
|
|
|
|
|
|
|
|
private:
|
2018-06-21 15:39:11 +08:00
|
|
|
std::map<std::string, std::string> _headers;
|
|
|
|
std::map<std::string, Cookie> _cookies;
|
|
|
|
HttpStatusCode _statusCode;
|
2018-05-14 16:40:03 +08:00
|
|
|
// FIXME: add http version
|
2018-06-21 15:39:11 +08:00
|
|
|
Version _v;
|
|
|
|
std::string _statusMessage;
|
|
|
|
bool _closeConnection;
|
|
|
|
std::string _body;
|
|
|
|
size_t _left_body_length;
|
|
|
|
size_t _current_chunk_length;
|
|
|
|
uint8_t _contentType=CT_TEXT_HTML;
|
2018-05-14 16:40:03 +08:00
|
|
|
//trantor::Date receiveTime_;
|
|
|
|
|
|
|
|
void setContentType(const std::string& contentType)
|
|
|
|
{
|
|
|
|
addHeader("Content-Type", contentType);
|
|
|
|
}
|
|
|
|
void setStatusMessage(const std::string& message)
|
|
|
|
{
|
2018-06-21 15:39:11 +08:00
|
|
|
_statusMessage = message;
|
2018-05-14 16:40:03 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|