Port kiwix-serve to new api in kiwix-lib to serve a content.

A lot of code removed from this repository !!
This commit is contained in:
Matthieu Gautier 2019-08-10 17:18:39 +02:00
parent ef0fc514ad
commit 8ffff9cd47
36 changed files with 34 additions and 11664 deletions

View File

@ -25,5 +25,4 @@ if static_linkage
endif
#subdir('include')
subdir('static')
subdir('src')

View File

@ -98,7 +98,7 @@ int main(int argc, char** argv)
if (reader) {
searcher = new kiwix::Searcher();
searcher->add_reader(reader, "");
searcher->add_reader(reader);
} else {
cerr << "Unable to search through zim '" << zimPath << "'." << endl;
exit(1);

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,5 @@
sources = ['kiwix-serve.cpp', 'request_context.cpp']
sources += server_resources
sources = ['kiwix-serve.cpp']
executable('kiwix-serve', sources,
dependencies:all_deps,

View File

@ -1,201 +0,0 @@
/*
* Copyright 2009-2016 Emmanuel Engelhart <kelson@kiwix.org>
* Copyright 2017 Matthieu Gautier<mgautier@kymeria.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include "request_context.h"
#include <string.h>
#include <stdexcept>
#include <sstream>
#include <cstdio>
RequestContext::RequestContext(struct MHD_Connection* connection,
std::string rootLocation,
const std::string& _url,
const std::string& method,
const std::string& version) :
full_url(_url),
url(_url),
valid_url(true),
version(version),
acceptEncodingDeflate(false),
accept_range(false),
range_pair(0, -1)
{
if (method == "GET") {
this->method = RequestMethod::GET;
} else if (method == "HEAD") {
this->method = RequestMethod::HEAD;
} else if (method == "POST") {
this->method = RequestMethod::POST;
} else if (method == "PUT") {
this->method = RequestMethod::PUT;
} else if (method == "DELETE") {
this->method = RequestMethod::DELETE_;
} else if (method == "CONNECT") {
this->method = RequestMethod::CONNECT;
} else if (method == "OPTIONS") {
this->method = RequestMethod::OPTIONS;
} else if (method == "TRACE") {
this->method = RequestMethod::TRACE;
} else if (method == "PATCH") {
this->method = RequestMethod::PATCH;
} else {
this->method = RequestMethod::OTHER;
}
MHD_get_connection_values(connection, MHD_HEADER_KIND, &RequestContext::fill_header, this);
MHD_get_connection_values(connection, MHD_GET_ARGUMENT_KIND, &RequestContext::fill_argument, this);
valid_url = true;
if (rootLocation.empty()) {
// nothing special to handle.
url = full_url;
} else {
if (full_url.size() > rootLocation.size() &&
full_url.substr(0, rootLocation.size()+1) == rootLocation + "/") {
url = full_url.substr(rootLocation.size());
} else {
valid_url = false;
}
}
try {
acceptEncodingDeflate =
(get_header(MHD_HTTP_HEADER_ACCEPT_ENCODING).find("deflate") != std::string::npos);
} catch (const std::out_of_range&) {}
/*Check if range is requested. */
try {
auto range = get_header(MHD_HTTP_HEADER_RANGE);
int start = 0;
int end = -1;
std::istringstream iss(range);
char c;
iss >> start >> c;
if (iss.good() && c=='-') {
iss >> end;
if (iss.fail()) {
// Something went wrong will extracting.
end = -1;
}
if (iss.eof()) {
accept_range = true;
range_pair = std::pair<int, int>(start, end);
}
}
} catch (const std::out_of_range&) {}
}
RequestContext::~RequestContext()
{}
int RequestContext::fill_header(void *__this, enum MHD_ValueKind kind,
const char *key, const char *value)
{
RequestContext *_this = static_cast<RequestContext*>(__this);
_this->headers[key] = value;
return MHD_YES;
}
int RequestContext::fill_argument(void *__this, enum MHD_ValueKind kind,
const char *key, const char* value)
{
RequestContext *_this = static_cast<RequestContext*>(__this);
_this->arguments[key] = value == nullptr ? "" : value;
return MHD_YES;
}
void RequestContext::print_debug_info() {
printf("method : %s (%d)\n", method==RequestMethod::GET ? "GET" :
method==RequestMethod::POST ? "POST" :
"OTHER", (int)method);
printf("version : %s\n", version.c_str());
printf("headers :\n");
for (auto it=headers.begin(); it!=headers.end(); it++) {
printf(" - %s : '%s'\n", it->first.c_str(), it->second.c_str());
}
printf("arguments :\n");
for (auto it=arguments.begin(); it!=arguments.end(); it++) {
printf(" - %s : '%s'\n", it->first.c_str(), it->second.c_str());
}
printf("Parsed : \n");
printf("url : %s\n", url.c_str());
printf("acceptEncodingDeflate : %d\n", acceptEncodingDeflate);
printf("has_range : %d\n", accept_range);
printf(".............\n");
}
RequestMethod RequestContext::get_method() {
return method;
}
std::string RequestContext::get_url() {
return url;
}
std::string RequestContext::get_url_part(int number) {
size_t start = 1;
while(true) {
auto found = url.find('/', start);
if (number == 0) {
if (found == std::string::npos) {
return url.substr(start);
} else {
return url.substr(start, found-start);
}
} else {
if (found == std::string::npos) {
throw std::out_of_range("No parts");
}
start = found + 1;
number -= 1;
}
}
}
std::string RequestContext::get_full_url() {
return full_url;
}
bool RequestContext::is_valid_url() {
return valid_url;
}
bool RequestContext::has_range() {
return accept_range;
}
std::pair<int, int> RequestContext::get_range() {
return range_pair;
}
template<>
std::string RequestContext::get_argument(const std::string& name) {
return arguments.at(name);
}
std::string RequestContext::get_header(const std::string& name) {
return headers.at(name);
}

View File

@ -1,108 +0,0 @@
/*
* Copyright 2009-2016 Emmanuel Engelhart <kelson@kiwix.org>
* Copyright 2017 Matthieu Gautier<mgautier@kymeria.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#ifndef REQUEST_CONTEXT_H
#define REQUEST_CONTEXT_H
#include <string>
#include <sstream>
#include <map>
#include <stdexcept>
extern "C" {
#include <microhttpd.h>
}
enum class RequestMethod {
GET,
HEAD,
POST,
PUT,
DELETE_,
CONNECT,
OPTIONS,
TRACE,
PATCH,
OTHER
};
class KeyError : public std::runtime_error {};
class IndexError: public std::runtime_error {};
class RequestContext {
public:
RequestContext(struct MHD_Connection* connection,
std::string rootLocation,
const std::string& url,
const std::string& method,
const std::string& version);
~RequestContext();
void print_debug_info();
bool is_valid_url();
std::string get_header(const std::string& name);
template<typename T=std::string>
T get_argument(const std::string& name) {
std::istringstream stream(arguments.at(name));
T v;
stream >> v;
return v;
}
RequestMethod get_method();
std::string get_url();
std::string get_url_part(int part);
std::string get_full_url();
bool has_range();
std::pair<int, int> get_range();
bool can_compress() { return acceptEncodingDeflate; }
// [TODO] Move this to the response builder
int httpResponseCode;
private:
std::string full_url;
std::string url;
bool valid_url;
RequestMethod method;
std::string version;
bool acceptEncodingDeflate;
bool accept_range;
std::pair<int, int> range_pair;
std::map<std::string, std::string> headers;
std::map<std::string, std::string> arguments;
static int fill_header(void *, enum MHD_ValueKind, const char*, const char*);
static int fill_argument(void *, enum MHD_ValueKind, const char*, const char*);
};
template<> std::string RequestContext::get_argument(const std::string& name);
#endif //REQUEST_CONTEXT_H

View File

@ -1,4 +0,0 @@
res_compiler = find_program('kiwix-compile-resources', 'compile_resources.py')
subdir('server')

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -1,13 +0,0 @@
<span class="kiwix">
<span id="kiwixtoolbar" class="ui-widget-header">
<div class="kiwix_centered">
<div class="kiwix_searchform" style="margin: auto auto;float: none;">
<form class="kiwixsearch" method="GET" action="__ROOT_LOCATION__/search" id="kiwixsearchform">
<label for="kiwixsearchbox" style="line-height: 30px;">&#x1f50d;</label>
<input autocomplete="off" class="ui-autocomplete-input" id="kiwixsearchbox" name="pattern" type="text">
</form>
</div>
</div>
</span>
</span>
<div style="display: block; height: 5em;"></div>

View File

@ -1,56 +0,0 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8" />
<title>Welcome to Kiwix Server</title>
<script type="text/javascript" src="__ROOT_LOCATION__/skin/jquery-ui/external/jquery/jquery.js"></script>
<script type="text/javascript" src="__ROOT_LOCATION__/skin/jquery-ui/jquery-ui.min.js"></script>
<link type="text/css" href="__ROOT_LOCATION__/skin/jquery-ui/jquery-ui.min.css" rel="Stylesheet" />
<link type="text/css" href="__ROOT_LOCATION__/skin/jquery-ui/jquery-ui.theme.min.css" rel="Stylesheet" />
<style>
body {
background:
radial-gradient(#EEEEEE 15%, transparent 16%) 0 0,
radial-gradient(#EEEEEE 15%, transparent 16%) 8px 8px,
radial-gradient(rgba(255,255,255,.1) 15%, transparent 20%) 0 1px,
radial-gradient(rgba(255,255,255,.1) 15%, transparent 20%) 8px 9px;
background-color:#E8E8E8;
background-size:16px 16px;
margin-left: auto;
margin-right: auto;
max-width: 1100px;
}
.book__list { text-align: center; }
.book {
display: inline-block; vertical-align: bottom; margin: 8px; padding: 12px 15px; width: 300px;
border: 1px solid #ccc; border-radius: 8px;
text-align: left; color: #000; font-family: sans-serif; font-size: 13px;
background-color:#F1F1F1;
box-shadow: 2px 2px 5px 0px #ccc;
}
.book:hover { background-color: #F9F9F9; box-shadow: none;}
.book__background { background-repeat: no-repeat; background-size: auto; background-position: top right; }
.book__title {
padding: 0 55px 0 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
font-size: 18px; color: #0645ad;
}
.book__description {
padding: 5px 55px 5px 0px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
font-size: 15px;
}
.book__info { line-height: 18px; color: #777; font-weight: bold; font-size: 13px; }
</style>
<script type="text/javascript" src="__ROOT_LOCATION__/skin/taskbar.js" async></script>
</head>
<body class="kiwix">
<div class="kiwix">
__BOOKS__
</div>
<div id="kiwixfooter">
Powered by <a href="https://kiwix.org">Kiwix</a>
</div>
</body>
</html>

View File

@ -1,28 +0,0 @@
<link type="text/css" href="__ROOT_LOCATION__/skin/jquery-ui/jquery-ui.min.css" rel="Stylesheet" />
<link type="text/css" href="__ROOT_LOCATION__/skin/jquery-ui/jquery-ui.theme.min.css" rel="Stylesheet" />
<link type="text/css" href="__ROOT_LOCATION__/skin/taskbar.css" rel="Stylesheet" />
<script type="text/javascript" src="__ROOT_LOCATION__/skin/jquery-ui/external/jquery/jquery.js"></script>
<script type="text/javascript" src="__ROOT_LOCATION__/skin/jquery-ui/jquery-ui.min.js"></script>
<script>
var jk = jQuery.noConflict();
jk(function() {
jk( "#kiwixsearchbox" ).autocomplete({
source: "__ROOT_LOCATION__/suggest?content=__CONTENT_ESCAPED__",
dataType: "json",
cache: false,
select: function(event, ui) {
jk( "#kiwixsearchbox" ).val(ui.item.value);
jk( "#kiwixsearchform" ).submit();
},
});
});
/* cybook hack */
if (navigator.userAgent.indexOf("bookeen/cybook") != -1) {
jk("html").addClass("cybook");
}
</script>
<script type="text/javascript" src="__ROOT_LOCATION__/skin/taskbar.js" async></script>

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 335 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 207 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 332 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 280 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,8 +0,0 @@
server_resources = custom_target('resources',
input: 'resources_list.txt',
output: ['server-resources.cpp', 'server-resources.h'],
command:[res_compiler, '--cxxfile', '@OUTPUT0@', '--hfile', '@OUTPUT1@', '@INPUT@'],
build_always: true
)

View File

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
<ShortName>Zim catalog search</ShortName>
<Description>Search zim files in the catalog.</Description>
<Url type="application/atom+xml;profile=opds-catalog"
xmlns:atom="http://www.w3.org/2005/Atom"
indexOffset="0"
template="/__ROOT_LOCATION__/catalog/search?q={searchTerms}&lang={language}&count={count}&start={startIndex}"/>
</OpenSearchDescription>

View File

@ -1,27 +0,0 @@
jquery-ui/jquery-ui.structure.min.css
jquery-ui/jquery-ui.min.js
jquery-ui/external/jquery/jquery.js
jquery-ui/images/ui-bg_flat_0_aaaaaa_40x100.png
jquery-ui/images/ui-bg_flat_75_ffffff_40x100.png
jquery-ui/images/ui-icons_222222_256x240.png
jquery-ui/images/ui-bg_glass_55_fbf9ee_1x400.png
jquery-ui/images/ui-bg_highlight-soft_75_cccccc_1x100.png
jquery-ui/images/ui-bg_glass_65_ffffff_1x400.png
jquery-ui/images/ui-icons_2e83ff_256x240.png
jquery-ui/images/ui-icons_cd0a0a_256x240.png
jquery-ui/images/ui-icons_888888_256x240.png
jquery-ui/images/ui-bg_glass_75_e6e6e6_1x400.png
jquery-ui/images/animated-overlay.gif
jquery-ui/images/ui-bg_glass_75_dadada_1x400.png
jquery-ui/images/ui-icons_454545_256x240.png
jquery-ui/images/ui-bg_glass_95_fef1ec_1x400.png
jquery-ui/jquery-ui.theme.min.css
jquery-ui/jquery-ui.min.css
home.html.tmpl
include.html.part
caret.png
taskbar.js
taskbar.css
taskbar.html.part
global_taskbar.html.part
opensearchdescription.xml

View File

@ -1,186 +0,0 @@
#kiwixtoolbar {
position: fixed;
padding: .5em;
left: 0;
right: 0;
top: 0;
z-index: 100;
background-position-y: 0px;
transition: 0.3s;
width: 100%;
box-sizing: border-box;
}
#kiwixtoolbar>a {
float: left;
}
#kiwixfooter {
text-align: center;
margin-top: 1em;
}
.height_separator {
height: 3em;
}
.kiwixsearch {
position: relative;
height: 26px;
width: 100%;
left: 0;
margin-bottom: 0;
}
.kiwix_searchform {
width: 20em;
}
#kiwix_serve_taskbar_home_button button {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 160px;
}
.kiwix .kiwix_centered {
max-width: 720px;
margin: 0 auto;
}
#kiwix_button_show_toggle {
display: none;
}
#kiwix_button_show_toggle:checked~label~.kiwix_button_cont,
#kiwix_button_show_toggle:checked~label~.kiwix_button_cont>a {
display: block;
}
#kiwix_button_show_toggle:not(:checked)~label~.kiwix_button_cont {
display: none;
}
label[for="kiwix_button_show_toggle"] {
display: inline-block;
height: 26px;
}
label[for="kiwix_button_show_toggle"] img {
transition: 0.1s;
height: 26px;
}
#kiwix_button_show_toggle:checked~label img {
transform: rotate(-180deg);
}
label[for="kiwix_button_show_toggle"],
.kiwix_button_cont {
display: block;
}
.kiwix .kiwix_searchform {
float: right;
}
.kiwix #kiwixtoolbar button,
.kiwix #kiwixtoolbar input[type="submit"] {
box-sizing: border-box !important;
height: 26px !important;
line-height: 20px !important;
margin-right: 5px !important;
padding: 2px 6px !important;
border: 1px solid #999 !important;
border-radius: 3px !important;
background-color: #ededed !important;
font-weight: normal !important;
cursor: pointer !important;
font-size: 16px !important;
}
.kiwix #kiwixtoolbar #kiwixsearchform input[type='text'] {
position: absolute;
left: 0;
box-sizing: border-box !important;
width: 100%;
height: 26px !important;
line-height: 20px !important;
border: 1px solid #999 !important;
border-radius: 3px !important;
background-color: #fff !important;
padding: 2px 2px 2px 27px !important;
font-size: 16px !important;
}
label[for=kiwixsearchbox] {
z-index: 1;
position: absolute;
height: 100%;
left: 5px;
font-size: 90%;
line-height: 26px;
vertical-align: middle;
}
body {
padding-top: 40px !important;
}
/* Try to fix buggy stuff in jquery-ui autocomplete */
#ui-id-1,
.ui-autocomplete {
background: white !important;
border: solid 1px grey !important;
}
li.ui-state-focus {
font-weight: bold;
}
@media(min-width:420px) {
.kiwix_button_cont {
display: inline-block !important;
}
.kiwix_button_cont>a {
display: inline-block !important;
}
label[for="kiwix_button_show_toggle"] {
display: none;
}
}
@media (max-width: 645px) {
#kiwix_button_show_toggle~label~.kiwix_button_cont.searching {
display: none !important;
}
label[for="kiwix_button_show_toggle"].searching {
display: none !important;
}
.kiwix_searchform.full_width {
width: 100%;
}
.kiwixsearch {
float: none;
}
.kiwix_searchform {
width: 36%;
}
.height_separator {
height: 6em;
}
}
@media(max-width:415px) {
.kiwix_searchform {
width: 80%;
}
}

