summaryrefslogtreecommitdiffstats
path: root/src/fluent-bit/lib/monkey/plugins/liana/liana.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fluent-bit/lib/monkey/plugins/liana/liana.c')
-rw-r--r--src/fluent-bit/lib/monkey/plugins/liana/liana.c221
1 files changed, 221 insertions, 0 deletions
diff --git a/src/fluent-bit/lib/monkey/plugins/liana/liana.c b/src/fluent-bit/lib/monkey/plugins/liana/liana.c
new file mode 100644
index 000000000..3bfe288b8
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/plugins/liana/liana.c
@@ -0,0 +1,221 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/* Monkey HTTP Server
+ * ==================
+ * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <fcntl.h>
+
+#ifdef _WIN32
+#include <winsock2.h>
+#else
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#endif
+
+#if defined (__linux__)
+#include <sys/sendfile.h>
+#endif
+
+#include <monkey/mk_api.h>
+
+int mk_liana_plugin_init(struct mk_plugin *plugin, char *confdir)
+{
+ (void) confdir;
+ (void) plugin;
+
+ return 0;
+}
+
+int mk_liana_plugin_exit(struct mk_plugin *plugin)
+{
+ (void) plugin;
+
+ return 0;
+}
+
+int mk_liana_read(struct mk_plugin *plugin, int socket_fd, void *buf, int count)
+{
+ (void) plugin;
+
+ return recv(socket_fd, (void*)buf, count, 0);
+}
+
+int mk_liana_write(struct mk_plugin *plugin, int socket_fd, const void *buf, size_t count )
+{
+ ssize_t bytes_sent = -1;
+
+ (void) plugin;
+
+ bytes_sent = send(socket_fd, buf, count, 0);
+
+ return bytes_sent;
+}
+
+int mk_liana_writev(struct mk_plugin *plugin, int socket_fd, struct mk_iov *mk_io)
+{
+ ssize_t bytes_sent = -1;
+
+ (void) plugin;
+
+ bytes_sent = plugin->api->iov_send(socket_fd, mk_io);
+
+ return bytes_sent;
+}
+
+int mk_liana_close(struct mk_plugin *plugin, int socket_fd)
+{
+ (void) plugin;
+
+#ifdef _WIN32
+ return closesocket(socket_fd);
+#else
+ return close(socket_fd);
+#endif
+}
+
+int mk_liana_send_file(struct mk_plugin *plugin, int socket_fd, int file_fd, off_t *file_offset,
+ size_t file_count)
+{
+ ssize_t ret = -1;
+
+ (void) plugin;
+
+#if defined (__linux__)
+ ret = sendfile(socket_fd, file_fd, file_offset, file_count);
+ if (ret == -1 && errno != EAGAIN) {
+ PLUGIN_TRACE("[FD %i] error from sendfile(): %s",
+ socket_fd, strerror(errno));
+ }
+ return ret;
+#elif defined (__APPLE__)
+ off_t offset = *file_offset;
+ off_t len = (off_t) file_count;
+
+ ret = sendfile(file_fd, socket_fd, offset, &len, NULL, 0);
+ if (ret == -1 && errno != EAGAIN) {
+ PLUGIN_TRACE("[FD %i] error from sendfile(): %s",
+ socket_fd, strerror(errno));
+ }
+ else if (len > 0) {
+ *file_offset += len;
+ return len;
+ }
+ return ret;
+#elif defined (__FreeBSD__)
+ off_t offset = *file_offset;
+ off_t len = (off_t) file_count;
+
+ ret = sendfile(file_fd, socket_fd, offset, len, NULL, 0, 0);
+ if (ret == -1 && errno != EAGAIN) {
+ PLUGIN_TRACE("[FD %i] error from sendfile(): %s",
+ socket_fd, strerror(errno));
+ }
+ else if (len > 0) {
+ *file_offset += len;
+ return len;
+ }
+ return ret;
+#else
+ #pragma message ("This is a terrible sendfile \"implementation\" and just a crutch")
+
+ ssize_t bytes_written = 0;
+ ssize_t to_be_sent = -1;
+ ssize_t send_ret = -1;
+ uint8_t temporary_buffer[1024];
+
+ if (NULL != file_offset) {
+ lseek(file_fd, *file_offset, SEEK_SET);
+ }
+
+ while (1) {
+ memset(temporary_buffer, 0, sizeof(temporary_buffer));
+
+ ret = read(file_fd, temporary_buffer, sizeof(temporary_buffer));
+
+ if (0 == ret)
+ {
+ return bytes_written;
+ }
+ else if (0 > ret)
+ {
+ return -1;
+ }
+ else if (0 < ret)
+ {
+ to_be_sent = ret;
+
+ while (to_be_sent > 0)
+ {
+ send_ret = send(file_fd, &temporary_buffer[ret - to_be_sent], to_be_sent, 0);
+
+ if (-1 == send_ret)
+ {
+ if (EAGAIN != errno &&
+ EWOULDBLOCK != errno)
+ {
+ return -1;
+ }
+ }
+ else
+ {
+ bytes_written += send_ret;
+ to_be_sent -= send_ret;
+ }
+ }
+ }
+ }
+#endif
+}
+
+/* Network Layer plugin Callbacks */
+struct mk_plugin_network mk_plugin_network_liana = {
+ .read = mk_liana_read,
+ .write = mk_liana_write,
+ .writev = mk_liana_writev,
+ .close = mk_liana_close,
+ .send_file = mk_liana_send_file,
+ .buffer_size = MK_REQUEST_CHUNK
+};
+
+struct mk_plugin mk_plugin_liana = {
+ /* Identification */
+ .shortname = "liana",
+ .name = "Liana Network Layer",
+ .version = MK_VERSION_STR,
+ .hooks = MK_PLUGIN_NETWORK_LAYER,
+
+ /* Init / Exit */
+ .init_plugin = mk_liana_plugin_init,
+ .exit_plugin = mk_liana_plugin_exit,
+
+ /* Init Levels */
+ .master_init = NULL,
+ .worker_init = NULL,
+
+ /* Type */
+ .network = &mk_plugin_network_liana,
+
+ /* Capabilities */
+ .capabilities = MK_CAP_SOCK_PLAIN
+};