drogon/lib/src/HttpResponseImpl.h

251 lines
7.4 KiB
C
Raw Normal View History

// 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
*
*/
#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)
{
}
virtual void setStatusCode(HttpStatusCode code) override
{
2018-06-21 15:39:11 +08:00
_statusCode = code;
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;
setStatusMessage(status_message);
}
virtual void setVersion(const Version v) override
{
2018-06-21 15:39:11 +08:00
_v = v;
}
virtual void setCloseConnection(bool on) override
{
2018-06-21 15:39:11 +08:00
_closeConnection = on;
}
virtual bool closeConnection() const override
{
2018-06-21 15:39:11 +08:00
return _closeConnection;
}
virtual void setContentTypeCode(uint8_t type) override
{
2018-06-21 15:39:11 +08:00
_contentType=type;
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())
{
return "";
}
else
{
2018-06-21 15:39:11 +08:00
return _headers[key];
}
}
virtual void addHeader(const std::string& key, const std::string& value) override
{
2018-06-21 15:39:11 +08:00
_headers[key] = value;
}
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;
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]))
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)));
}
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]))
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)));
}
}
}
}
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-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
}
virtual void setBody(const std::string& body) override
{
2018-06-21 15:39:11 +08:00
_body = body;
}
virtual void setBody(std::string&& body) override
{
2018-06-21 15:39:11 +08:00
_body = std::move(body);
}
virtual void redirect(const std::string& url) override
{
2018-06-21 15:39:11 +08:00
_headers["Location"] = url;
}
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;
}
// void setReceiveTime(trantor::Date t)
// {
// receiveTime_ = t;
// }
virtual std::string getBody() const override
{
2018-06-21 15:39:11 +08:00
return _body;
}
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;
// 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;
//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;
}
};
}