MXS-1220: Reorganize request and response processing
The standard response headers are now generated at a higher level. This reduces the scope of the HttpResponse class making it a leaner wrapper around a few simple variables, namely the JSON body of the response. The HttpRequest now exposes the Host header that the client sent. This allows resource relations to be real links that work without modification.
This commit is contained in:
parent
8c77e62872
commit
52e075963e
@ -74,18 +74,30 @@ int handle_client(void *cls,
|
||||
HttpRequest request(connection, url, method, json);
|
||||
HttpResponse reply = resource_handle_request(request);
|
||||
|
||||
string data = reply.get_response();
|
||||
string data;
|
||||
|
||||
struct MHD_Response *response = MHD_create_response_from_buffer(data.size(),
|
||||
(void*)data.c_str(),
|
||||
MHD_RESPMEM_MUST_COPY);
|
||||
json_t* js = reply.get_response();
|
||||
|
||||
for (map<string, string>::const_iterator it = reply.get_headers().begin();
|
||||
it != reply.get_headers().end(); it++)
|
||||
if (js)
|
||||
{
|
||||
MHD_add_response_header(response, it->first.c_str(), it->second.c_str());
|
||||
int flags = request.get_option("pretty") == "true" ? JSON_INDENT(4) : 0;
|
||||
data = mxs::json_dump(js, flags);
|
||||
}
|
||||
|
||||
struct MHD_Response *response =
|
||||
MHD_create_response_from_buffer(data.size(), (void*)data.c_str(),
|
||||
MHD_RESPMEM_MUST_COPY);
|
||||
|
||||
string http_date = http_get_date();
|
||||
|
||||
MHD_add_response_header(response, "Date", http_date.c_str());
|
||||
|
||||
// TODO: calculate modification times
|
||||
MHD_add_response_header(response, "Last-Modified", http_date.c_str());
|
||||
|
||||
// This ETag is the base64 encoding of `not-yet-implemented`
|
||||
MHD_add_response_header(response, "ETag", "bm90LXlldC1pbXBsZW1lbnRlZAo");
|
||||
|
||||
MHD_queue_response(connection, reply.get_code(), response);
|
||||
MHD_destroy_response(response);
|
||||
return MHD_YES;
|
||||
|
@ -89,6 +89,7 @@ HttpRequest::HttpRequest(struct MHD_Connection *connection, string url, string m
|
||||
m_connection(connection)
|
||||
{
|
||||
process_uri(url, m_resource_parts);
|
||||
m_hostname = get_header("Host");
|
||||
}
|
||||
|
||||
HttpRequest::~HttpRequest()
|
||||
|
@ -23,32 +23,35 @@
|
||||
using std::string;
|
||||
using std::stringstream;
|
||||
|
||||
HttpResponse::HttpResponse(int code, string response):
|
||||
HttpResponse::HttpResponse(int code, json_t* response):
|
||||
m_body(response),
|
||||
m_code(code)
|
||||
{
|
||||
m_headers["Date"] = http_get_date();
|
||||
}
|
||||
|
||||
// TODO: Add proper modification timestamps
|
||||
m_headers["Last-Modified"] = m_headers["Date"];
|
||||
// TODO: Add proper ETags
|
||||
m_headers["ETag"] = "bm90LXlldC1pbXBsZW1lbnRlZAo=";
|
||||
HttpResponse::HttpResponse(const HttpResponse& response):
|
||||
m_body(response.m_body),
|
||||
m_code(response.m_code)
|
||||
{
|
||||
json_incref(m_body);
|
||||
}
|
||||
|
||||
HttpResponse& HttpResponse::operator=(const HttpResponse& response)
|
||||
{
|
||||
m_body = json_incref(response.m_body);
|
||||
m_code = response.m_code;
|
||||
return *this;
|
||||
}
|
||||
|
||||
HttpResponse::~HttpResponse()
|
||||
{
|
||||
if (m_body)
|
||||
{
|
||||
json_decref(m_body);
|
||||
}
|
||||
}
|
||||
|
||||
void HttpResponse::add_header(string name, string value)
|
||||
{
|
||||
m_headers[name] = value;
|
||||
}
|
||||
const map<string, string>& HttpResponse::get_headers() const
|
||||
{
|
||||
return m_headers;
|
||||
}
|
||||
|
||||
string HttpResponse::get_response() const
|
||||
json_t* HttpResponse::get_response() const
|
||||
{
|
||||
return m_body;
|
||||
}
|
||||
|
@ -165,6 +165,10 @@ public:
|
||||
return m_resource_parts.size();
|
||||
}
|
||||
|
||||
const char* host() const
|
||||
{
|
||||
return m_hostname.c_str();
|
||||
}
|
||||
private:
|
||||
|
||||
map<string, string> m_options; /**< Request options */
|
||||
@ -173,5 +177,6 @@ private:
|
||||
string m_resource; /**< Requested resource */
|
||||
deque<string> m_resource_parts; /**< @c m_resource split into parts */
|
||||
string m_verb; /**< Request method */
|
||||
string m_hostname; /**< The value of the Host header */
|
||||
struct MHD_Connection* m_connection;
|
||||
};
|
||||
|
@ -40,31 +40,18 @@ public:
|
||||
* @param response Response body
|
||||
* @param code HTTP return code
|
||||
*/
|
||||
HttpResponse(int code = MHD_HTTP_OK, string response = "");
|
||||
HttpResponse(int code = MHD_HTTP_OK, json_t* response = NULL);
|
||||
HttpResponse(const HttpResponse& response);
|
||||
HttpResponse& operator = (const HttpResponse& response);
|
||||
|
||||
~HttpResponse();
|
||||
|
||||
/**
|
||||
* @brief Add a header to the response
|
||||
* @brief Get the response body
|
||||
*
|
||||
* @param name Header name
|
||||
* @param value Header value
|
||||
* @return The response body
|
||||
*/
|
||||
void add_header(string name, string value);
|
||||
|
||||
/**
|
||||
* @brief Get headers for this response
|
||||
*
|
||||
* @return Map of headers and values
|
||||
*/
|
||||
const map<string, string>& get_headers() const;
|
||||
|
||||
/**
|
||||
* @brief Get the response in string format
|
||||
*
|
||||
* @return The complete response that can be sent to a client
|
||||
*/
|
||||
string get_response() const;
|
||||
json_t* get_response() const;
|
||||
|
||||
/**
|
||||
* @brief Get the HTTP response code
|
||||
@ -74,7 +61,6 @@ public:
|
||||
int get_code() const;
|
||||
|
||||
private:
|
||||
string m_body; /**< Message body */
|
||||
map<string, string> m_headers; /**< Message headers */
|
||||
int m_code; /**< The HTTP code for the response */
|
||||
json_t* m_body; /**< Message body */
|
||||
int m_code; /**< The HTTP code for the response */
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user