1 /*
2  * Copyright 2019 Matthieu Gautier <mgautier@kymeria.fr>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU  General Public License as published by
6  * the Free Software Foundation; either version 3 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17  * MA 02110-1301, USA.
18  */
19 
20 #ifndef KIWIXLIB_SERVER_INTERNALSERVER_H
21 #define KIWIXLIB_SERVER_INTERNALSERVER_H
22 
23 
24 extern "C" {
25 #include "microhttpd_wrapper.h"
26 }
27 
28 #include "library.h"
29 #include "name_mapper.h"
30 
31 #include <mustache.hpp>
32 
33 #include <atomic>
34 #include <string>
35 
36 #include "server/request_context.h"
37 #include "server/response.h"
38 
39 namespace kiwix {
40 
41 typedef kainjow::mustache::data MustacheData;
42 
43 class Entry;
44 
45 class InternalServer {
46   public:
47     InternalServer(Library* library,
48                    NameMapper* nameMapper,
49                    std::string addr,
50                    int port,
51                    std::string root,
52                    int nbThreads,
53                    bool verbose,
54                    bool withTaskbar,
55                    bool withLibraryButton,
56                    bool blockExternalLinks);
57     virtual ~InternalServer() = default;
58 
59     MHD_Result handlerCallback(struct MHD_Connection* connection,
60                                const char* url,
61                                const char* method,
62                                const char* version,
63                                const char* upload_data,
64                                size_t* upload_data_size,
65                                void** cont_cls);
66     bool start();
67     void stop();
68 
69   private: // functions
70     std::unique_ptr<Response> handle_request(const RequestContext& request);
71     std::unique_ptr<Response> build_redirect(const std::string& bookName, const kiwix::Entry& entry) const;
72     std::unique_ptr<Response> build_homepage(const RequestContext& request);
73     std::unique_ptr<Response> handle_skin(const RequestContext& request);
74     std::unique_ptr<Response> handle_catalog(const RequestContext& request);
75     std::unique_ptr<Response> handle_meta(const RequestContext& request);
76     std::unique_ptr<Response> handle_search(const RequestContext& request);
77     std::unique_ptr<Response> handle_suggest(const RequestContext& request);
78     std::unique_ptr<Response> handle_random(const RequestContext& request);
79     std::unique_ptr<Response> handle_captured_external(const RequestContext& request);
80     std::unique_ptr<Response> handle_content(const RequestContext& request);
81 
82     MustacheData get_default_data() const;
83     MustacheData homepage_data() const;
84 
85     std::shared_ptr<Reader> get_reader(const std::string& bookName) const;
86     bool etag_not_needed(const RequestContext& r) const;
87     ETag get_matching_if_none_match_etag(const RequestContext& request) const;
88 
89   private: // data
90     std::string m_addr;
91     int m_port;
92     std::string m_root;
93     int m_nbThreads;
94     std::atomic_bool m_verbose;
95     bool m_withTaskbar;
96     bool m_withLibraryButton;
97     bool m_blockExternalLinks;
98     struct MHD_Daemon* mp_daemon;
99 
100     Library* mp_library;
101     NameMapper* mp_nameMapper;
102 
103     std::string m_server_id;
104 
105     friend std::unique_ptr<Response> Response::build(const InternalServer& server);
106     friend std::unique_ptr<ContentResponse> ContentResponse::build(const InternalServer& server, const std::string& content, const std::string& mimetype);
107     friend std::unique_ptr<Response> EntryResponse::build(const InternalServer& server, const RequestContext& request, const Entry& entry);
108     friend std::unique_ptr<Response> Response::build_500(const InternalServer& server, const std::string& msg);
109 
110 };
111 
112 }
113 
114 #endif //KIWIXLIB_SERVER_INTERNALSERVER_H
115