summaryrefslogtreecommitdiffstats
path: root/src/fluent-bit/lib/monkey/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/fluent-bit/lib/monkey/include')
-rw-r--r--src/fluent-bit/lib/monkey/include/CMakeLists.txt11
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_api.h102
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_cache.h26
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_cache_tls.h40
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_clock.h59
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_config.h227
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core.h69
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/external/dirent.h1027
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/external/wingetopt.h282
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/external/winpthreads.h340
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/external/winuio.h54
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_core_info.h.in26
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_dep_unistd.h56
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_dirent.h31
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_event.h156
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_event_epoll.h44
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_event_kqueue.h72
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_event_libevent.h45
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_event_select.h59
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_file.h48
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_getopt.h31
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_iov.h127
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_limits.h32
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_list.h244
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_macros.h184
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_memory.h125
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_pipe.h32
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_pthread.h31
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_rconf.h92
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_sleep.h59
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_string.h97
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_thread.h47
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_thread_channel.h127
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_uio.h13
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_unistd.h31
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_utils.h115
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_env.h.in26
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_fifo.h97
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_header.h113
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_http.h225
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_http2.h182
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_http2_settings.h71
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_http_internal.h197
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_http_parser.h348
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_http_status.h84
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_http_thread.h61
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_info.h.in45
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_kernel.h35
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_lib.h76
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_linuxtrace.h80
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_mimetype.h45
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_net.h40
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_plugin.h384
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_plugin_net.h40
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_plugin_stage.h99
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_scheduler.h353
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_scheduler_tls.h39
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_server.h75
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_server_tls.h34
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_socket.h85
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_static_plugins.h.in69
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_stream.h398
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_thread.h25
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_thread_libco.h123
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_thread_ucontext.h129
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_tls.h110
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_user.h35
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_utils.h54
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_vhost.h123
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/mk_vhost_tls.h38
-rw-r--r--src/fluent-bit/lib/monkey/include/monkey/monkey.h72
71 files changed, 8171 insertions, 0 deletions
diff --git a/src/fluent-bit/lib/monkey/include/CMakeLists.txt b/src/fluent-bit/lib/monkey/include/CMakeLists.txt
new file mode 100644
index 000000000..78af01bcc
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/CMakeLists.txt
@@ -0,0 +1,11 @@
+# MK_CORE
+if(NOT WITHOUT_HEADERS)
+ install(FILES "mk_core.h"
+ DESTINATION include/
+ PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
+
+ file(GLOB headers "mk_core/*.h")
+ install(FILES ${headers}
+ DESTINATION include/mk_core
+ PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
+endif()
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_api.h b/src/fluent-bit/lib/monkey/include/monkey/mk_api.h
new file mode 100644
index 000000000..fa5489cfe
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_api.h
@@ -0,0 +1,102 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/* Monkey HTTP Server
+ * ------------------
+ * Copyright (C) 2001-2015, Eduardo Silva P. <edsiper@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef MONKEY_PLUGIN_API_H
+#define MONKEY_PLUGIN_API_H
+
+#define _GNU_SOURCE
+
+/* Monkey Headers */
+#include <monkey/monkey.h>
+#include <monkey/mk_socket.h>
+#include <monkey/mk_plugin.h>
+#include <monkey/mk_vhost.h>
+#include <monkey/mk_http.h>
+#include <monkey/mk_socket.h>
+#include <monkey/mk_kernel.h>
+#include <monkey/mk_core.h>
+
+/* General Headers */
+#include <errno.h>
+
+/* global vars */
+struct plugin_api *mk_api;
+
+pthread_key_t MK_EXPORT _mkp_data;
+
+#define MONKEY_PLUGIN(a, b, c, d) \
+ struct mk_plugin_info MK_EXPORT _plugin_info = {a, b, c, d}
+
+#ifdef MK_TRACE
+#undef MK_TRACE
+#endif
+
+#ifdef TRACE
+
+#define MK_TRACE(api, ...) \
+ api->trace("pl", \
+ MK_TRACE_PLUGIN, \
+ __FUNCTION__, \
+ __FILENAME__, \
+ __LINE__, \
+ __VA_ARGS__)
+#define PLUGIN_TRACE MK_TRACE
+#else
+#define MK_TRACE(...) do {} while(0)
+#define PLUGIN_TRACE(...) do{} while(0)
+#endif
+
+/*
+ * Redefine messages macros
+ */
+
+#undef mk_info_ex
+#define mk_info_ex(api, ...) api->_error(MK_INFO, __VA_ARGS__)
+
+#undef mk_err_ex
+#define mk_err_ex(api, ...) api->_error(MK_ERR, __VA_ARGS__)
+
+#undef mk_warn_ex
+#define mk_warn_ex(api, ...) api->_error(MK_WARN, __VA_ARGS__)
+
+#undef mk_bug_ex
+#define mk_bug_ex(api, condition) do { \
+ if (mk_unlikely((condition)!=0)) { \
+ api->_error(MK_BUG, "[%s] Bug found in %s() at %s:%d", \
+ _plugin_info.shortname, __FUNCTION__, __FILE__, __LINE__); \
+ abort(); \
+ } \
+ } while(0)
+
+#undef mk_info
+#define mk_info(...) mk_info_ex(mk_api, __VA_ARGS__)
+
+#undef mk_err
+#define mk_err(...) mk_error_ex(mk_api, __VA_ARGS__)
+
+#undef mk_warn
+#define mk_warn(...) mk_error_ex(mk_api, __VA_ARGS__)
+
+#undef mk_bug
+#define mk_bug(condition) mk_bug_ex(mk_api, condition)
+
+#endif
+
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_cache.h b/src/fluent-bit/lib/monkey/include/monkey/mk_cache.h
new file mode 100644
index 000000000..40c2f83c3
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_cache.h
@@ -0,0 +1,26 @@
+/* -*- 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.
+ */
+
+#ifndef MK_CACHE_H
+#define MK_CACHE_H
+
+void mk_cache_worker_init();
+void mk_cache_worker_exit();
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_cache_tls.h b/src/fluent-bit/lib/monkey/include/monkey/mk_cache_tls.h
new file mode 100644
index 000000000..be3cbf98a
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_cache_tls.h
@@ -0,0 +1,40 @@
+/* -*- 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.
+ */
+
+#ifndef MK_CACHE_TLS_H
+#define MK_CACHE_TLS_H
+
+#ifdef MK_HAVE_C_TLS /* Use Compiler Thread Local Storage (TLS) */
+
+__thread mk_ptr_t *mk_tls_cache_header_cl;
+__thread mk_ptr_t *mk_tls_cache_header_lm;
+__thread struct tm *mk_tls_cache_gmtime;
+__thread struct mk_gmt_cache *mk_tls_cache_gmtext;
+
+#else
+
+pthread_key_t mk_tls_cache_iov_header;
+pthread_key_t mk_tls_cache_header_cl;
+pthread_key_t mk_tls_cache_header_lm;
+pthread_key_t mk_tls_cache_gmtime;
+pthread_key_t mk_tls_cache_gmtext;
+
+#endif /* MK_HACE_C_TLS */
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_clock.h b/src/fluent-bit/lib/monkey/include/monkey/mk_clock.h
new file mode 100644
index 000000000..814f39651
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_clock.h
@@ -0,0 +1,59 @@
+/* -*- 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.
+ */
+
+/* clock.h */
+
+#ifndef MK_CLOCK_H
+#define MK_CLOCK_H
+
+#include <time.h>
+#include <monkey/mk_core.h>
+
+extern time_t log_current_utime;
+extern time_t monkey_init_time;
+
+extern mk_ptr_t log_current_time;
+extern mk_ptr_t headers_preset;
+
+#define MK_CLOCK_GMT_DATEFORMAT "Date: %a, %d %b %Y %H:%M:%S GMT\r\n"
+#define HEADER_PRESET_SIZE 128
+#define HEADER_TIME_BUFFER_SIZE 64
+#define LOG_TIME_BUFFER_SIZE 30
+
+struct mk_server;
+
+struct mk_clock_context {
+ pthread_t mk_clock_tid;
+
+ time_t log_current_utime;
+ time_t monkey_init_time;
+
+ mk_ptr_t log_current_time;
+ mk_ptr_t headers_preset;
+
+ char *log_time_buffers[2];
+ char *header_time_buffers[2];
+};
+
+void *mk_clock_worker_init(void *args);
+void mk_clock_set_time(void);
+void mk_clock_sequential_init(struct mk_server *server);
+void mk_clock_exit(struct mk_server *server);
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_config.h b/src/fluent-bit/lib/monkey/include/monkey/mk_config.h
new file mode 100644
index 000000000..f65528153
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_config.h
@@ -0,0 +1,227 @@
+/* -*- 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.
+ */
+
+#ifndef MK_CONFIG_H
+#define MK_CONFIG_H
+
+#define _GNU_SOURCE
+#include <monkey/mk_core.h>
+
+#include <monkey/mk_info.h>
+#include "../../deps/rbtree/rbtree.h"
+
+#ifdef _WIN32
+typedef uint32_t mode_t;
+typedef uint32_t uid_t;
+typedef uint32_t gid_t;
+#endif
+
+#ifndef O_NOATIME
+#define O_NOATIME 01000000
+#endif
+
+#define MK_DEFAULT_CONFIG_FILE "monkey.conf"
+#define MK_DEFAULT_MIMES_CONF_FILE "monkey.mime"
+#define MK_DEFAULT_PLUGIN_LOAD_CONF_FILE "plugins.load"
+#define MK_DEFAULT_SITES_CONF_DIR "sites/"
+#define MK_DEFAULT_PLUGINS_CONF_DIR "plugins/"
+#define MK_DEFAULT_LISTEN_ADDR "0.0.0.0"
+#define MK_DEFAULT_LISTEN_PORT "2001"
+#define MK_WORKERS_DEFAULT 1
+
+/* Core capabilities, used as identifiers to match plugins */
+#define MK_CAP_HTTP 1
+
+/* HTTP/2: only if enabled */
+#ifdef MK_HAVE_HTTP2
+#define MK_CAP_HTTP2 2
+#endif
+
+#define MK_CAP_SOCK_PLAIN 4
+#define MK_CAP_SOCK_TLS 8
+
+struct plugin_api;
+struct mk_clock_context;
+
+struct mk_config_listener
+{
+ char *address; /* address to bind */
+ char *port; /* TCP port */
+ uint32_t flags; /* properties: http | http2 | ssl */
+ struct mk_list _head;
+};
+
+/* Base struct of server */
+struct mk_server
+{
+ int server_fd; /* server socket file descriptor */
+ int kernel_version; /* Running Linux Kernel version */
+ int kernel_features; /* Hold different server setup status */
+ int fd_limit; /* Limit of file descriptors */
+ unsigned int server_capacity; /* total server capacity */
+ short int workers; /* number of worker threads */
+ short int manual_tcp_cork; /* If enabled it will handle TCP_CORK */
+
+ int8_t fdt; /* is FDT enabled ? */
+ int8_t is_daemon;
+ int8_t is_seteuid;
+ int8_t scheduler_mode; /* Scheduler balancing mode */
+
+ /* Configuration paths (absolute paths) */
+ char *path_conf_root; /* absolute path to configuration files */
+ char *path_conf_pidfile; /* absolute path to PID file */
+
+ /* Specific names for configuration files or directories */
+ char *conf_mimetype; /* mimetype file name */
+ char *conf_main; /* name of main configuration file */
+ char *conf_sites; /* directory name for virtual host files */
+ char *conf_plugin_load; /* file name which load dynamic plugins */
+ char *conf_plugins; /* directory name for plugins conf files */
+ char *conf_user_pub; /* directory name for users public content */
+
+ mk_ptr_t server_software;
+
+ struct mk_list listeners;
+
+ char *one_shot;
+ char *port_override;
+ char *user;
+ char **request_headers_allowed;
+
+ int timeout; /* max time to wait for a new connection */
+ int standard_port; /* common port used in web servers (80) */
+ int pid_status;
+ int8_t hideversion; /* hide version of server to clients ? */
+ int8_t resume; /* Resume (on/off) */
+ int8_t symlink; /* symbolic links */
+
+ /* keep alive */
+ int8_t keep_alive; /* it's a persisten connection ? */
+ int max_keep_alive_request; /* max persistent connections to allow */
+ int keep_alive_timeout; /* persistent connection timeout */
+
+ /* counter of threads working */
+ int thread_counter;
+
+ /* real user */
+ uid_t egid;
+ gid_t euid;
+
+ int max_request_size;
+
+ struct mk_list *index_files;
+
+ /* configured host quantity */
+ int nhosts;
+ struct mk_list hosts;
+
+ mode_t open_flags;
+ struct mk_list plugins;
+
+ /* Safe EPOLLOUT event */
+ int safe_event_write;
+
+ /*
+ * Optional reference to force a specific transport, this one
+ * is used when overriding the configuration from some caller
+ */
+ char *transport_layer;
+
+ /* Define the default mime type when is not possible to find the proper one */
+ struct mk_list mimetype_list;
+ struct rb_tree mimetype_rb_head;
+ void *mimetype_default;
+ char *mimetype_default_str;
+
+ char server_signature[16];
+ char server_signature_header[32];
+ int server_signature_header_len;
+
+ /* Library mode */
+ int lib_mode; /* is running in Library mode ? */
+
+ int lib_ch_manager[2]; /* lib channel manager */
+ struct mk_event_loop *lib_evl; /* lib event loop */
+ struct mk_event lib_ch_event; /* lib channel manager event ? */
+ int lib_ch_start[2]; /* lib start signal channel */
+ struct mk_event_loop *lib_evl_start; /* lib start event loop */
+ struct mk_event lib_ch_start_event; /* lib start event */
+
+ /* Scheduler context (struct mk_sched_ctx) */
+ void *sched_ctx;
+
+ /*
+ * This list head, allow to link a set of callbacks that Monkey core
+ * must invoke inside each thread worker once created. This list is
+ * populated from mk_lib.c:mk_config_worker_callback(..).
+ */
+ struct mk_list sched_worker_callbacks;
+
+ /* source configuration from files */
+ struct mk_rconf *config;
+
+ /* FIXME: temporal map of Network Layer plugin */
+ struct mk_plugin_network *network;
+
+ /* Thread initializator helpers (sched_launch_thread) */
+ int pth_init;
+ pthread_cond_t pth_cond;
+ pthread_mutex_t pth_mutex;
+
+ /* Used for vhost initialization synchronization */
+ pthread_mutex_t vhost_fdt_mutex;
+
+ /* worker_id as used by mk_sched_register_thread, it was moved here
+ * because it has to be local to each mk_server instance.
+ */
+ int worker_id;
+
+ struct plugin_api *api;
+ struct mk_clock_context *clock_context;
+
+ /* Direct map to Stage plugins */
+ struct mk_list stage10_handler;
+ struct mk_list stage20_handler;
+ struct mk_list stage30_handler;
+ struct mk_list stage40_handler;
+ struct mk_list stage50_handler;
+};
+
+/* Functions */
+struct mk_server_config *mk_config_init();
+void mk_config_start_configure(struct mk_server *server);
+void mk_config_signature(struct mk_server *server);
+void mk_config_add_index(char *indexname);
+void mk_config_set_init_values(struct mk_server *config);
+int mk_config_listen_parse(char *value, struct mk_server *server);
+
+/* config helpers */
+void mk_config_error(const char *path, int line, const char *msg);
+struct mk_config_listener *mk_config_listener_add(char *address,
+ char *port, int flags,
+ struct mk_server *server);
+int mk_config_listen_check_busy(struct mk_server *server);
+void mk_config_listeners_free(struct mk_server *server);
+
+int mk_config_get_bool(char *value);
+void mk_config_read_hosts(char *path);
+void mk_config_sanity_check(struct mk_server *server);
+void mk_config_free_all(struct mk_server *server);
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core.h
new file mode 100644
index 000000000..b8068739d
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core.h
@@ -0,0 +1,69 @@
+/* -*- 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.
+ */
+
+#ifndef MK_CORE_H
+#define MK_CORE_H
+
+#ifdef __cplusplus /* If this is a C++ compiler, use C linkage */
+extern "C" {
+#endif
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <sys/types.h>
+
+#include <mk_core/mk_core_info.h>
+#include "mk_core/mk_pthread.h"
+#include "mk_core/mk_iov.h"
+#include "mk_core/mk_uio.h"
+#include "mk_core/mk_list.h"
+#include "mk_core/mk_pthread.h"
+#include "mk_core/mk_unistd.h"
+
+/* WIN32 */
+#ifdef _WIN32
+/* Posix function name deprecation warning */
+#pragma warning(disable : 4996)
+/* Type casting issues, only disabled momentarily*/
+#pragma warning(disable : 4244)
+#pragma warning(disable : 4267)
+#pragma warning(disable : 4133)
+#endif
+
+#include "mk_core/mk_getopt.h"
+#include "mk_core/mk_pipe.h"
+#include "mk_core/mk_sleep.h"
+/* --- end --- */
+
+#include "mk_core/mk_memory.h"
+#include "mk_core/mk_file.h"
+#include "mk_core/mk_event.h"
+#include "mk_core/mk_rconf.h"
+#include "mk_core/mk_string.h"
+#include "mk_core/mk_macros.h"
+#include "mk_core/mk_utils.h"
+#include "mk_core/mk_unistd.h"
+
+#ifdef __cplusplus /* If this is a C++ compiler, use C linkage */
+}
+#endif
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/external/dirent.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core/external/dirent.h
new file mode 100644
index 000000000..ffa4761bd
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/external/dirent.h
@@ -0,0 +1,1027 @@
+/*
+ * Dirent interface for Microsoft Visual Studio
+ *
+ * Copyright (C) 1998-2019 Toni Ronkko
+ * This file is part of dirent. Dirent may be freely distributed
+ * under the MIT license. For all details and documentation, see
+ * https://github.com/tronkko/dirent
+ */
+#ifndef DIRENT_H
+#define DIRENT_H
+
+/* Hide warnings about unreferenced local functions */
+#if defined(__clang__)
+# pragma clang diagnostic ignored "-Wunused-function"
+#elif defined(_MSC_VER)
+# pragma warning(disable:4505)
+#elif defined(__GNUC__)
+# pragma GCC diagnostic ignored "-Wunused-function"
+#endif
+
+/*
+ * Include windows.h without Windows Sockets 1.1 to prevent conflicts with
+ * Windows Sockets 2.0.
+ */
+#ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <wchar.h>
+#include <string.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <ctype.h>
+
+/* Indicates that d_type field is available in dirent structure */
+#define _DIRENT_HAVE_D_TYPE
+
+/* Indicates that d_namlen field is available in dirent structure */
+#define _DIRENT_HAVE_D_NAMLEN
+
+/* Entries missing from MSVC 6.0 */
+#if !defined(FILE_ATTRIBUTE_DEVICE)
+# define FILE_ATTRIBUTE_DEVICE 0x40
+#endif
+
+/* File type and permission flags for stat(), general mask */
+#if !defined(S_IFMT)
+# define S_IFMT _S_IFMT
+#endif
+
+/* Directory bit */
+#if !defined(S_IFDIR)
+# define S_IFDIR _S_IFDIR
+#endif
+
+/* Character device bit */
+#if !defined(S_IFCHR)
+# define S_IFCHR _S_IFCHR
+#endif
+
+/* Pipe bit */
+#if !defined(S_IFFIFO)
+# define S_IFFIFO _S_IFFIFO
+#endif
+
+/* Regular file bit */
+#if !defined(S_IFREG)
+# define S_IFREG _S_IFREG
+#endif
+
+/* Read permission */
+#if !defined(S_IREAD)
+# define S_IREAD _S_IREAD
+#endif
+
+/* Write permission */
+#if !defined(S_IWRITE)
+# define S_IWRITE _S_IWRITE
+#endif
+
+/* Execute permission */
+#if !defined(S_IEXEC)
+# define S_IEXEC _S_IEXEC
+#endif
+
+/* Pipe */
+#if !defined(S_IFIFO)
+# define S_IFIFO _S_IFIFO
+#endif
+
+/* Block device */
+#if !defined(S_IFBLK)
+# define S_IFBLK 0
+#endif
+
+/* Link */
+#if !defined(S_IFLNK)
+# define S_IFLNK 0
+#endif
+
+/* Socket */
+#if !defined(S_IFSOCK)
+# define S_IFSOCK 0
+#endif
+
+/* Read user permission */
+#if !defined(S_IRUSR)
+# define S_IRUSR S_IREAD
+#endif
+
+/* Write user permission */
+#if !defined(S_IWUSR)
+# define S_IWUSR S_IWRITE
+#endif
+
+/* Execute user permission */
+#if !defined(S_IXUSR)
+# define S_IXUSR 0
+#endif
+
+/* Read group permission */
+#if !defined(S_IRGRP)
+# define S_IRGRP 0
+#endif
+
+/* Write group permission */
+#if !defined(S_IWGRP)
+# define S_IWGRP 0
+#endif
+
+/* Execute group permission */
+#if !defined(S_IXGRP)
+# define S_IXGRP 0
+#endif
+
+/* Read others permission */
+#if !defined(S_IROTH)
+# define S_IROTH 0
+#endif
+
+/* Write others permission */
+#if !defined(S_IWOTH)
+# define S_IWOTH 0
+#endif
+
+/* Execute others permission */
+#if !defined(S_IXOTH)
+# define S_IXOTH 0
+#endif
+
+/* Maximum length of file name */
+#if !defined(PATH_MAX)
+# define PATH_MAX MAX_PATH
+#endif
+#if !defined(FILENAME_MAX)
+# define FILENAME_MAX MAX_PATH
+#endif
+#if !defined(NAME_MAX)
+# define NAME_MAX FILENAME_MAX
+#endif
+
+/* File type flags for d_type */
+#define DT_UNKNOWN 0
+#define DT_REG S_IFREG
+#define DT_DIR S_IFDIR
+#define DT_FIFO S_IFIFO
+#define DT_SOCK S_IFSOCK
+#define DT_CHR S_IFCHR
+#define DT_BLK S_IFBLK
+#define DT_LNK S_IFLNK
+
+/* Macros for converting between st_mode and d_type */
+#define IFTODT(mode) ((mode) & S_IFMT)
+#define DTTOIF(type) (type)
+
+/*
+ * File type macros. Note that block devices, sockets and links cannot be
+ * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are
+ * only defined for compatibility. These macros should always return false
+ * on Windows.
+ */
+#if !defined(S_ISFIFO)
+# define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
+#endif
+#if !defined(S_ISDIR)
+# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
+#endif
+#if !defined(S_ISREG)
+# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
+#endif
+#if !defined(S_ISLNK)
+# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
+#endif
+#if !defined(S_ISSOCK)
+# define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
+#endif
+#if !defined(S_ISCHR)
+# define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
+#endif
+#if !defined(S_ISBLK)
+# define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
+#endif
+
+/* Return the exact length of the file name without zero terminator */
+#define _D_EXACT_NAMLEN(p) ((p)->d_namlen)
+
+/* Return the maximum size of a file name */
+#define _D_ALLOC_NAMLEN(p) ((PATH_MAX)+1)
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Wide-character version */
+struct _wdirent {
+ /* Always zero */
+ long d_ino;
+
+ /* File position within stream */
+ long d_off;
+
+ /* Structure size */
+ unsigned short d_reclen;
+
+ /* Length of name without \0 */
+ size_t d_namlen;
+
+ /* File type */
+ int d_type;
+
+ /* File name */
+ wchar_t d_name[PATH_MAX+1];
+};
+typedef struct _wdirent _wdirent;
+
+struct _WDIR {
+ /* Current directory entry */
+ struct _wdirent ent;
+
+ /* Private file data */
+ WIN32_FIND_DATAW data;
+
+ /* True if data is valid */
+ int cached;
+
+ /* Win32 search handle */
+ HANDLE handle;
+
+ /* Initial directory name */
+ wchar_t *patt;
+};
+typedef struct _WDIR _WDIR;
+
+/* Multi-byte character version */
+struct dirent {
+ /* Always zero */
+ long d_ino;
+
+ /* File position within stream */
+ long d_off;
+
+ /* Structure size */
+ unsigned short d_reclen;
+
+ /* Length of name without \0 */
+ size_t d_namlen;
+
+ /* File type */
+ int d_type;
+
+ /* File name */
+ char d_name[PATH_MAX+1];
+};
+typedef struct dirent dirent;
+
+struct DIR {
+ struct dirent ent;
+ struct _WDIR *wdirp;
+};
+typedef struct DIR DIR;
+
+
+/* Dirent functions */
+static DIR *opendir(const char *dirname);
+static _WDIR *_wopendir(const wchar_t *dirname);
+
+static struct dirent *readdir(DIR *dirp);
+static struct _wdirent *_wreaddir(_WDIR *dirp);
+
+static int readdir_r(
+ DIR *dirp, struct dirent *entry, struct dirent **result);
+static int _wreaddir_r(
+ _WDIR *dirp, struct _wdirent *entry, struct _wdirent **result);
+
+static int closedir(DIR *dirp);
+static int _wclosedir(_WDIR *dirp);
+
+static void rewinddir(DIR* dirp);
+static void _wrewinddir(_WDIR* dirp);
+
+static int scandir(const char *dirname, struct dirent ***namelist,
+ int (*filter)(const struct dirent*),
+ int (*compare)(const struct dirent**, const struct dirent**));
+
+static int alphasort(const struct dirent **a, const struct dirent **b);
+
+static int versionsort(const struct dirent **a, const struct dirent **b);
+
+static int strverscmp(const char *a, const char *b);
+
+/* For compatibility with Symbian */
+#define wdirent _wdirent
+#define WDIR _WDIR
+#define wopendir _wopendir
+#define wreaddir _wreaddir
+#define wclosedir _wclosedir
+#define wrewinddir _wrewinddir
+
+/* Compatibility with older Microsoft compilers and non-Microsoft compilers */
+#if !defined(_MSC_VER) || _MSC_VER < 1400
+# define wcstombs_s dirent_wcstombs_s
+# define mbstowcs_s dirent_mbstowcs_s
+#endif
+
+/* Optimize dirent_set_errno() away on modern Microsoft compilers */
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+# define dirent_set_errno _set_errno
+#endif
+
+
+/* Internal utility functions */
+static WIN32_FIND_DATAW *dirent_first(_WDIR *dirp);
+static WIN32_FIND_DATAW *dirent_next(_WDIR *dirp);
+
+#if !defined(_MSC_VER) || _MSC_VER < 1400
+static int dirent_mbstowcs_s(
+ size_t *pReturnValue, wchar_t *wcstr, size_t sizeInWords,
+ const char *mbstr, size_t count);
+#endif
+
+#if !defined(_MSC_VER) || _MSC_VER < 1400
+static int dirent_wcstombs_s(
+ size_t *pReturnValue, char *mbstr, size_t sizeInBytes,
+ const wchar_t *wcstr, size_t count);
+#endif
+
+#if !defined(_MSC_VER) || _MSC_VER < 1400
+static void dirent_set_errno(int error);
+#endif
+
+
+/*
+ * Open directory stream DIRNAME for read and return a pointer to the
+ * internal working area that is used to retrieve individual directory
+ * entries.
+ */
+static _WDIR *_wopendir(const wchar_t *dirname)
+{
+ wchar_t *p;
+
+ /* Must have directory name */
+ if (dirname == NULL || dirname[0] == '\0') {
+ dirent_set_errno(ENOENT);
+ return NULL;
+ }
+
+ /* Allocate new _WDIR structure */
+ _WDIR *dirp = (_WDIR*) malloc(sizeof(struct _WDIR));
+ if (!dirp)
+ return NULL;
+
+ /* Reset _WDIR structure */
+ dirp->handle = INVALID_HANDLE_VALUE;
+ dirp->patt = NULL;
+ dirp->cached = 0;
+
+ /*
+ * Compute the length of full path plus zero terminator
+ *
+ * Note that on WinRT there's no way to convert relative paths
+ * into absolute paths, so just assume it is an absolute path.
+ */
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+ /* Desktop */
+ DWORD n = GetFullPathNameW(dirname, 0, NULL, NULL);
+#else
+ /* WinRT */
+ size_t n = wcslen(dirname);
+#endif
+
+ /* Allocate room for absolute directory name and search pattern */
+ dirp->patt = (wchar_t*) malloc(sizeof(wchar_t) * n + 16);
+ if (dirp->patt == NULL)
+ goto exit_closedir;
+
+ /*
+ * Convert relative directory name to an absolute one. This
+ * allows rewinddir() to function correctly even when current
+ * working directory is changed between opendir() and rewinddir().
+ *
+ * Note that on WinRT there's no way to convert relative paths
+ * into absolute paths, so just assume it is an absolute path.
+ */
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+ /* Desktop */
+ n = GetFullPathNameW(dirname, n, dirp->patt, NULL);
+ if (n <= 0)
+ goto exit_closedir;
+#else
+ /* WinRT */
+ wcsncpy_s(dirp->patt, n+1, dirname, n);
+#endif
+
+ /* Append search pattern \* to the directory name */
+ p = dirp->patt + n;
+ switch (p[-1]) {
+ case '\\':
+ case '/':
+ case ':':
+ /* Directory ends in path separator, e.g. c:\temp\ */
+ /*NOP*/;
+ break;
+
+ default:
+ /* Directory name doesn't end in path separator */
+ *p++ = '\\';
+ }
+ *p++ = '*';
+ *p = '\0';
+
+ /* Open directory stream and retrieve the first entry */
+ if (!dirent_first(dirp))
+ goto exit_closedir;
+
+ /* Success */
+ return dirp;
+
+ /* Failure */
+exit_closedir:
+ _wclosedir(dirp);
+ return NULL;
+}
+
+/*
+ * Read next directory entry.
+ *
+ * Returns pointer to static directory entry which may be overwritten by
+ * subsequent calls to _wreaddir().
+ */
+static struct _wdirent *_wreaddir(_WDIR *dirp)
+{
+ /*
+ * Read directory entry to buffer. We can safely ignore the return
+ * value as entry will be set to NULL in case of error.
+ */
+ struct _wdirent *entry;
+ (void) _wreaddir_r(dirp, &dirp->ent, &entry);
+
+ /* Return pointer to statically allocated directory entry */
+ return entry;
+}
+
+/*
+ * Read next directory entry.
+ *
+ * Returns zero on success. If end of directory stream is reached, then sets
+ * result to NULL and returns zero.
+ */
+static int _wreaddir_r(
+ _WDIR *dirp, struct _wdirent *entry, struct _wdirent **result)
+{
+ /* Read next directory entry */
+ WIN32_FIND_DATAW *datap = dirent_next(dirp);
+ if (!datap) {
+ /* Return NULL to indicate end of directory */
+ *result = NULL;
+ return /*OK*/0;
+ }
+
+ /*
+ * Copy file name as wide-character string. If the file name is too
+ * long to fit in to the destination buffer, then truncate file name
+ * to PATH_MAX characters and zero-terminate the buffer.
+ */
+ size_t n = 0;
+ while (n < PATH_MAX && datap->cFileName[n] != 0) {
+ entry->d_name[n] = datap->cFileName[n];
+ n++;
+ }
+ entry->d_name[n] = 0;
+
+ /* Length of file name excluding zero terminator */
+ entry->d_namlen = n;
+
+ /* File type */
+ DWORD attr = datap->dwFileAttributes;
+ if ((attr & FILE_ATTRIBUTE_DEVICE) != 0)
+ entry->d_type = DT_CHR;
+ else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0)
+ entry->d_type = DT_DIR;
+ else
+ entry->d_type = DT_REG;
+
+ /* Reset dummy fields */
+ entry->d_ino = 0;
+ entry->d_off = 0;
+ entry->d_reclen = sizeof(struct _wdirent);
+
+ /* Set result address */
+ *result = entry;
+ return /*OK*/0;
+}
+
+/*
+ * Close directory stream opened by opendir() function. This invalidates the
+ * DIR structure as well as any directory entry read previously by
+ * _wreaddir().
+ */
+static int _wclosedir(_WDIR *dirp)
+{
+ if (!dirp) {
+ dirent_set_errno(EBADF);
+ return /*failure*/-1;
+ }
+
+ /* Release search handle */
+ if (dirp->handle != INVALID_HANDLE_VALUE)
+ FindClose(dirp->handle);
+
+ /* Release search pattern */
+ free(dirp->patt);
+
+ /* Release directory structure */
+ free(dirp);
+ return /*success*/0;
+}
+
+/*
+ * Rewind directory stream such that _wreaddir() returns the very first
+ * file name again.
+ */
+static void _wrewinddir(_WDIR* dirp)
+{
+ if (!dirp)
+ return;
+
+ /* Release existing search handle */
+ if (dirp->handle != INVALID_HANDLE_VALUE)
+ FindClose(dirp->handle);
+
+ /* Open new search handle */
+ dirent_first(dirp);
+}
+
+/* Get first directory entry */
+static WIN32_FIND_DATAW *dirent_first(_WDIR *dirp)
+{
+ if (!dirp)
+ return NULL;
+
+ /* Open directory and retrieve the first entry */
+ dirp->handle = FindFirstFileExW(
+ dirp->patt, FindExInfoStandard, &dirp->data,
+ FindExSearchNameMatch, NULL, 0);
+ if (dirp->handle == INVALID_HANDLE_VALUE)
+ goto error;
+
+ /* A directory entry is now waiting in memory */
+ dirp->cached = 1;
+ return &dirp->data;
+
+error:
+ /* Failed to open directory: no directory entry in memory */
+ dirp->cached = 0;
+
+ /* Set error code */
+ DWORD errorcode = GetLastError();
+ switch (errorcode) {
+ case ERROR_ACCESS_DENIED:
+ /* No read access to directory */
+ dirent_set_errno(EACCES);
+ break;
+
+ case ERROR_DIRECTORY:
+ /* Directory name is invalid */
+ dirent_set_errno(ENOTDIR);
+ break;
+
+ case ERROR_PATH_NOT_FOUND:
+ default:
+ /* Cannot find the file */
+ dirent_set_errno(ENOENT);
+ }
+ return NULL;
+}
+
+/* Get next directory entry */
+static WIN32_FIND_DATAW *dirent_next(_WDIR *dirp)
+{
+ /* Is the next directory entry already in cache? */
+ if (dirp->cached) {
+ /* Yes, a valid directory entry found in memory */
+ dirp->cached = 0;
+ return &dirp->data;
+ }
+
+ /* No directory entry in cache */
+ if (dirp->handle == INVALID_HANDLE_VALUE)
+ return NULL;
+
+ /* Read the next directory entry from stream */
+ if (FindNextFileW(dirp->handle, &dirp->data) == FALSE)
+ goto exit_close;
+
+ /* Success */
+ return &dirp->data;
+
+ /* Failure */
+exit_close:
+ FindClose(dirp->handle);
+ dirp->handle = INVALID_HANDLE_VALUE;
+ return NULL;
+}
+
+/* Open directory stream using plain old C-string */
+static DIR *opendir(const char *dirname)
+{
+ /* Must have directory name */
+ if (dirname == NULL || dirname[0] == '\0') {
+ dirent_set_errno(ENOENT);
+ return NULL;
+ }
+
+ /* Allocate memory for DIR structure */
+ struct DIR *dirp = (DIR*) malloc(sizeof(struct DIR));
+ if (!dirp)
+ return NULL;
+
+ /* Convert directory name to wide-character string */
+ wchar_t wname[PATH_MAX + 1];
+ size_t n;
+ int error = mbstowcs_s(&n, wname, PATH_MAX + 1, dirname, PATH_MAX+1);
+ if (error)
+ goto exit_failure;
+
+ /* Open directory stream using wide-character name */
+ dirp->wdirp = _wopendir(wname);
+ if (!dirp->wdirp)
+ goto exit_failure;
+
+ /* Success */
+ return dirp;
+
+ /* Failure */
+exit_failure:
+ free(dirp);
+ return NULL;
+}
+
+/* Read next directory entry */
+static struct dirent *readdir(DIR *dirp)
+{
+ /*
+ * Read directory entry to buffer. We can safely ignore the return
+ * value as entry will be set to NULL in case of error.
+ */
+ struct dirent *entry;
+ (void) readdir_r(dirp, &dirp->ent, &entry);
+
+ /* Return pointer to statically allocated directory entry */
+ return entry;
+}
+
+/*
+ * Read next directory entry into called-allocated buffer.
+ *
+ * Returns zero on success. If the end of directory stream is reached, then
+ * sets result to NULL and returns zero.
+ */
+static int readdir_r(
+ DIR *dirp, struct dirent *entry, struct dirent **result)
+{
+ /* Read next directory entry */
+ WIN32_FIND_DATAW *datap = dirent_next(dirp->wdirp);
+ if (!datap) {
+ /* No more directory entries */
+ *result = NULL;
+ return /*OK*/0;
+ }
+
+ /* Attempt to convert file name to multi-byte string */
+ size_t n;
+ int error = wcstombs_s(
+ &n, entry->d_name, PATH_MAX + 1,
+ datap->cFileName, PATH_MAX + 1);
+
+ /*
+ * If the file name cannot be represented by a multi-byte string, then
+ * attempt to use old 8+3 file name. This allows the program to
+ * access files although file names may seem unfamiliar to the user.
+ *
+ * Be ware that the code below cannot come up with a short file name
+ * unless the file system provides one. At least VirtualBox shared
+ * folders fail to do this.
+ */
+ if (error && datap->cAlternateFileName[0] != '\0') {
+ error = wcstombs_s(
+ &n, entry->d_name, PATH_MAX + 1,
+ datap->cAlternateFileName, PATH_MAX + 1);
+ }
+
+ if (!error) {
+ /* Length of file name excluding zero terminator */
+ entry->d_namlen = n - 1;
+
+ /* File attributes */
+ DWORD attr = datap->dwFileAttributes;
+ if ((attr & FILE_ATTRIBUTE_DEVICE) != 0)
+ entry->d_type = DT_CHR;
+ else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0)
+ entry->d_type = DT_DIR;
+ else
+ entry->d_type = DT_REG;
+
+ /* Reset dummy fields */
+ entry->d_ino = 0;
+ entry->d_off = 0;
+ entry->d_reclen = sizeof(struct dirent);
+ } else {
+ /*
+ * Cannot convert file name to multi-byte string so construct
+ * an erroneous directory entry and return that. Note that
+ * we cannot return NULL as that would stop the processing
+ * of directory entries completely.
+ */
+ entry->d_name[0] = '?';
+ entry->d_name[1] = '\0';
+ entry->d_namlen = 1;
+ entry->d_type = DT_UNKNOWN;
+ entry->d_ino = 0;
+ entry->d_off = -1;
+ entry->d_reclen = 0;
+ }
+
+ /* Return pointer to directory entry */
+ *result = entry;
+ return /*OK*/0;
+}
+
+/* Close directory stream */
+static int closedir(DIR *dirp)
+{
+ int ok;
+
+ if (!dirp)
+ goto exit_failure;
+
+ /* Close wide-character directory stream */
+ ok = _wclosedir(dirp->wdirp);
+ dirp->wdirp = NULL;
+
+ /* Release multi-byte character version */
+ free(dirp);
+ return ok;
+
+exit_failure:
+ /* Invalid directory stream */
+ dirent_set_errno(EBADF);
+ return /*failure*/-1;
+}
+
+/* Rewind directory stream to beginning */
+static void rewinddir(DIR* dirp)
+{
+ if (!dirp)
+ return;
+
+ /* Rewind wide-character string directory stream */
+ _wrewinddir(dirp->wdirp);
+}
+
+/* Scan directory for entries */
+static int scandir(
+ const char *dirname, struct dirent ***namelist,
+ int (*filter)(const struct dirent*),
+ int (*compare)(const struct dirent**, const struct dirent**))
+{
+ int result;
+
+ /* Open directory stream */
+ DIR *dir = opendir(dirname);
+ if (!dir) {
+ /* Cannot open directory */
+ return /*Error*/ -1;
+ }
+
+ /* Read directory entries to memory */
+ struct dirent *tmp = NULL;
+ struct dirent **files = NULL;
+ size_t size = 0;
+ size_t allocated = 0;
+ while (1) {
+ /* Allocate room for a temporary directory entry */
+ if (!tmp) {
+ tmp = (struct dirent*) malloc(sizeof(struct dirent));
+ if (!tmp)
+ goto exit_failure;
+ }
+
+ /* Read directory entry to temporary area */
+ struct dirent *entry;
+ if (readdir_r(dir, tmp, &entry) != /*OK*/0)
+ goto exit_failure;
+
+ /* Stop if we already read the last directory entry */
+ if (entry == NULL)
+ goto exit_success;
+
+ /* Determine whether to include the entry in results */
+ if (filter && !filter(tmp))
+ continue;
+
+ /* Enlarge pointer table to make room for another pointer */
+ if (size >= allocated) {
+ /* Compute number of entries in the new table */
+ size_t num_entries = size * 2 + 16;
+
+ /* Allocate new pointer table or enlarge existing */
+ void *p = realloc(files, sizeof(void*) * num_entries);
+ if (!p)
+ goto exit_failure;
+
+ /* Got the memory */
+ files = (dirent**) p;
+ allocated = num_entries;
+ }
+
+ /* Store the temporary entry to ptr table */
+ files[size++] = tmp;
+ tmp = NULL;
+ }
+
+exit_failure:
+ /* Release allocated file entries */
+ for (size_t i = 0; i < size; i++) {
+ free(files[i]);
+ }
+
+ /* Release the pointer table */
+ free(files);
+ files = NULL;
+
+ /* Exit with error code */
+ result = /*error*/ -1;
+ goto exit_status;
+
+exit_success:
+ /* Sort directory entries */
+ qsort(files, size, sizeof(void*),
+ (int (*) (const void*, const void*)) compare);
+
+ /* Pass pointer table to caller */
+ if (namelist)
+ *namelist = files;
+
+ /* Return the number of directory entries read */
+ result = (int) size;
+
+exit_status:
+ /* Release temporary directory entry, if we had one */
+ free(tmp);
+
+ /* Close directory stream */
+ closedir(dir);
+ return result;
+}
+
+/* Alphabetical sorting */
+static int alphasort(const struct dirent **a, const struct dirent **b)
+{
+ return strcoll((*a)->d_name, (*b)->d_name);
+}
+
+/* Sort versions */
+static int versionsort(const struct dirent **a, const struct dirent **b)
+{
+ return strverscmp((*a)->d_name, (*b)->d_name);
+}
+
+/* Compare strings */
+static int strverscmp(const char *a, const char *b)
+{
+ size_t i = 0;
+ size_t j;
+
+ /* Find first difference */
+ while (a[i] == b[i]) {
+ if (a[i] == '\0') {
+ /* No difference */
+ return 0;
+ }
+ ++i;
+ }
+
+ /* Count backwards and find the leftmost digit */
+ j = i;
+ while (j > 0 && isdigit(a[j-1])) {
+ --j;
+ }
+
+ /* Determine mode of comparison */
+ if (a[j] == '0' || b[j] == '0') {
+ /* Find the next non-zero digit */
+ while (a[j] == '0' && a[j] == b[j]) {
+ j++;
+ }
+
+ /* String with more digits is smaller, e.g 002 < 01 */
+ if (isdigit(a[j])) {
+ if (!isdigit(b[j])) {
+ return -1;
+ }
+ } else if (isdigit(b[j])) {
+ return 1;
+ }
+ } else if (isdigit(a[j]) && isdigit(b[j])) {
+ /* Numeric comparison */
+ size_t k1 = j;
+ size_t k2 = j;
+
+ /* Compute number of digits in each string */
+ while (isdigit(a[k1])) {
+ k1++;
+ }
+ while (isdigit(b[k2])) {
+ k2++;
+ }
+
+ /* Number with more digits is bigger, e.g 999 < 1000 */
+ if (k1 < k2)
+ return -1;
+ else if (k1 > k2)
+ return 1;
+ }
+
+ /* Alphabetical comparison */
+ return (int) ((unsigned char) a[i]) - ((unsigned char) b[i]);
+}
+
+/* Convert multi-byte string to wide character string */
+#if !defined(_MSC_VER) || _MSC_VER < 1400
+static int dirent_mbstowcs_s(
+ size_t *pReturnValue, wchar_t *wcstr,
+ size_t sizeInWords, const char *mbstr, size_t count)
+{
+ /* Older Visual Studio or non-Microsoft compiler */
+ size_t n = mbstowcs(wcstr, mbstr, sizeInWords);
+ if (wcstr && n >= count)
+ return /*error*/ 1;
+
+ /* Zero-terminate output buffer */
+ if (wcstr && sizeInWords) {
+ if (n >= sizeInWords)
+ n = sizeInWords - 1;
+ wcstr[n] = 0;
+ }
+
+ /* Length of multi-byte string with zero terminator */
+ if (pReturnValue) {
+ *pReturnValue = n + 1;
+ }
+
+ /* Success */
+ return 0;
+}
+#endif
+
+/* Convert wide-character string to multi-byte string */
+#if !defined(_MSC_VER) || _MSC_VER < 1400
+static int dirent_wcstombs_s(
+ size_t *pReturnValue, char *mbstr,
+ size_t sizeInBytes, const wchar_t *wcstr, size_t count)
+{
+ /* Older Visual Studio or non-Microsoft compiler */
+ size_t n = wcstombs(mbstr, wcstr, sizeInBytes);
+ if (mbstr && n >= count)
+ return /*error*/1;
+
+ /* Zero-terminate output buffer */
+ if (mbstr && sizeInBytes) {
+ if (n >= sizeInBytes) {
+ n = sizeInBytes - 1;
+ }
+ mbstr[n] = '\0';
+ }
+
+ /* Length of resulting multi-bytes string WITH zero-terminator */
+ if (pReturnValue) {
+ *pReturnValue = n + 1;
+ }
+
+ /* Success */
+ return 0;
+}
+#endif
+
+/* Set errno variable */
+#if !defined(_MSC_VER) || _MSC_VER < 1400
+static void dirent_set_errno(int error)
+{
+ /* Non-Microsoft compiler or older Microsoft compiler */
+ errno = error;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*DIRENT_H*/
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/external/wingetopt.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core/external/wingetopt.h
new file mode 100644
index 000000000..29ea1002c
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/external/wingetopt.h
@@ -0,0 +1,282 @@
+/* This is a drop-in replacement of getopt library, based on the work of
+ * musl libc. This file is distributed under MIT License.
+ *
+ * ----
+ * Copyright © 2005-2014 Rich Felker, et al.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _WINGETOPT_H
+#define _WINGETOPT_H
+
+#define _GNU_SOURCE
+#include <wchar.h>
+#include <string.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+struct option {
+ const char *name;
+ int has_arg;
+ int *flag;
+ int val;
+};
+
+static char *optarg;
+static int optind=1, opterr=1, optopt, __optpos, __optreset=0;
+
+#define optpos __optpos
+#define optreset __optreset
+#define no_argument 0
+#define required_argument 1
+#define optional_argument 2
+
+/*
+ * Implementation of getopt()
+ */
+static inline void __getopt_msg(const char *a, const char *b, const char *c, size_t l)
+{
+ FILE *f = stderr;
+ fputs(a, f);
+ fwrite(b, strlen(b), 1, f);
+ fwrite(c, 1, l, f);
+ putc('\n', f);
+}
+
+static int getopt(int argc, char * const argv[], const char *optstring)
+{
+ int i;
+ wchar_t c, d;
+ int k, l;
+ char *optchar;
+
+ if (!optind || __optreset) {
+ __optreset = 0;
+ __optpos = 0;
+ optind = 1;
+ }
+
+ if (optind >= argc || !argv[optind])
+ return -1;
+
+ if (argv[optind][0] != '-') {
+ if (optstring[0] == '-') {
+ optarg = argv[optind++];
+ return 1;
+ }
+ return -1;
+ }
+
+ if (!argv[optind][1])
+ return -1;
+
+ if (argv[optind][1] == '-' && !argv[optind][2])
+ return optind++, -1;
+
+ if (!optpos) optpos++;
+ if ((k = mbtowc(&c, argv[optind]+optpos, MB_LEN_MAX)) < 0) {
+ k = 1;
+ c = 0xfffd; /* replacement char */
+ }
+ optchar = argv[optind]+optpos;
+ optpos += k;
+
+ if (!argv[optind][optpos]) {
+ optind++;
+ optpos = 0;
+ }
+
+ if (optstring[0] == '-' || optstring[0] == '+')
+ optstring++;
+
+ i = 0;
+ d = 0;
+ do {
+ l = mbtowc(&d, optstring+i, MB_LEN_MAX);
+ if (l>0) i+=l; else i++;
+ } while (l && d != c);
+
+ if (d != c || c == ':') {
+ optopt = c;
+ if (optstring[0] != ':' && opterr)
+ __getopt_msg(argv[0], ": unrecognized option: ", optchar, k);
+ return '?';
+ }
+ if (optstring[i] == ':') {
+ optarg = 0;
+ if (optstring[i+1] != ':' || optpos) {
+ optarg = argv[optind++] + optpos;
+ optpos = 0;
+ }
+ if (optind > argc) {
+ optopt = c;
+ if (optstring[0] == ':') return ':';
+ if (opterr) __getopt_msg(argv[0],
+ ": option requires an argument: ",
+ optchar, k);
+ return '?';
+ }
+ }
+ return c;
+}
+
+/*
+ * Implementation of getopt_long() and getopt_long_only()
+ */
+static inline void __getopt_permute(char *const *argv, int dest, int src)
+{
+ char **av = (char **)argv;
+ char *tmp = av[src];
+ int i;
+ for (i=src; i>dest; i--)
+ av[i] = av[i-1];
+ av[dest] = tmp;
+}
+
+static int __getopt_long_core(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly);
+
+static int __getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly)
+{
+ int ret, skipped, resumed;
+ if (!optind || __optreset) {
+ __optreset = 0;
+ __optpos = 0;
+ optind = 1;
+ }
+ if (optind >= argc || !argv[optind]) return -1;
+ skipped = optind;
+ if (optstring[0] != '+' && optstring[0] != '-') {
+ int i;
+ for (i=optind; ; i++) {
+ if (i >= argc || !argv[i]) return -1;
+ if (argv[i][0] == '-' && argv[i][1]) break;
+ }
+ optind = i;
+ }
+ resumed = optind;
+ ret = __getopt_long_core(argc, argv, optstring, longopts, idx, longonly);
+ if (resumed > skipped) {
+ int i, cnt = optind-resumed;
+ for (i=0; i<cnt; i++)
+ __getopt_permute(argv, skipped, optind-1);
+ optind = skipped + cnt;
+ }
+ return ret;
+}
+
+static int __getopt_long_core(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly)
+{
+ optarg = 0;
+ if (longopts && argv[optind][0] == '-' &&
+ ((longonly && argv[optind][1] && argv[optind][1] != '-') ||
+ (argv[optind][1] == '-' && argv[optind][2])))
+ {
+ int colon = optstring[optstring[0]=='+'||optstring[0]=='-']==':';
+ int i, cnt, match;
+ char *arg, *opt, *start = argv[optind]+1;
+ for (cnt=i=0; longopts[i].name; i++) {
+ const char *name = longopts[i].name;
+ opt = start;
+ if (*opt == '-') opt++;
+ while (*opt && *opt != '=' && *opt == *name)
+ name++, opt++;
+ if (*opt && *opt != '=') continue;
+ arg = opt;
+ match = i;
+ if (!*name) {
+ cnt = 1;
+ break;
+ }
+ cnt++;
+ }
+ if (cnt==1 && longonly && arg-start == mblen(start, MB_LEN_MAX)) {
+ int l = arg-start;
+ for (i=0; optstring[i]; i++) {
+ int j;
+ for (j=0; j<l && start[j]==optstring[i+j]; j++);
+ if (j==l) {
+ cnt++;
+ break;
+ }
+ }
+ }
+ if (cnt==1) {
+ i = match;
+ opt = arg;
+ optind++;
+ if (*opt == '=') {
+ if (!longopts[i].has_arg) {
+ optopt = longopts[i].val;
+ if (colon || !opterr)
+ return '?';
+ __getopt_msg(argv[0],
+ ": option does not take an argument: ",
+ longopts[i].name,
+ strlen(longopts[i].name));
+ return '?';
+ }
+ optarg = opt+1;
+ } else if (longopts[i].has_arg == required_argument) {
+ if (!(optarg = argv[optind])) {
+ optopt = longopts[i].val;
+ if (colon) return ':';
+ if (!opterr) return '?';
+ __getopt_msg(argv[0],
+ ": option requires an argument: ",
+ longopts[i].name,
+ strlen(longopts[i].name));
+ return '?';
+ }
+ optind++;
+ }
+ if (idx) *idx = i;
+ if (longopts[i].flag) {
+ *longopts[i].flag = longopts[i].val;
+ return 0;
+ }
+ return longopts[i].val;
+ }
+ if (argv[optind][1] == '-') {
+ optopt = 0;
+ if (!colon && opterr)
+ __getopt_msg(argv[0], cnt ?
+ ": option is ambiguous: " :
+ ": unrecognized option: ",
+ argv[optind]+2,
+ strlen(argv[optind]+2));
+ optind++;
+ return '?';
+ }
+ }
+ return getopt(argc, argv, optstring);
+}
+
+static int getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx)
+{
+ return __getopt_long(argc, argv, optstring, longopts, idx, 0);
+}
+
+static int getopt_long_only(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx)
+{
+ return __getopt_long(argc, argv, optstring, longopts, idx, 1);
+}
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/external/winpthreads.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core/external/winpthreads.h
new file mode 100644
index 000000000..97045a69a
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/external/winpthreads.h
@@ -0,0 +1,340 @@
+/*
+ * Posix Threads library for Microsoft Windows
+ *
+ * Use at own risk, there is no implied warranty to this code.
+ * It uses undocumented features of Microsoft Windows that can change
+ * at any time in the future.
+ *
+ * (C) 2010 Lockless Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of Lockless Inc. nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AN
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WIN_PTHREADS
+#define WIN_PTHREADS
+
+#define _WINSOCKAPI_
+#include <windows.h>
+#include <errno.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef ETIMEDOUT
+#define ETIMEDOUT 110
+#endif
+#ifndef ENOTSUP
+#define ENOTSUP 134
+#endif
+
+#ifndef PTHREAD_STACK_MIN
+#define PTHREAD_STACK_MIN 65535
+#endif
+
+#define PTHREAD_CANCEL_DISABLE 0
+#define PTHREAD_CANCEL_ENABLE 0x01
+
+#define PTHREAD_CANCEL_DEFERRED 0
+#define PTHREAD_CANCEL_ASYNCHRONOUS 0x02
+
+#define PTHREAD_CREATE_JOINABLE 0
+#define PTHREAD_CREATE_DETACHED 0x04
+
+#define PTHREAD_EXPLICT_SCHED 0
+#define PTHREAD_INHERIT_SCHED 0x08
+
+#define PTHREAD_SCOPE_PROCESS 0
+#define PTHREAD_SCOPE_SYSTEM 0x10
+
+#define PTHREAD_DEFAULT_ATTR (PTHREAD_CANCEL_ENABLE)
+
+#define PTHREAD_CANCELED ((void *) 0xDEADBEEF)
+
+#define PTHREAD_ONCE_INIT 0
+#define PTHREAD_MUTEX_INITIALIZER {(void*)-1,-1,0,0,0,0}
+#define PTHREAD_RWLOCK_INITIALIZER {0}
+#define PTHREAD_COND_INITIALIZER {0}
+#define PTHREAD_BARRIER_INITIALIZER \
+ {0,0,PTHREAD_MUTEX_INITIALIZER,PTHREAD_COND_INITIALIZER}
+#define PTHREAD_SPINLOCK_INITIALIZER 0
+
+#define PTHREAD_DESTRUCTOR_ITERATIONS 256
+#define PTHREAD_KEYS_MAX (1<<20)
+
+#define PTHREAD_MUTEX_NORMAL 0
+#define PTHREAD_MUTEX_ERRORCHECK 1
+#define PTHREAD_MUTEX_RECURSIVE 2
+#define PTHREAD_MUTEX_DEFAULT 3
+#define PTHREAD_MUTEX_SHARED 4
+#define PTHREAD_MUTEX_PRIVATE 0
+#define PTHREAD_PRIO_NONE 0
+#define PTHREAD_PRIO_INHERIT 8
+#define PTHREAD_PRIO_PROTECT 16
+#define PTHREAD_PRIO_MULT 32
+#define PTHREAD_PROCESS_SHARED 0
+#define PTHREAD_PROCESS_PRIVATE 1
+
+#define PTHREAD_BARRIER_SERIAL_THREAD 1
+
+/* Windows doesn't have this, so declare it ourselves. */
+#if (_MSC_VER < 1900)
+struct timespec
+{
+ /* long long in windows is the same as long in unix for 64bit */
+ long long tv_sec;
+ long long tv_nsec;
+};
+#else
+#include <time.h>
+#endif
+
+struct _pthread_v;
+typedef struct _pthread_v *pthread_t;
+
+struct pthread_barrier_t
+{
+ int count;
+ int total;
+ CRITICAL_SECTION m;
+ CONDITION_VARIABLE cv;
+};
+
+typedef struct pthread_barrier_t pthread_barrier_t;
+
+struct pthread_attr_t
+{
+ unsigned p_state;
+ void *stack;
+ size_t s_size;
+};
+
+typedef struct pthread_attr_t pthread_attr_t;
+
+typedef long pthread_once_t;
+typedef unsigned pthread_mutexattr_t;
+typedef SRWLOCK pthread_rwlock_t;
+typedef CRITICAL_SECTION pthread_mutex_t;
+typedef unsigned pthread_key_t;
+typedef void *pthread_barrierattr_t;
+typedef long pthread_spinlock_t;
+typedef int pthread_condattr_t;
+typedef CONDITION_VARIABLE pthread_cond_t;
+typedef int pthread_rwlockattr_t;
+
+extern pthread_t pthread_self(void);
+
+extern int pthread_once(pthread_once_t *o, void(*func)(void));
+
+extern int pthread_mutex_lock(pthread_mutex_t *m);
+
+extern int pthread_mutex_unlock(pthread_mutex_t *m);
+
+extern int pthread_mutex_trylock(pthread_mutex_t *m);
+
+extern int pthread_mutex_init(pthread_mutex_t *m, pthread_mutexattr_t *a);
+
+extern int pthread_mutex_destroy(pthread_mutex_t *m);
+
+#define pthread_mutex_getprioceiling(M, P) ENOTSUP
+#define pthread_mutex_setprioceiling(M, P) ENOTSUP
+
+extern int pthread_equal(pthread_t t1, pthread_t t2);
+
+extern int pthread_rwlock_init(pthread_rwlock_t *l, pthread_rwlockattr_t *a);
+
+extern int pthread_rwlock_destroy(pthread_rwlock_t *l);
+
+extern int pthread_rwlock_rdlock(pthread_rwlock_t *l);
+
+extern int pthread_rwlock_wrlock(pthread_rwlock_t *l);
+
+extern int pthread_rwlock_unlock(pthread_rwlock_t *l);
+
+extern int pthread_rwlock_tryrdlock(pthread_rwlock_t *l);
+
+extern int pthread_rwlock_trywrlock(pthread_rwlock_t *l);
+
+extern void pthread_tls_init(void);
+
+extern int pthread_rwlock_timedrdlock(pthread_rwlock_t *l, const struct timespec *ts);
+
+extern int pthread_rwlock_timedwrlock(pthread_rwlock_t *l, const struct timespec *ts);
+
+extern int pthread_get_concurrency(int *val);
+
+extern int pthread_set_concurrency(int val);
+
+#define pthread_getschedparam(T, P, S) ENOTSUP
+#define pthread_setschedparam(T, P, S) ENOTSUP
+#define pthread_getcpuclockid(T, C) ENOTSUP
+
+extern int pthread_exit(void *res);
+
+extern void pthread_testcancel(void);
+
+extern int pthread_cancel(pthread_t t);
+
+extern int pthread_attr_init(pthread_attr_t *attr);
+
+extern int pthread_attr_destroy(pthread_attr_t *attr);
+
+extern int pthread_attr_setdetachstate(pthread_attr_t *a, int flag);
+
+extern int pthread_attr_getdetachstate(pthread_attr_t *a, int *flag);
+
+extern int pthread_attr_setinheritsched(pthread_attr_t *a, int flag);
+
+extern int pthread_attr_getinheritsched(pthread_attr_t *a, int *flag);
+
+extern int pthread_attr_setscope(pthread_attr_t *a, int flag);
+
+extern int pthread_attr_getscope(pthread_attr_t *a, int *flag);
+
+extern int pthread_attr_getstackaddr(pthread_attr_t *attr, void **stack);
+
+extern int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stack);
+
+extern int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *size);
+
+extern int pthread_attr_setstacksize(pthread_attr_t *attr, size_t size);
+
+#define pthread_attr_getguardsize(A, S) ENOTSUP
+#define pthread_attr_setgaurdsize(A, S) ENOTSUP
+#define pthread_attr_getschedparam(A, S) ENOTSUP
+#define pthread_attr_setschedparam(A, S) ENOTSUP
+#define pthread_attr_getschedpolicy(A, S) ENOTSUP
+#define pthread_attr_setschedpolicy(A, S) ENOTSUP
+
+extern int pthread_setcancelstate(int state, int *oldstate);
+
+extern int pthread_setcanceltype(int type, int *oldtype);
+
+extern unsigned __stdcall pthread_create_wrapper(void *args);
+
+extern int pthread_create(pthread_t *th, pthread_attr_t *attr, void *(*func)(void *), void *arg);
+
+extern int pthread_join(pthread_t t, void **res);
+
+extern int pthread_detach(pthread_t t);
+
+extern int pthread_mutexattr_init(pthread_mutexattr_t *a);
+
+extern int pthread_mutexattr_destroy(pthread_mutexattr_t *a);
+
+extern int pthread_mutexattr_gettype(pthread_mutexattr_t *a, int *type);
+
+extern int pthread_mutexattr_settype(pthread_mutexattr_t *a, int type);
+
+extern int pthread_mutexattr_getpshared(pthread_mutexattr_t *a, int *type);
+
+extern int pthread_mutexattr_setpshared(pthread_mutexattr_t * a, int type);
+
+extern int pthread_mutexattr_getprotocol(pthread_mutexattr_t *a, int *type);
+
+extern int pthread_mutexattr_setprotocol(pthread_mutexattr_t *a, int type);
+
+extern int pthread_mutexattr_getprioceiling(pthread_mutexattr_t *a, int * prio);
+
+extern int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *a, int prio);
+
+extern int pthread_mutex_timedlock(pthread_mutex_t *m, struct timespec *ts);
+
+extern int pthread_barrier_destroy(pthread_barrier_t *b);
+
+extern int pthread_barrier_init(pthread_barrier_t *b, void *attr, int count);
+
+extern int pthread_barrier_wait(pthread_barrier_t *b);
+
+extern int pthread_barrierattr_init(void **attr);
+
+extern int pthread_barrierattr_destroy(void **attr);
+
+extern int pthread_barrierattr_setpshared(void **attr, int s);
+
+extern int pthread_barrierattr_getpshared(void **attr, int *s);
+
+extern int pthread_key_create(pthread_key_t *key, void(*dest)(void *));
+
+extern int pthread_key_delete(pthread_key_t key);
+
+extern void *pthread_getspecific(pthread_key_t key);
+
+extern int pthread_setspecific(pthread_key_t key, const void *value);
+
+extern int pthread_spin_init(pthread_spinlock_t *l, int pshared);
+
+extern int pthread_spin_destroy(pthread_spinlock_t *l);
+
+extern int pthread_spin_lock(pthread_spinlock_t *l);
+
+extern int pthread_spin_trylock(pthread_spinlock_t *l);
+
+extern int pthread_spin_unlock(pthread_spinlock_t *l);
+
+extern int pthread_cond_init(pthread_cond_t *c, pthread_condattr_t *a);
+
+extern int pthread_cond_signal(pthread_cond_t *c);
+
+extern int pthread_cond_broadcast(pthread_cond_t *c);
+
+extern int pthread_cond_wait(pthread_cond_t *c, pthread_mutex_t *m);
+
+extern int pthread_cond_destroy(pthread_cond_t *c);
+
+extern int pthread_cond_timedwait(pthread_cond_t *c, pthread_mutex_t *m, struct timespec *t);
+
+extern int pthread_condattr_destroy(pthread_condattr_t *a);
+
+#define pthread_condattr_getclock(A, C) ENOTSUP
+#define pthread_condattr_setclock(A, C) ENOTSUP
+
+extern int pthread_condattr_init(pthread_condattr_t *a);
+
+extern int pthread_condattr_getpshared(pthread_condattr_t *a, int *s);
+
+extern int pthread_condattr_setpshared(pthread_condattr_t *a, int s);
+
+extern int pthread_rwlockattr_destroy(pthread_rwlockattr_t *a);
+
+extern int pthread_rwlockattr_init(pthread_rwlockattr_t *a);
+
+extern int pthread_rwlockattr_getpshared(pthread_rwlockattr_t *a, int *s);
+
+extern int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *a, int s);
+
+/* No fork() in windows - so ignore this */
+#define pthread_atfork(F1,F2,F3) 0
+
+/* Windows has rudimentary signals support */
+#define pthread_kill(T, S) 0
+#define pthread_sigmask(H, S1, S2) 0
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* WIN_PTHREADS */
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/external/winuio.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core/external/winuio.h
new file mode 100644
index 000000000..4ae747888
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/external/winuio.h
@@ -0,0 +1,54 @@
+#ifndef _WINUIO_H
+#define _WINUIO_H
+
+#include <inttypes.h>
+
+#ifndef _WIN32
+#include <unistd.h>
+#else
+#include <errno.h>
+#include <io.h>
+#include <BaseTsd.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+typedef SSIZE_T ssize_t;
+#endif
+
+struct mk_iovec
+{
+ void *iov_base; /* Base address of a memory region for input or output */
+ size_t iov_len; /* The size of the memory pointed to by iov_base */
+};
+
+/* Long way to go here, it's mostly a placeholder */
+
+static inline ssize_t readv(int fildes, const struct mk_iovec *iov, int iovcnt)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
+static inline ssize_t writev(int fildes, const struct mk_iovec *iov, int iovcnt)
+{
+ int i;
+ uint32_t bytes_written = 0;
+
+ for (i = 0; i < iovcnt; i++) {
+ int len;
+
+ len = send((SOCKET)fildes, iov[i].iov_base, (int)iov[i].iov_len, 0);
+ if (len == SOCKET_ERROR) {
+ uint32_t err = GetLastError();
+ // errno = win_to_posix_error(err);
+ bytes_written = -1;
+ break;
+ }
+ bytes_written += len;
+ }
+
+ return bytes_written;
+}
+
+
+#endif /* _WINUIO_H */
+
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_core_info.h.in b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_core_info.h.in
new file mode 100644
index 000000000..1bd09e54a
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_core_info.h.in
@@ -0,0 +1,26 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/* Monkey HTTP Server
+ * ==================
+ * Copyright 2001-2015 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.
+ */
+
+#ifndef MK_CORE_INFO_H
+#define MK_CORE_INFO_H
+
+/* General flags set by CMakeLists.txt */
+@MK_CORE_BUILD_FLAGS@
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_dep_unistd.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_dep_unistd.h
new file mode 100644
index 000000000..46c3a874e
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_dep_unistd.h
@@ -0,0 +1,56 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+#ifndef _UNISTD_H
+#define _UNISTD_H 1
+
+/* This file intended to serve as a drop-in replacement for
+ * unistd.h on Windows
+ * Please add functionality as neeeded
+ */
+
+#include <stdlib.h>
+#include <io.h>
+
+/* Skip getopt.h for now */
+//#include <getopt.h> /* getopt at: https://gist.github.com/ashelly/7776712 */
+#include <process.h> /* for getpid() and the exec..() family */
+#include <direct.h> /* for _getcwd() and _chdir() */
+
+#define srandom srand
+#define random rand
+
+/* Values for the second argument to access.
+ These may be OR'd together. */
+#define R_OK 4 /* Test for read permission. */
+#define W_OK 2 /* Test for write permission. */
+//#define X_OK 1 /* execute permission - unsupported in windows*/
+#define F_OK 0 /* Test for existence. */
+
+#define access _access
+#define dup2 _dup2
+#define execve _execve
+#define ftruncate _chsize
+#define unlink _unlink
+#define fileno _fileno
+#define getcwd _getcwd
+#define chdir _chdir
+#define isatty _isatty
+#define lseek _lseek
+/* read, write, and close are NOT being #defined here, because while there are file handle specific versions for Windows, they probably don't work for sockets. You need to look at your app and consider whether to call e.g. closesocket(). */
+
+#define ssize_t SSIZE_T
+
+#define STDIN_FILENO 0
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
+/* should be in some equivalent to <sys/types.h> */
+typedef __int8 int8_t;
+typedef __int16 int16_t;
+typedef __int32 int32_t;
+typedef __int64 int64_t;
+typedef unsigned __int8 uint8_t;
+typedef unsigned __int16 uint16_t;
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int64 uint64_t;
+
+#endif /* unistd.h */
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_dirent.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_dirent.h
new file mode 100644
index 000000000..ed1527c1f
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_dirent.h
@@ -0,0 +1,31 @@
+/* -*- 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.
+ */
+
+#ifndef MK_DIRENT_H
+#define MK_DIRENT_H
+
+#include <mk_core/mk_core_info.h>
+
+#ifdef _WIN32
+#include "external/dirent.h"
+#else
+#include <dirent.h>
+#endif
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_event.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_event.h
new file mode 100644
index 000000000..e1990e878
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_event.h
@@ -0,0 +1,156 @@
+/* -*- 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 <stdint.h>
+#include "mk_macros.h"
+#include "mk_list.h"
+
+#ifndef MK_EVENT_H
+#define MK_EVENT_H
+
+/* Events type family */
+#define MK_EVENT_UNMODIFIED -1 /* keep old event type */
+#define MK_EVENT_NOTIFICATION 0 /* notification channel (pipe) */
+#define MK_EVENT_LISTENER 1 /* listener socket */
+#define MK_EVENT_FIFO 2 /* FIFO - Messaging */
+#define MK_EVENT_CONNECTION 3 /* data on active connection */
+#define MK_EVENT_CUSTOM 4 /* custom fd registered */
+#define MK_EVENT_THREAD 5 /* thread-coroutine */
+
+/* Event triggered for file descriptors */
+#define MK_EVENT_EMPTY 0
+#define MK_EVENT_READ 1
+#define MK_EVENT_WRITE 4
+#define MK_EVENT_SLEEP 8
+#define MK_EVENT_CLOSE (16 | 8 | 8192)
+#define MK_EVENT_IDLE (16 | 8)
+
+/* The event queue size */
+#define MK_EVENT_QUEUE_SIZE 256
+
+/* Events behaviors */
+#define MK_EVENT_LEVEL 256
+#define MK_EVENT_EDGE 512
+
+/* Event status */
+#define MK_EVENT_NONE 1 /* nothing */
+#define MK_EVENT_REGISTERED 2 /* event is registered into the ev loop */
+
+/* Priority bucket queue */
+#define MK_EVENT_PRIORITY_DEFAULT 6 /* default priority */
+
+/* Legacy definitions: temporal
+ * ----------------------------
+ *
+ * Once a connection is dropped, define
+ * a reason.
+ */
+#define MK_EP_SOCKET_CLOSED 0
+#define MK_EP_SOCKET_ERROR 1
+#define MK_EP_SOCKET_TIMEOUT 2
+#define MK_EP_SOCKET_DONE 3
+/* ---- end ---- */
+
+
+#define MK_EVENT_IS_REGISTERED(event) ((event->status & MK_EVENT_REGISTERED) != 0)
+
+#if defined(_WIN32)
+ #include "mk_event_libevent.h"
+#elif defined(MK_HAVE_EVENT_SELECT)
+ #include "mk_event_select.h"
+#elif defined(__linux__) && !defined(LINUX_KQUEUE)
+ #include "mk_event_epoll.h"
+#else
+ #include "mk_event_kqueue.h"
+#endif
+
+#if defined(_WIN32)
+ #define mk_event_closesocket(s) evutil_closesocket(s)
+#else
+ #define mk_event_closesocket(s) close(s)
+#endif
+
+/* Event reported by the event loop */
+struct mk_event {
+ int fd; /* monitored file descriptor */
+ int type; /* event type */
+ uint32_t mask; /* events mask */
+ uint8_t status; /* internal status */
+ void *data; /* custom data reference */
+
+ /* function handler for custom type */
+ int (*handler)(void *data);
+ struct mk_list _head;
+ struct mk_list _priority_head;
+ char priority; /* optional priority */
+};
+
+struct mk_event_loop {
+ int size; /* size of events array */
+ int n_events; /* number of events reported */
+ struct mk_event *events; /* copy or reference of events triggered */
+ void *data; /* mk_event_ctx_t from backend */
+};
+
+static inline void MK_EVENT_INIT(struct mk_event *ev, int fd, void *data,
+ int (*callback)(void *))
+{
+ ev->fd = fd;
+ ev->type = MK_EVENT_CUSTOM;
+ ev->mask = MK_EVENT_EMPTY;
+ ev->status = MK_EVENT_NONE;
+ ev->data = data;
+ ev->handler = callback;
+}
+
+static inline void MK_EVENT_ZERO(struct mk_event *e)
+{
+ MK_EVENT_INIT(e, -1, NULL, NULL);
+}
+
+static inline void MK_EVENT_NEW(struct mk_event *e)
+{
+ e->mask = MK_EVENT_EMPTY;
+ e->status = MK_EVENT_NONE;
+}
+
+int mk_event_init();
+int mk_event_initialize();
+struct mk_event_loop *mk_event_loop_create(int size);
+void mk_event_loop_destroy(struct mk_event_loop *loop);
+int mk_event_add(struct mk_event_loop *loop, int fd,
+ int type, uint32_t mask, void *data);
+int mk_event_del(struct mk_event_loop *loop, struct mk_event *event);
+int mk_event_inject(struct mk_event_loop *loop, struct mk_event *event,
+ int flags, int prevent_duplication);
+int mk_event_timeout_create(struct mk_event_loop *loop,
+ time_t sec, long nsec,void *data);
+int mk_event_timeout_disable(struct mk_event_loop *loop, void *data);
+int mk_event_timeout_destroy(struct mk_event_loop *loop, void *data);
+int mk_event_channel_create(struct mk_event_loop *loop,
+ int *r_fd, int *w_fd, void *data);
+int mk_event_channel_destroy(struct mk_event_loop *loop,
+ int r_fd, int w_fd, void *data);
+int mk_event_wait(struct mk_event_loop *loop);
+int mk_event_wait_2(struct mk_event_loop *loop, int timeout);
+int mk_event_translate(struct mk_event_loop *loop);
+char *mk_event_backend();
+struct mk_event_fdt *mk_event_get_fdt();
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_event_epoll.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_event_epoll.h
new file mode 100644
index 000000000..5180ef8b7
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_event_epoll.h
@@ -0,0 +1,44 @@
+/* -*- 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 <sys/epoll.h>
+
+#ifndef MK_EVENT_EPOLL_H
+#define MK_EVENT_EPOLL_H
+
+struct mk_event_ctx {
+ int efd;
+ int queue_size;
+ struct epoll_event *events;
+};
+
+#define mk_event_foreach(event, evl) \
+ int __i; \
+ struct mk_event_ctx *__ctx = evl->data; \
+ \
+ if (evl->n_events > 0) { \
+ event = __ctx->events[0].data.ptr; \
+ } \
+ \
+ for (__i = 0; \
+ __i < evl->n_events; \
+ __i++, \
+ event = ((__i < evl->n_events) ? __ctx->events[__i].data.ptr : NULL) \
+ )
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_event_kqueue.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_event_kqueue.h
new file mode 100644
index 000000000..ad6c1b9a2
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_event_kqueue.h
@@ -0,0 +1,72 @@
+/* -*- 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.
+ */
+
+
+#ifndef MK_EVENT_KQUEUE_H
+#define MK_EVENT_KQUEUE_H
+
+#ifndef __linux__
+ #include <sys/types.h>
+ #include <sys/event.h>
+ #include <sys/time.h>
+#endif
+
+#ifdef LINUX_KQUEUE
+ #include <kqueue/sys/event.h>
+
+ /* Not defined */
+ #ifndef NOTE_SECONDS
+ #define NOTE_SECONDS 0x00000001
+ #endif
+#endif
+
+struct mk_event_ctx {
+ int kfd;
+ int queue_size;
+ struct kevent *events;
+};
+
+static inline int filter_mask(int16_t f)
+{
+ if (f == EVFILT_READ) {
+ return MK_EVENT_READ;
+ }
+
+ if (f == EVFILT_WRITE) {
+ return MK_EVENT_WRITE;
+ }
+
+ return 0;
+}
+
+
+#define mk_event_foreach(event, evl) \
+ int __i; \
+ struct mk_event_ctx *__ctx = evl->data; \
+ \
+ if (evl->n_events > 0) { \
+ event = __ctx->events[0].udata; \
+ } \
+ \
+ for (__i = 0; \
+ __i < evl->n_events; \
+ __i++, \
+ event = ((__i < evl->n_events) ? __ctx->events[__i].udata : NULL) \
+ )
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_event_libevent.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_event_libevent.h
new file mode 100644
index 000000000..543788dd6
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_event_libevent.h
@@ -0,0 +1,45 @@
+/* -*- 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.
+ */
+
+#ifndef MK_EVENT_LIBEVENT_H
+#define MK_EVENT_LIBEVENT_H
+
+#include <event.h>
+
+struct mk_event_ctx {
+ size_t queue_size;
+ int fired_count;
+ struct event_base *base;
+ struct mk_event *fired; /* used to create iteration array */
+};
+
+#define mk_event_foreach(event, evl) \
+ int __i; \
+ struct mk_event_ctx *__ctx = evl->data; \
+ \
+ if (evl->n_events > 0) { \
+ event = __ctx->fired[0].data; \
+ } \
+ \
+ for (__i = 0; \
+ __i < evl->n_events; \
+ __i++, \
+ event = ((__i < evl->n_events) ? __ctx->fired[__i].data : NULL) \
+ )
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_event_select.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_event_select.h
new file mode 100644
index 000000000..b69c0ba38
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_event_select.h
@@ -0,0 +1,59 @@
+/* -*- 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.
+ */
+
+#ifndef MK_EVENT_SELECT_H
+#define MK_EVENT_SELECT_H
+
+#ifdef _WIN32
+#include <Winsock2.h>
+#else
+#include <sys/select.h>
+#endif
+
+struct mk_event_ctx {
+ int max_fd;
+
+ /* Original set of file descriptors */
+ fd_set rfds;
+ fd_set wfds;
+
+ /* Populated before every select(2) */
+ fd_set _rfds;
+ fd_set _wfds;
+
+ int queue_size;
+ struct mk_event **events; /* full array to register all events */
+ struct mk_event *fired; /* used to create iteration array */
+};
+
+#define mk_event_foreach(event, evl) \
+ int __i; \
+ struct mk_event_ctx *__ctx = evl->data; \
+ \
+ if (evl->n_events > 0) { \
+ event = __ctx->fired[0].data; \
+ } \
+ \
+ for (__i = 0; \
+ __i < evl->n_events; \
+ __i++, \
+ event = ((__i < evl->n_events) ? __ctx->fired[__i].data : NULL) \
+ )
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_file.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_file.h
new file mode 100644
index 000000000..2ae360471
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_file.h
@@ -0,0 +1,48 @@
+/* -*- 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.
+ */
+
+#ifndef MK_FILE_H
+#define MK_FILE_H
+
+#include <time.h>
+
+#define MK_FILE_EXISTS 1
+#define MK_FILE_READ 2
+#define MK_FILE_EXEC 4
+
+struct file_info
+{
+ size_t size;
+ time_t last_modification;
+
+ /* Suggest flags to open this file */
+ int flags_read_only;
+
+ unsigned char exists;
+ unsigned char is_file;
+ unsigned char is_link;
+ unsigned char is_directory;
+ unsigned char exec_access;
+ unsigned char read_access;
+};
+
+int mk_file_get_info(const char *path, struct file_info *f_info, int mode);
+char *mk_file_to_buffer(const char *path);
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_getopt.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_getopt.h
new file mode 100644
index 000000000..fde355628
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_getopt.h
@@ -0,0 +1,31 @@
+/*-*- 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.
+ */
+
+#ifndef MK_GETOPT_H
+#define MK_GETOPT_H
+
+#include <mk_core/mk_core_info.h>
+
+#ifdef __GNUC__ /* Heaven */
+#include <getopt.h>
+#else /* Not Heaven */
+#include "external/wingetopt.h"
+#endif
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_iov.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_iov.h
new file mode 100644
index 000000000..78152c49e
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_iov.h
@@ -0,0 +1,127 @@
+/* -*- 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.
+ */
+
+#ifndef MK_IOV_H
+#define MK_IOV_H
+
+#include <stdio.h>
+#include "mk_uio.h"
+#include "mk_utils.h"
+#include "mk_macros.h"
+
+/* iov separators */
+#define MK_IOV_CRLF "\r\n"
+#define MK_IOV_CRLFCRLF "\r\n\r\n"
+#define MK_IOV_LF "\n"
+#define MK_IOV_LFLF "\n\n"
+#define MK_IOV_LFLFLFLF "\n\n\n\n"
+#define MK_IOV_SPACE " "
+#define MK_IOV_SLASH "/"
+#define MK_IOV_NONE ""
+#define MK_IOV_EQUAL "="
+
+#include "mk_memory.h"
+
+extern const mk_ptr_t mk_iov_crlf;
+extern const mk_ptr_t mk_iov_lf;
+extern const mk_ptr_t mk_iov_space;
+extern const mk_ptr_t mk_iov_slash;
+extern const mk_ptr_t mk_iov_none;
+extern const mk_ptr_t mk_iov_equal;
+
+struct mk_iov {
+ int iov_idx;
+ int buf_idx;
+ int size;
+ unsigned long total_len;
+ struct mk_iovec *io;
+ void **buf_to_free;
+};
+
+struct mk_iov *mk_iov_create(int n, int offset);
+struct mk_iov *mk_iov_realloc(struct mk_iov *mk_io, int new_size);
+
+int mk_iov_add_separator(struct mk_iov *mk_io, mk_ptr_t sep);
+
+ssize_t mk_iov_send(int fd, struct mk_iov *mk_io);
+
+void mk_iov_free(struct mk_iov *mk_io);
+
+int _mk_iov_add(struct mk_iov *mk_io, void *buf, int len,
+ mk_ptr_t sep, int free, int idx);
+
+int mk_iov_set_entry(struct mk_iov *mk_io, void *buf, int len,
+ int free, int idx);
+
+void mk_iov_separators_init(void);
+void mk_iov_free_marked(struct mk_iov *mk_io);
+void mk_iov_print(struct mk_iov *mk_io);
+int mk_iov_consume(struct mk_iov *mk_io, size_t bytes);
+
+/* Initialize an IOV instance */
+static inline int mk_iov_init(struct mk_iov *iov, int n, int offset)
+{
+ int i;
+
+ iov->iov_idx = offset;
+ iov->buf_idx = 0;
+ iov->total_len = 0;
+ iov->size = n;
+
+ /*
+ * Make sure to set to zero initial entries when an offset
+ * is specified
+ */
+ if (offset > 0) {
+ for (i = 0; i < offset; i++) {
+ iov->io[i].iov_base = NULL;
+ iov->io[i].iov_len = 0;
+ }
+ }
+
+ return 0;
+}
+
+static inline void _mk_iov_set_free(struct mk_iov *mk_io, void *buf)
+{
+ mk_io->buf_to_free[mk_io->buf_idx] = (void *) buf;
+ mk_io->buf_idx++;
+}
+
+static inline int mk_iov_add(struct mk_iov *mk_io, void *buf, int len,
+ int free)
+{
+ mk_io->io[mk_io->iov_idx].iov_base = (unsigned char *) buf;
+ mk_io->io[mk_io->iov_idx].iov_len = len;
+ mk_io->iov_idx++;
+ mk_io->total_len += len;
+
+ if (free == MK_TRUE) {
+ _mk_iov_set_free(mk_io, buf);
+ }
+
+ if (mk_io->iov_idx > mk_io->size) {
+ MK_TRACE("[iov] buffer without space");
+ return -1;
+ }
+
+ return mk_io->iov_idx;
+}
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_limits.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_limits.h
new file mode 100644
index 000000000..0d5358b75
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_limits.h
@@ -0,0 +1,32 @@
+/* -*- 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.
+ */
+
+#ifndef MK_LIMITS_H
+#define MK_LIMITS_H
+
+/* Configuration */
+#define MK_HOSTNAME_LEN 64
+
+/* Networking */
+#define MK_SOMAXCONN 128
+
+/* File system */
+#define MK_PATH_BASE 128
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_list.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_list.h
new file mode 100644
index 000000000..0a87381a8
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_list.h
@@ -0,0 +1,244 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/* Monkey HTTP Server
+ * ==================
+ * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io>
+ * Copyright (C) 2010, Jonathan Gonzalez V. <zeus@gnu.org>
+ *
+ * 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.
+ */
+
+#ifndef MK_LIST_H_
+#define MK_LIST_H_
+
+#include <stddef.h>
+#include "mk_macros.h"
+
+#ifdef _WIN32
+/* Windows */
+#define container_of(address, type, field) ((type *)( \
+ (PCHAR)(address) - \
+ (ULONG_PTR)(&((type *)0)->field)))
+#else
+/* Rest of the world */
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+#endif
+
+struct mk_list
+{
+ struct mk_list *prev, *next;
+};
+
+static inline void mk_list_init(struct mk_list *list)
+{
+ list->next = list;
+ list->prev = list;
+}
+
+static inline void __mk_list_add(struct mk_list *_new, struct mk_list *prev,
+ struct mk_list *next)
+{
+ next->prev = _new;
+ _new->next = next;
+ _new->prev = prev;
+ prev->next = _new;
+}
+
+static inline void mk_list_add(struct mk_list *_new, struct mk_list *head)
+{
+ __mk_list_add(_new, head->prev, head);
+}
+
+static inline void mk_list_add_after(struct mk_list *_new,
+ struct mk_list *prev,
+ struct mk_list *head)
+{
+ struct mk_list *next;
+
+ if (head->prev == head->next || head->prev == prev) {
+ mk_list_add(_new, head);
+ return;
+ }
+
+ next = prev->next;
+ _new->next = next;
+ _new->prev = prev;
+ prev->next = _new;
+ next->prev = _new;
+}
+
+static inline int mk_list_is_empty(struct mk_list *head)
+{
+ if (head->next == head) return 0;
+ else return -1;
+}
+
+static inline void mk_list_add_before(struct mk_list *_new,
+ struct mk_list *next,
+ struct mk_list *head)
+{
+ struct mk_list *prev;
+
+ if (_new == NULL || next == NULL || head == NULL) {
+ return;
+ }
+
+ if (mk_list_is_empty(head) == 0 /*empty*/||
+ next == head) {
+ mk_list_add(_new, head);
+ return;
+ }
+
+ prev = next->prev;
+ _new->next = next;
+ _new->prev = prev;
+ prev->next = _new;
+ next->prev = _new;
+}
+
+static inline void mk_list_append(struct mk_list *_new, struct mk_list *head)
+{
+ if (mk_list_is_empty(head) == 0) {
+ __mk_list_add(_new, head->prev, head);
+ }
+ else {
+ mk_list_add_after(_new,
+ head->prev,
+ head);
+ }
+}
+
+static inline void mk_list_prepend(struct mk_list *_new, struct mk_list *head)
+{
+ if (mk_list_is_empty(head) == 0) {
+ __mk_list_add(_new, head->prev, head);
+ }
+ else {
+ mk_list_add_before(_new,
+ head->next,
+ head);
+ }
+}
+
+static inline void __mk_list_del(struct mk_list *prev, struct mk_list *next)
+{
+ prev->next = next;
+ next->prev = prev;
+}
+
+static inline void mk_list_del(struct mk_list *entry)
+{
+ __mk_list_del(entry->prev, entry->next);
+ entry->prev = NULL;
+ entry->next = NULL;
+}
+
+static inline int mk_list_is_set(struct mk_list *head)
+{
+ if (head->next && head->prev) {
+ return 0;
+ }
+
+ return -1;
+}
+
+static inline int mk_list_size(struct mk_list *head)
+{
+ int ret = 0;
+ struct mk_list *it;
+ for (it = head->next; it != head; it = it->next, ret++);
+ return ret;
+}
+
+static inline void mk_list_entry_init(struct mk_list *list)
+{
+ list->next = NULL;
+ list->prev = NULL;
+}
+
+static inline int mk_list_entry_is_orphan(struct mk_list *head)
+{
+ if (head->next != NULL &&
+ head->prev != NULL) {
+ return MK_FALSE;
+ }
+
+ return MK_TRUE;
+}
+
+static inline int mk_list_entry_orphan(struct mk_list *head)
+{
+ if (head->next && head->prev) {
+ return 0;
+ }
+
+ return -1;
+}
+
+static inline void mk_list_cat(struct mk_list *list, struct mk_list *head)
+{
+ struct mk_list *last;
+
+ last = head->prev;
+ last->next = list->next;
+ list->next->prev = last;
+ list->prev->next = head;
+ head->prev = list->prev;
+}
+
+#define mk_list_foreach(curr, head) for( curr = (head)->next; curr != (head); curr = curr->next )
+#define mk_list_foreach_safe(curr, n, head) \
+ for (curr = (head)->next, n = curr->next; curr != (head); curr = n, n = curr->next)
+
+
+#define mk_list_foreach_r(curr, head) for( curr = (head)->prev; curr != (head); curr = curr->prev )
+#define mk_list_foreach_safe_r(curr, n, head) \
+ for (curr = (head)->prev, n = curr->prev; curr != (head); curr = n, n = curr->prev)
+
+#define mk_list_entry( ptr, type, member ) container_of( ptr, type, member )
+
+/*
+ * First node of the list
+ * ----------------------
+ * Be careful with this Macro, its intended to be used when some node is already linked
+ * to the list (ptr). If the list is empty it will return the list address as it points
+ * to it self: list == list->prev == list->next.
+ *
+ * If exists some possiblity that your code handle an empty list, use mk_list_is_empty()
+ * previously to check if its empty or not.
+ */
+#define mk_list_entry_first(ptr, type, member) container_of((ptr)->next, type, member)
+
+/* First node of the list
+ * ---------------------
+ * Be careful with this Macro, its intended to be used when some node is already linked
+ * to the list (ptr). If the list is empty it will return the list address as it points
+ * to it self: list == list->prev == list->next.
+ *
+ * If exists some possiblity that your code handle an empty list, use mk_list_is_empty()
+ * previously to check if its empty or not.
+ */
+#define mk_list_entry_last(ptr, type, member) container_of((ptr)->prev, type, member)
+
+/* Next node */
+#define mk_list_entry_next(ptr, type, member, head) \
+ (ptr)->next == (head) ? container_of((head)->next, type, member) : \
+ container_of((ptr)->next, type, member);
+
+#endif /* !MK_LIST_H_ */
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_macros.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_macros.h
new file mode 100644
index 000000000..f5179faa1
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_macros.h
@@ -0,0 +1,184 @@
+/* -*- 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.
+ */
+
+#ifndef MK_MACROS_H
+#define MK_MACROS_H
+
+#include <stdlib.h>
+#include "mk_limits.h"
+
+/* Boolean */
+#define MK_FALSE 0
+#define MK_TRUE !MK_FALSE
+#define MK_ERROR -1
+
+/* Architecture */
+#define INTSIZE sizeof(int)
+
+/* Print macros */
+#define MK_INFO 0x1000
+#define MK_ERR 0X1001
+#define MK_WARN 0x1002
+#define MK_BUG 0x1003
+
+#define mk_info(...) mk_print(MK_INFO, __VA_ARGS__)
+#define mk_err(...) mk_print(MK_ERR, __VA_ARGS__)
+#define mk_warn(...) mk_print(MK_WARN, __VA_ARGS__)
+
+/* ANSI Colors */
+#ifndef _MSC_VER
+#define ANSI_RESET "\033[0m"
+#define ANSI_BOLD "\033[1m"
+#define ANSI_CYAN "\033[96m"
+#define ANSI_MAGENTA "\033[95m"
+#define ANSI_RED "\033[91m"
+#define ANSI_YELLOW "\033[93m"
+#define ANSI_BLUE "\033[94m"
+#define ANSI_GREEN "\033[92m"
+#define ANSI_WHITE "\033[97m"
+#else
+#define ANSI_RESET ""
+#define ANSI_BOLD ""
+#define ANSI_CYAN ""
+#define ANSI_MAGENTA ""
+#define ANSI_RED ""
+#define ANSI_YELLOW ""
+#define ANSI_BLUE ""
+#define ANSI_GREEN ""
+#define ANSI_WHITE ""
+#endif
+
+#define ANSI_BOLD_CYAN ANSI_BOLD ANSI_CYAN
+#define ANSI_BOLD_MAGENTA ANSI_BOLD ANSI_MAGENTA
+#define ANSI_BOLD_RED ANSI_BOLD ANSI_RED
+#define ANSI_BOLD_YELLOW ANSI_BOLD ANSI_YELLOW
+#define ANSI_BOLD_BLUE ANSI_BOLD ANSI_BLUE
+#define ANSI_BOLD_GREEN ANSI_BOLD ANSI_GREEN
+#define ANSI_BOLD_WHITE ANSI_BOLD ANSI_WHITE
+
+/* Tags */
+#define MK_BANNER_ENTRY ANSI_BOLD "[" ANSI_GREEN "+" ANSI_RESET ANSI_BOLD "] " \
+ ANSI_RESET
+
+/* Transport type */
+#define MK_TRANSPORT_HTTP "http"
+#define MK_TRANSPORT_HTTPS "https"
+
+#ifndef ARRAY_SIZE
+# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+#endif
+
+#ifdef __GNUC__ /* GCC supports this since 2.3. */
+ #define PRINTF_WARNINGS(a,b) __attribute__ ((format (printf, a, b)))
+#else
+ #define PRINTF_WARNINGS(a,b)
+#endif
+
+#ifdef __GNUC__ /* GCC supports this since 2.7. */
+ #define UNUSED_PARAM __attribute__ ((unused))
+#else
+ #define UNUSED_PARAM
+#endif
+
+/*
+ * Validation macros
+ * -----------------
+ * Based on article http://lwn.net/Articles/13183/
+ *
+ * ---
+ * ChangeSet 1.803, 2002/10/18 16:28:57-07:00, torvalds@home.transmeta.com
+ *
+ * Make a polite version of BUG_ON() - WARN_ON() which doesn't
+ * kill the machine.
+ *
+ * Damn I hate people who kill the machine for no good reason.
+ * ---
+ *
+ */
+
+#ifdef __GNUC__
+ #define mk_unlikely(x) __builtin_expect((x),0)
+ #define mk_likely(x) __builtin_expect((x),1)
+ #define mk_prefetch(x, ...) __builtin_prefetch(x, __VA_ARGS__)
+#else
+ #define mk_unlikely(x) (x)
+ #define mk_likely(x) (x)
+ #define mk_prefetch(x, ...) (x, __VA_ARGS__)
+#endif
+
+#define mk_is_bool(x) ((x == MK_TRUE || x == MK_FALSE) ? 1 : 0)
+
+#define mk_bug(condition) do { \
+ if (mk_unlikely((condition)!=0)) { \
+ mk_print(MK_BUG, "Bug found in %s() at %s:%d", \
+ __FUNCTION__, __FILE__, __LINE__); \
+ abort(); \
+ } \
+ } while(0)
+
+#define mk_exception() do { \
+ mk_print(MK_WARN, "Exception found in %s() at %s:%d", \
+ __FUNCTION__, __FILE__, __LINE__); \
+ } while(0)
+
+/*
+ * Macros to calculate sub-net data using ip address and sub-net prefix. Macros
+ * written by Zeus (@sxd).
+ *
+ * Zeus, why the hell you did not documented the macros data type ???.
+ *
+ * addr = struct in_addr -> s_addr.
+ * pos = numeric position for the octect (0, 1, 2..)
+ * net = integer representing the short network mask (e.g: /24)
+ */
+
+#define MK_NET_IP_OCTECT(addr,pos) (addr >> (8 * pos) & 255)
+#define MK_NET_NETMASK(addr,net) htonl((0xffffffff << (32 - net)))
+#define MK_NET_BROADCAST(addr,net) (addr | ~MK_NET_NETMASK(addr,net))
+#define MK_NET_NETWORK(addr,net) (addr & MK_NET_NETMASK(addr,net))
+#define MK_NET_WILDCARD(addr,net) (MK_NET_BROADCAST(addr,net) ^ MK_NET_NETWORK(addr,net))
+#define MK_NET_HOSTMIN(addr,net) net == 31 ? MK_NET_NETWORK(addr,net) : (MK_NET_NETWORK(addr,net) + 0x01000000)
+#define MK_NET_HOSTMAX(addr,net) net == 31 ? MK_NET_BROADCAST(addr,net) : (MK_NET_BROADCAST(addr,net) - 0x01000000)
+
+#ifdef __GNUC__
+ #if __GNUC__ >= 4
+ #define MK_EXPORT __attribute__ ((visibility ("default")))
+ #else
+ #define MK_EXPORT
+ #endif
+#elif defined(_WIN32)
+ #define MK_EXPORT __declspec(dllexport)
+#endif
+
+#ifdef _WIN32
+ #define MK_INLINE __forceinline
+#else
+ #define MK_INLINE inline __attribute__((always_inline))
+#endif
+
+/* Some old libc do not declare O_CLOEXEC */
+#ifndef O_CLOEXEC
+#define O_CLOEXEC 02000000 /* set close_on_exec */
+#endif
+
+/* Wrapper (mk_utils) libc error helpers */
+#define mk_libc_error(c) mk_utils_libc_error(c, __FILE__, __LINE__)
+#define mk_libc_warn(c) mk_utils_libc_warn(c, __FILE__, __LINE__)
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_memory.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_memory.h
new file mode 100644
index 000000000..6da593454
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_memory.h
@@ -0,0 +1,125 @@
+/* -*- 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.
+ */
+
+#ifndef MK_MEM_H
+#define MK_MEM_H
+
+#include <stdio.h>
+
+#ifdef MALLOC_JEMALLOC
+#include <jemalloc/jemalloc.h>
+#endif
+
+#include "mk_macros.h"
+
+typedef struct
+{
+ char *data;
+ unsigned long len;
+} mk_ptr_t;
+
+#ifdef __GNUC__
+ #if ((__GNUC__ * 100 + __GNUC__MINOR__) > 430) /* gcc version > 4.3 */
+ #define ALLOCSZ_ATTR(x,...) __attribute__ ((alloc_size(x, ##__VA_ARGS__)))
+ #else
+ #define ALLOCSZ_ATTR(x,...)
+ #endif
+#else
+ #define ALLOCSZ_ATTR(x,...)
+#endif
+
+static inline ALLOCSZ_ATTR(1)
+void *mk_mem_alloc(const size_t size)
+{
+#ifdef MALLOC_JEMALLOC
+ void *aux = je_malloc(size);
+#else
+ void *aux = malloc(size);
+#endif
+
+ if (mk_unlikely(!aux && size)) {
+ perror("malloc");
+ return NULL;
+ }
+
+ return aux;
+}
+
+static inline ALLOCSZ_ATTR(1)
+void *mk_mem_alloc_z(const size_t size)
+{
+#ifdef MALLOC_JEMALLOC
+ void *buf = je_calloc(1, size);
+#else
+ void *buf = calloc(1, size);
+#endif
+
+ if (mk_unlikely(!buf)) {
+ return NULL;
+ }
+
+ return buf;
+}
+
+static inline ALLOCSZ_ATTR(2)
+void *mk_mem_realloc(void *ptr, const size_t size)
+{
+#ifdef MALLOC_JEMALLOC
+ void *aux = je_realloc(ptr, size);
+#else
+ void *aux = realloc(ptr, size);
+#endif
+
+ if (mk_unlikely(!aux && size)) {
+ perror("realloc");
+ return NULL;
+ }
+
+ return aux;
+}
+
+static inline void mk_mem_free(void *ptr)
+{
+#ifdef MALLOC_JEMALLOC
+ je_free(ptr);
+#else
+ free(ptr);
+#endif
+}
+
+void mk_mem_free(void *ptr);
+void mk_mem_pointers_init(void);
+
+/* mk_ptr_t_* */
+mk_ptr_t mk_ptr_create(char *buf, long init, long end);
+void mk_ptr_free(mk_ptr_t * p);
+void mk_ptr_print(mk_ptr_t p);
+char *mk_ptr_to_buf(mk_ptr_t p);
+void mk_ptr_set(mk_ptr_t * p, char *data);
+
+static inline void mk_ptr_reset(mk_ptr_t * p)
+{
+ p->data = NULL;
+ p->len = 0;
+}
+
+
+#define mk_ptr_init(a) {a, sizeof(a) - 1}
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_pipe.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_pipe.h
new file mode 100644
index 000000000..ae2b4c25f
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_pipe.h
@@ -0,0 +1,32 @@
+/*-*- 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.
+ */
+
+#ifndef MK_PIPE_H
+#define MK_PIPE_H
+
+#include <mk_core/mk_core_info.h>
+
+/* For Windows we need a workaround to play with pipe(2) */
+#ifdef _WIN32
+#include <io.h>
+#include <fcntl.h>
+#define pipe(fds) _pipe(fds, 4096, _O_BINARY)
+#endif
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_pthread.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_pthread.h
new file mode 100644
index 000000000..b9a7de60f
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_pthread.h
@@ -0,0 +1,31 @@
+/*-*- 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.
+ */
+
+#ifndef MK_PTHREAD_H
+#define MK_PTHREAD_H
+
+#include <mk_core/mk_core_info.h>
+
+#if defined (MK_THREADS_POSIX) /* Heaven */
+#include <pthread.h>
+#elif defined (MK_THREADS_WIN32) /* Not Heaven */
+#include "external/winpthreads.h"
+#endif
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_rconf.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_rconf.h
new file mode 100644
index 000000000..800e0087c
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_rconf.h
@@ -0,0 +1,92 @@
+/* -*- 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.
+ */
+
+#ifndef MK_RCONF_H
+#define MK_RCONF_H
+
+#include <limits.h>
+
+#include "mk_list.h"
+#include "mk_memory.h"
+
+#define MK_RCONF_ON "on"
+#define MK_RCONF_OFF "off"
+
+#define MK_RCONF_STR 0
+#define MK_RCONF_NUM 1
+#define MK_RCONF_BOOL 2
+#define MK_RCONF_LIST 3
+
+/* default buffer size when reading a configuration line */
+#define MK_RCONF_KV_SIZE 4096
+
+struct mk_rconf_section
+{
+ char *name;
+
+ struct mk_list entries;
+ struct mk_list _head;
+};
+
+struct mk_rconf_entry
+{
+ char *key;
+ char *val;
+
+ struct mk_list _head;
+};
+
+struct mk_rconf_file
+{
+ char *path;
+ struct mk_list _head;
+};
+
+
+struct mk_rconf
+{
+ int level;
+ int created;
+ char *file;
+ char *root_path;
+
+ /* included files */
+ struct mk_list includes;
+
+ /* meta instructions */
+ struct mk_list metas;
+
+ /* list of sections */
+ struct mk_list sections;
+};
+
+void mk_rconf_free(struct mk_rconf *conf);
+void mk_rconf_free_entries(struct mk_rconf_section *section);
+
+struct mk_rconf *mk_rconf_open(const char *path);
+struct mk_rconf *mk_rconf_create(const char *path);
+struct mk_rconf_section *mk_rconf_section_add(struct mk_rconf *conf,
+ char *name);
+struct mk_rconf_section *mk_rconf_section_get(struct mk_rconf *conf,
+ const char *name);
+void *mk_rconf_section_get_key(struct mk_rconf_section *section,
+ char *key, int mode);
+char *mk_rconf_meta_get(struct mk_rconf *conf, char *key);
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_sleep.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_sleep.h
new file mode 100644
index 000000000..44f4d5aa6
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_sleep.h
@@ -0,0 +1,59 @@
+/*-*- 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.
+ */
+
+#ifndef MK_SLEEP_H
+#define MK_SLEEP_H
+
+#include <mk_core/mk_core_info.h>
+
+#ifdef __GNUC__ /* Heaven */
+#include <time.h>
+#include <unistd.h>
+#elif _WIN32 /* Not Heaven */
+
+/* WIN32 conversion */
+#define sleep(x) _sleep(x * 1000)
+
+#define _WINSOCKAPI_
+#include <windows.h> /* WinAPI */
+
+/* Windows sleep in 100ns units */
+static inline BOOLEAN nanosleep(LONGLONG ns){
+ /* Declarations */
+ HANDLE timer; /* Timer handle */
+ LARGE_INTEGER li; /* Time defintion */
+ /* Create timer */
+ if(!(timer = CreateWaitableTimer(NULL, TRUE, NULL)))
+ return FALSE;
+ /* Set timer properties */
+ li.QuadPart = -ns;
+ if(!SetWaitableTimer(timer, &li, 0, NULL, NULL, FALSE)){
+ CloseHandle(timer);
+ return FALSE;
+ }
+ /* Start & wait for timer */
+ WaitForSingleObject(timer, INFINITE);
+ /* Clean resources */
+ CloseHandle(timer);
+ /* Slept without problems */
+ return TRUE;
+}
+#endif
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_string.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_string.h
new file mode 100644
index 000000000..dddf9c6ce
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_string.h
@@ -0,0 +1,97 @@
+/* -*- 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.
+ */
+
+#ifndef MK_STR_H
+#define MK_STR_H
+
+#include <stdint.h>
+#include <mk_core/mk_core_info.h>
+#include "mk_memory.h"
+#include "mk_list.h"
+#include "mk_macros.h"
+
+#if defined(_WIN32) || defined(_WIN64)
+ #define snprintf _snprintf
+ #define vsnprintf _vsnprintf
+ #define strcasecmp _stricmp
+ #define strncasecmp _strnicmp
+#endif
+
+/* Case sensitive OFF */
+#define MK_STR_SENSITIVE 0
+
+/* Case sensitive ON */
+#define MK_STR_INSENSITIVE 1
+
+struct mk_string_line
+{
+ char *val;
+ int len;
+
+ struct mk_list _head;
+};
+
+#if !defined(MK_HAVE_MEMRCHR)
+void *memrchr(const void *s, int c, size_t n);
+#endif
+
+#ifndef MK_HAVE_MEMMEM
+void *memmem(const void *haystack, size_t haystacklen,
+ const void *needle, size_t needlelen);
+#endif
+
+/* Lookup char into string, return position */
+int mk_string_char_search(const char *string, int c, int len);
+
+/* Find char into string searching in reverse order, returns position */
+int mk_string_char_search_r(const char *string, int c, int len);
+
+/* Locate a substring, returns the position of the substring */
+int mk_string_search(const char *haystack, const char *needle, int sensitive);
+
+/* Locate a substring, compare the first n bytes of haystack */
+int mk_string_search_n(const char *haystack, const char *needle, int sensitive, int len);
+
+char *mk_string_remove_space(char *buf);
+char *mk_string_casestr(char *heystack, char *needle);
+char *mk_string_dup(const char *s);
+struct mk_list *mk_string_split_line(const char *line);
+void mk_string_split_free(struct mk_list *list);
+int mk_string_trim(char **str);
+char *mk_string_build(char **buffer, unsigned long *len,
+ const char *format, ...) PRINTF_WARNINGS(3,4);
+
+#if defined (__GNUC__) || defined (_WIN32)
+int mk_string_itop(uint64_t value, mk_ptr_t *p);
+#endif
+
+char *mk_string_copy_substr(const char *string, int pos_init, int pos_end);
+
+char *mk_string_tolower(const char *in);
+
+#if defined (__APPLE__) || defined (_WIN32)
+void *memrchr(const void *s, int c, size_t n);
+#endif
+
+#ifdef _WIN32
+char *strndup (const char *s, size_t n);
+char *strcasestr(const char *phaystack, const char *pneedle);
+#endif
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_thread.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_thread.h
new file mode 100644
index 000000000..411769e9b
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_thread.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/* Monkey HTTP Server (Duda I/O)
+ * -----------------------------
+ * Copyright 2017 Eduardo Silva <eduardo@monkey.io>
+ * Copyright 2014, Zeying Xie <swpdtz at gmail dot com>
+ *
+ * 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.
+ */
+
+#ifndef MK_THREAD_H
+#define MK_THREAD_H
+
+#include <mk_core/mk_pthread.h>
+#include "mk_thread_channel.h"
+
+#define MK_THREAD_DEAD 0
+#define MK_THREAD_READY 1
+#define MK_THREAD_RUNNING 2
+#define MK_THREAD_SUSPEND 3
+
+pthread_key_t mk_thread_scheduler;
+
+typedef void (*mk_thread_func)(void *data);
+
+struct mk_thread_scheduler *mk_thread_open();
+void mk_thread_close(struct mk_thread_scheduler *sch);
+
+int mk_thread_create(mk_thread_func func, void *data);
+int mk_thread_status(int id);
+void mk_thread_yield();
+void mk_thread_resume(int id);
+int mk_thread_running();
+
+void mk_thread_add_channel(int id, struct mk_thread_channel *chan);
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_thread_channel.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_thread_channel.h
new file mode 100644
index 000000000..de91ce9c1
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_thread_channel.h
@@ -0,0 +1,127 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/* Monkey HTTP Server (Duda I/O)
+ * -----------------------------
+ * Copyright 2017 Eduardo Silva <eduardo@monkey.io>
+ * Copyright 2014, Zeying Xie <swpdtz at gmail dot com>
+ *
+ * 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.
+ */
+
+#ifndef MK_THREAD_CHANNEL_H
+#define MK_THREAD_CHANNEL_H
+
+#include <errno.h>
+#include "mk_list.h"
+
+#define MK_THREAD_CHANNEL_OK 0
+#define MK_THREAD_CHANNEL_BROKEN -EPIPE
+
+struct mk_thread_channel {
+ int size;
+ int used;
+ struct mk_list bufs;
+ int sender;
+ int receiver;
+ int ended;
+ int done;
+ struct mk_list _head;
+};
+
+/*
+ * @METHOD_NAME: chan_get_sender
+ * @METHOD_DESC: get sender of the given channel.
+ * @METHOD_PROTO: int chan_get_sender(mk_thread_channel_t *chan)
+ * @METHOD_PARAM: chan the target channel.
+ * @METHOD_RETURN: the dthread id of sender of the channel.
+ */
+static inline int mk_thread_channel_get_sender(struct mk_thread_channel *chan)
+{
+ return chan->sender;
+}
+
+/*
+ * @METHOD_NAME: chan_set_sender
+ * @METHOD_DESC: set sender of the given channel.
+ * @METHOD_PROTO: void chan_set_sender(mk_thread_channel_t *chan, int sender)
+ * @METHOD_PARAM: chan the target channel.
+ * @METHOD_PARAM: sender the dthread id of target sender.
+ * @METHOD_RETURN: this method do not return any value.
+ */
+static inline void mk_thread_channel_set_sender(struct mk_thread_channel *chan,
+ int sender)
+{
+ chan->sender = sender;
+}
+
+/*
+ * @METHOD_NAME: chan_get_receiver
+ * @METHOD_DESC: get receiver of the given channel.
+ * @METHOD_PROTO: int chan_get_receiver(mk_thread_channel_t *chan)
+ * @METHOD_PARAM: chan the target channel.
+ * @METHOD_RETURN: the dthread id of receiver of the channel.
+ */
+static inline int mk_thread_channel_get_receiver(struct mk_thread_channel *chan)
+{
+ return chan->receiver;
+}
+
+void mk_thread_add_channel(int id, struct mk_thread_channel *chan);
+
+/*
+ * @METHOD_NAME: chan_set_receiver
+ * @METHOD_DESC: set receiver of the given channel.
+ * @METHOD_PROTO: void chan_set_receiver(mk_thread_channel_t *chan, int receiver)
+ * @METHOD_PARAM: chan the target channel.
+ * @METHOD_PARAM: receiver the dthread id of target receiver.
+ * @METHOD_RETURN: this method do not return any value.
+ */
+static inline void mk_thread_channel_set_receiver(struct mk_thread_channel *chan,
+ int receiver)
+{
+ chan->receiver = receiver;
+ mk_thread_add_channel(receiver, chan);
+}
+
+/*
+ * @METHOD_NAME: chan_done
+ * @METHOD_DESC: whether the channel is no longer necessary(this will be the case
+ * that a channel is empty and the sender won't send any more).
+ * @METHOD_PROTO: int chan_done(mk_thread_channel_t *chan)
+ * @METHOD_PARAM: chan the target channel.
+ * @METHOD_RETURN: returns 1 if the channel is no longer necessary, otherwise 0.
+ */
+static inline int mk_thread_channel_done(struct mk_thread_channel *chan)
+{
+ return chan->done;
+}
+
+/*
+ * @METHOD_NAME: chan_end
+ * @METHOD_DESC: it is used by the sender to tell the channel no more data will be
+ * sent.
+ * @METHOD_PROTO: void chan_end(mk_thread_channel_t *chan)
+ * @METHOD_PARAM: chan the target channel.
+ * @METHOD_RETURN: this method do not return any value.
+ */
+static inline void mk_thread_channel_end(struct mk_thread_channel *chan)
+{
+ chan->ended = 1;
+}
+
+struct mk_thread_channel *mk_thread_channel_create(int size);
+void mk_thread_channel_free(struct mk_thread_channel *chan);
+int mk_thread_channel_send(struct mk_thread_channel *chan, void *data);
+void *mk_thread_channel_recv(struct mk_thread_channel *chan);
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_uio.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_uio.h
new file mode 100644
index 000000000..8bb9a3ac9
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_uio.h
@@ -0,0 +1,13 @@
+#ifndef MK_UIO_H
+#define MK_UIO_H
+
+#include <mk_core/mk_core_info.h>
+
+#ifdef MK_HAVE_SYS_UIO_H
+#include <sys/uio.h>
+#define mk_iovec iovec
+#else
+#include "external/winuio.h"
+#endif
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_unistd.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_unistd.h
new file mode 100644
index 000000000..45df7fc4d
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_unistd.h
@@ -0,0 +1,31 @@
+/* -*- 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.
+ */
+
+#ifndef MK_UNISTD_H
+#define MK_UNISTD_H
+
+#include <mk_core/mk_core_info.h>
+
+#ifdef MK_HAVE_UNISTD_H
+#include <unistd.h>
+#else
+#include "mk_dep_unistd.h"
+#endif
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_utils.h b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_utils.h
new file mode 100644
index 000000000..2a91af65b
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_core/mk_utils.h
@@ -0,0 +1,115 @@
+/* -*- 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.
+ */
+
+#ifndef MK_CORE_UTILS_H
+#define MK_CORE_UTILS_H
+
+#include "mk_macros.h"
+
+#include <string.h>
+#include <errno.h>
+
+#include "mk_pthread.h"
+
+/* Trace definitions */
+#ifdef MK_HAVE_TRACE
+
+#define MK_TRACE_CORE 0
+#define MK_TRACE_PLUGIN 1
+#define MK_TRACE_COMP_CORE "mk"
+
+#define MK_TRACE(...) mk_utils_trace(MK_TRACE_COMP_CORE, MK_TRACE_CORE, \
+ __FUNCTION__, __FILENAME__, __LINE__, __VA_ARGS__)
+
+#else
+
+#ifdef MK_TRACE
+#undef MK_TRACE
+#endif
+
+#define MK_TRACE(...) do {} while (0)
+#endif
+
+void mk_print(int type, const char *format, ...) PRINTF_WARNINGS(2,3);
+
+#ifdef MK_HAVE_TRACE
+void mk_utils_trace(const char *component, int color, const char *function,
+ char *file, int line, const char* format, ...);
+int mk_utils_print_errno(int n);
+#endif
+
+
+/* Thread key to hold a re-entrant buffer for strerror formatting */
+#define MK_UTILS_ERROR_SIZE 128
+extern pthread_key_t mk_utils_error_key;
+
+/* Windows don't have strerror_r, instead it have strerror_s */
+#ifdef _WIN32
+ /* Reset as this is defined by mk_pthread.h */
+ #ifdef strerror_r
+ #undef strerror_r
+ #endif
+ #define strerror_r(errno, buf, len) strerror_s(buf, len, errno)
+#elif !defined(__APPLE__) && !defined(__unix__)
+ #ifdef __cplusplus
+ extern "C"
+ {
+ #endif
+ extern int __xpg_strerror_r(int errcode,char* buffer,size_t length);
+ #define strerror_r __xpg_strerror_r
+ #ifdef __cplusplus
+ }
+ #endif
+#endif
+
+/*
+ * Helpers to format and print out common errno errors.
+ */
+#define MK_UTILS_LIBC_ERRNO_BUFFER() \
+ char buf[MK_UTILS_ERROR_SIZE]; \
+ int _err; \
+ _err = errno; \
+ if (strerror_r(_err, buf, MK_UTILS_ERROR_SIZE) != 0) { \
+ mk_err("strerror_r() failed"); \
+ }
+
+static inline void mk_utils_libc_error(char *caller, char *file, int line)
+{
+ MK_UTILS_LIBC_ERRNO_BUFFER();
+ mk_err("%s: %s, errno=%i at %s:%i", caller, buf, _err, file, line);
+}
+
+static inline void mk_utils_libc_warn(char *caller, char *file, int line)
+{
+ MK_UTILS_LIBC_ERRNO_BUFFER();
+ mk_warn("%s: %s, errno=%i at %s:%i", caller, buf, _err, file, line);
+}
+
+int mk_utils_worker_spawn(void (*func) (void *), void *arg, pthread_t *tid);
+int mk_utils_worker_rename(const char *title);
+
+#ifndef _WIN32
+int mk_utils_set_daemon();
+int mk_utils_register_pid(char *path);
+int mk_utils_remove_pid(char *path);
+#endif
+
+int mk_core_init();
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_env.h.in b/src/fluent-bit/lib/monkey/include/monkey/mk_env.h.in
new file mode 100644
index 000000000..33e6a8661
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_env.h.in
@@ -0,0 +1,26 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/* Monkey HTTP Server
+ * ==================
+ * Copyright 2001-2015 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.
+ */
+
+#ifndef MK_ENV_H
+#define MK_ENV_H
+
+#define CC "@CMAKE_C_COMPILER@"
+#define AR "@CMAKE_AR@"
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_fifo.h b/src/fluent-bit/lib/monkey/include/monkey/mk_fifo.h
new file mode 100644
index 000000000..39fa450a0
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_fifo.h
@@ -0,0 +1,97 @@
+/* -*- 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.
+ */
+
+#ifndef MK_FIFO_H
+#define MK_FIFO_H
+
+#include <monkey/mk_info.h>
+#include <monkey/mk_config.h>
+#include <monkey/mk_core.h>
+
+#define MK_FIFO_BUF_SIZE 32768
+
+#ifdef _WIN32
+#ifdef _WIN64
+typedef long long mk_fifo_channel_fd;
+#else
+typedef long long mk_fifo_channel_fd;
+#endif
+#else
+typedef int mk_fifo_channel_fd;
+#endif
+
+struct mk_fifo_worker {
+ struct mk_event event; /* event loop 'event' */
+ int worker_id; /* worker ID */
+ mk_fifo_channel_fd channel[2]; /* pipe(2) communication channel */
+ void *data; /* opaque data for thread */
+
+ /* Read buffer */
+ char *buf_data;
+ size_t buf_len;
+ size_t buf_size;
+
+ void *fifo; /* original FIFO context associated with */
+ struct mk_list _head; /* link to paremt mk_msg.workers list */
+};
+
+struct mk_fifo_msg {
+ uint32_t length;
+ uint16_t flags;
+ uint16_t queue_id;
+ char data[];
+};
+
+struct mk_fifo_queue {
+ uint16_t id; /* queue id */
+ char name[16]; /* queue name */
+ struct mk_list _head; /* link to parent mk_msg.queues list */
+
+ /*
+ * Callback function to be used by message reader once a complete
+ * message is ready to be processed. This callback is invoked
+ * from a thread context (pipe read end).
+ */
+ void (*cb_message)(struct mk_fifo_queue *, void *, size_t, void *);
+ void *data;
+};
+
+struct mk_fifo {
+ pthread_key_t *key; /* pthread key */
+ pthread_mutex_t mutex_init; /* pthread mutex used for initialization */
+ void *data; /* opate data context */
+ struct mk_list queues; /* list of registered queues */
+ struct mk_list workers; /* context for Monkey workers */
+};
+
+void mk_fifo_worker_setup(void *data);
+int mk_fifo_worker_read(void *event);
+
+struct mk_fifo *mk_fifo_create(pthread_key_t *key, void *data);
+int mk_fifo_queue_create(struct mk_fifo *ctx, char *name,
+ void (*cb)(struct mk_fifo_queue *, void *,
+ size_t, void *),
+ void *data);
+struct mk_fifo_queue *mk_fifo_queue_get(struct mk_fifo *ctx, int id);
+int mk_fifo_queue_destroy(struct mk_fifo *ctx, struct mk_fifo_queue *q);
+int mk_fifo_queue_id_destroy(struct mk_fifo *ctx, int id);
+int mk_fifo_destroy(struct mk_fifo *ctx);
+int mk_fifo_send(struct mk_fifo *ctx, int id, void *data, size_t size);
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_header.h b/src/fluent-bit/lib/monkey/include/monkey/mk_header.h
new file mode 100644
index 000000000..df1205a53
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_header.h
@@ -0,0 +1,113 @@
+/* -*- 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.
+ */
+
+#ifndef MK_HEADER_H
+#define MK_HEADER_H
+
+#include "mk_http.h"
+#include "mk_http_status.h"
+
+#define MK_HEADER_BREAKLINE 1
+
+/*
+ * header response: We handle this as static global data in order
+ * to save some process time when building the response header.
+ */
+
+/* Informational */
+#define MK_RH_INFO_CONTINUE "HTTP/1.1 100 Continue\r\n"
+#define MK_RH_INFO_SWITCH_PROTOCOL "HTTP/1.1 101 Switching Protocols\r\n"
+
+/* Successfull */
+#define MK_RH_HTTP_OK "HTTP/1.1 200 OK\r\n"
+#define MK_RH_HTTP_CREATED "HTTP/1.1 201 Created\r\n"
+#define MK_RH_HTTP_ACCEPTED "HTTP/1.1 202 Accepted\r\n"
+#define MK_RH_HTTP_NON_AUTH_INFO "HTTP/1.1 203 Non-Authoritative Information\r\n"
+#define MK_RH_HTTP_NOCONTENT "HTTP/1.1 204 No Content\r\n"
+#define MK_RH_HTTP_RESET "HTTP/1.1 205 Reset Content\r\n"
+#define MK_RH_HTTP_PARTIAL "HTTP/1.1 206 Partial Content\r\n"
+
+/* Redirections */
+#define MK_RH_REDIR_MULTIPLE "HTTP/1.1 300 Multiple Choices\r\n"
+#define MK_RH_REDIR_MOVED "HTTP/1.1 301 Moved Permanently\r\n"
+#define MK_RH_REDIR_MOVED_T "HTTP/1.1 302 Found\r\n"
+#define MK_RH_REDIR_SEE_OTHER "HTTP/1.1 303 See Other\r\n"
+#define MK_RH_NOT_MODIFIED "HTTP/1.1 304 Not Modified\r\n"
+#define MK_RH_REDIR_USE_PROXY "HTTP/1.1 305 Use Proxy\r\n"
+
+/* Client side errors */
+#define MK_RH_CLIENT_BAD_REQUEST "HTTP/1.1 400 Bad Request\r\n"
+#define MK_RH_CLIENT_UNAUTH "HTTP/1.1 401 Unauthorized\r\n"
+#define MK_RH_CLIENT_PAYMENT_REQ "HTTP/1.1 402 Payment Required\r\n"
+#define MK_RH_CLIENT_FORBIDDEN "HTTP/1.1 403 Forbidden\r\n"
+#define MK_RH_CLIENT_NOT_FOUND "HTTP/1.1 404 Not Found\r\n"
+#define MK_RH_CLIENT_METHOD_NOT_ALLOWED "HTTP/1.1 405 Method Not Allowed\r\n"
+#define MK_RH_CLIENT_NOT_ACCEPTABLE "HTTP/1.1 406 Not Acceptable\r\n"
+#define MK_RH_CLIENT_PROXY_AUTH "HTTP/1.1 407 Proxy Authentication Required\r\n"
+#define MK_RH_CLIENT_REQUEST_TIMEOUT "HTTP/1.1 408 Request Timeout\r\n"
+#define MK_RH_CLIENT_CONFLICT "HTTP/1.1 409 Conflict\r\n"
+#define MK_RH_CLIENT_GONE "HTTP/1.1 410 Gone\r\n"
+#define MK_RH_CLIENT_LENGTH_REQUIRED "HTTP/1.1 411 Length Required\r\n"
+#define MK_RH_CLIENT_PRECOND_FAILED "HTTP/1.1 412 Precondition Failed\r\n"
+#define MK_RH_CLIENT_REQUEST_ENTITY_TOO_LARGE \
+ "HTTP/1.1 413 Request Entity Too Large\r\n"
+#define MK_RH_CLIENT_REQUEST_URI_TOO_LONG "HTTP/1.1 414 Request-URI Too Long\r\n"
+#define MK_RH_CLIENT_UNSUPPORTED_MEDIA "HTTP/1.1 415 Unsupported Media Type\r\n"
+#define MK_RH_CLIENT_REQUESTED_RANGE_NOT_SATISF \
+ "HTTP/1.1 416 Requested Range Not Satisfiable\r\n"
+
+/* Server side errors */
+#define MK_RH_SERVER_INTERNAL_ERROR "HTTP/1.1 500 Internal Server Error\r\n"
+#define MK_RH_SERVER_NOT_IMPLEMENTED "HTTP/1.1 501 Not Implemented\r\n"
+#define MK_RH_SERVER_BAD_GATEWAY "HTTP/1.1 502 Bad Gateway\r\n"
+#define MK_RH_SERVER_SERVICE_UNAV "HTTP/1.1 503 Service Unavailable\r\n"
+#define MK_RH_SERVER_GATEWAY_TIMEOUT "HTTP/1.1 504 Gateway Timeout\r\n"
+#define MK_RH_SERVER_HTTP_VERSION_UNSUP "HTTP/1.1 505 HTTP Version Not Supported\r\n"
+
+struct header_status_response {
+ int status;
+ int length;
+ char *response;
+};
+
+#define MK_HEADER_TE_TYPE_CHUNKED 0
+#define MK_HEADER_CONN_UPGRADED 11
+#define MK_HEADER_UPGRADED_H2C 20
+
+extern const mk_ptr_t mk_header_short_date;
+extern const mk_ptr_t mk_header_short_location;
+extern const mk_ptr_t mk_header_short_ct;
+
+/* mk pointers with response server headers */
+extern const mk_ptr_t mk_header_conn_ka;
+extern const mk_ptr_t mk_header_conn_close;
+extern const mk_ptr_t mk_header_content_length;
+extern const mk_ptr_t mk_header_content_encoding;
+extern const mk_ptr_t mk_header_accept_ranges;
+extern const mk_ptr_t mk_header_te_chunked;
+extern const mk_ptr_t mk_header_last_modified;
+
+int mk_header_prepare(struct mk_http_session *cs, struct mk_http_request *sr,
+ struct mk_server *server);
+
+void mk_header_response_reset(struct response_headers *header);
+void mk_header_set_http_status(struct mk_http_request *sr, int status);
+void mk_header_set_content_length(struct mk_http_request *sr, long len);
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_http.h b/src/fluent-bit/lib/monkey/include/monkey/mk_http.h
new file mode 100644
index 000000000..42204f9c6
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_http.h
@@ -0,0 +1,225 @@
+/* -*- 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.
+ */
+
+#ifndef MK_HTTP_H
+#define MK_HTTP_H
+
+#include <monkey/mk_scheduler.h>
+#include <monkey/mk_core.h>
+#include <monkey/mk_http_parser.h>
+
+#define MK_CRLF "\r\n"
+
+/* Request buffer chunks = 4KB */
+#define MK_REQUEST_CHUNK (int) 4096
+#define MK_REQUEST_DEFAULT_PAGE "<HTML><HEAD><STYLE type=\"text/css\"> body {font-size: 12px;} </STYLE></HEAD><BODY><H1>%s</H1>%s<BR><HR><ADDRESS>Powered by %s</ADDRESS></BODY></HTML>"
+
+/* Hard coded restrictions */
+#define MK_HTTP_DIRECTORY_BACKWARD ".."
+
+#define MK_METHOD_GET_STR "GET"
+#define MK_METHOD_POST_STR "POST"
+#define MK_METHOD_HEAD_STR "HEAD"
+#define MK_METHOD_PUT_STR "PUT"
+#define MK_METHOD_DELETE_STR "DELETE"
+#define MK_METHOD_OPTIONS_STR "OPTIONS"
+
+/* Headers */
+#define RH_ACCEPT "Accept:"
+#define RH_ACCEPT_CHARSET "Accept-Charset:"
+#define RH_ACCEPT_ENCODING "Accept-Encoding:"
+#define RH_ACCEPT_LANGUAGE "Accept-Language:"
+#define RH_CONNECTION "Connection:"
+#define RH_COOKIE "Cookie:"
+#define RH_CONTENT_LENGTH "Content-Length:"
+#define RH_CONTENT_RANGE "Content-Range:"
+#define RH_CONTENT_TYPE "Content-Type:"
+#define RH_IF_MODIFIED_SINCE "If-Modified-Since:"
+#define RH_HOST "Host:"
+#define RH_LAST_MODIFIED "Last-Modified:"
+#define RH_LAST_MODIFIED_SINCE "Last-Modified-Since:"
+#define RH_REFERER "Referer:"
+#define RH_RANGE "Range:"
+#define RH_USER_AGENT "User-Agent:"
+
+#define MK_REQUEST_STATUS_INCOMPLETE -1
+#define MK_REQUEST_STATUS_COMPLETED 0
+
+#define MK_EXIT_OK 0
+#define MK_EXIT_ERROR -1
+#define MK_EXIT_ABORT -2
+#define MK_EXIT_PCONNECTION 24
+
+/* Available methods */
+#define MK_HTTP_METHOD_AVAILABLE \
+ MK_HTTP_METHOD_GET_STR "," MK_HTTP_METHOD_POST_STR "," \
+ MK_HTTP_METHOD_HEAD_STR "," MK_HTTP_METHOD_PUT_STR "," \
+ MK_HTTP_METHOD_DELETE_STR "," MK_HTTP_METHOD_OPTIONS_STR \
+ MK_CRLF
+
+#define MK_HTTP_PROTOCOL_UNKNOWN (-1)
+#define MK_HTTP_PROTOCOL_09 (9)
+#define MK_HTTP_PROTOCOL_10 (10)
+#define MK_HTTP_PROTOCOL_11 (11)
+
+#define MK_HTTP_PROTOCOL_09_STR "HTTP/0.9"
+#define MK_HTTP_PROTOCOL_10_STR "HTTP/1.0"
+#define MK_HTTP_PROTOCOL_11_STR "HTTP/1.1"
+
+extern const mk_ptr_t mk_http_method_get_p;
+extern const mk_ptr_t mk_http_method_post_p;
+extern const mk_ptr_t mk_http_method_head_p;
+extern const mk_ptr_t mk_http_method_put_p;
+extern const mk_ptr_t mk_http_method_delete_p;
+extern const mk_ptr_t mk_http_method_options_p;
+extern const mk_ptr_t mk_http_method_null_p;
+
+extern const mk_ptr_t mk_http_protocol_09_p;
+extern const mk_ptr_t mk_http_protocol_10_p;
+extern const mk_ptr_t mk_http_protocol_11_p;
+extern const mk_ptr_t mk_http_protocol_null_p;
+
+/*
+ * A HTTP session represents an incoming session
+ * from a client, a session can be used for pipelined or
+ * keepalive requests.
+ */
+
+struct mk_http_session
+{
+ /*
+ * The first field of the struct appended to the sched_conn memory
+ * space needs to be an integer, the scheduler will set this flag
+ * to MK_FALSE to indicate it was just created. This work as a helper
+ * to the protocol handler.
+ *
+ * C rule: a pointer to a structure always points to it's first member.
+ */
+ int _sched_init; /* initialized ? */
+
+ int socket; /* socket associated */
+ int pipelined; /* Pipelined request */
+ int counter_connections; /* Count persistent connections */
+ int status; /* Request status */
+ int close_now; /* Close the session ASAP */
+
+ struct mk_channel *channel;
+ struct mk_sched_conn *conn;
+
+ unsigned int body_size;
+ unsigned int body_length;
+
+ /* head for mk_http_request list nodes, each request is linked here */
+ struct mk_list request_list;
+
+ /* creation time for this HTTP session */
+ time_t init_time;
+
+ /* request body buffer */
+ char *body;
+
+ /* Initial fixed size buffer for small requests */
+ char body_fixed[MK_REQUEST_CHUNK];
+
+ /*
+ * FIXME: in previous versions of Monkey we used to parse the complete request
+ * for pipelined requests and generate a linked lists of request. With the new
+ * parser we are taking the approach to parse one request and process it before
+ * parsing others, from that point of view we should not need a linked list
+ * of requests.
+ *
+ * Still testing...
+ */
+ struct mk_http_request sr_fixed;
+
+ /*
+ * Parser context: we only held one parser per connection
+ * which is re-used everytime we have a new request.
+ */
+ struct mk_http_parser parser;
+
+ /* Server context */
+ struct mk_server *server;
+};
+
+static inline int mk_http_status_completed(struct mk_http_session *cs,
+ struct mk_sched_conn *conn)
+{
+ (void) conn;
+
+ if (cs->status == MK_REQUEST_STATUS_COMPLETED) {
+ MK_TRACE("HTTP Completed but already completed, aborting conx");
+ return -1;
+ }
+
+ cs->status = MK_REQUEST_STATUS_COMPLETED;
+ return 0;
+}
+
+int mk_http_error(int http_status, struct mk_http_session *cs,
+ struct mk_http_request *sr,
+ struct mk_server *server);
+
+int mk_http_method_check(mk_ptr_t method);
+mk_ptr_t mk_http_method_check_str(int method);
+int mk_http_method_get(char *body);
+
+int mk_http_protocol_check(char *protocol, int len);
+mk_ptr_t mk_http_protocol_check_str(int protocol);
+
+int mk_http_init(struct mk_http_session *cs, struct mk_http_request *sr,
+ struct mk_server *server);
+
+int mk_http_keepalive_check(struct mk_http_session *cs,
+ struct mk_http_request *sr,
+ struct mk_server *server);
+
+int mk_http_pending_request(struct mk_http_session *cs);
+int mk_http_send_file(struct mk_http_session *cs, struct mk_http_request *sr);
+
+/* http session */
+int mk_http_session_init(struct mk_http_session *cs,
+ struct mk_sched_conn *conn,
+ struct mk_server *server);
+void mk_http_session_remove(struct mk_http_session *cs,
+ struct mk_server *server);
+
+/* event handlers */
+int mk_http_handler_read(struct mk_sched_conn *conn, struct mk_http_session *cs,
+ struct mk_server *server);
+
+int mk_http_handler_write(int socket, struct mk_http_session *cs);
+
+void mk_http_request_free(struct mk_http_request *sr, struct mk_server *server);
+void mk_http_request_free_list(struct mk_http_session *cs,
+ struct mk_server *server);
+
+void mk_http_request_init(struct mk_http_session *session,
+ struct mk_http_request *request,
+ struct mk_server *server);
+struct mk_http_header *mk_http_header_get(int name, struct mk_http_request *req,
+ const char *key, unsigned int len);
+
+int mk_http_request_end(struct mk_http_session *cs, struct mk_server *server);
+
+#define mk_http_session_get(conn) \
+ (struct mk_http_session *) \
+ (((uint8_t *) conn) + sizeof(struct mk_sched_conn))
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_http2.h b/src/fluent-bit/lib/monkey/include/monkey/mk_http2.h
new file mode 100644
index 000000000..46463632c
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_http2.h
@@ -0,0 +1,182 @@
+/* -*- 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.
+ */
+
+#ifndef MK_HTTP2_H
+#define MK_HTTP2_H
+
+#include <stdint.h>
+#include <monkey/mk_stream.h>
+#include <monkey/mk_http2_settings.h>
+
+/* Connection was just upgraded */
+#define MK_HTTP2_UPGRADED 1
+#define MK_HTTP2_OK 2
+
+/*
+ * The Client 'sent' the SETTINGS frame according to Section 6.5:
+ *
+ * https://httpwg.github.io/specs/rfc7540.html#ConnectionHeader
+ * https://httpwg.github.io/specs/rfc7540.html#SETTINGS
+ */
+#define MK_HTTP2_CLIENT_SETTINGS 2
+
+
+
+/* A buffer chunk size */
+#define MK_HTTP2_CHUNK 4096
+
+#define MK_HTTP2_HEADER_SIZE 9 /* Frame header size */
+
+/*
+ * 4.1 HTTP2 Frame format
+ *
+ * +-----------------------------------------------+
+ * | Length (24) |
+ * +---------------+---------------+---------------+
+ * | Type (8) | Flags (8) |
+ * +-+-------------+---------------+-------------------------------+
+ * |R| Stream Identifier (31) |
+ * +=+=============================================================+
+ * | Frame Payload (0...) ...
+ * +---------------------------------------------------------------+
+ *
+ */
+
+/* Structure to represent an incoming frame (not to write) */
+struct mk_http2_frame {
+ uint32_t len_type; /* (24 length + 8 type) */
+ uint8_t flags;
+ uint32_t stream_id;
+ void *payload;
+};
+
+/* a=target variable, b=bit number to act upon 0-n */
+#define BIT_CLEAR(a,b) ((a) &= ~(1<<(b)))
+
+static inline uint32_t mk_http2_bitdec_32u(uint8_t *b)
+{
+ return (uint32_t) ((b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]);
+}
+
+static inline uint32_t mk_http2_bitdec_stream_id(uint8_t *b)
+{
+ uint32_t sid = mk_http2_bitdec_32u(b);
+ return BIT_CLEAR(sid, 31);
+}
+
+static inline uint8_t mk_http2_frame_type(struct mk_http2_frame *f)
+{
+ return (uint8_t) (0xFFFFFF & f->len_type);
+}
+
+static inline uint32_t mk_http2_frame_len(struct mk_http2_frame *f)
+{
+ return (uint32_t) (f->len_type >> 8);
+}
+
+/* HTTP/2 General flags */
+
+#define MK_HTTP2_SETTINGS_ACK 0x1
+
+/*
+ * HTTP/2 Frame types
+ */
+#define MK_HTTP2_DATA 0x0 /* Section 6.1 */
+#define MK_HTTP2_HEADERS 0x1 /* Section 6.2 */
+#define MK_HTTP2_PRIORITY 0x2 /* Section 6.3 */
+#define MK_HTTP2_RST_STREAM 0x3 /* Section 6.4 */
+#define MK_HTTP2_SETTINGS 0x4 /* Section 6.5 */
+#define MK_HTTP2_PUSH_PROMISE 0x5 /* Section 6.6 */
+#define MK_HTTP2_PING 0x6 /* Section 6.7 */
+#define MK_HTTP2_GOAWAY 0x7 /* Section 6.8 */
+#define MK_HTTP2_WINDOW_UPDATE 0x8 /* Section 6.9 */
+#define MK_HTTP2_CONTINUATION 0x9 /* Section 6.10 */
+
+/*
+ * HTTP/2 Settings Parameters (Section 6.5.2)
+ * ------------------------------------------
+ */
+
+/*
+ * HTTP/2 Error codes
+ * ------------------
+ */
+
+/* The associated condition is not a result of an error */
+#define MK_HTTP2_NO_ERROR 0x0
+/* The endpoint detected an unspecific protocol error */
+#define MK_HTTP2_PROTOCOL_ERROR 0x1
+/* The endpoint encountered an unexpected internal error */
+#define MK_HTTP2_INTERNAL_ERROR 0x2
+/* The endpoint detected that its peer violated the flow-control protocol */
+#define MK_HTTP2_FLOW_CONTROL_ERROR 0x3
+/* The endpoint sent a SETTINGS frame but did not receive a response */
+#define MK_HTTP2_SETTINGS_TIMEOUT 0x4
+/* The endpoint received a frame after a stream was half-closed */
+#define MK_HTTP2_STREAM_CLOSED 0x5
+/* The endpoint received a frame with an invalid size */
+#define MK_HTTP2_FRAME_SIZE_ERROR 0x6
+/* The endpoint refused the stream prior to performing any application processing */
+#define MK_HTTP2_REFUSED_STREAM 0x7
+/* Used by the endpoint to indicate that the stream is no longer needed */
+#define MK_HTTP2_CANCEL 0x8
+/* The endpoint is unable to maintain the header compression context for the connection */
+#define MK_HTTP2_COMPRESSION_ERROR 0x9
+/* The connection established in response to a CONNECT request was reset */
+#define MK_HTTP2_CONNECT_ERROR 0xa
+/* The endpoint detected that its peer is exhibiting a behavior that might be generating excessive load */
+#define MK_HTTP2_ENHANCE_YOUR_CALM 0xb
+/* The underlying transport has properties that do not meet minimum security requirements (see Section 9.2) */
+#define MK_HTTP2_INADEQUATE_SECURITY 0xc
+/* The endpoint requires that HTTP/1.1 be used instead of HTTP/2 */
+#define MK_HTTP2_HTTP_1_1_REQUIRED 0xd
+
+
+#ifdef TRACE
+#define MK_H2_TRACE(conn, fmt, ...) \
+ mk_utils_trace("mk", \
+ MK_TRACE_CORE, \
+ __FUNCTION__, __FILENAME__, __LINE__, \
+ "[%sH2%s] (fd=%i) " fmt, \
+ ANSI_RESET ANSI_WHITE, ANSI_RED, \
+ conn->event.fd, ##__VA_ARGS__)
+#else
+#define MK_H2_TRACE(...) do {} while (0)
+#endif
+
+#define mk_http2_send_raw(conn, buf, length) \
+ mk_stream_set(NULL, MK_STREAM_RAW, &conn->channel, \
+ buf, length, NULL, NULL, NULL, NULL)
+
+struct mk_http2_session {
+ int status;
+
+ /* Buffer used to read data */
+ unsigned int buffer_size;
+ unsigned int buffer_length;
+ char *buffer;
+ char buffer_fixed[MK_HTTP2_CHUNK];
+
+ /* Session Settings */
+ struct mk_http2_settings settings;
+
+ struct mk_stream stream_settings;
+};
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_http2_settings.h b/src/fluent-bit/lib/monkey/include/monkey/mk_http2_settings.h
new file mode 100644
index 000000000..85af39664
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_http2_settings.h
@@ -0,0 +1,71 @@
+/* -*- 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.
+ */
+
+#ifndef MK_HTTP2_SETTINGS_H
+#define MK_HTTP2_SETTINGS_H
+
+struct mk_http2_settings {
+ uint32_t header_table_size;
+ uint32_t enable_push;
+ uint32_t max_concurrent_streams;
+ uint32_t initial_window_size;
+ uint32_t max_frame_size;
+ uint32_t max_header_list_size;
+};
+
+
+const struct mk_http2_settings MK_HTTP2_SETTINGS_DEFAULT =
+ {
+ .header_table_size = 4096,
+ .enable_push = 1,
+ .max_concurrent_streams = 64,
+ .initial_window_size = 65535,
+ .max_frame_size = 16384, /* 6.5.2 -> 2^14 */
+ .max_header_list_size = UINT32_MAX
+ };
+
+/*
+ * Default settings of Monkey, we send this upon a new connection arrives
+ * to the HTTP/2 handler.
+ */
+#define MK_HTTP2_SETTINGS_DEFAULT_FRAME \
+ "\x00\x00\x0c" /* frame length */ \
+ "\x04" /* type=SETTINGS */ \
+ "\x00" /* flags */ \
+ "\x00\x00\x00\x00" /* stream ID */ \
+ \
+ /* SETTINGS_MAX_CONCURRENT_STREAMS */ \
+ "\x00\x03" \
+ "\x00\x00\x00\x40" /* value=64 */ \
+ \
+ /* SETTINGS_INITIAL_WINDOW_SIZE */ \
+ "\x00\x04" \
+ "\x00\x00\xff\xff" /* value=65535 */
+
+#define MK_HTTP2_SETTINGS_ACK_FRAME \
+ "\x00\x00\x00\x04\x01\x00\x00\x00\x00"
+
+#define MK_HTTP2_SETTINGS_HEADER_TABLE_SIZE 0x1
+#define MK_HTTP2_SETTINGS_ENABLE_PUSH 0x2
+#define MK_HTTP2_SETTINGS_MAX_CONCURRENT_STREAMS 0x3
+#define MK_HTTP2_SETTINGS_INITIAL_WINDOW_SIZE 0x4
+#define MK_HTTP2_SETTINGS_MAX_FRAME_SIZE 0x5
+#define MK_HTTP2_SETTINGS_MAX_HEADER_LIST_SIZE 0x6
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_http_internal.h b/src/fluent-bit/lib/monkey/include/monkey/mk_http_internal.h
new file mode 100644
index 000000000..4d82191a6
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_http_internal.h
@@ -0,0 +1,197 @@
+/* -*- 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.
+ */
+
+#ifndef MK_HTTP_INTERNAL_H
+#define MK_HTTP_INTERNAL_H
+
+#include <monkey/mk_stream.h>
+
+#define MK_HEADER_IOV 32
+#define MK_HEADER_ETAG_SIZE 32
+
+struct response_headers
+{
+ int status;
+
+ /* Connection flag, if equal -1, the connection header is ommited */
+ int connection;
+
+ /*
+ * If some plugins wants to set a customized HTTP status, here
+ * is the 'how and where'
+ */
+ mk_ptr_t custom_status;
+
+ /* Length of the content to send */
+ long content_length;
+
+ /* Private value, real length of the file requested */
+ long real_length;
+
+ int cgi;
+ int pconnections_left;
+ int breakline;
+
+ int transfer_encoding;
+
+ int upgrade;
+
+ int ranges[2];
+
+ time_t last_modified;
+ mk_ptr_t allow_methods;
+ mk_ptr_t content_type;
+ mk_ptr_t content_encoding;
+ char *location;
+
+ int etag_len;
+ char etag_buf[MK_HEADER_ETAG_SIZE];
+
+ /*
+ * This field allow plugins to add their own response
+ * headers
+ */
+ struct mk_iov *_extra_rows;
+
+ /* Flag to track if the response headers were sent */
+ int sent;
+
+ /* IOV dirty hack */
+ struct mk_iov headers_iov;
+ struct mk_iovec __iov_io[MK_HEADER_IOV];
+ void *__iov_buf[MK_HEADER_IOV];
+};
+
+struct mk_http_request
+{
+ int status;
+ int protocol;
+
+ /* is it serving a user's home directory ? */
+ int user_home;
+
+ /*-Connection-*/
+ long port;
+ /*------------*/
+
+ /* Body Stream size */
+ uint64_t stream_size;
+
+ /* Streams handling: headers and static file */
+ struct mk_stream stream;
+ struct mk_stream_input in_headers;
+ struct mk_stream_input in_headers_extra;
+ struct mk_stream_input in_file;
+ struct mk_stream_input page_stream;
+
+ int headers_len;
+
+ /*----First header of client request--*/
+ int method;
+ mk_ptr_t method_p;
+ mk_ptr_t uri; /* original request */
+ mk_ptr_t uri_processed; /* processed request (decoded) */
+
+ mk_ptr_t protocol_p;
+
+ mk_ptr_t body;
+
+ /*---Request headers--*/
+ int content_length;
+
+ mk_ptr_t _content_length;
+ mk_ptr_t content_type;
+ mk_ptr_t connection;
+
+ mk_ptr_t host;
+ mk_ptr_t host_port;
+ mk_ptr_t if_modified_since;
+ mk_ptr_t last_modified_since;
+ mk_ptr_t range;
+
+ /*---------------------*/
+
+ /* POST/PUT data */
+ mk_ptr_t data;
+ /*-----------------*/
+
+ /*-Internal-*/
+ mk_ptr_t real_path; /* Absolute real path */
+
+ /*
+ * If a full URL length is less than MAX_PATH_BASE (defined in limits.h),
+ * it will be stored here and real_path will point this buffer
+ */
+ char real_path_static[MK_PATH_BASE];
+
+ /* Query string: ?.... */
+ mk_ptr_t query_string;
+
+
+ /*
+ * STAGE_30 block flag: in mk_http_init() when the file is not found, it
+ * triggers the plugin STAGE_30 to look for a plugin handler. In some
+ * cases the plugin would overwrite the real path of the requested file
+ * and make Monkey handle the new path for the static file. At this point
+ * we need to block STAGE_30 calls from mk_http_init().
+ *
+ * For short.. if a plugin overwrites the real_path, let Monkey handle that
+ * and do not trigger more STAGE_30's.
+ */
+ int stage30_blocked;
+
+ /*
+ * If the connection is being managed by a plugin (e.g: CGI), associate the
+ * plugin reference to the stage30_handler field. This is useful to handle
+ * protocol exception and notify the handlers about it.
+ */
+ void *stage30_handler;
+
+ /* Static file information */
+ int file_fd;
+ struct file_info file_info;
+
+ /* Vhost */
+ int vhost_fdt_id;
+ unsigned int vhost_fdt_hash;
+ int vhost_fdt_enabled;
+
+ struct mk_vhost *host_conf; /* root vhost config */
+ struct mk_vhost_alias *host_alias; /* specific vhost matched */
+
+ /*
+ * Reference used outside of Monkey Core, e.g: Plugins. It can be used
+ * to store some relevant information associated to a request.
+ */
+ void *handler_data;
+
+ /* Parent Session */
+ struct mk_http_session *session;
+
+ /* coroutine thread (if any) */
+ void *thread;
+
+ /* Head to list of requests */
+ struct mk_list _head;
+
+ /* Response headers */
+ struct response_headers headers;
+};
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_http_parser.h b/src/fluent-bit/lib/monkey/include/monkey/mk_http_parser.h
new file mode 100644
index 000000000..6d45c3941
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_http_parser.h
@@ -0,0 +1,348 @@
+/* -*- 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.
+ */
+
+#ifndef MK_HTTP_PARSER_H
+#define MK_HTTP_PARSER_H
+
+#define _GNU_SOURCE
+#include <ctype.h>
+
+#include <monkey/mk_core.h>
+#include <monkey/mk_http.h>
+#include <monkey/mk_http_internal.h>
+
+/* General status */
+#define MK_HTTP_PARSER_PENDING -10 /* cannot complete until more data arrives */
+#define MK_HTTP_PARSER_ERROR -1 /* found an error when parsing the string */
+#define MK_HTTP_PARSER_OK 0 /* parser OK, ready to go */
+
+/* Connection header values */
+#define MK_HTTP_PARSER_CONN_EMPTY 0
+#define MK_HTTP_PARSER_CONN_UNKNOWN -1
+#define MK_HTTP_PARSER_CONN_KA 1
+#define MK_HTTP_PARSER_CONN_CLOSE 2
+#define MK_HTTP_PARSER_CONN_UPGRADE 4
+#define MK_HTTP_PARSER_CONN_HTTP2_SE 8
+
+/* Upgrades supported */
+#define MK_HTTP_PARSER_UPGRADE_NONE 0
+#define MK_HTTP_PARSER_UPGRADE_H2 1
+#define MK_HTTP_PARSER_UPGRADE_H2C 2
+
+#define MK_HEADER_EXTRA_SIZE 50
+
+/* Request levels
+ * ==============
+ *
+ * 1. FIRST_LINE : Method, URI (+ QS) + Protocol version + CRLF
+ * 2. HEADERS (optional) : KEY, SEP, VALUE + CRLF
+ * 3. BODY (option) : data based on Content-Length or Chunked transfer encoding
+ */
+
+enum {
+ REQ_LEVEL_FIRST = 1,
+ REQ_LEVEL_CONTINUE ,
+ REQ_LEVEL_HEADERS ,
+ REQ_LEVEL_END ,
+ REQ_LEVEL_BODY
+};
+
+/* Statuses per levels */
+enum {
+ /* REQ_LEVEL_FIRST */
+ MK_ST_REQ_METHOD = 1,
+ MK_ST_REQ_URI ,
+ MK_ST_REQ_QUERY_STRING ,
+ MK_ST_REQ_PROT_VERSION ,
+ MK_ST_FIRST_CONTINUE ,
+ MK_ST_FIRST_FINALIZING , /* LEVEL_FIRST finalize the request */
+ MK_ST_FIRST_COMPLETE ,
+
+ /* REQ_HEADERS */
+ MK_ST_HEADER_KEY ,
+ MK_ST_HEADER_SEP ,
+ MK_ST_HEADER_VAL_STARTS ,
+ MK_ST_HEADER_VALUE ,
+ MK_ST_HEADER_END ,
+ MK_ST_BLOCK_END
+};
+
+/* Known HTTP Methods */
+enum mk_request_methods {
+ MK_METHOD_GET = 0,
+ MK_METHOD_POST ,
+ MK_METHOD_HEAD ,
+ MK_METHOD_PUT ,
+ MK_METHOD_DELETE ,
+ MK_METHOD_OPTIONS ,
+ MK_METHOD_SIZEOF ,
+ MK_METHOD_UNKNOWN
+};
+
+/*
+ * Define a list of known headers, they are used to perform headers
+ * lookups in the parser and further Monkey core.
+ */
+enum mk_request_headers {
+ MK_HEADER_ACCEPT = 0,
+ MK_HEADER_ACCEPT_CHARSET ,
+ MK_HEADER_ACCEPT_ENCODING ,
+ MK_HEADER_ACCEPT_LANGUAGE ,
+ MK_HEADER_AUTHORIZATION ,
+ MK_HEADER_CACHE_CONTROL ,
+ MK_HEADER_COOKIE ,
+ MK_HEADER_CONNECTION ,
+ MK_HEADER_CONTENT_LENGTH ,
+ MK_HEADER_CONTENT_RANGE ,
+ MK_HEADER_CONTENT_TYPE ,
+ MK_HEADER_HOST ,
+ MK_HEADER_HTTP2_SETTINGS ,
+ MK_HEADER_IF_MODIFIED_SINCE ,
+ MK_HEADER_LAST_MODIFIED ,
+ MK_HEADER_LAST_MODIFIED_SINCE ,
+ MK_HEADER_RANGE ,
+ MK_HEADER_REFERER ,
+ MK_HEADER_UPGRADE ,
+ MK_HEADER_USER_AGENT ,
+ MK_HEADER_SIZEOF ,
+
+ /* used by the core for custom headers */
+ MK_HEADER_OTHER
+};
+
+/*
+ * Expected Header values that are used to take logic
+ * decision.
+ */
+#define MK_CONN_KEEP_ALIVE "keep-alive"
+#define MK_CONN_CLOSE "close"
+#define MK_CONN_UPGRADE "upgrade"
+
+/* HTTP Upgrade options available */
+#define MK_UPGRADE_H2 "h2"
+#define MK_UPGRADE_H2C "h2c"
+
+struct mk_http_header {
+ /* The header type/name, e.g: MK_HEADER_CONTENT_LENGTH */
+ int type;
+
+ /* Reference the header Key name, e.g: 'Content-Lentth' */
+ mk_ptr_t key;
+
+ /* Reference the header Value, e/g: '123456' */
+ mk_ptr_t val;
+
+ /*
+ * Link to head list, it's used to reference this node and
+ * iterate it as a linked list
+ */
+ struct mk_list _head;
+};
+
+/* This structure is the 'Parser Context' */
+struct mk_http_parser {
+ int i;
+ int level; /* request level */
+ int status; /* level status */
+ int next; /* something next after status ? */
+ int length;
+ int method;
+
+ /* lookup fields */
+ int start;
+ int end;
+ int chars;
+
+ /* it stores the numeric value of Content-Length header */
+ int header_host_port;
+
+ long int body_received;
+ long int header_content_length;
+
+ /*
+ * connection header value discovered: it can be set with
+ * values:
+ *
+ * MK_HTTP_PARSER_CONN_EMPTY : header not set
+ * MK_HTTP_PARSER_CONN_UNKNOWN: unexpected value
+ * MK_HTTP_PARSER_CONN_KA : keep-alive
+ * MK_HTTP_PARSER_CONN_CLOSE : close
+ */
+ int header_connection;
+
+ /* upgrade request: we suppport the following values:
+ *
+ * MK_HTTP_PARSER_UPGRADE_H2 : HTTP/2.0 over TLS
+ * MK_HTTP_PARSER_UPGRADE_H2C : HTTP/2.0 (plain TCP)
+ */
+ int header_upgrade;
+
+ /* probable current header, fly parsing */
+ int header_key;
+ int header_sep;
+ int header_val;
+ int header_min;
+ int header_max;
+ int headers_extra_count;
+
+ /* Known headers */
+ struct mk_http_header headers[MK_HEADER_SIZEOF];
+
+ /* Head of linked list for all headers found in the request */
+ int header_count;
+ struct mk_list header_list;
+
+ /* Extra headers */
+ struct mk_http_header headers_extra[MK_HEADER_EXTRA_SIZE];
+};
+
+
+#ifdef HTTP_STANDALONE
+
+/* ANSI Colors */
+
+#define ANSI_RESET "\033[0m"
+#define ANSI_BOLD "\033[1m"
+
+#define ANSI_CYAN "\033[36m"
+#define ANSI_BOLD_CYAN ANSI_BOLD ANSI_CYAN
+#define ANSI_MAGENTA "\033[35m"
+#define ANSI_BOLD_MAGENTA ANSI_BOLD ANSI_MAGENTA
+#define ANSI_RED "\033[31m"
+#define ANSI_BOLD_RED ANSI_BOLD ANSI_RED
+#define ANSI_YELLOW "\033[33m"
+#define ANSI_BOLD_YELLOW ANSI_BOLD ANSI_YELLOW
+#define ANSI_BLUE "\033[34m"
+#define ANSI_BOLD_BLUE ANSI_BOLD ANSI_BLUE
+#define ANSI_GREEN "\033[32m"
+#define ANSI_BOLD_GREEN ANSI_BOLD ANSI_GREEN
+#define ANSI_WHITE "\033[37m"
+#define ANSI_BOLD_WHITE ANSI_BOLD ANSI_WHITE
+
+#define TEST_OK 0
+#define TEST_FAIL 1
+
+
+static inline void p_field(struct mk_http_parser *req, char *buffer)
+{
+ int i;
+
+ printf("'");
+ for (i = req->start; i < req->end; i++) {
+ printf("%c", buffer[i]);
+ }
+ printf("'");
+
+}
+
+static inline int eval_field(struct mk_http_parser *req, char *buffer)
+{
+ if (req->level == REQ_LEVEL_FIRST) {
+ printf("[ \033[35mfirst level\033[0m ] ");
+ }
+ else {
+ printf("[ \033[36mheaders\033[0m ] ");
+ }
+
+ printf(" ");
+ switch (req->status) {
+ case MK_ST_REQ_METHOD:
+ printf("MK_ST_REQ_METHOD : ");
+ break;
+ case MK_ST_REQ_URI:
+ printf("MK_ST_REQ_URI : ");
+ break;
+ case MK_ST_REQ_QUERY_STRING:
+ printf("MK_ST_REQ_QUERY_STRING : ");
+ break;
+ case MK_ST_REQ_PROT_VERSION:
+ printf("MK_ST_REQ_PROT_VERSION : ");
+ break;
+ case MK_ST_HEADER_KEY:
+ printf("MK_ST_HEADER_KEY : ");
+ break;
+ case MK_ST_HEADER_VAL_STARTS:
+ printf("MK_ST_HEADER_VAL_STARTS: ");
+ break;
+ case MK_ST_HEADER_VALUE:
+ printf("MK_ST_HEADER_VALUE : ");
+ break;
+ case MK_ST_HEADER_END:
+ printf("MK_ST_HEADER_END : ");
+ break;
+ default:
+ printf("\033[31mUNKNOWN STATUS (%i)\033[0m : ", req->status);
+ break;
+ };
+
+
+ p_field(req, buffer);
+ printf("\n");
+
+ return 0;
+}
+#endif /* HTTP_STANDALONE */
+
+#define mk_http_set_minor_version(c) \
+ if (c == '1') { \
+ req->protocol = MK_HTTP_PROTOCOL_11; \
+ } \
+ else if (c == '0') { \
+ req->protocol = MK_HTTP_PROTOCOL_10; \
+ } \
+ else { \
+ req->protocol = MK_HTTP_PROTOCOL_UNKNOWN; \
+ }
+
+
+static inline void mk_http_parser_init(struct mk_http_parser *p)
+{
+ memset(p, '\0', sizeof(struct mk_http_parser));
+
+ p->level = REQ_LEVEL_FIRST;
+ p->status = MK_ST_REQ_METHOD;
+ p->chars = -1;
+ p->method = -1;
+
+ /* init headers */
+ p->header_key = -1;
+ p->header_sep = -1;
+ p->header_val = -1;
+ p->header_min = -1;
+ p->header_max = -1;
+ p->header_content_length = -1;
+
+ /* init list header */
+ p->header_count = 0;
+ mk_list_init(&p->header_list);
+}
+
+static inline int mk_http_parser_more(struct mk_http_parser *p, int len)
+{
+ if (abs(len - p->i) - 1 > 0) {
+ return MK_TRUE;
+ }
+
+ return MK_FALSE;
+}
+
+int mk_http_parser(struct mk_http_request *req, struct mk_http_parser *p,
+ char *buffer, int buf_len, struct mk_server *server);
+
+#endif /* MK_HTTP_H */
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_http_status.h b/src/fluent-bit/lib/monkey/include/monkey/mk_http_status.h
new file mode 100644
index 000000000..568bf3802
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_http_status.h
@@ -0,0 +1,84 @@
+/* -*- 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.
+ */
+
+#ifndef MK_HTTP_STATUS_H
+#define MK_HTTP_STATUS_H
+
+#include <monkey/mk_core.h>
+
+/*
+ * - New macro names and structure by Monkey Dev Team
+ * - Initial HTTP Status provided by Juan C. Inostroza <jci@codemonkey.cl>
+ */
+
+/* Monkey allow plugins to set their customized status */
+#define MK_CUSTOM_STATUS 7
+
+/* Informational status */
+#define MK_INFO_CONTINUE 100
+#define MK_INFO_SWITCH_PROTOCOL 101
+
+/* Succesful */
+#define MK_HTTP_OK 200
+#define MK_HTTP_CREATED 201
+#define MK_HTTP_ACCEPTED 202
+#define MK_HTTP_NON_AUTH_INFO 203
+#define MK_HTTP_NOCONTENT 204
+#define MK_HTTP_RESET 205
+#define MK_HTTP_PARTIAL 206
+
+/* Redirections */
+#define MK_REDIR_MULTIPLE 300
+#define MK_REDIR_MOVED 301
+#define MK_REDIR_MOVED_T 302
+#define MK_REDIR_SEE_OTHER 303
+#define MK_NOT_MODIFIED 304
+#define MK_REDIR_USE_PROXY 305
+
+/* Client Errors */
+#define MK_CLIENT_BAD_REQUEST 400
+#define MK_CLIENT_UNAUTH 401
+#define MK_CLIENT_PAYMENT_REQ 402 /* Wtf?! :-) */
+#define MK_CLIENT_FORBIDDEN 403
+#define MK_CLIENT_NOT_FOUND 404
+#define MK_CLIENT_METHOD_NOT_ALLOWED 405
+#define MK_CLIENT_NOT_ACCEPTABLE 406
+#define MK_CLIENT_PROXY_AUTH 407
+#define MK_CLIENT_REQUEST_TIMEOUT 408
+#define MK_CLIENT_CONFLICT 409
+#define MK_CLIENT_GONE 410
+#define MK_CLIENT_LENGTH_REQUIRED 411
+#define MK_CLIENT_PRECOND_FAILED 412
+#define MK_CLIENT_REQUEST_ENTITY_TOO_LARGE 413
+#define MK_CLIENT_REQUEST_URI_TOO_LONG 414
+#define MK_CLIENT_UNSUPPORTED_MEDIA 415
+#define MK_CLIENT_REQUESTED_RANGE_NOT_SATISF 416
+
+/* Server Errors */
+#define MK_SERVER_INTERNAL_ERROR 500
+#define MK_SERVER_NOT_IMPLEMENTED 501
+#define MK_SERVER_BAD_GATEWAY 502
+#define MK_SERVER_SERVICE_UNAV 503
+#define MK_SERVER_GATEWAY_TIMEOUT 504
+#define MK_SERVER_HTTP_VERSION_UNSUP 505
+
+/* Text header messages */
+#define M_HTTP_OK_TXT "HTTP/1.1 200 OK\r\n"
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_http_thread.h b/src/fluent-bit/lib/monkey/include/monkey/mk_http_thread.h
new file mode 100644
index 000000000..9c267d60c
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_http_thread.h
@@ -0,0 +1,61 @@
+/* -*- 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.
+ */
+
+#ifndef MK_HTTP_THREAD_H
+#define MK_HTTP_THREAD_H
+
+#include <monkey/mk_http.h>
+#include <monkey/mk_thread.h>
+#include <monkey/mk_vhost.h>
+
+#define MK_HTTP_THREAD_LIB 0
+#define MK_HTTP_THREAD_PLUGIN 1
+
+struct mk_http_thread {
+ int close; /* Close TCP connection ? */
+ struct mk_http_session *session; /* HTTP session */
+ struct mk_http_request *request; /* HTTP request */
+ struct mk_thread *parent; /* Parent thread */
+ struct mk_list _head; /* Link to worker->threads */
+};
+
+extern MK_TLS_DEFINE(struct mk_http_libco_params, mk_http_thread_libco_params);
+extern MK_TLS_DEFINE(struct mk_thread, mk_thread);
+
+static MK_INLINE void mk_http_thread_resume(struct mk_http_thread *mth)
+{
+ mk_thread_resume(mth->parent);
+}
+
+void mk_http_thread_initialize_tls();
+
+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);
+int mk_http_thread_destroy(struct mk_http_thread *mth);
+
+int mk_http_thread_event(struct mk_event *event);
+
+int mk_http_thread_start(struct mk_http_thread *mth);
+int mk_http_thread_purge(struct mk_http_thread *mth, int close);
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_info.h.in b/src/fluent-bit/lib/monkey/include/monkey/mk_info.h.in
new file mode 100644
index 000000000..a4ef0a127
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_info.h.in
@@ -0,0 +1,45 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/* Monkey HTTP Server
+ * ==================
+ * Copyright 2001-2015 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.
+ */
+
+#ifndef MK_INFO_H
+#define MK_INFO_H
+
+#include <monkey/mk_core.h>
+
+/* Monkey Version */
+#define MK_VERSION_MAJOR @MK_VERSION_MAJOR@
+#define MK_VERSION_MINOR @MK_VERSION_MINOR@
+#define MK_VERSION_PATCH @MK_VERSION_PATCH@
+#define MK_VERSION (MK_VERSION_MAJOR * 10000 \
+ MK_VERSION_MINOR * 100 \
+ MK_VERSION_PATCH)
+#define MK_VERSION_STR "@MK_VERSION_STR@"
+
+/* Build system information */
+#define MK_BUILD_OS "@CMAKE_SYSTEM_NAME@"
+#define MK_BUILD_UNAME "@CMAKE_SYSTEM@"
+#define MK_BUILD_CMD "@MK_BUILD_CMD@"
+
+/* Default paths */
+#define MK_PATH_CONF "@MK_PATH_CONF@"
+#define MK_PLUGIN_DIR "/home/edsiper/coding/monkey/plugins"
+
+/* General flags set by CMakeLists.txt */
+@MK_BUILD_FLAGS@
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_kernel.h b/src/fluent-bit/lib/monkey/include/monkey/mk_kernel.h
new file mode 100644
index 000000000..fcaf56d03
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_kernel.h
@@ -0,0 +1,35 @@
+/* -*- 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.
+ */
+
+#ifndef MK_KERNEL_H
+#define MK_KERNEL_H
+
+/* Server features: depends on server setup and Linux Kernel version */
+#define MK_KERNEL_TCP_FASTOPEN 1
+#define MK_KERNEL_SO_REUSEPORT 2
+#define MK_KERNEL_TCP_AUTOCORKING 4
+
+#define MK_KERNEL_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c))
+
+int mk_kernel_version();
+int mk_kernel_features(int version);
+int mk_kernel_features_print(char *buffer, size_t size,
+ struct mk_server *server);
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_lib.h b/src/fluent-bit/lib/monkey/include/monkey/mk_lib.h
new file mode 100644
index 000000000..d02ac6987
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_lib.h
@@ -0,0 +1,76 @@
+/* -*- 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.
+ */
+
+#ifndef MK_LIB_H
+#define MK_LIB_H
+
+#define _GNU_SOURCE
+
+#include <monkey/mk_info.h>
+#include <monkey/mk_tls.h>
+#include <monkey/mk_vhost.h>
+#include <monkey/mk_config.h>
+#include <monkey/mk_fifo.h>
+#include <monkey/mk_http_internal.h>
+#include <monkey/mk_core.h>
+
+struct mk_lib_ctx {
+ pthread_t worker_tid;
+ struct mk_server *server;
+ struct mk_fifo *fifo;
+};
+
+typedef struct mk_fifo_queue mk_mq_t;
+typedef struct mk_lib_ctx mk_ctx_t;
+typedef struct mk_http_request mk_request_t;
+typedef struct mk_http_session mk_session_t;
+
+MK_EXPORT int mk_start(mk_ctx_t *ctx);
+MK_EXPORT int mk_stop(mk_ctx_t *ctx);
+
+MK_EXPORT mk_ctx_t *mk_create();
+MK_EXPORT int mk_destroy(mk_ctx_t *ctx);
+
+MK_EXPORT int mk_config_set(mk_ctx_t *ctx, ...);
+MK_EXPORT struct mk_vhost *mk_vhost_lookup(mk_ctx_t *ctx, int id);
+MK_EXPORT int mk_vhost_create(mk_ctx_t *ctx, char *name);
+
+MK_EXPORT int mk_vhost_set(mk_ctx_t *ctx, int vid, ...);
+MK_EXPORT int mk_vhost_handler(mk_ctx_t *ctx, int vid, char *regex,
+ void (*cb)(mk_request_t *, void *), void *data);
+
+MK_EXPORT int mk_http_status(mk_request_t *req, int status);
+MK_EXPORT int mk_http_header(mk_request_t *req,
+ char *key, int key_len,
+ char *val, int val_len);
+MK_EXPORT int mk_http_send(mk_request_t *req, char *buf, size_t len,
+ void (*cb_finish)(mk_request_t *));
+MK_EXPORT int mk_http_done(mk_request_t *req);
+
+MK_EXPORT int mk_worker_callback(mk_ctx_t *ctx,
+ void (*cb_func) (void *),
+ void *data);
+//MK_EXPORT int mk_mq_create(mk_ctx_t *ctx, char *name);
+MK_EXPORT int mk_mq_create(mk_ctx_t *ctx, char *name, void (*cb), void *data);
+
+MK_EXPORT int mk_mq_send(mk_ctx_t *ctx, int qid, void *data, size_t size);
+
+MK_EXPORT int mk_main();
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_linuxtrace.h b/src/fluent-bit/lib/monkey/include/monkey/mk_linuxtrace.h
new file mode 100644
index 000000000..abdf88c87
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_linuxtrace.h
@@ -0,0 +1,80 @@
+/* -*- 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.
+ */
+
+#ifdef LINUX_TRACE
+
+#undef TRACEPOINT_PROVIDER
+#define TRACEPOINT_PROVIDER monkey
+
+#if !defined(_MK_LINUXTRACE_PROVIDER_H) || defined(TRACEPOINT_HEADER_MULTI_READ)
+#define _MK_LINUXTRACE_PROVIDER_H
+#include <lttng/tracepoint.h>
+
+/* Trace point for epoll(2) events */
+TRACEPOINT_EVENT(
+ monkey,
+ epoll,
+ TP_ARGS(int, fd,
+ char *, text),
+ TP_FIELDS(
+ ctf_integer(int, fd, fd)
+ ctf_string(event, text)
+ )
+ )
+
+TRACEPOINT_EVENT(
+ monkey,
+ epoll_state,
+ TP_ARGS(int, fd,
+ int, mode,
+ char *, text),
+ TP_FIELDS(
+ ctf_integer(int, fd, fd)
+ ctf_string(event, text)
+ )
+ )
+
+TRACEPOINT_EVENT(
+ monkey,
+ scheduler,
+ TP_ARGS(int, fd,
+ char *, text),
+ TP_FIELDS(ctf_integer(int, fd, fd)
+ ctf_string(event, text))
+ )
+
+#endif
+
+#undef TRACEPOINT_INCLUDE
+#define TRACEPOINT_INCLUDE "./monkey/mk_linuxtrace.h"
+
+#include <lttng/tracepoint-event.h>
+
+/* Monkey Linux Trace helper macros */
+#define MK_LT_EPOLL(fd, event) tracepoint(monkey, epoll, fd, event)
+#define MK_LT_EPOLL_STATE(fd, mode, event) \
+ tracepoint(monkey, epoll_state, fd, mode, event)
+#define MK_LT_SCHED(fd, event) tracepoint(monkey, scheduler, fd, event)
+
+#else /* NO LINUX_TRACE */
+
+#define MK_LT_EPOLL(fd, event) do {} while(0)
+#define MK_LT_EPOLL_STATE(fd, mode, event) do{} while(0)
+#define MK_LT_SCHED(fd, event) do {} while(0)
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_mimetype.h b/src/fluent-bit/lib/monkey/include/monkey/mk_mimetype.h
new file mode 100644
index 000000000..4c45cbde3
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_mimetype.h
@@ -0,0 +1,45 @@
+/* -*- 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_core.h>
+#include <rbtree.h>
+
+#ifndef MK_MIMETYPE_H
+#define MK_MIMETYPE_H
+
+#define MIMETYPE_DEFAULT_TYPE "text/plain\r\n"
+#define MIMETYPE_DEFAULT_NAME "default"
+
+struct mk_mimetype
+{
+ char *name;
+ mk_ptr_t type;
+ mk_ptr_t header_type;
+ struct mk_list _head;
+ struct rb_tree_node _rb_head;
+};
+
+int mk_mimetype_init(struct mk_server *server);
+int mk_mimetype_add(struct mk_server *server, char *name, const char *type);
+int mk_mimetype_read_config(struct mk_server *server);
+struct mk_mimetype *mk_mimetype_find(struct mk_server *server, mk_ptr_t *filename);
+struct mk_mimetype *mk_mimetype_lookup(struct mk_server *server, char *name);
+void mk_mimetype_free_all(struct mk_server *server);
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_net.h b/src/fluent-bit/lib/monkey/include/monkey/mk_net.h
new file mode 100644
index 000000000..1bcfac88f
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_net.h
@@ -0,0 +1,40 @@
+/* -*- 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.
+ */
+
+#ifndef MK_NET_H
+#define MK_NET_H
+
+#include <monkey/mk_core.h>
+#include <monkey/mk_stream.h>
+
+struct mk_net_connection {
+ struct mk_event event;
+ int fd;
+ char *host;
+ int port;
+ void *thread;
+};
+
+int mk_net_init();
+
+struct mk_net_connection *mk_net_conn_create(char *addr, int port);
+int mk_net_conn_write(struct mk_channel *channel,
+ void *data, size_t len);
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_plugin.h b/src/fluent-bit/lib/monkey/include/monkey/mk_plugin.h
new file mode 100644
index 000000000..c180c143a
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_plugin.h
@@ -0,0 +1,384 @@
+/* -*- 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.
+ */
+
+#ifndef MK_PLUGIN_H
+#define MK_PLUGIN_H
+
+#include <monkey/monkey.h>
+#include <monkey/mk_kernel.h>
+#include <monkey/mk_config.h>
+#include <monkey/mk_socket.h>
+#include <monkey/mk_header.h>
+#include <monkey/mk_http_status.h>
+#include <monkey/mk_utils.h>
+#include <monkey/mk_info.h>
+#include <monkey/mk_plugin_net.h>
+#include <monkey/mk_core.h>
+
+#define MK_PLUGIN_ERROR -1 /* plugin execution error */
+#define MK_PLUGIN_
+
+/* Plugin: Stages */
+#define MK_PLUGIN_STAGE_10 (4) /* Connection just accept()ed */
+#define MK_PLUGIN_STAGE_20 (8) /* HTTP Request arrived */
+#define MK_PLUGIN_STAGE_30 (16) /* Object handler */
+#define MK_PLUGIN_STAGE_40 (32) /* Content served */
+#define MK_PLUGIN_STAGE_50 (64) /* Conection ended */
+
+/* Plugin: Network type */
+#define MK_PLUGIN_NETWORK_LAYER (128)
+#define MK_PLUGIN_STAGE (256)
+
+/* Return values */
+#define MK_PLUGIN_RET_NOT_ME -1
+#define MK_PLUGIN_RET_CONTINUE 100
+#define MK_PLUGIN_RET_END 200
+#define MK_PLUGIN_RET_CLOSE_CONX 300
+#define MK_PLUGIN_HEADER_EXTRA_ROWS 18
+
+/* Plugin types */
+#define MK_PLUGIN_STATIC 0 /* built-in into core */
+#define MK_PLUGIN_DYNAMIC 1 /* shared library */
+
+/* Plugin Flags */
+#define MK_PLUGIN_THREAD 1 /* It runs in a Monkey coroutine/thread */
+
+/*
+ * Event return values
+ * -------------------
+ * Any plugin can hook to any socket event, when a worker thread receives
+ * a socket event through epoll(), it will check first the plugins hooks
+ * before return the control to Monkey core.
+ */
+
+ /* The plugin request to the caller to continue invoking next plugins */
+#define MK_PLUGIN_RET_EVENT_NEXT -300
+
+/* The plugin has taken some action and no other plugin should go
+ * over the event in question, return as soon as possible
+ */
+#define MK_PLUGIN_RET_EVENT_OWNED -400
+
+/* The plugin request to finalize the session request */
+#define MK_PLUGIN_RET_EVENT_CLOSE -500
+
+/* The plugin request to the caller skip event hooks */
+#define MK_PLUGIN_RET_EVENT_CONTINUE -600
+
+struct mk_plugin;
+
+/* API functions exported to plugins */
+struct plugin_api
+{
+ /* socket functions */
+ int (*socket_cork_flag) (int, int);
+ int (*socket_reset) (int);
+ int (*socket_set_tcp_fastopen) (int);
+ int (*socket_set_tcp_nodelay) (int);
+ int (*socket_set_tcp_reuseport) (int);
+ int (*socket_connect) (char *, int, int);
+ int (*socket_open) (char *, int);
+ int (*socket_set_nonblocking) (int);
+ int (*socket_create) ();
+ int (*socket_close) (int);
+ int (*socket_read) (int, void *, int);
+ int (*socket_send_file) (int, int, off_t *, size_t);
+ int (*socket_ip_str) (int, char **, int, unsigned long *);
+
+ /* Async Network */
+ struct mk_net_connection *(*net_conn_create) (char *, int);
+
+ struct mk_server_config *config;
+ struct mk_list *plugins;
+
+ /* Error helper */
+ void (*_error) (int, const char *, ...) PRINTF_WARNINGS(2,3);
+
+ /* HTTP request function */
+ int (*http_request_end) (struct mk_plugin *plugin,
+ struct mk_http_session *cs, int close);
+ int (*http_request_error) (int, struct mk_http_session *,
+ struct mk_http_request *, struct mk_plugin *);
+
+ /* memory functions */
+ void *(*mem_alloc) (const size_t size);
+ void *(*mem_alloc_z) (const size_t size);
+ void *(*mem_realloc) (void *, const size_t size);
+ void (*mem_free) (void *);
+ void (*pointer_set) (mk_ptr_t *, char *);
+ void (*pointer_print) (mk_ptr_t);
+ char *(*pointer_to_buf) (mk_ptr_t);
+
+ /* string functions */
+ int (*str_itop) (uint64_t, mk_ptr_t *);
+ int (*str_search) (const char *, const char *, int);
+ int (*str_search_n) (const char *, const char *, int, int);
+ int (*str_char_search) (const char *, int, int);
+
+ char *(*str_build) (char **, unsigned long *, const char *, ...) PRINTF_WARNINGS(3,4);
+ char *(*str_dup) (const char *);
+ char *(*str_copy_substr) (const char *, int, int);
+ struct mk_list *(*str_split_line) (const char *);
+ void (*str_split_free) (struct mk_list *);
+
+ /* file functions */
+ char *(*file_to_buffer) (const char *);
+ int (*file_get_info) (const char *, struct file_info *, int);
+
+ /* header */
+ int (*header_prepare) (struct mk_plugin *,
+ struct mk_http_session *,
+ struct mk_http_request *);
+ struct mk_http_header *(*header_get) (int, struct mk_http_request *,
+ const char *, unsigned int);
+ int (*header_add) (struct mk_http_request *, char *row, int len);
+ void (*header_set_http_status) (struct mk_http_request *, int);
+
+ /* channel / stream handling */
+ struct mk_stream *(*stream_new) (int, struct mk_channel *, void *, size_t,
+ void *,
+ void (*) (struct mk_stream *),
+ void (*) (struct mk_stream *, long),
+ void (*) (struct mk_stream *, int));
+ struct mk_channel *(*channel_new) (int, int);
+ int (*channel_flush) (struct mk_channel *);
+ int (*channel_write) (struct mk_channel *, size_t *);
+ void (*channel_append_stream) (struct mk_channel *, struct mk_stream *stream);
+ void (*stream_set) (struct mk_stream *, int, struct mk_channel *, void *, size_t,
+ void *,
+ void (*) (struct mk_stream *),
+ void (*) (struct mk_stream *, long),
+ void (*) (struct mk_stream *, int));
+
+ /* iov functions */
+ struct mk_iov *(*iov_create) (int, int);
+ struct mk_iov *(*iov_realloc) (struct mk_iov *, int);
+ void (*iov_free) (struct mk_iov *);
+ void (*iov_free_marked) (struct mk_iov *);
+ int (*iov_add) (struct mk_iov *, void *, int, int);
+ int (*iov_set_entry) (struct mk_iov *, void *, int, int, int);
+ ssize_t (*iov_send) (int, struct mk_iov *);
+ void (*iov_print) (struct mk_iov *);
+
+ /* plugin functions */
+ void *(*plugin_load_symbol) (void *, const char *);
+
+ /* core events mechanism */
+ struct mk_event_loop *(*ev_loop_create) (int);
+ struct mk_event_fdt *(*ev_get_fdt) ();
+ int (*ev_add) (struct mk_event_loop *, int, int, uint32_t, void *);
+ int (*ev_del) (struct mk_event_loop *, struct mk_event *);
+ int (*ev_timeout_create) (struct mk_event_loop *, time_t, long, void *);
+ int (*ev_channel_create) (struct mk_event_loop *, int *, int *, void *);
+ int (*ev_wait) (struct mk_event_loop *);
+ char *(*ev_backend) ();
+
+ /* Mime type */
+ struct mk_mimetype *(*mimetype_lookup) (struct mk_server *, char *);
+
+ /* configuration reader functions */
+ struct mk_rconf *(*config_open) (const char *);
+ struct mk_rconf *(*config_create) (const char *);
+ void (*config_free) (struct mk_rconf *);
+ struct mk_rconf_section *(*config_section_get) (struct mk_rconf *,
+ const char *);
+ void *(*config_section_get_key) (struct mk_rconf_section *, char *, int);
+
+ /* Scheduler */
+ struct mk_event_loop *(*sched_loop)();
+ int (*sched_remove_client) (int, struct mk_server *);
+ struct mk_sched_conn *(*sched_get_connection)(struct mk_sched_worker *,
+ int);
+ void (*sched_event_free) (struct mk_event *);
+ struct mk_sched_worker *(*sched_worker_info)();
+
+ /* worker's functions */
+ int (*worker_spawn) (void (*func) (void *), void *, pthread_t *);
+ int (*worker_rename) (const char *);
+
+ /* event's functions */
+ int (*event_add) (int, int, struct mk_plugin *, unsigned int);
+ int (*event_del) (int);
+ struct plugin_event *(*event_get) (int);
+
+ int (*event_socket_change_mode) (int, int, unsigned int);
+
+ /* Time utils functions */
+ int (*time_unix) ();
+ int (*time_to_gmt) (char **, time_t);
+ mk_ptr_t *(*time_human) ();
+
+#ifdef TRACE
+ void (*trace)(const char *, int, const char *, char *, int, const char *, ...);
+ int (*errno_print) (int);
+#endif
+ void (*stacktrace)(void);
+
+ /* kernel interfaces */
+ int (*kernel_version) ();
+ int (*kernel_features_print) (char *, size_t, struct mk_server *);
+
+ /* Handler */
+ struct mk_vhost_handler_param *(*handler_param_get)(int, struct mk_list *);
+
+#ifdef JEMALLOC_STATS
+ int (*je_mallctl) (const char *, void *, size_t *, void *, size_t);
+#endif
+};
+
+extern struct plugin_api *api;
+
+struct mk_plugin_event
+{
+ struct mk_event event; /* event loop context */
+ struct mk_plugin *handler; /* plugin owner/handler */
+};
+
+struct mk_plugin_stage;
+
+/* Info: used to register a plugin */
+struct mk_plugin {
+ int flags;
+
+ /* Identification */
+ const char *shortname;
+ const char *name;
+ const char *version;
+
+ /* Hooks and capabilities */
+ unsigned int hooks;
+ char capabilities;
+
+ struct plugin_api *api;
+
+ /* Init / Exit */
+ int (*init_plugin) (struct mk_plugin *, char *);
+ int (*exit_plugin) (struct mk_plugin *);
+
+ /* Init Levels */
+ int (*master_init) (struct mk_server *);
+ void (*worker_init) (struct mk_server *);
+
+ /* Callback references for plugin type */
+ struct mk_plugin_network *network; /* MK_NETWORK_LAYER */
+ struct mk_plugin_stage *stage; /* MK_PLUGIN_STAGE */
+
+ /* Internal use variables */
+ void *handler; /* DSO handler */
+ char *path; /* Path for dynamic plugin */
+ pthread_key_t *thread_key; /* Worker thread key */
+ struct mk_list _head; /* Link to config->plugins list */
+ struct mk_list stage_list; /* Stages head list */
+
+ /* Load type: MK_PLUGIN_STATIC / MK_PLUGIN_DYNAMIC */
+ int load_type;
+
+ /* Sever context */
+ struct mk_server *server_ctx;
+};
+
+struct mk_plugin_stage {
+ int (*stage10) (int);
+ int (*stage20) (struct mk_http_session *, struct mk_http_request *);
+ int (*stage30) (struct mk_plugin *, struct mk_http_session *,
+ struct mk_http_request *, int, struct mk_list *);
+ void (*stage30_thread) (struct mk_plugin *, struct mk_http_session *,
+ struct mk_http_request *, int, struct mk_list *);
+ int (*stage30_hangup) (struct mk_plugin *, struct mk_http_session *,
+ struct mk_http_request *);
+ int (*stage40) (struct mk_http_session *, struct mk_http_request *);
+ int (*stage50) (int);
+
+ /* Just a reference to the parent plugin */
+ struct mk_plugin *plugin;
+
+ /* Only used when doing direct mapping from config->stageN_handler; */
+ struct mk_list _head;
+
+ struct mk_list _parent_head;
+};
+
+
+void mk_plugin_api_init(struct mk_server *server);
+void mk_plugin_load_all(struct mk_server *server);
+void mk_plugin_exit_all(struct mk_server *server);
+void mk_plugin_exit_worker();
+
+void mk_plugin_event_init_list();
+
+int mk_plugin_stage_run(unsigned int stage,
+ unsigned int socket,
+ struct mk_sched_conn *conx,
+ struct mk_http_session *cs, struct mk_http_request *sr);
+
+void mk_plugin_core_process(struct mk_server *server);
+void mk_plugin_core_thread(struct mk_server *server);
+
+void mk_plugin_preworker_calls(struct mk_server *server);
+
+/* Plugins events interface */
+int mk_plugin_event_add(int socket, int mode,
+ struct mk_plugin *handler,
+ unsigned int behavior);
+int mk_plugin_event_del(int socket);
+struct plugin_event *mk_plugin_event_get(int socket);
+
+int mk_plugin_event_socket_change_mode(int socket, int mode, unsigned int behavior);
+
+struct mk_plugin *mk_plugin_load(int type, const char *shortname,
+ void *data, struct mk_server *server);
+
+void *mk_plugin_load_symbol(void *handler, const char *symbol);
+int mk_plugin_http_error(int http_status, struct mk_http_session *cs,
+ struct mk_http_request *sr,
+ struct mk_plugin *plugin);
+int mk_plugin_http_request_end(struct mk_plugin *plugin,
+ struct mk_http_session *cs, int close);
+
+/* Register functions */
+struct plugin *mk_plugin_register(struct plugin *p);
+void mk_plugin_unregister(struct mk_plugin *p);
+
+struct plugin *mk_plugin_alloc(void *handler, const char *path);
+void mk_plugin_free(struct mk_plugin *p);
+
+int mk_plugin_time_now_unix(struct mk_server *server);
+mk_ptr_t *mk_plugin_time_now_human(struct mk_server *server);
+
+int mk_plugin_sched_remove_client(int socket, struct mk_server *server);
+
+
+int mk_plugin_header_prepare(struct mk_plugin *plugin,
+ struct mk_http_session *cs,
+ struct mk_http_request *sr);
+
+int mk_plugin_header_add(struct mk_http_request *sr, char *row, int len);
+int mk_plugin_header_get(struct mk_http_request *sr,
+ mk_ptr_t query,
+ mk_ptr_t *result);
+
+struct mk_sched_worker *mk_plugin_sched_get_thread_conf();
+struct mk_plugin *mk_plugin_cap(char cap, struct mk_server *server);
+struct mk_plugin *mk_plugin_lookup(char *shortname, struct mk_server *server);
+
+void mk_plugin_load_static(struct mk_server *server);
+struct mk_vhost_handler_param *mk_handler_param_get(int id,
+ struct mk_list *params);
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_plugin_net.h b/src/fluent-bit/lib/monkey/include/monkey/mk_plugin_net.h
new file mode 100644
index 000000000..e60c74cf7
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_plugin_net.h
@@ -0,0 +1,40 @@
+/* -*- 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.
+ */
+
+#ifndef MK_PLUGIN_NET_H
+#define MK_PLUGIN_NET_H
+
+#include <monkey/mk_core.h>
+
+/*
+ * Network plugin: a plugin that provides a network layer, eg: plain
+ * sockets or SSL.
+ */
+struct mk_plugin;
+struct mk_plugin_network {
+ int (*read) (struct mk_plugin *, int, void *, int);
+ int (*write) (struct mk_plugin *, int, const void *, size_t);
+ int (*writev) (struct mk_plugin *, int, struct mk_iov *);
+ int (*close) (struct mk_plugin *, int);
+ int (*send_file) (struct mk_plugin *, int, int, off_t *, size_t);
+ int buffer_size;
+ struct mk_plugin *plugin;
+};
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_plugin_stage.h b/src/fluent-bit/lib/monkey/include/monkey/mk_plugin_stage.h
new file mode 100644
index 000000000..5ad4b73ec
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_plugin_stage.h
@@ -0,0 +1,99 @@
+/* -*- 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.
+ */
+
+#ifndef MK_PLUGIN_STAGE_H
+#define MK_PLUGIN_STAGE_H
+
+static inline int mk_plugin_stage_run_10(int socket, struct mk_server *server)
+{
+ int ret;
+ struct mk_list *head;
+ struct mk_plugin_stage *stage;
+
+ mk_list_foreach(head, &server->stage10_handler) {
+ stage = mk_list_entry(head, struct mk_plugin_stage, _head);
+ ret = stage->stage10(socket);
+ switch (ret) {
+ case MK_PLUGIN_RET_CLOSE_CONX:
+ MK_TRACE("return MK_PLUGIN_RET_CLOSE_CONX");
+ return MK_PLUGIN_RET_CLOSE_CONX;
+ }
+ }
+
+ return -1;
+}
+
+static inline int mk_plugin_stage_run_20(struct mk_http_session *cs,
+ struct mk_http_request *sr,
+ struct mk_server *server)
+{
+ int ret;
+ struct mk_list *head;
+ struct mk_plugin_stage *stage;
+
+ mk_list_foreach(head, &server->stage20_handler) {
+ stage = mk_list_entry(head, struct mk_plugin_stage, _head);
+ ret = stage->stage20(cs, sr);
+ switch (ret) {
+ case MK_PLUGIN_RET_CLOSE_CONX:
+ MK_TRACE("return MK_PLUGIN_RET_CLOSE_CONX");
+ return MK_PLUGIN_RET_CLOSE_CONX;
+ }
+ }
+
+ return -1;
+}
+
+static inline int mk_plugin_stage_run_40(struct mk_http_session *cs,
+ struct mk_http_request *sr,
+ struct mk_server *server)
+{
+ struct mk_list *head;
+ struct mk_plugin_stage *stage;
+
+ mk_list_foreach(head, &server->stage40_handler) {
+ stage = mk_list_entry(head, struct mk_plugin_stage, _head);
+ stage->stage40(cs, sr);
+ }
+
+ return -1;
+}
+
+static inline int mk_plugin_stage_run_50(int socket, struct mk_server *server)
+{
+ int ret;
+
+ struct mk_list *head;
+ struct mk_plugin_stage *stage;
+
+ mk_list_foreach(head, &server->stage50_handler) {
+ stage = mk_list_entry(head, struct mk_plugin_stage, _head);
+ ret = stage->stage50(socket);
+ switch (ret) {
+ case MK_PLUGIN_RET_NOT_ME:
+ break;
+ case MK_PLUGIN_RET_CONTINUE:
+ return MK_PLUGIN_RET_CONTINUE;
+ }
+ }
+
+ return -1;
+}
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_scheduler.h b/src/fluent-bit/lib/monkey/include/monkey/mk_scheduler.h
new file mode 100644
index 000000000..f749cba54
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_scheduler.h
@@ -0,0 +1,353 @@
+/* -*- 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_info.h>
+#include <monkey/mk_tls.h>
+
+#include <monkey/mk_core.h>
+#include <monkey/mk_server.h>
+#include <monkey/mk_stream.h>
+#include <monkey/mk_net.h>
+
+#ifndef MK_SCHEDULER_H
+#define MK_SCHEDULER_H
+
+#define MK_SCHED_CONN_TIMEOUT -1
+#define MK_SCHED_CONN_CLOSED -2
+
+#define MK_SCHED_SIGNAL_DEADBEEF 0xDEADBEEF
+#define MK_SCHED_SIGNAL_FREE_ALL 0xFFEE0000
+#define MK_SCHED_SIGNAL_EVENT_LOOP_BREAK 0xEEFFAACC
+
+#ifdef _WIN32
+ /* The pid field in the mk_sched_worker structure is ignored in platforms other than
+ * linux and mac os so it can be safely plugged in this meaningless way
+ */
+ typedef uint64_t pid_t;
+#endif
+
+/*
+ * Scheduler balancing mode:
+ *
+ * - Fair Balancing: use a single socket and upon accept
+ * new connections, lookup the less loaded thread and
+ * assign the socket to that specific epoll queue.
+ *
+ * - ReusePort: Use new Linux Kernel 3.9 feature that
+ * allows thread to share binded address on a lister
+ * socket. We let the Kernel to decide how to balance.
+ */
+#define MK_SCHEDULER_FAIR_BALANCING 0
+#define MK_SCHEDULER_REUSEPORT 1
+
+/*
+ * Thread-scope structure/variable that holds the Scheduler context for the
+ * worker (or thread) in question.
+ */
+struct mk_sched_worker
+{
+ /* The event loop on this scheduler thread */
+ struct mk_event_loop *loop;
+
+ unsigned long long accepted_connections;
+ unsigned long long closed_connections;
+ unsigned long long over_capacity;
+
+ /*
+ * The timeout queue represents client connections that
+ * have not initiated it requests or the request status
+ * is incomplete. This linear lists allows the scheduler
+ * to perform a fast check upon every timeout.
+ */
+ struct mk_list timeout_queue;
+
+ short int idx;
+ unsigned char initialized;
+
+ pthread_t tid;
+
+ pid_t pid;
+
+ /* store the memory page size (_SC_PAGESIZE) */
+ unsigned int mem_pagesize;
+
+ struct mk_http_session *request_handler;
+
+
+ struct mk_list event_free_queue;
+
+ /*
+ * This variable is used to signal the active workers,
+ * just available because of ULONG_MAX bug described
+ * on mk_scheduler.c .
+ */
+ int signal_channel_r;
+ int signal_channel_w;
+
+ /* If using REUSEPORT, this points to the list of listeners */
+ struct mk_list *listeners;
+
+ /*
+ * List head for finished requests that need to be cleared after each
+ * event loop round.
+ */
+ struct mk_list requests_done;
+
+ /* List of co-routine threads */
+ struct mk_list threads;
+ struct mk_list threads_purge;
+
+};
+
+
+/* Every connection in the server is represented by this structure */
+struct mk_sched_conn
+{
+ struct mk_event event; /* event loop context */
+ int status; /* connection status */
+ uint32_t properties;
+ char is_timeout_on; /* registered to timeout queue? */
+ time_t arrive_time; /* arrive time */
+ struct mk_sched_handler *protocol; /* protocol handler */
+ struct mk_server_listen *server_listen;
+ struct mk_plugin_network *net; /* I/O network layer */
+ struct mk_channel channel; /* stream channel */
+ struct mk_list timeout_head; /* link to the timeout queue */
+ void *data; /* optional ref for protocols */
+};
+
+/* Protocol capabilities */
+#define MK_SCHED_CONN_CAP(conn) conn->protocol->capabilities
+
+/* Connection properties */
+#define MK_SCHED_CONN_PROP(conn) conn->server_listen->listen->flags
+
+/*
+ * It defines a Handler for a connection in questions. This struct
+ * is used inside mk_sched_conn to define which protocol/handler
+ * needs to take care of every action.
+ */
+struct mk_sched_handler
+{
+ /*
+ * Protocol definition and callbacks:
+ *
+ * - name : the protocol handler name.
+ * - cb_read : callback triggered when there is data on the socket to read.
+ * - cb_close: callback triggered when the socket channel have been closed.
+ * - cb_done : callback triggered when the whole channel data have been
+ * written. This callback is optional. The return value of this
+ * callback indicate to the scheduler of the channel should be
+ * closed or not: -1 = close, 0 = leave it open and wait for more
+ * data.
+ */
+ const char *name;
+ int (*cb_read) (struct mk_sched_conn *, struct mk_sched_worker *,
+ struct mk_server *);
+ int (*cb_close) (struct mk_sched_conn *, struct mk_sched_worker *, int,
+ struct mk_server *);
+ int (*cb_done) (struct mk_sched_conn *, struct mk_sched_worker *,
+ struct mk_server *);
+ int (*cb_upgrade) (void *, void *, struct mk_server *);
+
+ /*
+ * This extra field is a small hack. The scheduler connection context
+ * contains information about the connection, and setting this field
+ * will let the scheduler allocate some extra memory bytes on the
+ * context memory reference:
+ *
+ * e.g:
+ *
+ * t_size = (sizeof(struct mk_sched_conn) + sched_extra_size);
+ * struct sched_conn *conn = malloc(t_size);
+ *
+ * This is useful for protocol or handlers where a socket connection
+ * represents one unique instance, the use case is HTTP, e.g:
+ *
+ * HTTP : 1 connection = 1 client (one request at a time)
+ * HTTP2: 1 connection = 1 client with multiple-framed requests
+ *
+ * The purpose is to avoid protocol handlers to perform more memory
+ * allocations and connection lookups the sched context is good enough
+ * to help on this, e.g:
+ *
+ * t_size = (sizeof(struct mk_sched_conn) + (sizeof(struct mk_http_session);
+ * conn = malloc(t_size);
+ */
+ int sched_extra_size;
+ char capabilities;
+};
+
+struct mk_sched_notif {
+ struct mk_event event;
+};
+
+/* Struct under thread context */
+struct mk_sched_thread_conf {
+ struct mk_server *server;
+};
+
+struct mk_sched_worker_cb {
+ void (*cb_func) (void *);
+ void *data;
+ struct mk_list _head;
+};
+
+/*
+ * All data required by the Scheduler interface is mapped inside this
+ * struct which is later linked into config->scheduler_ctx.
+ */
+struct mk_sched_ctx {
+ /* Array of sched_worker */
+ struct mk_sched_worker *workers;
+};
+
+
+struct mk_sched_worker *mk_sched_next_target(struct mk_server *server);
+int mk_sched_init(struct mk_server *server);
+int mk_sched_exit(struct mk_server *server);
+
+int mk_sched_launch_thread(struct mk_server *server, pthread_t *tout);
+
+void *mk_sched_launch_epoll_loop(void *thread_conf);
+struct mk_sched_worker *mk_sched_get_handler_owner(void);
+
+static inline struct rb_root *mk_sched_get_request_list()
+{
+ return MK_TLS_GET(mk_tls_sched_cs);
+}
+
+static inline struct mk_sched_worker *mk_sched_get_thread_conf()
+{
+ return MK_TLS_GET(mk_tls_sched_worker_node);
+}
+
+static inline struct mk_event_loop *mk_sched_loop()
+{
+ struct mk_sched_worker *w;
+
+ w = MK_TLS_GET(mk_tls_sched_worker_node);
+ return w->loop;
+}
+
+void mk_sched_update_thread_status(struct mk_sched_worker *sched,
+ int active, int closed);
+
+int mk_sched_drop_connection(struct mk_sched_conn *conn,
+ struct mk_sched_worker *sched,
+ struct mk_server *server);
+
+int mk_sched_check_timeouts(struct mk_sched_worker *sched,
+ struct mk_server *server);
+
+
+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 mk_sched_remove_client(struct mk_sched_conn *conn,
+ struct mk_sched_worker *sched,
+ struct mk_server *server);
+
+struct mk_sched_conn *mk_sched_get_connection(struct mk_sched_worker
+ *sched, int remote_fd);
+int mk_sched_update_conn_status(struct mk_sched_worker *sched, int remote_fd,
+ int status);
+int mk_sched_sync_counters();
+void mk_sched_worker_free(struct mk_server *server);
+
+struct mk_sched_handler *mk_sched_handler_cap(char cap);
+
+/* Event handlers */
+int mk_sched_event_read(struct mk_sched_conn *conn,
+ struct mk_sched_worker *sched,
+ struct mk_server *server);
+
+int mk_sched_event_write(struct mk_sched_conn *conn,
+ struct mk_sched_worker *sched,
+ struct mk_server *server);
+
+
+int mk_sched_event_close(struct mk_sched_conn *conn,
+ struct mk_sched_worker *sched,
+ int type, struct mk_server *server);
+
+void mk_sched_event_free(struct mk_event *event);
+
+
+static inline void mk_sched_event_free_all(struct mk_sched_worker *sched)
+{
+ struct mk_list *tmp;
+ struct mk_list *head;
+ struct mk_event *event;
+
+ mk_list_foreach_safe(head, tmp, &sched->event_free_queue) {
+ event = mk_list_entry(head, struct mk_event, _head);
+ mk_list_del(&event->_head);
+ mk_mem_free(event);
+ }
+}
+
+static inline void mk_sched_conn_timeout_add(struct mk_sched_conn *conn,
+ struct mk_sched_worker *sched)
+{
+ if (conn->is_timeout_on == MK_FALSE) {
+ mk_list_add(&conn->timeout_head, &sched->timeout_queue);
+ conn->is_timeout_on = MK_TRUE;
+ }
+}
+
+static inline void mk_sched_conn_timeout_del(struct mk_sched_conn *conn)
+{
+ if (conn->is_timeout_on == MK_TRUE) {
+ mk_list_del(&conn->timeout_head);
+ conn->is_timeout_on = MK_FALSE;
+ }
+}
+
+
+#define mk_sched_conn_read(conn, buf, s) \
+ conn->net->read(conn->net->plugin, conn->event.fd, buf, s)
+#define mk_sched_conn_write(ch, buf, s) \
+ mk_net_conn_write(ch, buf, s)
+#define mk_sched_conn_writev(ch, iov) \
+ ch->io->writev(ch->io->plugin, ch->fd, iov)
+#define mk_sched_conn_sendfile(ch, f_fd, f_offs, f_count) \
+ ch->io->send_file(ch->io->plugin, ch->fd, f_fd, f_offs, f_count)
+
+#define mk_sched_switch_protocol(conn, cap) \
+ conn->protocol = mk_sched_handler_cap(cap)
+
+int mk_sched_worker_cb_add(struct mk_server *server,
+ void (*cb_func) (void *),
+ void *data);
+
+void mk_sched_worker_cb_free(struct mk_server *server);
+int mk_sched_send_signal(struct mk_sched_worker *worker, uint64_t val);
+int mk_sched_broadcast_signal(struct mk_server *server, uint64_t val);
+int mk_sched_workers_join(struct mk_server *server);
+int mk_sched_threads_purge(struct mk_sched_worker *sched);
+int mk_sched_threads_destroy_all(struct mk_sched_worker *sched);
+int mk_sched_threads_destroy_conn(struct mk_sched_worker *sched,
+ struct mk_sched_conn *conn);
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_scheduler_tls.h b/src/fluent-bit/lib/monkey/include/monkey/mk_scheduler_tls.h
new file mode 100644
index 000000000..e645684bd
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_scheduler_tls.h
@@ -0,0 +1,39 @@
+/* -*- 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.
+ */
+
+#ifndef MK_SCHEDULER_TLS_H
+#define MK_SCHEDULER_TLS_H
+
+#ifdef MK_HAVE_C_TLS /* Use Compiler Thread Local Storage (TLS) */
+
+__thread struct rb_root *mk_tls_sched_cs;
+__thread struct mk_list *mk_tls_sched_cs_incomplete;
+__thread struct mk_sched_notif *mk_tls_sched_worker_notif;
+__thread struct mk_sched_worker *mk_tls_sched_worker_node;
+
+#else
+
+pthread_key_t mk_tls_sched_cs;
+pthread_key_t mk_tls_sched_cs_incomplete;
+pthread_key_t mk_tls_sched_worker_notif;
+pthread_key_t mk_tls_sched_worker_node;
+
+#endif
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_server.h b/src/fluent-bit/lib/monkey/include/monkey/mk_server.h
new file mode 100644
index 000000000..f84a7d632
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_server.h
@@ -0,0 +1,75 @@
+/* -*- 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.
+ */
+
+#ifndef MK_SERVER_H
+#define MK_SERVER_H
+
+#define _GNU_SOURCE
+#include <monkey/mk_socket.h>
+#include <monkey/mk_config.h>
+#include <monkey/mk_core.h>
+
+#define MK_SERVER_SIGNAL_START 0xEEEEEEEE
+#define MK_SERVER_SIGNAL_STOP 0xDDDDDDDD
+
+struct mk_server_listen
+{
+ struct mk_event event;
+
+ int server_fd;
+ struct mk_plugin *network;
+ struct mk_sched_handler *protocol;
+ struct mk_config_listener *listen;
+ struct mk_list _head;
+};
+
+struct mk_server_timeout {
+ struct mk_event event;
+};
+
+extern pthread_key_t mk_server_fifo_key;
+
+#ifdef MK_HAVE_C_TLS
+extern __thread struct mk_list *server_listen;
+extern __thread struct mk_server_timeout *server_timeout;
+#endif
+
+struct mk_sched_worker;
+
+int mk_socket_set_cork_flag(int fd, int state);
+
+static inline int mk_server_cork_flag(int fd, int state)
+{
+ return mk_socket_set_cork_flag(fd, state);
+}
+
+struct mk_server *mk_server_create();
+int mk_server_listen_check(struct mk_server_listen *listen, int server_fd);
+
+void mk_server_listen_free();
+struct mk_list *mk_server_listen_init(struct mk_server *server);
+
+unsigned int mk_server_capacity(struct mk_server *server);
+void mk_server_launch_workers(struct mk_server *server);
+void mk_server_worker_loop(struct mk_server *server);
+void mk_server_loop_balancer(struct mk_server *server);
+void mk_server_worker_loop(struct mk_server *server);
+void mk_server_loop(struct mk_server *server);
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_server_tls.h b/src/fluent-bit/lib/monkey/include/monkey/mk_server_tls.h
new file mode 100644
index 000000000..1e47ee1b1
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_server_tls.h
@@ -0,0 +1,34 @@
+/* -*- 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.
+ */
+
+#ifndef MK_SERVER_TLS_H
+#define MK_SERVER_TLS_H
+
+#ifdef MK_HAVE_C_TLS /* Use Compiler Thread Local Storage (TLS) */
+
+__thread struct mk_list *mk_tls_server_listen;
+__thread struct mk_server_timeout *mk_tls_server_timeout;
+
+#else
+
+pthread_key_t mk_tls_server_listen;
+pthread_key_t mk_tls_server_timeout;
+
+#endif
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_socket.h b/src/fluent-bit/lib/monkey/include/monkey/mk_socket.h
new file mode 100644
index 000000000..67d290f08
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_socket.h
@@ -0,0 +1,85 @@
+/* -*- 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.
+ */
+
+#ifndef MK_SOCKET_H
+#define MK_SOCKET_H
+
+#include <fcntl.h>
+
+#ifdef _WIN32
+#include <winsock2.h>
+#include <afunix.h>
+#else
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <sys/un.h>
+#endif
+
+#include <monkey/mk_core.h>
+#include <monkey/mk_config.h>
+#include <monkey/mk_info.h>
+
+#ifndef SOCK_NONBLOCK
+#define SOCK_NONBLOCK 04000
+#endif
+
+#ifndef SO_REUSEPORT
+#define SO_REUSEPORT 15
+#endif
+
+/*
+ * TCP_FASTOPEN: as this is a very new option in the Linux Kernel, the value is
+ * not yet exported and can be missing, lets make sure is available for all
+ * cases:
+ *
+ * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=1046716368979dee857a2b8a91c4a8833f21b9cb
+ */
+#ifndef TCP_FASTOPEN
+#define TCP_FASTOPEN 23
+#endif
+
+#define TCP_CORK_ON 1
+#define TCP_CORK_OFF 0
+
+#define TCP_CORKING_PATH "/proc/sys/net/ipv4/tcp_autocorking"
+
+int mk_socket_set_cork_flag(int fd, int state);
+int mk_socket_set_tcp_fastopen(int sockfd);
+int mk_socket_set_tcp_nodelay(int sockfd);
+int mk_socket_set_tcp_defer_accept(int sockfd);
+int mk_socket_set_tcp_reuseport(int sockfd);
+int mk_socket_set_nonblocking(int sockfd);
+
+int mk_socket_create(int domain, int type, int protocol);
+int mk_socket_connect(char *host, int port, int async);
+int mk_socket_open(char *path, int async);
+int mk_socket_reset(int socket);
+int mk_socket_bind(int socket_fd, const struct sockaddr *addr,
+ socklen_t addrlen, int backlog, struct mk_server *server);
+int mk_socket_server(char *port, char *listen_addr,
+ int reuse_port, struct mk_server *server);
+int mk_socket_ip_str(int socket_fd, char **buf, int size, unsigned long *len);
+int mk_socket_accept(int server_fd);
+
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_static_plugins.h.in b/src/fluent-bit/lib/monkey/include/monkey/mk_static_plugins.h.in
new file mode 100644
index 000000000..33e3447bc
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_static_plugins.h.in
@@ -0,0 +1,69 @@
+/* -*- 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.
+ */
+
+#ifndef MK_STATIC_PLUGINS_H
+#define MK_STATIC_PLUGINS_H
+
+#include <monkey/mk_core.h>
+#include <monkey/mk_plugin.h>
+#include <monkey/mk_plugin_net.h>
+
+@STATIC_PLUGINS_DECL@
+
+static int mk_static_plugin_attach(struct mk_list *plugins,
+ struct mk_plugin *plugin)
+{
+ struct mk_plugin *instance;
+ struct mk_plugin_network *network;
+
+ instance = mk_mem_alloc_z(sizeof(struct mk_plugin));
+
+ if (instance == NULL) {
+ return MK_FALSE;
+ }
+
+ memcpy(instance, plugin, sizeof(struct mk_plugin));
+
+ network = mk_mem_alloc(sizeof(struct mk_plugin_network));
+
+ if (network == NULL) {
+ mk_mem_free(instance);
+
+ return MK_FALSE;
+ }
+
+ memcpy(network, plugin->network, sizeof(struct mk_plugin_network));
+
+ instance->network = network;
+
+ mk_list_add(&instance->_head, plugins);
+
+ return MK_TRUE;
+}
+
+static void mk_static_plugins(struct mk_list *plugins)
+{
+ struct mk_plugin *p;
+
+ (void) p;
+
+ @STATIC_PLUGINS_INIT@
+}
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_stream.h b/src/fluent-bit/lib/monkey/include/monkey/mk_stream.h
new file mode 100644
index 000000000..9dc81ba8e
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_stream.h
@@ -0,0 +1,398 @@
+/* -*- 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.
+ */
+
+#ifndef MK_STREAM_H
+#define MK_STREAM_H
+
+#include <monkey/mk_core.h>
+#include <monkey/mk_plugin_net.h>
+
+/*
+ * Stream types: each stream can have a different
+ * source of information and for hence it handler
+ * may need to be different for each cases.
+ */
+#define MK_STREAM_RAW 0 /* raw data from buffer */
+#define MK_STREAM_IOV 1 /* mk_iov struct */
+#define MK_STREAM_FILE 2 /* opened file */
+#define MK_STREAM_SOCKET 3 /* socket, scared.. */
+
+/* Channel return values for write event */
+#define MK_CHANNEL_OK 0 /* channel is ok (channel->status) */
+#define MK_CHANNEL_DONE 1 /* channel consumed all streams */
+#define MK_CHANNEL_ERROR 2 /* exception when flusing data */
+#define MK_CHANNEL_FLUSH 4 /* channel flushed some data */
+#define MK_CHANNEL_EMPTY 8 /* no streams available */
+#define MK_CHANNEL_BUSY 16 /* cannot write, busy (EAGAIN) */
+#define MK_CHANNEL_UNKNOWN 32 /* unhandled */
+
+/* Channel status */
+#define MK_CHANNEL_DISABLED 0 /* channel is sleeping */
+#define MK_CHANNEL_ENABLED 1 /* channel enabled, have some data */
+
+/*
+ * Channel types: by default the only channel supported
+ * is a direct write to the network layer.
+ */
+#define MK_CHANNEL_SOCKET 0
+
+/*
+ * A channel represents an end-point of a stream, for short
+ * where the stream data consumed and is send to. The channel
+ * knows how to read/write to a TCP connection through a
+ * defined network plugin.
+ */
+struct mk_channel {
+ int type;
+ int fd;
+ int status;
+
+ struct mk_event *event;
+ struct mk_plugin_network *io;
+ struct mk_list streams;
+ void *thread;
+};
+
+/* Stream input source */
+struct mk_stream_input {
+ int type; /* input type */
+ int fd; /* file descriptor (files) */
+ int dynamic;
+
+ size_t bytes_total; /* Total of data from the input */
+ off_t bytes_offset; /* Data already sent */
+
+ /*
+ * Based on the stream input type, 'data' could reference a RAW buffer
+ * or a mk_iov struct.
+ */
+ void *buffer;
+ void *context;
+
+ /* callbacks */
+ void (*cb_consumed)(struct mk_stream_input *, long);
+ void (*cb_finished)(struct mk_stream_input *);
+
+ struct mk_stream *stream; /* reference to parent stream */
+ struct mk_list _head; /* link to inputs stream list */
+};
+
+/*
+ * A stream holds a queue of components that refers to different
+ * data sources such as: static file, raw buffer, etc.
+ */
+struct mk_stream {
+ int preserve; /* preserve stream? (do not unlink) */
+ int encoding; /* some output encoding ? */
+ int dynamic; /* dynamic allocated ? */
+
+ size_t bytes_total; /* Total of data from stream_input */
+ off_t bytes_offset; /* Data already sent */
+
+ /* the outgoing channel, we do this for all streams */
+ struct mk_channel *channel;
+
+ /* Context the caller may want to reference with the stream (optional) */
+ void *context;
+
+ /* callbacks */
+ void (*cb_finished) (struct mk_stream *);
+ void (*cb_bytes_consumed) (struct mk_stream *, long);
+ void (*cb_exception) (struct mk_stream *, int);
+
+ /* Head of stream_input nodes */
+ struct mk_list inputs;
+
+ /* Link to the Channel parent */
+ struct mk_list _head;
+};
+
+int mk_stream_in_release(struct mk_stream_input *in);
+
+
+static inline int mk_channel_is_empty(struct mk_channel *channel)
+{
+ return mk_list_is_empty(&channel->streams);
+}
+
+static inline void mk_channel_append_stream(struct mk_channel *channel,
+ struct mk_stream *stream)
+{
+ mk_list_add(&stream->_head, &channel->streams);
+}
+
+static inline void mk_stream_append(struct mk_stream_input *in,
+ struct mk_stream *stream)
+{
+ mk_list_add(&in->_head, &stream->inputs);
+}
+
+static inline int mk_stream_input(struct mk_stream *stream,
+ struct mk_stream_input *in,
+ int type,
+ int fd,
+ void *buffer, size_t size,
+ off_t offset,
+ void (*cb_consumed) (struct mk_stream_input *, long),
+ void (*cb_finished)(struct mk_stream_input *))
+
+{
+ struct mk_iov *iov;
+
+ if (!in) {
+ in = mk_mem_alloc(sizeof(struct mk_stream_input));
+ if (!in) {
+ return -1;
+ }
+ in->dynamic = MK_TRUE;
+ }
+ else {
+ in->dynamic = MK_FALSE;
+ }
+
+ in->fd = fd;
+ in->type = type;
+ in->bytes_offset = offset;
+ in->buffer = buffer;
+ in->cb_consumed = cb_consumed;
+ in->cb_finished = cb_finished;
+ in->stream = stream;
+
+ if (type == MK_STREAM_IOV) {
+ iov = buffer;
+ in->bytes_total = iov->total_len;
+ }
+ else {
+ in->bytes_total = size;
+ }
+
+ mk_list_add(&in->_head, &stream->inputs);
+ return 0;
+}
+
+static inline int mk_stream_in_file(struct mk_stream *stream,
+ struct mk_stream_input *in, int fd,
+ size_t total_bytes,
+ off_t offset,
+ void (*cb_consumed)(struct mk_stream_input *, long),
+ void (*cb_finished)(struct mk_stream_input *))
+
+{
+ return mk_stream_input(stream,
+ in,
+ MK_STREAM_FILE,
+ fd,
+ NULL, total_bytes, offset,
+ cb_consumed, cb_finished);
+}
+
+static inline int mk_stream_in_iov(struct mk_stream *stream,
+ struct mk_stream_input *in,
+ struct mk_iov *iov,
+ void (*cb_consumed)(struct mk_stream_input *, long),
+ void (*cb_finished)(struct mk_stream_input *))
+
+{
+ return mk_stream_input(stream,
+ in,
+ MK_STREAM_IOV,
+ 0,
+ iov, 0, 0,
+ cb_consumed, cb_finished);
+}
+
+static inline int mk_stream_in_raw(struct mk_stream *stream,
+ struct mk_stream_input *in,
+ char *buf, size_t length,
+ void (*cb_consumed)(struct mk_stream_input *, long),
+ void (*cb_finished)(struct mk_stream_input *))
+{
+ return mk_stream_input(stream,
+ in,
+ MK_STREAM_RAW,
+ -1,
+ buf, length,
+ 0,
+ cb_consumed, cb_finished);
+}
+
+
+static inline void mk_stream_release(struct mk_stream *stream)
+{
+ struct mk_list *tmp;
+ struct mk_list *head;
+ struct mk_stream_input *in;
+
+ /* Release any pending input */
+ mk_list_foreach_safe(head, tmp, &stream->inputs) {
+ in = mk_list_entry(head, struct mk_stream_input, _head);
+ mk_stream_in_release(in);
+ }
+
+ if (stream->cb_finished) {
+ stream->cb_finished(stream);
+ }
+
+ stream->channel = NULL;
+ mk_list_del(&stream->_head);
+ if (stream->dynamic == MK_TRUE) {
+ mk_mem_free(stream);
+ }
+}
+
+static inline
+struct mk_stream *mk_stream_set(struct mk_stream *stream,
+ struct mk_channel *channel,
+ void *data,
+ void (*cb_finished) (struct mk_stream *),
+ void (*cb_bytes_consumed) (struct mk_stream *, long),
+ void (*cb_exception) (struct mk_stream *, int))
+{
+ /*
+ * The copybuf stream type it's a lazy stream mechanism on which the
+ * stream it self and the buffer are allocated dynamically. It just
+ * exists as an optional interface that do not care too much about
+ * performance and aim to make things easier. The COPYBUF type is not
+ * used by Monkey core, at the moment the only caller is the CGI plugin.
+ */
+ if (!stream) {
+ stream = mk_mem_alloc(sizeof(struct mk_stream));
+ if (!stream) {
+ return NULL;
+ }
+ stream->dynamic = MK_TRUE;
+ }
+ else {
+ stream->dynamic = MK_FALSE;
+ }
+
+ stream->channel = channel;
+ stream->bytes_offset = 0;
+ stream->context = data;
+ stream->preserve = MK_FALSE;
+
+ /* callbacks */
+ stream->cb_finished = cb_finished;
+ stream->cb_bytes_consumed = cb_bytes_consumed;
+ stream->cb_exception = cb_exception;
+
+ mk_list_init(&stream->inputs);
+ mk_list_add(&stream->_head, &channel->streams);
+
+ return stream;
+}
+
+static inline void mk_stream_input_unlink(struct mk_stream_input *in)
+{
+ mk_list_del(&in->_head);
+}
+
+/* Mark a specific number of bytes served (just on successfull flush) */
+static inline void mk_stream_input_consume(struct mk_stream_input *in, long bytes)
+{
+#ifdef TRACE
+ char *fmt = NULL;
+
+ if (in->type == MK_STREAM_RAW) {
+ fmt = "[INPUT_RAW %p] bytes consumed %lu/%lu";
+ }
+ else if (in->type == MK_STREAM_IOV) {
+ fmt = "[INPUT_IOV %p] bytes consumed %lu/%lu";
+ }
+ else if (in->type == MK_STREAM_FILE) {
+ fmt = "[INPUT_FILE %p] bytes consumed %lu/%lu";
+ }
+ else if (in->type == MK_STREAM_SOCKET) {
+ fmt = "[INPUT_SOCK %p] bytes consumed %lu/%lu";
+ }
+ else if (in->type == MK_STREAM_COPYBUF) {
+ fmt = "[INPUT_CBUF %p] bytes consumed %lu/%lu";
+ }
+ else {
+ fmt = "[INPUT_UNKW %p] bytes consumed %lu/%lu";
+ }
+ MK_TRACE(fmt, in, bytes, in->bytes_total);
+#endif
+
+ in->bytes_total -= bytes;
+}
+
+#ifdef TRACE
+static inline void mk_channel_debug(struct mk_channel *channel)
+{
+ int i = 0;
+ int i_input;
+ struct mk_list *head;
+ struct mk_list *h_inputs;
+ struct mk_stream *stream;
+ struct mk_stream_input *in;
+
+ printf("\n*** Channel ***\n");
+ mk_list_foreach(head, &channel->streams) {
+ stream = mk_list_entry(head, struct mk_stream, _head);
+ i_input = 0;
+
+ mk_list_foreach(h_inputs, &stream->inputs) {
+ in = mk_list_entry(h_inputs, struct mk_stream_input, _head);
+ switch (in->type) {
+ case MK_STREAM_RAW:
+ printf(" in.%i] %p RAW : ", i_input, in);
+ break;
+ case MK_STREAM_IOV:
+ printf(" in.%i] %p IOV : ", i_input, in);
+ break;
+ case MK_STREAM_FILE:
+ printf(" in.%i] %p FILE : ", i_input, in);
+ break;
+ case MK_STREAM_SOCKET:
+ printf(" in.%i] %p SOCKET : ", i_input, in);
+ break;
+ case MK_STREAM_COPYBUF:
+ printf(" in.%i] %p COPYBUF: ", i_input, in);
+ break;
+ case MK_STREAM_EOF:
+ printf("%i) [%p] STREAM EOF : ", i, stream);
+ break;
+ }
+#if defined(__APPLE__)
+ printf("bytes=%lld/%lu\n", in->bytes_offset, in->bytes_total);
+#else
+ printf("bytes=%ld/%zu\n", in->bytes_offset, in->bytes_total);
+#endif
+ i_input++;
+ }
+ }
+}
+#endif
+
+struct mk_stream *mk_stream_new(int type, struct mk_channel *channel,
+ void *buffer, size_t size, void *data,
+ void (*cb_finished) (struct mk_stream *),
+ void (*cb_bytes_consumed) (struct mk_stream *, long),
+ void (*cb_exception) (struct mk_stream *, int));
+
+int mk_channel_stream_write(struct mk_stream *stream, size_t *count);
+
+struct mk_channel *mk_channel_new(int type, int fd);
+int mk_channel_release(struct mk_channel *channel);
+
+int mk_channel_flush(struct mk_channel *channel);
+int mk_channel_write(struct mk_channel *channel, size_t *count);
+int mk_channel_clean(struct mk_channel *channel);
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_thread.h b/src/fluent-bit/lib/monkey/include/monkey/mk_thread.h
new file mode 100644
index 000000000..59ea38c8f
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_thread.h
@@ -0,0 +1,25 @@
+/* -*- 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.
+ */
+
+#ifndef MK_THREAD_H
+#define MK_THREAD_H
+
+#include <monkey/mk_thread_libco.h>
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_thread_libco.h b/src/fluent-bit/lib/monkey/include/monkey/mk_thread_libco.h
new file mode 100644
index 000000000..28c320fc5
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_thread_libco.h
@@ -0,0 +1,123 @@
+/* -*- 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.
+ */
+
+#ifndef MK_THREAD_LIBCO_H
+#define MK_THREAD_LIBCO_H
+
+#include <monkey/mk_info.h>
+#include <monkey/mk_core.h>
+#include <libco.h>
+
+#include <limits.h>
+
+#ifdef MK_HAVE_VALGRIND
+#include <valgrind/valgrind.h>
+#endif
+
+#include <monkey/mk_tls.h>
+
+struct mk_thread {
+
+#ifdef MK_HAVE_VALGRIND
+ unsigned int valgrind_stack_id;
+#endif
+
+ /* libco 'contexts' */
+ cothread_t caller;
+ cothread_t callee;
+
+ void *data;
+
+ /*
+ * Callback invoked before the thread is destroyed. Used to release
+ * any pending info in MK_THREAD_DATA(...).
+ */
+ void (*cb_destroy) (void *);
+};
+
+#define MK_THREAD_STACK_SIZE ((3 * PTHREAD_STACK_MIN) / 2)
+#define MK_THREAD_DATA(th) (((char *) th) + sizeof(struct mk_thread))
+
+extern MK_EXPORT MK_TLS_DEFINE(struct mk_thread, mk_thread);
+
+static MK_INLINE void mk_thread_yield(struct mk_thread *th)
+{
+ co_switch(th->caller);
+}
+
+static MK_INLINE void mk_thread_destroy(struct mk_thread *th)
+{
+ if (th->cb_destroy) {
+ th->cb_destroy(MK_THREAD_DATA(th));
+ }
+
+ MK_TRACE("[thread] destroy thread=%p data=%p", th, MK_THREAD_DATA(th));
+
+#ifdef MK_HAVE_VALGRIND
+ VALGRIND_STACK_DEREGISTER(th->valgrind_stack_id);
+#endif
+
+ co_delete(th->callee);
+ mk_mem_free(th);
+}
+
+#define mk_thread_return(th) co_switch(th->caller)
+
+static MK_INLINE void mk_thread_resume(struct mk_thread *th)
+{
+ MK_TLS_SET(mk_thread, th);
+
+ /*
+ * In the past we used to have a flag to mark when a coroutine
+ * has finished (th->ended == MK_TRUE), now we let the coroutine
+ * to submit an event to the event loop indicating what's going on
+ * through the call MK_OUTPUT_RETURN(...).
+ *
+ * So we just swap context and let the event loop to handle all
+ * the cleanup required.
+ */
+
+ th->caller = co_active();
+ co_switch(th->callee);
+}
+
+static MK_INLINE struct mk_thread *mk_thread_new(size_t data_size,
+ void (*cb_destroy) (void *))
+
+{
+ void *p;
+ struct mk_thread *th;
+
+ /* Create a thread context and initialize */
+ p = mk_mem_alloc(sizeof(struct mk_thread) + data_size);
+ if (!p) {
+
+ return NULL;
+ }
+
+ th = (struct mk_thread *) p;
+ th->cb_destroy = cb_destroy;
+
+ MK_TRACE("[thread %p] created (custom data at %p, size=%lu",
+ th, MK_THREAD_DATA(th), data_size);
+
+ return th;
+}
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_thread_ucontext.h b/src/fluent-bit/lib/monkey/include/monkey/mk_thread_ucontext.h
new file mode 100644
index 000000000..1d5272932
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_thread_ucontext.h
@@ -0,0 +1,129 @@
+/* -*- 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.
+ */
+
+#ifndef MK_THREAD_UCONTEXT_H
+#define MK_THREAD_UCONTEXT_H
+
+#include <ucontext.h>
+#include <pthread.h>
+#include <limits.h>
+#include <valgrind/valgrind.h>
+
+#include <monkey/mk_core.h>
+#include <monkey/mk_tls.h>
+
+struct mk_thread {
+ int id;
+
+ unsigned int valgrind_stack_id;
+
+ /* ucontext 'contexts' */
+ ucontext_t caller;
+ ucontext_t callee;
+
+ /*
+ * Callback invoked before the thread is destroyed. Used to release
+ * any pending info in MK_THREAD_DATA(...).
+ */
+ void (*cb_destroy) (void *);
+};
+
+#define MK_THREAD_STACK(th) (((char *) th) + sizeof(struct mk_thread))
+#define MK_THREAD_STACK_SIZE ((3 * PTHREAD_STACK_MIN) / 2)
+#define MK_THREAD_STACK_END(th) ((char *) MK_THREAD_STACK(th) + MK_THREAD_STACK_SIZE)
+#define MK_THREAD_DATA(th) ((char *) MK_THREAD_STACK_END(th))
+#define MK_THREAD_SIZE() (sizeof(struct mk_thread) + MK_THREAD_STACK_SIZE)
+
+extern MK_EXPORT MK_TLS_DEFINE(struct mk_thread, mk_thread);
+
+static MK_INLINE void *mk_thread_get()
+{
+ return MK_TLS_GET(mk_thread);
+}
+
+static MK_INLINE void mk_thread_yield(struct mk_thread *th, int ended)
+{
+ (void) ended;
+
+ swapcontext(&th->callee, &th->caller);
+}
+
+static MK_INLINE void mk_thread_destroy(struct mk_thread *th)
+{
+ if (th->cb_destroy) {
+ th->cb_destroy(MK_THREAD_DATA(th));
+ }
+
+ VALGRIND_STACK_DEREGISTER(th->valgrind_stack_id);
+
+ free(th);
+}
+
+static MK_INLINE void mk_thread_resume(struct mk_thread *th)
+{
+ MK_TLS_SET(mk_thread, th);
+
+ /*
+ * In the past we used to have a flag to mark when a coroutine
+ * has finished (th->ended == MK_TRUE), now we let the coroutine
+ * to submit an event to the event loop indicating what's going on
+ * through the call MK_OUTPUT_RETURN(...).
+ *
+ * So we just swap context and let the event loop to handle all
+ * the cleanup required.
+ */
+ swapcontext(&th->caller, &th->callee);
+}
+
+static inline struct mk_thread *mk_thread_new(size_t data_size,
+ void (*cb_destroy) (void *))
+
+{
+ int ret;
+ void *p;
+ struct mk_thread *th;
+
+ /* Create a thread context and initialize */
+ p = malloc(sizeof(struct mk_thread) + MK_THREAD_STACK_SIZE + data_size);
+ if (!p) {
+ return NULL;
+ }
+
+ th = (struct mk_thread *) p;
+ th->cb_destroy = cb_destroy;
+
+ ret = getcontext(&th->callee);
+ if (ret == -1) {
+ free(th);
+ return NULL;
+ }
+
+ /* Thread context */
+ th->callee.uc_stack.ss_sp = MK_THREAD_STACK(p);
+ th->callee.uc_stack.ss_size = MK_THREAD_STACK_SIZE;
+ th->callee.uc_stack.ss_flags = 0;
+ th->callee.uc_link = &th->caller;
+
+ th->valgrind_stack_id = VALGRIND_STACK_REGISTER(MK_THREAD_STACK(p),
+ MK_THREAD_STACK(p) + MK_THREAD_STACK_SIZE);
+
+ return th;
+}
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_tls.h b/src/fluent-bit/lib/monkey/include/monkey/mk_tls.h
new file mode 100644
index 000000000..fe80e3131
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_tls.h
@@ -0,0 +1,110 @@
+/* -*- 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.
+ */
+
+#ifndef MK_TLS_H
+#define MK_TLS_H
+
+#include <monkey/mk_info.h>
+
+#define MK_INIT_INITIALIZE_TLS_UNIVERSAL() \
+ /* mk_utils.c */ \
+ pthread_key_create(&mk_utils_error_key, NULL); \
+ /* mk_lib.c */ \
+ pthread_key_create(&mk_server_fifo_key, NULL);
+
+#ifdef MK_HAVE_C_TLS /* Use Compiler Thread Local Storage (TLS) */
+
+/* mk_cache.c */
+extern __thread struct mk_iov *mk_tls_cache_iov_header;
+extern __thread mk_ptr_t *mk_tls_cache_header_cl;
+extern __thread mk_ptr_t *mk_tls_cache_header_lm;
+extern __thread struct tm *mk_tls_cache_gmtime;
+extern __thread struct mk_gmt_cache *mk_tls_cache_gmtext;
+
+/* mk_vhost.c */
+extern __thread struct mk_list *mk_tls_vhost_fdt;
+
+/* mk_scheduler.c */
+extern __thread struct rb_root *mk_tls_sched_cs;
+extern __thread struct mk_list *mk_tls_sched_cs_incomplete;
+extern __thread struct mk_sched_notif *mk_tls_sched_worker_notif;
+extern __thread struct mk_sched_worker *mk_tls_sched_worker_node;
+
+/* mk_server.c */
+extern __thread struct mk_list *mk_tls_server_listen;
+extern __thread struct mk_server_timeout *mk_tls_server_timeout;
+
+/* TLS helper macros */
+#define MK_TLS_SET(key, val) key=val
+#define MK_TLS_GET(key) key
+#define MK_TLS_INIT(key) do {} while (0)
+#define MK_TLS_DEFINE(type, name) __thread type *name;
+
+#define MK_INIT_INITIALIZE_TLS() do {} while (0)
+
+#else /* Use Posix Thread Keys */
+
+/* mk_cache.c */
+extern pthread_key_t mk_tls_cache_iov_header;
+extern pthread_key_t mk_tls_cache_header_cl;
+extern pthread_key_t mk_tls_cache_header_lm;
+extern pthread_key_t mk_tls_cache_gmtime;
+extern pthread_key_t mk_tls_cache_gmtext;
+
+/* mk_vhost.c */
+extern pthread_key_t mk_tls_vhost_fdt;
+
+/* mk_scheduler.c */
+extern pthread_key_t mk_tls_sched_cs;
+extern pthread_key_t mk_tls_sched_cs_incomplete;
+extern pthread_key_t mk_tls_sched_worker_notif;
+extern pthread_key_t mk_tls_sched_worker_node;
+
+/* mk_server.c */
+extern pthread_key_t mk_tls_server_listen;
+extern pthread_key_t mk_tls_server_timeout;
+
+#define MK_TLS_SET(key, val) pthread_setspecific(key, (void *) val)
+#define MK_TLS_GET(key) pthread_getspecific(key)
+#define MK_TLS_INIT(key) pthread_key_create(&key, NULL)
+#define MK_TLS_DEFINE(type, name) pthread_key_t name;
+
+#define MK_INIT_INITIALIZE_TLS() \
+ /* mk_cache.c */ \
+ pthread_key_create(&mk_tls_cache_iov_header, NULL); \
+ pthread_key_create(&mk_tls_cache_header_cl, NULL); \
+ pthread_key_create(&mk_tls_cache_header_lm, NULL); \
+ pthread_key_create(&mk_tls_cache_gmtime, NULL); \
+ pthread_key_create(&mk_tls_cache_gmtext, NULL); \
+ \
+ /* mk_vhost.c */ \
+ pthread_key_create(&mk_tls_vhost_fdt, NULL); \
+ \
+ /* mk_scheduler.c */ \
+ pthread_key_create(&mk_tls_sched_cs, NULL); \
+ pthread_key_create(&mk_tls_sched_cs_incomplete, NULL); \
+ pthread_key_create(&mk_tls_sched_worker_notif, NULL); \
+ pthread_key_create(&mk_tls_sched_worker_node, NULL); \
+ \
+ /* mk_server.c */ \
+ pthread_key_create(&mk_tls_server_listen, NULL); \
+ pthread_key_create(&mk_tls_server_timeout, NULL);
+#endif
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_user.h b/src/fluent-bit/lib/monkey/include/monkey/mk_user.h
new file mode 100644
index 000000000..69a47a040
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_user.h
@@ -0,0 +1,35 @@
+/* -*- 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.
+ */
+
+#ifndef MK_USER_H
+#define MK_USER_H
+
+#include "mk_http.h"
+#include "mk_http_internal.h"
+
+/* User home string */
+#define MK_USER_HOME '~'
+
+/* user.c */
+int mk_user_init(struct mk_http_session *cs, struct mk_http_request *sr,
+ struct mk_server *server);
+int mk_user_set_uidgid(struct mk_server *server);
+int mk_user_undo_uidgid(struct mk_server *server);
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_utils.h b/src/fluent-bit/lib/monkey/include/monkey/mk_utils.h
new file mode 100644
index 000000000..7cf325e5d
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_utils.h
@@ -0,0 +1,54 @@
+/* -*- 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.
+ */
+
+#ifndef MK_UTILS_H
+#define MK_UTILS_H
+
+#define _GNU_SOURCE
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <monkey/mk_core.h>
+
+#define MK_UTILS_INT2MKP_BUFFER_LEN 16 /* Maximum buffer length when
+ * converting an int to mk_ptr_t */
+#define MK_GMT_CACHES 10
+
+struct mk_gmt_cache {
+ time_t time;
+ char text[32];
+ unsigned long long hits;
+};
+
+int mk_utils_get_system_core_count();
+int mk_utils_get_system_page_size();
+
+int mk_utils_utime2gmt(char **data, time_t date);
+time_t mk_utils_gmt2utime(char *date);
+
+int mk_buffer_cat(mk_ptr_t * p, char *buf1, int len1, char *buf2, int len2);
+
+char *mk_utils_url_decode(mk_ptr_t req_uri);
+void mk_utils_stacktrace(void);
+
+unsigned int mk_utils_gen_hash(const void *key, int len);
+
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_vhost.h b/src/fluent-bit/lib/monkey/include/monkey/mk_vhost.h
new file mode 100644
index 000000000..efb8f31c8
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_vhost.h
@@ -0,0 +1,123 @@
+/* -*- 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.
+ */
+
+#ifndef MK_VHOST_H
+#define MK_VHOST_H
+
+#include <monkey/mk_core.h>
+#include <monkey/mk_config.h>
+#include <monkey/mk_http.h>
+
+/* Custom error page */
+struct mk_vhost_error_page {
+ short int status;
+ char *file;
+ char *real_path;
+ struct mk_list _head;
+};
+
+struct mk_vhost_handler_param {
+ mk_ptr_t p;
+ struct mk_list _head;
+};
+
+struct mk_vhost_handler {
+ void *match; /* regex match rule */
+ char *name; /* plugin handler name */
+ int n_params; /* number of parameters */
+
+ /* optional callback and opaque data for lib mode */
+ void (*cb) (struct mk_http_request *, void *);
+ void *data;
+
+ struct mk_list params; /* parameters given by config */
+ struct mk_plugin *handler; /* handler plugin */
+ struct mk_list _head; /* link to vhost->handlers */
+};
+
+struct mk_vhost
+{
+ int id;
+ char *file; /* configuration file */
+ struct mk_list server_names; /* host names (a b c...) */
+
+ mk_ptr_t documentroot;
+ mk_ptr_t header_redirect;
+
+ /* source configuration */
+ struct mk_rconf *config;
+
+ /* custom error pages */
+ struct mk_list error_pages;
+
+ /* content handlers */
+ struct mk_list handlers;
+
+ /* link node */
+ struct mk_list _head;
+};
+
+struct mk_vhost_alias
+{
+ char *name;
+ unsigned int len;
+
+ struct mk_list _head;
+};
+
+
+#define VHOST_FDT_HASHTABLE_SIZE 64
+#define VHOST_FDT_HASHTABLE_CHAINS 8
+
+struct vhost_fdt_hash_chain {
+ int fd;
+ int readers;
+ unsigned int hash;
+};
+
+struct vhost_fdt_hash_table {
+ int av_slots;
+ struct vhost_fdt_hash_chain chain[VHOST_FDT_HASHTABLE_CHAINS];
+};
+
+struct vhost_fdt_host {
+ struct mk_vhost *host;
+ struct vhost_fdt_hash_table hash_table[VHOST_FDT_HASHTABLE_SIZE];
+ struct mk_list _head;
+};
+
+struct mk_vhost *mk_vhost_read(char *path);
+int mk_vhost_get(mk_ptr_t host, struct mk_vhost **vhost, struct
+ mk_vhost_alias **alias,
+ struct mk_server *server);
+void mk_vhost_set_single(char *path, struct mk_server *server);
+void mk_vhost_init(char *path, struct mk_server *server);
+
+int mk_vhost_fdt_worker_init(struct mk_server *server);
+int mk_vhost_fdt_worker_exit(struct mk_server *server);
+int mk_vhost_open(struct mk_http_request *sr, struct mk_server *server);
+int mk_vhost_close(struct mk_http_request *sr, struct mk_server *server);
+void mk_vhost_free_all(struct mk_server *server);
+int mk_vhost_map_handlers(struct mk_server *server);
+struct mk_vhost_handler *mk_vhost_handler_match(char *match,
+ void (*cb)(struct mk_http_request *,
+ void *),
+ void *data);
+int mk_vhost_destroy(struct mk_vhost *vh);
+#endif
diff --git a/src/fluent-bit/lib/monkey/include/monkey/mk_vhost_tls.h b/src/fluent-bit/lib/monkey/include/monkey/mk_vhost_tls.h
new file mode 100644
index 000000000..19dee4346
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/mk_vhost_tls.h
@@ -0,0 +1,38 @@
+/* -*- 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>
+
+
+#ifndef MK_VHOST_TLS_H
+#define MK_VHOST_TLS_H
+
+#include <monkey/mk_core.h>
+
+#ifdef MK_HAVE_C_TLS /* Use Compiler Thread Local Storage (TLS) */
+
+__thread struct mk_list *mk_tls_vhost_fdt;
+
+#else
+
+pthread_key_t mk_tls_vhost_fdt;
+
+#endif /* MK_HAVE_C_TLS */
+
+#endif /* MK_VHOST_TLS_H */
diff --git a/src/fluent-bit/lib/monkey/include/monkey/monkey.h b/src/fluent-bit/lib/monkey/include/monkey/monkey.h
new file mode 100644
index 000000000..0da8901e3
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/include/monkey/monkey.h
@@ -0,0 +1,72 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/* Monkey HTTP Server
+ * ------------------
+ * Copyright (C) 2001-2015, Eduardo Silva P. <edsiper@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef MK_MONKEY_H
+#define MK_MONKEY_H
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <monkey/mk_core.h>
+
+#ifdef LINUX_TRACE
+#define TRACEPOINT_CREATE_PROBES
+#define TRACEPOINT_DEFINE
+#include <monkey/mk_linuxtrace.h>
+#endif
+
+#include <monkey/mk_core.h>
+#include <monkey/mk_server.h>
+#include <monkey/mk_kernel.h>
+#include <monkey/mk_user.h>
+#include <monkey/mk_clock.h>
+#include <monkey/mk_cache.h>
+#include <monkey/mk_plugin.h>
+#include <monkey/mk_env.h>
+#include <monkey/mk_utils.h>
+#include <monkey/mk_config.h>
+#include <monkey/mk_scheduler.h>
+#include <monkey/mk_tls.h>
+
+/* Max Path lenth */
+#define MK_MAX_PATH 1024
+
+/* Send_Header(...,int cgi) */
+#define SH_NOCGI 0
+#define SH_CGI 1
+
+/* Monkey Protocol */
+extern const mk_ptr_t mk_monkey_protocol;
+
+struct mk_server *mk_server_init();
+
+void mk_server_info(struct mk_server *server);
+int mk_server_setup(struct mk_server *server);
+void mk_thread_keys_init();
+void mk_exit_all(struct mk_server *config);
+
+#endif