diff options
Diffstat (limited to 'fluent-bit/lib/monkey/mk_server/mk_plugin.c')
-rw-r--r-- | fluent-bit/lib/monkey/mk_server/mk_plugin.c | 804 |
1 files changed, 0 insertions, 804 deletions
diff --git a/fluent-bit/lib/monkey/mk_server/mk_plugin.c b/fluent-bit/lib/monkey/mk_server/mk_plugin.c deleted file mode 100644 index 50e2886b7..000000000 --- a/fluent-bit/lib/monkey/mk_server/mk_plugin.c +++ /dev/null @@ -1,804 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <monkey/monkey.h> -#include <monkey/mk_utils.h> -#include <monkey/mk_http.h> -#include <monkey/mk_clock.h> -#include <monkey/mk_plugin.h> -#include <monkey/mk_mimetype.h> -#include <monkey/mk_vhost.h> -#include <monkey/mk_static_plugins.h> -#include <monkey/mk_plugin_stage.h> -#include <monkey/mk_core.h> -#include <monkey/mk_net.h> - -#ifndef _WIN32 -#include <dlfcn.h> -#include <err.h> -#endif - -enum { - bufsize = 256 -}; - -static struct plugin_stagemap *plg_stagemap; -struct plugin_network_io *plg_netiomap; - -struct mk_plugin *mk_plugin_lookup(char *shortname, struct mk_server *server) -{ - struct mk_list *head; - struct mk_plugin *p = NULL; - - mk_list_foreach(head, &server->plugins) { - p = mk_list_entry(head, struct mk_plugin, _head); - if (strcmp(p->shortname, shortname) == 0){ - return p; - } - } - - return NULL; -} - -void *mk_plugin_load_dynamic(const char *path) -{ - void *handle; - -#ifdef _WIN32 - handle = (void *) LoadLibraryA(path); -#else - handle = dlopen(path, RTLD_LAZY); - - if (!handle) { - mk_warn("dlopen() %s", dlerror()); - } -#endif - - return handle; -} - -void *mk_plugin_load_symbol(void *handler, const char *symbol) -{ - void *s; - -#ifdef _WIN32 - s = GetProcAddress((HMODULE)handler, symbol); -#else - dlerror(); - s = dlsym(handler, symbol); - if (dlerror() != NULL) { - return NULL; - } -#endif - - return s; -} - -/* Initialize a plugin, trigger the init_plugin callback */ -static int mk_plugin_init(struct plugin_api *api, - struct mk_plugin *plugin, - struct mk_server *server) -{ - int ret; - unsigned long len; - char path[1024]; - char *conf_dir = NULL; - struct file_info f_info; - - MK_TRACE("Load Plugin: '%s'", plugin->shortname); - - snprintf(path, 1024, "%s/%s", - server->path_conf_root, server->conf_plugins); - ret = mk_file_get_info(path, &f_info, MK_FILE_READ); - if (ret == -1 || f_info.is_directory == MK_FALSE) { - snprintf(path, 1024, "%s", server->conf_plugins); - } - - /* Build plugin configuration path */ - mk_string_build(&conf_dir, - &len, - "%s/%s/", - path, plugin->shortname); - - /* Init plugin */ - plugin->api = api; - plugin->server_ctx = server; - - if (plugin->network != NULL) { - plugin->network->plugin = plugin; - } - - ret = plugin->init_plugin(plugin, conf_dir); - mk_mem_free(conf_dir); - - return ret; -} - - -/* - * Load a plugin into Monkey core, 'type' defines if it's a MK_PLUGIN_STATIC or - * a MK_PLUGIN_DYNAMIC. 'shortname' is mandatory and 'path' is only used when - * MK_PLUGIN_DYNAMIC is set and represents the absolute path of the shared - * library. - */ -struct mk_plugin *mk_plugin_load(int type, const char *shortname, - void *data, struct mk_server *server) -{ - char *path; - char symbol[64]; - void *handler; - struct mk_list *head; - struct mk_plugin *tmp; - struct mk_plugin *plugin = NULL; - struct mk_plugin_stage *stage; - - /* Set main struct name to reference */ - if (type == MK_PLUGIN_DYNAMIC) { - path = (char *) data; - handler = mk_plugin_load_dynamic(path); - if (!handler) { - return NULL; - } - - snprintf(symbol, sizeof(symbol) - 1, "mk_plugin_%s", shortname); - plugin = mk_plugin_load_symbol(handler, symbol); - if (!plugin) { - mk_warn("Plugin '%s' is not registering properly", path); -#ifdef _WIN32 - FreeLibrary((HMODULE)handler); -#else - dlclose(handler); -#endif - return NULL; - } - - /* Make sure this is not loaded twice (ref #218) */ - mk_list_foreach(head, &server->plugins) { - tmp = mk_list_entry(head, struct mk_plugin, _head); - if (tmp->load_type == MK_PLUGIN_STATIC && - strcmp(tmp->name, plugin->name) == 0){ - mk_warn("Plugin '%s' have been built-in.", - tmp->shortname); -#ifdef _WIN32 - FreeLibrary((HMODULE)handler); -#else - dlclose(handler); -#endif - return NULL; - } - } - - plugin->load_type = MK_PLUGIN_DYNAMIC; - plugin->handler = handler; - plugin->path = mk_string_dup(path); - } - else if (type == MK_PLUGIN_STATIC) { - plugin = (struct mk_plugin *) data; - plugin->load_type = MK_PLUGIN_STATIC; - } - - if (!plugin) { - return NULL; - } - - /* Validate all callbacks are set */ - if (!plugin->shortname || !plugin->name || !plugin->version || - !plugin->init_plugin || !plugin->exit_plugin) { - mk_warn("Plugin '%s' is not registering all fields properly", - shortname); - return NULL; - } - - if (plugin->hooks & MK_PLUGIN_NETWORK_LAYER) { - mk_bug(!plugin->network); - } - - mk_list_init(&plugin->stage_list); - if (plugin->hooks & MK_PLUGIN_STAGE) { - struct mk_plugin_stage *st; - - stage = plugin->stage; - if (stage->stage10) { - st = mk_mem_alloc(sizeof(struct mk_plugin_stage)); - st->stage10 = stage->stage10; - st->plugin = plugin; - mk_list_add(&st->_head, &server->stage10_handler); - mk_list_add(&st->_parent_head, &plugin->stage_list); - } - if (stage->stage20) { - st = mk_mem_alloc(sizeof(struct mk_plugin_stage)); - st->stage20 = stage->stage20; - st->plugin = plugin; - mk_list_add(&st->_head, &server->stage20_handler); - mk_list_add(&st->_parent_head, &plugin->stage_list); - } - if (stage->stage30) { - st = mk_mem_alloc(sizeof(struct mk_plugin_stage)); - st->stage30 = stage->stage30; - st->plugin = plugin; - mk_list_add(&st->_head, &server->stage30_handler); - mk_list_add(&st->_parent_head, &plugin->stage_list); - } - if (stage->stage40) { - st = mk_mem_alloc(sizeof(struct mk_plugin_stage)); - st->stage40 = stage->stage40; - st->plugin = plugin; - mk_list_add(&st->_head, &server->stage40_handler); - mk_list_add(&st->_parent_head, &plugin->stage_list); - } - if (stage->stage50) { - st = mk_mem_alloc(sizeof(struct mk_plugin_stage)); - st->stage50 = stage->stage50; - st->plugin = plugin; - mk_list_add(&st->_head, &server->stage50_handler); - mk_list_add(&st->_parent_head, &plugin->stage_list); - } - } - - if (type == MK_PLUGIN_DYNAMIC) { - /* Add Plugin to the end of the list */ - mk_list_add(&plugin->_head, &server->plugins); - } - - return plugin; -} - -void mk_plugin_unregister(struct mk_plugin *p) -{ - mk_mem_free(p->path); - mk_list_del(&p->_head); - if (p->load_type == MK_PLUGIN_DYNAMIC) { -#ifdef _WIN32 - FreeLibrary((HMODULE)p->handler); -#else - dlclose(p->handler); -#endif - } - -} - -void mk_plugin_api_init(struct mk_server *server) -{ - struct plugin_api *api; - - /* Create an instance of the API */ - api = mk_mem_alloc_z(sizeof(struct plugin_api)); - -#ifndef _WIN32 - __builtin_prefetch(api); -#endif - - /* Setup and connections list */ - /* FIXME: api->config = server; */ - - /* API plugins funcions */ - - /* Error helper */ - api->_error = mk_print; - - /* HTTP callbacks */ - api->http_request_end = mk_plugin_http_request_end; - api->http_request_error = mk_plugin_http_error; - - /* Memory callbacks */ - api->pointer_set = mk_ptr_set; - api->pointer_print = mk_ptr_print; - api->pointer_to_buf = mk_ptr_to_buf; - api->plugin_load_symbol = mk_plugin_load_symbol; - api->mem_alloc = mk_mem_alloc; - api->mem_alloc_z = mk_mem_alloc_z; - api->mem_realloc = mk_mem_realloc; - api->mem_free = mk_mem_free; - - /* String Callbacks */ - api->str_build = mk_string_build; - api->str_dup = mk_string_dup; - api->str_search = mk_string_search; - api->str_search_n = mk_string_search_n; - api->str_char_search = mk_string_char_search; - api->str_copy_substr = mk_string_copy_substr; - api->str_itop = mk_string_itop; - api->str_split_line = mk_string_split_line; - api->str_split_free = mk_string_split_free; - - /* File Callbacks */ - api->file_to_buffer = mk_file_to_buffer; - api->file_get_info = mk_file_get_info; - - /* HTTP Callbacks */ - api->header_prepare = mk_plugin_header_prepare; - api->header_add = mk_plugin_header_add; - api->header_get = mk_http_header_get; - api->header_set_http_status = mk_header_set_http_status; - - /* Channels / Streams */ - api->channel_new = mk_channel_new; - api->channel_flush = mk_channel_flush; - api->channel_write = mk_channel_write; - api->channel_append_stream = mk_channel_append_stream; - - /* IOV callbacks */ - api->iov_create = mk_iov_create; - api->iov_realloc = mk_iov_realloc; - api->iov_free = mk_iov_free; - api->iov_free_marked = mk_iov_free_marked; - api->iov_add = mk_iov_add; - api->iov_set_entry = mk_iov_set_entry; - api->iov_send = mk_iov_send; - api->iov_print = mk_iov_print; - - /* events mechanism */ - api->ev_loop_create = mk_event_loop_create; - api->ev_add = mk_event_add; - api->ev_del = mk_event_del; - api->ev_timeout_create = mk_event_timeout_create; - api->ev_channel_create = mk_event_channel_create; - api->ev_wait = mk_event_wait; - api->ev_backend = mk_event_backend; - - /* Mimetype */ - api->mimetype_lookup = mk_mimetype_lookup; - - /* Socket callbacks */ - api->socket_cork_flag = mk_socket_set_cork_flag; - api->socket_connect = mk_socket_connect; - api->socket_open = mk_socket_open; - api->socket_reset = mk_socket_reset; - api->socket_set_tcp_fastopen = mk_socket_set_tcp_fastopen; - api->socket_set_tcp_reuseport = mk_socket_set_tcp_reuseport; - api->socket_set_tcp_nodelay = mk_socket_set_tcp_nodelay; - api->socket_set_nonblocking = mk_socket_set_nonblocking; - api->socket_create = mk_socket_create; - api->socket_ip_str = mk_socket_ip_str; - - /* Async network */ - api->net_conn_create = mk_net_conn_create; - - /* Config Callbacks */ - api->config_create = mk_rconf_create; - api->config_open = mk_rconf_open; - api->config_free = mk_rconf_free; - api->config_section_get = mk_rconf_section_get; - api->config_section_get_key = mk_rconf_section_get_key; - - /* Scheduler and Event callbacks */ - api->sched_loop = mk_sched_loop; - api->sched_get_connection = mk_sched_get_connection; - api->sched_event_free = mk_sched_event_free; - api->sched_remove_client = mk_plugin_sched_remove_client; - api->sched_worker_info = mk_plugin_sched_get_thread_conf; - - /* Worker functions */ - api->worker_spawn = mk_utils_worker_spawn; - api->worker_rename = mk_utils_worker_rename; - - /* Time functions */ - api->time_unix = mk_plugin_time_now_unix; - api->time_to_gmt = mk_utils_utime2gmt; - api->time_human = mk_plugin_time_now_human; - - api->stacktrace = (void *) mk_utils_stacktrace; - api->kernel_version = mk_kernel_version; - api->kernel_features_print = mk_kernel_features_print; - api->plugins = &server->plugins; - - /* handler */ - api->handler_param_get = mk_handler_param_get; - - server->api = api; -} - -void mk_plugin_load_static(struct mk_server *server) -{ - /* Load static plugins */ - mk_list_init(&server->plugins); - mk_static_plugins(&server->plugins); -} - -void mk_plugin_load_all(struct mk_server *server) -{ - int ret; - char *tmp; - char *path; - char shortname[64]; - struct mk_plugin *p; - struct mk_rconf *cnf; - struct mk_rconf_section *section; - struct mk_rconf_entry *entry; - struct mk_list *head; - struct mk_list *htmp; - struct file_info f_info; - - mk_plugin_load_static(server); - mk_list_foreach_safe(head, htmp, &server->plugins) { - p = mk_list_entry(head, struct mk_plugin, _head); - - /* Load the static plugin */ - p = mk_plugin_load(MK_PLUGIN_STATIC, - p->shortname, - (void *) p, - server); - if (!p) { - continue; - } - ret = mk_plugin_init(server->api, p, server); - if (ret == -1) { - /* Free plugin, do not register, error initializing */ - mk_warn("Plugin initialization failed: %s", p->shortname); - mk_plugin_unregister(p); - continue; - } - else if (ret == -2) { - /* Do not register, just skip it */ - mk_plugin_unregister(p); - continue; - } - } - - /* In case there are not dynamic plugins */ - if (!server->conf_plugin_load) { - return; - } - - /* Read configuration file */ - path = mk_mem_alloc_z(1024); - snprintf(path, 1024, "%s/%s", server->path_conf_root, - server->conf_plugin_load); - ret = mk_file_get_info(path, &f_info, MK_FILE_READ); - if (ret == -1 || f_info.is_file == MK_FALSE) { - snprintf(path, 1024, "%s", server->conf_plugin_load); - } - - cnf = mk_rconf_open(path); - if (!cnf) { - mk_warn("No dynamic plugins loaded."); - mk_mem_free(path); - return; - } - - /* Read section 'PLUGINS' */ - section = mk_rconf_section_get(cnf, "PLUGINS"); - if (!section) { - exit(EXIT_FAILURE); - } - - /* Read key entries */ - mk_list_foreach_safe(head, htmp, §ion->entries) { - entry = mk_list_entry(head, struct mk_rconf_entry, _head); - if (strcasecmp(entry->key, "Load") == 0) { - - /* Get plugin 'shortname' */ - tmp = memrchr(entry->val, '-', strlen(entry->val)); - ++tmp; - memset(shortname, '\0', sizeof(shortname) - 1); - strncpy(shortname, tmp, strlen(tmp) - 3); - - /* Load the dynamic plugin */ - p = mk_plugin_load(MK_PLUGIN_DYNAMIC, - shortname, - entry->val, - server); - if (!p) { - mk_warn("Invalid plugin '%s'", entry->val); - continue; - } - - ret = mk_plugin_init(server->api, p, server); - if (ret < 0) { - /* Free plugin, do not register */ - MK_TRACE("Unregister plugin '%s'", p->shortname); - mk_plugin_unregister(p); - continue; - } - } - } - - /* Look for plugins thread key data */ - mk_plugin_preworker_calls(server); - mk_vhost_map_handlers(server); - mk_mem_free(path); - mk_rconf_free(cnf); -} - -static void mk_plugin_exit_stages(struct mk_plugin *p) -{ - struct mk_list *tmp; - struct mk_list *head; - struct mk_plugin_stage *st; - - mk_list_foreach_safe(head, tmp, &p->stage_list) { - st = mk_list_entry(head, struct mk_plugin_stage, _parent_head); - - /* remove from direct config->stageN head list */ - mk_list_del(&st->_head); - - /* remove from plugin->stage_lists */ - mk_list_del(&st->_parent_head); - mk_mem_free(st); - } -} - -/* Invoke all plugins 'exit' hook and free resources by the plugin interface */ -void mk_plugin_exit_all(struct mk_server *server) -{ - struct mk_plugin *plugin; - struct mk_list *head, *tmp; - - /* Plugins */ - mk_list_foreach(head, &server->plugins) { - plugin = mk_list_entry(head, struct mk_plugin, _head); - plugin->exit_plugin(plugin); - } - - /* Plugin interface it self */ - mk_list_foreach_safe(head, tmp, &server->plugins) { - plugin = mk_list_entry(head, struct mk_plugin, _head); - mk_list_del(&plugin->_head); - mk_plugin_exit_stages(plugin); - - if (plugin->load_type == MK_PLUGIN_DYNAMIC) { - mk_mem_free(plugin->path); -#ifdef _WIN32 - FreeLibrary((HMODULE)plugin->handler); -#else - dlclose(plugin ->handler); -#endif - } - else if (plugin->load_type == MK_PLUGIN_STATIC) { - if (plugin->network != NULL) { - mk_mem_free(plugin->network); - } - - mk_mem_free(plugin); - } - } - - mk_mem_free(server->api); - mk_mem_free(plg_stagemap); -} - -/* - * When a worker is exiting, it invokes this function to release any plugin - * associated data. - */ -void mk_plugin_exit_worker() -{ -} - -/* This function is called by every created worker - * for plugins which need to set some data under a thread - * context - */ -void mk_plugin_core_process(struct mk_server *server) -{ - struct mk_plugin *node; - struct mk_list *head; - - mk_list_foreach(head, &server->plugins) { - node = mk_list_entry(head, struct mk_plugin, _head); - - /* Init plugin */ - if (node->master_init) { - node->master_init(server); - } - } -} - -/* This function is called by every created worker - * for plugins which need to set some data under a thread - * context - */ -void mk_plugin_core_thread(struct mk_server *server) -{ - - struct mk_plugin *node; - struct mk_list *head; - - mk_list_foreach(head, &server->plugins) { - node = mk_list_entry(head, struct mk_plugin, _head); - - /* Init plugin thread context */ - if (node->worker_init) { - node->worker_init(server); - } - } -} - -/* This function is called by Monkey *outside* of the - * thread context for plugins, so here's the right - * place to set pthread keys or similar - */ -void mk_plugin_preworker_calls(struct mk_server *server) -{ - int ret; - struct mk_plugin *node; - struct mk_list *head; - - mk_list_foreach(head, &server->plugins) { - node = mk_list_entry(head, struct mk_plugin, _head); - - /* Init pthread keys */ - if (node->thread_key) { - MK_TRACE("[%s] Set thread key", node->shortname); - - ret = pthread_key_create(node->thread_key, NULL); - if (ret != 0) { - mk_err("Plugin Error: could not create key for %s", - node->shortname); - } - } - } -} - -int mk_plugin_http_error(int http_status, struct mk_http_session *cs, - struct mk_http_request *sr, - struct mk_plugin *plugin) -{ - return mk_http_error(http_status, cs, sr, plugin->server_ctx); -} - - -int mk_plugin_http_request_end(struct mk_plugin *plugin, - struct mk_http_session *cs, int close) -{ - int ret; - int con; - struct mk_http_request *sr; - struct mk_server *server = plugin->server_ctx; - - MK_TRACE("[FD %i] PLUGIN HTTP REQUEST END", cs->socket); - - cs->status = MK_REQUEST_STATUS_INCOMPLETE; - if (mk_list_is_empty(&cs->request_list) == 0) { - MK_TRACE("[FD %i] Tried to end non-existing request.", cs->socket); - return -1; - } - - sr = mk_list_entry_last(&cs->request_list, struct mk_http_request, _head); - mk_plugin_stage_run_40(cs, sr, server); - - if (close == MK_TRUE) { - cs->close_now = MK_TRUE; - } - - /* Let's check if we should ask to finalize the connection or not */ - ret = mk_http_request_end(cs, server); - MK_TRACE("[FD %i] HTTP session end = %i", cs->socket, ret); - if (ret < 0) { - con = mk_sched_event_close(cs->conn, mk_sched_get_thread_conf(), - MK_EP_SOCKET_DONE, server); - if (con != 0) { - return con; - } - else { - return -1; - } - } - - return ret; -} - -/* Plugin epoll event handlers - * --------------------------- - * this functions are called by connection.c functions as mk_conn_read(), - * mk_conn_write(),mk_conn_error(), mk_conn_close() and mk_conn_timeout(). - * - * Return Values: - * ------------- - * MK_PLUGIN_RET_EVENT_NOT_ME: There's no plugin hook associated - */ - -void mk_plugin_event_bad_return(const char *hook, int ret) -{ - mk_err("[%s] Not allowed return value %i", hook, ret); -} - -int mk_plugin_time_now_unix(struct mk_server *server) -{ - return server->clock_context->log_current_utime; -} - -mk_ptr_t *mk_plugin_time_now_human(struct mk_server *server) -{ - return &server->clock_context->log_current_time; -} - -int mk_plugin_sched_remove_client(int socket, struct mk_server *server) -{ - struct mk_sched_conn *conn; - struct mk_sched_worker *sched; - - MK_TRACE("[FD %i] remove client", socket); - - sched = mk_sched_get_thread_conf(); - conn = mk_sched_get_connection(sched, socket); - if (!conn) { - return -1; - } - - return mk_sched_remove_client(conn, sched, server); -} - -int mk_plugin_header_prepare(struct mk_plugin *plugin, - struct mk_http_session *cs, - struct mk_http_request *sr) -{ - return mk_header_prepare(cs, sr, plugin->server_ctx); -} - - -int mk_plugin_header_add(struct mk_http_request *sr, char *row, int len) -{ - mk_bug(!sr); - - if (!sr->headers._extra_rows) { - /* - * We allocate space for a fixed number of IOV entries: - * - * MK_PLUGIN_HEADER_EXTRA_ROWS = X - * - * we use (MK_PLUGIN_HEADER_EXTRA_ROWS * 2) thinking in an ending CRLF - */ - sr->headers._extra_rows = mk_iov_create(MK_PLUGIN_HEADER_EXTRA_ROWS * 2, 0); - mk_bug(!sr->headers._extra_rows); - } - - mk_iov_add(sr->headers._extra_rows, row, len, - MK_FALSE); - mk_iov_add(sr->headers._extra_rows, - mk_iov_crlf.data, mk_iov_crlf.len, - MK_FALSE); - return 0; -} - -struct mk_sched_worker *mk_plugin_sched_get_thread_conf() -{ - return MK_TLS_GET(mk_tls_sched_worker_node); -} - -struct mk_plugin *mk_plugin_cap(char cap, struct mk_server *server) -{ - struct mk_list *head; - struct mk_plugin *plugin; - - mk_list_foreach(head, &server->plugins) { - plugin = mk_list_entry(head, struct mk_plugin, _head); - if (plugin->capabilities & cap) { - return plugin; - } - } - - return NULL; -} - -struct mk_vhost_handler_param *mk_handler_param_get(int id, - struct mk_list *params) -{ - int i = 0; - struct mk_list *head; - - mk_list_foreach(head, params) { - if (i == id) { - return mk_list_entry(head, struct mk_vhost_handler_param, _head); - } - i++; - } - - return NULL; -} |