View File

@ -1,21 +0,0 @@
<span class="kiwix">
<span id="kiwixtoolbar" class="ui-widget-header">
<div class="kiwix_centered">
<div class="kiwix_searchform">
<form class="kiwixsearch" method="GET" action="__ROOT_LOCATION__/search" id="kiwixsearchform">
<input type="hidden" name="content" value="__CONTENT__" />
<label for="kiwixsearchbox">&#x1f50d;</label>
<input autocomplete="off" class="ui-autocomplete-input" id="kiwixsearchbox" name="pattern" type="text">
</form>
</div>
<input type="checkbox" id="kiwix_button_show_toggle">
<label for="kiwix_button_show_toggle"><img src="__ROOT_LOCATION__/skin/caret.png" alt=""></label>
<div class="kiwix_button_cont">
<a id="kiwix_serve_taskbar_library_button" href="__ROOT_LOCATION__/"><button>&#x1f3e0;</button></a>
<a id="kiwix_serve_taskbar_home_button" href="__ROOT_LOCATION__/__CONTENT__/"><button>__ZIM_TITLE__</button></a>
<a id="kiwix_serve_taskbar_random_button"
href="__ROOT_LOCATION__/random?content=__CONTENT_ESCAPED__"><button>&#x1F3B2;</button></a>
</div>
</div>
</span>
</span>

