Line data Source code
1 : // Snap Websites Servers -- snap websites child process hanlding
2 : // Copyright (c) 2011-2019 Made to Order Software Corp. All Rights Reserved
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 2 of the License, or
7 : // (at your option) 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 St, Fifth Floor, Boston, MA 02110-1301 USA
17 : #pragma once
18 :
19 : // snapwebsites lib
20 : //
21 : #include "snapwebsites/cache_control.h"
22 : #include "snapwebsites/http_cookie.h"
23 : #include "snapwebsites/http_link.h"
24 : #include "snapwebsites/snap_communicator.h"
25 : #include "snapwebsites/snap_signals.h"
26 : #include "snapwebsites/snap_thread.h"
27 : #include "snapwebsites/snap_uri.h"
28 : #include "snapwebsites/snap_version.h"
29 : #include "snapwebsites/tcp_client_server.h"
30 : #include "snapwebsites/udp_client_server.h"
31 :
32 : // libdbproxy lib
33 : //
34 : #include <libdbproxy/libdbproxy.h>
35 : #include <libdbproxy/context.h>
36 :
37 : // Qt lib
38 : //
39 : #include <QBuffer>
40 : #include <QDomDocument>
41 :
42 :
43 : namespace snap
44 : {
45 :
46 0 : class snap_child_exception : public snap_exception
47 : {
48 : public:
49 0 : explicit snap_child_exception(char const * whatmsg) : snap_exception("snap_child", whatmsg) {}
50 : explicit snap_child_exception(std::string const & whatmsg) : snap_exception("snap_child", whatmsg) {}
51 0 : explicit snap_child_exception(QString const & whatmsg) : snap_exception("snap_child", whatmsg) {}
52 : };
53 :
54 0 : class snap_child_exception_unique_number_error : public snap_child_exception
55 : {
56 : public:
57 : explicit snap_child_exception_unique_number_error(char const * whatmsg) : snap_child_exception(whatmsg) {}
58 : explicit snap_child_exception_unique_number_error(std::string const & whatmsg) : snap_child_exception(whatmsg) {}
59 0 : explicit snap_child_exception_unique_number_error(QString const & whatmsg) : snap_child_exception(whatmsg) {}
60 : };
61 :
62 0 : class snap_child_exception_invalid_header_value : public snap_child_exception
63 : {
64 : public:
65 : explicit snap_child_exception_invalid_header_value(char const * whatmsg) : snap_child_exception(whatmsg) {}
66 : explicit snap_child_exception_invalid_header_value(std::string const & whatmsg) : snap_child_exception(whatmsg) {}
67 0 : explicit snap_child_exception_invalid_header_value(QString const & whatmsg) : snap_child_exception(whatmsg) {}
68 : };
69 :
70 0 : class snap_child_exception_invalid_header_field_name : public snap_child_exception
71 : {
72 : public:
73 : explicit snap_child_exception_invalid_header_field_name(char const * whatmsg) : snap_child_exception(whatmsg) {}
74 : explicit snap_child_exception_invalid_header_field_name(std::string const & whatmsg) : snap_child_exception(whatmsg) {}
75 0 : explicit snap_child_exception_invalid_header_field_name(QString const & whatmsg) : snap_child_exception(whatmsg) {}
76 : };
77 :
78 0 : class snap_child_exception_no_server : public snap_child_exception
79 : {
80 : public:
81 0 : explicit snap_child_exception_no_server(char const * whatmsg) : snap_child_exception(whatmsg) {}
82 : explicit snap_child_exception_no_server(std::string const & whatmsg) : snap_child_exception(whatmsg) {}
83 : explicit snap_child_exception_no_server(QString const & whatmsg) : snap_child_exception(whatmsg) {}
84 : };
85 :
86 0 : class snap_child_exception_invalid_email : public snap_child_exception
87 : {
88 : public:
89 0 : explicit snap_child_exception_invalid_email(char const * whatmsg) : snap_child_exception(whatmsg) {}
90 : explicit snap_child_exception_invalid_email(std::string const & whatmsg) : snap_child_exception(whatmsg) {}
91 0 : explicit snap_child_exception_invalid_email(QString const & whatmsg) : snap_child_exception(whatmsg) {}
92 : };
93 :
94 0 : class snap_child_exception_no_cassandra : public snap_child_exception
95 : {
96 : public:
97 : explicit snap_child_exception_no_cassandra(char const * whatmsg) : snap_child_exception(whatmsg) {}
98 : explicit snap_child_exception_no_cassandra(std::string const & whatmsg) : snap_child_exception(whatmsg) {}
99 0 : explicit snap_child_exception_no_cassandra(QString const & whatmsg) : snap_child_exception(whatmsg) {}
100 : };
101 :
102 0 : class snap_child_exception_table_missing : public snap_child_exception
103 : {
104 : public:
105 : explicit snap_child_exception_table_missing(char const * whatmsg) : snap_child_exception(whatmsg) {}
106 : explicit snap_child_exception_table_missing(std::string const & whatmsg) : snap_child_exception(whatmsg) {}
107 0 : explicit snap_child_exception_table_missing(QString const & whatmsg) : snap_child_exception(whatmsg) {}
108 : };
109 :
110 :
111 :
112 : class permission_error_callback;
113 : class server;
114 :
115 :
116 :
117 : class snap_child
118 : {
119 : public:
120 : enum class http_code_t
121 : {
122 : // a couple of internal codes used here and there (never sent to user)
123 : HTTP_CODE_INVALID = -2,
124 : HTTP_CODE_UNDEFINED = -1,
125 :
126 : HTTP_CODE_CONTINUE = 100,
127 : HTTP_CODE_SWITCHING_PROTOCOLS = 101,
128 : HTTP_CODE_PROCESSING = 102,
129 : HTTP_CODE_RESPONSE_IS_STALE = 110, // If we return a cached page
130 :
131 : HTTP_CODE_OK = 200,
132 : HTTP_CODE_CREATED = 201,
133 : HTTP_CODE_ACCEPTED = 202,
134 : HTTP_CODE_NON_AUTHORITATIVE_INFORMATION = 203,
135 : HTTP_CODE_NO_CONTENT = 204,
136 : HTTP_CODE_RESET_CONTENT = 205,
137 : HTTP_CODE_PARTIAL_CONTENT = 206,
138 : HTTP_CODE_MULTI_STATUS = 207,
139 : HTTP_CODE_ALREADY_REPORTED = 208,
140 : HTTP_CODE_IM_USED = 226, // Instance Manipulation Used
141 :
142 : HTTP_CODE_MULTIPLE_CHOICE = 300,
143 : HTTP_CODE_MOVED_PERMANENTLY = 301,
144 : HTTP_CODE_FOUND = 302,
145 : HTTP_CODE_SEE_OTHER = 303,
146 : HTTP_CODE_NOT_MODIFIED = 304,
147 : HTTP_CODE_USE_PROXY = 305,
148 : HTTP_CODE_SWITCH_PROXY = 306,
149 : HTTP_CODE_TEMPORARY_REDIRECT = 307,
150 : HTTP_CODE_PERMANENT_REDIRECT = 308,
151 :
152 : HTTP_CODE_BAD_REQUEST = 400,
153 : HTTP_CODE_UNAUTHORIZED = 401,
154 : HTTP_CODE_PAYMENT_REQUIRED = 402,
155 : HTTP_CODE_FORBIDDEN = 403,
156 : HTTP_CODE_NOT_FOUND = 404,
157 : HTTP_CODE_METHOD_NOT_ALLOWED = 405,
158 : HTTP_CODE_NOT_ACCEPTABLE = 406,
159 : HTTP_CODE_PROXY_AUTHENTICATION_REQUIRED = 407,
160 : HTTP_CODE_REQUEST_TIMEOUT = 408,
161 : HTTP_CODE_CONFLICT = 409,
162 : HTTP_CODE_GONE = 410,
163 : HTTP_CODE_LENGTH_REQUIRED = 411,
164 : HTTP_CODE_PRECONDITION_FAILED = 412,
165 : HTTP_CODE_REQUEST_ENTITY_TOO_LARGE = 413,
166 : HTTP_CODE_REQUEST_URI_TOO_LONG = 414,
167 : HTTP_CODE_UNSUPPORTED_MEDIA_TYPE = 415,
168 : HTTP_CODE_REQUESTED_RANGE_NOT_SATISFIABLE = 416,
169 : HTTP_CODE_EXPECTATION_FAILED = 417,
170 : HTTP_CODE_I_AM_A_TEAPOT = 418,
171 : HTTP_CODE_ENHANCE_YOUR_CALM = 420,
172 : HTTP_CODE_METHOD_FAILURE = 420, /* WARNING: same as Enhance Your Calm */
173 : HTTP_CODE_UNPROCESSABLE_ENTITY = 422,
174 : HTTP_CODE_LOCKED = 423,
175 : HTTP_CODE_FAILED_DEPENDENCY = 424,
176 : HTTP_CODE_UNORDERED_COLLECTION = 425,
177 : HTTP_CODE_UPGRADE_REQUIRED = 426,
178 : HTTP_CODE_PRECONDITION_REQUIRED = 428,
179 : HTTP_CODE_TOO_MANY_REQUESTS = 429,
180 : HTTP_CODE_REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
181 : HTTP_CODE_NO_RESPONSE = 444,
182 : HTTP_CODE_RETRY_WITH = 449,
183 : HTTP_CODE_BLOCKED_BY_WINDOWS_PARENTAL_CONTROLS = 450,
184 : HTTP_CODE_UNAVAILABLE_FOR_LEGAL_REASONS = 451,
185 : HTTP_CODE_REDIRECT = 451, /* WARNING: same as Unavailable For Legal Reasons */
186 : HTTP_CODE_REQUEST_HEADER_TOO_LARGE = 494,
187 : HTTP_CODE_CERT_ERROR = 495,
188 : HTTP_CODE_NO_CERT = 496,
189 : HTTP_CODE_HTTP_TO_HTTPS = 497,
190 : HTTP_CODE_TOKEN_EXPIRED = 498,
191 : HTTP_CODE_CLIENT_CLOSED_REQUEST = 499,
192 : HTTP_CODE_TOKEN_REQUIRED = 499, /* WARNING: same as Client Close Request */
193 :
194 : HTTP_CODE_INTERNAL_SERVER_ERROR = 500,
195 : HTTP_CODE_NOT_IMPLEMENTED = 501,
196 : HTTP_CODE_BAD_GATEWAY = 502,
197 : HTTP_CODE_SERVICE_UNAVAILABLE = 503,
198 : HTTP_CODE_GATEWAY_TIMEOUT = 504,
199 : HTTP_CODE_HTTP_VERSION_NOT_SUPPORTED = 505,
200 : HTTP_CODE_VARIANTS_ALSO_NEGOTIATES = 506,
201 : HTTP_CODE_INSUFFICIANT_STORAGE = 507,
202 : HTTP_CODE_LOOP_DETECTED = 508,
203 : HTTP_CODE_BANDWIDTH_LIMIT_EXCEEDED = 509,
204 : HTTP_CODE_NOT_EXTENDED = 510,
205 : HTTP_CODE_NETWORK_AUTHENTICATION_REQUIRED = 511,
206 : HTTP_CODE_ACCESS_DENIED = 531,
207 : HTTP_CODE_NETWORK_READ_TIMEOUT_ERROR = 598,
208 : HTTP_CODE_NETWORK_CONNECT_TIMEOUT_ERROR = 599
209 : };
210 :
211 : enum class date_format_t
212 : {
213 : DATE_FORMAT_SHORT,
214 : DATE_FORMAT_SHORT_US,
215 : DATE_FORMAT_LONG,
216 : DATE_FORMAT_TIME,
217 : DATE_FORMAT_EMAIL,
218 : DATE_FORMAT_HTTP
219 : };
220 :
221 : enum class status_t
222 : {
223 : SNAP_CHILD_STATUS_READY,
224 : SNAP_CHILD_STATUS_RUNNING
225 : };
226 :
227 : enum class user_status_t
228 : {
229 : // WARNING: the order is very important, we use a '<' operation
230 : // to know whether a user has enough permission to see
231 : // a certain message (see details in:
232 : // snapserver-core-plugins/src/output/output.cpp)
233 : //
234 : USER_STATUS_UNKNOWN,
235 : USER_STATUS_LOGGED_OUT,
236 : USER_STATUS_WEAKLY_LOGGED_IN,
237 : USER_STATUS_LOGGED_IN,
238 : USER_STATUS_ADMINISTRATIVE_LOGGED_IN
239 : };
240 :
241 : typedef int64_t user_identifier_t;
242 :
243 : typedef std::weak_ptr<server> server_pointer_t;
244 : typedef QMap<QString, QString> environment_map_t;
245 :
246 : // Note: the information saved in files come from the POST and
247 : // is not to be trusted (especially the mime type)
248 0 : class post_file_t
249 : {
250 : public:
251 0 : void set_name(QString const & name) { f_name = name; }
252 0 : void set_filename(QString const & filename) { f_filename = filename; }
253 0 : void set_mime_type(QString const & mime_type) { f_mime_type = mime_type; }
254 0 : void set_original_mime_type(QString const & mime_type) { f_original_mime_type = mime_type; }
255 0 : void set_creation_time(time_t ctime) { f_creation_time = ctime; }
256 0 : void set_modification_time(time_t mtime) { f_modification_time = mtime; }
257 : void set_data(QByteArray const & data);
258 : void set_size(int size) { f_size = size; }
259 0 : void set_index(int index) { f_index = index; }
260 0 : void set_image_width(int width) { f_image_width = width; }
261 0 : void set_image_height(int height) { f_image_height = height; }
262 :
263 : QString get_name() const { return f_name; }
264 0 : QString get_filename() const { return f_filename; }
265 : QString get_basename() const;
266 : QString get_original_mime_type() const { return f_original_mime_type; }
267 0 : QString get_mime_type() const { return f_mime_type; }
268 : time_t get_creation_time() const { return f_creation_time; }
269 : time_t get_modification_time() const { return f_modification_time; }
270 0 : QByteArray get_data() const { return f_data; }
271 : int get_size() const;
272 : int get_index() const { return f_index; }
273 : int get_image_width() const { return f_image_width; }
274 : int get_image_height() const { return f_image_height; }
275 :
276 : private:
277 : QString f_name = QString(); // field name
278 : QString f_filename = QString();
279 : QString f_original_mime_type = QString();
280 : QString f_mime_type = QString();
281 : int64_t f_creation_time = 0; // time_t
282 : int64_t f_modification_time = 0; // time_t
283 : QByteArray f_data = QByteArray();
284 : uint32_t f_size = 0;
285 : uint32_t f_index = 0;
286 : uint32_t f_image_width = 0;
287 : uint32_t f_image_height = 0;
288 : };
289 : // map indexed by filename
290 : typedef QMap<QString, post_file_t> post_file_map_t;
291 :
292 : struct language_name_t
293 : {
294 : char const * f_language = nullptr; // full English name of the language
295 : char const * f_native = nullptr; // full Native name of the language
296 : char const f_short_name[3] = { 0, 0, 0 }; // expected name (xx); must be 2 characters
297 : char const * f_other_names = nullptr; // 3 or 4 letter names separated by commas; if NULL no extras
298 : };
299 :
300 : struct country_name_t
301 : {
302 : char const f_abbreviation[3] = { 0, 0, 0 }; // must be 2 characters
303 : char const * f_name = nullptr;
304 : };
305 :
306 0 : class locale_info_t
307 : {
308 : public:
309 0 : void set_language(QString const & language) { f_language = language; }
310 0 : void set_country(QString const & country) { f_country = country; }
311 :
312 0 : QString const & get_language() const { return f_language; }
313 0 : QString const & get_country() const { return f_country; }
314 :
315 : QString get_composed() const;
316 :
317 0 : bool operator == (locale_info_t const & rhs) const { return f_language == rhs.f_language && f_country == rhs.f_country; }
318 :
319 : private:
320 : QString f_language = QString();
321 : QString f_country = QString();
322 : };
323 : typedef QVector<locale_info_t> locale_info_vector_t;
324 :
325 : typedef int header_mode_t;
326 : static header_mode_t const HEADER_MODE_UNDEFINED = 0x0000;
327 : static header_mode_t const HEADER_MODE_NO_ERROR = 0x0001;
328 : static header_mode_t const HEADER_MODE_REDIRECT = 0x0002;
329 : static header_mode_t const HEADER_MODE_ERROR = 0x0004;
330 : static header_mode_t const HEADER_MODE_EVERYWHERE = 0xFFFF;
331 :
332 : enum class compression_t
333 : {
334 : COMPRESSION_INVALID = -2,
335 : COMPRESSION_UNDEFINED = -1,
336 : COMPRESSION_IDENTITY = 0, // no compression
337 : COMPRESSION_GZIP,
338 : COMPRESSION_DEFLATE, // zlib without the gzip magic numbers
339 : COMPRESSION_BZ2,
340 : COMPRESSION_SDCH
341 : };
342 : typedef QVector<compression_t> compression_vector_t;
343 :
344 : enum class verified_email_t
345 : {
346 : VERIFIED_EMAIL_UNKNOWN,
347 : VERIFIED_EMAIL_EMPTY,
348 : VERIFIED_EMAIL_STANDARD,
349 : VERIFIED_EMAIL_EXAMPLE,
350 : VERIFIED_EMAIL_MIXED
351 : };
352 :
353 : snap_child(server_pointer_t s);
354 : virtual ~snap_child();
355 :
356 : bool process(tcp_client_server::bio_client::pointer_t client);
357 : std::shared_ptr<server> get_server() const;
358 : pid_t get_child_pid() const;
359 : void kill();
360 : status_t check_status();
361 :
362 : snap_uri const & get_uri() const;
363 : void set_uri_path(QString const & path);
364 : bool has_post() const { return f_has_post; }
365 : QString get_action() const;
366 : void set_action(QString const & action);
367 : snap_child::verified_email_t verify_email(QString const & email, size_t const max = 1, bool allow_example_domain = false);
368 :
369 : virtual void exit(int code);
370 : bool is_debug() const;
371 : bool is_ready() const;
372 : static char const * get_running_server_version();
373 : bool is_core_plugin(QString const & name) const;
374 : QString get_server_parameter(QString const & name);
375 : QString get_data_path();
376 : QString get_list_data_path();
377 : void reset_sites_table();
378 : libdbproxy::value get_site_parameter(QString const & name);
379 : void set_site_parameter(QString const & name, libdbproxy::value const & value);
380 : void user_status(user_status_t status, user_identifier_t id);
381 : void improve_signature(QString const & path, QDomDocument doc, QDomElement signature_tag);
382 : QString error_body(http_code_t err_code, QString const & err_name, QString const & err_description);
383 : libdbproxy::libdbproxy::pointer_t
384 : get_cassandra() { return f_cassandra; }
385 : libdbproxy::context::pointer_t
386 : get_context() { return f_context; }
387 : QString const & get_domain_key() const { return f_domain_key; }
388 0 : QString const & get_website_key() const { return f_website_key; }
389 0 : QString const & get_site_key() const { return f_site_key; }
390 0 : QString const & get_site_key_with_slash() const { return f_site_key_with_slash; }
391 : static int64_t get_current_date();
392 : void init_start_date();
393 0 : int64_t get_start_date() const { return f_start_date; }
394 0 : time_t get_start_time() const { return f_start_date / static_cast<int64_t>(1000000); }
395 : cache_control_settings const &
396 : client_cache_control() const;
397 : cache_control_settings & server_cache_control();
398 : cache_control_settings & page_cache_control();
399 : bool no_caching() const;
400 : void set_header(QString const & name, QString const & value, header_mode_t modes = HEADER_MODE_NO_ERROR);
401 : void add_http_link(http_link const & link);
402 : bool http_link_is_defined(std::string const & name);
403 : http_link const & get_http_link(std::string const & name);
404 : void output_http_links(header_mode_t modes);
405 : void set_cookie(http_cookie const & cookie);
406 : void set_ignore_cookies();
407 : bool has_header(QString const & name) const;
408 : QString get_header(QString const & name) const;
409 : QString get_unique_number();
410 : libdbproxy::table::pointer_t
411 : get_table(QString const & table_name);
412 : void new_content();
413 : void verify_permissions(QString const & path, permission_error_callback & err_callback);
414 : QString default_action(QString uri_path);
415 : void process_post();
416 : QString get_language();
417 : QString get_country() const;
418 : QString get_language_key();
419 : locale_info_vector_t const &
420 : get_plugins_locales();
421 : locale_info_vector_t const &
422 : get_browser_locales() const;
423 : locale_info_vector_t get_all_locales();
424 : bool get_working_branch() const;
425 : snap_version::version_number_t
426 : get_branch() const;
427 : snap_version::version_number_t
428 : get_revision() const;
429 : QString get_revision_key() const; // <branch>.<revision> as a string (pre-defined)
430 : compression_vector_t get_compression() const;
431 : static void canonicalize_path(QString & path);
432 : static QString date_to_string(int64_t v, date_format_t date_format = date_format_t::DATE_FORMAT_SHORT);
433 : static time_t string_to_date(QString const & date);
434 : static int last_day_of_month(int month, int year);
435 : bool verify_locale(QString & lang, QString & country, bool generate_errors);
436 : static bool verify_language_name(QString & lang);
437 : static bool verify_country_name(QString & country);
438 : static language_name_t const *
439 : get_languages();
440 : static country_name_t const *
441 : get_countries();
442 : static bool tag_is_inline(char const * tag, int length);
443 : void set_timezone(QString const & timezone);
444 : void set_locale(QString const & locale);
445 :
446 : QString snapenv(QString const & name) const;
447 : bool postenv_exists(QString const & name) const;
448 : QString postenv(QString const & name, QString const & default_value = "") const;
449 : void replace_postenv(QString const & name, QString const & value);
450 : environment_map_t const & all_postenv() const { return f_post; }
451 : bool postfile_exists(QString const & name) const;
452 : post_file_t const & postfile(QString const & name) const;
453 : bool cookie_is_defined(QString const & name) const;
454 : QString cookie(QString const & name) const;
455 : void attach_to_session();
456 : bool load_file(post_file_t & file);
457 : // TODO translations? (not too important though)
458 : void page_redirect(QString const & path, http_code_t http_code = http_code_t::HTTP_CODE_MOVED_PERMANENTLY, QString const & reason_brief = "Moved", QString const & reason = "This page has moved");
459 : void die(http_code_t err_code, QString err_name, QString const & err_description, QString const & err_details);
460 : void not_modified();
461 : static void define_http_name(http_code_t http_code, QString & http_name);
462 : void finish_update();
463 :
464 : QByteArray get_output() const;
465 : void output(QByteArray const & data);
466 : void output(QString const & data);
467 : void output(std::string const & data);
468 : void output(char const * data);
469 : void output(wchar_t const * data);
470 : bool empty_output() const;
471 : void output_result(header_mode_t mode, QByteArray output_data);
472 : void trace(QString const & data);
473 : void trace(std::string const & data);
474 : void trace(char const * data);
475 : void show_resources(std::ostream & out);
476 : void extract_resource(QString const & resource_name, QString const & output_filename);
477 :
478 : void backend_process();
479 : void udp_ping(char const * name);
480 :
481 : protected:
482 : pid_t fork_child();
483 : bool connect_cassandra(bool child);
484 : virtual void disconnect_cassandra();
485 : void canonicalize_domain();
486 : void canonicalize_website();
487 : void canonicalize_options();
488 : void site_redirect();
489 : snap_string_list init_plugins(bool const add_defaults, QString const & introducer = QString());
490 :
491 : server_pointer_t f_server = server_pointer_t();
492 : bool f_is_child = false;
493 : pid_t f_child_pid = 0;
494 : tcp_client_server::bio_client::pointer_t f_client = tcp_client_server::bio_client::pointer_t();
495 : libdbproxy::libdbproxy::pointer_t f_cassandra = libdbproxy::libdbproxy::pointer_t();
496 : libdbproxy::context::pointer_t f_context = libdbproxy::context::pointer_t();
497 : int64_t f_start_date = 0; // time request arrived
498 : bool f_ready = false; // becomes true just before the server::execute() call
499 : environment_map_t f_env = environment_map_t();
500 : snap_uri f_uri = snap_uri();
501 : QString f_site_key = QString();
502 : QString f_original_site_key = QString();
503 :
504 : private:
505 0 : struct http_header_t
506 : {
507 : QString f_header = QString();
508 : header_mode_t f_modes = HEADER_MODE_UNDEFINED;
509 : };
510 : typedef QMap<QString, http_header_t> header_map_t;
511 : typedef QMap<QString, http_cookie> cookie_map_t;
512 :
513 0 : class messenger_runner
514 : : public snap_thread::snap_runner
515 : {
516 : public:
517 : messenger_runner( snap_child * sc );
518 : messenger_runner( messenger_runner const & rhs ) = delete;
519 :
520 : messenger_runner & operator = ( messenger_runner const & rhs ) = delete;
521 :
522 : virtual void run() override;
523 :
524 : private:
525 : snap_child * f_child = nullptr;
526 : };
527 :
528 0 : class child_messenger
529 : : public snap_communicator::snap_tcp_client_permanent_message_connection
530 : {
531 : public:
532 : typedef std::shared_ptr<child_messenger> pointer_t;
533 :
534 : child_messenger( snap_child * s
535 : , std::string const & addr
536 : , int port
537 : );
538 : child_messenger(child_messenger & rhs) = delete;
539 :
540 : child_messenger & operator = (child_messenger & rhs) = delete;
541 :
542 : virtual void process_message( snap_communicator_message const & message ) override;
543 : virtual void process_connected() override;
544 :
545 : private:
546 : snap_child * f_child = nullptr;
547 : QString f_service_name = QString();
548 : };
549 :
550 : friend class messenger_runner;
551 : friend class child_messenger;
552 :
553 : void read_environment();
554 : void mark_for_initialization();
555 : void setup_uri();
556 : void snap_info();
557 : void snap_statistics();
558 : void update_plugins(snap_string_list const & list_of_plugins);
559 : void execute();
560 : void process_backend_uri(QString const & uri);
561 : void write(char const * data, ssize_t size);
562 : void write(char const * str);
563 : void write(QString const & str);
564 : void set_cache_control();
565 : void output_headers(header_mode_t modes);
566 : void output_cookies();
567 : void output_session_log( QString const& what );
568 : void connect_messenger();
569 : void stop_messenger();
570 :
571 : libdbproxy::table::pointer_t f_sites_table = libdbproxy::table::pointer_t();
572 : bool f_new_content = false;
573 : bool f_is_being_initialized = false;
574 : environment_map_t f_post = environment_map_t();
575 : post_file_map_t f_files = post_file_map_t();
576 : environment_map_t f_browser_cookies = environment_map_t();
577 : bool f_has_post = false;
578 : mutable bool f_fixed_server_protocol = false;
579 : QString f_domain_key = QString();
580 : QString f_website_key = QString();
581 : QString f_site_key_with_slash = QString();
582 : QBuffer f_output;
583 : header_map_t f_header = header_map_t();
584 : http_link::map_t f_http_links = http_link::map_t();
585 : cookie_map_t f_cookies = cookie_map_t();
586 : bool f_ignore_cookies = false;
587 : bool f_died = false; // die() was already called once
588 : QString f_language = QString();
589 : QString f_country = QString();
590 : QString f_language_key = QString();
591 : bool f_original_timezone_defined = false;
592 : QString f_original_timezone = QString();
593 : bool f_plugins_locales_was_not_ready = false;
594 : locale_info_vector_t f_plugins_locales = locale_info_vector_t();
595 : locale_info_vector_t f_browser_locales = locale_info_vector_t();
596 : locale_info_vector_t f_all_locales = locale_info_vector_t();
597 : bool f_working_branch = false;
598 : snap_version::version_number_t f_branch = snap_version::version_number_t();
599 : snap_version::version_number_t f_revision = snap_version::version_number_t();
600 : QString f_revision_key = QString();
601 : compression_vector_t f_compressions = compression_vector_t();
602 : cache_control_settings f_client_cache_control = cache_control_settings();
603 : cache_control_settings f_server_cache_control = cache_control_settings();
604 : cache_control_settings f_page_cache_control = cache_control_settings();
605 : messenger_runner f_messenger_runner;
606 : snap::snap_thread f_messenger_thread;
607 : snap_communicator::pointer_t f_communicator = snap_communicator::pointer_t();
608 : child_messenger::pointer_t f_messenger = child_messenger::pointer_t();
609 : };
610 :
611 : typedef std::vector<snap_child *> snap_child_vector_t;
612 :
613 : } // namespace snap
614 : // vim: ts=4 sw=4 et
|