summaryrefslogtreecommitdiffstats
path: root/src/web_server.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/web_server.c')
-rw-r--r--src/web_server.c152
1 files changed, 148 insertions, 4 deletions
diff --git a/src/web_server.c b/src/web_server.c
index 72168d15b..d231cbb5c 100644
--- a/src/web_server.c
+++ b/src/web_server.c
@@ -168,6 +168,11 @@ void *socket_listen_main_multi_threaded(void *ptr) {
continue;
}
+ if(api_sockets.fds_families[i] == AF_UNIX)
+ web_client_set_unix(w);
+ else
+ web_client_set_tcp(w);
+
if(pthread_create(&w->thread, NULL, web_client_main, w) != 0) {
error("%llu: failed to create new thread for web client.", w->id);
WEB_CLIENT_IS_OBSOLETE(w);
@@ -203,8 +208,8 @@ static inline int single_threaded_link_client(struct web_client *w, fd_set *ifds
if(unlikely(web_client_check_obsolete(w) || web_client_check_dead(w) || (!web_client_has_wait_receive(w) && !web_client_has_wait_send(w))))
return 1;
- if(unlikely(w->ifd < 0 || w->ifd >= FD_SETSIZE || w->ofd < 0 || w->ofd >= FD_SETSIZE)) {
- error("%llu: invalid file descriptor, ifd = %d, ofd = %d (required 0 <= fd < FD_SETSIZE (%d)", w->id, w->ifd, w->ofd, FD_SETSIZE);
+ if(unlikely(w->ifd < 0 || w->ifd >= (int)FD_SETSIZE || w->ofd < 0 || w->ofd >= (int)FD_SETSIZE)) {
+ error("%llu: invalid file descriptor, ifd = %d, ofd = %d (required 0 <= fd < FD_SETSIZE (%d)", w->id, w->ifd, w->ofd, (int)FD_SETSIZE);
return 1;
}
@@ -261,7 +266,7 @@ void *socket_listen_main_single_threaded(void *ptr) {
fatal("LISTENER: no listen sockets available.");
size_t i;
- for(i = 0; i < FD_SETSIZE ; i++)
+ for(i = 0; i < (size_t)FD_SETSIZE ; i++)
single_threaded_clients[i] = NULL;
fd_set ifds, ofds, efds, rifds, rofds, refds;
@@ -271,7 +276,7 @@ void *socket_listen_main_single_threaded(void *ptr) {
int fdmax = 0;
for(i = 0; i < api_sockets.opened ; i++) {
- if (api_sockets.fds[i] < 0 || api_sockets.fds[i] >= FD_SETSIZE)
+ if (api_sockets.fds[i] < 0 || api_sockets.fds[i] >= (int)FD_SETSIZE)
fatal("LISTENER: Listen socket %d is not ready, or invalid.", api_sockets.fds[i]);
info("Listening on '%s'", (api_sockets.fds_names[i])?api_sockets.fds_names[i]:"UNKNOWN");
@@ -372,3 +377,142 @@ void *socket_listen_main_single_threaded(void *ptr) {
pthread_exit(NULL);
return NULL;
}
+
+
+#if 0
+// new TCP client connected
+static void *web_server_add_callback(int fd, int socktype, short int *events) {
+ (void)fd;
+ (void)socktype;
+
+ *events = POLLIN;
+
+ debug(D_WEB_CLIENT_ACCESS, "LISTENER on %d: new connection.", fd);
+ struct web_client *w = web_client_create(fd);
+
+ if(unlikely(socktype == AF_UNIX))
+ web_client_set_unix(w);
+ else
+ web_client_set_tcp(w);
+
+ return (void *)w;
+}
+
+// TCP client disconnected
+static void web_server_del_callback(int fd, int socktype, void *data) {
+ (void)fd;
+ (void)socktype;
+
+ struct web_client *w = (struct web_client *)data;
+
+ if(w) {
+ if(w->ofd == -1 || fd == w->ofd) {
+ // we free the client, only if the closing fd
+ // is the client socket
+ web_client_free(w);
+ }
+ }
+
+ return;
+}
+
+// Receive data
+static int web_server_rcv_callback(int fd, int socktype, void *data, short int *events) {
+ (void)fd;
+ (void)socktype;
+
+ *events = 0;
+
+ struct web_client *w = (struct web_client *)data;
+
+ if(unlikely(!web_client_has_wait_receive(w)))
+ return -1;
+
+ if(unlikely(web_client_receive(w) < 0))
+ return -1;
+
+ if(unlikely(w->mode == WEB_CLIENT_MODE_FILECOPY)) {
+ if(unlikely(w->ifd != -1 && w->ifd != fd)) {
+ // FIXME: we switched input fd
+ // add a new socket to poll_events, with the same
+ }
+ else if(unlikely(w->ifd == -1)) {
+ // FIXME: we closed input fd
+ // instruct poll_events() to close fd
+ return -1;
+ }
+ }
+ else {
+ debug(D_WEB_CLIENT, "%llu: Processing received data.", w->id);
+ web_client_process_request(w);
+ }
+
+ if(unlikely(w->ifd == fd && web_client_has_wait_receive(w)))
+ *events |= POLLIN;
+
+ if(unlikely(w->ofd == fd && web_client_has_wait_send(w)))
+ *events |= POLLOUT;
+
+ if(unlikely(*events == 0))
+ return -1;
+
+ return 0;
+}
+
+static int web_server_snd_callback(int fd, int socktype, void *data, short int *events) {
+ (void)fd;
+ (void)socktype;
+
+ struct web_client *w = (struct web_client *)data;
+
+ if(unlikely(!web_client_has_wait_send(w)))
+ return -1;
+
+ if(unlikely(web_client_send(w) < 0))
+ return -1;
+
+ if(unlikely(w->ifd == fd && web_client_has_wait_receive(w)))
+ *events |= POLLIN;
+
+ if(unlikely(w->ofd == fd && web_client_has_wait_send(w)))
+ *events |= POLLOUT;
+
+ if(unlikely(*events == 0))
+ return -1;
+
+ return 0;
+}
+
+void *socket_listen_main_single_threaded(void *ptr) {
+ struct netdata_static_thread *static_thread = (struct netdata_static_thread *)ptr;
+
+ web_server_mode = WEB_SERVER_MODE_SINGLE_THREADED;
+
+ info("Single-threaded WEB SERVER thread created with task id %d", gettid());
+
+ if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
+ error("Cannot set pthread cancel type to DEFERRED.");
+
+ if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
+ error("Cannot set pthread cancel state to ENABLE.");
+
+ if(!api_sockets.opened)
+ fatal("LISTENER: no listen sockets available.");
+
+ poll_events(&api_sockets
+ , web_server_add_callback
+ , web_server_del_callback
+ , web_server_rcv_callback
+ , web_server_snd_callback
+ , web_allow_connections_from
+ , NULL
+ );
+
+ debug(D_WEB_CLIENT, "LISTENER: exit!");
+ listen_sockets_close(&api_sockets);
+
+ static_thread->enabled = 0;
+ pthread_exit(NULL);
+ return NULL;
+}
+#endif