View File

@ -1,49 +0,0 @@
(function ($) {
if ($(window).width() < 520) {
var didScroll;
var lastScrollTop = 0;
var delta = 5;
// on scroll, let the interval function know the user has scrolled
$(window).scroll(function (event) {
didScroll = true;
});
// run hasScrolled() and reset didScroll status
setInterval(function () {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 250);
function hasScrolled() {
var st = $(this).scrollTop();
// Make sure they scroll more than delta
if (Math.abs(lastScrollTop - st) <= delta)
return;
// If they scrolled down and are past the navbar, add class .nav-up.
// This is necessary so you never see what is "behind" the navbar.
if (st > lastScrollTop) {
// Scroll Down
$('#kiwixtoolbar').css({ top: '-100%' });
} else {
// Scroll Up
$('#kiwixtoolbar').css({ top: '0' });
}
lastScrollTop = st;
}
}
$('#kiwixsearchbox').on({
focus: function () {
$('.kiwix_searchform').addClass('full_width');
$('label[for="kiwix_button_show_toggle"], .kiwix_button_cont').addClass('searching');
},
blur: function () {
$('.kiwix_searchform').removeClass('full_width');
$('label[for="kiwix_button_show_toggle"], .kiwix_button_cont').removeClass('searching');
}
});
})(jQuery);