summaryrefslogtreecommitdiffstats
path: root/fluent-bit/lib/monkey/mk_server
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-07-24 09:54:23 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-07-24 09:54:44 +0000
commit836b47cb7e99a977c5a23b059ca1d0b5065d310e (patch)
tree1604da8f482d02effa033c94a84be42bc0c848c3 /fluent-bit/lib/monkey/mk_server
parentReleasing debian version 1.44.3-2. (diff)
downloadnetdata-836b47cb7e99a977c5a23b059ca1d0b5065d310e.tar.xz
netdata-836b47cb7e99a977c5a23b059ca1d0b5065d310e.zip
Merging upstream version 1.46.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'fluent-bit/lib/monkey/mk_server')
-rw-r--r--fluent-bit/lib/monkey/mk_server/CMakeLists.txt57
-rw-r--r--fluent-bit/lib/monkey/mk_server/mk_cache.c81
-rw-r--r--fluent-bit/lib/monkey/mk_server/mk_clock.c171
-rw-r--r--fluent-bit/lib/monkey/mk_server/mk_config.c636
-rw-r--r--fluent-bit/lib/monkey/mk_server/mk_fifo.c463
-rw-r--r--fluent-bit/lib/monkey/mk_server/mk_header.c451
-rw-r--r--fluent-bit/lib/monkey/mk_server/mk_http.c1638
-rw-r--r--fluent-bit/lib/monkey/mk_server/mk_http2.c384
-rw-r--r--fluent-bit/lib/monkey/mk_server/mk_http_parser.c744
-rw-r--r--fluent-bit/lib/monkey/mk_server/mk_http_thread.c290
-rw-r--r--fluent-bit/lib/monkey/mk_server/mk_kernel.c165
-rw-r--r--fluent-bit/lib/monkey/mk_server/mk_lib.c796
-rw-r--r--fluent-bit/lib/monkey/mk_server/mk_mimetype.c227
-rw-r--r--fluent-bit/lib/monkey/mk_server/mk_net.c284
-rw-r--r--fluent-bit/lib/monkey/mk_server/mk_plugin.c804
-rw-r--r--fluent-bit/lib/monkey/mk_server/mk_scheduler.c866
-rw-r--r--fluent-bit/lib/monkey/mk_server/mk_server.c679
-rw-r--r--fluent-bit/lib/monkey/mk_server/mk_socket.c402
-rw-r--r--fluent-bit/lib/monkey/mk_server/mk_stream.c338
-rw-r--r--fluent-bit/lib/monkey/mk_server/mk_user.c175
-rw-r--r--fluent-bit/lib/monkey/mk_server/mk_utils.c589
-rw-r--r--fluent-bit/lib/monkey/mk_server/mk_vhost.c821
-rw-r--r--fluent-bit/lib/monkey/mk_server/monkey.c241
23 files changed, 0 insertions, 11302 deletions
diff --git a/fluent-bit/lib/monkey/mk_server/CMakeLists.txt b/fluent-bit/lib/monkey/mk_server/CMakeLists.txt
deleted file mode 100644
index 457525e6..00000000
--- a/fluent-bit/lib/monkey/mk_server/CMakeLists.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-set(CMAKE_POSITION_INDEPENDENT_CODE ON)
-
-set(src
- monkey.c
- mk_lib.c
- mk_fifo.c
- mk_mimetype.c
- mk_vhost.c
- mk_header.c
- mk_config.c
- mk_user.c
- mk_utils.c
- mk_stream.c
- mk_scheduler.c
- mk_http.c
- mk_http_parser.c
- mk_http_thread.c
- mk_socket.c
- mk_net.c
- mk_clock.c
- mk_cache.c
- mk_server.c
- mk_kernel.c
- mk_plugin.c
- )
-
-if(MK_HTTP2)
- set(src
- ${src}
- "mk_http2.c"
- )
-endif()
-
-# Always build a static library, thats our core :)
-add_library(monkey-core-static STATIC ${src})
-set_target_properties(monkey-core-static PROPERTIES OUTPUT_NAME monkey)
-target_link_libraries(monkey-core-static mk_core ${CMAKE_THREAD_LIBS_INIT} ${STATIC_PLUGINS_LIBS} ${CMAKE_DL_LIBS} rbtree co)
-
-message(STATUS "LINKING ${STATIC_PLUGINS_LIBS}")
-
-if(NOT DEFINED MK_HAVE_REGEX)
- target_link_libraries(monkey-core-static regex)
-endif()
-
-# Linux Kqueue emulation
-if(MK_HAVE_LINUX_KQUEUE)
- target_link_libraries(monkey-core-static kqueue)
-endif()
-
-# FreeBSD backtrace
-if (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
- target_link_libraries(monkey-core-static execinfo)
-endif()
-
-if (CMAKE_SYSTEM_NAME MATCHES "SunOS")
- target_link_libraries(monkey-core-static socket nsl)
-endif()
diff --git a/fluent-bit/lib/monkey/mk_server/mk_cache.c b/fluent-bit/lib/monkey/mk_server/mk_cache.c
deleted file mode 100644
index c678afa8..00000000
--- a/fluent-bit/lib/monkey/mk_server/mk_cache.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-
-/* Monkey HTTP Server
- * ==================
- * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define _GNU_SOURCE
-
-#include <monkey/mk_core.h>
-#include <monkey/mk_cache.h>
-#include <monkey/mk_cache_tls.h>
-#include <monkey/mk_config.h>
-#include <monkey/mk_utils.h>
-#include <monkey/mk_vhost.h>
-#include <monkey/mk_tls.h>
-
-/* This function is called when a thread is created */
-void mk_cache_worker_init()
-{
- char *cache_error;
- mk_ptr_t *p_tmp;
-
- /* Cache header request -> last modified */
- p_tmp = mk_mem_alloc_z(sizeof(mk_ptr_t));
- p_tmp->data = mk_mem_alloc_z(32);
- p_tmp->len = -1;
- MK_TLS_SET(mk_tls_cache_header_lm, p_tmp);
-
- /* Cache header request -> content length */
- p_tmp = mk_mem_alloc_z(sizeof(mk_ptr_t));
- p_tmp->data = mk_mem_alloc_z(MK_UTILS_INT2MKP_BUFFER_LEN);
- p_tmp->len = -1;
- MK_TLS_SET(mk_tls_cache_header_cl, p_tmp);
-
- /* Cache gmtime buffer */
- MK_TLS_SET(mk_tls_cache_gmtime, mk_mem_alloc(sizeof(struct tm)));
-
- /* Cache the most used text representations of utime2gmt */
- MK_TLS_SET(mk_tls_cache_gmtext,
- mk_mem_alloc_z(sizeof(struct mk_gmt_cache) * MK_GMT_CACHES));
-
- /* Cache buffer for strerror_r(2) */
- cache_error = mk_mem_alloc(MK_UTILS_ERROR_SIZE);
- pthread_setspecific(mk_utils_error_key, (void *) cache_error);
-}
-
-void mk_cache_worker_exit()
-{
- char *cache_error;
-
- /* Cache header request -> last modified */
- mk_ptr_free(MK_TLS_GET(mk_tls_cache_header_lm));
- mk_mem_free(MK_TLS_GET(mk_tls_cache_header_lm));
-
- /* Cache header request -> content length */
- mk_ptr_free(MK_TLS_GET(mk_tls_cache_header_cl));
- mk_mem_free(MK_TLS_GET(mk_tls_cache_header_cl));
-
- /* Cache gmtime buffer */
- mk_mem_free(MK_TLS_GET(mk_tls_cache_gmtime));
-
- /* Cache the most used text representations of utime2gmt */
- mk_mem_free(MK_TLS_GET(mk_tls_cache_gmtext));
-
- /* Cache buffer for strerror_r(2) */
- cache_error = pthread_getspecific(mk_utils_error_key);
- mk_mem_free(cache_error);
-}
diff --git a/fluent-bit/lib/monkey/mk_server/mk_clock.c b/fluent-bit/lib/monkey/mk_server/mk_clock.c
deleted file mode 100644
index 3a45512f..00000000
--- a/fluent-bit/lib/monkey/mk_server/mk_clock.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-
-/* Monkey HTTP Server
- * ==================
- * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-
-#include <mk_core/mk_pthread.h>
-#include <mk_core/mk_unistd.h>
-
-#include <monkey/mk_core.h>
-#include <monkey/mk_config.h>
-#include <monkey/mk_clock.h>
-#include <monkey/mk_utils.h>
-#include <monkey/mk_tls.h>
-
-#ifdef _WIN32
-static struct tm* localtime_r(const time_t* timep, struct tm* result)
-{
- localtime_s(result, timep);
-
- return result;
-}
-
-static struct tm* gmtime_r(const time_t* timep, struct tm* result)
-{
- gmtime_s(result, timep);
-
- return result;
-}
-#endif
-
-
-/*
- * The mk_ptr_ts have two buffers for avoid in half-way access from
- * another thread while a buffer is being modified. The function below returns
- * one of two buffers to work with.
- */
-static inline char *_next_buffer(mk_ptr_t *pointer, char **buffers)
-{
- if (pointer->data == buffers[0]) {
- return buffers[1];
- }
- else {
- return buffers[0];
- }
-}
-
-static void mk_clock_log_set_time(time_t utime, struct mk_server *server)
-{
- char *time_string;
- struct tm result;
-
- time_string = _next_buffer(&server->clock_context->log_current_time, server->clock_context->log_time_buffers);
- server->clock_context->log_current_utime = utime;
-
- strftime(time_string, LOG_TIME_BUFFER_SIZE, "[%d/%b/%G %T %z]",
- localtime_r(&utime, &result));
-
- server->clock_context->log_current_time.data = time_string;
-}
-
-static void mk_clock_headers_preset(time_t utime, struct mk_server *server)
-{
- int len1;
- int len2;
- struct tm *gmt_tm;
- struct tm result;
- char *buffer;
-
- buffer = _next_buffer(&server->clock_context->headers_preset,
- server->clock_context->header_time_buffers);
-
- gmt_tm = gmtime_r(&utime, &result);
-
- len1 = snprintf(buffer,
- HEADER_TIME_BUFFER_SIZE,
- "%s",
- server->server_signature_header);
-
- len2 = strftime(buffer + len1,
- HEADER_PRESET_SIZE - len1,
- MK_CLOCK_GMT_DATEFORMAT,
- gmt_tm);
-
- server->clock_context->headers_preset.data = buffer;
- server->clock_context->headers_preset.len = len1 + len2;
-}
-
-void *mk_clock_worker_init(void *data)
-{
- time_t cur_time;
- struct mk_server *server = data;
-
- mk_utils_worker_rename("monkey: clock");
- pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
- pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
-
- server->clock_context->mk_clock_tid = pthread_self();
-
- while (1) {
- cur_time = time(NULL);
-
- if(cur_time != ((time_t)-1)) {
- mk_clock_log_set_time(cur_time, server);
- mk_clock_headers_preset(cur_time, server);
- }
- sleep(1);
- }
-
- return NULL;
-}
-
-void mk_clock_exit(struct mk_server *server)
-{
- pthread_cancel(server->clock_context->mk_clock_tid);
- pthread_join(server->clock_context->mk_clock_tid, NULL);
-
- mk_mem_free(server->clock_context->header_time_buffers[0]);
- mk_mem_free(server->clock_context->header_time_buffers[1]);
- mk_mem_free(server->clock_context->log_time_buffers[0]);
- mk_mem_free(server->clock_context->log_time_buffers[1]);
-
- mk_mem_free(server->clock_context);
-}
-
-/* This function must be called before any threads are created */
-void mk_clock_sequential_init(struct mk_server *server)
-{
- server->clock_context = mk_mem_alloc_z(sizeof(struct mk_clock_context));
-
- if (server->clock_context == NULL) {
- return;
- }
-
- /* Time when monkey was started */
- server->clock_context->monkey_init_time = time(NULL);
-
- server->clock_context->log_current_time.len = LOG_TIME_BUFFER_SIZE - 2;
- server->clock_context->headers_preset.len = HEADER_PRESET_SIZE - 1;
-
- server->clock_context->header_time_buffers[0] = mk_mem_alloc_z(HEADER_PRESET_SIZE);
- server->clock_context->header_time_buffers[1] = mk_mem_alloc_z(HEADER_PRESET_SIZE);
-
- server->clock_context->log_time_buffers[0] = mk_mem_alloc_z(LOG_TIME_BUFFER_SIZE);
- server->clock_context->log_time_buffers[1] = mk_mem_alloc_z(LOG_TIME_BUFFER_SIZE);
-
- /* Set the time once */
- time_t cur_time = time(NULL);
-
- if (cur_time != ((time_t)-1)) {
- mk_clock_log_set_time(cur_time, server);
- mk_clock_headers_preset(cur_time, server);
- }
-}
diff --git a/fluent-bit/lib/monkey/mk_server/mk_config.c b/fluent-bit/lib/monkey/mk_server/mk_config.c
deleted file mode 100644
index f8dc9c00..00000000
--- a/fluent-bit/lib/monkey/mk_server/mk_config.c
+++ /dev/null
@@ -1,636 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-
-/* Monkey HTTP Server
- * ==================
- * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <monkey/monkey.h>
-#include <monkey/mk_kernel.h>
-#include <monkey/mk_config.h>
-#include <monkey/mk_utils.h>
-#include <monkey/mk_mimetype.h>
-#include <monkey/mk_info.h>
-#include <monkey/mk_core.h>
-#include <monkey/mk_server.h>
-#include <monkey/mk_plugin.h>
-#include <monkey/mk_vhost.h>
-#include <monkey/mk_mimetype.h>
-#include <monkey/mk_info.h>
-
-#include <ctype.h>
-#include <limits.h>
-#include <mk_core/mk_dirent.h>
-#include <sys/stat.h>
-
-struct mk_server_config *mk_config;
-
-static int mk_config_key_have(struct mk_list *list, const char *value)
-{
- struct mk_list *head;
- struct mk_string_line *entry;
-
- mk_list_foreach(head, list) {
- entry = mk_list_entry(head, struct mk_string_line, _head);
- if (strcasecmp(entry->val, value) == 0) {
- return MK_TRUE;
- }
- }
- return MK_FALSE;
-}
-
-void mk_config_listeners_free(struct mk_server *server)
-{
- struct mk_list *tmp;
- struct mk_list *head;
- struct mk_config_listener *l;
-
- mk_list_foreach_safe(head, tmp, &server->listeners) {
- l = mk_list_entry(head, struct mk_config_listener, _head);
- mk_list_del(&l->_head);
- mk_mem_free(l->address);
- mk_mem_free(l->port);
- mk_mem_free(l);
- }
-}
-
-void mk_config_free_all(struct mk_server *server)
-{
- mk_vhost_free_all(server);
- mk_mimetype_free_all(server);
-
- if (server->config) {
- mk_rconf_free(server->config);
- }
-
- if (server->path_conf_root) {
- mk_mem_free(server->path_conf_root);
- }
-
- if (server->path_conf_pidfile) {
- mk_mem_free(server->path_conf_pidfile);
- }
-
- if (server->conf_user_pub) {
- mk_mem_free(server->conf_user_pub);
- }
-
- /* free config->index_files */
- if (server->index_files) {
- mk_string_split_free(server->index_files);
- }
-
- if (server->user) {
- mk_mem_free(server->user);
- }
-
- if (server->transport_layer) {
- mk_mem_free(server->transport_layer);
- }
-
- mk_config_listeners_free(server);
-
- mk_ptr_free(&server->server_software);
- mk_mem_free(server);
-}
-
-/* Print a specific error */
-static void mk_config_print_error_msg(char *variable, char *path)
-{
- mk_err("[config] %s at %s has an invalid value",
- variable, path);
- mk_mem_free(path);
- exit(EXIT_FAILURE);
-}
-
-/*
- * Check if at least one of the Listen interfaces are being used by another
- * process.
- */
-int mk_config_listen_check_busy(struct mk_server *server)
-{
- int fd;
- struct mk_list *head;
- struct mk_plugin *p;
- struct mk_config_listener *listen;
-
- p = mk_plugin_cap(MK_CAP_SOCK_PLAIN, server);
- if (!p) {
- mk_warn("Listen check: consider build monkey with basic socket handling!");
- return MK_FALSE;
- }
-
- mk_list_foreach(head, &server->listeners) {
- listen = mk_list_entry(head, struct mk_config_listener, _head);
-
- fd = mk_socket_connect(listen->address, atol(listen->port), MK_FALSE);
- if (fd != -1) {
- close(fd);
- return MK_TRUE;
- }
- }
-
- return MK_FALSE;
-}
-
-int mk_config_listen_parse(char *value, struct mk_server *server)
-{
- int ret = -1;
- int flags = 0;
- long port_num;
- char *address = NULL;
- char *port = NULL;
- char *divider;
- struct mk_list *list = NULL;
- struct mk_string_line *listener;
-
- list = mk_string_split_line(value);
- if (!list) {
- goto error;
- }
-
- if (mk_list_is_empty(list) == 0) {
- goto error;
- }
-
- /* Parse the listener interface */
- listener = mk_list_entry_first(list, struct mk_string_line, _head);
- if (listener->val[0] == '[') {
- /* IPv6 address */
- divider = strchr(listener->val, ']');
- if (divider == NULL) {
- mk_err("[config] Expected closing ']' in IPv6 address.");
- goto error;
- }
- if (divider[1] != ':' || divider[2] == '\0') {
- mk_err("[config] Expected ':port' after IPv6 address.");
- goto error;
- }
-
- address = mk_string_copy_substr(listener->val + 1, 0,
- divider - listener->val - 1);
- port = mk_string_dup(divider + 2);
- }
- else if (strchr(listener->val, ':') != NULL) {
- /* IPv4 address */
- divider = strrchr(listener->val, ':');
- if (divider == NULL || divider[1] == '\0') {
- mk_err("[config] Expected ':port' after IPv4 address.");
- goto error;
- }
-
- address = mk_string_copy_substr(listener->val, 0,
- divider - listener->val);
- port = mk_string_dup(divider + 1);
- }
- else {
- /* Port only */
- address = NULL;
- port = mk_string_dup(listener->val);
- }
-
- errno = 0;
- port_num = strtol(port, NULL, 10);
- if (errno != 0 || port_num == LONG_MAX || port_num == LONG_MIN) {
- mk_warn("Using defaults, could not understand \"Listen %s\"",
- listener->val);
- port = NULL;
- }
-
- /* Check extra properties of the listener */
- flags = MK_CAP_HTTP;
- if (mk_config_key_have(list, "!http")) {
- flags |= ~MK_CAP_HTTP;
- }
-
-#ifdef MK_HAVE_HTTP2
- if (mk_config_key_have(list, "h2")) {
- flags |= (MK_CAP_HTTP2 | MK_CAP_SOCK_TLS);
- }
-
- if (mk_config_key_have(list, "h2c")) {
- flags |= MK_CAP_HTTP2;
- }
-#endif
-
- if (mk_config_key_have(list, "tls")) {
- flags |= MK_CAP_SOCK_TLS;
- }
-
- /* register the new listener */
- mk_config_listener_add(address, port, flags, server);
- mk_string_split_free(list);
- list = NULL;
- ret = 0;
-
-error:
- if (address) {
- mk_mem_free(address);
- }
- if (port) {
- mk_mem_free(port);
- }
- if (list) {
- mk_string_split_free(list);
- }
-
- return ret;
-}
-
-static int mk_config_listen_read(struct mk_rconf_section *section,
- struct mk_server *server)
-{
- int ret;
- struct mk_list *cur;
- struct mk_rconf_entry *entry;
-
- mk_list_foreach(cur, &section->entries) {
- entry = mk_list_entry(cur, struct mk_rconf_entry, _head);
- if (strcasecmp(entry->key, "Listen")) {
- continue;
- }
-
- ret = mk_config_listen_parse(entry->val, server);
- if (ret != 0) {
- return -1;
- }
- }
-
- return 0;
-}
-
-/* Read configuration files */
-static int mk_config_read_files(char *path_conf, char *file_conf,
- struct mk_server *server)
-{
- unsigned long len;
- char *tmp = NULL;
- struct stat checkdir;
- struct mk_rconf *cnf;
- struct mk_rconf_section *section;
-
- if (!path_conf) {
- return -1;
- }
-
- if (!file_conf) {
- file_conf = "monkey.conf";
- }
-
- server->path_conf_root = mk_string_dup(path_conf);
-
- if (stat(server->path_conf_root, &checkdir) == -1) {
- mk_err("ERROR: Cannot find/open '%s'", server->path_conf_root);
- return -1;
- }
-
- mk_string_build(&tmp, &len, "%s/%s", path_conf, file_conf);
- cnf = mk_rconf_open(tmp);
- if (!cnf) {
- mk_mem_free(tmp);
- mk_err("Cannot read '%s'", server->conf_main);
- return -1;
- }
- section = mk_rconf_section_get(cnf, "SERVER");
- if (!section) {
- mk_err("ERROR: No 'SERVER' section defined");
- return -1;
- }
-
- /* Map source configuration */
- server->config = cnf;
-
- /* Listen */
- if (!server->port_override) {
- /* Process each Listen entry */
- if (mk_config_listen_read(section, server)) {
- mk_err("[config] Failed to read listen sections.");
- }
- if (mk_list_is_empty(&server->listeners) == 0) {
- mk_warn("[config] No valid Listen entries found, set default");
- mk_config_listener_add(NULL, NULL, MK_CAP_HTTP, server);
- }
- }
- else {
- mk_config_listener_add(NULL, server->port_override,
- MK_CAP_HTTP, server);
- }
-
- /* Number of thread workers */
- if (server->workers == -1) {
- server->workers = (size_t) mk_rconf_section_get_key(section,
- "Workers",
- MK_RCONF_NUM);
- }
-
- if (server->workers < 1) {
- server->workers = mk_utils_get_system_core_count();
-
- if (server->workers < 1) {
- mk_config_print_error_msg("Workers", tmp);
- }
- }
-
- /* Timeout */
- server->timeout = (size_t) mk_rconf_section_get_key(section,
- "Timeout", MK_RCONF_NUM);
- if (server->timeout < 1) {
- mk_config_print_error_msg("Timeout", tmp);
- }
-
- /* KeepAlive */
- server->keep_alive = (size_t) mk_rconf_section_get_key(section,
- "KeepAlive",
- MK_RCONF_BOOL);
- if (server->keep_alive == MK_ERROR) {
- mk_config_print_error_msg("KeepAlive", tmp);
- }
-
- /* MaxKeepAliveRequest */
- server->max_keep_alive_request = (size_t)
- mk_rconf_section_get_key(section,
- "MaxKeepAliveRequest",
- MK_RCONF_NUM);
-
- if (server->max_keep_alive_request == 0) {
- mk_config_print_error_msg("MaxKeepAliveRequest", tmp);
- }
-
- /* KeepAliveTimeout */
- server->keep_alive_timeout = (size_t) mk_rconf_section_get_key(section,
- "KeepAliveTimeout",
- MK_RCONF_NUM);
- if (server->keep_alive_timeout == 0) {
- mk_config_print_error_msg("KeepAliveTimeout", tmp);
- }
-
- /* Pid File */
- if (!server->path_conf_pidfile) {
- server->path_conf_pidfile = mk_rconf_section_get_key(section,
- "PidFile",
- MK_RCONF_STR);
- }
-
- /* Home user's directory /~ */
- server->conf_user_pub = mk_rconf_section_get_key(section,
- "UserDir",
- MK_RCONF_STR);
-
- /* Index files */
- server->index_files = mk_rconf_section_get_key(section,
- "Indexfile", MK_RCONF_LIST);
-
- /* HideVersion Variable */
- server->hideversion = (size_t) mk_rconf_section_get_key(section,
- "HideVersion",
- MK_RCONF_BOOL);
- if (server->hideversion == MK_ERROR) {
- mk_config_print_error_msg("HideVersion", tmp);
- }
-
- /* User Variable */
- server->user = mk_rconf_section_get_key(section, "User", MK_RCONF_STR);
-
- /* Resume */
- server->resume = (size_t) mk_rconf_section_get_key(section,
- "Resume", MK_RCONF_BOOL);
- if (server->resume == MK_ERROR) {
- mk_config_print_error_msg("Resume", tmp);
- }
-
- /* Max Request Size */
- server->max_request_size = (size_t) mk_rconf_section_get_key(section,
- "MaxRequestSize",
- MK_RCONF_NUM);
- if (server->max_request_size <= 0) {
- mk_config_print_error_msg("MaxRequestSize", tmp);
- }
- else {
- server->max_request_size *= 1024;
- }
-
- /* Symbolic Links */
- server->symlink = (size_t) mk_rconf_section_get_key(section,
- "SymLink", MK_RCONF_BOOL);
- if (server->symlink == MK_ERROR) {
- mk_config_print_error_msg("SymLink", tmp);
- }
-
- /* Transport Layer plugin */
- if (!server->transport_layer) {
- server->transport_layer = mk_rconf_section_get_key(section,
- "TransportLayer",
- MK_RCONF_STR);
- }
-
- /* Default Mimetype */
- mk_mem_free(tmp);
- tmp = mk_rconf_section_get_key(section, "DefaultMimeType", MK_RCONF_STR);
- if (tmp) {
- mk_string_build(&server->mimetype_default_str, &len, "%s\r\n", tmp);
- }
-
- /* File Descriptor Table (FDT) */
- server->fdt = (size_t) mk_rconf_section_get_key(section,
- "FDT",
- MK_RCONF_BOOL);
-
- /* FIXME: Overcapacity not ready */
- server->fd_limit = (size_t) mk_rconf_section_get_key(section,
- "FDLimit",
- MK_RCONF_NUM);
- /* Get each worker clients capacity based on FDs system limits */
- server->server_capacity = mk_server_capacity(server);
-
-
- if (!server->one_shot) {
- mk_vhost_init(path_conf, server);
- }
- else {
- mk_vhost_set_single(server->one_shot, server);
- }
-
- mk_mem_free(tmp);
- return 0;
-}
-
-void mk_config_signature(struct mk_server *server)
-{
- unsigned long len;
-
- /* Server Signature */
- if (server->hideversion == MK_FALSE) {
- snprintf(server->server_signature,
- sizeof(server->server_signature) - 1,
- "Monkey/%s", MK_VERSION_STR);
- }
- else {
- snprintf(server->server_signature,
- sizeof(server->server_signature) - 1,
- "Monkey");
- }
- len = snprintf(server->server_signature_header,
- sizeof(server->server_signature_header) - 1,
- "Server: %s\r\n", server->server_signature);
- server->server_signature_header_len = len;
-}
-
-/* read main configuration from monkey.conf */
-void mk_config_start_configure(struct mk_server *server)
-{
- int ret;
- unsigned long len;
-
- ret = mk_config_read_files(server->path_conf_root,
- server->conf_main, server);
- if (ret != 0) {
- return;
- }
-
- /* Load mimes */
- mk_mimetype_read_config(server);
-
- mk_ptr_reset(&server->server_software);
-
- /* Basic server information */
- if (server->hideversion == MK_FALSE) {
- mk_string_build(&server->server_software.data,
- &len, "Monkey/%s (%s)", MK_VERSION_STR, MK_BUILD_OS);
- server->server_software.len = len;
- }
- else {
- mk_string_build(&server->server_software.data, &len, "Monkey Server");
- server->server_software.len = len;
- }
-}
-
-/* Register a new listener into the main configuration */
-struct mk_config_listener *mk_config_listener_add(char *address,
- char *port, int flags,
- struct mk_server *server)
-{
- struct mk_list *head;
- struct mk_config_listener *check;
- struct mk_config_listener *listen = NULL;
-
- listen = mk_mem_alloc(sizeof(struct mk_config_listener));
- if (!listen) {
- mk_err("[listen_add] malloc() failed");
- return NULL;
- }
-
- if (!address) {
- listen->address = mk_string_dup(MK_DEFAULT_LISTEN_ADDR);
- }
- else {
- listen->address = mk_string_dup(address);
- }
-
- /* Set the port */
- if (!port) {
- mk_err("[listen_add] TCP port not defined");
- exit(EXIT_FAILURE);
- }
-
- listen->port = mk_string_dup(port);
- listen->flags = flags;
-
- /* Before to add a new listener, lets make sure it's not a duplicated */
- mk_list_foreach(head, &server->listeners) {
- check = mk_list_entry(head, struct mk_config_listener, _head);
- if (strcmp(listen->address, check->address) == 0 &&
- strcmp(listen->port, check->port) == 0) {
- mk_warn("Listener: duplicated %s:%s, skip.",
- listen->address, listen->port);
-
- /* free resources */
- mk_mem_free(listen->address);
- mk_mem_free(listen->port);
- mk_mem_free(listen);
- return NULL;
- }
- }
-
- mk_list_add(&listen->_head, &server->listeners);
- return listen;
-}
-
-void mk_config_set_init_values(struct mk_server *server)
-{
- /* Init values */
- server->is_seteuid = MK_FALSE;
- server->timeout = 15;
- server->hideversion = MK_FALSE;
- server->keep_alive = MK_TRUE;
- server->keep_alive_timeout = 15;
- server->max_keep_alive_request = 50;
- server->resume = MK_TRUE;
- server->standard_port = 80;
- server->symlink = MK_FALSE;
- server->nhosts = 0;
- mk_list_init(&server->hosts);
- server->user = NULL;
- server->open_flags = O_RDONLY; /* The only place this is effectively used (other than the sanity check)
- * is mk_http.c where it's used to test for file existence and the fd is apparently leaked */
- server->index_files = NULL;
- server->conf_user_pub = NULL;
- server->workers = 1;
-
- /* TCP REUSEPORT: available on Linux >= 3.9 */
- if (server->scheduler_mode == -1) {
- if (server->kernel_features & MK_KERNEL_SO_REUSEPORT) {
- server->scheduler_mode = MK_SCHEDULER_REUSEPORT;
- }
- else {
- server->scheduler_mode = MK_SCHEDULER_FAIR_BALANCING;
- }
- }
-
- /* Max request buffer size allowed
- * right now, every chunk size is 4KB (4096 bytes),
- * so we are setting a maximum request size to 32 KB */
- server->max_request_size = MK_REQUEST_CHUNK * 8;
-
- /* Internals */
- server->safe_event_write = MK_FALSE;
-
- /* Init plugin list */
- mk_list_init(&server->plugins);
-
- /* Init listeners */
- mk_list_init(&server->listeners);
-}
-
-void mk_config_sanity_check(struct mk_server *server)
-{
- /* Check O_NOATIME for current user, flag will just be used
- * if running user is allowed to.
- */
- int fd;
- int flags;
-
- if (!server->path_conf_root) {
- return;
- }
-
- flags = server->open_flags;
- flags |= O_NOATIME;
- fd = open(server->path_conf_root, flags);
-
- if (fd > -1) {
- server->open_flags = flags;
- close(fd);
- }
-}
diff --git a/fluent-bit/lib/monkey/mk_server/mk_fifo.c b/fluent-bit/lib/monkey/mk_server/mk_fifo.c
deleted file mode 100644
index fd148db7..00000000
--- a/fluent-bit/lib/monkey/mk_server/mk_fifo.c
+++ /dev/null
@@ -1,463 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-
-/* Monkey HTTP Server
- * ==================
- * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <monkey/mk_fifo.h>
-#include <monkey/mk_scheduler.h>
-
-#ifdef _WIN32
-#include <event.h>
-#endif
-
-static struct mk_fifo_worker *mk_fifo_worker_create(struct mk_fifo *ctx,
- void *data)
-{
- int id;
- int ret;
- struct mk_fifo_worker *fw;
-
- /* Get an ID */
- id = mk_list_size(&ctx->workers);
-
- fw = mk_mem_alloc_z(sizeof(struct mk_fifo_worker));
- if (!fw) {
- perror("malloc");
- return NULL;
- }
- MK_EVENT_NEW(&fw->event);
-
- fw->worker_id = id;
- fw->data = data;
- fw->fifo = ctx;
-
- fw->buf_data = mk_mem_alloc(MK_FIFO_BUF_SIZE);
- if (!fw->buf_data) {
- perror("malloc");
- mk_mem_free(fw);
- return NULL;
- }
- fw->buf_len = 0;
- fw->buf_size = MK_FIFO_BUF_SIZE;
-
-#ifdef _WIN32
- ret = evutil_socketpair(AF_INET, SOCK_STREAM, 0, fw->channel);
- if (ret == -1) {
- perror("socketpair");
- mk_mem_free(fw);
- return NULL;
- }
-#else
- ret = pipe(fw->channel);
- if (ret == -1) {
- perror("pipe");
- mk_mem_free(fw);
- return NULL;
- }
-#endif
-
- mk_list_add(&fw->_head, &ctx->workers);
- return fw;
-}
-
-/*
- * Function used as a callback triggered by mk_worker_callback() or
- * through a mk_sched_worker_cb_add(). It purpose is to prepare the
- * channels on the final worker thread so it can consume pushed
- * messages.
- */
-void mk_fifo_worker_setup(void *data)
-{
- struct mk_fifo_worker *mw = NULL;
- struct mk_fifo *ctx = data;
-
- pthread_mutex_lock(&ctx->mutex_init);
-
- mw = mk_fifo_worker_create(ctx, data);
- if (!mw) {
- mk_err("[msg] error configuring msg-worker context ");
- pthread_mutex_unlock(&ctx->mutex_init);
- return;
- }
-
- /* Make the current worker context available */
- pthread_setspecific(*ctx->key, mw);
- pthread_mutex_unlock(&ctx->mutex_init);
-}
-
-struct mk_fifo *mk_fifo_create(pthread_key_t *key, void *data)
-{
- struct mk_fifo *ctx;
-
- ctx = mk_mem_alloc(sizeof(struct mk_fifo));
- if (!ctx) {
- perror("malloc");
- return NULL;
- }
- ctx->data = data;
-
- /* Lists */
- mk_list_init(&ctx->queues);
- mk_list_init(&ctx->workers);
-
-
- /* Pthread specifics */
-
- /* We need to isolate this because there is a key that's shared between monkey
- * instances by design.
- */
- if (key != NULL) {
- ctx->key = key;
- pthread_key_create(ctx->key, NULL);
- }
-
- pthread_mutex_init(&ctx->mutex_init, NULL);
-
- return ctx;
-}
-
-int mk_fifo_queue_create(struct mk_fifo *ctx, char *name,
- void (*cb)(struct mk_fifo_queue *, void *,
- size_t, void *),
- void *data)
-
-{
- int id = -1;
- int len;
- struct mk_list *head;
- struct mk_fifo_queue *q;
-
- /* Get ID for the new queue */
- if (mk_list_is_empty(&ctx->queues) == 0) {
- id = 0;
- }
- else {
- q = mk_list_entry_last(&ctx->queues, struct mk_fifo_queue, _head);
- id = q->id + 1;
- }
-
- /* queue name might need to be truncated if is too long */
- len = strlen(name);
- if (len > (int) sizeof(q->name) - 1) {
- len = sizeof(q->name) - 1;
- }
-
- /* Validate that name is not a duplicated */
- mk_list_foreach(head, &ctx->queues) {
- q = mk_list_entry(head, struct mk_fifo_queue, _head);
- if (strlen(q->name) != (unsigned int) len) {
- continue;
- }
-
- if (strncmp(q->name, name, len) == 0) {
- return -1;
- }
- }
-
- /* Allocate and register queue */
- q = mk_mem_alloc(sizeof(struct mk_fifo_queue));
- if (!q) {
- perror("malloc");
- return -1;
- }
- q->id = id;
- q->cb_message = cb;
- q->data = data;
-
- strncpy(q->name, name, len);
- q->name[len] = '\0';
- mk_list_add(&q->_head, &ctx->queues);
-
- return id;
-}
-
-struct mk_fifo_queue *mk_fifo_queue_get(struct mk_fifo *ctx, int id)
-{
- struct mk_list *head;
- struct mk_fifo_queue *q = NULL;
-
- mk_list_foreach(head, &ctx->queues) {
- q = mk_list_entry(head, struct mk_fifo_queue, _head);
- if (q->id == id) {
- return q;
- }
- }
-
- return NULL;
-}
-
-int mk_fifo_queue_destroy(struct mk_fifo *ctx, struct mk_fifo_queue *q)
-{
- (void) ctx;
-
- mk_list_del(&q->_head);
- mk_mem_free(q);
- return 0;
-}
-
-int mk_fifo_queue_id_destroy(struct mk_fifo *ctx, int id)
-{
- struct mk_fifo_queue *q;
-
- q = mk_fifo_queue_get(ctx, id);
- if (!q) {
- return -1;
- }
-
- mk_fifo_queue_destroy(ctx, q);
- return 0;
-}
-
-static int mk_fifo_queue_destroy_all(struct mk_fifo *ctx)
-{
- int c = 0;
- struct mk_list *tmp;
- struct mk_list *head;
- struct mk_fifo_queue *q;
-
- mk_list_foreach_safe(head, tmp, &ctx->queues) {
- q = mk_list_entry(head, struct mk_fifo_queue, _head);
- mk_fifo_queue_destroy(ctx, q);
- c++;
- }
-
- return c;
-}
-
-static int mk_fifo_worker_destroy_all(struct mk_fifo *ctx)
-{
- int c = 0;
- struct mk_list *tmp;
- struct mk_list *head;
- struct mk_fifo_worker *fw;
-
- mk_list_foreach_safe(head, tmp, &ctx->workers) {
- fw = mk_list_entry(head, struct mk_fifo_worker, _head);
-
-#ifdef _WIN32
- evutil_closesocket(fw->channel[0]);
- evutil_closesocket(fw->channel[1]);
-#else
- close(fw->channel[0]);
- close(fw->channel[1]);
-#endif
- mk_list_del(&fw->_head);
- mk_mem_free(fw->buf_data);
- mk_mem_free(fw);
- c++;
- }
-
- return c;
-}
-
-static int msg_write(int fd, void *buf, size_t count)
-{
- ssize_t bytes;
- size_t total = 0;
-
- do {
-#ifdef _WIN32
- bytes = send(fd, (uint8_t *)buf + total, count - total, 0);
-#else
- bytes = write(fd, (uint8_t *)buf + total, count - total);
-#endif
- if (bytes == -1) {
- if (errno == EAGAIN) {
- /*
- * This could happen, since this function goal is not to
- * return until all data have been read, just sleep a little
- * bit (0.05 seconds)
- */
-
-#ifdef _WIN32
- Sleep(5);
-#else
- usleep(50000);
-#endif
- continue;
- }
- }
- else if (bytes == 0) {
- /* Broken pipe ? */
- perror("write");
- return -1;
- }
- total += bytes;
-
- } while (total < count);
-
- return total;
-}
-
-/*
- * Push a message into a queue: this function runs from the parent thread
- * so it needs to write the message to every thread pipe channel.
- */
-int mk_fifo_send(struct mk_fifo *ctx, int id, void *data, size_t size)
-{
- int ret;
- struct mk_list *head;
- struct mk_fifo_msg msg;
- struct mk_fifo_queue *q;
- struct mk_fifo_worker *fw;
-
- /* Validate queue ID */
- q = mk_fifo_queue_get(ctx, id);
- if (!q) {
- return -1;
- }
-
- pthread_mutex_lock(&ctx->mutex_init);
-
- mk_list_foreach(head, &ctx->workers) {
- fw = mk_list_entry(head, struct mk_fifo_worker, _head);
-
- msg.length = size;
- msg.flags = 0;
- msg.queue_id = (uint16_t) id;
-
- ret = msg_write(fw->channel[1], &msg, sizeof(struct mk_fifo_msg));
- if (ret == -1) {
- pthread_mutex_unlock(&ctx->mutex_init);
- perror("write");
- fprintf(stderr, "[msg] error writing message header\n");
- return -1;
- }
-
- ret = msg_write(fw->channel[1], data, size);
- if (ret == -1) {
- pthread_mutex_unlock(&ctx->mutex_init);
- perror("write");
- fprintf(stderr, "[msg] error writing message body\n");
- return -1;
- }
- }
-
- pthread_mutex_unlock(&ctx->mutex_init);
-
- return 0;
-}
-
-static inline void consume_bytes(char *buf, int bytes, int length)
-{
- memmove(buf, buf + bytes, length - bytes);
-}
-
-static inline int fifo_drop_msg(struct mk_fifo_worker *fw)
-{
- size_t drop_bytes;
- struct mk_fifo_msg *msg;
-
- msg = (struct mk_fifo_msg *) fw->buf_data;
- drop_bytes = (sizeof(struct mk_fifo_msg) + msg->length);
- consume_bytes(fw->buf_data, drop_bytes, fw->buf_len);
- fw->buf_len -= drop_bytes;
-
- return 0;
-}
-
-static inline int fifo_is_msg_ready(struct mk_fifo_worker *fw)
-{
- struct mk_fifo_msg *msg;
-
- msg = (struct mk_fifo_msg *) fw->buf_data;
- if (fw->buf_len >= (msg->length + sizeof(struct mk_fifo_msg))) {
- return MK_TRUE;
- }
-
- return MK_FALSE;
-}
-
-int mk_fifo_worker_read(void *event)
-{
- int available;
- char *tmp;
- size_t size;
- ssize_t bytes;
- struct mk_fifo_msg *fm;
- struct mk_fifo_worker *fw;
- struct mk_fifo_queue *fq;
-
- fw = (struct mk_fifo_worker *) event;
-
- /* Check available space */
- available = fw->buf_size - fw->buf_len;
- if (available <= 1) {
- size = fw->buf_size + (MK_FIFO_BUF_SIZE / 2);
- tmp = mk_mem_realloc(fw->buf_data, size);
- if (!tmp) {
- perror("realloc");
- return -1;
- }
- fw->buf_data = tmp;
- fw->buf_size = size;
- available = fw->buf_size - fw->buf_len;
- }
-
- /* Read data from pipe */
-#ifdef _WIN32
- bytes = recv(fw->channel[0], fw->buf_data + fw->buf_len, available, 0);
-#else
- bytes = read(fw->channel[0], fw->buf_data + fw->buf_len, available);
-#endif
-
- if (bytes == 0) {
- return -1;
- }
- else if (bytes == -1){
- perror("read");
- return -1;
- }
-
- fw->buf_len += bytes;
-
- /* Find messages and trigger callbacks */
- while (fw->buf_len > 0) {
- if (fifo_is_msg_ready(fw) == MK_TRUE) {
- /* we got a complete message */
- fm = (struct mk_fifo_msg *) fw->buf_data;
- fq = mk_fifo_queue_get(fw->fifo, fm->queue_id);
- if (!fq) {
- /* Invalid queue */
- fprintf(stderr, "[fifo worker read] invalid queue id %i\n",
- fm->queue_id);
- fifo_drop_msg(fw);
- continue;
- }
-
- /* Trigger callback if any */
- if (fq->cb_message) {
- fq->cb_message(fq, fm->data, fm->length, fq->data);
- }
- fifo_drop_msg(fw);
- }
- else {
- /* msg not ready */
- break;
- }
- }
-
- return 0;
-}
-
-int mk_fifo_destroy(struct mk_fifo *ctx)
-{
- mk_fifo_queue_destroy_all(ctx);
- mk_fifo_worker_destroy_all(ctx);
- mk_mem_free(ctx);
- return 0;
-}
diff --git a/fluent-bit/lib/monkey/mk_server/mk_header.c b/fluent-bit/lib/monkey/mk_server/mk_header.c
deleted file mode 100644
index cd8f77bd..00000000
--- a/fluent-bit/lib/monkey/mk_server/mk_header.c
+++ /dev/null
@@ -1,451 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-
-/* Monkey HTTP Server
- * ==================
- * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <monkey/monkey.h>
-#include <monkey/mk_server.h>
-#include <monkey/mk_header.h>
-#include <monkey/mk_core.h>
-#include <monkey/mk_http_status.h>
-#include <monkey/mk_config.h>
-#include <monkey/mk_socket.h>
-#include <monkey/mk_utils.h>
-#include <monkey/mk_clock.h>
-#include <monkey/mk_cache.h>
-#include <monkey/mk_http.h>
-#include <monkey/mk_vhost.h>
-#include <monkey/mk_tls.h>
-
-#define MK_HEADER_SHORT_DATE "Date: "
-#define MK_HEADER_SHORT_LOCATION "Location: "
-#define MK_HEADER_SHORT_CT "Content-Type: "
-#define MK_HEADER_ACCEPT_RANGES "Accept-Ranges: bytes" MK_CRLF
-#define MK_HEADER_ALLOWED_METHODS "Allow: "
-#define MK_HEADER_CONN_KA "Connection: Keep-Alive" MK_CRLF
-#define MK_HEADER_CONN_CLOSE "Connection: Close" MK_CRLF
-#define MK_HEADER_CONN_UPGRADE "Connection: Upgrade" MK_CRLF
-#define MK_HEADER_CONTENT_LENGTH "Content-Length: "
-#define MK_HEADER_CONTENT_ENCODING "Content-Encoding: "
-#define MK_HEADER_TE_CHUNKED "Transfer-Encoding: chunked" MK_CRLF
-#define MK_HEADER_LAST_MODIFIED "Last-Modified: "
-#define MK_HEADER_UPGRADE_H2C "Upgrade: h2c" MK_CRLF
-
-const mk_ptr_t mk_header_short_date = mk_ptr_init(MK_HEADER_SHORT_DATE);
-const mk_ptr_t mk_header_short_location = mk_ptr_init(MK_HEADER_SHORT_LOCATION);
-const mk_ptr_t mk_header_short_ct = mk_ptr_init(MK_HEADER_SHORT_CT);
-const mk_ptr_t mk_header_allow = mk_ptr_init(MK_HEADER_ALLOWED_METHODS);
-
-const mk_ptr_t mk_header_conn_ka = mk_ptr_init(MK_HEADER_CONN_KA);
-const mk_ptr_t mk_header_conn_close = mk_ptr_init(MK_HEADER_CONN_CLOSE);
-const mk_ptr_t mk_header_conn_upgrade = mk_ptr_init(MK_HEADER_CONN_UPGRADE);
-const mk_ptr_t mk_header_content_length = mk_ptr_init(MK_HEADER_CONTENT_LENGTH);
-const mk_ptr_t mk_header_content_encoding = mk_ptr_init(MK_HEADER_CONTENT_ENCODING);
-const mk_ptr_t mk_header_accept_ranges = mk_ptr_init(MK_HEADER_ACCEPT_RANGES);
-const mk_ptr_t mk_header_te_chunked = mk_ptr_init(MK_HEADER_TE_CHUNKED);
-const mk_ptr_t mk_header_last_modified = mk_ptr_init(MK_HEADER_LAST_MODIFIED);
-const mk_ptr_t mk_header_upgrade_h2c = mk_ptr_init(MK_HEADER_UPGRADE_H2C);
-
-#define status_entry(num, str) {num, sizeof(str) - 1, str}
-
-static const struct header_status_response status_response[] = {
-
- /*
- * The most used first:
- *
- * - HTTP/1.1 200 OK
- * - HTTP/1.1 404 Not Found
- */
- status_entry(MK_HTTP_OK, MK_RH_HTTP_OK),
- status_entry(MK_CLIENT_NOT_FOUND, MK_RH_CLIENT_NOT_FOUND),
-
- /* Informational */
- status_entry(MK_INFO_CONTINUE, MK_RH_INFO_CONTINUE),
- status_entry(MK_INFO_SWITCH_PROTOCOL, MK_RH_INFO_SWITCH_PROTOCOL),
-
- /* Successful */
- status_entry(MK_HTTP_CREATED, MK_RH_HTTP_CREATED),
- status_entry(MK_HTTP_ACCEPTED, MK_RH_HTTP_ACCEPTED),
- status_entry(MK_HTTP_NON_AUTH_INFO, MK_RH_HTTP_NON_AUTH_INFO),
- status_entry(MK_HTTP_NOCONTENT, MK_RH_HTTP_NOCONTENT),
- status_entry(MK_HTTP_RESET, MK_RH_HTTP_RESET),
- status_entry(MK_HTTP_PARTIAL, MK_RH_HTTP_PARTIAL),
-
- /* Redirections */
- status_entry(MK_REDIR_MULTIPLE, MK_RH_REDIR_MULTIPLE),
- status_entry(MK_REDIR_MOVED, MK_RH_REDIR_MOVED),
- status_entry(MK_REDIR_MOVED_T, MK_RH_REDIR_MOVED_T),
- status_entry(MK_REDIR_SEE_OTHER, MK_RH_REDIR_SEE_OTHER),
- status_entry(MK_NOT_MODIFIED, MK_RH_NOT_MODIFIED),
- status_entry(MK_REDIR_USE_PROXY, MK_RH_REDIR_USE_PROXY),
-
- /* Client side errors */
- status_entry(MK_CLIENT_BAD_REQUEST, MK_RH_CLIENT_BAD_REQUEST),
- status_entry(MK_CLIENT_UNAUTH, MK_RH_CLIENT_UNAUTH),
- status_entry(MK_CLIENT_PAYMENT_REQ, MK_RH_CLIENT_PAYMENT_REQ),
- status_entry(MK_CLIENT_FORBIDDEN, MK_RH_CLIENT_FORBIDDEN),
- status_entry(MK_CLIENT_METHOD_NOT_ALLOWED, MK_RH_CLIENT_METHOD_NOT_ALLOWED),
- status_entry(MK_CLIENT_NOT_ACCEPTABLE, MK_RH_CLIENT_NOT_ACCEPTABLE),
- status_entry(MK_CLIENT_PROXY_AUTH, MK_RH_CLIENT_PROXY_AUTH),
- status_entry(MK_CLIENT_REQUEST_TIMEOUT, MK_RH_CLIENT_REQUEST_TIMEOUT),
- status_entry(MK_CLIENT_CONFLICT, MK_RH_CLIENT_CONFLICT),
- status_entry(MK_CLIENT_GONE, MK_RH_CLIENT_GONE),
- status_entry(MK_CLIENT_LENGTH_REQUIRED, MK_RH_CLIENT_LENGTH_REQUIRED),
- status_entry(MK_CLIENT_PRECOND_FAILED, MK_RH_CLIENT_PRECOND_FAILED),
- status_entry(MK_CLIENT_REQUEST_ENTITY_TOO_LARGE,
- MK_RH_CLIENT_REQUEST_ENTITY_TOO_LARGE),
- status_entry(MK_CLIENT_REQUEST_URI_TOO_LONG,
- MK_RH_CLIENT_REQUEST_URI_TOO_LONG),
- status_entry(MK_CLIENT_UNSUPPORTED_MEDIA, MK_RH_CLIENT_UNSUPPORTED_MEDIA),
- status_entry(MK_CLIENT_REQUESTED_RANGE_NOT_SATISF,
- MK_RH_CLIENT_REQUESTED_RANGE_NOT_SATISF),
-
- /* Server side errors */
- status_entry(MK_SERVER_INTERNAL_ERROR, MK_RH_SERVER_INTERNAL_ERROR),
- status_entry(MK_SERVER_NOT_IMPLEMENTED, MK_RH_SERVER_NOT_IMPLEMENTED),
- status_entry(MK_SERVER_BAD_GATEWAY, MK_RH_SERVER_BAD_GATEWAY),
- status_entry(MK_SERVER_SERVICE_UNAV, MK_RH_SERVER_SERVICE_UNAV),
- status_entry(MK_SERVER_GATEWAY_TIMEOUT, MK_RH_SERVER_GATEWAY_TIMEOUT),
- status_entry(MK_SERVER_HTTP_VERSION_UNSUP, MK_RH_SERVER_HTTP_VERSION_UNSUP)
-};
-
-static const int status_response_len =
- (sizeof(status_response)/(sizeof(status_response[0])));
-
-static void mk_header_cb_finished(struct mk_stream_input *in)
-{
- struct mk_iov *iov = in->buffer;
-
- mk_iov_free_marked(iov);
-
-#if defined(__APPLE__)
- /*
- * Disable TCP_CORK right away, according to:
- *
- * ---
- * commit 81e8b869d70f9da93ddfbfb17ec7f12ce3c28fc6
- * Author: Sonny Karlsson <ksonny@lotrax.org>
- * Date: Sat Oct 18 12:11:49 2014 +0200
- *
- * http: Remove cork before first call to sendfile().
- *
- * This removes a large delay on Mac OS X when headers and file content
- * does not fill a single frame.
- * Deactivating TCP_NOPUSH does not cause pending frames to be sent until
- * the next write operation.
- * ---
- */
-
- mk_server_cork_flag(in->stream->channel->fd, TCP_CORK_OFF);
-#endif
-}
-
-static void cb_stream_iov_extended_free(struct mk_stream_input *in)
-{
- struct mk_iov *iov;
-
- iov = in->buffer;
- mk_iov_free(iov);
-}
-
-/* Send response headers */
-int mk_header_prepare(struct mk_http_session *cs, struct mk_http_request *sr,
- struct mk_server *server)
-{
- int i = 0;
- unsigned long len = 0;
- char *buffer = 0;
- mk_ptr_t response;
- struct response_headers *sh;
- struct mk_iov *iov;
-
- sh = &sr->headers;
- iov = &sh->headers_iov;
-
- /* HTTP Status Code */
- if (sh->status == MK_CUSTOM_STATUS) {
- response.data = sh->custom_status.data;
- response.len = sh->custom_status.len;
- }
- else {
- for (i = 0; i < status_response_len; i++) {
- if (status_response[i].status == sh->status) {
- response.data = status_response[i].response;
- response.len = status_response[i].length;
- break;
- }
- }
- }
-
- /* Invalid status set */
- mk_bug(i == status_response_len);
-
- mk_iov_add(iov, response.data, response.len, MK_FALSE);
-
- /*
- * Preset headers (mk_clock.c):
- *
- * - Server
- * - Date
- */
- mk_iov_add(iov,
- server->clock_context->headers_preset.data,
- server->clock_context->headers_preset.len,
- MK_FALSE);
-
- /* Last-Modified */
- if (sh->last_modified > 0) {
- mk_ptr_t *lm = MK_TLS_GET(mk_tls_cache_header_lm);
- lm->len = mk_utils_utime2gmt(&lm->data, sh->last_modified);
-
- mk_iov_add(iov,
- mk_header_last_modified.data,
- mk_header_last_modified.len,
- MK_FALSE);
- mk_iov_add(iov,
- lm->data,
- lm->len,
- MK_FALSE);
- }
-
- /* Connection */
- if (sh->connection == 0) {
- if (cs->close_now == MK_FALSE) {
- if (sr->connection.len > 0) {
- if (sr->protocol != MK_HTTP_PROTOCOL_11) {
- mk_iov_add(iov,
- mk_header_conn_ka.data,
- mk_header_conn_ka.len,
- MK_FALSE);
- }
- }
- }
- else {
- mk_iov_add(iov,
- mk_header_conn_close.data,
- mk_header_conn_close.len,
- MK_FALSE);
- }
- }
- else if (sh->connection == MK_HEADER_CONN_UPGRADED) {
- mk_iov_add(iov,
- mk_header_conn_upgrade.data,
- mk_header_conn_upgrade.len,
- MK_FALSE);
- }
-
- /* Location */
- if (sh->location != NULL) {
- mk_iov_add(iov,
- mk_header_short_location.data,
- mk_header_short_location.len,
- MK_FALSE);
-
- mk_iov_add(iov,
- sh->location,
- strlen(sh->location),
- MK_TRUE);
- }
-
- /* allowed methods */
- if (sh->allow_methods.len > 0) {
- mk_iov_add(iov,
- mk_header_allow.data,
- mk_header_allow.len,
- MK_FALSE);
- mk_iov_add(iov,
- sh->allow_methods.data,
- sh->allow_methods.len,
- MK_FALSE);
- }
-
- /* Content type */
- if (sh->content_type.len > 0) {
- mk_iov_add(iov,
- sh->content_type.data,
- sh->content_type.len,
- MK_FALSE);
- }
-
- /*
- * Transfer Encoding: the transfer encoding header is just sent when
- * the response has some content defined by the HTTP status response
- */
- switch (sh->transfer_encoding) {
- case MK_HEADER_TE_TYPE_CHUNKED:
- mk_iov_add(iov,
- mk_header_te_chunked.data,
- mk_header_te_chunked.len,
- MK_FALSE);
- break;
- }
-
- /* E-Tag */
- if (sh->etag_len > 0) {
- mk_iov_add(iov, sh->etag_buf, sh->etag_len, MK_FALSE);
- }
-
- /* Content-Encoding */
- if (sh->content_encoding.len > 0) {
- mk_iov_add(iov, mk_header_content_encoding.data,
- mk_header_content_encoding.len,
- MK_FALSE);
- mk_iov_add(iov, sh->content_encoding.data,
- sh->content_encoding.len,
- MK_FALSE);
- }
-
- /* Content-Length */
- if (sh->content_length >= 0 && sh->transfer_encoding != 0) {
- /* Map content length to MK_POINTER */
- mk_ptr_t *cl = MK_TLS_GET(mk_tls_cache_header_cl);
- mk_string_itop(sh->content_length, cl);
-
- /* Set headers */
- mk_iov_add(iov,
- mk_header_content_length.data,
- mk_header_content_length.len,
- MK_FALSE);
- mk_iov_add(iov,
- cl->data,
- cl->len,
- MK_FALSE);
- }
-
- if ((sh->content_length != 0 && (sh->ranges[0] >= 0 || sh->ranges[1] >= 0)) &&
- server->resume == MK_TRUE) {
- buffer = 0;
-
- /* yyy- */
- if (sh->ranges[0] >= 0 && sh->ranges[1] == -1) {
- mk_string_build(&buffer,
- &len,
- "%s bytes %d-%ld/%ld\r\n",
- RH_CONTENT_RANGE,
- sh->ranges[0],
- (sh->real_length - 1), sh->real_length);
- mk_iov_add(iov, buffer, len, MK_TRUE);
- }
-
- /* yyy-xxx */
- if (sh->ranges[0] >= 0 && sh->ranges[1] >= 0) {
- mk_string_build(&buffer,
- &len,
- "%s bytes %d-%d/%ld\r\n",
- RH_CONTENT_RANGE,
- sh->ranges[0], sh->ranges[1], sh->real_length);
-
- mk_iov_add(iov, buffer, len, MK_TRUE);
- }
-
- /* -xxx */
- if (sh->ranges[0] == -1 && sh->ranges[1] > 0) {
- mk_string_build(&buffer,
- &len,
- "%s bytes %ld-%ld/%ld\r\n",
- RH_CONTENT_RANGE,
- (sh->real_length - sh->ranges[1]),
- (sh->real_length - 1), sh->real_length);
- mk_iov_add(iov, buffer, len, MK_TRUE);
- }
- }
-
- if (sh->upgrade == MK_HEADER_UPGRADED_H2C) {
- mk_iov_add(iov, mk_header_upgrade_h2c.data, mk_header_upgrade_h2c.len,
- MK_FALSE);
- }
-
-
- if (sh->cgi == SH_NOCGI || sh->breakline == MK_HEADER_BREAKLINE) {
- if (!sr->headers._extra_rows) {
- mk_iov_add(iov, mk_iov_crlf.data, mk_iov_crlf.len,
- MK_FALSE);
- }
- else {
- mk_iov_add(sr->headers._extra_rows, mk_iov_crlf.data,
- mk_iov_crlf.len, MK_FALSE);
- }
- }
-
- /*
- * Configure the Stream to dispatch the headers
- */
-
- /* Set the IOV input stream */
- sr->in_headers.buffer = iov;
- sr->in_headers.bytes_total = iov->total_len;
- sr->in_headers.cb_finished = mk_header_cb_finished;
-
- if (sr->headers._extra_rows) {
- /* Our main sr->stream contains the main headers (header_iov)
- * and 'may' have already some linked data. If we have some
- * extra headers rows we need to link this IOV right after
- * the main header_iov.
- */
- struct mk_stream_input *in = &sr->in_headers_extra;
- in->type = MK_STREAM_IOV;
- in->dynamic = MK_FALSE;
- in->cb_consumed = NULL;
- in->cb_finished = cb_stream_iov_extended_free;
- in->stream = &sr->stream;
- in->buffer = sr->headers._extra_rows;
- in->bytes_total = sr->headers._extra_rows->total_len;
-
- mk_list_add_after(&sr->in_headers_extra._head,
- &sr->in_headers._head,
- &sr->stream.inputs);
- }
-
- sh->sent = MK_TRUE;
-
- return 0;
-}
-
-void mk_header_set_http_status(struct mk_http_request *sr, int status)
-{
- mk_bug(!sr);
- sr->headers.status = status;
-
- MK_TRACE("Set HTTP status = %i", status);
-}
-
-void mk_header_response_reset(struct response_headers *header)
-{
- struct mk_iov *iov;
-
- header->status = -1;
- header->sent = MK_FALSE;
- header->ranges[0] = -1;
- header->ranges[1] = -1;
- header->content_length = -1;
- header->connection = 0;
- header->transfer_encoding = -1;
- header->last_modified = -1;
- header->upgrade = -1;
- header->cgi = SH_NOCGI;
- mk_ptr_reset(&header->content_type);
- mk_ptr_reset(&header->content_encoding);
- header->location = NULL;
- header->_extra_rows = NULL;
- header->allow_methods.len = 0;
-
- /* Initialize headers IOV */
- iov = &header->headers_iov;
- iov->io = (struct iovec *) &header->__iov_io;
- iov->buf_to_free = (void *) &header->__iov_buf;
- mk_iov_init(&header->headers_iov, MK_HEADER_IOV, 0);
-}
diff --git a/fluent-bit/lib/monkey/mk_server/mk_http.c b/fluent-bit/lib/monkey/mk_server/mk_http.c
deleted file mode 100644
index 1e2d219d..00000000
--- a/fluent-bit/lib/monkey/mk_server/mk_http.c
+++ /dev/null
@@ -1,1638 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-
-/* Monkey HTTP Server
- * ==================
- * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define _GNU_SOURCE
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <sys/stat.h>
-#include <fcntl.h>
-//#include <regex.h>
-#include <re.h>
-
-#include <monkey/monkey.h>
-#include <monkey/mk_user.h>
-#include <monkey/mk_core.h>
-#include <monkey/mk_http.h>
-#include <monkey/mk_http_status.h>
-#include <monkey/mk_http_thread.h>
-#include <monkey/mk_clock.h>
-#include <monkey/mk_utils.h>
-#include <monkey/mk_config.h>
-#include <monkey/mk_socket.h>
-#include <monkey/mk_mimetype.h>
-#include <monkey/mk_header.h>
-#include <monkey/mk_plugin.h>
-#include <monkey/mk_vhost.h>
-#include <monkey/mk_server.h>
-#include <monkey/mk_plugin_stage.h>
-
-const mk_ptr_t mk_http_method_get_p = mk_ptr_init(MK_METHOD_GET_STR);
-const mk_ptr_t mk_http_method_post_p = mk_ptr_init(MK_METHOD_POST_STR);
-const mk_ptr_t mk_http_method_head_p = mk_ptr_init(MK_METHOD_HEAD_STR);
-const mk_ptr_t mk_http_method_put_p = mk_ptr_init(MK_METHOD_PUT_STR);
-const mk_ptr_t mk_http_method_delete_p = mk_ptr_init(MK_METHOD_DELETE_STR);
-const mk_ptr_t mk_http_method_options_p = mk_ptr_init(MK_METHOD_OPTIONS_STR);
-const mk_ptr_t mk_http_method_null_p = { NULL, 0 };
-
-const mk_ptr_t mk_http_protocol_09_p = mk_ptr_init(MK_HTTP_PROTOCOL_09_STR);
-const mk_ptr_t mk_http_protocol_10_p = mk_ptr_init(MK_HTTP_PROTOCOL_10_STR);
-const mk_ptr_t mk_http_protocol_11_p = mk_ptr_init(MK_HTTP_PROTOCOL_11_STR);
-const mk_ptr_t mk_http_protocol_null_p = { NULL, 0 };
-
-/* Create a memory allocation in order to handle the request data */
-void mk_http_request_init(struct mk_http_session *session,
- struct mk_http_request *request,
- struct mk_server *server)
-{
- struct mk_list *host_list = &server->hosts;
-
- request->port = 0;
- request->status = MK_TRUE;
- request->uri.data = NULL;
- request->method = MK_METHOD_UNKNOWN;
- request->protocol = MK_HTTP_PROTOCOL_UNKNOWN;
- request->connection.len = -1;
- request->file_fd = -1;
- request->file_info.size = -1;
- request->vhost_fdt_id = 0;
- request->vhost_fdt_hash = 0;
- request->vhost_fdt_enabled = MK_FALSE;
- request->host.data = NULL;
- request->stage30_blocked = MK_FALSE;
- request->session = session;
- request->host_conf = mk_list_entry_first(host_list, struct mk_vhost, _head);
- request->uri_processed.data = NULL;
- request->real_path.data = NULL;
- request->handler_data = NULL;
-
- request->in_file.fd = -1;
-
- /* Response Headers */
- mk_header_response_reset(&request->headers);
-
- /* Reset callbacks for headers stream */
- mk_stream_set(&request->stream,
- session->channel,
- NULL,
- NULL, NULL, NULL);
-}
-
-static inline int mk_http_point_header(mk_ptr_t *h,
- struct mk_http_parser *parser, int key)
-{
- struct mk_http_header *header;
-
- header = &parser->headers[key];
- if (header->type == key) {
- h->data = header->val.data;
- h->len = header->val.len;
- return 0;
- }
- else {
- h->data = NULL;
- h->len = -1;
- }
-
- return -1;
-}
-
-static int mk_http_request_prepare(struct mk_http_session *cs,
- struct mk_http_request *sr,
- struct mk_server *server)
-{
- int ret;
- int status = 0;
- char *temp;
- struct mk_list *hosts = &server->hosts;
- struct mk_list *alias;
- struct mk_http_header *header;
-
- /*
- * Process URI, if it contains ASCII encoded strings like '%20',
- * it will return a new memory buffer with the decoded string, otherwise
- * it returns NULL
- */
- temp = mk_utils_url_decode(sr->uri);
-
- if (temp) {
- sr->uri_processed.data = temp;
- sr->uri_processed.len = strlen(temp);
- }
- else {
- sr->uri_processed.data = sr->uri.data;
- sr->uri_processed.len = sr->uri.len;
- }
-
- /* Always assign the default vhost' */
- sr->host_conf = mk_list_entry_first(hosts, struct mk_vhost, _head);
- sr->user_home = MK_FALSE;
-
- /* Valid request URI? */
- if (sr->uri_processed.data[0] != '/') {
- mk_http_error(MK_CLIENT_BAD_REQUEST, cs, sr, server);
- return MK_EXIT_OK;
- }
-
- /* Check if we have a Host header: Hostname ; port */
- mk_http_point_header(&sr->host, &cs->parser, MK_HEADER_HOST);
-
- /* Header: Connection */
- mk_http_point_header(&sr->connection, &cs->parser, MK_HEADER_CONNECTION);
-
- /* Header: Range */
- mk_http_point_header(&sr->range, &cs->parser, MK_HEADER_RANGE);
-
- /* Header: If-Modified-Since */
- mk_http_point_header(&sr->if_modified_since,
- &cs->parser,
- MK_HEADER_IF_MODIFIED_SINCE);
-
- /* HTTP/1.1 needs Host header */
- if (!sr->host.data && sr->protocol == MK_HTTP_PROTOCOL_11) {
- mk_http_error(MK_CLIENT_BAD_REQUEST, cs, sr, server);
- return MK_EXIT_OK;
- }
-
- /* Should we close the session after this request ? */
- mk_http_keepalive_check(cs, sr, server);
-
- /* Content Length */
- header = &cs->parser.headers[MK_HEADER_CONTENT_LENGTH];
- if (header->type == MK_HEADER_CONTENT_LENGTH) {
- sr->_content_length.data = header->val.data;
- sr->_content_length.len = header->val.len;
- }
- else {
- sr->_content_length.data = NULL;
- }
-
- /* Assign the first node alias */
- alias = &sr->host_conf->server_names;
- sr->host_alias = mk_list_entry_first(alias,
- struct mk_vhost_alias, _head);
-
- if (sr->host.data) {
- /* Set the given port */
- if (cs->parser.header_host_port > 0) {
- sr->port = cs->parser.header_host_port;
- }
-
- /* Match the virtual host */
- mk_vhost_get(sr->host, &sr->host_conf, &sr->host_alias, server);
-
- /* Check if this virtual host have some redirection */
- if (sr->host_conf->header_redirect.data) {
- mk_header_set_http_status(sr, MK_REDIR_MOVED);
- sr->headers.location = mk_string_dup(sr->host_conf->header_redirect.data);
- sr->headers.content_length = 0;
- sr->headers.location = NULL;
- mk_header_prepare(cs, sr, server);
- return 0;
- }
- }
-
- /* Is requesting an user home directory ? */
- if (server->conf_user_pub &&
- sr->uri_processed.len > 2 &&
- sr->uri_processed.data[1] == MK_USER_HOME) {
-
- if (mk_user_init(cs, sr, server) != 0) {
- mk_http_error(MK_CLIENT_NOT_FOUND, cs, sr, server);
- return MK_EXIT_ABORT;
- }
- }
-
- /* Plugins Stage 20 */
- ret = mk_plugin_stage_run_20(cs, sr, server);
- if (ret == MK_PLUGIN_RET_CLOSE_CONX) {
- MK_TRACE("STAGE 20 requested close conexion");
- return MK_EXIT_ABORT;
- }
-
- /* Normal HTTP process */
- status = mk_http_init(cs, sr, server);
-
- MK_TRACE("[FD %i] HTTP Init returning %i", cs->socket, status);
- return status;
-}
-
-/*
- * This function allow the core to invoke the closing connection process
- * when some connection was not proceesed due to a premature close or similar
- * exception, it also take care of invoke the STAGE_40 and STAGE_50 plugins events
- */
-static void mk_request_premature_close(int http_status, struct mk_http_session *cs,
- struct mk_server *server)
-{
- struct mk_http_request *sr;
- struct mk_list *sr_list = &cs->request_list;
- struct mk_list *host_list = &server->hosts;
-
- /*
- * If the connection is too premature, we need to allocate a temporal session_request
- * to do not break the plugins stages
- */
- if (mk_list_is_empty(sr_list) == 0) {
- sr = &cs->sr_fixed;
- memset(sr, 0, sizeof(struct mk_http_request));
- mk_http_request_init(cs, sr, server);
- mk_list_add(&sr->_head, &cs->request_list);
- }
- else {
- sr = mk_list_entry_first(sr_list, struct mk_http_request, _head);
- }
-
- /* Raise error */
- if (http_status > 0) {
- if (!sr->host_conf) {
- sr->host_conf = mk_list_entry_first(host_list,
- struct mk_vhost, _head);
- }
- mk_http_error(http_status, cs, sr, server);
-
- /* STAGE_40, request has ended */
- mk_plugin_stage_run_40(cs, sr, server);
- }
-
- /* STAGE_50, connection closed and remove the http_session */
- mk_plugin_stage_run_50(cs->socket, server);
- mk_http_session_remove(cs, server);
-}
-
-int mk_http_handler_read(struct mk_sched_conn *conn, struct mk_http_session *cs,
- struct mk_server *server)
-{
- int bytes;
- int max_read;
- int available = 0;
- int new_size;
- int total_bytes = 0;
- char *tmp = 0;
-
-#ifdef MK_HAVE_TRACE
- int socket = conn->event.fd;
-#endif
-
- MK_TRACE("MAX REQUEST SIZE: %i", server->max_request_size);
-
- try_pending:
-
- available = cs->body_size - cs->body_length;
- if (available <= 0) {
- /* Reallocate buffer size if pending data does not have space */
- new_size = cs->body_size + conn->net->buffer_size;
- if (new_size > server->max_request_size) {
- MK_TRACE("Requested size is > mk_config->max_request_size");
- mk_request_premature_close(MK_CLIENT_REQUEST_ENTITY_TOO_LARGE, cs,
- server);
- return -1;
- }
-
- /*
- * Check if the body field still points to the initial body_fixed, if so,
- * allow the new space required in body, otherwise perform a realloc over
- * body.
- */
- if (cs->body == cs->body_fixed) {
- cs->body = mk_mem_alloc(new_size + 1);
- cs->body_size = new_size;
- memcpy(cs->body, cs->body_fixed, cs->body_length);
- MK_TRACE("[FD %i] New size: %i, length: %i",
- socket, new_size, cs->body_length);
- }
- else {
- MK_TRACE("[FD %i] Realloc from %i to %i",
- socket, cs->body_size, new_size);
- tmp = mk_mem_realloc(cs->body, new_size + 1);
- if (tmp) {
- cs->body = tmp;
- cs->body_size = new_size;
- }
- else {
- mk_request_premature_close(MK_SERVER_INTERNAL_ERROR, cs,
- server);
- return -1;
- }
- }
- }
-
- /* Read content */
- max_read = (cs->body_size - cs->body_length);
- bytes = mk_sched_conn_read(conn, cs->body + cs->body_length, max_read);
- MK_TRACE("[FD %i] read %i", socket, bytes);
-
- if (bytes == 0) {
- MK_TRACE("[FD %i] broken pipe?", socket);
- errno = 0;
- return -1;
- }
- else if (bytes == -1) {
- return -1;
- }
-
- if (bytes > max_read) {
- MK_TRACE("[FD %i] Buffer still have data: %i",
- socket, bytes - max_read);
- cs->body_length += max_read;
- cs->body[cs->body_length] = '\0';
- total_bytes += max_read;
-
- goto try_pending;
- }
- else {
- cs->body_length += bytes;
- cs->body[cs->body_length] = '\0';
-
- total_bytes += bytes;
- }
-
- MK_TRACE("[FD %i] Retry total bytes: %i", socket, total_bytes);
- return total_bytes;
-}
-
-/* Build error page */
-static int mk_http_error_page(char *title, mk_ptr_t *message, char *signature,
- char **out_buf, unsigned long *out_size)
-{
- char *temp;
-
- *out_buf = NULL;
-
- if (message) {
- temp = mk_ptr_to_buf(*message);
- }
- else {
- temp = mk_string_dup("");
- }
-
- mk_string_build(out_buf, out_size,
- MK_REQUEST_DEFAULT_PAGE, title, temp, signature);
- mk_mem_free(temp);
- return 0;
-}
-
-static int mk_http_range_set(struct mk_http_request *sr, size_t file_size,
- struct mk_server *server)
-{
- struct response_headers *sh = &sr->headers;
- struct mk_stream_input *in;
-
- in = &sr->in_file;
- in->bytes_total = file_size;
- in->bytes_offset = 0;
-
- if (server->resume == MK_TRUE && sr->range.data) {
- /* yyy- */
- if (sh->ranges[0] >= 0 && sh->ranges[1] == -1) {
- in->bytes_offset = sh->ranges[0];
- in->bytes_total = file_size - in->bytes_offset;
- }
-
- /* yyy-xxx */
- if (sh->ranges[0] >= 0 && sh->ranges[1] >= 0) {
- in->bytes_offset = sh->ranges[0];
- in->bytes_total = labs(sh->ranges[1] - sh->ranges[0]) + 1;
- }
-
- /* -xxx */
- if (sh->ranges[0] == -1 && sh->ranges[1] > 0) {
- in->bytes_total = sh->ranges[1];
- in->bytes_offset = file_size - sh->ranges[1];
- }
-
- if ((size_t) in->bytes_offset >= file_size ||
- in->bytes_total > file_size) {
- return -1;
- }
-
- lseek(in->fd, in->bytes_offset, SEEK_SET);
- }
- return 0;
-}
-
-static int mk_http_range_parse(struct mk_http_request *sr)
-{
- int eq_pos, sep_pos, len;
- char *buffer = 0;
- struct response_headers *sh;
-
- if (!sr->range.data)
- return -1;
-
- if ((eq_pos = mk_string_char_search(sr->range.data, '=', sr->range.len)) < 0)
- return -1;
-
- if (strncasecmp(sr->range.data, "Bytes", eq_pos) != 0)
- return -1;
-
- if ((sep_pos = mk_string_char_search(sr->range.data, '-', sr->range.len)) < 0)
- return -1;
-
- len = sr->range.len;
- sh = &sr->headers;
-
- /* =-xxx */
- if (eq_pos + 1 == sep_pos) {
- sh->ranges[0] = -1;
- sh->ranges[1] = (unsigned long) atol(sr->range.data + sep_pos + 1);
-
- if (sh->ranges[1] <= 0) {
- return -1;
- }
-
- sh->content_length = sh->ranges[1];
- return 0;
- }
-
- /* =yyy-xxx */
- if ((eq_pos + 1 != sep_pos) && (len > sep_pos + 1)) {
- buffer = mk_string_copy_substr(sr->range.data, eq_pos + 1, sep_pos);
- sh->ranges[0] = (unsigned long) atol(buffer);
- mk_mem_free(buffer);
-
- buffer = mk_string_copy_substr(sr->range.data, sep_pos + 1, len);
- sh->ranges[1] = (unsigned long) atol(buffer);
- mk_mem_free(buffer);
-
- if (sh->ranges[1] < 0 || (sh->ranges[0] > sh->ranges[1])) {
- return -1;
- }
-
- sh->content_length = abs(sh->ranges[1] - sh->ranges[0]) + 1;
- return 0;
- }
- /* =yyy- */
- if ((eq_pos + 1 != sep_pos) && (len == sep_pos + 1)) {
- buffer = mk_string_copy_substr(sr->range.data, eq_pos + 1, len);
- sr->headers.ranges[0] = (unsigned long) atol(buffer);
- mk_mem_free(buffer);
-
- sh->content_length = (sh->content_length - sh->ranges[0]);
- return 0;
- }
-
- return -1;
-}
-
-static int mk_http_directory_redirect_check(struct mk_http_session *cs,
- struct mk_http_request *sr,
- struct mk_server *server)
-{
- int port_redirect = 0;
- char *host;
- char *location = 0;
- char *real_location = 0;
- char *protocol = "http";
- unsigned long len;
-
- /*
- * We have to check if there is a slash at the end of
- * this string. If it doesn't exist, we send a redirection header.
- */
- if (sr->uri_processed.data[sr->uri_processed.len - 1] == '/') {
- return 0;
- }
-
- host = mk_ptr_to_buf(sr->host);
-
- /*
- * Add ending slash to the location string
- */
- location = mk_mem_alloc(sr->uri_processed.len + 2);
- memcpy(location, sr->uri_processed.data, sr->uri_processed.len);
- location[sr->uri_processed.len] = '/';
- location[sr->uri_processed.len + 1] = '\0';
-
- /* FIXME: should we done something similar for SSL = 443 */
- if (sr->host.data && sr->port > 0) {
- if (sr->port != server->standard_port) {
- port_redirect = sr->port;
- }
- }
-
- if (MK_SCHED_CONN_PROP(cs->conn) & MK_CAP_SOCK_TLS) {
- protocol = "https";
- }
-
- if (port_redirect > 0) {
- mk_string_build(&real_location, &len, "%s://%s:%i%s\r\n",
- protocol, host, port_redirect, location);
- }
- else {
- mk_string_build(&real_location, &len, "%s://%s%s\r\n",
- protocol, host, location);
- }
-
- MK_TRACE("Redirecting to '%s'", real_location);
- mk_mem_free(host);
-
- mk_header_set_http_status(sr, MK_REDIR_MOVED);
- sr->headers.content_length = 0;
-
- mk_ptr_reset(&sr->headers.content_type);
- sr->headers.location = real_location;
- sr->headers.cgi = SH_NOCGI;
- sr->headers.pconnections_left =
- (server->max_keep_alive_request - cs->counter_connections);
-
- mk_header_prepare(cs, sr, server);
-
- /* we do not free() real_location as it's freed by iov */
- mk_mem_free(location);
- sr->headers.location = NULL;
- return -1;
-}
-
-/* Look for some index.xxx in pathfile */
-static inline char *mk_http_index_lookup(mk_ptr_t *path_base,
- char *buf, size_t buf_size,
- size_t *out, size_t *bytes,
- struct mk_server *server)
-{
- off_t off = 0;
- size_t len;
- struct mk_string_line *entry;
- struct mk_list *head;
-
- if (!server->index_files) {
- return NULL;
- }
-
- off = path_base->len;
- memcpy(buf, path_base->data, off);
-
- mk_list_foreach(head, server->index_files) {
- entry = mk_list_entry(head, struct mk_string_line, _head);
-
- len = off + entry->len + 1;
- if (len >= buf_size) {
- continue;
- }
-
- memcpy(buf + off, entry->val, entry->len);
- buf[off + entry->len] = '\0';
-
- if (access(buf, F_OK) == 0) {
- MK_TRACE("Index lookup OK '%s'", buf);
- *out = off + entry->len;
- *bytes = path_base->len - 1;
- return buf;
- }
- }
-
- return NULL;
-}
-
-/* Turn CORK_OFF once headers are sent */
-#if defined (__linux__)
-static inline void mk_http_cb_file_on_consume(struct mk_stream_input *in,
- long bytes)
-{
- int ret;
- (void) bytes;
-
- /*
- * This callback is invoked just once as we want to turn off
- * the TCP Cork. We do this just overriding the callback for
- * the file stream.
- */
- ret = mk_server_cork_flag(in->stream->channel->fd, TCP_CORK_OFF);
- if (ret == -1) {
- mk_warn("Could not set TCP_CORK/TCP_NOPUSH off");
- }
- MK_TRACE("[FD %i] Disable TCP_CORK/TCP_NOPUSH",
- in->stream->channel->fd);
- in->cb_consumed = NULL;
-}
-#endif
-
-int mk_http_init(struct mk_http_session *cs, struct mk_http_request *sr,
- struct mk_server *server)
-{
- int ret;
- int ret_file;
- struct mk_mimetype *mime;
- struct mk_list *head;
- struct mk_list *handlers;
- struct mk_plugin *plugin;
- struct mk_vhost_handler *h_handler;
- struct mk_http_thread *mth = NULL;
- size_t index_length;
- size_t index_bytes;
- char *index_path = NULL;
-
- MK_TRACE("[FD %i] HTTP Protocol Init, session %p", cs->socket, sr);
-
- /* Request to root path of the virtualhost in question */
- if (sr->uri_processed.len == 1 && sr->uri_processed.data[0] == '/') {
- sr->real_path.data = sr->host_conf->documentroot.data;
- sr->real_path.len = sr->host_conf->documentroot.len;
- }
-
- /* Compose real path */
- if (sr->user_home == MK_FALSE) {
- int len;
-
- len = sr->host_conf->documentroot.len + sr->uri_processed.len;
- if (len < MK_PATH_BASE) {
- memcpy(sr->real_path_static,
- sr->host_conf->documentroot.data,
- sr->host_conf->documentroot.len);
- memcpy(sr->real_path_static + sr->host_conf->documentroot.len,
- sr->uri_processed.data,
- sr->uri_processed.len);
- sr->real_path_static[len] = '\0';
- sr->real_path.data = sr->real_path_static;
- sr->real_path.len = len;
- }
- else {
- ret = mk_buffer_cat(&sr->real_path,
- sr->host_conf->documentroot.data,
- sr->host_conf->documentroot.len,
- sr->uri_processed.data,
- sr->uri_processed.len);
-
- if (ret < 0) {
- MK_TRACE("Error composing real path");
- return MK_EXIT_ERROR;
- }
- }
- }
-
- /* Check if this is related to a protocol upgrade */
-#ifdef MK_HAVE_HTTP2
- if (cs->parser.header_connection & MK_HTTP_PARSER_CONN_UPGRADE) {
- /* HTTP/2.0 upgrade ? */
- if (cs->parser.header_connection & MK_HTTP_PARSER_CONN_HTTP2_SE) {
- MK_TRACE("Connection Upgrade request: HTTP/2.0");
- /*
- * This is a HTTP/2.0 upgrade, we need to validate that we
- * have at least the 'Upgrade' and 'HTTP2-Settings' headers.
- */
- struct mk_http_header *p;
- p = &cs->parser.headers[MK_HEADER_HTTP2_SETTINGS];
- if (cs->parser.header_upgrade == MK_HTTP_PARSER_UPGRADE_H2C &&
- p->key.data) {
- /*
- * Switch protocols and invoke the callback upgrade to prepare
- * the new protocol internals.
- */
- mk_sched_switch_protocol(cs->conn, MK_CAP_HTTP2);
- return cs->conn->protocol->cb_upgrade(cs, sr, server);
- }
- else {
- MK_TRACE("Invalid client upgrade request, skip it");
- }
- }
- }
-#endif
-
- /* Check backward directory request */
- if (memmem(sr->uri_processed.data, sr->uri_processed.len,
- MK_HTTP_DIRECTORY_BACKWARD,
- sizeof(MK_HTTP_DIRECTORY_BACKWARD) - 1)) {
- return mk_http_error(MK_CLIENT_FORBIDDEN, cs, sr, server);
- }
-
- if (sr->_content_length.data &&
- (sr->method != MK_METHOD_POST &&
- sr->method != MK_METHOD_PUT)) {
- sr->_content_length.data = NULL;
- sr->_content_length.len = 0;
- }
-
- ret_file = mk_file_get_info(sr->real_path.data, &sr->file_info, MK_FILE_READ);
-
- /* Manually set the headers input streams */
- sr->in_headers.type = MK_STREAM_IOV;
- sr->in_headers.dynamic = MK_FALSE;
- sr->in_headers.cb_consumed = NULL;
- sr->in_headers.cb_finished = NULL;
- sr->in_headers.stream = &sr->stream;
- mk_list_add(&sr->in_headers._head, &sr->stream.inputs);
-
- /* Plugin Stage 30: look for handlers for this request */
- if (sr->stage30_blocked == MK_FALSE) {
- sr->uri_processed.data[sr->uri_processed.len] = '\0';
- handlers = &sr->host_conf->handlers;
- mk_list_foreach(head, handlers) {
- h_handler = mk_list_entry(head, struct mk_vhost_handler, _head);
-
- if (re_matchp(h_handler->match,
- sr->uri_processed.data, NULL) == -1) {
- continue;
- }
-
- if (h_handler->cb) {
- /* Create coroutine/thread context */
- sr->headers.content_length = 0;
- mth = mk_http_thread_create(MK_HTTP_THREAD_LIB,
- h_handler,
- cs, sr,
- 0, NULL);
- if (!mth) {
- return -1;
- }
-
- mk_http_thread_start(mth);
- return MK_EXIT_OK;
- }
- else {
- if (!h_handler->handler) {
- return mk_http_error(MK_SERVER_INTERNAL_ERROR, cs, sr,
- server);
- }
- plugin = h_handler->handler;
- sr->stage30_handler = h_handler->handler;
- ret = plugin->stage->stage30(plugin, cs, sr,
- h_handler->n_params,
- &h_handler->params);
- mk_header_prepare(cs, sr, server);
- }
-
- MK_TRACE("[FD %i] STAGE_30 returned %i", cs->socket, ret);
- switch (ret) {
- case MK_PLUGIN_RET_CONTINUE:
- /* FIXME: PLUGINS DISABLED
- if ((plugin->flags & MK_PLUGIN_THREAD) &&
- plugin->stage->stage30_thread) {
- mth = mk_http_thread_new(MK_HTTP_THREAD_PLUGIN,
- plugin, cs, sr,
- h_handler->n_params,
- &h_handler->params);
- printf("[http thread] %p\n", mth);
- mk_http_thread_resume(mth->parent);
- }
- */
- return MK_PLUGIN_RET_CONTINUE;
- case MK_PLUGIN_RET_CLOSE_CONX:
- if (sr->headers.status > 0) {
- return mk_http_error(sr->headers.status, cs, sr, server);
- }
- else {
- return mk_http_error(MK_CLIENT_FORBIDDEN, cs, sr, server);
- }
- case MK_PLUGIN_RET_END:
- return MK_EXIT_OK;
- }
- }
- }
-
- /* If there is no handler and the resource don't exists, raise a 404 */
- if (ret_file == -1) {
- return mk_http_error(MK_CLIENT_NOT_FOUND, cs, sr, server);
- }
-
- /* is it a valid directory ? */
- if (sr->file_info.is_directory == MK_TRUE) {
- /* Send redirect header if end slash is not found */
- if (mk_http_directory_redirect_check(cs, sr, server) == -1) {
- MK_TRACE("Directory Redirect");
-
- /* Redirect has been sent */
- return -1;
- }
-
- /* looking for an index file */
- char tmppath[MK_MAX_PATH];
- index_path = mk_http_index_lookup(&sr->real_path,
- tmppath, MK_MAX_PATH,
- &index_length, &index_bytes,
- server);
- if (index_path) {
- if (sr->real_path.data != sr->real_path_static) {
- mk_ptr_free(&sr->real_path);
- sr->real_path.data = mk_string_dup(index_path);
- }
- /* If it's static and it still fits */
- else if (index_length < MK_PATH_BASE) {
- memcpy(sr->real_path_static, index_path, index_length);
- sr->real_path_static[index_length] = '\0';
- }
- /* It was static, but didn't fit */
- else {
- sr->real_path.data = mk_string_dup(index_path);
- }
- sr->real_path.len = index_length;
-
- ret = mk_file_get_info(sr->real_path.data,
- &sr->file_info, MK_FILE_READ);
- if (ret != 0) {
- return mk_http_error(MK_CLIENT_FORBIDDEN, cs, sr, server);
- }
-
- }
- }
-
-#ifndef _WIN32
- /* Check symbolic link file */
- if (sr->file_info.is_link == MK_TRUE) {
- if (server->symlink == MK_FALSE) {
- return mk_http_error(MK_CLIENT_FORBIDDEN, cs, sr, server);
- }
- else {
- int n;
- char linked_file[MK_MAX_PATH];
- n = readlink(sr->real_path.data, linked_file, MK_MAX_PATH);
- if (n < 0) {
- return mk_http_error(MK_CLIENT_FORBIDDEN, cs, sr, server);
- }
- }
- }
-#endif
-
- /* Plugin Stage 30: look for handlers for this request */
- if (sr->stage30_blocked == MK_FALSE) {
- char *uri;
-
- if (!index_path) {
- sr->uri_processed.data[sr->uri_processed.len] = '\0';
- uri = sr->uri_processed.data;
- }
- else {
- uri = sr->real_path.data + index_bytes;
- }
-
- handlers = &sr->host_conf->handlers;
- mk_list_foreach(head, handlers) {
- h_handler = mk_list_entry(head, struct mk_vhost_handler, _head);
- if (re_matchp(h_handler->match, uri, NULL) == -1) {
- continue;
- }
-
- plugin = h_handler->handler;
- sr->stage30_handler = h_handler->handler;
- ret = plugin->stage->stage30(plugin, cs, sr,
- h_handler->n_params,
- &h_handler->params);
-
- MK_TRACE("[FD %i] STAGE_30 returned %i", cs->socket, ret);
- switch (ret) {
- case MK_PLUGIN_RET_CONTINUE:
- return MK_PLUGIN_RET_CONTINUE;
- case MK_PLUGIN_RET_CLOSE_CONX:
- if (sr->headers.status > 0) {
- return mk_http_error(sr->headers.status, cs, sr, server);
- }
- else {
- return mk_http_error(MK_CLIENT_FORBIDDEN, cs, sr, server);
- }
- case MK_PLUGIN_RET_END:
- return MK_EXIT_OK;
- }
- }
- }
-
- /*
- * Monkey listens for PUT and DELETE methods in addition to GET, POST and
- * HEAD, but it does not care about them, so if any plugin did not worked
- * on it, Monkey will return error 501 (501 Not Implemented).
- */
- if (sr->method == MK_METHOD_PUT || sr->method == MK_METHOD_DELETE) {
- return mk_http_error(MK_CLIENT_METHOD_NOT_ALLOWED, cs, sr, server);
- }
- else if (sr->method == MK_METHOD_UNKNOWN) {
- return mk_http_error(MK_SERVER_NOT_IMPLEMENTED, cs, sr, server);
- }
-
- /* counter connections */
- sr->headers.pconnections_left = (int)
- (server->max_keep_alive_request - cs->counter_connections);
-
- /* Set default value */
- mk_header_set_http_status(sr, MK_HTTP_OK);
- sr->headers.location = NULL;
- sr->headers.content_length = 0;
-
- /*
- * For OPTIONS method, we let the plugin handle it and
- * return without any content.
- */
- if (sr->method == MK_METHOD_OPTIONS) {
- /* FIXME: OPTIONS NOT WORKING */
- //sr->headers.allow_methods.data = MK_METHOD_AVAILABLE;
- //sr->headers.allow_methods.len = strlen(MK_METHOD_AVAILABLE);
-
- mk_ptr_reset(&sr->headers.content_type);
- mk_header_prepare(cs, sr, server);
- return MK_EXIT_OK;
- }
- else {
- mk_ptr_reset(&sr->headers.allow_methods);
- }
-
- /* read permissions and check file */
- if (sr->file_info.read_access == MK_FALSE) {
- return mk_http_error(MK_CLIENT_FORBIDDEN, cs, sr, server);
- }
-
- /* Matching MimeType */
- mime = mk_mimetype_find(server, &sr->real_path);
- if (!mime) {
- mime = server->mimetype_default;
- }
-
- if (sr->file_info.is_directory == MK_TRUE) {
- return mk_http_error(MK_CLIENT_FORBIDDEN, cs, sr, server);
- }
-
- /* get file size */
- if (sr->file_info.size == 0) {
- return mk_http_error(MK_CLIENT_NOT_FOUND, cs, sr, server);
- }
-
- /* Configure some headers */
- sr->headers.last_modified = sr->file_info.last_modification;
- sr->headers.etag_len = snprintf(sr->headers.etag_buf,
- MK_HEADER_ETAG_SIZE,
- "ETag: \"%x-%zx\"\r\n",
- (unsigned int) sr->file_info.last_modification,
- sr->file_info.size);
-
- if (sr->if_modified_since.data && sr->method == MK_METHOD_GET) {
- time_t date_client; /* Date sent by client */
- time_t date_file_server; /* Date server file */
-
- date_client = mk_utils_gmt2utime(sr->if_modified_since.data);
- date_file_server = sr->file_info.last_modification;
-
- if (date_file_server <= date_client &&
- date_client > 0) {
- mk_header_set_http_status(sr, MK_NOT_MODIFIED);
- mk_header_prepare(cs, sr, server);
- return MK_EXIT_OK;
- }
- }
-
- /* Object size for log and response headers */
- sr->headers.content_length = sr->file_info.size;
- sr->headers.real_length = sr->file_info.size;
-
- /* Open file */
- if (mk_likely(sr->file_info.size > 0)) {
- sr->file_fd = mk_vhost_open(sr, server);
- if (sr->file_fd == -1) {
- MK_TRACE("open() failed");
- return mk_http_error(MK_CLIENT_FORBIDDEN, cs, sr, server);
- }
- sr->in_file.fd = sr->file_fd;
- sr->in_file.bytes_offset = 0;
- sr->in_file.bytes_total = sr->file_info.size;
- sr->in_file.stream = &sr->stream;
- }
-
- /* Process methods */
- if (sr->method == MK_METHOD_GET || sr->method == MK_METHOD_HEAD) {
- if (mime) {
- sr->headers.content_type = mime->header_type;
- }
-
- /* HTTP Ranges */
- if (sr->range.data != NULL && server->resume == MK_TRUE) {
- if (mk_http_range_parse(sr) < 0) {
- sr->headers.ranges[0] = -1;
- sr->headers.ranges[1] = -1;
- return mk_http_error(MK_CLIENT_BAD_REQUEST, cs, sr, server);
- }
- if (sr->headers.ranges[0] >= 0 || sr->headers.ranges[1] >= 0) {
- mk_header_set_http_status(sr, MK_HTTP_PARTIAL);
- }
-
- /* Calc bytes to send & offset */
- if (mk_http_range_set(sr, sr->file_info.size, server) != 0) {
- sr->headers.content_length = -1;
- sr->headers.ranges[0] = -1;
- sr->headers.ranges[1] = -1;
- return mk_http_error(MK_CLIENT_REQUESTED_RANGE_NOT_SATISF,
- cs, sr, server);
- }
- }
- }
- else {
- /* without content-type */
- mk_ptr_reset(&sr->headers.content_type);
- }
-
- /* Send headers */
- mk_header_prepare(cs, sr, server);
- if (mk_unlikely(sr->headers.content_length == 0)) {
- return 0;
- }
- /* Send file content */
- if (sr->method == MK_METHOD_GET || sr->method == MK_METHOD_POST) {
- /* Note: bytes and offsets are set after the Range check */
- sr->in_file.type = MK_STREAM_FILE;
- mk_stream_append(&sr->in_file, &sr->stream);
- }
-
- /*
- * Enable TCP Cork for the remote socket. It will be disabled
- * later by the file stream on the channel after send the first
- * file bytes.
- */
-#if defined(__linux__)
- sr->in_file.cb_consumed = mk_http_cb_file_on_consume;
-#endif
-
- /*
- * Enable CORK/NO_PUSH
- * -------------------
- * If it was compiled for Linux, it will turn the Cork off after
- * send the first round of bytes from the target static file.
- *
- * For OSX, it sets TCP_NOPUSH off after send all HTTP headers. Refer
- * to mk_header.c for more details.
- */
- //mk_server_cork_flag(cs->socket, TCP_CORK_ON);
-
- /* Start sending data to the channel */
- return MK_EXIT_OK;
-}
-
-/*
- * Check if a connection can stay open using
- * the keepalive headers vars and Monkey configuration as criteria
- */
-int mk_http_keepalive_check(struct mk_http_session *cs,
- struct mk_http_request *sr,
- struct mk_server *server)
-{
- if (server->keep_alive == MK_FALSE) {
- return -1;
- }
-
- /* Default Keepalive is off */
- if (sr->protocol == MK_HTTP_PROTOCOL_10) {
- cs->close_now = MK_TRUE;
- }
- else if (sr->protocol == MK_HTTP_PROTOCOL_11) {
- cs->close_now = MK_FALSE;
- }
-
- if (sr->connection.data) {
- if (cs->parser.header_connection == MK_HTTP_PARSER_CONN_KA &&
- sr->protocol == MK_HTTP_PROTOCOL_11) {
- cs->close_now = MK_FALSE;
- }
- else if (cs->parser.header_connection == MK_HTTP_PARSER_CONN_CLOSE) {
- cs->close_now = MK_TRUE;
- }
- }
-
- /* Client has reached keep-alive connections limit */
- if (cs->counter_connections >= server->max_keep_alive_request) {
- cs->close_now = MK_TRUE;
- return -1;
- }
-
- return 0;
-}
-
-static inline void mk_http_request_ka_next(struct mk_http_session *cs)
-{
- cs->body_length = 0;
- cs->counter_connections++;
-
- /* Update data for scheduler */
- cs->init_time = cs->server->clock_context->log_current_utime;
- cs->status = MK_REQUEST_STATUS_INCOMPLETE;
-
- /* Initialize parser */
- mk_http_parser_init(&cs->parser);
-}
-
-int mk_http_request_end(struct mk_http_session *cs, struct mk_server *server)
-{
- int ret;
- int status;
- int len;
- struct mk_http_request *sr = NULL;
-
- if (server->max_keep_alive_request <= cs->counter_connections) {
- cs->close_now = MK_TRUE;
- goto shutdown;
- }
-
- /* Check if we have some enqueued pipeline requests */
- ret = mk_http_parser_more(&cs->parser, cs->body_length);
- if (ret == MK_TRUE) {
- /* Our pipeline request limit is the same that our keepalive limit */
- cs->counter_connections++;
- len = (cs->body_length - cs->parser.i) -1;
- memmove(cs->body,
- cs->body + cs->parser.i + 1,
- len);
- cs->body_length = len;
-
- /* Prepare for next one */
- sr = mk_list_entry_first(&cs->request_list, struct mk_http_request, _head);
- mk_http_request_free(sr, server);
- mk_http_request_init(cs, sr, server);
- mk_http_parser_init(&cs->parser);
- status = mk_http_parser(sr, &cs->parser, cs->body, cs->body_length,
- server);
- if (status == MK_HTTP_PARSER_OK) {
- ret = mk_http_request_prepare(cs, sr, server);
- if (ret == MK_EXIT_ABORT) {
- return -1;
- }
-
- /*
- * Return 1 means, we still have more data to send in a different
- * scheduler round.
- */
- return 1;
- }
- else if (status == MK_HTTP_PARSER_PENDING) {
- return 0;
- }
- else if (status == MK_HTTP_PARSER_ERROR) {
- cs->close_now = MK_TRUE;
- }
- }
-
- shutdown:
- /*
- * We need to ask to http_keepalive if this
- * connection can continue working or we must
- * close it.
- */
- if (cs->close_now == MK_TRUE) {
- MK_TRACE("[FD %i] No KeepAlive mode, remove", cs->conn->event.fd);
- mk_http_session_remove(cs, server);
- return -1;
- }
- else {
- mk_http_request_free_list(cs, server);
- mk_http_request_ka_next(cs);
- mk_sched_conn_timeout_add(cs->conn, mk_sched_get_thread_conf());
- return 0;
- }
-
- return -1;
-}
-
-void cb_stream_page_finished(struct mk_stream_input *in)
-{
- mk_ptr_t *page = in->buffer;
-
- mk_ptr_free(page);
- mk_mem_free(page);
-}
-
-/* Enqueue an error response. This function always returns MK_EXIT_OK */
-int mk_http_error(int http_status, struct mk_http_session *cs,
- struct mk_http_request *sr,
- struct mk_server *server)
-{
- int ret, fd;
- size_t count;
- mk_ptr_t message;
- mk_ptr_t page;
- struct mk_vhost_error_page *entry;
- struct mk_list *head;
- struct file_info finfo;
- struct mk_iov *iov;
-
- /* This function requires monkey to be properly initialized which is not the case
- * when it's just used to parse http requests in fluent-bit so we want it to ignore
- * that case and let fluent-bit handle it.
- */
- if (server->workers == 0) {
- return MK_EXIT_OK;
- }
-
- mk_header_set_http_status(sr, http_status);
- mk_ptr_reset(&page);
-
- /*
- * We are nice sending error pages for clients who at least respect
- * the especification
- */
- if (http_status != MK_CLIENT_LENGTH_REQUIRED &&
- http_status != MK_CLIENT_BAD_REQUEST &&
- http_status != MK_CLIENT_REQUEST_ENTITY_TOO_LARGE) {
-
- /* Lookup a customized error page */
- mk_list_foreach(head, &sr->host_conf->error_pages) {
- entry = mk_list_entry(head, struct mk_vhost_error_page, _head);
- if (entry->status != http_status) {
- continue;
- }
-
- /* validate error file */
- ret = mk_file_get_info(entry->real_path, &finfo, MK_FILE_READ);
- if (ret == -1) {
- break;
- }
-
- /* open file */
- fd = open(entry->real_path, server->open_flags);
- if (fd == -1) {
- break;
- }
- /* This fd seems to be leaked, we need to verify this logic */
-
- /* Outgoing headers */
- sr->headers.content_length = finfo.size;
- sr->headers.real_length = finfo.size;
- mk_header_prepare(cs, sr, server);
-
- /* Stream setup */
- mk_stream_in_file(&sr->stream, &sr->in_file, sr->file_fd,
- finfo.size, 0, NULL, NULL);
- return MK_EXIT_OK;
- }
- }
-
- mk_ptr_reset(&message);
-
- switch (http_status) {
- case MK_CLIENT_FORBIDDEN:
- mk_http_error_page("Forbidden",
- &sr->uri,
- server->server_signature,
- &page.data, &page.len);
- break;
- case MK_CLIENT_NOT_FOUND:
- mk_string_build(&message.data, &message.len,
- "The requested URL was not found on this server.");
- mk_http_error_page("Not Found",
- &message,
- server->server_signature,
- &page.data, &page.len);
- mk_ptr_free(&message);
- break;
- case MK_CLIENT_REQUEST_ENTITY_TOO_LARGE:
- mk_string_build(&message.data, &message.len,
- "The request entity is too large.");
- mk_http_error_page("Entity too large",
- &message,
- server->server_signature,
- &page.data, &page.len);
- mk_ptr_free(&message);
- break;
- case MK_CLIENT_METHOD_NOT_ALLOWED:
- mk_http_error_page("Method Not Allowed",
- &sr->uri,
- server->server_signature,
- &page.data, &page.len);
- break;
- case MK_SERVER_NOT_IMPLEMENTED:
- mk_http_error_page("Method Not Implemented",
- &sr->uri,
- server->server_signature,
- &page.data, &page.len);
- break;
- case MK_SERVER_INTERNAL_ERROR:
- mk_http_error_page("Internal Server Error",
- &sr->uri,
- server->server_signature,
- &page.data, &page.len);
- break;
- }
-
- if (page.len > 0 && sr->method != MK_METHOD_HEAD && sr->method != MK_METHOD_UNKNOWN) {
- sr->headers.content_length = page.len;
- }
- else {
- sr->headers.content_length = 0;
- }
-
- sr->headers.location = NULL;
- sr->headers.cgi = SH_NOCGI;
- sr->headers.pconnections_left = 0;
- sr->headers.last_modified = -1;
-
- if (!page.data) {
- mk_ptr_reset(&sr->headers.content_type);
- }
- else {
- mk_ptr_set(&sr->headers.content_type, "Content-Type: text/html\r\n");
- }
-
- mk_header_prepare(cs, sr, server);
- if (page.data) {
- if (sr->method != MK_METHOD_HEAD) {
- if (sr->headers._extra_rows) {
- iov = sr->headers._extra_rows;
- sr->in_headers_extra.bytes_total += page.len;
- }
- else {
- iov = &sr->headers.headers_iov;
- sr->in_headers.bytes_total += page.len;
- }
- mk_iov_add(iov, page.data, page.len, MK_TRUE);
- }
- else {
- mk_mem_free(page.data);
- }
- }
-
- mk_channel_write(cs->channel, &count);
- mk_http_request_end(cs, server);
-
- return MK_EXIT_OK;
-}
-
-/*
- * From thread mk_sched_worker "list", remove the http_session
- * struct information
- */
-void mk_http_session_remove(struct mk_http_session *cs,
- struct mk_server *server)
-{
- struct mk_list *tmp;
- struct mk_list *head;
- struct mk_plugin *handler;
- struct mk_http_request *sr;
-
- MK_TRACE("[FD %i] HTTP Session remove", cs->socket);
- if (cs->_sched_init == MK_FALSE) {
- return;
- }
-
- /* On session remove, make sure to cleanup any handler */
- mk_list_foreach_safe(head, tmp, &cs->request_list) {
- sr = mk_list_entry(head, struct mk_http_request, _head);
- if (sr->stage30_handler) {
- MK_TRACE("Hangup stage30 handler");
- handler = sr->stage30_handler;
- if (mk_unlikely(!handler->stage->stage30_hangup)) {
- mk_warn("Plugin %s, do not implement stage30_hangup", handler->name);
- continue;
- }
- handler->stage->stage30_hangup(handler, cs, sr);
- }
- }
-
- if (cs->body != cs->body_fixed) {
- mk_mem_free(cs->body);
- }
- mk_http_request_free_list(cs, server);
- mk_list_del(&cs->request_list);
-
- cs->_sched_init = MK_FALSE;
-}
-
-/* FIXME: nobody is using this */
-struct mk_http_session *mk_http_session_lookup(int socket)
-{
- (void) socket;
- return NULL;
-}
-
-
-/* Initialize a HTTP session (just created) */
-int mk_http_session_init(struct mk_http_session *cs, struct mk_sched_conn *conn,
- struct mk_server *server)
-{
- /* Alloc memory for node */
- cs->_sched_init = MK_TRUE;
- cs->pipelined = MK_FALSE;
- cs->counter_connections = 0;
- cs->close_now = MK_FALSE;
- cs->socket = conn->event.fd;
- cs->status = MK_REQUEST_STATUS_INCOMPLETE;
- cs->server = server;
-
- /* Map the channel, just for protocol-handler internal stuff */
- cs->channel = &conn->channel;
-
- /* Map the connection instance, required to handle exceptions */
- cs->conn = conn;
-
- /* creation time in unix time */
- cs->init_time = conn->arrive_time;
-
- /* alloc space for body content */
- if (conn->net->buffer_size > MK_REQUEST_CHUNK) {
- cs->body = mk_mem_alloc(conn->net->buffer_size);
- cs->body_size = conn->net->buffer_size;
- }
- else {
- /* Buffer size based in Chunk bytes */
- cs->body = cs->body_fixed;
- cs->body_size = MK_REQUEST_CHUNK;
- }
-
- /* Current data length */
- cs->body_length = 0;
-
- /* Init session request list */
- mk_list_init(&cs->request_list);
-
- /* Initialize the parser */
- mk_http_parser_init(&cs->parser);
-
- return 0;
-}
-
-
-void mk_http_request_free(struct mk_http_request *sr, struct mk_server *server)
-{
- /* Let the vhost interface to handle the session close */
- mk_vhost_close(sr, server);
-
- if (sr->headers.location) {
- mk_mem_free(sr->headers.location);
- }
-
- if (sr->uri_processed.data != sr->uri.data) {
- mk_ptr_free(&sr->uri_processed);
- }
-
- if (sr->real_path.data != sr->real_path_static) {
- mk_ptr_free(&sr->real_path);
- }
-
- if (sr->stream.channel) {
- mk_stream_release(&sr->stream);
- }
-}
-
-void mk_http_request_free_list(struct mk_http_session *cs,
- struct mk_server *server)
-{
- struct mk_list *head, *tmp;
- struct mk_http_request *request;
-
- /* sr = last node */
- MK_TRACE("[FD %i] Free struct client_session", cs->socket);
- mk_list_foreach_safe(head, tmp, &cs->request_list) {
- request = mk_list_entry(head, struct mk_http_request, _head);
- mk_list_del(&request->_head);
-
- mk_http_request_free(request, server);
- if (request != &cs->sr_fixed) {
- mk_mem_free(request);
- }
- }
-}
-
-/*
- * Lookup a known header or a non-known header. For unknown headers
- * set the 'key' value wth a lowercase string
- */
-struct mk_http_header *mk_http_header_get(int name, struct mk_http_request *req,
- const char *key, unsigned int len)
-{
- int i;
- struct mk_http_parser *parser = &req->session->parser;
- struct mk_http_header *header;
-
- /* Known header */
- if (name >= 0 && name < MK_HEADER_SIZEOF) {
- return &parser->headers[name];
- }
-
- /* Check if want to retrieve a custom header */
- if (name == MK_HEADER_OTHER) {
- /* Iterate over the extra headers identified by the parser */
- for (i = 0; i < parser->headers_extra_count; i++) {
- header = &parser->headers_extra[i];
- if (header->key.len != len) {
- continue;
- }
-
- if (strncmp(header->key.data, key, len) == 0) {
- return header;
- }
- }
- return NULL;
- }
-
- return NULL;
-}
-
-/*
- * Main callbacks for the Scheduler
- */
-int mk_http_sched_read(struct mk_sched_conn *conn,
- struct mk_sched_worker *worker,
- struct mk_server *server)
-{
- int ret;
- int status;
- size_t count;
- (void) worker;
- struct mk_http_session *cs;
- struct mk_http_request *sr;
-
-#ifdef MK_HAVE_TRACE
- int socket = conn->event.fd;
-#endif
-
- cs = mk_http_session_get(conn);
- if (cs->_sched_init == MK_FALSE) {
- /* Create session for the client */
- MK_TRACE("[FD %i] Create HTTP session", socket);
- ret = mk_http_session_init(cs, conn, server);
- if (ret == -1) {
- return -1;
- }
- }
-
- /* Invoke the read handler, on this case we only support HTTP (for now :) */
- ret = mk_http_handler_read(conn, cs, server);
- if (ret > 0) {
- if (mk_list_is_empty(&cs->request_list) == 0) {
- /* Add the first entry */
- sr = &cs->sr_fixed;
- mk_list_add(&sr->_head, &cs->request_list);
- mk_http_request_init(cs, sr, server);
- }
- else {
- sr = mk_list_entry_first(&cs->request_list, struct mk_http_request, _head);
- }
- status = mk_http_parser(sr, &cs->parser, cs->body,
- cs->body_length, server);
- if (status == MK_HTTP_PARSER_OK) {
- MK_TRACE("[FD %i] HTTP_PARSER_OK", socket);
- if (mk_http_status_completed(cs, conn) == -1) {
- mk_http_session_remove(cs, server);
- return -1;
- }
- mk_sched_conn_timeout_del(conn);
- ret = mk_http_request_prepare(cs, sr, server);
- }
- else if (status == MK_HTTP_PARSER_ERROR) {
- /* The HTTP parser may enqueued some response error */
- if (mk_channel_is_empty(cs->channel) != 0) {
- mk_channel_write(cs->channel, &count);
- }
- mk_http_session_remove(cs, server);
- MK_TRACE("[FD %i] HTTP_PARSER_ERROR", socket);
- return -1;
- }
- else {
- MK_TRACE("[FD %i] HTTP_PARSER_PENDING", socket);
- }
- }
-
- return ret;
-}
-
-/* The scheduler got a connection close event from the remote client */
-int mk_http_sched_close(struct mk_sched_conn *conn,
- struct mk_sched_worker *sched,
- int type, struct mk_server *server)
-{
- struct mk_http_session *session;
- (void) sched;
-
-#ifdef MK_HAVE_TRACE
- MK_TRACE("[FD %i] HTTP sched close (type=%i)", conn->event.fd, type);
-#else
- (void) type;
-#endif
-
- /* Release resources of the requests and session */
- session = mk_http_session_get(conn);
- mk_http_session_remove(session, server);
- return 0;
-}
-
-int mk_http_sched_done(struct mk_sched_conn *conn,
- struct mk_sched_worker *worker,
- struct mk_server *server)
-{
- (void) worker;
- struct mk_http_session *session;
- struct mk_http_request *sr;
-
- session = mk_http_session_get(conn);
- sr = mk_list_entry_first(&session->request_list,
- struct mk_http_request, _head);
- mk_plugin_stage_run_40(session, sr, server);
-
- return mk_http_request_end(session, server);
-}
-
-struct mk_sched_handler mk_http_handler = {
- .name = "http",
- .cb_read = mk_http_sched_read,
- .cb_close = mk_http_sched_close,
- .cb_done = mk_http_sched_done,
- .sched_extra_size = sizeof(struct mk_http_session),
- .capabilities = MK_CAP_HTTP
-};
diff --git a/fluent-bit/lib/monkey/mk_server/mk_http2.c b/fluent-bit/lib/monkey/mk_server/mk_http2.c
deleted file mode 100644
index 7a4f1e82..00000000
--- a/fluent-bit/lib/monkey/mk_server/mk_http2.c
+++ /dev/null
@@ -1,384 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-
-/* Monkey HTTP Server
- * ==================
- * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define _GNU_SOURCE
-
-#include <inttypes.h>
-
-#include <monkey/mk_http2.h>
-#include <monkey/mk_http2_settings.h>
-#include <monkey/mk_header.h>
-#include <monkey/mk_scheduler.h>
-
-/* HTTP/2 Connection Preface */
-#define MK_HTTP2_PREFACE "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
-static mk_ptr_t http2_preface = {
- .data = MK_HTTP2_PREFACE,
- .len = sizeof(MK_HTTP2_PREFACE) - 1
-};
-
-static inline void buffer_consume(struct mk_http2_session *h2s, int bytes)
-{
- memmove(h2s->buffer,
- h2s->buffer + bytes,
- h2s->buffer_length - bytes);
-
- MK_TRACE("[h2] consume buffer length from %i to %i",
- h2s->buffer_length, h2s->buffer_length - bytes);
- h2s->buffer_length -= bytes;
-}
-
-static struct mk_http2_session *mk_http2_session_create()
-{
- struct mk_http2_session *h2s;
-
- h2s = mk_mem_alloc(sizeof(struct mk_http2_session));
- if (!h2s) {
- return NULL;
- }
- h2s->buffer = NULL;
- h2s->buffer_length = 0;
- h2s->buffer_size = sizeof(h2s->buffer_fixed);
- h2s->buffer = h2s->buffer_fixed;
- h2s->settings = MK_HTTP2_SETTINGS_DEFAULT;
-
- return h2s;
-}
-
-/* FIXME
-static int mk_http2_session_destroy(struct mk_http2_session *h2s)
-{
- if (h2s->buffer != h2s->buffer_fixed) {
- mk_mem_free(h2s->buffer);
- }
- mk_mem_free(h2s);
- return 0;
-}
-
-static int mk_http2_frame_header(char *buf, uint32_t length, uint8_t type,
- uint32_t flags, void *data)
-{
- struct mk_http2_frame *f = (struct mk_http2_frame *) buf;
-
- f->len_type = (length << 8 | type);
- f->flags = flags;
- f->payload = data;
-
- return sizeof(struct mk_http2_frame);
-}
-
-*/
-
-/* Handle an upgraded session */
-static int mk_http2_upgrade(void *cs, void *sr, struct mk_server *server)
-{
- struct mk_http_session *s = cs;
- struct mk_http_request *r = sr;
- struct mk_http2_session *h2s;
-
- mk_header_set_http_status(r, MK_INFO_SWITCH_PROTOCOL);
- r->headers.connection = MK_HEADER_CONN_UPGRADED;
- r->headers.upgrade = MK_HEADER_UPGRADED_H2C;
- mk_header_prepare(s, r, server);
-
- h2s = mk_http2_session_create();
- if (!h2s) {
- return -1;
- }
-
- h2s->status = MK_HTTP2_UPGRADED;
- s->conn->data = h2s;
-
- return MK_HTTP_OK;
-}
-
-/* FIXME Decode a frame header, no more... no less
-static inline void mk_http2_frame_decode_header(uint8_t *buf,
- struct mk_http2_frame *frame)
-{
- struct mk_http2_session *h2s;
- (void) h2s;
-
- frame->len_type = mk_http2_bitdec_32u(buf);
- frame->flags = buf[4];
- frame->stream_id = mk_http2_bitdec_stream_id(buf + 5);
- frame->payload = buf + 9;
-
-#ifdef MK_HAVE_TRACE
- MK_TRACE("Frame Header");
- printf(" length=%i, type=%i, stream_id=%i\n",
- mk_http2_frame_len(frame),
- mk_http2_frame_type(frame),
- frame->stream_id);
-#endif
-}
-*/
-
-static inline int mk_http2_handle_settings(struct mk_sched_conn *conn,
- struct mk_http2_frame *frame)
-{
- int i;
- int frame_len;
- int settings;
- int setting_size = 6; /* 16 bits identifier + 32 bits value = 6 bytes */
- uint16_t setting_id;
- uint32_t setting_value;
- uint8_t *p;
- struct mk_http2_session *h2s;
-
- h2s = conn->data;
- frame_len = mk_http2_frame_len(frame);
- if (frame->flags == MK_HTTP2_SETTINGS_ACK) {
- /*
- * Nothing to do, the peer just received our SETTINGS and it's
- * sending an acknowledge.
- *
- * note: validate that frame length is zero.
- */
- if (frame_len > 0) {
- /*
- * This must he handled as a connection error, we must reply
- * with a FRAME_SIZE_ERROR. ref:
- *
- * https://httpwg.github.io/specs/rfc7540.html#SETTINGS
- */
-
- /* FIXME: send a GOAWAY error frame */
- MK_TRACE("FRAME SIZE ERR: %i\n", frame_len);
- return -1;
-
- }
- return 0;
- }
-
- /*
- * Iterate our SETTINGS payload, it may contain many entries in the
- * following format:
- *
- * +-------------------------------+
- * | Identifier (16) |
- * +-------------------------------+-------------------------------+
- * | Value (32) |
- * +---------------------------------------------------------------+
- *
- * 48 bits = 6 bytes
- */
- settings = (frame_len / setting_size);
- for (i = 0; i < settings; i++ ) {
- /* Seek payload per SETTINGS entry */
- p = frame->payload + (setting_size * i);
-
- setting_id = p[0] << 8 | p[1];
- setting_value = p[2] << 24 | p[3] << 16 | p[4] << 8 | p[5];
- MK_H2_TRACE(conn, "[Setting] ID=%" PRIu16 " VAL=%" PRIu32,
- setting_id, setting_value);
-
- switch (setting_id) {
- case MK_HTTP2_SETTINGS_HEADER_TABLE_SIZE:
- /* unhandled */
- break;
- case MK_HTTP2_SETTINGS_ENABLE_PUSH:
- if (setting_value != 0 && setting_value != 1) {
- /* FIXME: PROTOCOL_ERROR */
- MK_H2_TRACE(conn, "Invalid SETTINGS_ENABLE_PUSH");
- return -1;
- }
- h2s->settings.enable_push = setting_value;
- break;
- case MK_HTTP2_SETTINGS_MAX_CONCURRENT_STREAMS:
- if (setting_value < 64) {
- h2s->settings.max_concurrent_streams = setting_value;
- }
- else {
- h2s->settings.max_concurrent_streams = 64;
- }
- MK_H2_TRACE(conn, "SETTINGS MAX_CONCURRENT_STREAMS=%i",
- setting_value);
- break;
- case MK_HTTP2_SETTINGS_INITIAL_WINDOW_SIZE:
- if (setting_value < 65535 || setting_value > 2147483647) {
- /* FIXME: send FLOW_CONTROL_ERROR */
- MK_H2_TRACE(conn, "Invalid INITIAL_WINDOW_SIZE");
- return -1;
- }
- h2s->settings.initial_window_size = setting_value;
- break;
- case MK_HTTP2_SETTINGS_MAX_FRAME_SIZE:
- if (setting_value < 16384 || setting_value > 2147483647) {
- /* FIXME: send PROTOCOL_ERROR */
- return -1;
- }
- h2s->settings.max_frame_size = setting_value;
- break;
- case MK_HTTP2_SETTINGS_MAX_HEADER_LIST_SIZE:
- /* Unhandled */
- break;
- default:
- /*
- * 5.5 Extending HTTP/2: ...Implementations MUST ignore unknown
- * or unsupported values in all extensible protocol elements...
- */
- break;
- }
- }
-
- /* FIXME // No errors, send the ACK
- mk_http2_send_raw(conn, MK_HTTP2_SETTINGS_ACK_FRAME,
- sizeof(MK_HTTP2_SETTINGS_ACK_FRAME) - 1);
- */
- return 0;
-}
-
-
-static inline int mk_http2_frame_run(struct mk_sched_conn *conn,
- struct mk_sched_worker *worker)
-{
- int ret;
- struct mk_http2_frame frame;
- struct mk_http2_session *h2s;
- (void) worker;
-
- h2s = conn->data;
-
- /* Decode the frame header */
- //FIXME mk_http2_frame_decode_header(h2s->buffer, &frame);
-
- /* Do some validations */
- if (h2s->buffer_length < (MK_HTTP2_HEADER_SIZE + (frame.len_type >> 8))) {
- /* FIXME: need more data */
- return 0;
- }
-
- /* Do some work based on the frame type */
- if (mk_http2_frame_type(&frame) == MK_HTTP2_SETTINGS) {
- ret = mk_http2_handle_settings(conn, &frame);
- /* FIXME: send our MK_HTTP2_SETTINGS_ACK_FRAME */
- return ret;
- }
-
- return 0;
-}
-
-static int mk_http2_sched_read(struct mk_sched_conn *conn,
- struct mk_sched_worker *worker,
- struct mk_server *server)
-{
- int bytes;
- int new_size;
- int available;
- char *tmp;
- struct mk_http2_session *h2s;
- (void) worker;
- (void) server;
-
- h2s = conn->data;
- available = h2s->buffer_size - h2s->buffer_length;
- if (available == 0) {
- new_size = h2s->buffer_size + MK_HTTP2_CHUNK;
- if (h2s->buffer == h2s->buffer_fixed) {
- h2s->buffer = mk_mem_alloc(new_size);
- if (!h2s->buffer) {
- /* FIXME: send internal server error ? */
- return -1;
- }
- memcpy(h2s->buffer, h2s->buffer_fixed, h2s->buffer_length);
- MK_TRACE("[FD %i] Buffer new size: %i, length: %i",
- conn->event.fd, new_size, h2s->buffer_length);
- }
- else {
- MK_TRACE("[FD %i] Buffer realloc from %i to %i",
- conn->event.fd, h2s->buffer_size, new_size);
- tmp = mk_mem_realloc(h2s->buffer, new_size);
- if (tmp) {
- h2s->buffer = tmp;
- h2s->buffer_size = new_size;
- }
- else {
- /* FIXME: send internal server error ? */
- return -1;
- }
-
- }
- }
-
- /* Read the incoming data */
- bytes = mk_sched_conn_read(conn,
- h2s->buffer,
- h2s->buffer_size - h2s->buffer_length);
- if (bytes == 0) {
- errno = 0;
- return -1;
- }
- else if (bytes == -1) {
- return -1;
- }
-
- h2s->buffer_length += bytes;
-
- /* Upgraded connections from HTTP/1.x requires the preface */
- if (h2s->status == MK_HTTP2_UPGRADED) {
- if (h2s->buffer_length >= http2_preface.len) {
- if (memcmp(h2s->buffer,
- http2_preface.data, http2_preface.len) != 0) {
- MK_H2_TRACE(conn, "Invalid HTTP/2 preface");
- return 0;
- }
-
- MK_H2_TRACE(conn, "HTTP/2 preface OK");
-
- buffer_consume(h2s, http2_preface.len);
- h2s->status = MK_HTTP2_OK;
-
- /* Send out our default settings
- mk_stream_set(&h2s->stream_settings,
- MK_STREAM_RAW,
- &conn->channel,
- MK_HTTP2_SETTINGS_DEFAULT_FRAME,
- sizeof(MK_HTTP2_SETTINGS_DEFAULT_FRAME) - 1,
- NULL,
- NULL, NULL, NULL);
- */
- }
- else {
- /* We need more data */
- return 0;
- }
- }
-
- /* Check that we have a minimum header size */
- if (h2s->buffer_length < MK_HTTP2_HEADER_SIZE) {
- MK_TRACE("HEADER FRAME incomplete %i/%i bytes",
- h2s->buffer_length, MK_HTTP2_HEADER_SIZE);
- return 0;
- }
-
- /* We have at least one frame */
- return mk_http2_frame_run(conn, worker);
-}
-
-
-struct mk_sched_handler mk_http2_handler = {
- .name = "http2",
- .cb_read = mk_http2_sched_read,
- .cb_close = NULL,
- .cb_done = NULL,
- .cb_upgrade = mk_http2_upgrade,
- .sched_extra_size = sizeof(struct mk_http2_session),
- .capabilities = MK_CAP_HTTP2
-};
diff --git a/fluent-bit/lib/monkey/mk_server/mk_http_parser.c b/fluent-bit/lib/monkey/mk_server/mk_http_parser.c
deleted file mode 100644
index 4e7aa316..00000000
--- a/fluent-bit/lib/monkey/mk_server/mk_http_parser.c
+++ /dev/null
@@ -1,744 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-
-/* Monkey HTTP Server
- * ==================
- * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define _GNU_SOURCE
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <stdint.h>
-#include <limits.h>
-
-#include <monkey/mk_http.h>
-#include <monkey/mk_http_parser.h>
-#include <monkey/mk_http_status.h>
-
-#define mark_end() \
- p->end = p->i; \
- p->chars = -1;
-
-#define start_next() \
- p->start = p->i + 1; \
- continue
-
-#define field_len() (p->end - p->start)
-#define header_scope_eq(p, x) p->header_min = p->header_max = x
-
-struct row_entry {
- int len;
- const char name[32];
-};
-
-struct row_entry mk_methods_table[] = {
- { 3, "GET" },
- { 4, "POST" },
- { 4, "HEAD" },
- { 3, "PUT" },
- { 6, "DELETE" },
- { 7, "OPTIONS" }
-};
-
-struct row_entry mk_headers_table[] = {
- { 6, "accept" },
- { 14, "accept-charset" },
- { 15, "accept-encoding" },
- { 15, "accept-language" },
- { 13, "authorization" },
- { 13, "cache-control" },
- { 6, "cookie" },
- { 10, "connection" },
- { 14, "content-length" },
- { 13, "content-range" },
- { 12, "content-type" },
- { 4, "host" },
- { 14, "http2-settings" },
- { 17, "if-modified-since" },
- { 13, "last-modified" },
- { 19, "last-modified-since" },
- { 5, "range" },
- { 7, "referer" },
- { 7, "upgrade" },
- { 10, "user-agent" }
-};
-
-static inline void reverse_char_lookup(char *buf, char c, int len, struct mk_http_parser *p)
-{
- int x = 0;
- int y = 0;
-
- x = p->i;
- do {
- if (buf[x - y] == c) {
- p->i = x - y;
- return;
- }
- y++;
- } while (y < len);
-}
-
-static inline void char_lookup(char *buf, char c, int len, struct mk_http_parser *p)
-{
- int x = 0;
-
- x = p->i;
- do {
- if (buf[x] == c) {
- p->i = x;
- return;
- }
- x++;
- } while (x < len);
-}
-
-static inline int str_searchr(char *buf, char c, int len)
-{
- int i;
-
- for (i = len - 1; i >= 0; i--) {
- if (buf[i] == c) {
- return i;
- }
- }
-
- return -1;
-}
-
-static inline int method_lookup(struct mk_http_request *req,
- struct mk_http_parser *p, char *buffer)
-{
- int i = 0;
- int len;
-
- /* Method lenght */
- len = field_len();
-
- /* Point the buffer */
- req->method = MK_METHOD_UNKNOWN;
- req->method_p.data = buffer + p->start;
- req->method_p.len = len;
-
- if (p->method >= 0) {
- if (strncmp(buffer + p->start + 1,
- mk_methods_table[p->method].name + 1,
- len - 1) == 0) {
- req->method = p->method;
- return req->method;
- }
- }
-
- for (i = 0; i < MK_METHOD_SIZEOF; i++) {
- if (len != mk_methods_table[i].len) {
- continue;
- }
-
- if (strncmp(buffer + p->start, mk_methods_table[i].name, len) == 0) {
- req->method = i;
- return i;
- }
- }
- return MK_METHOD_UNKNOWN;
-}
-
-static inline void request_set(mk_ptr_t *ptr, struct mk_http_parser *p, char *buffer)
-{
- ptr->data = buffer + p->start;
- ptr->len = field_len();
-}
-
-/*
- * expected: a known & expected value in lowercase
- * value : the expected string value in the header
- * len : the value string length.
- *
- * If it matches it return zero. Otherwise -1.
- */
-static inline int header_cmp(const char *expected, char *value, int len)
-{
- int i = 0;
-
- if (len >= 8) {
- if (expected[0] != tolower(value[0])) return -1;
- if (expected[1] != tolower(value[1])) return -1;
- if (expected[2] != tolower(value[2])) return -1;
- if (expected[3] != tolower(value[3])) return -1;
- if (expected[4] != tolower(value[4])) return -1;
- if (expected[5] != tolower(value[5])) return -1;
- if (expected[6] != tolower(value[6])) return -1;
- if (expected[7] != tolower(value[7])) return -1;
- i = 8;
- }
-
- for (; i < len; i++) {
- if (expected[i] != tolower(value[i])) {
- return -1;
- }
- }
-
- return 0;
-}
-
-static inline int header_lookup(struct mk_http_parser *p, char *buffer)
-{
- int i;
- int len;
- int pos;
- long val;
- char *endptr;
- char *tmp;
-
- struct mk_http_header *header;
- struct mk_http_header *header_extra;
- struct row_entry *h;
-
- len = (p->header_sep - p->header_key);
- for (i = p->header_min; i <= p->header_max && i >= 0; i++) {
- h = &mk_headers_table[i];
- /* Check string length first */
- if (h->len != len) {
- continue;
- }
-
- if (header_cmp(h->name + 1, buffer + p->header_key + 1, len - 1) == 0) {
- /* We got a header match, register the header index */
- header = &p->headers[i];
- header->type = i;
- header->key.data = buffer + p->header_key;
- header->key.len = len;
- header->val.data = buffer + p->header_val;
- header->val.len = p->end - p->header_val;
- p->header_count++;
- mk_list_add(&header->_head, &p->header_list);
-
- if (i == MK_HEADER_HOST) {
- /* Handle a possible port number in the Host header */
- int sep = str_searchr(header->val.data, ':', header->val.len);
- if (sep > 0) {
- int plen;
- short int port_size = 6;
- char port[6]; /* Can't use port_size to declare a stack allocated array in vc++ */
-
- plen = header->val.len - sep - 1;
- if (plen <= 0 || plen >= port_size) {
- return -MK_CLIENT_BAD_REQUEST;
- }
- memcpy(&port, header->val.data + sep + 1, plen);
- port[plen] = '\0';
-
- errno = 0;
- val = strtol(port, &endptr, 10);
- if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
- || (errno != 0 && val == 0)) {
- return -MK_CLIENT_BAD_REQUEST;
- }
-
- if (endptr == port || *endptr != '\0') {
- return -MK_CLIENT_BAD_REQUEST;
- }
-
- p->header_host_port = val;
-
- /* Re-set the Host header value without port */
- header->val.len = sep;
- }
- }
- else if (i == MK_HEADER_CONTENT_LENGTH) {
- errno = 0;
- val = strtol(header->val.data, &endptr, 10);
- if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
- || (errno != 0 && val == 0)) {
- return -MK_CLIENT_REQUEST_ENTITY_TOO_LARGE;
- }
- if (endptr == header->val.data) {
- return -1;
- }
- if (val < 0) {
- return -1;
- }
-
- p->header_content_length = val;
- }
- else if (i == MK_HEADER_CONNECTION) {
- /* Check Connection: Keep-Alive */
- if (header->val.len == sizeof(MK_CONN_KEEP_ALIVE) - 1) {
- if (header_cmp(MK_CONN_KEEP_ALIVE,
- header->val.data,
- header->val.len ) == 0) {
- p->header_connection = MK_HTTP_PARSER_CONN_KA;
- }
- }
- /* Check Connection: Close */
- else if (header->val.len == sizeof(MK_CONN_CLOSE) -1) {
- if (header_cmp(MK_CONN_CLOSE,
- header->val.data, header->val.len) == 0) {
- p->header_connection = MK_HTTP_PARSER_CONN_CLOSE;
- }
- }
- else {
- p->header_connection = MK_HTTP_PARSER_CONN_UNKNOWN;
-
- /* Try to find some known values */
-
- /* Connection: upgrade */
- pos = mk_string_search_n(header->val.data,
- "Upgrade",
- MK_STR_INSENSITIVE,
- header->val.len);
- if (pos >= 0) {
- p->header_connection = MK_HTTP_PARSER_CONN_UPGRADE;
- }
-
- /* Connection: HTTP2-Settings */
- pos = mk_string_search_n(header->val.data,
- "HTTP2-Settings",
- MK_STR_INSENSITIVE,
- header->val.len);
- if (pos >= 0) {
- p->header_connection |= MK_HTTP_PARSER_CONN_HTTP2_SE;
- }
- }
- }
- else if (i == MK_HEADER_UPGRADE) {
- if (header_cmp(MK_UPGRADE_H2C,
- header->val.data, header->val.len) == 0) {
- p->header_upgrade = MK_HTTP_PARSER_UPGRADE_H2C;
- }
- }
-
- return 0;
- }
- }
-
- /*
- * The header_lookup did not match any known header, so we register this
- * entry into the headers_extra array.
- */
- if (p->headers_extra_count < MK_HEADER_EXTRA_SIZE) {
- header_extra = &p->headers_extra[p->headers_extra_count];
- header_extra->key.data = tmp = (buffer + p->header_key);
- header_extra->key.len = len;
-
- /* Transform the header key string to lowercase */
- for (i = 0; i < len; i++) {
- tmp[i] = tolower(tmp[i]);
- }
-
- header_extra->val.data = buffer + p->header_val;
- header_extra->val.len = p->end - p->header_val;
- p->headers_extra_count++;
- p->header_count++;
- mk_list_add(&header_extra->_head, &p->header_list);
- return 0;
- }
-
- /*
- * Header is unknown and we cannot store it on our extra headers
- * list as it's already full. Request is too large.
- */
- return -MK_CLIENT_REQUEST_ENTITY_TOO_LARGE;
-}
-
-/*
- * This function is invoked everytime the parser evaluate the request is
- * OK. Here we perform some extra validations mostly based on some logic
- * and protocol requirements according to the data received.
- */
-static inline int mk_http_parser_ok(struct mk_http_request *req,
- struct mk_http_parser *p,
- struct mk_server *server)
-{
- /* Validate HTTP Version */
- if (req->protocol == MK_HTTP_PROTOCOL_UNKNOWN) {
- mk_http_error(MK_SERVER_HTTP_VERSION_UNSUP, req->session, req, server);
- return MK_HTTP_PARSER_ERROR;
- }
-
- /* POST checks */
- if (req->method == MK_METHOD_POST || req->method == MK_METHOD_PUT) {
- /* validate Content-Length exists */
- if (p->headers[MK_HEADER_CONTENT_LENGTH].type == 0) {
- mk_http_error(MK_CLIENT_LENGTH_REQUIRED, req->session, req, server);
- return MK_HTTP_PARSER_ERROR;
- }
- }
-
- return MK_HTTP_PARSER_OK;
-}
-
-/*
- * Parse the protocol and point relevant fields, don't take logic decisions
- * based on this, just parse to locate things.
- */
-int mk_http_parser(struct mk_http_request *req, struct mk_http_parser *p,
- char *buffer, int buf_len, struct mk_server *server)
-{
- int s;
- int tmp;
- int ret;
- int len;
-
- /* lazy test
- printf("p->i=%i buf_len=%i\n",
- p->i, buf_len);
-
- for (s = p->i; s < buf_len; s++) {
- if (buffer[s] == '\r') {
- printf("CR");
- }
- else if (buffer[s] == '\n') {
- printf("LF");
- }
- else {
- printf("%c", buffer[s]);
- }
- }
- printf("\n");
- */
-
- len = buf_len;
- for (; p->i < len; p->i++, p->chars++) {
- /* FIRST LINE LEVEL: Method, URI & Protocol */
- if (p->level == REQ_LEVEL_FIRST) {
- switch (p->status) {
- case MK_ST_REQ_METHOD: /* HTTP Method */
- if (p->chars == -1) {
- switch (buffer[p->i]) {
- case 'G':
- p->method = MK_METHOD_GET;
- break;
- case 'P':
- p->method = MK_METHOD_POST;
- break;
- case 'H':
- p->method = MK_METHOD_HEAD;
- break;
- case 'D':
- p->method = MK_METHOD_DELETE;
- break;
- case 'O':
- p->method = MK_METHOD_OPTIONS;
- break;
- }
- continue;
- }
-
- if (buffer[p->i] == ' ') {
- mark_end();
- p->status = MK_ST_REQ_URI;
- if (p->end < 2) {
- return MK_HTTP_PARSER_ERROR;
- }
- method_lookup(req, p, buffer);
- start_next();
- }
- else {
- if ((p->i - p->start) > 10) {
- return MK_HTTP_PARSER_ERROR;
- }
- }
- break;
- case MK_ST_REQ_URI: /* URI */
- if (buffer[p->i] == ' ') {
- mark_end();
- p->status = MK_ST_REQ_PROT_VERSION;
- if (field_len() < 1) {
- return MK_HTTP_PARSER_ERROR;
- }
- request_set(&req->uri, p, buffer);
- start_next();
- }
- else if (buffer[p->i] == '?') {
- mark_end();
- request_set(&req->uri, p, buffer);
- p->status = MK_ST_REQ_QUERY_STRING;
- start_next();
- }
- else if (buffer[p->i] == '\r' || buffer[p->i] == '\n') {
- mk_http_error(MK_CLIENT_BAD_REQUEST, req->session,
- req, server);
- return MK_HTTP_PARSER_ERROR;
- }
- break;
- case MK_ST_REQ_QUERY_STRING: /* Query string */
- char_lookup(buffer, '\n', len, p);
-
- if (buffer[p->i] == '\n') {
- reverse_char_lookup(buffer, ' ', p->i, p);
- }
-
- if (buffer[p->i] == ' ') {
- mark_end();
- request_set(&req->query_string, p, buffer);
- p->status = MK_ST_REQ_PROT_VERSION;
- start_next();
- }
- else if (buffer[p->i] == '\r' || buffer[p->i] == '\n') {
- mk_http_error(MK_CLIENT_BAD_REQUEST, req->session,
- req, server);
- return MK_HTTP_PARSER_ERROR;
- }
- break;
- case MK_ST_REQ_PROT_VERSION: /* Protocol Version */
- /*
- * Most of the time we already have the string version in our
- * buffer, for that case try to match the version and avoid
- * loop rounds.
- */
- if (p->start + 6 >= p->i) {
- continue;
- }
-
- tmp = p->start;
- if (buffer[tmp] == 'H' &&
- buffer[tmp + 1] == 'T' &&
- buffer[tmp + 2] == 'T' &&
- buffer[tmp + 3] == 'P' &&
- buffer[tmp + 4] == '/' &&
- buffer[tmp + 5] == '1' &&
- buffer[tmp + 6] == '.') {
-
- request_set(&req->protocol_p, p, buffer);
- req->protocol_p.len = 8;
- mk_http_set_minor_version(buffer[tmp + 7]);
- }
- else {
- mk_http_error(MK_SERVER_HTTP_VERSION_UNSUP,
- req->session, req, server);
- return MK_HTTP_PARSER_ERROR;
- }
- p->status = MK_ST_FIRST_CONTINUE;
- break;
- case MK_ST_FIRST_CONTINUE:
- if (buffer[p->i] == '\r') {
- p->status = MK_ST_FIRST_FINALIZING;
- }
- else {
- return MK_HTTP_PARSER_ERROR;
- }
- break;
- case MK_ST_FIRST_FINALIZING: /* New Line */
- if (buffer[p->i] == '\n') {
- p->level = REQ_LEVEL_CONTINUE;
- start_next();
- }
- else {
- return MK_HTTP_PARSER_ERROR;
- }
- break;
- case MK_ST_BLOCK_END:
- if (buffer[p->i] == '\n') {
- return mk_http_parser_ok(req, p, server);
- }
- else {
- return MK_HTTP_PARSER_ERROR;
- }
- break;
- };
- }
- else if (p->level == REQ_LEVEL_CONTINUE) {
- if (buffer[p->i] == '\r') {
- p->level = REQ_LEVEL_FIRST;
- p->status = MK_ST_BLOCK_END;
- }
- else {
- p->level = REQ_LEVEL_HEADERS;
- p->status = MK_ST_HEADER_KEY;
- p->chars = 0;
- }
- }
- /* HEADERS: all headers stuff */
- if (p->level == REQ_LEVEL_HEADERS) {
- /* Expect a Header key */
- if (p->status == MK_ST_HEADER_KEY) {
- if (buffer[p->i] == '\r') {
- if (p->chars == 0) {
- p->level = REQ_LEVEL_END;
- start_next();
- }
- else {
- return MK_HTTP_PARSER_ERROR;
- }
- }
-
- if (p->chars == 0) {
- /*
- * We reach the start of a Header row, lets catch the most
- * probable header.
- *
- * The goal of this 'first row character lookup', is to define a
- * small range set of probable headers comparison once we catch
- * a header end.
- */
- s = tolower(buffer[p->i]);
- switch (s) {
- case 'a':
- p->header_min = MK_HEADER_ACCEPT;
- p->header_max = MK_HEADER_AUTHORIZATION;
- break;
- case 'c':
- p->header_min = MK_HEADER_CACHE_CONTROL;
- p->header_max = MK_HEADER_CONTENT_TYPE;
- break;
- case 'h':
- p->header_min = MK_HEADER_HOST;
- p->header_max = MK_HEADER_HTTP2_SETTINGS;
- break;
- case 'i':
- header_scope_eq(p, MK_HEADER_IF_MODIFIED_SINCE);
- break;
- case 'l':
- p->header_min = MK_HEADER_LAST_MODIFIED;
- p->header_max = MK_HEADER_LAST_MODIFIED_SINCE;
- break;
- case 'r':
- p->header_min = MK_HEADER_RANGE;
- p->header_max = MK_HEADER_REFERER;
- break;
- case 'u':
- p->header_min = MK_HEADER_UPGRADE;
- p->header_max = MK_HEADER_USER_AGENT;
- break;
- default:
- p->header_key = -1;
- p->header_sep = -1;
- p->header_min = -1;
- p->header_max = -1;
- };
- p->header_key = p->i;
- continue;
- }
-
- /* Found key/value separator */
- char_lookup(buffer, ':', len, p);
- if (buffer[p->i] == ':') {
- /* Set the key/value middle point */
- p->header_sep = p->i;
-
- /* validate length */
- mark_end();
- if (field_len() < 1) {
- return MK_HTTP_PARSER_ERROR;
- }
-
- /* Wait for a value */
- p->status = MK_ST_HEADER_VALUE;
- start_next();
- }
- }
- /* Parsing the header value */
- else if (p->status == MK_ST_HEADER_VALUE) {
- /* Trim left, set starts only when found something != ' ' */
- if (buffer[p->i] == '\r' || buffer[p->i] == '\n') {
- return MK_HTTP_PARSER_ERROR;
- }
- else if (buffer[p->i] != ' ') {
- p->status = MK_ST_HEADER_VAL_STARTS;
- p->start = p->header_val = p->i;
- }
- continue;
- }
- /* New header row starts */
- else if (p->status == MK_ST_HEADER_VAL_STARTS) {
- /* Maybe there is no more headers and we reach the end ? */
- if (buffer[p->i] == '\r') {
- mark_end();
- if (field_len() <= 0) {
- return MK_HTTP_PARSER_ERROR;
- }
-
- /*
- * A header row has ended, lets lookup the header and populate
- * our headers table index.
- */
- ret = header_lookup(p, buffer);
- if (ret != 0) {
- if (ret < -1) {
- mk_http_error(-ret, req->session, req, server);
- }
- return MK_HTTP_PARSER_ERROR;
- }
-
- /* Try to catch next LF */
- if (p->i + 1 < len) {
- if (buffer[p->i + 1] == '\n') {
- p->i++;
- p->status = MK_ST_HEADER_KEY;
- p->chars = -1;
- start_next();
- }
- }
-
- p->status = MK_ST_HEADER_END;
- start_next();
- }
- else if (buffer[p->i] == '\n' && buffer[p->i - 1] != '\r') {
- return MK_HTTP_PARSER_ERROR;
- }
- }
- else if (p->status == MK_ST_HEADER_END) {
- if (buffer[p->i] == '\n') {
- p->status = MK_ST_HEADER_KEY;
- p->chars = -1;
- start_next();
- }
- else {
- return MK_HTTP_PARSER_ERROR;
- }
- }
- }
- else if (p->level == REQ_LEVEL_END) {
- if (buffer[p->i] == '\n') {
- if (p->header_content_length > 0) {
- p->level = REQ_LEVEL_BODY;
- p->chars = -1;
- start_next();
- }
- else {
- return mk_http_parser_ok(req, p, server);
- }
- }
- else {
- return MK_HTTP_PARSER_ERROR;
- }
- }
- else if (p->level == REQ_LEVEL_BODY) {
- /*
- * Reaching this level can means two things:
- *
- * - A Pipeline Request
- * - A Body content (POST/PUT methods)
- */
- if (p->header_content_length > 0) {
-
- p->body_received = len - p->start;
- if ((len - p->start) < p->header_content_length) {
- return MK_HTTP_PARSER_PENDING;
- }
-
- /* Cut off */
- p->i += p->body_received;
- req->data.len = p->body_received;
- req->data.data = (buffer + p->start);
- }
- return mk_http_parser_ok(req, p, server);
- }
- }
-
- return MK_HTTP_PARSER_PENDING;
-}
diff --git a/fluent-bit/lib/monkey/mk_server/mk_http_thread.c b/fluent-bit/lib/monkey/mk_server/mk_http_thread.c
deleted file mode 100644
index d3c606f3..00000000
--- a/fluent-bit/lib/monkey/mk_server/mk_http_thread.c
+++ /dev/null
@@ -1,290 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-
-/* Monkey HTTP Server
- * ==================
- * Copyright 2001-2016 Monkey Software LLC <eduardo@monkey.io>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <monkey/mk_info.h>
-#include <monkey/mk_plugin.h>
-#include <monkey/mk_thread.h>
-#include <monkey/mk_net.h>
-#include <monkey/mk_vhost.h>
-#include <monkey/mk_http_thread.h>
-
-#include <stdlib.h>
-
-/*
- * libco do not support parameters in the entrypoint function due to the
- * complexity of implementation in terms of architecture and compiler, but
- * it provide a workaround using a global structure as a middle entry-point
- * that achieve the same stuff.
- */
-struct mk_http_libco_params {
- int type;
- struct mk_vhost_handler *handler;
- struct mk_http_session *session;
- struct mk_http_request *request;
- int n_params;
- struct mk_list *params;
- struct mk_thread *th;
-};
-
-pthread_once_t mk_http_thread_initialize_tls_once_flag = PTHREAD_ONCE_INIT;
-
-MK_TLS_DEFINE(struct mk_http_libco_params, mk_http_thread_libco_params);
-MK_TLS_DEFINE(struct mk_thread, mk_thread);
-
-/* This function could return NULL if the process runs out of memory, in that
- * case failure is imminent.
- */
-static inline struct mk_http_libco_params *thread_get_libco_params()
-{
- struct mk_http_libco_params *libco_params;
-
- libco_params = MK_TLS_GET(mk_http_thread_libco_params);
-
- if (libco_params == NULL) {
- libco_params = mk_mem_alloc_z(sizeof(struct mk_http_libco_params));
-
- if (libco_params == NULL) {
- mk_err("libco thread params could not be allocated.");
- }
-
- MK_TLS_SET(mk_http_thread_libco_params, libco_params);
- }
-
- return libco_params;
-}
-
-static void mk_http_thread_initialize_tls_once()
-{
- MK_TLS_INIT(mk_http_thread_libco_params);
- MK_TLS_INIT(mk_thread);
-}
-
-void mk_http_thread_initialize_tls()
-{
- pthread_once(&mk_http_thread_initialize_tls_once_flag,
- mk_http_thread_initialize_tls_once);
-}
-
-static inline void thread_cb_init_vars()
-{
- struct mk_http_libco_params *libco_params;
- struct mk_vhost_handler *handler;
- struct mk_http_session *session;
- struct mk_http_request *request;
- int close;
- int type;
- struct mk_http_thread *mth;
- struct mk_thread *th;
-
- libco_params = thread_get_libco_params();
-
- type = libco_params->type;
- handler = libco_params->handler;
- session = libco_params->session;
- request = libco_params->request;
- th = libco_params->th;
-
- /*
- * Until this point the th->callee already set the variables, so we
- * wait until the core wanted to resume so we really trigger the
- * output callback.
- */
- co_switch(th->caller);
-
- if (type == MK_HTTP_THREAD_LIB) {
- /* Invoke the handler callback */
- handler->cb(request, handler->data);
-
- /*
- * Once the callback finished, we need to sanitize the connection
- * so other further requests can be processed.
- */
- int ret;
- struct mk_sched_worker *sched;
- struct mk_channel *channel;
-
- channel = request->session->channel;
- sched = mk_sched_get_thread_conf();
-
- MK_EVENT_NEW(channel->event);
- ret = mk_event_add(sched->loop,
- channel->fd,
- MK_EVENT_CONNECTION,
- MK_EVENT_READ, channel->event);
- if (ret == -1) {
- //return -1;
- }
-
- /* Save temporal session */
- mth = request->thread;
-
- /*
- * Finalize request internally, if ret == -1 means we should
- * ask to shutdown the connection.
- */
- ret = mk_http_request_end(session, session->server);
- if (ret == -1) {
- close = MK_TRUE;
- }
- else {
- close = MK_FALSE;
- }
- mk_http_thread_purge(mth, close);
-
- /* Return control to caller */
- mk_thread_yield(th);
- }
- else if (type == MK_HTTP_THREAD_PLUGIN) {
- /* FIXME: call plugin handler callback with params */
- }
-}
-
-static inline void thread_params_set(struct mk_thread *th,
- int type,
- struct mk_vhost_handler *handler,
- struct mk_http_session *session,
- struct mk_http_request *request,
- int n_params,
- struct mk_list *params)
-{
- struct mk_http_libco_params *libco_params;
-
- libco_params = thread_get_libco_params();
-
- /* Callback parameters in order */
- libco_params->type = type;
- libco_params->handler = handler;
- libco_params->session = session;
- libco_params->request = request;
- libco_params->n_params = n_params;
- libco_params->params = params;
- libco_params->th = th;
-
- co_switch(th->callee);
-}
-
-struct mk_http_thread *mk_http_thread_create(int type,
- struct mk_vhost_handler *handler,
- struct mk_http_session *session,
- struct mk_http_request *request,
- int n_params,
- struct mk_list *params)
-{
- size_t stack_size;
- struct mk_thread *th = NULL;
- struct mk_http_thread *mth;
- struct mk_sched_worker *sched;
-
- sched = mk_sched_get_thread_conf();
- if (!sched) {
- return NULL;
- }
-
- th = mk_thread_new(sizeof(struct mk_http_thread), NULL);
- if (!th) {
- return NULL;
- }
-
- mth = (struct mk_http_thread *) MK_THREAD_DATA(th);
- if (!mth) {
- return NULL;
- }
-
- mth->session = session;
- mth->request = request;
- mth->parent = th;
- mth->close = MK_FALSE;
- request->thread = mth;
- mk_list_add(&mth->_head, &sched->threads);
-
- th->caller = co_active();
- th->callee = co_create(MK_THREAD_STACK_SIZE,
- thread_cb_init_vars, &stack_size);
-
-#ifdef MK_HAVE_VALGRIND
- th->valgrind_stack_id = VALGRIND_STACK_REGISTER(th->callee,
- ((char *)th->callee) + stack_size);
-#endif
-
- /* Workaround for makecontext() */
- thread_params_set(th, type, handler, session, request, n_params, params);
-
- return mth;
-}
-
-/*
- * Move a http thread context from sched->thread to sched->threads_purge list.
- * On this way the scheduler will release or reasign the resource later.
- */
-int mk_http_thread_purge(struct mk_http_thread *mth, int close)
-{
- struct mk_sched_worker *sched;
-
- sched = mk_sched_get_thread_conf();
- if (!sched) {
- return -1;
- }
-
- mth->close = close;
- mk_list_del(&mth->_head);
- mk_list_add(&mth->_head, &sched->threads_purge);
-
- return 0;
-}
-
-int mk_http_thread_destroy(struct mk_http_thread *mth)
-{
- struct mk_thread *th;
-
- /* Unlink from scheduler thread list */
- mk_list_del(&mth->_head);
-
- /* release original memory context */
- th = mth->parent;
- mth->session->channel->event->type = MK_EVENT_CONNECTION;
- mk_thread_destroy(th);
-
- return 0;
-}
-
-int mk_http_thread_event(struct mk_event *event)
-{
- struct mk_sched_conn *conn = (struct mk_sched_conn *) event;
-
- /*
- struct mk_thread *th;
- struct mk_http_thread *mth;
-
- th = conn->channel.thread;
- mth = (struct mk_http_thread *) MK_THREAD_DATA(th);
- */
-
- mk_thread_resume(conn->channel.thread);
- return 0;
-}
-
-/*
- * Start the co-routine: invoke coroutine callback and start processing
- * data flush requests.
- */
-int mk_http_thread_start(struct mk_http_thread *mth)
-{
- mk_http_thread_resume(mth);
- return 0;
-}
diff --git a/fluent-bit/lib/monkey/mk_server/mk_kernel.c b/fluent-bit/lib/monkey/mk_server/mk_kernel.c
deleted file mode 100644
index cc69e96c..00000000
--- a/fluent-bit/lib/monkey/mk_server/mk_kernel.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/*-*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-
-/* Monkey HTTP Server
- * ==================
- * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <monkey/monkey.h>
-#include <monkey/mk_core.h>
-#include <monkey/mk_kernel.h>
-#include <monkey/mk_utils.h>
-#include <monkey/mk_server.h>
-#include <monkey/mk_scheduler.h>
-
-#include <ctype.h>
-
-#ifndef _WIN32
-#include <sys/utsname.h>
-
-int mk_kernel_version()
-{
- int a, b, c;
- int len;
- int pos;
- char *p, *t;
- char *tmp;
- struct utsname uts;
-
- if (uname(&uts) == -1) {
- mk_libc_error("uname");
- }
- len = strlen(uts.release);
-
- /* Fixme: this don't support Linux Kernel 10.x.x :P */
- a = (*uts.release - '0');
-
- /* Second number */
- p = (uts.release) + 2;
- pos = mk_string_char_search(p, '.', len - 2);
- if (pos <= 0) {
- /* Some Debian systems uses a different notation, e.g: 3.14-2-amd64 */
- pos = mk_string_char_search(p, '-', len - 2);
- if (pos <= 0) {
- return -1;
- }
- }
-
- tmp = mk_string_copy_substr(p, 0, pos);
- if (!tmp) {
- return -1;
- }
- b = atoi(tmp);
- mk_mem_free(tmp);
-
- /* Last number (it needs filtering) */
- t = p = p + pos + 1;
- do {
- t++;
- } while (isdigit(*t));
-
- tmp = mk_string_copy_substr(p, 0, t - p);
- if (!tmp) {
- return -1;
- }
- c = atoi(tmp);
- mk_mem_free(tmp);
-
- MK_TRACE("Kernel detected: %i.%i.%i", a, b, c);
- return MK_KERNEL_VERSION(a, b, c);
-}
-
-/* Detect specific Linux Kernel features that we may use */
-int mk_kernel_features(int version)
-{
- int flags = 0;
-
- /*
- * TCP Auto Corking (disabled by #175)
- * -----------------------------------
- * I found that running some benchmarks on Linux 3.16 with
- * tcp_autocorking enabled, it lead to lower performance, looks like
- * a manual cork fits better for our needs.
- *
- * I think there is something wrong that we need to clarify, by now
- * I've logged the following issue:
- *
- * https://github.com/monkey/monkey/issues/175
- *
- if (mk_kernel_runver >= MK_KERNEL_VERSION(3, 14, 0) &&
- mk_socket_tcp_autocorking() == MK_TRUE) {
- flags |= MK_KERNEL_TCP_AUTOCORKING;
- }
- */
-
- /* SO_REUSEPORT */
- if (version >= MK_KERNEL_VERSION(3, 9, 0)) {
- flags |= MK_KERNEL_SO_REUSEPORT;
- }
-
- /* TCP_FASTOPEN */
- if (version >= MK_KERNEL_VERSION(3, 7, 0)) {
- flags |= MK_KERNEL_TCP_FASTOPEN;
- }
-
- return flags;
-}
-
-int mk_kernel_features_print(char *buffer, size_t size,
- struct mk_server *server)
-{
- int offset = 0;
- int features = 0;
-
- if (server->kernel_features & MK_KERNEL_TCP_FASTOPEN) {
- offset += snprintf(buffer, size - offset, "%s", "TCP_FASTOPEN ");
- features++;
- }
-
- if (server->kernel_features & MK_KERNEL_SO_REUSEPORT) {
- if (server->scheduler_mode == MK_SCHEDULER_FAIR_BALANCING) {
- offset += snprintf(buffer + offset, size - offset,
- "%s!%s", ANSI_BOLD ANSI_RED, ANSI_RESET);
- }
- offset += snprintf(buffer + offset, size - offset, "%s", "SO_REUSEPORT ");
- features++;
- }
-
- if (server->kernel_features & MK_KERNEL_TCP_AUTOCORKING) {
- snprintf(buffer + offset, size - offset, "%s", "TCP_AUTOCORKING ");
- features++;
- }
-
- return features;
-}
-#else
-/* We still need to determine if this can be safely ignored or what do we need to do here */
-
-int mk_kernel_version()
-{
- return 1;
-}
-
-int mk_kernel_features(int version)
-{
- return 0;
-}
-
-int mk_kernel_features_print(char* buffer, size_t size,
- struct mk_server* server)
-{
- return 0;
-}
-#endif
diff --git a/fluent-bit/lib/monkey/mk_server/mk_lib.c b/fluent-bit/lib/monkey/mk_server/mk_lib.c
deleted file mode 100644
index c2940086..00000000
--- a/fluent-bit/lib/monkey/mk_server/mk_lib.c
+++ /dev/null
@@ -1,796 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-
-/* Monkey HTTP Server
- * ==================
- * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define _GNU_SOURCE
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <signal.h>
-
-#include <mk_core/mk_pthread.h>
-
-#include <monkey/mk_lib.h>
-#include <monkey/monkey.h>
-#include <monkey/mk_stream.h>
-#include <monkey/mk_thread.h>
-#include <monkey/mk_scheduler.h>
-#include <monkey/mk_fifo.h>
-#include <monkey/mk_utils.h>
-#include <monkey/mk_tls.h>
-
-#define config_eq(a, b) strcasecmp(a, b)
-
-static inline int bool_val(char *v)
-{
- if (strcasecmp(v, "On") == 0 || strcasecmp(v, "Yes") == 0) {
- return MK_TRUE;
- }
- else if (strcasecmp(v, "Off") == 0 || strcasecmp(v, "No") == 0) {
- return MK_FALSE;
- }
-
- return -1;
-}
-
-mk_ctx_t *mk_create()
-{
- mk_ctx_t *ctx;
-
- ctx = mk_mem_alloc_z(sizeof(mk_ctx_t));
- if (!ctx) {
- return NULL;
- }
-
- /* Create Monkey server instance */
- ctx->server = mk_server_create();
-
- /*
- * FIFO
- * ====
- * Before to prepare the background service, we create a MK_FIFO interface
- * for further communication between the caller (user) and HTTP end-point
- * callbacks.
- */
- ctx->fifo = mk_fifo_create(NULL, ctx->server);
- ctx->fifo->key = &mk_server_fifo_key;
-
- /*
- * FIFO: Set workers callback associated to the Monkey scheduler to prepare them
- * before to enter the event loop
- */
- mk_sched_worker_cb_add(ctx->server, mk_fifo_worker_setup, ctx->fifo);
- return ctx;
-}
-
-int mk_destroy(mk_ctx_t *ctx)
-{
- mk_fifo_destroy(ctx->fifo);
- mk_mem_free(ctx);
-
- return 0;
-}
-
-static inline int mk_lib_yield(mk_request_t *req)
-{
- int ret;
- struct mk_thread *th;
- struct mk_channel *channel;
- struct mk_sched_worker *sched;
-
- sched = mk_sched_get_thread_conf();
- if (!sched) {
- return -1;
- }
-
- th = MK_TLS_GET(mk_thread);
- channel = req->session->channel;
-
- channel->thread = th;
-
- ret = mk_event_add(sched->loop,
- channel->fd,
- MK_EVENT_THREAD,
- MK_EVENT_WRITE, channel->event);
- if (ret == -1) {
- return -1;
- }
-
- /* Just wait */
- mk_thread_yield(th);
-
- if (channel->event->status & MK_EVENT_REGISTERED) {
- /* We got a notification, remove the event registered
- ret = mk_event_add(sched->loop,
- channel->fd,
- MK_EVENT_CONNECTION,
- MK_EVENT_READ, channel->event);
- mk_thread_yield(th);
- */
-
- ret = mk_event_del(sched->loop, channel->event);
- }
-
- return 0;
-}
-
-static void mk_lib_worker(void *data)
-{
- int fd;
- int bytes;
- uint64_t val;
- struct mk_server *server;
- struct mk_event *event;
-
- mk_ctx_t *ctx = data;
- server = ctx->server;
-
- /* Start the service */
- mk_server_setup(server);
- mk_server_loop(server);
-
- /*
- * Give a second to the parent context to avoid consume an event
- * we should not read at the moment (SIGNAL_START).
- */
- sleep(1);
-
- /* Wait for events */
- mk_event_wait(server->lib_evl);
- mk_event_foreach(event, server->lib_evl) {
- fd = event->fd;
-
-#ifdef _WIN32
- bytes = recv(fd, &val, sizeof(uint64_t), MSG_WAITALL);
-#else
- bytes = read(fd, &val, sizeof(uint64_t));
-#endif
-
- if (bytes <= 0) {
- return;
- }
-
- if (val == MK_SERVER_SIGNAL_STOP) {
- break;
- }
- }
-
- mk_event_loop_destroy(server->lib_evl);
- mk_exit_all(server);
- pthread_kill(pthread_self(), 0);
-
- return;
-}
-
-int mk_start(mk_ctx_t *ctx)
-{
- int fd;
- int bytes;
- int ret;
- uint64_t val;
- pthread_t tid;
- struct mk_event *event;
- struct mk_server *server;
-
- server = ctx->server;
-
- ret = mk_utils_worker_spawn(mk_lib_worker, ctx, &tid);
- if (ret == -1) {
- return -1;
- }
- ctx->worker_tid = tid;
-
- /* Wait for the started signal so we can return to the caller */
- mk_event_wait(server->lib_evl_start);
- mk_event_foreach(event, server->lib_evl_start) {
- fd = event->fd;
-
- /* When using libevent _mk_event_channel_create creates a unix socket
- * instead of a pipe and windows doesn't us calling read / write on a
- * socket instead of recv / send
- */
-#ifdef _WIN32
- bytes = recv(fd, &val, sizeof(uint64_t), MSG_WAITALL);
-#else
- bytes = read(fd, &val, sizeof(uint64_t));
-#endif
-
- if (bytes <= 0) {
- ret = -1;
- break;
- }
-
- if (val == MK_SERVER_SIGNAL_START) {
- ret = 0;
- break;
- }
- else {
- ret = -1;
- break;
- }
- }
-
- mk_event_loop_destroy(server->lib_evl_start);
- if (ret == -1) {
- mk_stop(ctx);
- }
-
- return ret;
-}
-
-int mk_stop(mk_ctx_t *ctx)
-{
- int n;
- uint64_t val;
- int8_t scheduler_mode ;
- struct mk_server *server = ctx->server;
-
- /* Keep track of the scheduler mode on stack, since the
- * the worker may free the server before we need the info.
- */
- scheduler_mode = server->scheduler_mode;
-
- val = MK_SERVER_SIGNAL_STOP;
-
- /* Send a stop signal to the main lib channel to abort.
- *
- * MK_SCHEDULER_FAIR_BALANCING: this signal will be
- * consumed by mk_server_loop_balancer.
- *
- * MK_SCHEDULER_REUSEPORT: this signal will be consumed
- * by mk_lib_worker.
- */
-#ifdef _WIN32
- n = send(server->lib_ch_manager[1], &val, sizeof(val), 0);
-#else
- n = write(server->lib_ch_manager[1], &val, sizeof(val));
-#endif
- if (n <= 0) {
- perror("write");
- return -1;
- }
-
- /* In MK_SCHEDULER_FAIR_BALANCING mode, we need one more
- * stop signal to abort mk_lib_worker.
- */
- if (scheduler_mode == MK_SCHEDULER_FAIR_BALANCING) {
- /* Give mk_server_loop_balancer time to clean up. */
- sleep(1);
-
- /* Send a signal for mk_lib_worker to abort */
-#ifdef _WIN32
- n = send(server->lib_ch_manager[1], &val, sizeof(val), 0);
-#else
- n = write(server->lib_ch_manager[1], &val, sizeof(val));
-#endif
- if (n <= 0) {
- perror("write");
- return -1;
- }
- }
-
- /* Wait for the child thread to exit */
- pthread_join(ctx->worker_tid, NULL);
- return 0;
-}
-
-/*
- * Instruct Monkey core to invoke a callback function inside each worker
- * started by the scheduler.
- */
-int mk_worker_callback(mk_ctx_t *ctx,
- void (*cb_func) (void *),
- void *data)
-{
- return mk_sched_worker_cb_add(ctx->server, cb_func, data);
-}
-
-int mk_config_set_property(struct mk_server *server, char *k, char *v)
-{
- int b;
- int ret;
- int num;
- unsigned long len;
-
- if (config_eq(k, "Listen") == 0) {
- ret = mk_config_listen_parse(v, server);
- if (ret != 0) {
- return -1;
- }
- }
- else if (config_eq(k, "Workers") == 0) {
- num = atoi(v);
- if (num <= 0) {
- server->workers = mk_utils_get_system_core_count();
- }
- else {
- server->workers = num;
- }
- }
- else if (config_eq(k, "Timeout") == 0) {
- num = atoi(v);
- if (num <= 0) {
- return -1;
- }
- server->timeout = num;
- }
- else if (config_eq(k, "KeepAlive") == 0) {
- b = bool_val(v);
- if (b == -1) {
- return -1;
- }
- server->keep_alive = b;
- }
- else if (config_eq(k, "MaxKeepAliveRequest") == 0) {
- num = atoi(v);
- if (num <= 0) {
- return -1;
- }
- server->max_keep_alive_request = num;
- }
- else if (config_eq(k, "KeepAliveTimeout") == 0) {
- num = atoi(v);
- if (num <= 0) {
- return -1;
- }
- server->keep_alive_timeout = num;
- }
- else if (config_eq(k, "UserDir") == 0) {
- server->conf_user_pub = mk_string_dup(v);
- }
- else if (config_eq(k, "IndexFile") == 0) {
- server->index_files = mk_string_split_line(v);
- if (!server->index_files) {
- return -1;
- }
- }
- else if (config_eq(k, "HideVersion") == 0) {
- b = bool_val(v);
- if (b == -1) {
- return -1;
- }
- server->hideversion = b;
- }
- else if (config_eq(k, "Resume") == 0) {
- b = bool_val(v);
- if (b == -1) {
- return -1;
- }
- server->resume = b;
- }
- else if (config_eq(k, "MaxRequestSize") == 0) {
- num = atoi(v);
- if (num <= 0) {
- return -1;
- }
- server->max_request_size = num;
- }
- else if (config_eq(k, "SymLink") == 0) {
- b = bool_val(v);
- if (b == -1) {
- return -1;
- }
- server->symlink = b;
- }
- else if (config_eq(k, "DefaultMimeType") == 0) {
- mk_string_build(&server->mimetype_default_str, &len, "%s\r\n", v);
- }
- else if (config_eq(k, "FDT") == 0) {
- b = bool_val(v);
- if (b == -1) {
- return -1;
- }
- server->fdt = b;
- }
-
- return 0;
-}
-
-int mk_config_set(mk_ctx_t *ctx, ...)
-{
- int ret;
- char *key;
- char *value;
- va_list va;
-
- va_start(va, ctx);
-
- while ((key = va_arg(va, char *))) {
- value = va_arg(va, char *);
- if (!value) {
- /* Wrong parameter */
- va_end(va);
- return -1;
- }
-
- ret = mk_config_set_property(ctx->server, key, value);
- if (ret != 0) {
- va_end(va);
- return -1;
- }
- }
-
- va_end(va);
- return 0;
-}
-
-/* Given a vhost id, return the vhost context */
-struct mk_vhost *mk_vhost_lookup(mk_ctx_t *ctx, int id)
-{
- struct mk_vhost *host;
- struct mk_list *head;
-
- mk_list_foreach(head, &ctx->server->hosts) {
- host = mk_list_entry(head, struct mk_vhost, _head);
- if (host->id == id) {
- return host;
- }
- }
-
- return NULL;
-}
-
-int mk_vhost_create(mk_ctx_t *ctx, char *name)
-{
- struct mk_vhost *h;
- struct mk_vhost_alias *halias;
-
- /* Virtual host */
- h = mk_mem_alloc_z(sizeof(struct mk_vhost));
- if (!h) {
- return -1;
- }
-
- /* Assign a virtual host id, we just set based on list size */
- h->id = mk_list_size(&ctx->server->hosts);
- mk_list_init(&h->error_pages);
- mk_list_init(&h->server_names);
- mk_list_init(&h->handlers);
-
- /* Host alias */
- halias = mk_mem_alloc_z(sizeof(struct mk_vhost_alias));
- if (!halias) {
- mk_mem_free(h);
- return -1;
- }
-
- /* Host name */
- if (!name) {
- halias->name = mk_string_dup("127.0.0.1");
- }
- else {
- halias->name = mk_string_dup(name);
- }
- mk_list_add(&halias->_head, &h->server_names);
- mk_list_add(&h->_head, &ctx->server->hosts);
-
- /* Return the host id, that number is enough for further operations */
- return h->id;
-}
-
-static int mk_vhost_set_property(struct mk_vhost *vh, char *k, char *v)
-{
- struct mk_vhost_alias *ha;
-
- if (config_eq(k, "Name") == 0) {
- ha = mk_mem_alloc(sizeof(struct mk_vhost_alias));
- if (!ha) {
- return -1;
- }
- ha->name = mk_string_dup(v);
- ha->len = strlen(v);
- mk_list_add(&ha->_head, &vh->server_names);
- }
- else if (config_eq(k, "DocumentRoot") == 0) {
- vh->documentroot.data = mk_string_dup(v);
- vh->documentroot.len = strlen(v);
- }
-
- return 0;
-}
-
-int mk_vhost_set(mk_ctx_t *ctx, int vid, ...)
-{
- int ret;
- char *key;
- char *value;
- va_list va;
- struct mk_vhost *vh;
-
- /* Lookup the virtual host */
- vh = mk_vhost_lookup(ctx, vid);
- if (!vh) {
- return -1;
- }
-
- va_start(va, vid);
-
- while ((key = va_arg(va, char *))) {
- value = va_arg(va, char *);
- if (!value) {
- /* Wrong parameter */
- return -1;
- }
-
- ret = mk_vhost_set_property(vh, key, value);
- if (ret != 0) {
- va_end(va);
- return -1;
- }
- }
-
- va_end(va);
- return 0;
-}
-
-int mk_vhost_handler(mk_ctx_t *ctx, int vid, char *regex,
- void (*cb)(mk_request_t *, void *), void *data)
-{
- struct mk_vhost *vh;
- struct mk_vhost_handler *handler;
- void (*_cb) (struct mk_http_request *, void *);
-
- /* Lookup the virtual host */
- vh = mk_vhost_lookup(ctx, vid);
- if (!vh) {
- return -1;
- }
-
- _cb = cb;
- handler = mk_vhost_handler_match(regex, _cb, data);
- if (!handler) {
- return -1;
- }
- mk_list_add(&handler->_head, &vh->handlers);
-
- return 0;
-}
-
-/* Flush streams data associated to a request in question */
-int mk_http_flush(mk_request_t *req)
-{
- int ret;
- size_t out_bytes = 0;
-
- ret = mk_channel_stream_write(&req->stream, &out_bytes);
- return ret;
-}
-
-int mk_http_status(mk_request_t *req, int status)
-{
- req->headers.status = status;
- return 0;
-}
-
-/* Append a response header */
-int mk_http_header(mk_request_t *req,
- char *key, int key_len,
- char *val, int val_len)
-{
- int pos;
- int len;
- char *buf;
- struct response_headers *h;
-
- h = &req->headers;
- if (!h->_extra_rows) {
- h->_extra_rows = mk_iov_create(MK_PLUGIN_HEADER_EXTRA_ROWS * 2, 0);
- if (!h->_extra_rows) {
- return -1;
- }
- }
-
- len = key_len + val_len + 4;
- buf = mk_mem_alloc(len);
- if (!buf) {
- /* we don't free extra_rows as it's released later */
- return -1;
- }
-
- /* Compose the buffer */
- memcpy(buf, key, key_len);
- pos = key_len;
- buf[pos++] = ':';
- buf[pos++] = ' ';
- memcpy(buf + pos, val, val_len);
- pos += val_len;
- buf[pos++] = '\r';
- buf[pos++] = '\n';
-
- /* Add the new buffer */
- mk_iov_add(h->_extra_rows, buf, pos, MK_TRUE);
-
- return 0;
-}
-
-static inline int chunk_header(long num, char *out)
-{
- int i = 1;
- int j, c;
- int remainder;
- int quotient;
- char tmp[32];
- char hex[] = "0123456789ABCDEF";
-
- if (num == 0) {
- out[0] = '0';
- out[1] = '\r';
- out[2] = '\n';
- out[3] = '\r';
- out[4] = '\n';
- out[5] = '\0';
- return 5;
- }
-
- quotient = num;
- while (quotient != 0) {
- remainder = quotient % 16;
- tmp[i++] = hex[remainder];
- quotient = quotient / 16;
- }
-
- c = 0;
- for (j = i -1 ; j > 0; j--, c++) {
- out[c] = tmp[j];
- }
-
- out[c++] = '\r';
- out[c++] = '\n';
- out[c] = '\0';
-
- return c;
-}
-
-static void free_chunk_header(struct mk_stream_input *input)
-{
- mk_mem_free(input->buffer);
- input->buffer = NULL;
-}
-
-
-/* Check if response headers were processed, otherwise prepare them */
-static int headers_setup(mk_request_t *req)
-{
- /*
- * Let's keep it simple for now: if the headers have not been sent, do it
- * now and then send the body content just queued.
- */
- if (req->headers.sent == MK_FALSE) {
- /* Force chunked-transfer encoding */
- if (req->protocol == MK_HTTP_PROTOCOL_11) {
- req->headers.transfer_encoding = MK_HEADER_TE_TYPE_CHUNKED;
- }
- else {
- req->headers.content_length = -1;
- }
- mk_header_prepare(req->session, req, req->session->server);
- }
- return 0;
-}
-
-/* Enqueue some data for the body response */
-int mk_http_send(mk_request_t *req, char *buf, size_t len,
- void (*cb_finish)(mk_request_t *))
-{
- int chunk_len;
- int ret;
- char *tmp;
- char chunk_pre[32];
- (void) cb_finish;
-
- if (req->session->channel->status != MK_CHANNEL_OK) {
- return -1;
- }
-
- if (req->headers.status == -1) {
- /* Cannot append data if the status have not been set */
- mk_err("HTTP: set the response status first");
- return -1;
- }
-
- /* Chunk encoding prefix */
- if (req->protocol == MK_HTTP_PROTOCOL_11) {
- chunk_len = chunk_header(len, chunk_pre);
- tmp = mk_string_dup(chunk_pre);
- if (!tmp) {
- return -1;
- }
- ret = mk_stream_in_raw(&req->stream, NULL,
- tmp, chunk_len, NULL, free_chunk_header);
- if (ret != 0) {
- return -1;
- }
- }
-
- /* Append raw data */
- if (len > 0) {
- ret = mk_stream_in_raw(&req->stream, NULL,
- buf, len, NULL, NULL);
- if (ret == 0) {
- /* Update count of bytes */
- req->stream_size += len;
- }
- }
-
- if (req->protocol == MK_HTTP_PROTOCOL_11 && len > 0) {
- ret = mk_stream_in_raw(&req->stream, NULL,
- "\r\n", 2, NULL, NULL);
- }
-
- /* Validate if the response headers are ready */
- headers_setup(req);
-
- /* Flush channel data */
- ret = mk_http_flush(req);
-
- /*
- * Flush have been done, before to return our original caller, we want to yield
- * and give some execution time to the event loop to avoid possible blocking
- * since the caller might be using this mk_http_send() in a loop.
- */
- mk_lib_yield(req);
- return ret;
-}
-
-int mk_http_done(mk_request_t *req)
-{
- if (req->session->channel->status != MK_CHANNEL_OK) {
- return -1;
- }
-
- /* Validate if the response headers are ready */
- headers_setup(req);
-
- if (req->headers.transfer_encoding == MK_HEADER_TE_TYPE_CHUNKED) {
- /* Append end-of-chunk bytes */
- mk_http_send(req, NULL, 0, NULL);
- }
- else {
- mk_http_send(req, NULL, 0, NULL);
- }
-
- if (req->session->close_now == MK_TRUE) {
- mk_lib_yield(req);
- }
-
- return 0;
-}
-
-/* Create a messaging queue end-point */
-int mk_mq_create(mk_ctx_t *ctx, char *name, void (*cb), void *data)
-{
- int id;
-
- id = mk_fifo_queue_create(ctx->fifo, name, cb, data);
- return id;
-}
-
-/* Write a message to a specific queue ID */
-int mk_mq_send(mk_ctx_t *ctx, int qid, void *data, size_t size)
-{
- return mk_fifo_send(ctx->fifo, qid, data, size);
-}
-
-int mk_main()
-{
- while (1) {
- sleep(60);
- }
-
- return 0;
-}
diff --git a/fluent-bit/lib/monkey/mk_server/mk_mimetype.c b/fluent-bit/lib/monkey/mk_server/mk_mimetype.c
deleted file mode 100644
index b86b4ef1..00000000
--- a/fluent-bit/lib/monkey/mk_server/mk_mimetype.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-
-/* Monkey HTTP Server
- * ==================
- * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define _GNU_SOURCE
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <string.h>
-#include <ctype.h>
-
-#include <mk_core/mk_unistd.h>
-
-#include <monkey/monkey.h>
-#include <monkey/mk_mimetype.h>
-#include <monkey/mk_utils.h>
-#include <monkey/mk_config.h>
-#include <monkey/mk_core.h>
-#include <monkey/mk_http.h>
-
-struct mk_mimetype *mimetype_default;
-
-static int rbtree_compare(const void *lhs, const void *rhs)
-{
- return strcmp((const char *)lhs, (const char *)rhs);
-}
-
-/* Match mime type for requested resource */
-struct mk_mimetype *mk_mimetype_lookup(struct mk_server *server, char *name)
-{
- int cmp;
- struct rb_tree_node *node = server->mimetype_rb_head.root;
-
- while (node) {
- struct mk_mimetype *entry = container_of(node, struct mk_mimetype, _rb_head);
- cmp = strcmp(name, entry->name);
- if (cmp < 0)
- node = node->left;
- else if (cmp > 0)
- node = node->right;
- else {
- return entry;
- }
- }
- return NULL;
-}
-
-int mk_mimetype_add(struct mk_server *server, char *name, const char *type)
-{
- int len = strlen(type) + 3;
- char *p;
- struct mk_mimetype *new_mime;
-
- /* make sure we register the extension in lower case */
- p = name;
- for ( ; *p; ++p) *p = tolower(*p);
-
- new_mime = mk_mem_alloc_z(sizeof(struct mk_mimetype));
- if (!new_mime) {
- return -1;
- }
- new_mime->name = mk_string_dup(name);
- if (!new_mime->name) {
- mk_mem_free(new_mime);
- return -1;
- }
- new_mime->type.data = mk_mem_alloc(len);
- if (!new_mime->type.data) {
- mk_mem_free(new_mime->name);
- mk_mem_free(new_mime);
- return -1;
- }
- new_mime->type.len = len - 1;
- new_mime->header_type.data = mk_mem_alloc(len + 32);
- if (!new_mime->header_type.data) {
- mk_mem_free(new_mime->name);
- mk_mem_free(new_mime->type.data);
- mk_mem_free(new_mime);
- return -1;
- }
- new_mime->header_type.len = snprintf(new_mime->header_type.data,
- len + 32,
- "Content-Type: %s\r\n",
- type);
- strcpy(new_mime->type.data, type);
- strcat(new_mime->type.data, MK_CRLF);
- new_mime->type.data[len-1] = '\0';
-
- /* Insert the node into the RBT */
- rb_tree_insert(&server->mimetype_rb_head,
- new_mime->name, &new_mime->_rb_head);
-
- /* Add to linked list head */
- mk_list_add(&new_mime->_head, &server->mimetype_list);
-
- return 0;
-}
-
-int mk_mimetype_init(struct mk_server *server)
-{
- char *name;
- int ret;
-
- /* Initialize the heads */
- mk_list_init(&server->mimetype_list);
- rb_tree_new(&server->mimetype_rb_head, rbtree_compare);
-
- name = mk_string_dup(MIMETYPE_DEFAULT_NAME);
- if (server->mimetype_default_str) {
- ret = mk_mimetype_add(server, name, server->mimetype_default_str);
- }
- else {
- ret = mk_mimetype_add(server, name, MIMETYPE_DEFAULT_TYPE);
- }
- if (ret < 0) {
- mk_mem_free(name);
- return -1;
- }
- server->mimetype_default = mk_list_entry_first(&server->mimetype_list,
- struct mk_mimetype,
- _head);
- mk_mem_free(name);
- return 0;
-}
-
-/* Load the two mime arrays into memory */
-int mk_mimetype_read_config(struct mk_server *server)
-{
- char path[MK_MAX_PATH];
- struct mk_rconf *cnf;
- struct mk_rconf_section *section;
- struct mk_rconf_entry *entry;
- struct mk_list *head;
- struct file_info f_info;
- int ret;
-
- if (!server->conf_mimetype) {
- return -1;
- }
-
- /* Read mime types configuration file */
- snprintf(path, MK_MAX_PATH, "%s/%s",
- server->path_conf_root,
- server->conf_mimetype);
-
- ret = mk_file_get_info(path, &f_info, MK_FILE_EXISTS);
- if (ret == -1 || f_info.is_file == MK_FALSE) {
- snprintf(path, MK_MAX_PATH, "%s", server->conf_mimetype);
- }
- cnf = mk_rconf_open(path);
- if (!cnf) {
- mk_warn("[mime] skipping mimetype configuration file");
- return -1;
- }
-
- /* Get MimeTypes tag */
- section = mk_rconf_section_get(cnf, "MIMETYPES");
- if (!section) {
- mk_err("[mime] Invalid mime type file");
- return -1;
- }
-
- mk_list_foreach(head, &section->entries) {
- entry = mk_list_entry(head, struct mk_rconf_entry, _head);
- if (!entry->key || !entry->val) {
- continue;
- }
-
- if (mk_mimetype_add(server, entry->key, entry->val) != 0) {
- mk_err("[mime] Error loading Mime Types");
- return -1;
- }
- }
-
- mk_rconf_free(cnf);
-
- return 0;
-}
-
-struct mk_mimetype *mk_mimetype_find(struct mk_server *server, mk_ptr_t *filename)
-{
- int j, len;
-
- j = len = filename->len;
-
- /* looking for extension */
- while (j >= 0 && filename->data[j] != '.') {
- j--;
- }
-
- if (j <= 0) {
- return NULL;
- }
-
- return mk_mimetype_lookup(server, filename->data + j + 1);
-}
-
-void mk_mimetype_free_all(struct mk_server *server)
-{
- struct mk_list *head;
- struct mk_list *tmp;
- struct mk_mimetype *mime;
-
- mk_list_foreach_safe(head, tmp, &server->mimetype_list) {
- mime = mk_list_entry(head, struct mk_mimetype, _head);
- mk_ptr_free(&mime->type);
- mk_mem_free(mime->name);
- mk_mem_free(mime->header_type.data);
- mk_mem_free(mime);
- }
-}
diff --git a/fluent-bit/lib/monkey/mk_server/mk_net.c b/fluent-bit/lib/monkey/mk_server/mk_net.c
deleted file mode 100644
index de183de4..00000000
--- a/fluent-bit/lib/monkey/mk_server/mk_net.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-
-/* Monkey HTTP Server
- * ==================
- * Copyright 2001-2016 Monkey Software LLC <eduardo@monkey.io>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <monkey/mk_core.h>
-#include <monkey/mk_net.h>
-#include <monkey/mk_scheduler.h>
-#include <monkey/mk_plugin.h>
-#include <monkey/mk_thread.h>
-#include <monkey/mk_tls.h>
-
-#ifdef _WIN32
-#include <winsock2.h>
-#include <afunix.h>
-#else
-#include <sys/socket.h>
-#include <netinet/tcp.h>
-#endif
-
-/* Initialize the network stack*/
-int mk_net_init()
-{
-#ifdef _WIN32
- int result;
- WSADATA wsa_data;
- static int initialized = 0;
-
- if(0 != initialized) {
- return 0;
- }
-
- result = WSAStartup(MAKEWORD(2, 2), &wsa_data);
-
- if(0 != result) {
- if(WSAEINPROGRESS == result)
- {
- Sleep(100); /* Let the other thread finish initializing the stack */
-
- return 0;
- }
-
- return -1;
- }
-
- initialized = 1;
-#endif
-
- return 0;
-}
-
-/* Connect to a TCP socket server */
-static int mk_net_fd_connect(int fd, char *host, unsigned long port)
-{
- int ret;
- struct addrinfo hints;
- struct addrinfo *res;
- char _port[6];
-
- memset(&hints, 0, sizeof hints);
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
-
- snprintf(_port, sizeof(_port), "%lu", port);
- ret = getaddrinfo(host, _port, &hints, &res);
- if (ret != 0) {
- return -1;
- }
-
- ret = connect(fd, res->ai_addr, res->ai_addrlen);
- freeaddrinfo(res);
-
- return ret;
-}
-
-struct mk_net_connection *mk_net_conn_create(char *addr, int port)
-{
- int fd;
- int ret;
- int error = 0;
- socklen_t len = sizeof(error);
- struct mk_sched_worker *sched;
- struct mk_net_connection *conn;
-
- /* Allocate connection context */
- conn = mk_mem_alloc(sizeof(struct mk_net_connection));
- if (!conn) {
- return NULL;
- }
-
- /* Create socket */
- fd = mk_socket_create(AF_INET, SOCK_STREAM, 0);
- if (fd == -1) {
- mk_mem_free(conn);
- return NULL;
- }
-
- /* Make socket async */
- mk_socket_set_nonblocking(fd);
- conn->fd = fd;
-
- ret = mk_net_fd_connect(conn->fd, addr, port);
- if (ret == -1) {
- if (errno != EINPROGRESS) {
- close(fd);
- mk_mem_free(conn);
- return NULL;
- }
-
- MK_EVENT_NEW(&conn->event);
-
- sched = mk_sched_get_thread_conf();
- // FIXME: not including the thread
- //conn->thread = mk_thread_get();
- ret = mk_event_add(sched->loop, conn->fd, MK_EVENT_THREAD,
- MK_EVENT_WRITE, &conn->event);
- if (ret == -1) {
- close(fd);
- mk_mem_free(conn);
- return NULL;
- }
-
- /*
- * Return the control to the parent caller, we need to wait for
- * the event loop to get back to us.
- */
- mk_thread_yield(conn->thread);
-
- /* We got a notification, remove the event registered */
- ret = mk_event_del(sched->loop, &conn->event);
-
- /* Check the connection status */
- if (conn->event.mask & MK_EVENT_WRITE) {
- ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len);
- if (ret == -1) {
- close(fd);
- mk_mem_free(conn);
- return NULL;
- }
-
- if (error != 0) {
- /* Connection is broken, not much to do here */
- fprintf(stderr, "Async connection failed %s:%i\n",
- conn->host, conn->port);
- close(fd);
- mk_mem_free(conn);
- return NULL;
- }
- MK_EVENT_NEW(&conn->event);
- return conn;
- }
- else {
- close(fd);
- mk_mem_free(conn);
- return NULL;
- }
- }
-
- return NULL;
-}
-
-int mk_net_conn_write(struct mk_channel *channel,
- void *data, size_t len)
-{
- int ret = 0;
- int error;
- ssize_t bytes;
- size_t total = 0;
- size_t send;
- socklen_t slen = sizeof(error);
- struct mk_thread *th = MK_TLS_GET(mk_thread);
- struct mk_sched_worker *sched;
-
- sched = mk_sched_get_thread_conf();
- if (!sched) {
- return -1;
- }
-
- retry:
- error = 0;
-
- if (len - total > 524288) {
- send = 524288;
- }
- else {
- send = (len - total);
- }
-
- send = len - total;
- bytes = channel->io->write(channel->io->plugin, channel->fd, (uint8_t *)data + total, send);
- if (bytes == -1) {
- if (errno == EAGAIN) {
- MK_EVENT_NEW(channel->event);
- channel->thread = th;
- ret = mk_event_add(sched->loop,
- channel->fd,
- MK_EVENT_THREAD,
- MK_EVENT_WRITE, channel->event);
- if (ret == -1) {
- /*
- * If we failed here there no much that we can do, just
- * let the caller we failed
- */
- return -1;
- }
-
- /*
- * Return the control to the parent caller, we need to wait for
- * the event loop to get back to us.
- */
- mk_thread_yield(th);
-
- /* We got a notification, remove the event registered */
- ret = mk_event_del(sched->loop, channel->event);
- if (ret == -1) {
- return -1;
- }
-
- /* Check the connection status */
- if (channel->event->mask & MK_EVENT_WRITE) {
- ret = getsockopt(channel->fd, SOL_SOCKET, SO_ERROR, &error, &slen);
- if (ret == -1) {
- fprintf(stderr, "[io] could not validate socket status");
- return -1;
- }
-
- if (error != 0) {
- return -1;
- }
-
- MK_EVENT_NEW(channel->event);
- goto retry;
- }
- else {
- return -1;
- }
-
- }
- else {
- return -1;
- }
- }
-
- /* Update counters */
- total += bytes;
- if (total < len) {
- channel->thread = th;
- ret = mk_event_add(sched->loop,
- channel->fd,
- MK_EVENT_THREAD,
- MK_EVENT_WRITE, channel->event);
- if (ret == -1) {
- /*
- * If we failed here there no much that we can do, just
- * let the caller we failed
- */
- return -1;
- }
-
- mk_thread_yield(th);
- goto retry;
- }
-
- if (channel->event->status & MK_EVENT_REGISTERED) {
- /* We got a notification, remove the event registered */
- ret = mk_event_del(sched->loop, channel->event);
- }
-
- return total;
-}
diff --git a/fluent-bit/lib/monkey/mk_server/mk_plugin.c b/fluent-bit/lib/monkey/mk_server/mk_plugin.c
deleted file mode 100644
index 50e2886b..00000000
--- a/fluent-bit/lib/monkey/mk_server/mk_plugin.c
+++ /dev/null
@@ -1,804 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-
-/* Monkey HTTP Server
- * ==================
- * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <monkey/monkey.h>
-#include <monkey/mk_utils.h>
-#include <monkey/mk_http.h>
-#include <monkey/mk_clock.h>
-#include <monkey/mk_plugin.h>
-#include <monkey/mk_mimetype.h>
-#include <monkey/mk_vhost.h>
-#include <monkey/mk_static_plugins.h>
-#include <monkey/mk_plugin_stage.h>
-#include <monkey/mk_core.h>
-#include <monkey/mk_net.h>
-
-#ifndef _WIN32
-#include <dlfcn.h>
-#include <err.h>
-#endif
-
-enum {
- bufsize = 256
-};
-
-static struct plugin_stagemap *plg_stagemap;
-struct plugin_network_io *plg_netiomap;
-
-struct mk_plugin *mk_plugin_lookup(char *shortname, struct mk_server *server)
-{
- struct mk_list *head;
- struct mk_plugin *p = NULL;
-
- mk_list_foreach(head, &server->plugins) {
- p = mk_list_entry(head, struct mk_plugin, _head);
- if (strcmp(p->shortname, shortname) == 0){
- return p;
- }
- }
-
- return NULL;
-}
-
-void *mk_plugin_load_dynamic(const char *path)
-{
- void *handle;
-
-#ifdef _WIN32
- handle = (void *) LoadLibraryA(path);
-#else
- handle = dlopen(path, RTLD_LAZY);
-
- if (!handle) {
- mk_warn("dlopen() %s", dlerror());
- }
-#endif
-
- return handle;
-}
-
-void *mk_plugin_load_symbol(void *handler, const char *symbol)
-{
- void *s;
-
-#ifdef _WIN32
- s = GetProcAddress((HMODULE)handler, symbol);
-#else
- dlerror();
- s = dlsym(handler, symbol);
- if (dlerror() != NULL) {
- return NULL;
- }
-#endif
-
- return s;
-}
-
-/* Initialize a plugin, trigger the init_plugin callback */
-static int mk_plugin_init(struct plugin_api *api,
- struct mk_plugin *plugin,
- struct mk_server *server)
-{
- int ret;
- unsigned long len;
- char path[1024];
- char *conf_dir = NULL;
- struct file_info f_info;
-
- MK_TRACE("Load Plugin: '%s'", plugin->shortname);
-
- snprintf(path, 1024, "%s/%s",
- server->path_conf_root, server->conf_plugins);
- ret = mk_file_get_info(path, &f_info, MK_FILE_READ);
- if (ret == -1 || f_info.is_directory == MK_FALSE) {
- snprintf(path, 1024, "%s", server->conf_plugins);
- }
-
- /* Build plugin configuration path */
- mk_string_build(&conf_dir,
- &len,
- "%s/%s/",
- path, plugin->shortname);
-
- /* Init plugin */
- plugin->api = api;
- plugin->server_ctx = server;
-
- if (plugin->network != NULL) {
- plugin->network->plugin = plugin;
- }
-
- ret = plugin->init_plugin(plugin, conf_dir);
- mk_mem_free(conf_dir);
-
- return ret;
-}
-
-
-/*
- * Load a plugin into Monkey core, 'type' defines if it's a MK_PLUGIN_STATIC or
- * a MK_PLUGIN_DYNAMIC. 'shortname' is mandatory and 'path' is only used when
- * MK_PLUGIN_DYNAMIC is set and represents the absolute path of the shared
- * library.
- */
-struct mk_plugin *mk_plugin_load(int type, const char *shortname,
- void *data, struct mk_server *server)
-{
- char *path;
- char symbol[64];
- void *handler;
- struct mk_list *head;
- struct mk_plugin *tmp;
- struct mk_plugin *plugin = NULL;
- struct mk_plugin_stage *stage;
-
- /* Set main struct name to reference */
- if (type == MK_PLUGIN_DYNAMIC) {
- path = (char *) data;
- handler = mk_plugin_load_dynamic(path);
- if (!handler) {
- return NULL;
- }
-
- snprintf(symbol, sizeof(symbol) - 1, "mk_plugin_%s", shortname);
- plugin = mk_plugin_load_symbol(handler, symbol);
- if (!plugin) {
- mk_warn("Plugin '%s' is not registering properly", path);
-#ifdef _WIN32
- FreeLibrary((HMODULE)handler);
-#else
- dlclose(handler);
-#endif
- return NULL;
- }
-
- /* Make sure this is not loaded twice (ref #218) */
- mk_list_foreach(head, &server->plugins) {
- tmp = mk_list_entry(head, struct mk_plugin, _head);
- if (tmp->load_type == MK_PLUGIN_STATIC &&
- strcmp(tmp->name, plugin->name) == 0){
- mk_warn("Plugin '%s' have been built-in.",
- tmp->shortname);
-#ifdef _WIN32
- FreeLibrary((HMODULE)handler);
-#else
- dlclose(handler);
-#endif
- return NULL;
- }
- }
-
- plugin->load_type = MK_PLUGIN_DYNAMIC;
- plugin->handler = handler;
- plugin->path = mk_string_dup(path);
- }
- else if (type == MK_PLUGIN_STATIC) {
- plugin = (struct mk_plugin *) data;
- plugin->load_type = MK_PLUGIN_STATIC;
- }
-
- if (!plugin) {
- return NULL;
- }
-
- /* Validate all callbacks are set */
- if (!plugin->shortname || !plugin->name || !plugin->version ||
- !plugin->init_plugin || !plugin->exit_plugin) {
- mk_warn("Plugin '%s' is not registering all fields properly",
- shortname);
- return NULL;
- }
-
- if (plugin->hooks & MK_PLUGIN_NETWORK_LAYER) {
- mk_bug(!plugin->network);
- }
-
- mk_list_init(&plugin->stage_list);
- if (plugin->hooks & MK_PLUGIN_STAGE) {
- struct mk_plugin_stage *st;
-
- stage = plugin->stage;
- if (stage->stage10) {
- st = mk_mem_alloc(sizeof(struct mk_plugin_stage));
- st->stage10 = stage->stage10;
- st->plugin = plugin;
- mk_list_add(&st->_head, &server->stage10_handler);
- mk_list_add(&st->_parent_head, &plugin->stage_list);
- }
- if (stage->stage20) {
- st = mk_mem_alloc(sizeof(struct mk_plugin_stage));
- st->stage20 = stage->stage20;
- st->plugin = plugin;
- mk_list_add(&st->_head, &server->stage20_handler);
- mk_list_add(&st->_parent_head, &plugin->stage_list);
- }
- if (stage->stage30) {
- st = mk_mem_alloc(sizeof(struct mk_plugin_stage));
- st->stage30 = stage->stage30;
- st->plugin = plugin;
- mk_list_add(&st->_head, &server->stage30_handler);
- mk_list_add(&st->_parent_head, &plugin->stage_list);
- }
- if (stage->stage40) {
- st = mk_mem_alloc(sizeof(struct mk_plugin_stage));
- st->stage40 = stage->stage40;
- st->plugin = plugin;
- mk_list_add(&st->_head, &server->stage40_handler);
- mk_list_add(&st->_parent_head, &plugin->stage_list);
- }
- if (stage->stage50) {
- st = mk_mem_alloc(sizeof(struct mk_plugin_stage));
- st->stage50 = stage->stage50;
- st->plugin = plugin;
- mk_list_add(&st->_head, &server->stage50_handler);
- mk_list_add(&st->_parent_head, &plugin->stage_list);
- }
- }
-
- if (type == MK_PLUGIN_DYNAMIC) {
- /* Add Plugin to the end of the list */
- mk_list_add(&plugin->_head, &server->plugins);
- }
-
- return plugin;
-}
-
-void mk_plugin_unregister(struct mk_plugin *p)
-{
- mk_mem_free(p->path);
- mk_list_del(&p->_head);
- if (p->load_type == MK_PLUGIN_DYNAMIC) {
-#ifdef _WIN32
- FreeLibrary((HMODULE)p->handler);
-#else
- dlclose(p->handler);
-#endif
- }
-
-}
-
-void mk_plugin_api_init(struct mk_server *server)
-{
- struct plugin_api *api;
-
- /* Create an instance of the API */
- api = mk_mem_alloc_z(sizeof(struct plugin_api));
-
-#ifndef _WIN32
- __builtin_prefetch(api);
-#endif
-
- /* Setup and connections list */
- /* FIXME: api->config = server; */
-
- /* API plugins funcions */
-
- /* Error helper */
- api->_error = mk_print;
-
- /* HTTP callbacks */
- api->http_request_end = mk_plugin_http_request_end;
- api->http_request_error = mk_plugin_http_error;
-
- /* Memory callbacks */
- api->pointer_set = mk_ptr_set;
- api->pointer_print = mk_ptr_print;
- api->pointer_to_buf = mk_ptr_to_buf;
- api->plugin_load_symbol = mk_plugin_load_symbol;
- api->mem_alloc = mk_mem_alloc;
- api->mem_alloc_z = mk_mem_alloc_z;
- api->mem_realloc = mk_mem_realloc;
- api->mem_free = mk_mem_free;
-
- /* String Callbacks */
- api->str_build = mk_string_build;
- api->str_dup = mk_string_dup;
- api->str_search = mk_string_search;
- api->str_search_n = mk_string_search_n;
- api->str_char_search = mk_string_char_search;
- api->str_copy_substr = mk_string_copy_substr;
- api->str_itop = mk_string_itop;
- api->str_split_line = mk_string_split_line;
- api->str_split_free = mk_string_split_free;
-
- /* File Callbacks */
- api->file_to_buffer = mk_file_to_buffer;
- api->file_get_info = mk_file_get_info;
-
- /* HTTP Callbacks */
- api->header_prepare = mk_plugin_header_prepare;
- api->header_add = mk_plugin_header_add;
- api->header_get = mk_http_header_get;
- api->header_set_http_status = mk_header_set_http_status;
-
- /* Channels / Streams */
- api->channel_new = mk_channel_new;
- api->channel_flush = mk_channel_flush;
- api->channel_write = mk_channel_write;
- api->channel_append_stream = mk_channel_append_stream;
-
- /* IOV callbacks */
- api->iov_create = mk_iov_create;
- api->iov_realloc = mk_iov_realloc;
- api->iov_free = mk_iov_free;
- api->iov_free_marked = mk_iov_free_marked;
- api->iov_add = mk_iov_add;
- api->iov_set_entry = mk_iov_set_entry;
- api->iov_send = mk_iov_send;
- api->iov_print = mk_iov_print;
-
- /* events mechanism */
- api->ev_loop_create = mk_event_loop_create;
- api->ev_add = mk_event_add;
- api->ev_del = mk_event_del;
- api->ev_timeout_create = mk_event_timeout_create;
- api->ev_channel_create = mk_event_channel_create;
- api->ev_wait = mk_event_wait;
- api->ev_backend = mk_event_backend;
-
- /* Mimetype */
- api->mimetype_lookup = mk_mimetype_lookup;
-
- /* Socket callbacks */
- api->socket_cork_flag = mk_socket_set_cork_flag;
- api->socket_connect = mk_socket_connect;
- api->socket_open = mk_socket_open;
- api->socket_reset = mk_socket_reset;
- api->socket_set_tcp_fastopen = mk_socket_set_tcp_fastopen;
- api->socket_set_tcp_reuseport = mk_socket_set_tcp_reuseport;
- api->socket_set_tcp_nodelay = mk_socket_set_tcp_nodelay;
- api->socket_set_nonblocking = mk_socket_set_nonblocking;
- api->socket_create = mk_socket_create;
- api->socket_ip_str = mk_socket_ip_str;
-
- /* Async network */
- api->net_conn_create = mk_net_conn_create;
-
- /* Config Callbacks */
- api->config_create = mk_rconf_create;
- api->config_open = mk_rconf_open;
- api->config_free = mk_rconf_free;
- api->config_section_get = mk_rconf_section_get;
- api->config_section_get_key = mk_rconf_section_get_key;
-
- /* Scheduler and Event callbacks */
- api->sched_loop = mk_sched_loop;
- api->sched_get_connection = mk_sched_get_connection;
- api->sched_event_free = mk_sched_event_free;
- api->sched_remove_client = mk_plugin_sched_remove_client;
- api->sched_worker_info = mk_plugin_sched_get_thread_conf;
-
- /* Worker functions */
- api->worker_spawn = mk_utils_worker_spawn;
- api->worker_rename = mk_utils_worker_rename;
-
- /* Time functions */
- api->time_unix = mk_plugin_time_now_unix;
- api->time_to_gmt = mk_utils_utime2gmt;
- api->time_human = mk_plugin_time_now_human;
-
- api->stacktrace = (void *) mk_utils_stacktrace;
- api->kernel_version = mk_kernel_version;
- api->kernel_features_print = mk_kernel_features_print;
- api->plugins = &server->plugins;
-
- /* handler */
- api->handler_param_get = mk_handler_param_get;
-
- server->api = api;
-}
-
-void mk_plugin_load_static(struct mk_server *server)
-{
- /* Load static plugins */
- mk_list_init(&server->plugins);
- mk_static_plugins(&server->plugins);
-}
-
-void mk_plugin_load_all(struct mk_server *server)
-{
- int ret;
- char *tmp;
- char *path;
- char shortname[64];
- struct mk_plugin *p;
- struct mk_rconf *cnf;
- struct mk_rconf_section *section;
- struct mk_rconf_entry *entry;
- struct mk_list *head;
- struct mk_list *htmp;
- struct file_info f_info;
-
- mk_plugin_load_static(server);
- mk_list_foreach_safe(head, htmp, &server->plugins) {
- p = mk_list_entry(head, struct mk_plugin, _head);
-
- /* Load the static plugin */
- p = mk_plugin_load(MK_PLUGIN_STATIC,
- p->shortname,
- (void *) p,
- server);
- if (!p) {
- continue;
- }
- ret = mk_plugin_init(server->api, p, server);
- if (ret == -1) {
- /* Free plugin, do not register, error initializing */
- mk_warn("Plugin initialization failed: %s", p->shortname);
- mk_plugin_unregister(p);
- continue;
- }
- else if (ret == -2) {
- /* Do not register, just skip it */
- mk_plugin_unregister(p);
- continue;
- }
- }
-
- /* In case there are not dynamic plugins */
- if (!server->conf_plugin_load) {
- return;
- }
-
- /* Read configuration file */
- path = mk_mem_alloc_z(1024);
- snprintf(path, 1024, "%s/%s", server->path_conf_root,
- server->conf_plugin_load);
- ret = mk_file_get_info(path, &f_info, MK_FILE_READ);
- if (ret == -1 || f_info.is_file == MK_FALSE) {
- snprintf(path, 1024, "%s", server->conf_plugin_load);
- }
-
- cnf = mk_rconf_open(path);
- if (!cnf) {
- mk_warn("No dynamic plugins loaded.");
- mk_mem_free(path);
- return;
- }
-
- /* Read section 'PLUGINS' */
- section = mk_rconf_section_get(cnf, "PLUGINS");
- if (!section) {
- exit(EXIT_FAILURE);
- }
-
- /* Read key entries */
- mk_list_foreach_safe(head, htmp, &section->entries) {
- entry = mk_list_entry(head, struct mk_rconf_entry, _head);
- if (strcasecmp(entry->key, "Load") == 0) {
-
- /* Get plugin 'shortname' */
- tmp = memrchr(entry->val, '-', strlen(entry->val));
- ++tmp;
- memset(shortname, '\0', sizeof(shortname) - 1);
- strncpy(shortname, tmp, strlen(tmp) - 3);
-
- /* Load the dynamic plugin */
- p = mk_plugin_load(MK_PLUGIN_DYNAMIC,
- shortname,
- entry->val,
- server);
- if (!p) {
- mk_warn("Invalid plugin '%s'", entry->val);
- continue;
- }
-
- ret = mk_plugin_init(server->api, p, server);
- if (ret < 0) {
- /* Free plugin, do not register */
- MK_TRACE("Unregister plugin '%s'", p->shortname);
- mk_plugin_unregister(p);
- continue;
- }
- }
- }
-
- /* Look for plugins thread key data */
- mk_plugin_preworker_calls(server);
- mk_vhost_map_handlers(server);
- mk_mem_free(path);
- mk_rconf_free(cnf);
-}
-
-static void mk_plugin_exit_stages(struct mk_plugin *p)
-{
- struct mk_list *tmp;
- struct mk_list *head;
- struct mk_plugin_stage *st;
-
- mk_list_foreach_safe(head, tmp, &p->stage_list) {
- st = mk_list_entry(head, struct mk_plugin_stage, _parent_head);
-
- /* remove from direct config->stageN head list */
- mk_list_del(&st->_head);
-
- /* remove from plugin->stage_lists */
- mk_list_del(&st->_parent_head);
- mk_mem_free(st);
- }
-}
-
-/* Invoke all plugins 'exit' hook and free resources by the plugin interface */
-void mk_plugin_exit_all(struct mk_server *server)
-{
- struct mk_plugin *plugin;
- struct mk_list *head, *tmp;
-
- /* Plugins */
- mk_list_foreach(head, &server->plugins) {
- plugin = mk_list_entry(head, struct mk_plugin, _head);
- plugin->exit_plugin(plugin);
- }
-
- /* Plugin interface it self */
- mk_list_foreach_safe(head, tmp, &server->plugins) {
- plugin = mk_list_entry(head, struct mk_plugin, _head);
- mk_list_del(&plugin->_head);
- mk_plugin_exit_stages(plugin);
-
- if (plugin->load_type == MK_PLUGIN_DYNAMIC) {
- mk_mem_free(plugin->path);
-#ifdef _WIN32
- FreeLibrary((HMODULE)plugin->handler);
-#else
- dlclose(plugin ->handler);
-#endif
- }
- else if (plugin->load_type == MK_PLUGIN_STATIC) {
- if (plugin->network != NULL) {
- mk_mem_free(plugin->network);
- }
-
- mk_mem_free(plugin);
- }
- }
-
- mk_mem_free(server->api);
- mk_mem_free(plg_stagemap);
-}
-
-/*
- * When a worker is exiting, it invokes this function to release any plugin
- * associated data.
- */
-void mk_plugin_exit_worker()
-{
-}
-
-/* This function is called by every created worker
- * for plugins which need to set some data under a thread
- * context
- */
-void mk_plugin_core_process(struct mk_server *server)
-{
- struct mk_plugin *node;
- struct mk_list *head;
-
- mk_list_foreach(head, &server->plugins) {
- node = mk_list_entry(head, struct mk_plugin, _head);
-
- /* Init plugin */
- if (node->master_init) {
- node->master_init(server);
- }
- }
-}
-
-/* This function is called by every created worker
- * for plugins which need to set some data under a thread
- * context
- */
-void mk_plugin_core_thread(struct mk_server *server)
-{
-
- struct mk_plugin *node;
- struct mk_list *head;
-
- mk_list_foreach(head, &server->plugins) {
- node = mk_list_entry(head, struct mk_plugin, _head);
-
- /* Init plugin thread context */
- if (node->worker_init) {
- node->worker_init(server);
- }
- }
-}
-
-/* This function is called by Monkey *outside* of the
- * thread context for plugins, so here's the right
- * place to set pthread keys or similar
- */
-void mk_plugin_preworker_calls(struct mk_server *server)
-{
- int ret;
- struct mk_plugin *node;
- struct mk_list *head;
-
- mk_list_foreach(head, &server->plugins) {
- node = mk_list_entry(head, struct mk_plugin, _head);
-
- /* Init pthread keys */
- if (node->thread_key) {
- MK_TRACE("[%s] Set thread key", node->shortname);
-
- ret = pthread_key_create(node->thread_key, NULL);
- if (ret != 0) {
- mk_err("Plugin Error: could not create key for %s",
- node->shortname);
- }
- }
- }
-}
-
-int mk_plugin_http_error(int http_status, struct mk_http_session *cs,
- struct mk_http_request *sr,
- struct mk_plugin *plugin)
-{
- return mk_http_error(http_status, cs, sr, plugin->server_ctx);
-}
-
-
-int mk_plugin_http_request_end(struct mk_plugin *plugin,
- struct mk_http_session *cs, int close)
-{
- int ret;
- int con;
- struct mk_http_request *sr;
- struct mk_server *server = plugin->server_ctx;
-
- MK_TRACE("[FD %i] PLUGIN HTTP REQUEST END", cs->socket);
-
- cs->status = MK_REQUEST_STATUS_INCOMPLETE;
- if (mk_list_is_empty(&cs->request_list) == 0) {
- MK_TRACE("[FD %i] Tried to end non-existing request.", cs->socket);
- return -1;
- }
-
- sr = mk_list_entry_last(&cs->request_list, struct mk_http_request, _head);
- mk_plugin_stage_run_40(cs, sr, server);
-
- if (close == MK_TRUE) {
- cs->close_now = MK_TRUE;
- }
-
- /* Let's check if we should ask to finalize the connection or not */
- ret = mk_http_request_end(cs, server);
- MK_TRACE("[FD %i] HTTP session end = %i", cs->socket, ret);
- if (ret < 0) {
- con = mk_sched_event_close(cs->conn, mk_sched_get_thread_conf(),
- MK_EP_SOCKET_DONE, server);
- if (con != 0) {
- return con;
- }
- else {
- return -1;
- }
- }
-
- return ret;
-}
-
-/* Plugin epoll event handlers
- * ---------------------------
- * this functions are called by connection.c functions as mk_conn_read(),
- * mk_conn_write(),mk_conn_error(), mk_conn_close() and mk_conn_timeout().
- *
- * Return Values:
- * -------------
- * MK_PLUGIN_RET_EVENT_NOT_ME: There's no plugin hook associated
- */
-
-void mk_plugin_event_bad_return(const char *hook, int ret)
-{
- mk_err("[%s] Not allowed return value %i", hook, ret);
-}
-
-int mk_plugin_time_now_unix(struct mk_server *server)
-{
- return server->clock_context->log_current_utime;
-}
-
-mk_ptr_t *mk_plugin_time_now_human(struct mk_server *server)
-{
- return &server->clock_context->log_current_time;
-}
-
-int mk_plugin_sched_remove_client(int socket, struct mk_server *server)
-{
- struct mk_sched_conn *conn;
- struct mk_sched_worker *sched;
-
- MK_TRACE("[FD %i] remove client", socket);
-
- sched = mk_sched_get_thread_conf();
- conn = mk_sched_get_connection(sched, socket);
- if (!conn) {
- return -1;
- }
-
- return mk_sched_remove_client(conn, sched, server);
-}
-
-int mk_plugin_header_prepare(struct mk_plugin *plugin,
- struct mk_http_session *cs,
- struct mk_http_request *sr)
-{
- return mk_header_prepare(cs, sr, plugin->server_ctx);
-}
-
-
-int mk_plugin_header_add(struct mk_http_request *sr, char *row, int len)
-{
- mk_bug(!sr);
-
- if (!sr->headers._extra_rows) {
- /*
- * We allocate space for a fixed number of IOV entries:
- *
- * MK_PLUGIN_HEADER_EXTRA_ROWS = X
- *
- * we use (MK_PLUGIN_HEADER_EXTRA_ROWS * 2) thinking in an ending CRLF
- */
- sr->headers._extra_rows = mk_iov_create(MK_PLUGIN_HEADER_EXTRA_ROWS * 2, 0);
- mk_bug(!sr->headers._extra_rows);
- }
-
- mk_iov_add(sr->headers._extra_rows, row, len,
- MK_FALSE);
- mk_iov_add(sr->headers._extra_rows,
- mk_iov_crlf.data, mk_iov_crlf.len,
- MK_FALSE);
- return 0;
-}
-
-struct mk_sched_worker *mk_plugin_sched_get_thread_conf()
-{
- return MK_TLS_GET(mk_tls_sched_worker_node);
-}
-
-struct mk_plugin *mk_plugin_cap(char cap, struct mk_server *server)
-{
- struct mk_list *head;
- struct mk_plugin *plugin;
-
- mk_list_foreach(head, &server->plugins) {
- plugin = mk_list_entry(head, struct mk_plugin, _head);
- if (plugin->capabilities & cap) {
- return plugin;
- }
- }
-
- return NULL;
-}
-
-struct mk_vhost_handler_param *mk_handler_param_get(int id,
- struct mk_list *params)
-{
- int i = 0;
- struct mk_list *head;
-
- mk_list_foreach(head, params) {
- if (i == id) {
- return mk_list_entry(head, struct mk_vhost_handler_param, _head);
- }
- i++;
- }
-
- return NULL;
-}
diff --git a/fluent-bit/lib/monkey/mk_server/mk_scheduler.c b/fluent-bit/lib/monkey/mk_server/mk_scheduler.c
deleted file mode 100644
index a680d3cd..00000000
--- a/fluent-bit/lib/monkey/mk_server/mk_scheduler.c
+++ /dev/null
@@ -1,866 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-
-/* Monkey HTTP Server
- * ==================
- * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <monkey/monkey.h>
-#include <monkey/mk_info.h>
-#include <monkey/mk_core.h>
-#include <monkey/mk_vhost.h>
-#include <monkey/mk_scheduler.h>
-#include <monkey/mk_scheduler_tls.h>
-#include <monkey/mk_server.h>
-#include <monkey/mk_thread.h>
-#include <monkey/mk_cache.h>
-#include <monkey/mk_config.h>
-#include <monkey/mk_clock.h>
-#include <monkey/mk_plugin.h>
-#include <monkey/mk_utils.h>
-#include <monkey/mk_linuxtrace.h>
-#include <monkey/mk_server.h>
-#include <monkey/mk_plugin_stage.h>
-#include <monkey/mk_http_thread.h>
-
-#include <signal.h>
-
-#ifndef _WIN32
-#include <sys/syscall.h>
-#endif
-
-extern struct mk_sched_handler mk_http_handler;
-extern struct mk_sched_handler mk_http2_handler;
-
-pthread_mutex_t mutex_worker_init = PTHREAD_MUTEX_INITIALIZER;
-pthread_mutex_t mutex_worker_exit = PTHREAD_MUTEX_INITIALIZER;
-
-/*
- * Returns the worker id which should take a new incomming connection,
- * it returns the worker id with less active connections. Just used
- * if config->scheduler_mode is MK_SCHEDULER_FAIR_BALANCING.
- */
-static inline int _next_target(struct mk_server *server)
-{
- int i;
- int target = 0;
- unsigned long long tmp = 0, cur = 0;
- struct mk_sched_ctx *ctx = server->sched_ctx;
- struct mk_sched_worker *worker;
-
- cur = (ctx->workers[0].accepted_connections -
- ctx->workers[0].closed_connections);
- if (cur == 0) {
- return 0;
- }
-
- /* Finds the lowest load worker */
- for (i = 1; i < server->workers; i++) {
- worker = &ctx->workers[i];
- tmp = worker->accepted_connections - worker->closed_connections;
- if (tmp < cur) {
- target = i;
- cur = tmp;
-
- if (cur == 0)
- break;
- }
- }
-
- /*
- * If sched_ctx->workers[target] worker is full then the whole server too,
- * because it has the lowest load.
- */
- if (mk_unlikely(server->server_capacity > 0 &&
- server->server_capacity <= cur)) {
- MK_TRACE("Too many clients: %i", server->server_capacity);
-
- /* Instruct to close the connection anyways, we lie, it will die */
- return -1;
- }
-
- return target;
-}
-
-struct mk_sched_worker *mk_sched_next_target(struct mk_server *server)
-{
- int t;
- struct mk_sched_ctx *ctx = server->sched_ctx;
-
- t = _next_target(server);
- if (mk_likely(t != -1)) {
- return &ctx->workers[t];
- }
-
- return NULL;
-}
-
-/*
- * This function is invoked when the core triggers a MK_SCHED_SIGNAL_FREE_ALL
- * event through the signal channels, it means the server will stop working
- * so this is the last call to release all memory resources in use. Of course
- * this takes place in a thread context.
- */
-void mk_sched_worker_free(struct mk_server *server)
-{
- int i;
- pthread_t tid;
- struct mk_sched_ctx *ctx = server->sched_ctx;
- struct mk_sched_worker *worker = NULL;
-
- pthread_mutex_lock(&mutex_worker_exit);
-
- /*
- * Fix Me: needs to implement API to make plugins release
- * their resources first at WORKER LEVEL
- */
-
- /* External */
- mk_plugin_exit_worker();
- mk_vhost_fdt_worker_exit(server);
- mk_cache_worker_exit();
-
- /* Scheduler stuff */
- tid = pthread_self();
- for (i = 0; i < server->workers; i++) {
- worker = &ctx->workers[i];
- if (worker->tid == tid) {
- break;
- }
- worker = NULL;
- }
-
- mk_bug(!worker);
-
- /* FIXME!: there is nothing done here with the worker context */
-
- /* Free master array (av queue & busy queue) */
- mk_mem_free(MK_TLS_GET(mk_tls_sched_cs));
- mk_mem_free(MK_TLS_GET(mk_tls_sched_cs_incomplete));
- mk_mem_free(MK_TLS_GET(mk_tls_sched_worker_notif));
- pthread_mutex_unlock(&mutex_worker_exit);
-}
-
-struct mk_sched_handler *mk_sched_handler_cap(char cap)
-{
- if (cap == MK_CAP_HTTP) {
- return &mk_http_handler;
- }
-
-#ifdef MK_HAVE_HTTP2
- else if (cap == MK_CAP_HTTP2) {
- return &mk_http2_handler;
- }
-#endif
-
- return NULL;
-}
-
-/*
- * Register a new client connection into the scheduler, this call takes place
- * inside the worker/thread context.
- */
-struct mk_sched_conn *mk_sched_add_connection(int remote_fd,
- struct mk_server_listen *listener,
- struct mk_sched_worker *sched,
- struct mk_server *server)
-{
- int ret;
- int size;
- struct mk_sched_handler *handler;
- struct mk_sched_conn *conn;
- struct mk_event *event;
-
- /* Before to continue, we need to run plugin stage 10 */
- ret = mk_plugin_stage_run_10(remote_fd, server);
-
- /* Close connection, otherwise continue */
- if (ret == MK_PLUGIN_RET_CLOSE_CONX) {
- listener->network->network->close(listener->network, remote_fd);
- MK_LT_SCHED(remote_fd, "PLUGIN_CLOSE");
- return NULL;
- }
-
- handler = listener->protocol;
- if (handler->sched_extra_size > 0) {
- void *data;
- size = (sizeof(struct mk_sched_conn) + handler->sched_extra_size);
- data = mk_mem_alloc_z(size);
- conn = (struct mk_sched_conn *) data;
- }
- else {
- conn = mk_mem_alloc_z(sizeof(struct mk_sched_conn));
- }
-
- if (!conn) {
- mk_err("[server] Could not register client");
- return NULL;
- }
-
- event = &conn->event;
- event->fd = remote_fd;
- event->type = MK_EVENT_CONNECTION;
- event->mask = MK_EVENT_EMPTY;
- event->status = MK_EVENT_NONE;
- conn->arrive_time = server->clock_context->log_current_utime;
- conn->protocol = handler;
- conn->net = listener->network->network;
- conn->is_timeout_on = MK_FALSE;
- conn->server_listen = listener;
-
- /* Stream channel */
- conn->channel.type = MK_CHANNEL_SOCKET; /* channel type */
- conn->channel.fd = remote_fd; /* socket conn */
- conn->channel.io = conn->net; /* network layer */
- conn->channel.event = event; /* parent event ref */
- mk_list_init(&conn->channel.streams);
-
- /*
- * Register the connections into the timeout_queue:
- *
- * When a new connection arrives, we cannot assume it contains some data
- * to read, meaning the event loop may not get notifications and the protocol
- * handler will never be called. So in order to avoid DDoS we always register
- * this session in the timeout_queue for further lookup.
- *
- * The protocol handler is in charge to remove the session from the
- * timeout_queue.
- */
- mk_sched_conn_timeout_add(conn, sched);
-
- /* Linux trace message */
- MK_LT_SCHED(remote_fd, "REGISTERED");
-
- return conn;
-}
-
-static void mk_sched_thread_lists_init()
-{
- struct mk_list *sched_cs_incomplete;
-
- /* mk_tls_sched_cs_incomplete */
- sched_cs_incomplete = mk_mem_alloc(sizeof(struct mk_list));
- mk_list_init(sched_cs_incomplete);
- MK_TLS_SET(mk_tls_sched_cs_incomplete, sched_cs_incomplete);
-}
-
-/* Register thread information. The caller thread is the thread information's owner */
-static int mk_sched_register_thread(struct mk_server *server)
-{
- struct mk_sched_ctx *ctx = server->sched_ctx;
- struct mk_sched_worker *worker;
-
- /*
- * If this thread slept inside this section, some other thread may touch
- * server->worker_id.
- * So protect it with a mutex, only one thread may handle server->worker_id.
- *
- * Note : Let's use the platform agnostic atomics we implemented in cmetrics here
- * instead of a lock.
- */
- worker = &ctx->workers[server->worker_id];
- worker->idx = server->worker_id++;
- worker->tid = pthread_self();
-
-#if defined(__linux__)
- /*
- * Under Linux does not exists the difference between process and
- * threads, everything is a thread in the kernel task struct, and each
- * one has it's own numerical identificator: PID .
- *
- * Here we want to know what's the PID associated to this running
- * task (which is different from parent Monkey PID), it can be
- * retrieved with gettid() but Glibc does not export to userspace
- * the syscall, we need to call it directly through syscall(2).
- */
- worker->pid = syscall(__NR_gettid);
-#elif defined(__APPLE__)
- uint64_t tid;
- pthread_threadid_np(NULL, &tid);
- worker->pid = tid;
-#else
- worker->pid = 0xdeadbeef;
-#endif
-
- /* Initialize lists */
- mk_list_init(&worker->timeout_queue);
- worker->request_handler = NULL;
-
- return worker->idx;
-}
-
-static void mk_signal_thread_sigpipe_safe()
-{
-#ifndef _WIN32
- sigset_t old;
- sigset_t set;
-
- sigemptyset(&set);
- sigaddset(&set, SIGPIPE);
- pthread_sigmask(SIG_BLOCK, &set, &old);
-#endif
-}
-
-/* created thread, all these calls are in the thread context */
-void *mk_sched_launch_worker_loop(void *data)
-{
- int ret;
- int wid;
- unsigned long len;
- char *thread_name = 0;
- struct mk_list *head;
- struct mk_sched_worker_cb *wcb;
- struct mk_sched_worker *sched = NULL;
- struct mk_sched_notif *notif = NULL;
- struct mk_sched_thread_conf *thinfo = data;
- struct mk_sched_ctx *ctx;
- struct mk_server *server;
-
- server = thinfo->server;
- ctx = server->sched_ctx;
-
- /* Avoid SIGPIPE signals on this thread */
- mk_signal_thread_sigpipe_safe();
-
- /* Init specific thread cache */
- mk_sched_thread_lists_init();
- mk_cache_worker_init();
-
- /* Virtual hosts: initialize per thread-vhost data */
- mk_vhost_fdt_worker_init(server);
-
- /* Register working thread */
- wid = mk_sched_register_thread(server);
- sched = &ctx->workers[wid];
- sched->loop = mk_event_loop_create(MK_EVENT_QUEUE_SIZE);
- if (!sched->loop) {
- mk_err("Error creating Scheduler loop");
- exit(EXIT_FAILURE);
- }
-
-
- sched->mem_pagesize = mk_utils_get_system_page_size();
-
- /*
- * Create the notification instance and link it to the worker
- * thread-scope list.
- */
- notif = mk_mem_alloc_z(sizeof(struct mk_sched_notif));
- MK_TLS_SET(mk_tls_sched_worker_notif, notif);
-
- /* Register the scheduler channel to signal active workers */
- ret = mk_event_channel_create(sched->loop,
- &sched->signal_channel_r,
- &sched->signal_channel_w,
- notif);
- if (ret < 0) {
- exit(EXIT_FAILURE);
- }
-
- mk_list_init(&sched->event_free_queue);
- mk_list_init(&sched->threads);
- mk_list_init(&sched->threads_purge);
-
- /*
- * ULONG_MAX BUG test only
- * =======================
- * to test the workaround we can use the following value:
- *
- * thinfo->closed_connections = 1000;
- */
-
- //thinfo->ctx = thconf->ctx;
-
- /* Rename worker */
- mk_string_build(&thread_name, &len, "monkey: wrk/%i", sched->idx);
- mk_utils_worker_rename(thread_name);
- mk_mem_free(thread_name);
-
- /* Export known scheduler node to context thread */
- MK_TLS_SET(mk_tls_sched_worker_node, sched);
- mk_plugin_core_thread(server);
-
- if (server->scheduler_mode == MK_SCHEDULER_REUSEPORT) {
- sched->listeners = mk_server_listen_init(server);
- if (!sched->listeners) {
- exit(EXIT_FAILURE);
- }
- }
-
- /* Unlock the conditional initializator */
- pthread_mutex_lock(&server->pth_mutex);
- server->pth_init = MK_TRUE;
- pthread_cond_signal(&server->pth_cond);
- pthread_mutex_unlock(&server->pth_mutex);
-
- /* Invoke custom worker-callbacks defined by the scheduler (lib) */
- mk_list_foreach(head, &server->sched_worker_callbacks) {
- wcb = mk_list_entry(head, struct mk_sched_worker_cb, _head);
- wcb->cb_func(wcb->data);
- }
-
- mk_mem_free(thinfo);
-
- /* init server thread loop */
- mk_server_worker_loop(server);
-
- return 0;
-}
-
-/* Create thread which will be listening for incomings requests */
-int mk_sched_launch_thread(struct mk_server *server, pthread_t *tout)
-{
- pthread_t tid;
- pthread_attr_t attr;
- struct mk_sched_thread_conf *thconf;
-
- server->pth_init = MK_FALSE;
-
- /*
- * This lock is used for the 'pth_cond' conditional. Once the worker
- * thread is ready it will signal the condition.
- */
- pthread_mutex_lock(&server->pth_mutex);
-
- /* Thread data */
- thconf = mk_mem_alloc_z(sizeof(struct mk_sched_thread_conf));
- thconf->server = server;
-
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
- if (pthread_create(&tid, &attr, mk_sched_launch_worker_loop,
- (void *) thconf) != 0) {
- mk_libc_error("pthread_create");
- pthread_mutex_unlock(&server->pth_mutex);
- return -1;
- }
-
- *tout = tid;
-
- /* Block until the child thread is ready */
- while (!server->pth_init) {
- pthread_cond_wait(&server->pth_cond, &server->pth_mutex);
- }
-
- pthread_mutex_unlock(&server->pth_mutex);
-
- return 0;
-}
-
-/*
- * The scheduler nodes are an array of struct mk_sched_worker type,
- * each worker thread belongs to a scheduler node, on this function we
- * allocate a scheduler node per number of workers defined.
- */
-int mk_sched_init(struct mk_server *server)
-{
- int size;
- struct mk_sched_ctx *ctx;
-
- ctx = mk_mem_alloc_z(sizeof(struct mk_sched_ctx));
- if (!ctx) {
- mk_libc_error("malloc");
- return -1;
- }
-
- size = (sizeof(struct mk_sched_worker) * server->workers);
- ctx->workers = mk_mem_alloc(size);
- if (!ctx->workers) {
- mk_libc_error("malloc");
- mk_mem_free(ctx);
- return -1;
- }
- memset(ctx->workers, '\0', size);
-
- /* Initialize helpers */
- pthread_mutex_init(&server->pth_mutex, NULL);
- pthread_cond_init(&server->pth_cond, NULL);
- server->pth_init = MK_FALSE;
-
- /* Map context into server context */
- server->sched_ctx = ctx;
-
- /* The mk_thread_prepare call was replaced by mk_http_thread_initialize_tls
- * which is called earlier.
- */
-
- return 0;
-}
-
-int mk_sched_exit(struct mk_server *server)
-{
- struct mk_sched_ctx *ctx;
-
- ctx = server->sched_ctx;
- mk_sched_worker_cb_free(server);
- mk_mem_free(ctx->workers);
- mk_mem_free(ctx);
-
- return 0;
-}
-
-void mk_sched_set_request_list(struct rb_root *list)
-{
- MK_TLS_SET(mk_tls_sched_cs, list);
-}
-
-int mk_sched_remove_client(struct mk_sched_conn *conn,
- struct mk_sched_worker *sched,
- struct mk_server *server)
-{
- struct mk_event *event;
-
- /*
- * Close socket and change status: we must invoke mk_epoll_del()
- * because when the socket is closed is cleaned from the queue by
- * the Kernel at its leisure, and we may get false events if we rely
- * on that.
- */
- event = &conn->event;
- MK_TRACE("[FD %i] Scheduler remove", event->fd);
-
- mk_event_del(sched->loop, event);
-
- /* Invoke plugins in stage 50 */
- mk_plugin_stage_run_50(event->fd, server);
-
- sched->closed_connections++;
-
- /* Unlink from the red-black tree */
- //rb_erase(&conn->_rb_head, &sched->rb_queue);
- mk_sched_conn_timeout_del(conn);
-
- /* Close at network layer level */
- conn->net->close(conn->net->plugin, event->fd);
-
- /* Release and return */
- mk_channel_clean(&conn->channel);
- mk_sched_event_free(&conn->event);
- conn->status = MK_SCHED_CONN_CLOSED;
-
- MK_LT_SCHED(remote_fd, "DELETE_CLIENT");
- return 0;
-}
-
-/* FIXME: nobody is using this function, check back later */
-struct mk_sched_conn *mk_sched_get_connection(struct mk_sched_worker *sched,
- int remote_fd)
-{
- (void) sched;
- (void) remote_fd;
- return NULL;
-}
-
-/*
- * For a given connection number, remove all resources associated: it can be
- * used on any context such as: timeout, I/O errors, request finished,
- * exceptions, etc.
- */
-int mk_sched_drop_connection(struct mk_sched_conn *conn,
- struct mk_sched_worker *sched,
- struct mk_server *server)
-{
- mk_sched_threads_destroy_conn(sched, conn);
- return mk_sched_remove_client(conn, sched, server);
-}
-
-int mk_sched_check_timeouts(struct mk_sched_worker *sched,
- struct mk_server *server)
-{
- int client_timeout;
- struct mk_sched_conn *conn;
- struct mk_list *head;
- struct mk_list *temp;
-
- /* PENDING CONN TIMEOUT */
- mk_list_foreach_safe(head, temp, &sched->timeout_queue) {
- conn = mk_list_entry(head, struct mk_sched_conn, timeout_head);
- if (conn->event.type & MK_EVENT_IDLE) {
- continue;
- }
-
- client_timeout = conn->arrive_time + server->timeout;
-
- /* Check timeout */
- if (client_timeout <= server->clock_context->log_current_utime) {
- MK_TRACE("Scheduler, closing fd %i due TIMEOUT",
- conn->event.fd);
- MK_LT_SCHED(conn->event.fd, "TIMEOUT_CONN_PENDING");
- conn->protocol->cb_close(conn, sched, MK_SCHED_CONN_TIMEOUT,
- server);
- mk_sched_drop_connection(conn, sched, server);
- }
- }
-
- return 0;
-}
-
-static int sched_thread_cleanup(struct mk_sched_worker *sched,
- struct mk_list *list)
-{
- int c = 0;
- struct mk_list *tmp;
- struct mk_list *head;
- struct mk_http_thread *mth;
- (void) sched;
-
- mk_list_foreach_safe(head, tmp, list) {
- mth = mk_list_entry(head, struct mk_http_thread, _head);
- mk_http_thread_destroy(mth);
- c++;
- }
-
- return c;
-
-}
-
-int mk_sched_threads_purge(struct mk_sched_worker *sched)
-{
- int c = 0;
-
- c = sched_thread_cleanup(sched, &sched->threads_purge);
- return c;
-}
-
-int mk_sched_threads_destroy_all(struct mk_sched_worker *sched)
-{
- int c = 0;
-
- c = sched_thread_cleanup(sched, &sched->threads_purge);
- c += sched_thread_cleanup(sched, &sched->threads);
-
- return c;
-}
-
-/*
- * Destroy the thread contexts associated to the particular
- * connection.
- *
- * Return the number of contexts destroyed.
- */
-int mk_sched_threads_destroy_conn(struct mk_sched_worker *sched,
- struct mk_sched_conn *conn)
-{
- int c = 0;
- struct mk_list *tmp;
- struct mk_list *head;
- struct mk_http_thread *mth;
- (void) sched;
-
- mk_list_foreach_safe(head, tmp, &sched->threads) {
- mth = mk_list_entry(head, struct mk_http_thread, _head);
- if (mth->session->conn == conn) {
- mk_http_thread_destroy(mth);
- c++;
- }
- }
- return c;
-}
-
-/*
- * Scheduler events handler: lookup for event handler and invoke
- * proper callbacks.
- */
-int mk_sched_event_read(struct mk_sched_conn *conn,
- struct mk_sched_worker *sched,
- struct mk_server *server)
-{
- int ret = 0;
-
-#ifdef MK_HAVE_TRACE
- MK_TRACE("[FD %i] Connection Handler / read", conn->event.fd);
-#endif
-
- /*
- * When the event loop notify that there is some readable information
- * from the socket, we need to invoke the protocol handler associated
- * to this connection and also pass as a reference the 'read()' function
- * that handle 'read I/O' operations, e.g:
- *
- * - plain sockets through liana will use just read(2)
- * - ssl though mbedtls should use mk_mbedtls_read(..)
- */
- ret = conn->protocol->cb_read(conn, sched, server);
- if (ret == -1) {
- if (errno == EAGAIN) {
- MK_TRACE("[FD %i] EAGAIN: need to read more data", conn->event.fd);
- return 1;
- }
- return -1;
- }
-
- return ret;
-}
-
-int mk_sched_event_write(struct mk_sched_conn *conn,
- struct mk_sched_worker *sched,
- struct mk_server *server)
-{
- int ret = -1;
- size_t count;
- struct mk_event *event;
-
- MK_TRACE("[FD %i] Connection Handler / write", conn->event.fd);
-
- ret = mk_channel_write(&conn->channel, &count);
- if (ret == MK_CHANNEL_FLUSH || ret == MK_CHANNEL_BUSY) {
- return 0;
- }
- else if (ret == MK_CHANNEL_DONE || ret == MK_CHANNEL_EMPTY) {
- if (conn->protocol->cb_done) {
- ret = conn->protocol->cb_done(conn, sched, server);
- }
- if (ret == -1) {
- return -1;
- }
- else if (ret == 0) {
- event = &conn->event;
- mk_event_add(sched->loop, event->fd,
- MK_EVENT_CONNECTION,
- MK_EVENT_READ,
- conn);
- }
- return 0;
- }
- else if (ret & MK_CHANNEL_ERROR) {
- return -1;
- }
-
- /* avoid to make gcc cry :_( */
- return -1;
-}
-
-int mk_sched_event_close(struct mk_sched_conn *conn,
- struct mk_sched_worker *sched,
- int type, struct mk_server *server)
-{
- MK_TRACE("[FD %i] Connection Handler, closed", conn->event.fd);
- mk_event_del(sched->loop, &conn->event);
-
- if (type != MK_EP_SOCKET_DONE) {
- conn->protocol->cb_close(conn, sched, type, server);
- }
- /*
- * Remove the socket from the scheduler and make sure
- * to disable all notifications.
- */
- mk_sched_drop_connection(conn, sched, server);
- return 0;
-}
-
-void mk_sched_event_free(struct mk_event *event)
-{
- struct mk_sched_worker *sched = mk_sched_get_thread_conf();
-
- if ((event->type & MK_EVENT_IDLE) != 0) {
- return;
- }
-
- event->type |= MK_EVENT_IDLE;
- mk_list_add(&event->_head, &sched->event_free_queue);
-}
-
-/* Register a new callback function to invoke when a worker is created */
-int mk_sched_worker_cb_add(struct mk_server *server,
- void (*cb_func) (void *),
- void *data)
-{
- struct mk_sched_worker_cb *wcb;
-
- wcb = mk_mem_alloc(sizeof(struct mk_sched_worker_cb));
- if (!wcb) {
- return -1;
- }
-
- wcb->cb_func = cb_func;
- wcb->data = data;
- mk_list_add(&wcb->_head, &server->sched_worker_callbacks);
- return 0;
-}
-
-void mk_sched_worker_cb_free(struct mk_server *server)
-{
- struct mk_list *tmp;
- struct mk_list *head;
- struct mk_sched_worker_cb *wcb;
-
- mk_list_foreach_safe(head, tmp, &server->sched_worker_callbacks) {
- wcb = mk_list_entry(head, struct mk_sched_worker_cb, _head);
- mk_list_del(&wcb->_head);
- mk_mem_free(wcb);
- }
-}
-
-int mk_sched_send_signal(struct mk_sched_worker *worker, uint64_t val)
-{
- ssize_t n;
-
- /* When using libevent _mk_event_channel_create creates a unix socket
- * instead of a pipe and windows doesn't us calling read / write on a
- * socket instead of recv / send
- */
-
-#ifdef _WIN32
- n = send(worker->signal_channel_w, &val, sizeof(uint64_t), 0);
-#else
- n = write(worker->signal_channel_w, &val, sizeof(uint64_t));
-#endif
-
- if (n < 0) {
- mk_libc_error("write");
-
- return 0;
- }
-
- return 1;
-}
-
-int mk_sched_broadcast_signal(struct mk_server *server, uint64_t val)
-{
- int i;
- int count = 0;
- struct mk_sched_ctx *ctx;
- struct mk_sched_worker *worker;
-
- ctx = server->sched_ctx;
- for (i = 0; i < server->workers; i++) {
- worker = &ctx->workers[i];
-
- count += mk_sched_send_signal(worker, val);
- }
-
- return count;
-}
-
-/*
- * Wait for all workers to finish: this function assumes that previously a
- * MK_SCHED_SIGNAL_FREE_ALL was sent to the worker channels.
- */
-int mk_sched_workers_join(struct mk_server *server)
-{
- int i;
- int count = 0;
- struct mk_sched_ctx *ctx;
- struct mk_sched_worker *worker;
-
- ctx = server->sched_ctx;
- for (i = 0; i < server->workers; i++) {
- worker = &ctx->workers[i];
- pthread_join(worker->tid, NULL);
- count++;
- }
-
- return count;
-}
diff --git a/fluent-bit/lib/monkey/mk_server/mk_server.c b/fluent-bit/lib/monkey/mk_server/mk_server.c
deleted file mode 100644
index a84ef448..00000000
--- a/fluent-bit/lib/monkey/mk_server/mk_server.c
+++ /dev/null
@@ -1,679 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-
-/* Monkey HTTP Server
- * ==================
- * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <monkey/mk_info.h>
-#include <monkey/monkey.h>
-#include <monkey/mk_config.h>
-#include <monkey/mk_scheduler.h>
-#include <monkey/mk_plugin.h>
-#include <monkey/mk_utils.h>
-#include <monkey/mk_server.h>
-#include <monkey/mk_server_tls.h>
-#include <monkey/mk_scheduler.h>
-#include <monkey/mk_core.h>
-#include <monkey/mk_fifo.h>
-#include <monkey/mk_http_thread.h>
-
-#ifdef _WIN32
-#include <winsock2.h>
-#else
-#include <sys/socket.h>
-#include <netinet/in.h>
-#endif
-
-#ifndef _WIN32
-#include <sys/time.h>
-#include <sys/resource.h>
-#endif
-
-pthread_key_t mk_server_fifo_key;
-
-static int mk_server_lib_notify_event_loop_break(struct mk_sched_worker *sched);
-
-/* Return the number of clients that can be attended */
-unsigned int mk_server_capacity(struct mk_server *server)
-{
- int ret;
- int cur;
-
-#ifndef _WIN32
- struct rlimit lim;
-
- /* Limit by system */
- getrlimit(RLIMIT_NOFILE, &lim);
- cur = lim.rlim_cur;
-
- if (server->fd_limit > cur) {
- lim.rlim_cur = server->fd_limit;
- lim.rlim_max = server->fd_limit;
-
- ret = setrlimit(RLIMIT_NOFILE, &lim);
- if (ret == -1) {
- mk_warn("Could not increase FDLimit to %i.", server->fd_limit);
- }
- else {
- cur = server->fd_limit;
- }
- }
- else if (server->fd_limit > 0) {
- cur = server->fd_limit;
- }
-
-#else
- ret = 0;
- cur = INT_MAX;
-
- /* This is not the right way to plug this, according to raymond chen the only limit
- * to fd count is free memory in their winsock provider and there are no other limits
- * that I know of but I should still look for a more elegant solution. (even if it
- * was just ignoring the server_capacity limit in scheduler.c: _next_target)
- */
-#endif
-
- return cur;
-}
-
-static inline
-struct mk_sched_conn *mk_server_listen_handler(struct mk_sched_worker *sched,
- void *data,
- struct mk_server *server)
-{
- int ret;
- int client_fd = -1;
- struct mk_sched_conn *conn;
- struct mk_server_listen *listener = data;
-
- client_fd = mk_socket_accept(listener->server_fd);
- if (mk_unlikely(client_fd == -1)) {
- MK_TRACE("[server] Accept connection failed: %s", strerror(errno));
- goto error;
- }
-
- conn = mk_sched_add_connection(client_fd, listener, sched, server);
- if (mk_unlikely(!conn)) {
- goto error;
- }
-
- ret = mk_event_add(sched->loop, client_fd,
- MK_EVENT_CONNECTION, MK_EVENT_READ, conn);
- if (mk_unlikely(ret != 0)) {
- mk_err("[server] Error registering file descriptor: %s",
- strerror(errno));
- goto error;
- }
-
- sched->accepted_connections++;
- MK_TRACE("[server] New connection arrived: FD %i", client_fd);
- return conn;
-
-error:
- if (client_fd != -1) {
- listener->network->network->close(listener->network, client_fd);
- }
-
- return NULL;
-}
-
-void mk_server_listen_free()
-{
- struct mk_list *list;
- struct mk_list *tmp;
- struct mk_list *head;
- struct mk_server_listen *listener;
-
- list = MK_TLS_GET(mk_tls_server_listen);
- mk_list_foreach_safe(head, tmp, list) {
- listener = mk_list_entry(head, struct mk_server_listen, _head);
- mk_list_del(&listener->_head);
- mk_mem_free(listener);
- }
-}
-
-void mk_server_listen_exit(struct mk_list *list)
-{
- struct mk_list *tmp;
- struct mk_list *head;
- struct mk_server_listen *listen;
-
- if (!list) {
- return;
- }
-
- mk_list_foreach_safe(head, tmp, list) {
- listen = mk_list_entry(head, struct mk_server_listen, _head);
- mk_event_closesocket(listen->server_fd);
- mk_list_del(&listen->_head);
- mk_mem_free(listen);
- }
-
- mk_mem_free(list);
-}
-
-struct mk_list *mk_server_listen_init(struct mk_server *server)
-{
- int server_fd;
- int reuse_port = MK_FALSE;
- struct mk_list *head;
- struct mk_list *listeners;
- struct mk_event *event;
- struct mk_server_listen *listener;
- struct mk_sched_handler *protocol;
- struct mk_plugin *plugin;
- struct mk_config_listener *listen;
-
- if (!server) {
- goto error;
- }
-
- listeners = mk_mem_alloc(sizeof(struct mk_list));
- mk_list_init(listeners);
-
- if (server->scheduler_mode == MK_SCHEDULER_REUSEPORT) {
- reuse_port = MK_TRUE;
- }
-
- mk_list_foreach(head, &server->listeners) {
- listen = mk_list_entry(head, struct mk_config_listener, _head);
-
- server_fd = mk_socket_server(listen->port,
- listen->address,
- reuse_port,
- server);
- if (server_fd >= 0) {
- if (mk_socket_set_tcp_defer_accept(server_fd) != 0) {
-#if defined (__linux__)
- mk_warn("[server] Could not set TCP_DEFER_ACCEPT");
-#endif
- }
-
- listener = mk_mem_alloc_z(sizeof(struct mk_server_listen));
-
- /* configure the internal event_state */
- event = &listener->event;
- event->fd = server_fd;
- event->type = MK_EVENT_LISTENER;
- event->mask = MK_EVENT_EMPTY;
- event->status = MK_EVENT_NONE;
-
- /* continue with listener setup and linking */
- listener->server_fd = server_fd;
- listener->listen = listen;
-
- if (listen->flags & MK_CAP_HTTP) {
- protocol = mk_sched_handler_cap(MK_CAP_HTTP);
- if (!protocol) {
- mk_err("HTTP protocol not supported");
- exit(EXIT_FAILURE);
- }
- listener->protocol = protocol;
- }
-
-#ifdef MK_HAVE_HTTP2
- if (listen->flags & MK_CAP_HTTP2) {
- protocol = mk_sched_handler_cap(MK_CAP_HTTP2);
- if (!protocol) {
- mk_err("HTTP2 protocol not supported");
- exit(EXIT_FAILURE);
- }
- listener->protocol = protocol;
- }
-#endif
- listener->network = mk_plugin_cap(MK_CAP_SOCK_PLAIN, server);
-
- if (listen->flags & MK_CAP_SOCK_TLS) {
- plugin = mk_plugin_cap(MK_CAP_SOCK_TLS, server);
- if (!plugin) {
- mk_err("SSL/TLS not supported");
- exit(EXIT_FAILURE);
- }
- listener->network = plugin;
- }
-
- mk_list_add(&listener->_head, listeners);
- }
- else {
- mk_err("[server] Failed to bind server socket to %s:%s.",
- listen->address,
- listen->port);
- return NULL;
- }
- }
-
- if (reuse_port == MK_TRUE) {
- MK_TLS_SET(mk_tls_server_listen, listeners);
- }
-
- return listeners;
-
-error:
- return NULL;
-}
-
-/* Here we launch the worker threads to attend clients */
-void mk_server_launch_workers(struct mk_server *server)
-{
- int i;
- pthread_t skip;
-
- /* Launch workers */
- for (i = 0; i < server->workers; i++) {
- /* Spawn the thread */
- mk_sched_launch_thread(server, &skip);
- }
-}
-
-/*
- * When using the FIFO interface, this function get's the FIFO worker
- * context and register the pipe file descriptor into the main event
- * loop.
- *
- * note: this function is invoked by each worker thread.
- */
-static int mk_server_fifo_worker_setup(struct mk_event_loop *evl)
-{
- int ret;
- struct mk_fifo_worker *fw;
-
- fw = pthread_getspecific(mk_server_fifo_key);
- if (!fw) {
- return -1;
- }
-
- ret = mk_event_add(evl, fw->channel[0],
- MK_EVENT_FIFO, MK_EVENT_READ,
- fw);
- if (ret != 0) {
- mk_err("[server] Error registering fifo worker channel: %s",
- strerror(errno));
- return -1;
- }
-
- return 0;
-}
-
-/*
- * The loop_balancer() runs in the main process context and is considered
- * the old-fashion way to handle connections. It have an event queue waiting
- * for connections, once one arrives, it decides which worker (thread) may
- * handle it registering the accept(2)ed file descriptor on the worker
- * event monitored queue.
- */
-void mk_server_loop_balancer(struct mk_server *server)
-{
- size_t bytes;
- uint64_t val;
- int operation_flag;
- struct mk_list *head;
- struct mk_list *listeners;
- struct mk_server_listen *listener;
- struct mk_event *event;
- struct mk_event_loop *evl;
- struct mk_sched_worker *sched;
- struct mk_event management_event;
-
- /* Init the listeners */
- listeners = mk_server_listen_init(server);
- if (!listeners) {
- mk_err("Failed to initialize listen sockets.");
- return;
- }
-
- /* Create an event loop context */
- evl = mk_event_loop_create(MK_EVENT_QUEUE_SIZE);
- if (!evl) {
- mk_err("Could not initialize event loop");
- exit(EXIT_FAILURE);
- }
-
- /* Register the listeners */
- mk_list_foreach(head, listeners) {
- listener = mk_list_entry(head, struct mk_server_listen, _head);
- mk_event_add(evl, listener->server_fd,
- MK_EVENT_LISTENER, MK_EVENT_READ,
- listener);
- }
-
- memset(&management_event, 0, sizeof(struct mk_event));
-
- mk_event_add(evl,
- server->lib_ch_manager[0],
- MK_EVENT_NOTIFICATION,
- MK_EVENT_READ,
- &management_event);
-
- operation_flag = MK_TRUE;
- while (operation_flag) {
- mk_event_wait(evl);
- mk_event_foreach(event, evl) {
- if (event->mask & MK_EVENT_READ) {
- /* This signal is sent by mk_stop and both this and
- * mk_lib_worker are expecting it.
- */
- if (server->lib_ch_manager[0] == event->fd) {
-#ifdef _WIN32
- bytes = recv(event->fd, &val, sizeof(uint64_t), MSG_WAITALL);
-#else
- bytes = read(event->fd, &val, sizeof(uint64_t));
-#endif
-
- if (bytes <= 0) {
- return;
- }
-
- if (val == MK_SERVER_SIGNAL_STOP) {
- operation_flag = MK_FALSE;
-
- break;
- }
-
- continue;
- }
-
- /*
- * Accept connection: determinate which thread may work on this
- * new connection.
- */
- sched = mk_sched_next_target(server);
- if (sched != NULL) {
- mk_server_listen_handler(sched, event, server);
-
- mk_server_lib_notify_event_loop_break(sched);
-
-#ifdef MK_HAVE_TRACE
- int i;
- struct mk_sched_ctx *ctx = server->sched_ctx;
-
- for (i = 0; i < server->workers; i++) {
- MK_TRACE("Worker Status");
- MK_TRACE(" WID %i / conx = %llu",
- ctx->workers[i].idx,
- ctx->workers[i].accepted_connections -
- ctx->workers[i].closed_connections);
- }
-#endif
- }
- else {
- mk_warn("[server] Over capacity.");
- }
- }
- else if (event->mask & MK_EVENT_CLOSE) {
- mk_err("[server] Error on socket %d: %s",
- event->fd, strerror(errno));
- }
- }
- }
- mk_event_loop_destroy(evl);
- mk_server_listen_exit(listeners);
-}
-
-/*
- * This function is called when the scheduler is running in the REUSEPORT
- * mode. That means that each worker is listening on shared TCP ports.
- *
- * When using shared TCP ports the Kernel decides to which worker the
- * connection will be assigned.
- */
-void mk_server_worker_loop(struct mk_server *server)
-{
- int ret = -1;
- int timeout_fd;
- uint64_t val;
- struct mk_event *event;
- struct mk_event_loop *evl;
- struct mk_list *list;
- struct mk_list *head;
- struct mk_sched_conn *conn;
- struct mk_sched_worker *sched;
- struct mk_server_listen *listener;
- struct mk_server_timeout *server_timeout;
-
- /* Get thread conf */
- sched = mk_sched_get_thread_conf();
- evl = sched->loop;
-
- /*
- * The worker will NOT process any connection until the master
- * process through mk_server_loop() send us the green light
- * signal MK_SERVER_SIGNAL_START.
- */
- mk_event_wait(evl);
- mk_event_foreach(event, evl) {
- if ((event->mask & MK_EVENT_READ) &&
- event->type == MK_EVENT_NOTIFICATION) {
- if (event->fd == sched->signal_channel_r) {
- /* When using libevent _mk_event_channel_create creates a unix socket
- * instead of a pipe and windows doesn't us calling read / write on a
- * socket instead of recv / send
- */
-#ifdef _WIN32
- ret = recv(event->fd, &val, sizeof(val), MSG_WAITALL);
-#else
- ret = read(event->fd, &val, sizeof(val));
-#endif
- if (ret < 0) {
- mk_libc_error("read");
- continue;
- }
- if (val == MK_SERVER_SIGNAL_START) {
- MK_TRACE("Worker %i started (SIGNAL_START)", sched->idx);
- break;
- }
- }
- }
- }
-
- if (server->scheduler_mode == MK_SCHEDULER_REUSEPORT) {
- /* Register listeners */
- list = MK_TLS_GET(mk_tls_server_listen);
- mk_list_foreach(head, list) {
- listener = mk_list_entry(head, struct mk_server_listen, _head);
- mk_event_add(sched->loop, listener->server_fd,
- MK_EVENT_LISTENER, MK_EVENT_READ,
- listener);
- }
- }
-
- /*
- * If running in library mode, register the FIFO pipe file descriptors
- * into the main event loop.
- */
- if (server->lib_mode == MK_TRUE) {
- mk_server_fifo_worker_setup(evl);
- }
-
- /* create a new timeout file descriptor */
- server_timeout = mk_mem_alloc_z(sizeof(struct mk_server_timeout));
- MK_TLS_SET(mk_tls_server_timeout, server_timeout);
- timeout_fd = mk_event_timeout_create(evl, server->timeout, 0, server_timeout);
-
- while (1) {
- mk_event_wait(evl);
- mk_event_foreach(event, evl) {
- ret = 0;
- if (event->type & MK_EVENT_IDLE) {
- continue;
- }
-
- if (event->type == MK_EVENT_CONNECTION) {
- conn = (struct mk_sched_conn *) event;
-
- if (event->mask & MK_EVENT_WRITE) {
- MK_TRACE("[FD %i] Event WRITE", event->fd);
- ret = mk_sched_event_write(conn, sched, server);
- }
-
- if (event->mask & MK_EVENT_READ) {
- MK_TRACE("[FD %i] Event READ", event->fd);
- ret = mk_sched_event_read(conn, sched, server);
- }
-
-
- if (event->mask & MK_EVENT_CLOSE && ret != -1) {
- MK_TRACE("[FD %i] Event CLOSE", event->fd);
- ret = -1;
- }
-
- if (ret < 0 && conn->status != MK_SCHED_CONN_CLOSED) {
- MK_TRACE("[FD %i] Event FORCE CLOSE | ret = %i",
- event->fd, ret);
- mk_sched_event_close(conn, sched, MK_EP_SOCKET_CLOSED,
- server);
- }
- }
- else if (event->type == MK_EVENT_LISTENER) {
- /*
- * A new connection have been accepted..or failed, despite
- * the result, we let the loop continue processing the other
- * events triggered.
- */
- conn = mk_server_listen_handler(sched, event, server);
- if (conn) {
- //conn->event.mask = MK_EVENT_READ
- //goto speed;
- }
- continue;
- }
- else if (event->type == MK_EVENT_CUSTOM) {
- /*
- * We got an event associated to a custom interface, that
- * means a plugin registered some file descriptor on this
- * event loop and an event was triggered. We pass the control
- * to the defined event handler.
- */
- event->handler(event);
- }
- else if (event->type == MK_EVENT_NOTIFICATION) {
-#ifdef _WIN32
- ret = recv(event->fd, &val, sizeof(val), MSG_WAITALL);
-#else
- ret = read(event->fd, &val, sizeof(val));
-#endif
- if (ret < 0) {
- mk_libc_error("read");
- continue;
- }
-
- if (event->fd == sched->signal_channel_r) {
- if (val == MK_SCHED_SIGNAL_DEADBEEF) {
- //FIXME:mk_sched_sync_counters();
- continue;
- }
- else if (val == MK_SCHED_SIGNAL_FREE_ALL) {
- if (timeout_fd > 0) {
- mk_event_timeout_destroy(evl, server_timeout);
- }
- mk_mem_free(MK_TLS_GET(mk_tls_server_timeout));
- mk_server_listen_exit(sched->listeners);
- mk_event_loop_destroy(evl);
- mk_sched_worker_free(server);
- return;
- }
- else if (val == MK_SCHED_SIGNAL_EVENT_LOOP_BREAK) {
- /* NOTE: This is just a notification that's sent to break out
- * of the libevent loop in windows after accepting a new
- * client
- */
- MK_TRACE("New client accepted, awesome!");
- }
- }
- else if (event->fd == timeout_fd) {
- mk_sched_check_timeouts(sched, server);
- }
- continue;
- }
- else if (event->type == MK_EVENT_THREAD) {
- mk_http_thread_event(event);
- continue;
- }
- else if (event->type == MK_EVENT_FIFO) {
- mk_fifo_worker_read(event);
- continue;
- }
- }
- mk_sched_threads_purge(sched);
- mk_sched_event_free_all(sched);
- }
-}
-
-static int mk_server_lib_notify_event_loop_break(struct mk_sched_worker *sched)
-{
- uint64_t val;
-
- /* Check the channel is valid (enabled by library mode) */
- if (sched->signal_channel_w <= 0) {
- return -1;
- }
-
- val = MK_SCHED_SIGNAL_EVENT_LOOP_BREAK;
-
-#ifdef _WIN32
- return send(sched->signal_channel_w, &val, sizeof(uint64_t), 0);
-#else
- return write(sched->signal_channel_w, &val, sizeof(uint64_t));
-#endif
-}
-
-static int mk_server_lib_notify_started(struct mk_server *server)
-{
- uint64_t val;
-
- /* Check the channel is valid (enabled by library mode) */
- if (server->lib_ch_start[1] <= 0) {
- return -1;
- }
-
- val = MK_SERVER_SIGNAL_START;
-
-#ifdef _WIN32
- return send(server->lib_ch_start[1], &val, sizeof(uint64_t), 0);
-#else
- return write(server->lib_ch_start[1], &val, sizeof(uint64_t));
-#endif
-}
-
-void mk_server_loop(struct mk_server *server)
-{
- uint64_t val;
-
- /* Rename worker */
- mk_utils_worker_rename("monkey: server");
-
- if (server->lib_mode == MK_FALSE) {
- mk_info("HTTP Server started");
- }
-
- /* Wake up workers */
- val = MK_SERVER_SIGNAL_START;
- mk_sched_broadcast_signal(server, val);
-
- /* Signal lib caller (if any) */
- mk_server_lib_notify_started(server);
-
- /*
- * When using REUSEPORT mode on the Scheduler, we need to signal
- * them so they can start processing connections.
- */
- if (server->scheduler_mode == MK_SCHEDULER_REUSEPORT) {
- /* do thing :) */
- }
- else {
- /* FIXME!: this old mode needs some checks on library mode */
- mk_server_loop_balancer(server);
- }
-}
diff --git a/fluent-bit/lib/monkey/mk_server/mk_socket.c b/fluent-bit/lib/monkey/mk_server/mk_socket.c
deleted file mode 100644
index 0277ab1c..00000000
--- a/fluent-bit/lib/monkey/mk_server/mk_socket.c
+++ /dev/null
@@ -1,402 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-
-/* Monkey HTTP Server
- * ==================
- * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define _GNU_SOURCE
-
-#ifndef SOL_TCP
-#define SOL_TCP IPPROTO_TCP
-#endif
-
-#include <monkey/monkey.h>
-#include <monkey/mk_info.h>
-#include <monkey/mk_socket.h>
-#include <monkey/mk_kernel.h>
-#include <monkey/mk_net.h>
-#include <monkey/mk_core.h>
-#include <monkey/mk_utils.h>
-#include <monkey/mk_plugin.h>
-
-#include <time.h>
-
-/*
- * Example from:
- * http://www.baus.net/on-tcp_cork
- */
-int mk_socket_set_cork_flag(int fd, int state)
-{
- MK_TRACE("Socket, set Cork Flag FD %i to %s", fd, (state ? "ON" : "OFF"));
-
-#if defined (TCP_CORK)
- return setsockopt(fd, SOL_TCP, TCP_CORK, &state, sizeof(state));
-#elif defined (TCP_NOPUSH)
- return setsockopt(fd, SOL_SOCKET, TCP_NOPUSH, &state, sizeof(state));
-#endif
-
- return 0;
-}
-
-int mk_socket_set_nonblocking(int sockfd)
-{
-
- MK_TRACE("Socket, set FD %i to non-blocking", sockfd);
-
-#ifdef _WIN32
- u_long flags;
-
- flags = 0;
- if (SOCKET_ERROR == ioctlsocket(sockfd, FIONBIO, &flags)) {
- mk_err("Can't set to non-blocking mode socket %i", sockfd);
- return -1;
- }
-#else
- if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL, 0) | O_NONBLOCK) == -1) {
- mk_err("Can't set to non-blocking mode socket %i", sockfd);
- return -1;
- }
- fcntl(sockfd, F_SETFD, FD_CLOEXEC);
-#endif
-
- return 0;
-}
-
-/*
- * Enable the TCP_FASTOPEN feature for server side implemented in
- * Linux Kernel >= 3.7, for more details read here:
- *
- * TCP Fast Open: expediting web services: http://lwn.net/Articles/508865/
- */
-int mk_socket_set_tcp_fastopen(int sockfd)
-{
-#if defined (__linux__)
- int qlen = 5;
- return setsockopt(sockfd, SOL_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen));
-#endif
-
- (void) sockfd;
- return -1;
-}
-
-int mk_socket_set_tcp_nodelay(int sockfd)
-{
- int on = 1;
-
- return setsockopt(sockfd, SOL_TCP, TCP_NODELAY, &on, sizeof(on));
-}
-
-int mk_socket_set_tcp_defer_accept(int sockfd)
-{
-#if defined (__linux__)
- int timeout = 0;
-
- return setsockopt(sockfd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &timeout, sizeof(int));
-#else
- (void) sockfd;
- return -1;
-#endif
-}
-
-int mk_socket_set_tcp_reuseport(int sockfd)
-{
- int on = 1;
- return setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on));
-}
-
-int mk_socket_create(int domain, int type, int protocol)
-{
- int fd;
-
-#ifdef SOCK_CLOEXEC
- fd = socket(domain, type | SOCK_CLOEXEC, protocol);
-#else
- fd = socket(domain, type, protocol);
-
-#ifndef _WIN32
- fcntl(fd, F_SETFD, FD_CLOEXEC);
-#endif
-#endif
-
- if (fd == -1) {
- mk_libc_error("socket");
- return -1;
- }
-
- return fd;
-}
-
-int mk_socket_open(char *path, int async)
-{
- int ret;
- int socket_fd;
- struct sockaddr_un address;
-
- socket_fd = mk_socket_create(PF_UNIX, SOCK_STREAM, 0);
- if (socket_fd == -1) {
- return -1;
- }
-
- memset(&address, '\0', sizeof(struct sockaddr_un));
- address.sun_family = AF_UNIX;
- snprintf(address.sun_path, sizeof(address.sun_path), "%s", path);
-
- if (async == MK_TRUE) {
- mk_socket_set_nonblocking(socket_fd);
- }
-
- ret = connect(socket_fd, (struct sockaddr *) &address,
- sizeof(struct sockaddr_un));
- if (ret == -1) {
- if (errno == EINPROGRESS) {
- return socket_fd;
- }
- else {
-#ifdef MK_HAVE_TRACE
- mk_libc_error("connect");
-#endif
- close(socket_fd);
- return -1;
- }
- }
-
- return socket_fd;
-}
-
-
-int mk_socket_connect(char *host, int port, int async)
-{
- int ret;
- int socket_fd = -1;
- char *port_str = 0;
- unsigned long len;
- struct addrinfo hints;
- struct addrinfo *res, *rp;
-
- memset(&hints, 0, sizeof hints);
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
-
- mk_string_build(&port_str, &len, "%d", port);
-
- ret = getaddrinfo(host, port_str, &hints, &res);
- mk_mem_free(port_str);
- if(ret != 0) {
- mk_err("Can't get addr info: %s", gai_strerror(ret));
- return -1;
- }
- for (rp = res; rp != NULL; rp = rp->ai_next) {
- socket_fd = mk_socket_create(rp->ai_family,
- rp->ai_socktype, rp->ai_protocol);
-
- if (socket_fd == -1) {
- mk_warn("Error creating client socket, retrying");
- continue;
- }
-
- if (async == MK_TRUE) {
- mk_socket_set_nonblocking(socket_fd);
- }
-
- ret = connect(socket_fd,
- (struct sockaddr *) rp->ai_addr, rp->ai_addrlen);
- if (ret == -1) {
- if (errno == EINPROGRESS) {
- break;
- }
- else {
- printf("%s", strerror(errno));
- perror("connect");
- exit(1);
- close(socket_fd);
- continue;
- }
- }
- break;
- }
- freeaddrinfo(res);
-
- if (rp == NULL)
- return -1;
-
- return socket_fd;
-}
-
-int mk_socket_reset(int socket)
-{
- int status = 1;
-
- if (setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &status, sizeof(int)) == -1) {
- mk_libc_error("socket");
- exit(EXIT_FAILURE);
- }
-
- return 0;
-}
-
-int mk_socket_bind(int socket_fd, const struct sockaddr *addr,
- socklen_t addrlen, int backlog, struct mk_server *server)
-{
- int ret;
-
- ret = bind(socket_fd, addr, addrlen);
- if( ret == -1 ) {
- mk_warn("Error binding socket");
- return ret;
- }
-
- /*
- * Enable TCP_FASTOPEN by default: if for some reason this call fail,
- * it will not affect the behavior of the server, in order to succeed,
- * Monkey must be running in a Linux system with Kernel >= 3.7 and the
- * tcp_fastopen flag enabled here:
- *
- * # cat /proc/sys/net/ipv4/tcp_fastopen
- *
- * To enable this feature just do:
- *
- * # echo 1 > /proc/sys/net/ipv4/tcp_fastopen
- */
- if (server->kernel_features & MK_KERNEL_TCP_FASTOPEN) {
- ret = mk_socket_set_tcp_fastopen(socket_fd);
- if (ret == -1) {
- mk_warn("Could not set TCP_FASTOPEN");
- }
- }
-
- ret = listen(socket_fd, backlog);
- if(ret == -1 ) {
- return -1;
- }
-
- return ret;
-}
-
-/* Just IPv4 for now... */
-int mk_socket_server(char *port, char *listen_addr,
- int reuse_port, struct mk_server *server)
-{
- int ret;
- int socket_fd = -1;
- struct addrinfo hints;
- struct addrinfo *res, *rp;
-
- memset(&hints, 0, sizeof hints);
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_flags = AI_PASSIVE;
-
- mk_net_init();
-
- ret = getaddrinfo(listen_addr, port, &hints, &res);
- if(ret != 0) {
- mk_err("Can't get addr info: %s", gai_strerror(ret));
- return -1;
- }
-
- for (rp = res; rp != NULL; rp = rp->ai_next) {
- socket_fd = mk_socket_create(rp->ai_family,
- rp->ai_socktype, rp->ai_protocol);
- if (socket_fd == -1) {
- mk_warn("Error creating server socket, retrying");
- continue;
- }
-
- ret = mk_socket_set_tcp_nodelay(socket_fd);
- if (ret == -1) {
- mk_warn("Could not set TCP_NODELAY");
- }
-
- mk_socket_reset(socket_fd);
-
- /* Check if reuse port can be enabled on this socket */
- if (reuse_port == MK_TRUE &&
- (server->kernel_features & MK_KERNEL_SO_REUSEPORT)) {
- ret = mk_socket_set_tcp_reuseport(socket_fd);
- if (ret == -1) {
- mk_warn("Could not use SO_REUSEPORT, using fair balancing mode");
- server->scheduler_mode = MK_SCHEDULER_FAIR_BALANCING;
- }
- }
-
- ret = mk_socket_bind(socket_fd, rp->ai_addr, rp->ai_addrlen,
- MK_SOMAXCONN, server);
- if(ret == -1) {
- mk_err("Cannot listen on %s:%s", listen_addr, port);
- freeaddrinfo(res);
- return -1;
- }
- break;
- }
- freeaddrinfo(res);
-
- if (rp == NULL)
- return -1;
-
- return socket_fd;
-}
-
-int mk_socket_ip_str(int socket_fd, char **buf, int size, unsigned long *len)
-{
- int ret;
- struct sockaddr_storage addr;
- socklen_t s_len = sizeof(addr);
-
- ret = getpeername(socket_fd, (struct sockaddr *) &addr, &s_len);
-
- if (mk_unlikely(ret == -1)) {
- MK_TRACE("[FD %i] Can't get addr for this socket", socket_fd);
- return -1;
- }
-
- errno = 0;
-
- if(addr.ss_family == AF_INET) {
- if((inet_ntop(AF_INET, &((struct sockaddr_in *)&addr)->sin_addr,
- *buf, size)) == NULL) {
- mk_warn("mk_socket_ip_str: Can't get the IP text form (%i)", errno);
- return -1;
- }
- }
- else if(addr.ss_family == AF_INET6) {
- if((inet_ntop(AF_INET6, &((struct sockaddr_in6 *)&addr)->sin6_addr,
- *buf, size)) == NULL) {
- mk_warn("mk_socket_ip_str: Can't get the IP text form (%i)", errno);
- return -1;
- }
- }
-
- *len = strlen(*buf);
- return 0;
-}
-
-int mk_socket_accept(int server_fd)
-{
- int remote_fd;
-
- struct sockaddr sock_addr;
- socklen_t socket_size = sizeof(struct sockaddr);
-
-#ifdef MK_HAVE_ACCEPT4
- remote_fd = accept4(server_fd, &sock_addr, &socket_size,
- SOCK_NONBLOCK | SOCK_CLOEXEC);
-#else
- remote_fd = accept(server_fd, &sock_addr, &socket_size);
- mk_socket_set_nonblocking(remote_fd);
-#endif
-
- return remote_fd;
-}
diff --git a/fluent-bit/lib/monkey/mk_server/mk_stream.c b/fluent-bit/lib/monkey/mk_server/mk_stream.c
deleted file mode 100644
index df0f1b0b..00000000
--- a/fluent-bit/lib/monkey/mk_server/mk_stream.c
+++ /dev/null
@@ -1,338 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-
-/* Monkey HTTP Server
- * ==================
- * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <monkey/monkey.h>
-#include <monkey/mk_stream.h>
-#include <assert.h>
-
-/* Create a new channel */
-struct mk_channel *mk_channel_new(int type, int fd)
-{
- struct mk_channel *channel;
-
- channel = mk_mem_alloc(sizeof(struct mk_channel));
- if (!channel) {
- return NULL;
- }
- channel->type = type;
- channel->fd = fd;
- channel->status = MK_CHANNEL_OK;
- mk_list_init(&channel->streams);
-
- return channel;
-}
-
-int mk_channel_release(struct mk_channel *channel)
-{
- mk_mem_free(channel);
- return 0;
-}
-
-static inline size_t channel_write_in_file(struct mk_channel *channel,
- struct mk_stream_input *in)
-{
- ssize_t bytes = 0;
-
- MK_TRACE("[CH %i] STREAM_FILE [fd=%i], bytes=%lu",
- channel->fd, in->fd, in->bytes_total);
-
- /* Direct write */
- bytes = mk_sched_conn_sendfile(channel,
- in->fd,
- &in->bytes_offset,
- in->bytes_total
- );
- MK_TRACE("[CH=%d] [FD=%i] WRITE STREAM FILE: %lu bytes",
- channel->fd, in->fd, bytes);
-
- return bytes;
-}
-
-size_t mk_stream_size(struct mk_stream *stream)
-{
- return (stream->bytes_total - stream->bytes_offset);
-}
-
-/*
- * It 'intent' to write a few streams over the channel and alter the
- * channel notification side if required: READ -> WRITE.
- */
-int mk_channel_flush(struct mk_channel *channel)
-{
- int ret = 0;
- size_t count = 0;
- size_t total = 0;
- uint32_t stop = (MK_CHANNEL_DONE | MK_CHANNEL_ERROR | MK_CHANNEL_EMPTY);
-
- do {
- ret = mk_channel_write(channel, &count);
- total += count;
-
-#ifdef MK_HAVE_TRACE
- MK_TRACE("Channel flush: %d bytes", count);
- if (ret & MK_CHANNEL_DONE) {
- MK_TRACE("Channel was empty");
- }
- if (ret & MK_CHANNEL_ERROR) {
- MK_TRACE("Channel error");
- }
- if (ret & MK_CHANNEL_EMPTY) {
- MK_TRACE("Channel empty");
- }
-#endif
- } while (total <= 4096 && ((ret & stop) == 0));
-
- if (ret == MK_CHANNEL_DONE) {
- MK_TRACE("Channel done");
- return ret;
- }
- else if (ret & (MK_CHANNEL_FLUSH | MK_CHANNEL_BUSY)) {
- MK_TRACE("Channel FLUSH | BUSY");
- if ((channel->event->mask & MK_EVENT_WRITE) == 0) {
- mk_event_add(mk_sched_loop(),
- channel->fd,
- MK_EVENT_CONNECTION,
- MK_EVENT_WRITE,
- channel->event);
- }
- }
-
- return ret;
-}
-
-int mk_stream_in_release(struct mk_stream_input *in)
-{
- if (in->cb_finished) {
- in->cb_finished(in);
- }
-
- mk_stream_input_unlink(in);
- if (in->dynamic == MK_TRUE) {
- mk_mem_free(in);
- }
-
- return 0;
-}
-
-int mk_channel_stream_write(struct mk_stream *stream, size_t *count)
-{
- ssize_t bytes = 0;
- struct mk_iov *iov;
- struct mk_list *tmp;
- struct mk_list *head;
- struct mk_channel *channel;
- struct mk_stream_input *input;
-
- channel = stream->channel;
-
- /* Validate channel status */
- if (channel->status != MK_CHANNEL_OK) {
- return -MK_CHANNEL_ERROR;
- }
-
- /* Iterate inputs and process stream */
- mk_list_foreach_safe(head, tmp, &stream->inputs) {
- input = mk_list_entry(head, struct mk_stream_input, _head);
- if (input->type == MK_STREAM_FILE) {
- bytes = channel_write_in_file(channel, input);
- }
- else if (input->type == MK_STREAM_IOV) {
- iov = input->buffer;
- if (!iov) {
- return MK_CHANNEL_EMPTY;
- }
-
- bytes = mk_sched_conn_writev(channel, iov);
-
- MK_TRACE("[CH %i] STREAM_IOV, wrote %d bytes",
- channel->fd, bytes);
- if (bytes > 0) {
- /* Perform the adjustment on mk_iov */
- mk_iov_consume(iov, bytes);
- }
- }
- else if (input->type == MK_STREAM_RAW) {
- bytes = mk_sched_conn_write(channel,
- input->buffer, input->bytes_total);
- MK_TRACE("[CH %i] STREAM_RAW, bytes=%lu/%lu\n",
- channel->fd, bytes, input->bytes_total);
- }
-
- if (bytes > 0) {
- *count = bytes;
- mk_stream_input_consume(input, bytes);
-
- /* notification callback, optional */
- if (stream->cb_bytes_consumed) {
- stream->cb_bytes_consumed(stream, bytes);
- }
-
- if (input->cb_consumed) {
- input->cb_consumed(input, bytes);
- }
-
- if (input->bytes_total == 0) {
- MK_TRACE("Input done, unlinking (channel=%p)", channel);
- mk_stream_in_release(input);
- }
- MK_TRACE("[CH %i] CHANNEL_FLUSH", channel->fd);
- }
- else if (bytes < 0) {
- mk_stream_in_release(input);
- return -MK_CHANNEL_ERROR;
- }
- else if (bytes == 0) {
- mk_stream_in_release(input);
- return -MK_CHANNEL_ERROR;
- }
- }
-
- return bytes;
-}
-
-/* It perform a direct stream I/O write through the network layer */
-int mk_channel_write(struct mk_channel *channel, size_t *count)
-{
- ssize_t bytes = -1;
- struct mk_iov *iov;
- struct mk_stream *stream = NULL;
- struct mk_stream_input *input;
-
- errno = 0;
-
- if (mk_list_is_empty(&channel->streams) == 0) {
- MK_TRACE("[CH %i] CHANNEL_EMPTY", channel->fd);
- return MK_CHANNEL_EMPTY;
- }
-
- /* Get the input source */
- stream = mk_list_entry_first(&channel->streams, struct mk_stream, _head);
- if (mk_list_is_empty(&stream->inputs) == 0) {
- return MK_CHANNEL_EMPTY;
- }
- input = mk_list_entry_first(&stream->inputs, struct mk_stream_input, _head);
-
- /*
- * Based on the Stream Input type we consume on that way, not all inputs
- * requires to read from buffer, e.g: Static File, Pipes.
- */
- if (channel->type == MK_CHANNEL_SOCKET) {
- if (input->type == MK_STREAM_FILE) {
- bytes = channel_write_in_file(channel, input);
- }
- else if (input->type == MK_STREAM_IOV) {
- iov = input->buffer;
- if (!iov) {
- return MK_CHANNEL_EMPTY;
- }
-
- bytes = mk_sched_conn_writev(channel, iov);
-
- MK_TRACE("[CH %i] STREAM_IOV, wrote %d bytes",
- channel->fd, bytes);
- if (bytes > 0) {
- /* Perform the adjustment on mk_iov */
- mk_iov_consume(iov, bytes);
- }
- }
- else if (input->type == MK_STREAM_RAW) {
- bytes = mk_sched_conn_write(channel,
- input->buffer, input->bytes_total);
- MK_TRACE("[CH %i] STREAM_RAW, bytes=%lu/%lu",
- channel->fd, bytes, input->bytes_total);
- if (bytes > 0) {
- /* DEPRECATED: consume_raw(input, bytes); */
- }
- }
-
- if (bytes > 0) {
- *count = bytes;
- mk_stream_input_consume(input, bytes);
-
- /* notification callback, optional */
- if (stream->cb_bytes_consumed) {
- stream->cb_bytes_consumed(stream, bytes);
- }
-
- if (input->cb_consumed) {
- input->cb_consumed(input, bytes);
- }
-
- if (input->bytes_total == 0) {
- MK_TRACE("Input done, unlinking (channel=%p)", channel);
- mk_stream_in_release(input);
- }
-
- if (mk_list_is_empty(&stream->inputs) == 0) {
- /* Everytime the stream is empty, we notify the trigger the cb */
- if (stream->cb_finished) {
- stream->cb_finished(stream);
- }
-
- if (mk_channel_is_empty(channel) == 0) {
- MK_TRACE("[CH %i] CHANNEL_DONE", channel->fd);
- return MK_CHANNEL_DONE;
- }
- else {
- MK_TRACE("[CH %i] CHANNEL_FLUSH", channel->fd);
- return MK_CHANNEL_FLUSH;
- }
- }
-
- MK_TRACE("[CH %i] CHANNEL_FLUSH", channel->fd);
- return MK_CHANNEL_FLUSH;
- }
- else if (bytes < 0) {
- if (errno == EAGAIN) {
- return MK_CHANNEL_BUSY;
- }
-
- mk_stream_in_release(input);
- return MK_CHANNEL_ERROR;
- }
- else if (bytes == 0) {
- mk_stream_in_release(input);
- return MK_CHANNEL_ERROR;
- }
- }
-
- return MK_CHANNEL_ERROR;
-}
-
-/* Remove any dynamic memory associated */
-int mk_channel_clean(struct mk_channel *channel)
-{
- struct mk_list *tmp;
- struct mk_list *tmp_in;
- struct mk_list *head;
- struct mk_list *head_in;
- struct mk_stream *stream;
- struct mk_stream_input *in;
-
- mk_list_foreach_safe(head, tmp, &channel->streams) {
- stream = mk_list_entry(head, struct mk_stream, _head);
- mk_list_foreach_safe(head_in, tmp_in, &stream->inputs) {
- in = mk_list_entry(head_in, struct mk_stream_input, _head);
- mk_stream_in_release(in);
- }
- mk_stream_release(stream);
- }
-
- return 0;
-}
diff --git a/fluent-bit/lib/monkey/mk_server/mk_user.c b/fluent-bit/lib/monkey/mk_server/mk_user.c
deleted file mode 100644
index 7200ff08..00000000
--- a/fluent-bit/lib/monkey/mk_server/mk_user.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-
-/* Monkey HTTP Server
- * ==================
- * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <monkey/monkey.h>
-#include <monkey/mk_user.h>
-#include <monkey/mk_http.h>
-#include <monkey/mk_http_status.h>
-#include <monkey/mk_core.h>
-#include <monkey/mk_utils.h>
-#include <monkey/mk_config.h>
-
-#ifndef _WIN32
-#include <pwd.h>
-#include <sys/resource.h>
-#include <sys/types.h>
-#include <grp.h>
-
-int mk_user_init(struct mk_http_session *cs, struct mk_http_request *sr,
- struct mk_server *server)
-{
- int limit;
- const int offset = 2; /* The user is defined after the '/~' string, so offset = 2 */
- const int user_len = 255;
- char user[/*user_len*/ 255]; /* VC++ Doesn't allow for this to be a const int*/
- char *user_uri;
- struct passwd *s_user;
-
- if (sr->uri_processed.len <= 2) {
- return -1;
- }
-
- limit = mk_string_char_search(sr->uri_processed.data + offset, '/',
- sr->uri_processed.len);
-
- if (limit == -1) {
- limit = (sr->uri_processed.len) - offset;
- }
-
- if (limit + offset >= (user_len)) {
- return -1;
- }
-
- memcpy(user, sr->uri_processed.data + offset, limit);
- user[limit] = '\0';
-
- MK_TRACE("user: '%s'", user);
-
- /* Check system user */
- if ((s_user = getpwnam(user)) == NULL) {
- mk_http_error(MK_CLIENT_NOT_FOUND, cs, sr, server);
- return -1;
- }
-
- if (sr->uri_processed.len > (unsigned int) (offset+limit)) {
- user_uri = mk_mem_alloc(sr->uri_processed.len);
- if (!user_uri) {
- return -1;
- }
-
- memcpy(user_uri,
- sr->uri_processed.data + (offset + limit),
- sr->uri_processed.len - offset - limit);
- user_uri[sr->uri_processed.len - offset - limit] = '\0';
-
- mk_string_build(&sr->real_path.data, &sr->real_path.len,
- "%s/%s%s",
- s_user->pw_dir, server->conf_user_pub, user_uri);
- mk_mem_free(user_uri);
- }
- else {
- mk_string_build(&sr->real_path.data, &sr->real_path.len,
- "%s/%s", s_user->pw_dir, server->conf_user_pub);
- }
-
- sr->user_home = MK_TRUE;
- return 0;
-}
-
-/* Change process user */
-int mk_user_set_uidgid(struct mk_server *server)
-{
- struct passwd *usr;
-
- /* Launched by root ? */
- if (geteuid() == 0 && server->user) {
- struct rlimit rl;
-
- if (getrlimit(RLIMIT_NOFILE, &rl)) {
- mk_warn("cannot get resource limits");
- }
-
- /* Check if user exists */
- if ((usr = getpwnam(server->user)) == NULL) {
- mk_err("Invalid user '%s'", server->user);
- goto out;
- }
-
- if (initgroups(server->user, usr->pw_gid) != 0) {
- mk_err("Initgroups() failed");
- }
-
- /* Change process UID and GID */
- if (setegid(usr->pw_gid) == -1) {
- mk_err("I cannot change the GID to %u", usr->pw_gid);
- }
-
- if (seteuid(usr->pw_uid) == -1) {
- mk_err("I cannot change the UID to %u", usr->pw_uid);
- }
-
- server->is_seteuid = MK_TRUE;
- }
-
- out:
- /* Variables set for run checks on file permission */
- //FIXME
- //EUID = geteuid();
- //EGID = getegid();
-
- return 0;
-}
-
-/* Return process to the original user */
-int mk_user_undo_uidgid(struct mk_server *server)
-{
- if (server->is_seteuid == MK_TRUE) {
- if (setegid(0) < 0) {
- mk_err("Can't restore effective GID");
- }
- if (seteuid(0) < 0) {
- mk_err("Can't restore effective UID");
- }
- }
- return 0;
-}
-
-#else
-/*
- None of these functionalities are going to be available in windows at the moment
-*/
-
-int mk_user_init(struct mk_http_session* cs, struct mk_http_request* sr,
- struct mk_server* server)
-{
- return -1;
-}
-
-int mk_user_set_uidgid(struct mk_server* server)
-{
- mk_err("Cannot impersonate users in windows");
-
- return 0;
-}
-
-int mk_user_undo_uidgid(struct mk_server* server)
-{
- return 0;
-}
-#endif
diff --git a/fluent-bit/lib/monkey/mk_server/mk_utils.c b/fluent-bit/lib/monkey/mk_server/mk_utils.c
deleted file mode 100644
index 443c0ec3..00000000
--- a/fluent-bit/lib/monkey/mk_server/mk_utils.c
+++ /dev/null
@@ -1,589 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-
-/* Monkey HTTP Server
- * ==================
- * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-/* local headers */
-#include <monkey/monkey.h>
-#include <monkey/mk_core.h>
-#include <monkey/mk_utils.h>
-#include <monkey/mk_config.h>
-#include <monkey/mk_socket.h>
-#include <monkey/mk_clock.h>
-#include <monkey/mk_user.h>
-#include <monkey/mk_cache.h>
-#include <monkey/mk_tls.h>
-
-#include <assert.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <time.h>
-#include <inttypes.h>
-
-#ifdef _WIN32
-#include <winsock2.h>
-#else
-#include <sys/socket.h>
-#endif
-
-/* stacktrace */
-#ifndef _WIN32
-#include <dlfcn.h>
-#endif
-
-#ifdef MK_HAVE_BACKTRACE
-#include <execinfo.h>
-#endif
-
-#define MK_UTILS_GMT_DATEFORMAT "%a, %d %b %Y %H:%M:%S GMT"
-
-#ifdef _WIN32
-static struct tm* localtime_r(const time_t* timep, struct tm* result)
-{
- localtime_s(result, timep);
-
- return result;
-}
-
-static struct tm* gmtime_r(const time_t* timep, struct tm* result)
-{
- gmtime_s(result, timep);
-
- return result;
-}
-
-static time_t timegm(struct tm* timeptr)
-{
- return _mkgmtime(timeptr);
-}
-#endif
-
-#ifdef _WIN32
-int mk_utils_get_system_core_count()
-{
- SYSTEM_LOGICAL_PROCESSOR_INFORMATION *proc_info_buffer;
- unsigned int result_entry_count;
- unsigned int entry_index;
- DWORD result_length;
- int result_code;
- int core_count;
-
- core_count = 1;
- result_length = 0;
- proc_info_buffer = NULL;
-
- result_code = GetLogicalProcessorInformation(proc_info_buffer, &result_length);
- /* We're passing a null buffer, result_code has to be false */
-
- if (ERROR_INSUFFICIENT_BUFFER == GetLastError()) {
- result_entry_count = result_length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
- proc_info_buffer = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION *) _alloca(result_length);
-
- if(NULL != proc_info_buffer) {
- result_code = GetLogicalProcessorInformation(proc_info_buffer, &result_length);
-
- if (0 != result_code) {
- core_count = 0;
-
- for(entry_index = 0 ; entry_index < result_entry_count ; entry_index++) {
- if(RelationProcessorCore == proc_info_buffer[entry_index].Relationship) {
- core_count++;
- }
- }
- }
- }
-
- /* Athread stack allocation error is a pretty serious
- * error so in that case we let someone else handle it by returning a
- * sane default (1 core)
- */
- }
-
- return core_count;
-}
-
-int mk_utils_get_system_page_size()
-{
- SYSTEM_INFO si;
-
- GetSystemInfo(&si);
-
- return si.dwPageSize;
-}
-
-#else
-int mk_utils_get_system_core_count()
-{
- return sysconf(_SC_NPROCESSORS_ONLN);
-}
-
-int mk_utils_get_system_page_size()
-{
- return sysconf(_SC_PAGESIZE);
-}
-
-#endif
-
-
-/* Date helpers */
-static const char mk_date_wd[][6] = {"Sun, ", "Mon, ", "Tue, ", "Wed, ", "Thu, ", "Fri, ", "Sat, "};
-static const char mk_date_ym[][5] = {"Jan ", "Feb ", "Mar ", "Apr ", "May ", "Jun ", "Jul ",
- "Aug ", "Sep ", "Oct ", "Nov ", "Dec "};
-
-static int mk_utils_gmt_cache_get(char **data, time_t date)
-{
- unsigned int i;
- struct mk_gmt_cache *gcache = MK_TLS_GET(mk_tls_cache_gmtext);
-
- if (mk_unlikely(!gcache)) {
- return MK_FALSE;
- }
-
- for (i = 0; i < MK_GMT_CACHES; i++) {
- if (date == gcache[i].time) {
- memcpy(*data, gcache[i].text, 32);
- gcache[i].hits++;
- return MK_TRUE;
- }
- }
-
- return MK_FALSE;
-}
-
-static void mk_utils_gmt_cache_add(char *data, time_t time)
-{
- unsigned int i, min = 0;
- struct mk_gmt_cache *gcache = MK_TLS_GET(mk_tls_cache_gmtext);
-
- for (i = 1; i < MK_GMT_CACHES; i++) {
- if (gcache[i].hits < gcache[min].hits)
- min = i;
- }
-
- gcache[min].hits = 1;
- gcache[min].time = time;
- memcpy(gcache[min].text, data, 32);
-}
-
-/*
- *This function given a unix time, set in a mk_ptr_t
- * the date in the RFC1123 format like:
- *
- * Wed, 23 Jun 2010 22:32:01 GMT
- *
- * it also adds a 'CRLF' at the end
- */
-int mk_utils_utime2gmt(char **data, time_t date)
-{
- const int size = 31;
- unsigned short year, mday, hour, min, sec;
- char *buf=0;
- struct tm *gtm;
-
- if (date == 0) {
- if ((date = time(NULL)) == -1) {
- return -1;
- }
- }
- else {
- /* Maybe it's converted already? */
- if (mk_utils_gmt_cache_get(data, date) == MK_TRUE) {
- return size;
- }
- }
-
- /* Convert unix time to struct tm */
- gtm = MK_TLS_GET(mk_tls_cache_gmtime);
-
- /* If this function was invoked from a non-thread context it should exit */
- mk_bug(!gtm);
- gtm = gmtime_r(&date, gtm);
- if (!gtm) {
- return -1;
- }
-
- /* struct tm -> tm_year counts number of years after 1900 */
- year = gtm->tm_year + 1900;
-
- /* Signed division is slow, by using unsigned we gain 25% speed */
- mday = gtm->tm_mday;
- hour = gtm->tm_hour;
- min = gtm->tm_min;
- sec = gtm->tm_sec;
-
- /* Compose template */
- buf = *data;
-
- /* Week day */
- memcpy(buf, mk_date_wd[gtm->tm_wday], 5);
- buf += 5;
-
- /* Day of the month */
- *buf++ = ('0' + (mday / 10));
- *buf++ = ('0' + (mday % 10));
- *buf++ = ' ';
-
- /* Month */
- memcpy(buf, mk_date_ym[gtm->tm_mon], 4);
- buf += 4;
-
- /* Year */
- *buf++ = ('0' + (year / 1000) % 10);
- *buf++ = ('0' + (year / 100) % 10);
- *buf++ = ('0' + (year / 10) % 10);
- *buf++ = ('0' + (year % 10));
- *buf++ = ' ';
-
- /* Hour */
- *buf++ = ('0' + (hour / 10));
- *buf++ = ('0' + (hour % 10));
- *buf++ = ':';
-
- /* Minutes */
- *buf++ = ('0' + (min / 10));
- *buf++ = ('0' + (min % 10));
- *buf++ = ':';
-
- /* Seconds */
- *buf++ = ('0' + (sec / 10));
- *buf++ = ('0' + (sec % 10));
-
- /* GMT Time zone + CRLF */
- memcpy(buf, " GMT\r\n\0", 7);
-
- /* Add new entry to the cache */
- mk_utils_gmt_cache_add(*data, date);
-
- /* Set mk_ptr_t data len */
- return size;
-}
-
-time_t mk_utils_gmt2utime(char *date)
-{
- time_t new_unix_time;
- struct tm t_data;
- memset(&t_data, 0, sizeof(struct tm));
-
-
-#ifdef _WIN32
-#pragma message("Since there is no strptime in windows we'll parse the date in a really crude way just to get it out of the way")
-
- if (0 != strcmp(MK_UTILS_GMT_DATEFORMAT, "%a, %d %b %Y %H:%M:%S GMT")) {
- return -1;
- }
-
- {
- char *token;
-
- token = strtok(date, " "); /* "%a, " */
-
- if (NULL == token) {
- return -1;
- }
-
- token = strtok(NULL, " "); /* "%d " */
-
- if (NULL == token) {
- return -1;
- }
-
- t_data.tm_mday = strtol(token, NULL, 10);
-
- token = strtok(NULL, " "); /* "%b " */
-
- if (NULL == token) {
- return -1;
- }
-
- if(0 == _strnicmp(token, "jan", 3)){
- t_data.tm_mon = 0;
- }
- else if(0 == _strnicmp(token, "feb", 3)){
- t_data.tm_mon = 1;
- }
- else if(0 == _strnicmp(token, "mar", 3)){
- t_data.tm_mon = 2;
- }
- else if(0 == _strnicmp(token, "apr", 3)){
- t_data.tm_mon = 3;
- }
- else if(0 == _strnicmp(token, "may", 3)){
- t_data.tm_mon = 4;
- }
- else if(0 == _strnicmp(token, "jun", 3)){
- t_data.tm_mon = 5;
- }
- else if(0 == _strnicmp(token, "jul", 3)){
- t_data.tm_mon = 6;
- }
- else if(0 == _strnicmp(token, "aug", 3)){
- t_data.tm_mon = 7;
- }
- else if(0 == _strnicmp(token, "sep", 3)){
- t_data.tm_mon = 8;
- }
- else if(0 == _strnicmp(token, "oct", 3)){
- t_data.tm_mon = 9;
- }
- else if(0 == _strnicmp(token, "nov", 3)){
- t_data.tm_mon = 10;
- }
- else if(0 == _strnicmp(token, "dec", 3)){
- t_data.tm_mon = 11;
- }
- else {
- return -1;
- }
-
- token = strtok(NULL, " "); /* "%Y " */
-
- if (NULL == token) {
- return -1;
- }
-
- t_data.tm_year = strtol(token, NULL, 10);
-
- token = strtok(NULL, ":"); /* "%H:" */
-
- if (NULL == token) {
- return -1;
- }
-
- t_data.tm_hour = strtol(token, NULL, 10);
-
- token = strtok(NULL, ":"); /* "%M:" */
-
- if (NULL == token) {
- return -1;
- }
-
- t_data.tm_min = strtol(token, NULL, 10);
-
- token = strtok(NULL, " "); /* "%S " */
-
- if (NULL == token) {
- return -1;
- }
-
- t_data.tm_sec = strtol(token, NULL, 10);
- }
-
-#else
- if (!strptime(date, MK_UTILS_GMT_DATEFORMAT, (struct tm*)&t_data)) {
- return -1;
- }
-#endif
-
- new_unix_time = timegm((struct tm *) &t_data);
-
- return (new_unix_time);
-}
-
-int mk_buffer_cat(mk_ptr_t *p, char *buf1, int len1, char *buf2, int len2)
-{
- /* Validate lengths */
- if (mk_unlikely(len1 < 0 || len2 < 0)) {
- return -1;
- }
-
- /* alloc space */
- p->data = (char *) mk_mem_alloc(len1 + len2 + 1);
-
- /* copy data */
- memcpy(p->data, buf1, len1);
- memcpy(p->data + len1, buf2, len2);
- p->data[len1 + len2] = '\0';
-
- /* assign len */
- p->len = len1 + len2;
-
- return 0;
-}
-
-/* Convert hexadecimal to int */
-int mk_utils_hex2int(char *hex, int len)
-{
- int i = 0;
- int res = 0;
- char c;
-
- while ((c = *hex++) && i < len) {
- res *= 0x10;
-
- if (c >= 'a' && c <= 'f') {
- res += (c - 0x57);
- }
- else if (c >= 'A' && c <= 'F') {
- res += (c - 0x37);
- }
- else if (c >= '0' && c <= '9') {
- res += (c - 0x30);
- }
- else {
- return -1;
- }
- i++;
- }
-
- if (res < 0) {
- return -1;
- }
-
- return res;
-}
-
-/* If the URI contains hexa format characters it will return
- * convert the Hexa values to ASCII character
- */
-char *mk_utils_url_decode(mk_ptr_t uri)
-{
- int tmp, hex_result;
- unsigned int i;
- int buf_idx = 0;
- char *buf;
- char hex[3];
-
- if ((tmp = mk_string_char_search(uri.data, '%', uri.len)) < 0) {
- return NULL;
- }
-
- i = tmp;
-
- buf = mk_mem_alloc_z(uri.len + 1);
- if (i > 0) {
- memcpy(buf, uri.data, i);
- buf_idx = i;
- }
-
- while (i < uri.len) {
- if (uri.data[i] == '%' && i + 2 < uri.len) {
- memcpy(hex, uri.data + i + 1, 2);
- hex[2] = '\0';
-
- hex_result = mk_utils_hex2int(hex, 2);
-
- if (hex_result != -1) {
- buf[buf_idx] = hex_result;
- }
- else {
- mk_mem_free(buf);
- return NULL;
- }
- i += 2;
- }
- else {
- buf[buf_idx] = uri.data[i];
- }
- i++;
- buf_idx++;
- }
- buf[buf_idx] = '\0';
-
- return buf;
-}
-
-#ifndef MK_HAVE_BACKTRACE
-void mk_utils_stacktrace(void) {}
-#else
-void mk_utils_stacktrace(void)
-{
- unsigned int i;
- int ret;
- size_t size;
- void *arr[10];
- Dl_info d;
-
- printf("[stack trace]\n");
- size = backtrace(arr, 10);
-
- for (i = 1; i < size && i < 10; i++) {
- ret = dladdr(arr[i], &d);
- if (ret == 0 || !d.dli_sname) {
- printf(" #%i 0x%016" PRIxPTR " in \?\?\?\?\?\?\?()\n",
- (i - 1), (uintptr_t) arr[i]);
- continue;
- }
-
- printf(" #%i 0x%016" PRIxPTR " in %s() from %s\n",
- (i - 1), (uintptr_t) arr[i], d.dli_sname, d.dli_fname);
- }
-}
-#endif
-
-
-
-/*
- * This hash generation function is taken originally from Redis source code:
- *
- * https://github.com/antirez/redis/blob/unstable/src/dict.c#L109
- *
- * ----
- * MurmurHash2, by Austin Appleby
- * Note - This code makes a few assumptions about how your machine behaves -
- * 1. We can read a 4-byte value from any address without crashing
- * 2. sizeof(int) == 4
- *
- * And it has a few limitations -
- *
- * 1. It will not work incrementally.
- * 2. It will not produce the same results on little-endian and big-endian
- * machines.
- */
-unsigned int mk_utils_gen_hash(const void *key, int len)
-{
- /* 'm' and 'r' are mixing constants generated offline.
- They're not really 'magic', they just happen to work well. */
- uint32_t seed = 5381;
- const uint32_t m = 0x5bd1e995;
- const int r = 24;
-
- /* Initialize the hash to a 'random' value */
- uint32_t h = seed ^ len;
-
- /* Mix 4 bytes at a time into the hash */
- const unsigned char *data = (const unsigned char *)key;
-
- while(len >= 4) {
- uint32_t k = *(uint32_t*) data;
-
- k *= m;
- k ^= k >> r;
- k *= m;
-
- h *= m;
- h ^= k;
-
- data += 4;
- len -= 4;
- }
-
- /* Handle the last few bytes of the input array */
- switch(len) {
- case 3: h ^= data[2] << 16; // fallthrough
- case 2: h ^= data[1] << 8; // fallthrough
- case 1: h ^= data[0]; h *= m;
- };
-
- /* Do a few final mixes of the hash to ensure the last few
- * bytes are well-incorporated. */
- h ^= h >> 13;
- h *= m;
- h ^= h >> 15;
-
- return (unsigned int) h;
-}
diff --git a/fluent-bit/lib/monkey/mk_server/mk_vhost.c b/fluent-bit/lib/monkey/mk_server/mk_vhost.c
deleted file mode 100644
index 2dc35fb1..00000000
--- a/fluent-bit/lib/monkey/mk_server/mk_vhost.c
+++ /dev/null
@@ -1,821 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-
-/* Monkey HTTP Server
- * ==================
- * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <monkey/mk_info.h>
-#include <monkey/monkey.h>
-#include <monkey/mk_core.h>
-#include <monkey/mk_vhost.h>
-#include <monkey/mk_vhost_tls.h>
-#include <monkey/mk_utils.h>
-#include <monkey/mk_http_status.h>
-#include <monkey/mk_info.h>
-
-#include <mk_core/mk_dirent.h>
-
-#include <re.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-static int str_to_regex(char *str, regex_t *reg)
-{
- char *p = str;
- regex_t *result;
-
- while (*p) {
- if (*p == ' ') *p = '|';
- p++;
- }
-
- result = re_compile(str);
-
- memcpy(reg, result, REGEXP_SIZE);
-
- return 0;
-}
-
-/*
- * This function is triggered upon thread creation (inside the thread
- * context), here we configure per-thread data.
- */
-int mk_vhost_fdt_worker_init(struct mk_server *server)
-{
- int i;
- int j;
- struct mk_vhost *h;
- struct mk_list *list;
- struct mk_list *head;
- struct vhost_fdt_host *fdt;
- struct vhost_fdt_hash_table *ht;
- struct vhost_fdt_hash_chain *hc;
-
- if (server->fdt == MK_FALSE) {
- return -1;
- }
-
- /*
- * We are under a thread context and the main configuration is
- * already in place. Now for every existent virtual host we are
- * going to create the File Descriptor Table (FDT) which aims to
- * hold references of 'open and shared' file descriptors under
- * the Virtual Host context.
- */
-
- /*
- * Under an initialization context we need to protect this critical
- * section
- */
- pthread_mutex_lock(&server->vhost_fdt_mutex);
-
- /*
- * Initialize the thread FDT/Hosts list and create an entry per
- * existent virtual host
- */
- list = mk_mem_alloc_z(sizeof(struct mk_list));
- mk_list_init(list);
-
- mk_list_foreach(head, &server->hosts) {
- h = mk_list_entry(head, struct mk_vhost, _head);
-
- fdt = mk_mem_alloc(sizeof(struct vhost_fdt_host));
- fdt->host = h;
-
- /* Initialize hash table */
- for (i = 0; i < VHOST_FDT_HASHTABLE_SIZE; i++) {
- ht = &fdt->hash_table[i];
- ht->av_slots = VHOST_FDT_HASHTABLE_CHAINS;
-
- /* for each chain under the hash table, set the fd */
- for (j = 0; j < VHOST_FDT_HASHTABLE_CHAINS; j++) {
- hc = &ht->chain[j];
- hc->fd = -1;
- hc->hash = 0;
- hc->readers = 0;
- }
- }
- mk_list_add(&fdt->_head, list);
- }
-
- MK_TLS_SET(mk_tls_vhost_fdt, list);
- pthread_mutex_unlock(&server->vhost_fdt_mutex);
-
- return 0;
-}
-
-int mk_vhost_fdt_worker_exit(struct mk_server *server)
-{
- struct mk_list *list;
- struct mk_list *head;
- struct mk_list *tmp;
- struct vhost_fdt_host *fdt;
-
- if (server->fdt == MK_FALSE) {
- return -1;
- }
-
- list = MK_TLS_GET(mk_tls_vhost_fdt);
- mk_list_foreach_safe(head, tmp, list) {
- fdt = mk_list_entry(head, struct vhost_fdt_host, _head);
- mk_list_del(&fdt->_head);
- mk_mem_free(fdt);
- }
-
- mk_mem_free(list);
- return 0;
-}
-
-
-static inline
-struct vhost_fdt_hash_table *mk_vhost_fdt_table_lookup(int id, struct mk_vhost *host)
-{
- struct mk_list *head;
- struct mk_list *list;
- struct vhost_fdt_host *fdt_host;
- struct vhost_fdt_hash_table *ht = NULL;
-
- list = MK_TLS_GET(mk_tls_vhost_fdt);
- mk_list_foreach(head, list) {
- fdt_host = mk_list_entry(head, struct vhost_fdt_host, _head);
- if (fdt_host->host == host) {
- ht = &fdt_host->hash_table[id];
- return ht;
- }
- }
-
- return ht;
-}
-
-static inline
-struct vhost_fdt_hash_chain
-*mk_vhost_fdt_chain_lookup(unsigned int hash, struct vhost_fdt_hash_table *ht)
-{
- int i;
- struct vhost_fdt_hash_chain *hc = NULL;
-
- for (i = 0; i < VHOST_FDT_HASHTABLE_CHAINS; i++) {
- hc = &ht->chain[i];
- if (hc->hash == hash) {
- return hc;
- }
- }
-
- return NULL;
-}
-
-
-static inline int mk_vhost_fdt_open(int id, unsigned int hash,
- struct mk_http_request *sr,
- struct mk_server *server)
-{
- int i;
- int fd = -1;
- struct vhost_fdt_hash_table *ht = NULL;
- struct vhost_fdt_hash_chain *hc;
-
- if (server->fdt == MK_FALSE) {
- return open(sr->real_path.data, sr->file_info.flags_read_only);
- }
-
- ht = mk_vhost_fdt_table_lookup(id, sr->host_conf);
- if (mk_unlikely(!ht)) {
- return open(sr->real_path.data, sr->file_info.flags_read_only);
- }
-
- /* We got the hash table, now look around the chains array */
- hc = mk_vhost_fdt_chain_lookup(hash, ht);
- if (hc) {
- /* Increment the readers and return the shared FD */
- hc->readers++;
- sr->vhost_fdt_id = id;
- sr->vhost_fdt_hash = hash;
- sr->vhost_fdt_enabled = MK_TRUE;
- return hc->fd;
- }
-
- /*
- * Get here means that no entry exists in the hash table for the
- * requested file descriptor and hash, we must try to open the file
- * and register the entry in the table.
- */
- fd = open(sr->real_path.data, sr->file_info.flags_read_only);
- if (fd == -1) {
- return -1;
- }
-
- /* If chains are full, just return the new FD, bad luck... */
- if (ht->av_slots <= 0) {
- return fd;
- }
-
- /* Register the new entry in an available slot */
- for (i = 0; i < VHOST_FDT_HASHTABLE_CHAINS; i++) {
- hc = &ht->chain[i];
- if (hc->fd == -1) {
- hc->fd = fd;
- hc->hash = hash;
- hc->readers++;
- ht->av_slots--;
-
- sr->vhost_fdt_id = id;
- sr->vhost_fdt_hash = hash;
- sr->vhost_fdt_enabled = MK_TRUE;
-
- return fd;
- }
- }
-
- return fd;
-}
-
-static inline int mk_vhost_fdt_close(struct mk_http_request *sr,
- struct mk_server *server)
-{
- int id;
- unsigned int hash;
- struct vhost_fdt_hash_table *ht = NULL;
- struct vhost_fdt_hash_chain *hc;
-
- if (server->fdt == MK_FALSE || sr->vhost_fdt_enabled == MK_FALSE) {
- if (sr->in_file.fd > 0) {
- return close(sr->in_file.fd);
- }
- return -1;
- }
-
- id = sr->vhost_fdt_id;
- hash = sr->vhost_fdt_hash;
-
- ht = mk_vhost_fdt_table_lookup(id, sr->host_conf);
- if (mk_unlikely(!ht)) {
- return close(sr->in_file.fd);
- }
-
- /* We got the hash table, now look around the chains array */
- hc = mk_vhost_fdt_chain_lookup(hash, ht);
- if (hc) {
- /* Increment the readers and check if we should close */
- hc->readers--;
- sr->vhost_fdt_enabled = MK_FALSE;
-
- if (hc->readers == 0) {
- hc->fd = -1;
- hc->hash = 0;
- ht->av_slots++;
- return close(sr->in_file.fd);
- }
- else {
- return 0;
- }
- }
- return close(sr->in_file.fd);
-}
-
-
-int mk_vhost_open(struct mk_http_request *sr, struct mk_server *server)
-{
- int id;
- int off;
- unsigned int hash;
-
- off = sr->host_conf->documentroot.len;
- hash = mk_utils_gen_hash(sr->real_path.data + off,
- sr->real_path.len - off);
- id = (hash % VHOST_FDT_HASHTABLE_SIZE);
-
- return mk_vhost_fdt_open(id, hash, sr, server);
-}
-
-int mk_vhost_close(struct mk_http_request *sr, struct mk_server *server)
-{
- return mk_vhost_fdt_close(sr, server);
-}
-
-struct mk_vhost_handler *mk_vhost_handler_match(char *match,
- void (*cb)(struct mk_http_request *,
- void *),
- void *data)
-{
- int ret;
- struct mk_vhost_handler *h;
-
- h = mk_mem_alloc(sizeof(struct mk_vhost_handler));
- if (!h) {
- return NULL;
- }
- h->name = NULL;
- h->cb = cb;
- h->data = data;
- h->match = mk_mem_alloc(REGEXP_SIZE);
- if (!h->match) {
- mk_mem_free(h);
- return NULL;
- }
- mk_list_init(&h->params);
-
- ret = str_to_regex(match, h->match);
- if (ret == -1) {
- mk_mem_free(h);
- return NULL;
- }
-
- return h;
-}
-
-/*
- * Open a virtual host configuration file and return a structure with
- * definitions.
- */
-struct mk_vhost *mk_vhost_read(char *path)
-{
- int ret;
- char *tmp;
- char *host_low;
- struct stat checkdir;
- struct mk_vhost *host;
- struct mk_vhost_alias *new_alias;
- struct mk_vhost_error_page *err_page;
- struct mk_rconf *cnf;
- struct mk_rconf_section *section_host;
- struct mk_rconf_section *section_ep;
- struct mk_rconf_section *section_handlers;
- struct mk_rconf_entry *entry_ep;
- struct mk_string_line *entry;
- struct mk_list *head, *list, *line;
- struct mk_vhost_handler *h_handler;
- struct mk_vhost_handler_param *h_param;
-
- /* Read configuration file */
- cnf = mk_rconf_open(path);
- if (!cnf) {
- mk_err("Configuration error, aborting.");
- exit(EXIT_FAILURE);
- }
-
- /* Read 'HOST' section */
- section_host = mk_rconf_section_get(cnf, "HOST");
- if (!section_host) {
- mk_err("Invalid config file %s", path);
- return NULL;
- }
-
- /* Alloc configuration node */
- host = mk_mem_alloc_z(sizeof(struct mk_vhost));
- host->config = cnf;
- host->file = mk_string_dup(path);
-
- /* Init list for host name aliases */
- mk_list_init(&host->server_names);
-
- /* Init list for custom error pages */
- mk_list_init(&host->error_pages);
-
- /* Init list for content handlers */
- mk_list_init(&host->handlers);
-
- /* Lookup Servername */
- list = mk_rconf_section_get_key(section_host, "Servername", MK_RCONF_LIST);
- if (!list) {
- mk_err("Hostname does not contain a Servername");
- exit(EXIT_FAILURE);
- }
-
- mk_list_foreach(head, list) {
- entry = mk_list_entry(head, struct mk_string_line, _head);
- if (entry->len > MK_HOSTNAME_LEN - 1) {
- continue;
- }
-
- /* Hostname to lowercase */
- host_low = mk_string_tolower(entry->val);
-
- /* Alloc node */
- new_alias = mk_mem_alloc_z(sizeof(struct mk_vhost_alias));
- new_alias->name = mk_mem_alloc_z(entry->len + 1);
- strncpy(new_alias->name, host_low, entry->len);
- mk_mem_free(host_low);
-
- new_alias->len = entry->len;
-
- mk_list_add(&new_alias->_head, &host->server_names);
- }
- mk_string_split_free(list);
-
- /* Lookup document root handled by a mk_ptr_t */
- host->documentroot.data = mk_rconf_section_get_key(section_host,
- "DocumentRoot",
- MK_RCONF_STR);
- if (!host->documentroot.data) {
- mk_err("Missing DocumentRoot entry on %s file", path);
- mk_rconf_free(cnf);
- mk_mem_free(host->file);
- mk_mem_free(host);
- return NULL;
- }
-
- host->documentroot.len = strlen(host->documentroot.data);
-
- /* Validate document root configured */
- if (stat(host->documentroot.data, &checkdir) == -1) {
- mk_err("Invalid path to DocumentRoot in %s", path);
- }
- else if (!(checkdir.st_mode & S_IFDIR)) {
- mk_err("DocumentRoot variable in %s has an invalid directory path", path);
- }
-
- if (mk_list_is_empty(&host->server_names) == 0) {
- mk_rconf_free(cnf);
- mk_mem_free(host->file);
- mk_mem_free(host);
- return NULL;
- }
-
- /* Check Virtual Host redirection */
- host->header_redirect.data = NULL;
- host->header_redirect.len = 0;
-
- tmp = mk_rconf_section_get_key(section_host,
- "Redirect",
- MK_RCONF_STR);
- if (tmp) {
- host->header_redirect.data = mk_string_dup(tmp);
- host->header_redirect.len = strlen(tmp);
- mk_mem_free(tmp);
- }
-
- /* Error Pages */
- section_ep = mk_rconf_section_get(cnf, "ERROR_PAGES");
- if (section_ep) {
- mk_list_foreach(head, &section_ep->entries) {
- entry_ep = mk_list_entry(head, struct mk_rconf_entry, _head);
-
- int ep_status = -1;
- char *ep_file = NULL;
- unsigned long len;
-
- ep_status = atoi(entry_ep->key);
- ep_file = entry_ep->val;
-
- /* Validate input values */
- if (ep_status < MK_CLIENT_BAD_REQUEST ||
- ep_status > MK_SERVER_HTTP_VERSION_UNSUP ||
- ep_file == NULL) {
- continue;
- }
-
- /* Alloc error page node */
- err_page = mk_mem_alloc_z(sizeof(struct mk_vhost_error_page));
- err_page->status = ep_status;
- err_page->file = mk_string_dup(ep_file);
- err_page->real_path = NULL;
- mk_string_build(&err_page->real_path, &len, "%s/%s",
- host->documentroot.data, err_page->file);
-
- MK_TRACE("Map error page: status %i -> %s", err_page->status, err_page->file);
-
- /* Link page to the error page list */
- mk_list_add(&err_page->_head, &host->error_pages);
- }
- }
-
- /* Handlers */
- int i;
- int params;
- struct mk_list *head_line;
-
- section_handlers = mk_rconf_section_get(cnf, "HANDLERS");
- if (!section_handlers) {
- return host;
- }
- mk_list_foreach(head, &section_handlers->entries) {
- entry_ep = mk_list_entry(head, struct mk_rconf_entry, _head);
- if (strncasecmp(entry_ep->key, "Match", strlen(entry_ep->key)) == 0) {
- line = mk_string_split_line(entry_ep->val);
- if (!line) {
- continue;
- }
- h_handler = mk_mem_alloc(sizeof(struct mk_vhost_handler));
- if (!h_handler) {
- exit(EXIT_FAILURE);
- }
- h_handler->match = mk_mem_alloc(REGEXP_SIZE);
- if (!h_handler->match) {
- mk_mem_free(h_handler);
- exit(EXIT_FAILURE);
- }
- h_handler->cb = NULL;
- mk_list_init(&h_handler->params);
-
- i = 0;
- params = 0;
- mk_list_foreach(head_line, line) {
- entry = mk_list_entry(head_line, struct mk_string_line, _head);
- switch (i) {
- case 0:
- ret = str_to_regex(entry->val, h_handler->match);
- if (ret == -1) {
- return NULL;
- }
- break;
- case 1:
- h_handler->name = mk_string_dup(entry->val);
- break;
- default:
- /* link parameters */
- h_param = mk_mem_alloc(sizeof(struct mk_vhost_handler_param));
- h_param->p.data = mk_string_dup(entry->val);
- h_param->p.len = entry->len;
- mk_list_add(&h_param->_head, &h_handler->params);
- params++;
- };
- i++;
- }
- h_handler->n_params = params;
- mk_string_split_free(line);
-
- if (i < 2) {
- mk_err("[Host Handlers] invalid Match value\n");
- exit(EXIT_FAILURE);
- }
- mk_list_add(&h_handler->_head, &host->handlers);
- }
- }
-
-
- return host;
-}
-
-int mk_vhost_map_handlers(struct mk_server *server)
-{
- int n = 0;
- struct mk_list *head;
- struct mk_list *head_handler;
- struct mk_vhost *host;
- struct mk_vhost_handler *h_handler;
- struct mk_plugin *p;
-
- mk_list_foreach(head, &server->hosts) {
- host = mk_list_entry(head, struct mk_vhost, _head);
- mk_list_foreach(head_handler, &host->handlers) {
- h_handler = mk_list_entry(head_handler,
- struct mk_vhost_handler, _head);
-
- /* Lookup plugin by name */
- p = mk_plugin_lookup(h_handler->name, server);
- if (!p) {
- mk_err("Plugin '%s' was not loaded", h_handler->name);
- continue;
- }
-
- if (p->hooks != MK_PLUGIN_STAGE) {
- mk_err("Plugin '%s' is not a handler", h_handler->name);
- continue;
- }
-
- h_handler->handler = p;
- n++;
- }
- }
-
- return n;
-}
-
-void mk_vhost_set_single(char *path, struct mk_server *server)
-{
- struct mk_vhost *host;
- struct mk_vhost_alias *halias;
- struct stat checkdir;
-
- /* Set the default host */
- host = mk_mem_alloc_z(sizeof(struct mk_vhost));
- mk_list_init(&host->error_pages);
- mk_list_init(&host->server_names);
-
- /* Prepare the unique alias */
- halias = mk_mem_alloc_z(sizeof(struct mk_vhost_alias));
- halias->name = mk_string_dup("127.0.0.1");
- mk_list_add(&halias->_head, &host->server_names);
-
- host->documentroot.data = mk_string_dup(path);
- host->documentroot.len = strlen(path);
- host->header_redirect.data = NULL;
-
- /* Validate document root configured */
- if (stat(host->documentroot.data, &checkdir) == -1) {
- mk_err("Invalid path to DocumentRoot in %s", path);
- exit(EXIT_FAILURE);
- }
- else if (!(checkdir.st_mode & S_IFDIR)) {
- mk_err("DocumentRoot variable in %s has an invalid directory path", path);
- exit(EXIT_FAILURE);
- }
- mk_list_add(&host->_head, &server->hosts);
- mk_list_init(&host->handlers);
-}
-
-/* Given a configuration directory, start reading the virtual host entries */
-void mk_vhost_init(char *path, struct mk_server *server)
-{
- DIR *dir;
- unsigned long len;
- char *buf = 0;
- char *sites = 0;
- char *file;
- struct mk_vhost *p_host; /* debug */
- struct dirent *ent;
- struct file_info f_info;
- int ret;
-
- if (!server->conf_sites) {
- mk_warn("[vhost] skipping default site");
- return;
- }
-
- /* Read default virtual host file */
- mk_string_build(&sites, &len, "%s/%s/",
- path, server->conf_sites);
- ret = mk_file_get_info(sites, &f_info, MK_FILE_EXISTS);
- if (ret == -1 || f_info.is_directory == MK_FALSE) {
- mk_mem_free(sites);
- sites = server->conf_sites;
- }
-
- mk_string_build(&buf, &len, "%s/default", sites);
-
- p_host = mk_vhost_read(buf);
- if (!p_host) {
- mk_err("Error parsing main configuration file 'default'");
- }
- mk_list_add(&p_host->_head, &server->hosts);
- server->nhosts++;
- mk_mem_free(buf);
- buf = NULL;
-
-
- /* Read all virtual hosts defined in sites/ */
- if (!(dir = opendir(sites))) {
- mk_mem_free(sites);
- mk_err("Could not open %s", sites);
- exit(EXIT_FAILURE);
- }
-
- /* Reading content */
- while ((ent = readdir(dir)) != NULL) {
- if (ent->d_name[0] == '.') {
- continue;
- }
- if (strcmp((char *) ent->d_name, "..") == 0) {
- continue;
- }
- if (ent->d_name[strlen(ent->d_name) - 1] == '~') {
- continue;
- }
- if (strcasecmp((char *) ent->d_name, "default") == 0) {
- continue;
- }
- file = NULL;
- mk_string_build(&file, &len, "%s/%s", sites, ent->d_name);
-
- p_host = mk_vhost_read(file);
- mk_mem_free(file);
- if (!p_host) {
- continue;
- }
- else {
- mk_list_add(&p_host->_head, &server->hosts);
- server->nhosts++;
- }
- }
- closedir(dir);
- mk_mem_free(sites);
-}
-
-
-/* Lookup a registered virtual host based on the given 'host' input */
-int mk_vhost_get(mk_ptr_t host, struct mk_vhost **vhost,
- struct mk_vhost_alias **alias,
- struct mk_server *server)
-{
- struct mk_vhost *entry_host;
- struct mk_vhost_alias *entry_alias;
- struct mk_list *head_vhost, *head_alias;
-
- mk_list_foreach(head_vhost, &server->hosts) {
- entry_host = mk_list_entry(head_vhost, struct mk_vhost, _head);
- mk_list_foreach(head_alias, &entry_host->server_names) {
- entry_alias = mk_list_entry(head_alias, struct mk_vhost_alias, _head);
- if (entry_alias->len == host.len &&
- strncmp(entry_alias->name, host.data, host.len) == 0) {
- *vhost = entry_host;
- *alias = entry_alias;
- return 0;
- }
- }
- }
-
- return -1;
-}
-
-static void mk_vhost_handler_free(struct mk_vhost_handler *h)
-{
- struct mk_list *tmp;
- struct mk_list *head;
- struct mk_vhost_handler_param *param;
-
- /* Release Params */
- mk_list_foreach_safe(head, tmp, &h->params) {
- param = mk_list_entry(head, struct mk_vhost_handler_param, _head);
- mk_list_del(&param->_head);
- mk_mem_free(param->p.data);
- mk_mem_free(param);
- }
-
- mk_mem_free(h->match);
- mk_mem_free(h->name);
- mk_mem_free(h);
-}
-
-int mk_vhost_destroy(struct mk_vhost *vh)
-{
- struct mk_vhost_alias *halias = NULL;
- struct mk_vhost_handler *hhandler;
- struct mk_vhost_error_page *ep;
- struct mk_list *head;
- struct mk_list *tmp;
-
- if (vh) {
- /* Free aliases or servernames */
- mk_list_foreach_safe(head, tmp, &vh->server_names) {
- halias = mk_list_entry(head, struct mk_vhost_alias, _head);
- if (halias) {
- mk_list_del(&halias->_head);
- if (halias->name) {
- mk_mem_free(halias->name);
- }
- mk_mem_free(halias);
- }
- }
-
- /* Handlers */
- mk_list_foreach_safe(head, tmp, &vh->handlers) {
- hhandler = mk_list_entry(head, struct mk_vhost_handler, _head);
- if (hhandler) {
- mk_vhost_handler_free(hhandler);
- }
- }
-
- /* Free error pages */
- mk_list_foreach_safe(head, tmp, &vh->error_pages) {
- ep = mk_list_entry(head, struct mk_vhost_error_page, _head);
- if (ep) {
- mk_list_del(&ep->_head);
- if (ep->file) {
- mk_mem_free(ep->file);
- }
- if (ep->real_path) {
- mk_mem_free(ep->real_path);
- }
- mk_mem_free(ep);
- }
- }
- mk_ptr_free(&vh->documentroot);
-
- /* Free source configuration */
- if (vh->config) {
- mk_rconf_free(vh->config);
- }
- mk_list_del(&vh->_head);
- if (vh->file) {
- mk_mem_free(vh->file);
- }
-
- mk_mem_free(vh);
- }
- return 0;
-}
-
-void mk_vhost_free_all(struct mk_server *server)
-{
- struct mk_vhost *host;
- struct mk_list *head;
- struct mk_list *tmp;
-
- mk_list_foreach_safe(head, tmp, &server->hosts) {
- host = mk_list_entry(head, struct mk_vhost, _head);
- mk_vhost_destroy(host);
- }
-}
diff --git a/fluent-bit/lib/monkey/mk_server/monkey.c b/fluent-bit/lib/monkey/mk_server/monkey.c
deleted file mode 100644
index 68513d21..00000000
--- a/fluent-bit/lib/monkey/mk_server/monkey.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-
-/* Monkey HTTP Server
- * ==================
- * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define _GNU_SOURCE
-
-#include <mk_core/mk_pthread.h>
-#include <mk_core/mk_event.h>
-
-#include <monkey/mk_scheduler.h>
-#include <monkey/mk_plugin.h>
-#include <monkey/mk_clock.h>
-#include <monkey/mk_thread.h>
-#include <monkey/mk_mimetype.h>
-#include <monkey/mk_http_thread.h>
-
-pthread_once_t mk_server_tls_setup_once = PTHREAD_ONCE_INIT;
-
-static void mk_set_up_tls_keys()
-{
- MK_INIT_INITIALIZE_TLS_UNIVERSAL();
- MK_INIT_INITIALIZE_TLS();
-
- mk_http_thread_initialize_tls();
-}
-
-void mk_server_info(struct mk_server *server)
-{
- struct mk_list *head;
- struct mk_plugin *p;
- struct mk_config_listener *l;
-
-#ifdef _WIN32
- printf(MK_BANNER_ENTRY "Process ID is %ld\n", (long)GetCurrentProcessId());
-#else
- printf(MK_BANNER_ENTRY "Process ID is %ld\n", (long) getpid());
-#endif
- mk_list_foreach(head, &server->listeners) {
- l = mk_list_entry(head, struct mk_config_listener, _head);
- printf(MK_BANNER_ENTRY "Server listening on %s:%s\n",
- l->address, l->port);
- }
- printf(MK_BANNER_ENTRY
- "%i threads, may handle up to %i client connections\n",
- server->workers, server->server_capacity);
-
- /* List loaded plugins */
- printf(MK_BANNER_ENTRY "Loaded Plugins: ");
- mk_list_foreach(head, &server->plugins) {
- p = mk_list_entry(head, struct mk_plugin, _head);
- printf("%s ", p->shortname);
- }
- printf("\n");
-
-#ifdef __linux__
- char tmp[64];
-
- if (mk_kernel_features_print(tmp, sizeof(tmp), server) > 0) {
- printf(MK_BANNER_ENTRY "Linux Features: %s\n", tmp);
- }
-#endif
-
- fflush(stdout);
-}
-
-/* Initialize Monkey Server */
-struct mk_server *mk_server_create()
-{
- int ret;
- int kern_version;
- int kern_features;
- struct mk_server *server;
-
- server = mk_mem_alloc_z(sizeof(struct mk_server));
- if (!server) {
- return NULL;
- }
-
- /* I'll try to leave both initializations here because
- * it should be possible to run in windows using the accept
- * backend in which case it doesn't make sense to tie the net stack
- * initialization to libevent.
- */
- mk_net_init();
- mk_event_init();
-
- /* Library mode: event loop */
- server->lib_mode = MK_TRUE;
- server->lib_evl = mk_event_loop_create(8);
- if (!server->lib_evl) {
- mk_mem_free(server);
- return NULL;
- }
-
- /* Library mode: channel manager */
-
- memset(&server->lib_ch_event, 0, sizeof(struct mk_event));
-
- ret = mk_event_channel_create(server->lib_evl,
- &server->lib_ch_manager[0],
- &server->lib_ch_manager[1],
- &server->lib_ch_event);
-
- if (ret != 0) {
- mk_event_loop_destroy(server->lib_evl);
- mk_mem_free(server);
- return NULL;
- }
-
- /* Library mode: start event loop */
- server->lib_evl_start = mk_event_loop_create(1);
- if (!server->lib_evl_start) {
- mk_event_loop_destroy(server->lib_evl);
- mk_mem_free(server);
- return NULL;
- }
-
- memset(&server->lib_ch_start_event, 0, sizeof(struct mk_event));
-
- ret = mk_event_channel_create(server->lib_evl_start,
- &server->lib_ch_start[0],
- &server->lib_ch_start[1],
- &server->lib_ch_start_event);
-
- if (ret != 0) {
- mk_event_loop_destroy(server->lib_evl);
- mk_event_loop_destroy(server->lib_evl_start);
- mk_mem_free(server);
- return NULL;
- }
-
- /* Initialize linked list heads */
- mk_list_init(&server->plugins);
- mk_list_init(&server->sched_worker_callbacks);
- mk_list_init(&server->stage10_handler);
- mk_list_init(&server->stage20_handler);
- mk_list_init(&server->stage30_handler);
- mk_list_init(&server->stage40_handler);
- mk_list_init(&server->stage50_handler);
- server->scheduler_mode = -1;
-
- mk_core_init();
-
- /* Init thread keys */
- pthread_once(&mk_server_tls_setup_once, mk_set_up_tls_keys);
-
- /* Init Kernel version data */
- kern_version = mk_kernel_version();
- kern_features = mk_kernel_features(kern_version);
-
- server->kernel_version = kern_version;
- server->kernel_features = kern_features;
-
-#ifdef MK_HAVE_TRACE
- MK_TRACE("Monkey TRACE is enabled");
- //pthread_mutex_init(&mutex_trace, (pthread_mutexattr_t *) NULL);
-#endif
-
-#ifdef LINUX_TRACE
- mk_info("Linux Trace enabled");
-#endif
-
- mk_config_set_init_values(server);
-
- mk_mimetype_init(server);
-
- pthread_mutex_init(&server->vhost_fdt_mutex, NULL);
-
- return server;
-}
-
-int mk_server_setup(struct mk_server *server)
-{
- int ret;
- pthread_t tid;
-
- /* Core and Scheduler setup */
- mk_config_start_configure(server);
- mk_config_signature(server);
-
- mk_sched_init(server);
-
-
- /* Clock init that must happen before starting threads */
- mk_clock_sequential_init(server);
-
- /* Load plugins */
- mk_plugin_api_init(server);
- mk_plugin_load_all(server);
-
- /* Workers: logger and clock */
- ret = mk_utils_worker_spawn((void *) mk_clock_worker_init, server, &tid);
- if (ret != 0) {
- return -1;
- }
-
- /* Configuration sanity check */
- mk_config_sanity_check(server);
-
- /* Invoke Plugin PRCTX hooks */
- mk_plugin_core_process(server);
-
- /* Launch monkey http workers */
- mk_server_launch_workers(server);
-
- return 0;
-}
-
-void mk_exit_all(struct mk_server *server)
-{
- uint64_t val;
-
- /* Distribute worker signals to stop working */
- val = MK_SCHED_SIGNAL_FREE_ALL;
- mk_sched_broadcast_signal(server, val);
-
- /* Wait for all workers to finish */
- mk_sched_workers_join(server);
-
- /* Continue exiting */
- mk_plugin_exit_all(server);
- mk_clock_exit(server);
-
- mk_sched_exit(server);
- mk_config_free_all(server);
-}