mirror of https://github.com/kiwix/libkiwix.git
Move the entry response to its own class.
This commit is contained in:
parent
f014fb2895
commit
7b2ee37437
|
@ -840,9 +840,7 @@ std::unique_ptr<Response> InternalServer::handle_content(const RequestContext& r
|
||||||
return build_404(request, bookName);
|
return build_404(request, bookName);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto response = Response::build(*this);
|
auto response = EntryResponse::build(*this, request, entry);
|
||||||
|
|
||||||
response->set_entry(entry, request);
|
|
||||||
response->set_taskbar(bookName, reader->getTitle());
|
response->set_taskbar(bookName, reader->getTitle());
|
||||||
|
|
||||||
if (m_verbose.load()) {
|
if (m_verbose.load()) {
|
||||||
|
|
|
@ -108,6 +108,8 @@ class InternalServer {
|
||||||
friend std::unique_ptr<Response> Response::build(const InternalServer& server);
|
friend std::unique_ptr<Response> Response::build(const InternalServer& server);
|
||||||
friend std::unique_ptr<Response> RedirectionResponse::build(const InternalServer& server, const std::string& redirectionUrl);
|
friend std::unique_ptr<Response> RedirectionResponse::build(const InternalServer& server, const std::string& redirectionUrl);
|
||||||
friend std::unique_ptr<Response> ContentResponse::build(const InternalServer& server, const std::string& content, const std::string& mimetype);
|
friend std::unique_ptr<Response> ContentResponse::build(const InternalServer& server, const std::string& content, const std::string& mimetype);
|
||||||
|
friend std::unique_ptr<Response> EntryResponse::build(const InternalServer& server, const RequestContext& request, const Entry& entry);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -253,31 +253,6 @@ Response::create_raw_content_mhd_response(const RequestContext& request)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MHD_Response*
|
|
||||||
Response::create_entry_mhd_response() const
|
|
||||||
{
|
|
||||||
const auto content_length = m_byteRange.length();
|
|
||||||
MHD_Response* response = MHD_create_response_from_callback(content_length,
|
|
||||||
16384,
|
|
||||||
callback_reader_from_entry,
|
|
||||||
new RunningResponse(m_entry, m_byteRange.first()),
|
|
||||||
callback_free_response);
|
|
||||||
MHD_add_response_header(response,
|
|
||||||
MHD_HTTP_HEADER_CONTENT_TYPE, m_mimeType.c_str());
|
|
||||||
MHD_add_response_header(response, MHD_HTTP_HEADER_ACCEPT_RANGES, "bytes");
|
|
||||||
if ( m_byteRange.kind() == ByteRange::RESOLVED_PARTIAL_CONTENT ) {
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << "bytes " << m_byteRange.first() << "-" << m_byteRange.last()
|
|
||||||
<< "/" << m_entry.getSize();
|
|
||||||
|
|
||||||
MHD_add_response_header(response,
|
|
||||||
MHD_HTTP_HEADER_CONTENT_RANGE, oss.str().c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
MHD_add_response_header(response,
|
|
||||||
MHD_HTTP_HEADER_CONTENT_LENGTH, kiwix::to_string(content_length).c_str());
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
MHD_Response*
|
MHD_Response*
|
||||||
Response::create_mhd_response(const RequestContext& request)
|
Response::create_mhd_response(const RequestContext& request)
|
||||||
|
@ -288,9 +263,6 @@ Response::create_mhd_response(const RequestContext& request)
|
||||||
|
|
||||||
case ResponseMode::RAW_CONTENT :
|
case ResponseMode::RAW_CONTENT :
|
||||||
return create_raw_content_mhd_response(request);
|
return create_raw_content_mhd_response(request);
|
||||||
|
|
||||||
case ResponseMode::ENTRY :
|
|
||||||
return create_entry_mhd_response();
|
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -324,30 +296,6 @@ void Response::set_template(const std::string& template_str, kainjow::mustache::
|
||||||
m_mode = ResponseMode::RAW_CONTENT;
|
m_mode = ResponseMode::RAW_CONTENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Response::set_entry(const Entry& entry, const RequestContext& request) {
|
|
||||||
m_entry = entry;
|
|
||||||
m_mode = ResponseMode::ENTRY;
|
|
||||||
|
|
||||||
const std::string mimeType = get_mime_type(entry);
|
|
||||||
set_mimeType(mimeType);
|
|
||||||
set_cacheable();
|
|
||||||
|
|
||||||
m_byteRange = request.get_range().resolve(entry.getSize());
|
|
||||||
const bool noRange = m_byteRange.kind() == ByteRange::RESOLVED_FULL_CONTENT;
|
|
||||||
if ( noRange && is_compressible_mime_type(mimeType) ) {
|
|
||||||
zim::Blob raw_content = entry.getBlob();
|
|
||||||
const std::string content = string(raw_content.data(), raw_content.size());
|
|
||||||
|
|
||||||
m_content = content;
|
|
||||||
m_mode = ResponseMode::RAW_CONTENT;
|
|
||||||
set_compress(true);
|
|
||||||
} else if ( m_byteRange.kind() == ByteRange::RESOLVED_UNSATISFIABLE ) {
|
|
||||||
set_code(416);
|
|
||||||
m_content = "";
|
|
||||||
m_mode = ResponseMode::ERROR_RESPONSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Response::set_taskbar(const std::string& bookName, const std::string& bookTitle)
|
void Response::set_taskbar(const std::string& bookName, const std::string& bookTitle)
|
||||||
{
|
{
|
||||||
m_bookName = bookName;
|
m_bookName = bookName;
|
||||||
|
@ -400,6 +348,77 @@ std::unique_ptr<Response> ContentResponse::build(const InternalServer& server, c
|
||||||
mimetype));
|
mimetype));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EntryResponse::EntryResponse(const std::string& root, bool verbose, bool withTaskbar, bool withLibraryButton, bool blockExternalLinks, const Entry& entry, const std::string& mimetype, const ByteRange& byterange) :
|
||||||
|
Response(root, verbose, withTaskbar, withLibraryButton, blockExternalLinks),
|
||||||
|
m_entry(entry)
|
||||||
|
{
|
||||||
|
m_mimeType = mimetype;
|
||||||
|
m_byteRange = byterange;
|
||||||
|
m_mode = ResponseMode::RAW_CONTENT; // We don't care about raw, but we must init it to something else than error.
|
||||||
|
set_cacheable();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<Response> EntryResponse::build(const InternalServer& server, const RequestContext& request, const Entry& entry)
|
||||||
|
{
|
||||||
|
const std::string mimetype = get_mime_type(entry);
|
||||||
|
auto byteRange = request.get_range().resolve(entry.getSize());
|
||||||
|
const bool noRange = byteRange.kind() == ByteRange::RESOLVED_FULL_CONTENT;
|
||||||
|
if (noRange && is_compressible_mime_type(mimetype)) {
|
||||||
|
// Return a contentResponse
|
||||||
|
zim::Blob raw_content = entry.getBlob();
|
||||||
|
const std::string content = string(raw_content.data(), raw_content.size());
|
||||||
|
auto response = ContentResponse::build(server, content, mimetype);
|
||||||
|
response->set_cacheable();
|
||||||
|
response->set_compress(true);
|
||||||
|
response->m_byteRange = byteRange;
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (byteRange.kind() == ByteRange::RESOLVED_UNSATISFIABLE) {
|
||||||
|
auto response = ContentResponse::build(server, "", mimetype);
|
||||||
|
response->set_cacheable();
|
||||||
|
response->set_code(416);
|
||||||
|
response->m_byteRange = byteRange;
|
||||||
|
response->m_mode = ResponseMode::ERROR_RESPONSE;
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::unique_ptr<Response>(new EntryResponse(
|
||||||
|
server.m_root,
|
||||||
|
server.m_verbose.load(),
|
||||||
|
server.m_withTaskbar,
|
||||||
|
server.m_withLibraryButton,
|
||||||
|
server.m_blockExternalLinks,
|
||||||
|
entry,
|
||||||
|
mimetype,
|
||||||
|
byteRange));
|
||||||
|
}
|
||||||
|
|
||||||
|
MHD_Response*
|
||||||
|
EntryResponse::create_mhd_response(const RequestContext& request)
|
||||||
|
{
|
||||||
|
const auto content_length = m_byteRange.length();
|
||||||
|
MHD_Response* response = MHD_create_response_from_callback(content_length,
|
||||||
|
16384,
|
||||||
|
callback_reader_from_entry,
|
||||||
|
new RunningResponse(m_entry, m_byteRange.first()),
|
||||||
|
callback_free_response);
|
||||||
|
MHD_add_response_header(response,
|
||||||
|
MHD_HTTP_HEADER_CONTENT_TYPE, m_mimeType.c_str());
|
||||||
|
MHD_add_response_header(response, MHD_HTTP_HEADER_ACCEPT_RANGES, "bytes");
|
||||||
|
if ( m_byteRange.kind() == ByteRange::RESOLVED_PARTIAL_CONTENT ) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "bytes " << m_byteRange.first() << "-" << m_byteRange.last()
|
||||||
|
<< "/" << m_entry.getSize();
|
||||||
|
|
||||||
|
MHD_add_response_header(response,
|
||||||
|
MHD_HTTP_HEADER_CONTENT_RANGE, oss.str().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
MHD_add_response_header(response,
|
||||||
|
MHD_HTTP_HEADER_CONTENT_LENGTH, kiwix::to_string(content_length).c_str());
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,12 +37,13 @@ namespace kiwix {
|
||||||
enum class ResponseMode {
|
enum class ResponseMode {
|
||||||
ERROR_RESPONSE,
|
ERROR_RESPONSE,
|
||||||
RAW_CONTENT,
|
RAW_CONTENT,
|
||||||
ENTRY
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class InternalServer;
|
class InternalServer;
|
||||||
class RequestContext;
|
class RequestContext;
|
||||||
|
|
||||||
|
class EntryResponse;
|
||||||
|
|
||||||
class Response {
|
class Response {
|
||||||
public:
|
public:
|
||||||
Response(const std::string& root, bool verbose, bool withTaskbar, bool withLibraryButton, bool blockExternalLinks);
|
Response(const std::string& root, bool verbose, bool withTaskbar, bool withLibraryButton, bool blockExternalLinks);
|
||||||
|
@ -53,8 +54,6 @@ class Response {
|
||||||
MHD_Result send(const RequestContext& request, MHD_Connection* connection);
|
MHD_Result send(const RequestContext& request, MHD_Connection* connection);
|
||||||
|
|
||||||
void set_template(const std::string& template_str, kainjow::mustache::data data);
|
void set_template(const std::string& template_str, kainjow::mustache::data data);
|
||||||
void set_entry(const Entry& entry, const RequestContext& request);
|
|
||||||
|
|
||||||
|
|
||||||
void set_mimeType(const std::string& mimeType) { m_mimeType = mimeType; }
|
void set_mimeType(const std::string& mimeType) { m_mimeType = mimeType; }
|
||||||
void set_code(int code) { m_returnCode = code; }
|
void set_code(int code) { m_returnCode = code; }
|
||||||
|
@ -77,14 +76,12 @@ class Response {
|
||||||
virtual MHD_Response* create_mhd_response(const RequestContext& request);
|
virtual MHD_Response* create_mhd_response(const RequestContext& request);
|
||||||
MHD_Response* create_error_response(const RequestContext& request) const;
|
MHD_Response* create_error_response(const RequestContext& request) const;
|
||||||
MHD_Response* create_raw_content_mhd_response(const RequestContext& request);
|
MHD_Response* create_raw_content_mhd_response(const RequestContext& request);
|
||||||
MHD_Response* create_entry_mhd_response() const;
|
|
||||||
|
|
||||||
protected: // data
|
protected: // data
|
||||||
bool m_verbose;
|
bool m_verbose;
|
||||||
ResponseMode m_mode;
|
ResponseMode m_mode;
|
||||||
std::string m_root;
|
std::string m_root;
|
||||||
std::string m_content;
|
std::string m_content;
|
||||||
Entry m_entry;
|
|
||||||
std::string m_mimeType;
|
std::string m_mimeType;
|
||||||
int m_returnCode;
|
int m_returnCode;
|
||||||
bool m_withTaskbar;
|
bool m_withTaskbar;
|
||||||
|
@ -95,6 +92,8 @@ class Response {
|
||||||
std::string m_bookTitle;
|
std::string m_bookTitle;
|
||||||
ByteRange m_byteRange;
|
ByteRange m_byteRange;
|
||||||
ETag m_etag;
|
ETag m_etag;
|
||||||
|
|
||||||
|
friend class EntryResponse; // temporary to allow the builder to change m_mode
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -118,6 +117,19 @@ class ContentResponse : public Response {
|
||||||
static std::unique_ptr<Response> build(const InternalServer& server, const std::string& content, const std::string& mimetype);
|
static std::unique_ptr<Response> build(const InternalServer& server, const std::string& content, const std::string& mimetype);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class EntryResponse : public Response {
|
||||||
|
public:
|
||||||
|
EntryResponse(const std::string& root, bool verbose, bool withTaskbar, bool withLibraryButton, bool blockExternalLinks, const Entry& entry, const std::string& mimetype, const ByteRange& byterange);
|
||||||
|
|
||||||
|
static std::unique_ptr<Response> build(const InternalServer& server, const RequestContext& request, const Entry& entry);
|
||||||
|
|
||||||
|
private:
|
||||||
|
MHD_Response* create_mhd_response(const RequestContext& request);
|
||||||
|
|
||||||
|
Entry m_entry;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //KIWIXLIB_SERVER_RESPONSE_H
|
#endif //KIWIXLIB_SERVER_RESPONSE_H
|
||||||
|
|
Loading…
Reference in New Issue