diff --git a/buildconf/base.ini b/buildconf/base.ini index a8cd89f0..6058d1b1 100644 --- a/buildconf/base.ini +++ b/buildconf/base.ini @@ -6,13 +6,7 @@ json = auto sqlite3 = auto zeromq = auto snmp = true -spooler = true -embedded = true ssl = auto -udp = true -multicast = true -threading = true -minterpreters = true async = true ldap = auto pcre = auto diff --git a/buildconf/unbit.ini b/buildconf/unbit.ini index 671846e7..e0acc804 100644 --- a/buildconf/unbit.ini +++ b/buildconf/unbit.ini @@ -5,14 +5,6 @@ yaml = true json = false sqlite3 = false zeromq = false -snmp = false -spooler = true -embedded = true -udp = true -multicast = false -threading = true -minterpreters = true -async = true ldap = true pcre = true routing = true diff --git a/core/async.c b/core/async.c index 5d00f7cb..17f0808c 100644 --- a/core/async.c +++ b/core/async.c @@ -1,4 +1,4 @@ -#include "uwsgi.h" +#include extern struct uwsgi_server uwsgi; @@ -216,7 +216,7 @@ void async_add_fd_write(struct wsgi_request *wsgi_req, int fd, int timeout) { } void async_schedule_to_req(void) { - uwsgi.wsgi_req->async_status = uwsgi.p[uwsgi.wsgi_req->uh.modifier1]->request(uwsgi.wsgi_req); + uwsgi.wsgi_req->async_status = uwsgi.p[uwsgi.wsgi_req->uh->modifier1]->request(uwsgi.wsgi_req); } void async_loop() { diff --git a/core/buffer.c b/core/buffer.c index 038cd5cc..e05a66b2 100644 --- a/core/buffer.c +++ b/core/buffer.c @@ -250,7 +250,7 @@ void uwsgi_buffer_destroy(struct uwsgi_buffer *ub) { ssize_t uwsgi_buffer_write_simple(struct wsgi_request *wsgi_req, struct uwsgi_buffer *ub) { size_t remains = ub->pos; while(remains) { - ssize_t len = write(wsgi_req->poll.fd, ub->buf + (ub->pos - remains), remains); + ssize_t len = write(wsgi_req->fd, ub->buf + (ub->pos - remains), remains); if (len <= 0) { return len; } diff --git a/core/channels.c b/core/channels.c deleted file mode 100644 index ce8a4927..00000000 --- a/core/channels.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - - uWSGI channels - -Channels are a way to cores to exchange messages with other cores (both on other workers and other instances) - -Channels are quiet expensive (2 descriptors for each core in the instance) but very fast - -1000 core for 4 workers = 8000 fd for a channel - - a channel structure (created by the master for each channel) - - char *name; - int fd[cores*numproc*2]; - uint8_t subscriptions[cores*numproc]; - uint64_t max_packet_size; - uint64_t tx; - uint64_t rx; - -the channels messages dispatcher lives in a master's thread - -when a worker dies: - clear the whole subscriptions memory area (read: unsubscribe dead cores) - -when a request end: - clear the byte in the subscriptions memory area: - - -non-blocking communication: - - the first rule is not block. If the socket queue of a core is full the message is discarded... REMEMBER THAT - only the main socket (the one in which cores write) can block (as the dispatcher constantly read from it) - - -avoiding unwanted messages: - -race conditions will be all over the place. To avoid receiving unwanted messages (that could be in the queue), the socket queue -is emptied before joining a channel and soon after leaving it. - -When a worker restarts all of its queue are emptied. - -queue size is tunable (this is a vital part for gaming as you may want to enqueue a lot of events, or just drop them instead of slowing down things) - - -*/ - -#include "../uwsgi.h" -extern struct uwsgi_server uwsgi; - -struct uwsgi_channel *uwsgi_channel_new(char *name) { - struct uwsgi_channel *old_c = NULL, *channel = uwsgi.channels; - while(channel) { - old_c = channel; - channel = channel->next; - } - - channel = uwsgi_calloc_shared(sizeof(struct uwsgi_channel)); - channel->name = name; -#if defined(SOCK_SEQPACKET) && defined(__linux__) - if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, channel->write_pipe)) { -#else - if (socketpair(AF_UNIX, SOCK_DGRAM, 0, channel->write_pipe)) { -#endif - uwsgi_error("unable to initialize channel/socketpair()"); - exit(1); - } - - uwsgi_socket_nb(channel->write_pipe[0]); - uwsgi_socket_nb(channel->write_pipe[1]); - - channel->fd = uwsgi_calloc_shared(sizeof(int) * ((uwsgi.cores*uwsgi.numproc) * 2)); - int i,j; - for(i=0;ifd[fd_pos])) { -#else - if (socketpair(AF_UNIX, SOCK_DGRAM, 0, &channel->fd[fd_pos])) { -#endif - uwsgi_error("unable to initialize channel/socketpair()"); - exit(1); - } - uwsgi_socket_nb(channel->fd[fd_pos]); - uwsgi_socket_nb(channel->fd[fd_pos+1]); - } - } - - channel->subscriptions = uwsgi_calloc_shared(uwsgi.cores*uwsgi.numproc); - channel->max_packet_size = 65536; - channel->pktbuf = uwsgi_malloc(channel->max_packet_size); - - if (old_c) { - old_c->next = channel; - } - else { - uwsgi.channels = channel; - } - - return channel; -} - -struct uwsgi_buffer *uwsgi_channel_simple_recv(struct wsgi_request *wsgi_req, int fd, struct uwsgi_buffer *ub, int timeout) { - int ret = uwsgi_waitfd(fd, timeout); - if (ret < 0) return NULL; - if (ret == 0) return ub; - ssize_t len = read(fd, ub->buf, ub->len); - if (len <= 0) return NULL; - ub->pos += len; - return ub; -} - -void uwsgi_channels_init(void) { - struct uwsgi_string_list *c = uwsgi.channels_list; - while(c) { - uwsgi_channel_new(c->value); - c = c->next; - } - - uwsgi.channel_recv_hook = uwsgi_channel_simple_recv; -} - -struct uwsgi_channel *uwsgi_channel_by_name(char *name) { - struct uwsgi_channel *channel = uwsgi.channels; - while(channel) { - if (!strcmp(name, channel->name)) { - return channel; - } - channel = channel->next; - } - - return NULL; -} - -struct uwsgi_channel *uwsgi_channel_find_by_fd(int fd) { - struct uwsgi_channel *channel = uwsgi.channels; - while(channel) { - if (fd == channel->write_pipe[0]) { - return channel; - } - channel = channel->next; - } - - return NULL; -} - -void uwsgi_channel_consume(struct uwsgi_channel *c, int fd) { - char *buf = uwsgi_calloc(c->max_packet_size); - for(;;) { - ssize_t len = read(fd, buf, c->max_packet_size); - if (len <= 0) { - free(buf); - return; - } - } -} - -// 1 -> standard join -// 2 -> websocket join -void uwsgi_channel_join(struct wsgi_request *wsgi_req, struct uwsgi_channel *c, uint8_t t) { - - int s_pos = (uwsgi.cores * (uwsgi.mywid-1)) + wsgi_req->async_id; - int fd_pos = ((uwsgi.cores * (uwsgi.mywid-1)) + wsgi_req->async_id) *2; - - uint8_t subscribed = c->subscriptions[s_pos]; - - if (subscribed) { - return; - } - - int fd = c->fd[fd_pos+1]; - - uwsgi_channel_consume(c, fd); - - c->subscriptions[s_pos] = t; - -} - -void uwsgi_channel_leave(struct wsgi_request *wsgi_req, struct uwsgi_channel *c) { - int s_pos = (uwsgi.cores * (uwsgi.mywid-1)) + wsgi_req->async_id; - int fd_pos = ((uwsgi.cores * (uwsgi.mywid-1)) + wsgi_req->async_id) *2; - - uint8_t subscribed = c->subscriptions[s_pos]; - - if (!subscribed) { - return; - } - - c->subscriptions[s_pos] = 0; - - int fd = c->fd[fd_pos+1]; - - uwsgi_channel_consume(c, fd); -} - -void uwsgi_channels_leave(struct wsgi_request *wsgi_req) { - struct uwsgi_channel *channel = uwsgi.channels; - while(channel) { - uwsgi_channel_leave(wsgi_req, channel); - channel = channel->next; - } -} - - -int uwsgi_channel_send(struct uwsgi_channel *c, char *msg, size_t msg_len) { - ssize_t len = write(c->write_pipe[1], msg, msg_len); - if (len != (ssize_t) msg_len) { - uwsgi_error("uwsgi_channel_send()/write()"); - return -1; - } - return 0; -} - -struct uwsgi_buffer *uwsgi_channel_recv(struct wsgi_request *wsgi_req, struct uwsgi_channel *c, int timeout) { - int s_pos = (uwsgi.cores * (uwsgi.mywid-1)) + wsgi_req->async_id; - int fd_pos = ((uwsgi.cores * (uwsgi.mywid-1)) + wsgi_req->async_id) *2; - - uint8_t subscribed = c->subscriptions[s_pos]; - - if (!subscribed) { - return NULL; - } - - int fd = c->fd[fd_pos+1]; - - struct uwsgi_buffer *ub = uwsgi_buffer_new(c->max_packet_size); - if (!uwsgi.channel_recv_hook(wsgi_req, fd, ub, timeout)) { - uwsgi_buffer_destroy(ub); - ub = NULL; - } - return ub; -} - -void uwsgi_channels_reset_worker_subscriptions(int wid) { - struct uwsgi_channel *channel = uwsgi.channels; - while(channel) { - memset(channel->subscriptions + (uwsgi.cores * (wid-1)), 0, uwsgi.cores); - channel = channel->next; - } -} - -void *uwsgi_channels_loop(void *foobar) { - - // block all signals - sigset_t smask; - sigfillset(&smask); - pthread_sigmask(SIG_BLOCK, &smask, NULL); - - int i; - int queue = event_queue_init(); - struct uwsgi_channel *channel = uwsgi.channels; - while(channel) { - event_queue_add_fd_read(queue, channel->write_pipe[0]); - channel = channel->next; - } - - void *events = event_queue_alloc(64); - int items = uwsgi.cores * uwsgi.numproc; - - for(;;) { - int nevents = event_queue_wait_multi(queue, -1, events, 64); - for(i=0;iwrite_pipe[0], channel->pktbuf, channel->max_packet_size); - if (len <= 0) { - uwsgi_error("[channel-dispatcher] read()"); - continue; - } - - int j; - for(j=0;jsubscriptions[j] > 0) { - int fd = channel->fd[j*2]; - ssize_t wlen = write(fd, channel->pktbuf, len); - if (wlen != len) { - uwsgi_error("channels_dispatcher_write()"); - } - } - } - } - } - - return NULL; -} diff --git a/core/cluster.c b/core/cluster.c deleted file mode 100644 index 76c749c2..00000000 --- a/core/cluster.c +++ /dev/null @@ -1,466 +0,0 @@ -#include "uwsgi.h" - -extern struct uwsgi_server uwsgi; - - -#ifdef UWSGI_UDP - -static void cluster_manage_opt(char *key, uint16_t keylen, char *value, uint16_t vallen, void *foobar) { - - add_exported_option(uwsgi_concat2n(key, keylen, "", 0), uwsgi_concat2n(value, vallen, "", 0), 0); - -} - -void cluster_setup() { - - int rlen; -// get cluster configuration - if (uwsgi.cluster != NULL) { - // get multicast socket - - uwsgi.cluster_fd = uwsgi_cluster_join(uwsgi.cluster); - - uwsgi_log("JOINED CLUSTER: %s\n", uwsgi.cluster); - - // ask for cluster options only if bot pre-existent options are set - if (uwsgi.exported_opts_cnt == 1 && !uwsgi.cluster_nodes) { - // now wait max 60 seconds and resend multicast request every 10 seconds - for (;;) { - uwsgi_log("asking \"%s\" uWSGI cluster for configuration data:\n", uwsgi.cluster); - if (uwsgi_send_empty_pkt(uwsgi.cluster_fd, uwsgi.cluster, 99, 0) < 0) { - uwsgi_log("unable to send multicast message to %s\n", uwsgi.cluster); - continue; - } -waitfd: - rlen = uwsgi_waitfd(uwsgi.cluster_fd, 10); - if (rlen < 0) { - break; - } - else if (rlen > 0) { - // receive the packet - char clusterbuf[4096]; - if (!uwsgi_hooked_parse_dict_dgram(uwsgi.cluster_fd, clusterbuf, 4096, 99, 1, cluster_manage_opt, NULL)) { - uwsgi_configure(); - goto options_parsed; - } - else { - goto waitfd; - } - } - } - } -options_parsed: - - if (!uwsgi.cluster_nodes) - uwsgi_cluster_add_me(); - } -} - - - - -void uwsgi_cluster_add_node(struct uwsgi_cluster_node *nucn, int type) { - - int i; - struct uwsgi_cluster_node *ucn; - char *tcp_port; - -#ifdef UWSGI_DEBUG - uwsgi_log("adding node\n"); -#endif - - tcp_port = strchr(nucn->name, ':'); -#ifndef UWSGI_ZEROMQ - if (tcp_port == NULL) { -#else - char *zmq_dash = strchr(nucn->name, '-'); - if (tcp_port == NULL && zmq_dash == NULL) { -#endif - - fprintf(stdout, "invalid cluster node name %s\n", nucn->name); - return; - } - - // first check for already present node - for (i = 0; i < MAX_CLUSTER_NODES; i++) { - ucn = &uwsgi.shared->nodes[i]; - if (ucn->name[0] != 0) { - if (!strcmp(ucn->name, nucn->name)) { - ucn->status = UWSGI_NODE_OK; - ucn->last_seen = uwsgi_now(); - // update requests - ucn->requests = nucn->requests; - return; - } - } - } - - for (i = 0; i < MAX_CLUSTER_NODES; i++) { - ucn = &uwsgi.shared->nodes[i]; - - if (ucn->name[0] == 0) { - memcpy(ucn->name, nucn->name, strlen(nucn->name) + 1); - memcpy(ucn->nodename, nucn->nodename, strlen(nucn->nodename) + 1); - ucn->workers = nucn->workers; - ucn->ucn_addr.sin_family = AF_INET; - if (tcp_port) { - ucn->ucn_addr.sin_port = htons(atoi(tcp_port + 1)); - tcp_port[0] = 0; - } - if (nucn->name[0] == 0) { - ucn->ucn_addr.sin_addr.s_addr = INADDR_ANY; - } - else { -#ifdef UWSGI_DEBUG - uwsgi_log("%s\n", nucn->name); -#endif - ucn->ucn_addr.sin_addr.s_addr = inet_addr(nucn->name); - } - - ucn->type = type; - // here memory can be freed, as it is allocated by uwsgi_concat2n - if (type != CLUSTER_NODE_DYNAMIC && tcp_port) { - tcp_port[0] = ':'; - } - ucn->last_seen = uwsgi_now(); - ucn->requests = nucn->requests; - uwsgi_log("[uWSGI cluster] added node %s\n", ucn->name); - return; - } - } - - uwsgi_log("unable to add node %s\n", nucn->name); -} - - - -int uwsgi_cluster_add_me() { - - const char *key1 = "hostname"; - const char *key2 = "address"; - const char *key3 = "workers"; - const char *key4 = "requests"; - - char *ptrbuf; - uint16_t ustrlen; - char numproc[6]; - -#ifdef UWSGI_ZEROMQ - char uuid_zmq_str[37]; - uuid_t uuid_zmq; - if (!uwsgi.sockets && !uwsgi.zeromq) { -#else - if (!uwsgi.sockets) { -#endif - uwsgi_log("you need to specify at least a socket to start a uWSGI cluster\n"); - exit(1); - } - - snprintf(numproc, 6, "%d", uwsgi.numproc); - - size_t len; - - if (uwsgi.sockets) { - len = 2 + strlen(key1) + 2 + strlen(uwsgi.hostname) + 2 + strlen(key2) + 2 + strlen(uwsgi.sockets->name) + 2 + strlen(key3) + 2 + strlen(numproc) + 2 + strlen(key4) + 2 + 1; - } -#ifdef UWSGI_ZEROMQ - else if (uwsgi.zeromq) { - uuid_generate(uuid_zmq); - uuid_unparse(uuid_zmq, uuid_zmq_str); - len = 2 + strlen(key1) + 2 + strlen(uwsgi.hostname) + 2 + strlen(key2) + 2 + strlen(uuid_zmq_str) + 2 + strlen(key3) + 2 + strlen(numproc) + 2 + strlen(key4) + 2 + 1; - } -#endif - else { - len = 2 + strlen(key1) + 2 + strlen(uwsgi.hostname) + 2 + strlen(key3) + 2 + strlen(numproc) + 2 + strlen(key4) + 2 + 1; - } - char *buf = uwsgi_malloc(len); - - ptrbuf = buf; - - ustrlen = strlen(key1); - *ptrbuf++ = (uint8_t) (ustrlen & 0xff); - *ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff); - memcpy(ptrbuf, key1, strlen(key1)); - ptrbuf += strlen(key1); - - ustrlen = strlen(uwsgi.hostname); - *ptrbuf++ = (uint8_t) (ustrlen & 0xff); - *ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff); - memcpy(ptrbuf, uwsgi.hostname, strlen(uwsgi.hostname)); - ptrbuf += strlen(uwsgi.hostname); - - - if (uwsgi.sockets && uwsgi.sockets->name) { - ustrlen = strlen(key2); - *ptrbuf++ = (uint8_t) (ustrlen & 0xff); - *ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff); - memcpy(ptrbuf, key2, strlen(key2)); - ptrbuf += strlen(key2); - - ustrlen = strlen(uwsgi.sockets->name); - *ptrbuf++ = (uint8_t) (ustrlen & 0xff); - *ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff); - memcpy(ptrbuf, uwsgi.sockets->name, strlen(uwsgi.sockets->name)); - ptrbuf += strlen(uwsgi.sockets->name); - } -#ifdef UWSGI_ZEROMQ - else if (uwsgi.zeromq) { - ustrlen = strlen(key2); - *ptrbuf++ = (uint8_t) (ustrlen & 0xff); - *ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff); - memcpy(ptrbuf, key2, strlen(key2)); - ptrbuf += strlen(key2); - - ustrlen = strlen(uuid_zmq_str); - *ptrbuf++ = (uint8_t) (ustrlen & 0xff); - *ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff); - memcpy(ptrbuf, uuid_zmq_str, strlen(uuid_zmq_str)); - ptrbuf += strlen(uuid_zmq_str); - } -#endif - - - ustrlen = strlen(key3); - *ptrbuf++ = (uint8_t) (ustrlen & 0xff); - *ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff); - memcpy(ptrbuf, key3, strlen(key3)); - ptrbuf += strlen(key3); - - ustrlen = strlen(numproc); - *ptrbuf++ = (uint8_t) (ustrlen & 0xff); - *ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff); - memcpy(ptrbuf, numproc, strlen(numproc)); - ptrbuf += strlen(numproc); - - ustrlen = strlen(key4); - *ptrbuf++ = (uint8_t) (ustrlen & 0xff); - *ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff); - memcpy(ptrbuf, key4, strlen(key4)); - ptrbuf += strlen(key4); - - ustrlen = 1; - *ptrbuf++ = (uint8_t) (ustrlen & 0xff); - *ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff); - memcpy(ptrbuf, "0", 1); - ptrbuf += 1; - - - uwsgi_string_sendto(uwsgi.cluster_fd, 95, 0, (struct sockaddr *) &uwsgi.mc_cluster_addr, sizeof(uwsgi.mc_cluster_addr), buf, len); - - free(buf); - -#ifdef UWSGI_DEBUG - uwsgi_log("add_me() successfull\n"); -#endif - - return 0; -} - - -int uwsgi_cluster_join(char *name) { - - int fd; - char *cp; - int broadcast = 0; - - - - if (name[0] == ':') { - fd = bind_to_udp(name, 0, 1); - broadcast = 1; - } - else { - fd = bind_to_udp(name, 1, 0); - } - - if (fd >= 0) { - cp = strchr(name, ':'); - cp[0] = 0; - uwsgi.mc_cluster_addr.sin_family = AF_INET; - if (broadcast) { - uwsgi.mc_cluster_addr.sin_addr.s_addr = INADDR_BROADCAST; - } - else { - uwsgi.mc_cluster_addr.sin_addr.s_addr = inet_addr(name); - } - uwsgi.mc_cluster_addr.sin_port = htons(atoi(cp + 1)); - cp[0] = ':'; - - - // announce my presence to all the nodes - uwsgi_string_sendto(fd, 73, 0, (struct sockaddr *) &uwsgi.mc_cluster_addr, sizeof(uwsgi.mc_cluster_addr), uwsgi.hostname, strlen(uwsgi.hostname)); - } - else { - exit(1); - } - - - return fd; - -} - - -char *uwsgi_cluster_best_node() { - - int i; - int best_node = -1; - struct uwsgi_cluster_node *ucn; - - for (i = 0; i < MAX_CLUSTER_NODES; i++) { - ucn = &uwsgi.shared->nodes[i]; - if (ucn->name[0] != 0 && ucn->status == UWSGI_NODE_OK) { - if (best_node == -1) { - best_node = i; - } - else { - if (ucn->last_choosen < uwsgi.shared->nodes[best_node].last_choosen) { - best_node = i; - } - } - } - } - - if (best_node == -1) { - return NULL; - } - - uwsgi.shared->nodes[best_node].last_choosen = uwsgi_now(); - return uwsgi.shared->nodes[best_node].name; -} - - -void manage_cluster_announce(char *key, uint16_t keylen, char *val, uint16_t vallen, void *data) { - - char *tmpstr; - struct uwsgi_cluster_node *ucn = (struct uwsgi_cluster_node *) data; - -#ifdef UWSGI_DEBUG - uwsgi_log("%.*s = %.*s\n", keylen, key, vallen, val); -#endif - - if (!uwsgi_strncmp("hostname", 8, key, keylen)) { - strncpy(ucn->nodename, val, UMIN(vallen, 255)); - } - - if (!uwsgi_strncmp("address", 7, key, keylen)) { - strncpy(ucn->name, val, UMIN(vallen, 100)); - } - - if (!uwsgi_strncmp("workers", 7, key, keylen)) { - tmpstr = uwsgi_concat2n(val, vallen, "", 0); - ucn->workers = atoi(tmpstr); - free(tmpstr); - } - - if (!uwsgi_strncmp("requests", 8, key, keylen)) { - tmpstr = uwsgi_concat2n(val, vallen, "", 0); - ucn->requests = strtoul(tmpstr, NULL, 0); - free(tmpstr); - } -} - -void manage_cluster_message(char *cluster_opt_buf, int cluster_opt_size) { - - struct uwsgi_cluster_node nucn; - - switch (uwsgi.workers[0].cores[0].req.uh.modifier1) { - case 95: - memset(&nucn, 0, sizeof(struct uwsgi_cluster_node)); - -#ifdef __BIG_ENDIAN__ - uwsgi.workers[0].cores[0].req.uh.pktsize = uwsgi_swap16(uwsgi.workers[0].cores[0].req.uh.pktsize); -#endif - uwsgi_hooked_parse(uwsgi.workers[0].cores[0].req.buffer, uwsgi.workers[0].cores[0].req.uh.pktsize, manage_cluster_announce, &nucn); - if (nucn.name[0] != 0) { - uwsgi_cluster_add_node(&nucn, CLUSTER_NODE_DYNAMIC); - } - break; - case 96: -#ifdef __BIG_ENDIAN__ - uwsgi.workers[0].cores[0].req.uh.pktsize = uwsgi_swap16(uwsgi.workers[0].cores[0].req.uh.pktsize); -#endif - uwsgi_log_verbose("%.*s\n", uwsgi.workers[0].cores[0].req.uh.pktsize, uwsgi.workers[0].cores[0].req.buffer); - break; - case 98: - if (kill(getpid(), SIGHUP)) { - uwsgi_error("kill()"); - } - break; - case 99: - if (uwsgi.cluster_nodes) - break; - if (uwsgi.workers[0].cores[0].req.uh.modifier2 == 0) { - uwsgi_log("requested configuration data, sending %d bytes\n", cluster_opt_size); - if (sendto(uwsgi.cluster_fd, cluster_opt_buf, cluster_opt_size, 0, (struct sockaddr *) &uwsgi.mc_cluster_addr, sizeof(uwsgi.mc_cluster_addr)) < 0) { - uwsgi_error("sendto()"); - } - } - break; - case 73: -#ifdef __BIG_ENDIAN__ - uwsgi.workers[0].cores[0].req.uh.pktsize = uwsgi_swap16(uwsgi.workers[0].cores[0].req.uh.pktsize); -#endif - uwsgi_log_verbose("[uWSGI cluster %s] new node available: %.*s\n", uwsgi.cluster, uwsgi.workers[0].cores[0].req.uh.pktsize, uwsgi.workers[0].cores[0].req.buffer); - break; - } -} - -#endif - - -char *uwsgi_setup_clusterbuf(size_t * size) { - - size_t cluster_opt_size = 4; - int i; - - for (i = 0; i < uwsgi.exported_opts_cnt; i++) { - //uwsgi_log("%s\n", uwsgi.exported_opts[i]->key); - cluster_opt_size += 2 + strlen(uwsgi.exported_opts[i]->key); - if (uwsgi.exported_opts[i]->value) { - cluster_opt_size += 2 + strlen(uwsgi.exported_opts[i]->value); - } - else { - cluster_opt_size += 2 + 1; - } - } - - //uwsgi_log("cluster opts size: %d\n", cluster_opt_size); - char *cluster_opt_buf = uwsgi_malloc(cluster_opt_size); - - struct uwsgi_header *uh = (struct uwsgi_header *) cluster_opt_buf; - - uh->modifier1 = 99; - uh->pktsize = cluster_opt_size - 4; - uh->modifier2 = 1; - -#ifdef __BIG_ENDIAN__ - uh->pktsize = uwsgi_swap16(uh->pktsize); -#endif - - char *cptrbuf = cluster_opt_buf + 4; - - for (i = 0; i < uwsgi.exported_opts_cnt; i++) { - //uwsgi_log("%s\n", uwsgi.exported_opts[i]->key); - uint16_t ustrlen = strlen(uwsgi.exported_opts[i]->key); - *cptrbuf++ = (uint8_t) (ustrlen & 0xff); - *cptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff); - memcpy(cptrbuf, uwsgi.exported_opts[i]->key, ustrlen); - cptrbuf += ustrlen; - - if (uwsgi.exported_opts[i]->value) { - ustrlen = strlen(uwsgi.exported_opts[i]->value); - *cptrbuf++ = (uint8_t) (ustrlen & 0xff); - *cptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff); - memcpy(cptrbuf, uwsgi.exported_opts[i]->value, ustrlen); - } - else { - ustrlen = 1; - *cptrbuf++ = (uint8_t) (ustrlen & 0xff); - *cptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff); - *cptrbuf = '1'; - } - cptrbuf += ustrlen; - } - - return cluster_opt_buf; -} diff --git a/core/init.c b/core/init.c index cbb287b4..4a661ef1 100644 --- a/core/init.c +++ b/core/init.c @@ -87,7 +87,6 @@ void uwsgi_init_default() { uwsgi.subscribe_freq = 10; uwsgi.subscription_tolerance = 17; - uwsgi.cluster_fd = -1; uwsgi.cores = 1; uwsgi.threads = 1; @@ -96,6 +95,7 @@ void uwsgi_init_default() { uwsgi.default_app = -1; uwsgi.buffer_size = 4096; + uwsgi.body_read_warning = 8; uwsgi.numproc = 1; uwsgi.forkbomb_delay = 2; @@ -117,12 +117,11 @@ void uwsgi_init_default() { uwsgi.shared->options[UWSGI_OPTION_MIN_WORKER_LIFETIME] = 60; -#ifdef UWSGI_SPOOLER uwsgi.shared->spooler_frequency = 30; uwsgi.shared->spooler_signal_pipe[0] = -1; uwsgi.shared->spooler_signal_pipe[1] = -1; -#endif + uwsgi.shared->mule_signal_pipe[0] = -1; uwsgi.shared->mule_signal_pipe[1] = -1; @@ -148,10 +147,8 @@ void uwsgi_init_default() { #endif -#ifdef UWSGI_MULTICAST uwsgi.multicast_ttl = 1; uwsgi.multicast_loop = 1; -#endif // filling http status codes struct http_status_codes *http_sc; @@ -159,8 +156,11 @@ void uwsgi_init_default() { http_sc->message_size = strlen(http_sc->message); } + uwsgi.empty = ""; + + uwsgi.wait_read_hook = uwsgi_simple_wait_read_hook; uwsgi.wait_write_hook = uwsgi_simple_wait_write_hook; - uwsgi.buffer_write_hook = uwsgi_buffer_write_simple; + uwsgi_websockets_init(); } @@ -304,7 +304,8 @@ void uwsgi_setup_workers() { // this is a trick for avoiding too much memory areas void *ts = uwsgi_calloc_shared(sizeof(void *) * uwsgi.max_apps * uwsgi.cores); - void *buffers = uwsgi_malloc_shared(uwsgi.buffer_size * uwsgi.cores); + // add 4 bytes for uwsgi header + void *buffers = uwsgi_malloc_shared((uwsgi.buffer_size+4) * uwsgi.cores); void *hvec = uwsgi_malloc_shared(sizeof(struct iovec) * uwsgi.vec_size * uwsgi.cores); void *post_buf = NULL; if (uwsgi.post_buffering > 0) @@ -314,8 +315,8 @@ void uwsgi_setup_workers() { for (j = 0; j < uwsgi.cores; j++) { // allocate shared memory for thread states (required for some language, like python) uwsgi.workers[i].cores[j].ts = ts + ((sizeof(void *) * uwsgi.max_apps) * j); - // raw per-request buffer - uwsgi.workers[i].cores[j].buffer = buffers + (uwsgi.buffer_size * j); + // raw per-request buffer (+4 bytes for uwsgi header) + uwsgi.workers[i].cores[j].buffer = buffers + ((uwsgi.buffer_size+4) * j); // iovec for uwsgi vars uwsgi.workers[i].cores[j].hvec = hvec + ((sizeof(struct iovec) * uwsgi.vec_size) * j); if (post_buf) diff --git a/core/io.c b/core/io.c index 6ddc7a13..3bbfaba0 100644 --- a/core/io.c +++ b/core/io.c @@ -2,225 +2,6 @@ extern struct uwsgi_server uwsgi; -int uwsgi_read_whole_body_in_mem(struct wsgi_request *wsgi_req, char *buf) { - - size_t post_remains = wsgi_req->post_cl; - int ret; - ssize_t len; - char *ptr = buf; - - while (post_remains > 0) { - if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0) { - inc_harakiri(uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); - } - - ret = uwsgi_waitfd(wsgi_req->poll.fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); - if (ret < 0) { - return 0; - } - - if (!ret) { - uwsgi_log("buffering POST data to memory timed-out !!! (Content-Length: %llu received: %llu)\n", (unsigned long long) wsgi_req->post_cl, (unsigned long long) wsgi_req->post_cl - post_remains); - return 0; - } - - if (wsgi_req->socket->proto_read_body) { - len = wsgi_req->socket->proto_read_body(wsgi_req, ptr, post_remains); - } - else { - len = read(wsgi_req->poll.fd, ptr, post_remains); - } - - if (len < 0) { - uwsgi_error("read()"); - return 0; - } - - if (len == 0) { - uwsgi_log("client did not send the whole body: %s (Content-Length: %llu received: %llu)\n", strerror(errno), (unsigned long long) wsgi_req->post_cl, (unsigned long long) wsgi_req->post_cl - post_remains); - return 0; - } - - ptr += len; - post_remains -= len; - } - - return 1; - -} - -int uwsgi_read_whole_body(struct wsgi_request *wsgi_req, char *buf, size_t len) { - - size_t post_remains = wsgi_req->post_cl; - ssize_t post_chunk; - int ret, i; - int upload_progress_fd = -1; - char *upload_progress_filename = NULL; - const char *x_progress_id = "X-Progress-ID="; - char *xpi_ptr = (char *) x_progress_id; - - wsgi_req->async_post = tmpfile(); - if (!wsgi_req->async_post) { - uwsgi_error("tmpfile()"); - return 0; - } - - if (uwsgi.upload_progress) { - // first check for X-Progress-ID size - // separator + 'X-Progress-ID' + '=' + uuid - if (wsgi_req->uri_len > 51) { - for (i = 0; i < wsgi_req->uri_len; i++) { - if (wsgi_req->uri[i] == xpi_ptr[0]) { - if (xpi_ptr[0] == '=') { - if (wsgi_req->uri + i + 36 <= wsgi_req->uri + wsgi_req->uri_len) { - upload_progress_filename = wsgi_req->uri + i + 1; - } - break; - } - xpi_ptr++; - } - else { - xpi_ptr = (char *) x_progress_id; - } - } - - // now check for valid uuid (from spec available at http://en.wikipedia.org/wiki/Universally_unique_identifier) - if (upload_progress_filename) { - - uwsgi_log("upload progress uuid = %.*s\n", 36, upload_progress_filename); - if (!check_hex(upload_progress_filename, 8)) - goto cycle; - if (upload_progress_filename[8] != '-') - goto cycle; - - if (!check_hex(upload_progress_filename + 9, 4)) - goto cycle; - if (upload_progress_filename[13] != '-') - goto cycle; - - if (!check_hex(upload_progress_filename + 14, 4)) - goto cycle; - if (upload_progress_filename[18] != '-') - goto cycle; - - if (!check_hex(upload_progress_filename + 19, 4)) - goto cycle; - if (upload_progress_filename[23] != '-') - goto cycle; - - if (!check_hex(upload_progress_filename + 24, 12)) - goto cycle; - - upload_progress_filename = uwsgi_concat4n(uwsgi.upload_progress, strlen(uwsgi.upload_progress), "/", 1, upload_progress_filename, 36, ".js", 3); - // here we use O_EXCL to avoid eventual application bug in uuid generation/using - upload_progress_fd = open(upload_progress_filename, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP); - if (upload_progress_fd < 0) { - uwsgi_error_open(upload_progress_filename); - free(upload_progress_filename); - } - } - } - } - -cycle: - if (upload_progress_filename && upload_progress_fd == -1) { - uwsgi_log("invalid X-Progress-ID value: must be a UUID\n"); - } - // manage buffered data and upload progress - while (post_remains > 0) { - - if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0) { - inc_harakiri(uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); - } - - ret = uwsgi_waitfd(wsgi_req->poll.fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); - if (ret < 0) { - return 0; - } - - if (!ret) { - uwsgi_log("buffering POST data to disk timed-out !!! (Content-Length: %llu received: %llu)\n", (unsigned long long) wsgi_req->post_cl, (unsigned long long) wsgi_req->post_cl - post_remains); - goto end; - } - - if (post_remains > len) { - if (wsgi_req->socket->proto_read_body) { - post_chunk = wsgi_req->socket->proto_read_body(wsgi_req, buf, len); - } - else { - post_chunk = read(wsgi_req->poll.fd, buf, len); - } - } - else { - if (wsgi_req->socket->proto_read_body) { - post_chunk = wsgi_req->socket->proto_read_body(wsgi_req, buf, len); - } - else { - post_chunk = read(wsgi_req->poll.fd, buf, post_remains); - } - } - - if (post_chunk < 0) { - uwsgi_error("read()"); - goto end; - } - - if (post_chunk == 0) { - uwsgi_log("client did not send the whole body: %s (Content-Length: %llu received: %llu)\n", strerror(errno), (unsigned long long) wsgi_req->post_cl, (unsigned long long) wsgi_req->post_cl - post_remains); - goto end; - } - - if (fwrite(buf, post_chunk, 1, wsgi_req->async_post) != 1) { - uwsgi_error("fwrite()"); - goto end; - } - if (upload_progress_fd > -1) { - //write json data to the upload progress file - if (lseek(upload_progress_fd, 0, SEEK_SET)) { - uwsgi_error("lseek()"); - goto end; - } - - // reuse buf for json buffer - ret = snprintf(buf, len, "{ \"state\" : \"uploading\", \"received\" : %d, \"size\" : %d }\r\n", (int) (wsgi_req->post_cl - post_remains), (int) wsgi_req->post_cl); - if (ret < 0) { - uwsgi_log("unable to write JSON data in upload progress file %s\n", upload_progress_filename); - goto end; - } - if (write(upload_progress_fd, buf, ret) < 0) { - uwsgi_error("write()"); - goto end; - } - - if (fsync(upload_progress_fd)) { - uwsgi_error("fsync()"); - } - } - post_remains -= post_chunk; - } - rewind(wsgi_req->async_post); - - if (upload_progress_fd > -1) { - close(upload_progress_fd); - if (unlink(upload_progress_filename)) { - uwsgi_error("unlink()"); - } - free(upload_progress_filename); - } - - return 1; - -end: - if (upload_progress_fd > -1) { - close(upload_progress_fd); - if (unlink(upload_progress_filename)) { - uwsgi_error("unlink()"); - } - free(upload_progress_filename); - } - return 0; -} - int uwsgi_waitfd_event(int fd, int timeout, int event) { int ret; @@ -239,7 +20,7 @@ int uwsgi_waitfd_event(int fd, int timeout, int event) { ret = poll(&upoll, 1, timeout); if (ret < 0) { - uwsgi_error("poll()"); + uwsgi_error("uwsgi_waitfd_event()/poll()"); } else if (ret > 0) { if (upoll.revents & event) { diff --git a/core/logging.c b/core/logging.c index 4f333071..908e1c05 100644 --- a/core/logging.c +++ b/core/logging.c @@ -209,7 +209,6 @@ void logto(char *logfile) { int fd; -#ifdef UWSGI_UDP char *udp_port; struct sockaddr_in udp_addr; @@ -245,7 +244,6 @@ void logto(char *logfile) { } } else { -#endif if (uwsgi.log_truncate) { fd = open(logfile, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP); } @@ -263,9 +261,7 @@ void logto(char *logfile) { uwsgi_error("chmod()"); } } -#ifdef UWSGI_UDP } -#endif /* stdout */ @@ -654,11 +650,13 @@ void uwsgi_logit_simple(struct wsgi_request *wsgi_req) { } - rlen = snprintf(logpkt, 4096, "[pid: %d|app: %d|req: %d/%llu] %.*s (%.*s) {%d vars in %d bytes} [%.*s] %.*s %.*s => generated %llu bytes in %llu %s%s(%.*s %d) %d headers in %llu bytes (%d switches on core %d)\n", (int) uwsgi.mypid, wsgi_req->app_id, app_req, (unsigned long long) uwsgi.workers[0].requests, wsgi_req->remote_addr_len, wsgi_req->remote_addr, wsgi_req->remote_user_len, wsgi_req->remote_user, wsgi_req->var_cnt, wsgi_req->uh.pktsize, 24, time_request, wsgi_req->method_len, wsgi_req->method, wsgi_req->uri_len, wsgi_req->uri, (unsigned long long) wsgi_req->response_size, (unsigned long long) rt, tsize, via, wsgi_req->protocol_len, wsgi_req->protocol, wsgi_req->status, wsgi_req->header_cnt, (unsigned long long) wsgi_req->headers_size, wsgi_req->switches, wsgi_req->async_id); + rlen = snprintf(logpkt, 4096, "[pid: %d|app: %d|req: %d/%llu] %.*s (%.*s) {%d vars in %d bytes} [%.*s] %.*s %.*s => generated %llu bytes in %llu %s%s(%.*s %d) %d headers in %llu bytes (%d switches on core %d)\n", (int) uwsgi.mypid, wsgi_req->app_id, app_req, (unsigned long long) uwsgi.workers[0].requests, wsgi_req->remote_addr_len, wsgi_req->remote_addr, wsgi_req->remote_user_len, wsgi_req->remote_user, wsgi_req->var_cnt, wsgi_req->uh->pktsize, + 24, time_request, wsgi_req->method_len, wsgi_req->method, wsgi_req->uri_len, wsgi_req->uri, (unsigned long long) wsgi_req->response_size, (unsigned long long) rt, tsize, via, wsgi_req->protocol_len, wsgi_req->protocol, wsgi_req->status, wsgi_req->header_cnt, (unsigned long long) wsgi_req->headers_size, wsgi_req->switches, wsgi_req->async_id); // not enough space for logging the request, just log a (safe) minimal message if (rlen > 4096) { - rlen = snprintf(logpkt, 4096, "[pid: %d|app: %d|req: %d/%llu] 0.0.0.0 () {%d vars in %d bytes} [%.*s] - - => generated %llu bytes in %llu %s%s(- %d) %d headers in %llu bytes (%d switches on core %d)\n", (int) uwsgi.mypid, wsgi_req->app_id, app_req, (unsigned long long) uwsgi.workers[0].requests, wsgi_req->var_cnt, wsgi_req->uh.pktsize, 24, time_request, (unsigned long long) wsgi_req->response_size, (unsigned long long) rt, tsize, via, wsgi_req->status, wsgi_req->header_cnt, (unsigned long long) wsgi_req->headers_size, wsgi_req->switches, wsgi_req->async_id); + rlen = snprintf(logpkt, 4096, "[pid: %d|app: %d|req: %d/%llu] 0.0.0.0 () {%d vars in %d bytes} [%.*s] - - => generated %llu bytes in %llu %s%s(- %d) %d headers in %llu bytes (%d switches on core %d)\n", (int) uwsgi.mypid, wsgi_req->app_id, app_req, (unsigned long long) uwsgi.workers[0].requests, wsgi_req->var_cnt, wsgi_req->uh->pktsize, + 24, time_request, (unsigned long long) wsgi_req->response_size, (unsigned long long) rt, tsize, via, wsgi_req->status, wsgi_req->header_cnt, (unsigned long long) wsgi_req->headers_size, wsgi_req->switches, wsgi_req->async_id); // argh, last resort, truncate it if (rlen > 4096) { rlen = 4096; diff --git a/core/loop.c b/core/loop.c index 0b7979d1..2848d98d 100644 --- a/core/loop.c +++ b/core/loop.c @@ -64,12 +64,10 @@ void simple_loop() { void uwsgi_loop_cores_run(void *(*func) (void *)) { int i; -#ifdef UWSGI_THREADING for (i = 1; i < uwsgi.threads; i++) { long j = i; pthread_create(&uwsgi.workers[uwsgi.mywid].cores[i].thread_id, &uwsgi.threads_attr, func, (void *) j); } -#endif long y = 0; func((void *) y); } @@ -120,12 +118,9 @@ void *simple_loop_run(void *arg1) { struct wsgi_request *wsgi_req = &uwsgi.workers[uwsgi.mywid].cores[core_id].req; -#ifdef UWSGI_THREADING if (uwsgi.threads > 1) { uwsgi_setup_thread_req(core_id, wsgi_req); } -#endif - // initialize the main event queue to monitor sockets int main_queue = event_queue_init(); @@ -146,7 +141,7 @@ void *simple_loop_run(void *arg1) { continue; } - if (wsgi_req_recv(wsgi_req)) { + if (wsgi_req_recv(main_queue, wsgi_req)) { uwsgi_destroy_request(wsgi_req); continue; } diff --git a/core/master.c b/core/master.c index fe758c6a..7972ebf1 100644 --- a/core/master.c +++ b/core/master.c @@ -31,7 +31,6 @@ void uwsgi_unblock_signal(int signum) { } } -#ifdef UWSGI_SNMP void uwsgi_master_manage_snmp(int snmp_fd) { struct sockaddr_in udp_client; socklen_t udp_len = sizeof(udp_client); @@ -45,9 +44,6 @@ void uwsgi_master_manage_snmp(int snmp_fd) { } } -#endif - -#ifdef UWSGI_UDP void uwsgi_master_manage_udp(int udp_fd) { struct sockaddr_in udp_client; char udp_client_addr[16]; @@ -65,11 +61,9 @@ void uwsgi_master_manage_udp(int udp_fd) { if (inet_ntop(AF_INET, &udp_client.sin_addr.s_addr, udp_client_addr, 16)) { if (uwsgi.wsgi_req->buffer[0] == UWSGI_MODIFIER_MULTICAST_ANNOUNCE) { } -#ifdef UWSGI_SNMP else if (uwsgi.wsgi_req->buffer[0] == 0x30 && uwsgi.snmp) { manage_snmp(udp_fd, (uint8_t *) uwsgi.wsgi_req->buffer, rlen, &udp_client); } -#endif else { // loop the various udp manager until one returns true @@ -95,7 +89,6 @@ void uwsgi_master_manage_udp(int udp_fd) { } } -#endif void uwsgi_master_manage_emperor() { char byte; @@ -392,21 +385,10 @@ int master_loop(char **argv, char **environ) { uint64_t last_request_count = 0; pthread_t logger_thread; - pthread_t channels_loop; -#ifdef UWSGI_UDP int udp_fd = -1; -#ifdef UWSGI_MULTICAST - char *cluster_opt_buf = NULL; - size_t cluster_opt_size = 4; -#endif -#endif - - - -#ifdef UWSGI_SNMP int snmp_fd = -1; -#endif + int i = 0; int rlen; @@ -455,11 +437,9 @@ int master_loop(char **argv, char **environ) { #endif event_queue_add_fd_read(uwsgi.master_queue, uwsgi.shared->worker_signal_pipe[0]); -#ifdef UWSGI_SPOOLER if (uwsgi.spoolers) { event_queue_add_fd_read(uwsgi.master_queue, uwsgi.shared->spooler_signal_pipe[0]); } -#endif if (uwsgi.mules_cnt > 0) { event_queue_add_fd_read(uwsgi.master_queue, uwsgi.shared->mule_signal_pipe[0]); @@ -501,18 +481,6 @@ int master_loop(char **argv, char **environ) { uwsgi_cache_start_sweepers(); uwsgi_cache_start_sync_servers(); - if (uwsgi.channels) { - if (pthread_create(&channels_loop, NULL, uwsgi_channels_loop, NULL)) { - uwsgi_error("pthread_create()"); - uwsgi_log("unable to run the channels dispatcher thread !!!\n"); - } - else { - uwsgi_log("channels dispatcher thread enabled\n"); - } - - } - - uwsgi.wsgi_req->buffer = uwsgi.workers[0].cores[0].buffer; if (uwsgi.has_emperor) { @@ -550,11 +518,10 @@ int master_loop(char **argv, char **environ) { } } -#ifdef UWSGI_UDP if (uwsgi.udp_socket) { udp_fd = bind_to_udp(uwsgi.udp_socket, 0, 0); if (udp_fd < 0) { - uwsgi_log("unable to bind to udp socket. SNMP and cluster management services will be disabled.\n"); + uwsgi_log("unable to bind to udp socket. SNMP services will be disabled.\n"); } else { uwsgi_log("UDP server enabled.\n"); @@ -562,17 +529,7 @@ int master_loop(char **argv, char **environ) { } } -#ifdef UWSGI_MULTICAST - if (uwsgi.cluster) { - event_queue_add_fd_read(uwsgi.master_queue, uwsgi.cluster_fd); - cluster_opt_buf = uwsgi_setup_clusterbuf(&cluster_opt_size); - } -#endif -#endif - -#ifdef UWSGI_SNMP snmp_fd = uwsgi_setup_snmp(); -#endif if (uwsgi.cheap) { uwsgi_add_sockets_to_queue(uwsgi.master_queue, -1); @@ -886,35 +843,17 @@ int master_loop(char **argv, char **environ) { if (found) continue; } -#ifdef UWSGI_SNMP + if (uwsgi.snmp_addr && interesting_fd == snmp_fd) { uwsgi_master_manage_snmp(snmp_fd); goto health_cycle; } -#endif -#ifdef UWSGI_UDP if (uwsgi.udp_socket && interesting_fd == udp_fd) { uwsgi_master_manage_udp(udp_fd); goto health_cycle; } -#ifdef UWSGI_MULTICAST - if (interesting_fd == uwsgi.cluster_fd) { - - if (uwsgi_get_dgram(uwsgi.cluster_fd, &uwsgi.workers[0].cores[0].req)) { - goto health_cycle; - } - - manage_cluster_message(cluster_opt_buf, cluster_opt_size); - - goto health_cycle; - } -#endif - -#endif - - int next_iteration = 0; uwsgi_lock(uwsgi.fmon_table_lock); @@ -972,7 +911,6 @@ int master_loop(char **argv, char **environ) { goto health_cycle; } -#ifdef UWSGI_SPOOLER // check for spooler signal if (uwsgi.spoolers) { if (interesting_fd == uwsgi.shared->spooler_signal_pipe[0]) { @@ -994,7 +932,6 @@ int master_loop(char **argv, char **environ) { } } -#endif // check for mules signal if (uwsgi.mules_cnt > 0) { @@ -1182,7 +1119,6 @@ health_cycle: } } } -#ifdef UWSGI_SPOOLER struct uwsgi_spooler *uspool = uwsgi.spoolers; while (uspool) { if (uspool->harakiri > 0 && uspool->harakiri < (time_t) uwsgi.current_time) { @@ -1192,7 +1128,6 @@ health_cycle: } uspool = uspool->next; } -#endif #ifdef __linux__ #ifdef MADV_MERGEABLE @@ -1202,22 +1137,11 @@ health_cycle: #endif #endif -#ifdef UWSGI_UDP - // check for cluster nodes - master_check_cluster_nodes(); - - // reannounce myself every 10 cycles - if (uwsgi.cluster && uwsgi.cluster_fd >= 0 && !uwsgi.cluster_nodes && (uwsgi.master_cycles % 10) == 0) { - uwsgi_cluster_add_me(); - } - // resubscribe every 10 cycles by default if (( (uwsgi.subscriptions || uwsgi.subscriptions2) && ((uwsgi.master_cycles % uwsgi.subscribe_freq) == 0 || uwsgi.master_cycles == 1)) && !uwsgi.to_heaven && !uwsgi.to_hell && !uwsgi.workers[0].suspended) { uwsgi_subscribe_all(0, 0); } -#endif - uwsgi_cache_sync_all(); if (uwsgi.queue_store && uwsgi.queue_filesize && uwsgi.queue_store_sync && ((uwsgi.master_cycles % uwsgi.queue_store_sync) == 0)) { @@ -1251,7 +1175,6 @@ health_cycle: // reload gateways and daemons only on normal workflow (+outworld status) if (!uwsgi.to_heaven && !uwsgi.to_hell) { -#ifdef UWSGI_SPOOLER /* reload the spooler */ struct uwsgi_spooler *uspool = uwsgi.spoolers; pid_found = 0; @@ -1268,7 +1191,6 @@ health_cycle: if (pid_found) continue; -#endif if (uwsgi.emperor_pid >= 0) { uwsgi_log_verbose("!!! Emperor died !!!\n"); @@ -1325,7 +1247,6 @@ health_cycle: uwsgi.mywid = find_worker_id(diedpid); if (uwsgi.mywid <= 0) { // check spooler, mules, gateways and daemons -#ifdef UWSGI_SPOOLER struct uwsgi_spooler *uspool = uwsgi.spoolers; while (uspool) { if (uspool->pid > 0 && diedpid == uspool->pid) { @@ -1334,7 +1255,6 @@ health_cycle: } uspool = uspool->next; } -#endif for (i = 0; i < uwsgi.mules_cnt; i++) { if (uwsgi.mules[i].pid == diedpid) { diff --git a/core/master_utils.c b/core/master_utils.c index e4c44253..a4a41586 100644 --- a/core/master_utils.c +++ b/core/master_utils.c @@ -375,35 +375,6 @@ void uwsgi_reload(char **argv) { } -void master_check_cluster_nodes() { - - int i; - - for (i = 0; i < MAX_CLUSTER_NODES; i++) { - struct uwsgi_cluster_node *ucn = &uwsgi.shared->nodes[i]; - - if (ucn->name[0] != 0 && ucn->type == CLUSTER_NODE_STATIC && ucn->status == UWSGI_NODE_FAILED) { - // should i retry ? - if (uwsgi.master_cycles % ucn->errors == 0) { - if (!uwsgi_ping_node(i, uwsgi.wsgi_req)) { - ucn->status = UWSGI_NODE_OK; - uwsgi_log("re-enabled cluster node %d/%s\n", i, ucn->name); - } - else { - ucn->errors++; - } - } - } - else if (ucn->name[0] != 0 && ucn->type == CLUSTER_NODE_DYNAMIC) { - // if the last_seen attr is higher than 30 secs ago, mark the node as dead - if ((uwsgi.current_time - ucn->last_seen) > 30) { - uwsgi_log_verbose("no presence announce in the last 30 seconds by node %s, i assume it is dead.\n", ucn->name); - ucn->name[0] = 0; - } - } - } -} - void uwsgi_fixup_fds(int wid, int muleid, struct uwsgi_gateway *ug) { int i; @@ -445,14 +416,13 @@ void uwsgi_fixup_fds(int wid, int muleid, struct uwsgi_gateway *ug) { close(uwsgi.workers[i].signal_pipe[1]); } } -#ifdef UWSGI_SPOOLER + if (uwsgi.i_am_a_spooler && uwsgi.i_am_a_spooler->pid != getpid()) { if (uwsgi.shared->spooler_signal_pipe[0] != -1) close(uwsgi.shared->spooler_signal_pipe[0]); if (uwsgi.shared->spooler_signal_pipe[1] != -1) close(uwsgi.shared->spooler_signal_pipe[1]); } -#endif if (uwsgi.shared->mule_signal_pipe[0] != -1) close(uwsgi.shared->mule_signal_pipe[0]); @@ -520,9 +490,6 @@ int uwsgi_respawn_worker(int wid) { int i; - // reset channels subscriptions - uwsgi_channels_reset_worker_subscriptions(wid); - if (uwsgi.threaded_logger) { pthread_mutex_lock(&uwsgi.threaded_logger_lock); } @@ -1163,7 +1130,6 @@ struct uwsgi_stats *uwsgi_master_generate_stats() { if (uwsgi_stats_list_close(us)) goto end; -#ifdef UWSGI_SPOOLER struct uwsgi_spooler *uspool = uwsgi.spoolers; if (uspool) { if (uwsgi_stats_comma(us)) @@ -1202,7 +1168,6 @@ struct uwsgi_stats *uwsgi_master_generate_stats() { if (uwsgi_stats_list_close(us)) goto end; } -#endif #ifdef UWSGI_SSL struct uwsgi_legion *legion = NULL; diff --git a/core/offload.c b/core/offload.c index ff2a84a0..3494f46e 100644 --- a/core/offload.c +++ b/core/offload.c @@ -21,7 +21,7 @@ static void uwsgi_offload_setup(struct uwsgi_offload_request *uor, struct wsgi_r wsgi_req->fd_closed = 1; memset(uor, 0, sizeof(struct uwsgi_offload_request)); - uor->s = wsgi_req->poll.fd; + uor->s = wsgi_req->fd; uor->func = func; // put socket in non-blocking mode uwsgi_socket_nb(uor->s); diff --git a/core/progress.c b/core/progress.c new file mode 100644 index 00000000..36518243 --- /dev/null +++ b/core/progress.c @@ -0,0 +1,107 @@ +#include + +/* + + upload progress facilities + +*/ + +extern struct uwsgi_server uwsgi; + +char *uwsgi_upload_progress_create(struct wsgi_request *wsgi_req, int *fd) { + const char *x_progress_id = "X-Progress-ID="; + char *xpi_ptr = (char *) x_progress_id; + uint16_t i; + char *upload_progress_filename = NULL; + + if (wsgi_req->uri_len <= 51) + return NULL; + + + for (i = 0; i < wsgi_req->uri_len; i++) { + if (wsgi_req->uri[i] == xpi_ptr[0]) { + if (xpi_ptr[0] == '=') { + if (wsgi_req->uri + i + 36 <= wsgi_req->uri + wsgi_req->uri_len) { + upload_progress_filename = wsgi_req->uri + i + 1; + } + break; + } + xpi_ptr++; + } + else { + xpi_ptr = (char *) x_progress_id; + } + } + + // now check for valid uuid (from spec available at http://en.wikipedia.org/wiki/Universally_unique_identifier) + if (!upload_progress_filename) + return NULL; + + uwsgi_log("upload progress uuid = %.*s\n", 36, upload_progress_filename); + if (!check_hex(upload_progress_filename, 8)) + return NULL; + if (upload_progress_filename[8] != '-') + return NULL; + + if (!check_hex(upload_progress_filename + 9, 4)) + return NULL; + if (upload_progress_filename[13] != '-') + return NULL; + + if (!check_hex(upload_progress_filename + 14, 4)) + return NULL; + if (upload_progress_filename[18] != '-') + return NULL; + + if (!check_hex(upload_progress_filename + 19, 4)) + return NULL; + if (upload_progress_filename[23] != '-') + return NULL; + + if (!check_hex(upload_progress_filename + 24, 12)) + return NULL; + + upload_progress_filename = uwsgi_concat4n(uwsgi.upload_progress, strlen(uwsgi.upload_progress), "/", 1, upload_progress_filename, 36, ".js", 3); + // here we use O_EXCL to avoid eventual application bug in uuid generation/using + *fd = open(upload_progress_filename, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP); + if (*fd < 0) { + uwsgi_error_open(upload_progress_filename); + free(upload_progress_filename); + return NULL; + } + + return upload_progress_filename; +} + +int uwsgi_upload_progress_update(struct wsgi_request *wsgi_req, int fd, size_t remains) { + char buf[4096]; + + int ret = snprintf(buf, 4096, "{ \"state\" : \"uploading\", \"received\" : %llu, \"size\" : %llu }\r\n", (unsigned long long) (wsgi_req->post_cl - remains), (unsigned long long) wsgi_req->post_cl); + if (ret < 0) { + return -1; + } + + if (lseek(fd, 0, SEEK_SET)) { + uwsgi_error("uwsgi_upload_progress_update()/lseek()"); + return -1; + } + + if (write(fd, buf, ret) != ret) { + uwsgi_error("uwsgi_upload_progress_update()/write()"); + return -1; + } + + if (fsync(fd)) { + uwsgi_error("uwsgi_upload_progress_update()/fsync()"); + return -1; + } + return 0; +} + +void uwsgi_upload_progress_destroy(char *filename, int fd) { + close(fd); + if (unlink(filename)) { + uwsgi_error("uwsgi_upload_progress_destroy()/unlink()"); + } + free(filename); +} diff --git a/core/protocol.c b/core/protocol.c index 3965adb7..0f00af18 100644 --- a/core/protocol.c +++ b/core/protocol.c @@ -287,7 +287,7 @@ int uwsgi_read_response(int fd, struct uwsgi_header *uh, int timeout, char **buf return ret; } -int uwsgi_parse_packet(struct wsgi_request *wsgi_req, int timeout) { +int uwsgi_receive_request(int queue, struct wsgi_request *wsgi_req, int timeout) { int rlen; int status = UWSGI_AGAIN; @@ -295,7 +295,7 @@ int uwsgi_parse_packet(struct wsgi_request *wsgi_req, int timeout) { timeout = 1; while (status == UWSGI_AGAIN) { - rlen = poll(&wsgi_req->poll, 1, timeout * 1000); + //rlen = poll(&wsgi_req->poll, 1, timeout * 1000); if (rlen < 0) { uwsgi_error("poll()"); exit(1); @@ -631,12 +631,11 @@ static int uwsgi_proto_check_14(struct wsgi_request *wsgi_req, char *key, char * if (!uwsgi_proto_key("UWSGI_POSTFILE", 14)) { char *postfile = uwsgi_concat2n(buf, len, "", 0); - wsgi_req->async_post = fopen(postfile, "r"); - if (!wsgi_req->async_post) { + wsgi_req->post_file = fopen(postfile, "r"); + if (!wsgi_req->post_file) { uwsgi_error_open(postfile); } free(postfile); - wsgi_req->body_as_file = 1; return 0; } @@ -697,6 +696,11 @@ static int uwsgi_proto_check_20(struct wsgi_request *wsgi_req, char *key, char * return 0; } + if (!uwsgi_proto_key("HTTP_X_FORWARDED_SSL", 20)) { + wsgi_req->https = buf; + wsgi_req->https_len = len; + } + if (!uwsgi_proto_key("HTTP_ACCEPT_ENCODING", 20)) { wsgi_req->encoding = buf; wsgi_req->encoding_len = len; @@ -745,7 +749,7 @@ int uwsgi_parse_vars(struct wsgi_request *wsgi_req) { struct uwsgi_dyn_dict *udd; ptrbuf = buffer; - bufferend = ptrbuf + wsgi_req->uh.pktsize; + bufferend = ptrbuf + wsgi_req->uh->pktsize; int i; /* set an HTTP 500 status as default */ @@ -843,17 +847,17 @@ int uwsgi_parse_vars(struct wsgi_request *wsgi_req) { next: - if (uwsgi.post_buffering > 0 && !wsgi_req->body_as_file && !wsgi_req->async_post) { + // manage post buffering (if needed) + if (uwsgi.post_buffering > 0) { // read to disk if post_cl > post_buffering (it will eventually do upload progress...) - if (wsgi_req->post_cl >= (size_t) uwsgi.post_buffering) { - if (!uwsgi_read_whole_body(wsgi_req, wsgi_req->post_buffering_buf, uwsgi.post_buffering_bufsize)) { + if (wsgi_req->post_cl >= uwsgi.post_buffering) { + if (uwsgi_postbuffer_do_in_disk(wsgi_req)) { return -1; } - wsgi_req->body_as_file = 1; } // on tiny post use memory else { - if (!uwsgi_read_whole_body_in_mem(wsgi_req, wsgi_req->post_buffering_buf)) { + if (uwsgi_postbuffer_do_in_mem(wsgi_req)) { return -1; } } @@ -951,19 +955,15 @@ next: while (udd) { // need to build the path ? if (udd->value == NULL) { -#ifdef UWSGI_THREADING if (uwsgi.threads > 1) pthread_mutex_lock(&uwsgi.lock_static); -#endif udd->value = uwsgi_malloc(PATH_MAX + 1); if (!realpath(udd->key, udd->value)) { free(udd->value); udd->value = NULL; } -#ifdef UWSGI_THREADING if (uwsgi.threads > 1) pthread_mutex_unlock(&uwsgi.lock_static); -#endif if (!udd->value) goto nextcs; udd->vallen = strlen(udd->value); @@ -983,20 +983,16 @@ nextcs: uwsgi_log("checking for %.*s <-> %.*s %.*s\n", (int)wsgi_req->path_info_len, wsgi_req->path_info, (int)udd->keylen, udd->key, (int) udd->vallen, udd->value); #endif if (udd->status == 0) { -#ifdef UWSGI_THREADING if (uwsgi.threads > 1) pthread_mutex_lock(&uwsgi.lock_static); -#endif char *real_docroot = uwsgi_malloc(PATH_MAX + 1); if (!realpath(udd->value, real_docroot)) { free(real_docroot); real_docroot = NULL; udd->value = NULL; } -#ifdef UWSGI_THREADING if (uwsgi.threads > 1) pthread_mutex_unlock(&uwsgi.lock_static); -#endif if (!real_docroot) goto nextsm; udd->value = real_docroot; @@ -1020,20 +1016,16 @@ nextsm: uwsgi_log("checking for %.*s <-> %.*s\n", wsgi_req->path_info_len, wsgi_req->path_info, udd->keylen, udd->key); #endif if (udd->status == 0) { -#ifdef UWSGI_THREADING if (uwsgi.threads > 1) pthread_mutex_lock(&uwsgi.lock_static); -#endif char *real_docroot = uwsgi_malloc(PATH_MAX + 1); if (!realpath(udd->value, real_docroot)) { free(real_docroot); real_docroot = NULL; udd->value = NULL; } -#ifdef UWSGI_THREADING if (uwsgi.threads > 1) pthread_mutex_unlock(&uwsgi.lock_static); -#endif if (!real_docroot) goto nextsm2; udd->value = real_docroot; @@ -1067,52 +1059,6 @@ nextsm2: return 0; } -int uwsgi_ping_node(int node, struct wsgi_request *wsgi_req) { - - - struct pollfd uwsgi_poll; - - struct uwsgi_cluster_node *ucn = &uwsgi.shared->nodes[node]; - - if (ucn->name[0] == 0) { - return 0; - } - - if (ucn->status == UWSGI_NODE_OK) { - return 0; - } - -#if defined(__linux__) && defined(SOCK_NONBLOCK) && !defined(OBSOLETE_LINUX_KERNEL) - uwsgi_poll.fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0); -#else - uwsgi_poll.fd = socket(AF_INET, SOCK_STREAM, 0); -#endif - if (uwsgi_poll.fd < 0) { - uwsgi_error("socket()"); - return -1; - } - - if (timed_connect(&uwsgi_poll, (const struct sockaddr *) &ucn->ucn_addr, sizeof(struct sockaddr_in), uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], 0)) { - close(uwsgi_poll.fd); - return -1; - } - - wsgi_req->uh.modifier1 = UWSGI_MODIFIER_PING; - wsgi_req->uh.pktsize = 0; - wsgi_req->uh.modifier2 = 0; - if (write(uwsgi_poll.fd, wsgi_req, 4) != 4) { - uwsgi_error("write()"); - return -1; - } - - uwsgi_poll.events = POLLIN; - if (!uwsgi_parse_packet(wsgi_req, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT])) { - return -1; - } - - return 0; -} - ssize_t uwsgi_send_empty_pkt(int fd, char *socket_name, uint8_t modifier1, uint8_t modifier2) { struct uwsgi_header uh; @@ -1183,15 +1129,15 @@ int uwsgi_get_dgram(int fd, struct wsgi_request *wsgi_req) { uh = (struct uwsgi_header *) buffer; - wsgi_req->uh.modifier1 = uh->modifier1; + wsgi_req->uh->modifier1 = uh->modifier1; /* big endian ? */ #ifdef __BIG_ENDIAN__ uh->pktsize = uwsgi_swap16(uh->pktsize); #endif - wsgi_req->uh.pktsize = uh->pktsize; - wsgi_req->uh.modifier2 = uh->modifier2; + wsgi_req->uh->pktsize = uh->pktsize; + wsgi_req->uh->modifier2 = uh->modifier2; - if (wsgi_req->uh.pktsize > uwsgi.buffer_size) { + if (wsgi_req->uh->pktsize > uwsgi.buffer_size) { uwsgi_log("invalid uwsgi packet size, probably you need to increase buffer size\n"); return -1; } @@ -1199,7 +1145,7 @@ int uwsgi_get_dgram(int fd, struct wsgi_request *wsgi_req) { wsgi_req->buffer = buffer + 4; #ifdef UWSGI_DEBUG - uwsgi_log("request received %d %d\n", wsgi_req->uh.modifier1, wsgi_req->uh.modifier2); + uwsgi_log("request received %d %d\n", wsgi_req->uh->modifier1, wsgi_req->uh->modifier2); #endif return 0; @@ -1468,96 +1414,9 @@ uint16_t fcgi_get_record(int fd, char *buf) { } -char *uwsgi_simple_message_string(char *socket_name, uint8_t modifier1, uint8_t modifier2, char *what, uint16_t what_len, char *buffer, uint16_t * response_len, int timeout) { - - struct wsgi_request msg_req; - - int fd = uwsgi_connect(socket_name, timeout, 0); - - if (fd < 0) { - if (response_len) - *response_len = 0; - return NULL; - } - - if (uwsgi_send_message(fd, modifier1, modifier2, what, what_len, -1, 0, timeout) <= 0) { - close(fd); - if (response_len) - *response_len = 0; - return NULL; - } - - memset(&msg_req, 0, sizeof(struct wsgi_request)); - msg_req.poll.fd = fd; - msg_req.poll.events = POLLIN; - msg_req.buffer = buffer; - - if (buffer) { - if (!uwsgi_parse_packet(&msg_req, timeout)) { - close(fd); - if (response_len) - *response_len = 0; - return NULL; - } - - if (response_len) - *response_len = msg_req.uh.pktsize; - } - - close(fd); - return buffer; -} - -int uwsgi_simple_send_string2(char *socket_name, uint8_t modifier1, uint8_t modifier2, char *item1, uint16_t item1_len, char *item2, uint16_t item2_len, int timeout) { - - struct uwsgi_header uh; - char strsize1[2], strsize2[2]; - - struct iovec iov[5]; - - int fd = uwsgi_connect(socket_name, timeout, 0); - - if (fd < 0) { - return -1; - } - - uh.modifier1 = modifier1; - uh.pktsize = 2 + item1_len + 2 + item2_len; - uh.modifier2 = modifier2; - - strsize1[0] = (uint8_t) (item1_len & 0xff); - strsize1[1] = (uint8_t) ((item1_len >> 8) & 0xff); - - strsize2[0] = (uint8_t) (item2_len & 0xff); - strsize2[1] = (uint8_t) ((item2_len >> 8) & 0xff); - - iov[0].iov_base = &uh; - iov[0].iov_len = 4; - - iov[1].iov_base = strsize1; - iov[1].iov_len = 2; - - iov[2].iov_base = item1; - iov[2].iov_len = item1_len; - - iov[3].iov_base = strsize2; - iov[3].iov_len = 2; - - iov[4].iov_base = item2; - iov[4].iov_len = item2_len; - - if (writev(fd, iov, 5) < 0) { - uwsgi_error("writev()"); - } - - close(fd); - - return 0; -} - char *uwsgi_req_append(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, char *val, uint16_t vallen) { - if (wsgi_req->uh.pktsize + (2 + keylen + 2 + vallen) > uwsgi.buffer_size) { + if ((wsgi_req->uh->pktsize + (2 + keylen + 2 + vallen)) > uwsgi.buffer_size) { uwsgi_log("not enough buffer space to add %.*s variable, consider increasing it with the --buffer-size option\n", keylen, key); return NULL; } @@ -1567,7 +1426,7 @@ char *uwsgi_req_append(struct wsgi_request *wsgi_req, char *key, uint16_t keylen return NULL; } - char *ptr = wsgi_req->buffer + wsgi_req->uh.pktsize; + char *ptr = wsgi_req->buffer + wsgi_req->uh->pktsize; *ptr++ = (uint8_t) (keylen & 0xff); *ptr++ = (uint8_t) ((keylen >> 8) & 0xff); @@ -1588,7 +1447,7 @@ char *uwsgi_req_append(struct wsgi_request *wsgi_req, char *key, uint16_t keylen wsgi_req->hvec[wsgi_req->var_cnt].iov_len = vallen; wsgi_req->var_cnt++; - wsgi_req->uh.pktsize += (2 + keylen + 2 + vallen); + wsgi_req->uh->pktsize += (2 + keylen + 2 + vallen); return ptr; } diff --git a/core/reader.c b/core/reader.c new file mode 100644 index 00000000..ba01e639 --- /dev/null +++ b/core/reader.c @@ -0,0 +1,522 @@ +#include + +extern struct uwsgi_server uwsgi; + +int uwsgi_simple_wait_read_hook(int fd, int timeout) { + return uwsgi_waitfd(fd, timeout); +} + +/* + seek()/rewind() language-independent implementations. +*/ + +void uwsgi_request_body_seek(struct wsgi_request *wsgi_req, off_t pos) { + if (wsgi_req->post_file) { + if (fseek(wsgi_req->post_file, pos, SEEK_SET)) { + uwsgi_error("uwsgi_request_body_seek()/fseek()"); + } + return; + } + + if (uwsgi.post_buffering) { + wsgi_req->post_pos += pos; + } +} + +/* + + read() and readline() language-independent implementations. + +*/ + +#define uwsgi_read_error(x) uwsgi_log("[uwsgi-body-read] Error reading %llu bytes. Content-Length: %llu consumed: %llu available: %llu message: %s\n",\ + (unsigned long long) x,\ + (unsigned long long) wsgi_req->post_cl, (unsigned long long) wsgi_req->post_pos, (unsigned long long) wsgi_req->post_cl-wsgi_req->post_pos,\ + strerror(errno)); + +#define uwsgi_read_timeout(x) uwsgi_log("[uwsgi-body-read] Timeout reading %llu bytes. Content-Length: %llu consumed: %llu available: %llu\n",\ + (unsigned long long) x,\ + (unsigned long long) wsgi_req->post_cl, (unsigned long long) wsgi_req->post_pos, (unsigned long long) wsgi_req->post_cl-wsgi_req->post_pos); + +static int consume_body_for_readline(struct wsgi_request *wsgi_req) { + + size_t remains = UMIN(uwsgi.buffer_size, wsgi_req->post_cl - wsgi_req->post_pos); + + int ret; + + // allocate more memory if needed + if (wsgi_req->post_readline_size - wsgi_req->post_readline_watermark == 0) { + memcpy(wsgi_req->post_readline_buf, wsgi_req->post_readline_buf + wsgi_req->post_readline_pos, wsgi_req->post_readline_watermark - wsgi_req->post_readline_pos); + wsgi_req->post_readline_watermark -= wsgi_req->post_readline_pos; + wsgi_req->post_readline_pos = 0; + // still something to use ? + if (wsgi_req->post_readline_size - wsgi_req->post_readline_watermark < remains) { + char *tmp_buf = realloc(wsgi_req->post_readline_buf, wsgi_req->post_readline_size + remains); + if (!tmp_buf) { + uwsgi_error("consume_body_for_readline()/realloc()"); + return -1; + } + wsgi_req->post_readline_buf = tmp_buf; + wsgi_req->post_readline_size += remains; + // INFORM THE USER HIS readline() USAGE IS FOOLISH + if (!wsgi_req->post_warning && wsgi_req->post_readline_size > (uwsgi.body_read_warning * 1024*1024)) { + uwsgi_log("[uwsgi-warning] you are using readline() on request body allocating over than %llu MB, that is really bad and can be avoided...\n", (unsigned long long) (wsgi_req->post_readline_size/(1024*1024))); + wsgi_req->post_warning = 1; + } + } + } + + + // read from a file + if (wsgi_req->post_file) { + size_t ret = fread(wsgi_req->post_readline_buf + wsgi_req->post_readline_watermark, wsgi_req->post_readline_size - wsgi_req->post_readline_watermark, 1, wsgi_req->post_file); + if (ret == 0) { + uwsgi_error("consume_body_for_readline()/fread()"); + return -1; + } + wsgi_req->post_pos += wsgi_req->post_readline_size - wsgi_req->post_readline_watermark; + wsgi_req->post_readline_watermark += wsgi_req->post_readline_size - wsgi_req->post_readline_watermark; + return 0; + } + + + // read from post_buffering memory + if (uwsgi.post_buffering) { + wsgi_req->post_pos += wsgi_req->post_readline_size - wsgi_req->post_readline_watermark; + memcpy(wsgi_req->post_readline_buf + wsgi_req->post_readline_watermark, wsgi_req->post_buffering_buf + wsgi_req->post_pos, wsgi_req->post_readline_size - wsgi_req->post_readline_watermark); + wsgi_req->post_readline_watermark += wsgi_req->post_readline_size - wsgi_req->post_readline_watermark; + return 0; + } + + // read from socket + ssize_t len = wsgi_req->socket->proto_read_body(wsgi_req, wsgi_req->post_readline_buf + wsgi_req->post_readline_watermark , wsgi_req->post_readline_size - wsgi_req->post_readline_watermark); + if (len > 0) { + wsgi_req->post_pos += len; + wsgi_req->post_readline_watermark += len; + return 0; + } + if (len == 0) { + uwsgi_read_error(wsgi_req->post_readline_size - wsgi_req->post_readline_watermark); + return -1; + } + if (len < 0) { + if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) { + goto wait; + } + uwsgi_read_error(wsgi_req->post_readline_size - wsgi_req->post_readline_watermark); + return -1; + } +wait: + ret = uwsgi_wait_read_req(wsgi_req); + if (ret > 0) { + len = wsgi_req->socket->proto_read_body(wsgi_req, wsgi_req->post_readline_buf + wsgi_req->post_readline_watermark , wsgi_req->post_readline_size - wsgi_req->post_readline_watermark); + if (len > 0) { + wsgi_req->post_pos += len; + wsgi_req->post_readline_watermark += len; + return 0; + } + uwsgi_read_error(wsgi_req->post_readline_size - wsgi_req->post_readline_watermark); + return -1; + } + // 0 means timeout + else if (ret == 0) { + uwsgi_read_timeout(wsgi_req->post_readline_size - wsgi_req->post_readline_watermark); + return -1; + } + uwsgi_read_error(wsgi_req->post_readline_size - wsgi_req->post_readline_watermark); + return -1; +} + +// TODO take hint into account +// readline_buf is allocated when needed and freed at the end of the request +char *uwsgi_request_body_readline(struct wsgi_request *wsgi_req, ssize_t hint, ssize_t *rlen) { + + // return 0 if no post_cl or pos >= post_cl and no residual data + if ((!wsgi_req->post_cl || wsgi_req->post_pos >= wsgi_req->post_cl ) && !wsgi_req->post_readline_pos) { + return uwsgi.empty; + } + + // some residual data ? + if (wsgi_req->post_readline_pos > 0) { + size_t i; + for(i=wsgi_req->post_readline_pos;ipost_readline_watermark;i++) { + // found a newline + if (wsgi_req->post_readline_buf[i] == '\n') { + *rlen = (i+1)-wsgi_req->post_readline_pos; + char *buf = wsgi_req->post_readline_buf + wsgi_req->post_readline_pos; + wsgi_req->post_readline_pos += *rlen; + // all the readline buffer has been consumed + if (wsgi_req->post_readline_pos >= wsgi_req->post_readline_watermark) { + wsgi_req->post_readline_pos = 0; + wsgi_req->post_readline_watermark = 0; + } + return buf; + } + } + // ok, no newline found, continue below + } + + // allocate memory on the first round + if (!wsgi_req->post_readline_buf) { + size_t amount = UMIN(uwsgi.buffer_size, wsgi_req->post_cl); + wsgi_req->post_readline_buf = malloc(amount); + if (!wsgi_req->post_readline_buf) { + uwsgi_error("uwsgi_request_body_readline()/malloc()"); + *rlen = -1; + return NULL; + } + wsgi_req->post_readline_size = amount; + } + + // ok, no newline found, consume a bit more of memory and retry + for(;;) { + // no more data to consume + if (wsgi_req->post_pos >= wsgi_req->post_cl) break; + + if (consume_body_for_readline(wsgi_req)) { + *rlen = -1; + return NULL; + } + size_t i; + for(i=wsgi_req->post_readline_pos;ipost_readline_watermark;i++) { + if (wsgi_req->post_readline_buf[i] == '\n') { + *rlen = (i+1)-wsgi_req->post_readline_pos; + char *buf = wsgi_req->post_readline_buf + wsgi_req->post_readline_pos; + wsgi_req->post_readline_pos += *rlen; + if (wsgi_req->post_readline_pos >= wsgi_req->post_readline_watermark) { + wsgi_req->post_readline_pos = 0; + wsgi_req->post_readline_watermark = 0; + } + return buf; + } + } + } + + // no line found, let's return all + *rlen = wsgi_req->post_readline_size - wsgi_req->post_readline_pos; + char *buf = wsgi_req->post_readline_buf + wsgi_req->post_readline_pos; + wsgi_req->post_readline_pos = 0; + return buf; + +} + +char *uwsgi_request_body_read(struct wsgi_request *wsgi_req, ssize_t hint, ssize_t *rlen) { + + int ret = -1; + size_t remains = hint; + + // return empty if no post_cl or pos >= post_cl and no residual data + if ((!wsgi_req->post_cl || wsgi_req->post_pos >= wsgi_req->post_cl ) && !wsgi_req->post_readline_pos) { + return uwsgi.empty; + } + + // return the whole input + if (remains <= 0) { + remains = wsgi_req->post_cl; + } + + // some residual data ? + if (wsgi_req->post_readline_pos > 0) { + if (remains <= (wsgi_req->post_readline_watermark - wsgi_req->post_readline_pos)) { + *rlen = remains; + char *buf = wsgi_req->post_readline_buf + wsgi_req->post_readline_pos; + wsgi_req->post_readline_pos += remains; + return buf; + } + // the hint is higher than residual data, let's copy it to read() memory and go on + size_t avail = wsgi_req->post_readline_watermark - wsgi_req->post_readline_pos; + // check if we have enough memory... + if (avail > wsgi_req->post_read_buf_size) { + char *tmp_buf = realloc(wsgi_req->post_read_buf, avail); + if (!tmp_buf) { + uwsgi_error("uwsgi_request_body_read()/realloc()"); + *rlen = -1; + return NULL; + } + wsgi_req->post_read_buf = tmp_buf; + wsgi_req->post_read_buf_size = avail; + if (!wsgi_req->post_warning && wsgi_req->post_read_buf_size > (uwsgi.body_read_warning * 1024*1024)) { + uwsgi_log("[uwsgi-warning] you are using read() on request body allocating over than %llu MB, that is really bad and can be avoided...\n", (unsigned long long) (wsgi_req->post_read_buf_size/(1024*1024))); + wsgi_req->post_warning = 1; + } + } + // fix remains... + if (remains > 0) { + remains -= avail; + } + *rlen += avail; + memcpy(wsgi_req->post_read_buf, wsgi_req->post_readline_buf + wsgi_req->post_readline_pos, avail); + wsgi_req->post_readline_pos = 0; + wsgi_req->post_readline_watermark = 0; + } + + if (remains + wsgi_req->post_pos > wsgi_req->post_cl) { + remains = wsgi_req->post_cl - wsgi_req->post_pos; + } + + + + if (remains == 0) { + if (*rlen > 0) { + return wsgi_req->post_read_buf; + } + else { + return uwsgi.empty; + } + } + + // read from post buffering memory + if (uwsgi.post_buffering > 0 && !wsgi_req->post_file) { + *rlen += remains; + char *buf = wsgi_req->post_buffering_buf+wsgi_req->post_pos; + wsgi_req->post_pos += remains; + return buf; + } + + // ok we need to check if we need to allocate memory + if (!wsgi_req->post_read_buf) { + wsgi_req->post_read_buf = malloc(remains); + if (!wsgi_req->post_read_buf) { + uwsgi_error("uwsgi_request_body_read()/malloc()"); + *rlen = -1; + return NULL; + } + wsgi_req->post_read_buf_size = remains; + } + // need to realloc ? + else { + if ((remains+*rlen) > wsgi_req->post_read_buf_size) { + char *tmp_buf = realloc(wsgi_req->post_read_buf, (remains+*rlen)); + if (!tmp_buf) { + uwsgi_error("uwsgi_request_body_read()/realloc()"); + *rlen = -1; + return NULL; + } + wsgi_req->post_read_buf = tmp_buf; + wsgi_req->post_read_buf_size = (remains+*rlen); + if (!wsgi_req->post_warning && wsgi_req->post_read_buf_size > (uwsgi.body_read_warning * 1024*1024)) { + uwsgi_log("[uwsgi-warning] you are using read() on request body allocating over than %llu MB, that is really bad and can be avoided...\n", (unsigned long long) (wsgi_req->post_read_buf_size/(1024*1024))); + wsgi_req->post_warning = 1; + } + } + } + + // check for disk buffered body first (they are all read in one shot) + if (wsgi_req->post_file) { + if (fread(wsgi_req->post_read_buf + *rlen, remains, 1, wsgi_req->post_file) != 1) { + *rlen = -1; + uwsgi_log("%llu\n", remains); + uwsgi_error("uwsgi_request_body_read()/fread()"); + return NULL; + } + *rlen += remains; + wsgi_req->post_pos+= remains; + return wsgi_req->post_read_buf; + } + + // ok read all the required bytes... + while(remains > 0) { + // here we first try to read (as data could be already available) + ssize_t len = wsgi_req->socket->proto_read_body(wsgi_req, wsgi_req->post_read_buf + *rlen , remains); + if (len > 0) { + wsgi_req->post_pos+=len; + remains -= len; + *rlen += len; + continue; + } + // client closed connection... + if (len == 0) { + *rlen = -1; + uwsgi_read_error(remains); + return NULL; + } + if (len < 0) { + if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) { + goto wait; + } + *rlen = -1; + uwsgi_read_error(remains); + return NULL; + } +wait: + ret = uwsgi_wait_read_req(wsgi_req); + if (ret > 0) { + len = wsgi_req->socket->proto_read_body(wsgi_req, wsgi_req->post_read_buf + *rlen, remains); + if (len > 0) { + wsgi_req->post_pos+=len; + remains -= len; + *rlen += len; + continue; + } + *rlen = -1; + uwsgi_read_error(remains); + return NULL; + } + // 0 means timeout + else if (ret == 0) { + *rlen = 0; + uwsgi_read_timeout(remains); + return NULL; + } + *rlen = -1; + uwsgi_read_error(remains); + return NULL; + } + + return wsgi_req->post_read_buf; +} + +/* + + post buffering + +*/ + +int uwsgi_postbuffer_do_in_mem(struct wsgi_request *wsgi_req) { + + size_t remains = wsgi_req->post_cl; + int ret; + char *ptr = wsgi_req->post_buffering_buf; + + while (remains > 0) { + if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0) { + inc_harakiri(uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); + } + + ssize_t rlen = wsgi_req->socket->proto_read_body(wsgi_req, ptr, remains); + if (rlen > 0) { + remains -= rlen; + ptr += rlen; + continue; + } + if (rlen == 0) { + uwsgi_read_error(remains); + return -1; + } + if (rlen < 0) { + if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) { + goto wait; + } + uwsgi_read_error(remains); + return -1; + } + +wait: + ret = uwsgi_wait_read_req(wsgi_req); + if (ret > 0) { + rlen = wsgi_req->socket->proto_read_body(wsgi_req, ptr, remains); + if (rlen > 0) { + remains -= rlen; + ptr += rlen; + continue; + } + } + if (ret < 0) { + uwsgi_read_error(remains); + return -1; + } + uwsgi_read_timeout(remains); + return -1; + } + + return 0; + +} + + +int uwsgi_postbuffer_do_in_disk(struct wsgi_request *wsgi_req) { + + size_t post_remains = wsgi_req->post_cl; + int ret; + int upload_progress_fd = -1; + char *upload_progress_filename = NULL; + + wsgi_req->post_file = tmpfile(); + if (!wsgi_req->post_file) { + uwsgi_error("uwsgi_postbuffer_do_in_disk()/tmpfile()"); + return -1; + } + + if (uwsgi.upload_progress) { + // first check for X-Progress-ID size + // separator + 'X-Progress-ID' + '=' + uuid + upload_progress_filename = uwsgi_upload_progress_create(wsgi_req, &upload_progress_fd); + if (!upload_progress_filename) { + uwsgi_log("invalid X-Progress-ID value: must be a UUID\n"); + } + } + + // manage buffered data and upload progress + while (post_remains > 0) { + + // during post buffering we need to constantly reset the harakiri + if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0) { + inc_harakiri(uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); + } + + // we use the already available post buffering buffer to read chunks.... + size_t remains = UMIN(post_remains, uwsgi.post_buffering); + + // first try to read data (there could be something already available + ssize_t rlen = wsgi_req->socket->proto_read_body(wsgi_req, wsgi_req->post_buffering_buf, remains); + if (rlen > 0) goto write; + if (rlen == 0) { + uwsgi_read_error(remains); + goto end; + } + if (rlen < 0) { + if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) { + goto wait; + } + uwsgi_read_error(remains); + goto end; + } + +wait: + ret = uwsgi_wait_read_req(wsgi_req); + if (ret > 0) { + rlen = wsgi_req->socket->proto_read_body(wsgi_req, wsgi_req->post_buffering_buf, remains); + if (rlen > 0) goto write; + if (rlen <= 0) { + uwsgi_read_error(remains); + goto end; + } + } + if (ret < 0) { + uwsgi_read_error(remains); + goto end; + } + uwsgi_read_timeout(remains); + goto end; + +write: + if (fwrite(wsgi_req->post_buffering_buf, rlen, 1, wsgi_req->post_file) != 1) { + uwsgi_error("uwsgi_postbuffer_do_in_disk()/fwrite()"); + goto end; + } + + post_remains -= rlen; + + if (upload_progress_filename) { + // stop updating it on errors + if (uwsgi_upload_progress_update(wsgi_req, upload_progress_fd, post_remains)) { + uwsgi_upload_progress_destroy(upload_progress_filename, upload_progress_fd); + upload_progress_filename = NULL; + } + } + } + rewind(wsgi_req->post_file); + + if (upload_progress_filename) { + uwsgi_upload_progress_destroy(upload_progress_filename, upload_progress_fd); + } + + return 0; + +end: + if (upload_progress_filename) { + uwsgi_upload_progress_destroy(upload_progress_filename, upload_progress_fd); + } + return -1; +} + diff --git a/core/setup_utils.c b/core/setup_utils.c index cbdfa0c5..88174969 100644 --- a/core/setup_utils.c +++ b/core/setup_utils.c @@ -106,10 +106,6 @@ void uwsgi_setup_inherited_sockets() { //now close all the unbound fd for (j = 3; j < (int) uwsgi.max_fd; j++) { int useless = 1; -#ifdef UWSGI_MULTICAST - if (j == uwsgi.cluster_fd) - continue; -#endif if (uwsgi.has_emperor) { if (j == uwsgi.emperor_fd) continue; diff --git a/core/signal.c b/core/signal.c index 46a04c6c..f9dd0b2b 100644 --- a/core/signal.c +++ b/core/signal.c @@ -55,13 +55,11 @@ int uwsgi_signal_handler(uint8_t sig) { set_mule_harakiri(uwsgi.shared->options[UWSGI_OPTION_MULE_HARAKIRI]); } } -#ifdef UWSGI_SPOOLER else if (uwsgi.i_am_a_spooler && (getpid() == uwsgi.i_am_a_spooler->pid)) { if (uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI] > 0) { set_spooler_harakiri(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI]); } } -#endif int ret = uwsgi.p[use->modifier1]->signal_handler(sig, use->handler); @@ -77,13 +75,11 @@ int uwsgi_signal_handler(uint8_t sig) { set_mule_harakiri(0); } } -#ifdef UWSGI_SPOOLER else if (uwsgi.i_am_a_spooler && (getpid() == uwsgi.i_am_a_spooler->pid)) { if (uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI] > 0) { set_spooler_harakiri(0); } } -#endif return ret; } @@ -457,7 +453,6 @@ void uwsgi_route_signal(uint8_t sig) { else if (!strcmp(use->receiver, "subscribed")) { } // route to spooler -#ifdef UWSGI_SPOOLER else if (!strcmp(use->receiver, "spooler")) { if (ushared->worker_signal_pipe[0] != -1) { if (uwsgi_signal_send(ushared->spooler_signal_pipe[0], sig)) { @@ -465,7 +460,6 @@ void uwsgi_route_signal(uint8_t sig) { } } } -#endif else if (!strcmp(use->receiver, "mules")) { for (i = 0; i < uwsgi.mules_cnt; i++) { if (uwsgi_signal_send(uwsgi.mules[i].signal_pipe[0], sig)) { diff --git a/core/snmp.c b/core/snmp.c index da895ee9..4a5eceaa 100644 --- a/core/snmp.c +++ b/core/snmp.c @@ -1,6 +1,4 @@ -#ifdef UWSGI_SNMP - -#include "uwsgi.h" +#include extern struct uwsgi_server uwsgi; @@ -408,6 +406,3 @@ int uwsgi_setup_snmp(void) { return snmp_fd; } -#else -#warning "*** SNMP support is disabled ***" -#endif diff --git a/core/socket.c b/core/socket.c index d99a54b0..13a11df1 100644 --- a/core/socket.c +++ b/core/socket.c @@ -168,7 +168,6 @@ int bind_to_unix(char *socket_name, int listen_queue, int chmod_socket, int abst return serverfd; } -#ifdef UWSGI_UDP int bind_to_udp(char *socket_name, int multicast, int broadcast) { int serverfd; struct sockaddr_in uws_addr; @@ -176,9 +175,7 @@ int bind_to_udp(char *socket_name, int multicast, int broadcast) { int bcast = 1; int reuse = 1; -#ifdef UWSGI_MULTICAST struct ip_mreq mc; -#endif udp_port = strchr(socket_name, ':'); if (udp_port == NULL) { @@ -195,7 +192,6 @@ int bind_to_udp(char *socket_name, int multicast, int broadcast) { uws_addr.sin_family = AF_INET; uws_addr.sin_port = htons(atoi(udp_port + 1)); -#ifdef UWSGI_MULTICAST if (!broadcast && !multicast) { char quad[4]; char *first_part = strchr(socket_name, '.'); @@ -206,9 +202,6 @@ int bind_to_udp(char *socket_name, int multicast, int broadcast) { multicast = 1; } } -#else - if (!broadcast) { -#endif if (!strcmp(socket_name, "255.255.255.255")) { broadcast = 1; } @@ -235,14 +228,12 @@ int bind_to_udp(char *socket_name, int multicast, int broadcast) { uwsgi_error("setsockopt()"); } -#ifdef UWSGI_MULTICAST if (multicast) { // if multicast is enabled remember to bind to INADDR_ANY uws_addr.sin_addr.s_addr = INADDR_ANY; mc.imr_multiaddr.s_addr = inet_addr(socket_name); mc.imr_interface.s_addr = INADDR_ANY; } -#endif if (broadcast) { if (setsockopt(serverfd, SOL_SOCKET, SO_BROADCAST, &bcast, sizeof(bcast))) { @@ -258,7 +249,6 @@ int bind_to_udp(char *socket_name, int multicast, int broadcast) { return -1; } -#ifdef UWSGI_MULTICAST if (multicast) { uwsgi_log("[uwsgi-mcast] joining multicast group: %s:%d\n", socket_name, ntohs(uws_addr.sin_port)); if (setsockopt(serverfd, IPPROTO_IP, IP_MULTICAST_LOOP, &uwsgi.multicast_loop, sizeof(uwsgi.multicast_loop))) { @@ -274,13 +264,11 @@ int bind_to_udp(char *socket_name, int multicast, int broadcast) { } } -#endif udp_port[0] = ':'; return serverfd; } -#endif int uwsgi_connectn(char *socket_name, uint16_t len, int timeout, int async) { @@ -1064,7 +1052,7 @@ void uwsgi_add_socket_from_fd(struct uwsgi_socket *uwsgi_sock, int fd) { } } } -#ifdef UWSGI_IPV6 +#ifdef AF_INET6 else if (gsa.sa->sa_family == AF_INET6) { char *computed_addr; char computed_port[6]; @@ -1380,7 +1368,7 @@ nextsock: } -#ifdef UWSGI_IPV6 +#ifdef AF_INET6 int bind_to_tcp6(char *socket_name, int listen_queue, char *tcp_port) { int serverfd; @@ -1516,7 +1504,7 @@ void uwsgi_setup_shared_sockets() { uwsgi_log("uwsgi shared socket %d bound to UNIX address %s fd %d\n", uwsgi_get_shared_socket_num(shared_sock), shared_sock->name, shared_sock->fd); } else { -#ifdef UWSGI_IPV6 +#ifdef AF_INET6 if (shared_sock->name[0] == '[' && tcp_port[-1] == ']') { shared_sock->fd = bind_to_tcp6(shared_sock->name, uwsgi.listen_queue, tcp_port); shared_sock->family = AF_INET6; @@ -1531,7 +1519,7 @@ void uwsgi_setup_shared_sockets() { // fix socket name shared_sock->name = uwsgi_getsockname(shared_sock->fd); uwsgi_log("uwsgi shared socket %d bound to TCP address %s fd %d\n", uwsgi_get_shared_socket_num(shared_sock), shared_sock->name, shared_sock->fd); -#ifdef UWSGI_IPV6 +#ifdef AF_INET6 } #endif } @@ -1675,7 +1663,7 @@ void uwsgi_bind_sockets() { uwsgi_log("uwsgi socket %d bound to UNIX address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd); } else { -#ifdef UWSGI_IPV6 +#ifdef AF_INET6 if (uwsgi_sock->name[0] == '[' && tcp_port[-1] == ']') { uwsgi_sock->fd = bind_to_tcp6(uwsgi_sock->name, uwsgi.listen_queue, tcp_port); uwsgi_log("uwsgi socket %d bound to TCP6 address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd); @@ -1686,7 +1674,7 @@ void uwsgi_bind_sockets() { uwsgi_sock->fd = bind_to_tcp(uwsgi_sock->name, uwsgi.listen_queue, tcp_port); uwsgi_log("uwsgi socket %d bound to TCP address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd); uwsgi_sock->family = AF_INET; -#ifdef UWSGI_IPV6 +#ifdef AF_INET6 } #endif } @@ -1762,14 +1750,14 @@ void uwsgi_bind_sockets() { uwsgi_sock = uwsgi.sockets; while (uwsgi_sock) { if (uwsgi_sock->auto_port) { -#ifdef UWSGI_IPV6 +#ifdef AF_INET6 if (uwsgi_sock->family == AF_INET6) { uwsgi_log("uwsgi socket %d bound to TCP6 address %s (port auto-assigned) fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd); } else { #endif uwsgi_log("uwsgi socket %d bound to TCP address %s (port auto-assigned) fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd); -#ifdef UWSGI_IPV6 +#ifdef AF_INET6 } #endif } @@ -1814,6 +1802,7 @@ setup_proto: uwsgi_sock->proto_prepare_headers = uwsgi_proto_base_prepare_headers; uwsgi_sock->proto_add_header = uwsgi_proto_base_add_header; uwsgi_sock->proto_fix_headers = uwsgi_proto_base_fix_headers; + uwsgi_sock->proto_read_body = uwsgi_proto_base_read_body; uwsgi_sock->proto_write = uwsgi_proto_base_write; uwsgi_sock->proto_write_headers = uwsgi_proto_base_write; uwsgi_sock->proto_sendfile = uwsgi_proto_base_sendfile; @@ -1822,9 +1811,6 @@ setup_proto: uwsgi_sock->can_offload = 1; } else if (requested_protocol && (!strcmp("fastcgi", requested_protocol) || !strcmp("fcgi", requested_protocol))) { - if (uwsgi.protocol && (!strcmp(uwsgi.protocol, "fastcgi") || !strcmp(uwsgi.protocol, "fcgi"))) { - uwsgi.shared->options[UWSGI_OPTION_CGI_MODE] = 1; - } uwsgi_sock->proto = uwsgi_proto_fastcgi_parser; uwsgi_sock->proto_accept = uwsgi_proto_base_accept; uwsgi_sock->proto_write = uwsgi_proto_fastcgi_write; @@ -1843,6 +1829,7 @@ setup_proto: uwsgi_sock->proto_prepare_headers = uwsgi_proto_base_prepare_headers; uwsgi_sock->proto_add_header = uwsgi_proto_base_add_header; uwsgi_sock->proto_fix_headers = uwsgi_proto_base_fix_headers; + uwsgi_sock->proto_read_body = uwsgi_proto_base_read_body; uwsgi_sock->proto_write = uwsgi_proto_base_write; uwsgi_sock->proto_write_headers = uwsgi_proto_base_write; uwsgi_sock->proto_sendfile = uwsgi_proto_base_sendfile; diff --git a/core/spooler.c b/core/spooler.c index d0449ac5..f79f6a42 100644 --- a/core/spooler.c +++ b/core/spooler.c @@ -1,4 +1,3 @@ -#ifdef UWSGI_SPOOLER #include "uwsgi.h" extern struct uwsgi_server uwsgi; @@ -584,7 +583,3 @@ void spooler_manage_task(struct uwsgi_spooler *uspool, char *dir, char *task) { } } } - -#else -#warning "*** Spooler support is disabled ***" -#endif diff --git a/core/static.c b/core/static.c index 85a88f0e..d194d826 100644 --- a/core/static.c +++ b/core/static.c @@ -426,15 +426,13 @@ int uwsgi_real_file_serve(struct wsgi_request *wsgi_req, char *real_filename, si int mime_type_size = 0; char http_last_modified[49]; -#ifdef UWSGI_THREADING if (uwsgi.threads > 1) pthread_mutex_lock(&uwsgi.lock_static); -#endif + char *mime_type = uwsgi_get_mime_type(real_filename, real_filename_len, &mime_type_size); -#ifdef UWSGI_THREADING + if (uwsgi.threads > 1) pthread_mutex_unlock(&uwsgi.lock_static); -#endif if (wsgi_req->if_modified_since_len) { time_t ims = parse_http_date(wsgi_req->if_modified_since, wsgi_req->if_modified_since_len); diff --git a/core/stats.c b/core/stats.c index b913ca5e..98c68eee 100644 --- a/core/stats.c +++ b/core/stats.c @@ -552,14 +552,15 @@ static void stats_dump_var(char *k, uint16_t kl, char *v, uint16_t vl, void *dat int uwsgi_stats_dump_vars(struct uwsgi_stats *us, struct uwsgi_core *uc) { if (!uc->in_request) return 0; - uint16_t pktsize = uc->req.uh.pktsize; + struct uwsgi_header *uh = (struct uwsgi_header *) uwsgi.workers[0].cores[0].buffer; + uint16_t pktsize = uh->pktsize; if (!pktsize) return 0; char *dst = uwsgi.workers[0].cores[0].buffer; - memcpy(dst, uc->buffer, uwsgi.buffer_size); + memcpy(dst, uc->buffer+4, uwsgi.buffer_size); // ok now check if something changed... if (!uc->in_request) return 0; - if (uc->req.uh.pktsize != pktsize) return 0; - if (memcmp(dst, uc->buffer, uwsgi.buffer_size)) return 0; + if (uh->pktsize != pktsize) return 0; + if (memcmp(dst, uc->buffer+4, uwsgi.buffer_size)) return 0; // nothing changed let's dump vars int ret = uwsgi_hooked_parse(dst, pktsize, stats_dump_var, us); if (ret) return -1; diff --git a/core/utils.c b/core/utils.c index 7a24ed5e..6e5e1c78 100644 --- a/core/utils.c +++ b/core/utils.c @@ -92,7 +92,6 @@ void set_mule_harakiri(int sec) { } } -#ifdef UWSGI_SPOOLER // set spooler harakiri void set_spooler_harakiri(int sec) { if (sec == 0) { @@ -105,7 +104,6 @@ void set_spooler_harakiri(int sec) { alarm(sec); } } -#endif // daemonize to the specified logfile @@ -560,13 +558,11 @@ void uwsgi_destroy_request(struct wsgi_request *wsgi_req) { wsgi_req->socket->proto_close(wsgi_req); -#ifdef UWSGI_THREADING int foo; if (uwsgi.threads > 1) { // now the thread can die... pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &foo); } -#endif memset(wsgi_req, 0, sizeof(struct wsgi_request)); @@ -604,11 +600,28 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) { } - // close the connection with the webserver - if (!wsgi_req->fd_closed || wsgi_req->body_as_file) { + // close the connection with the client + if (!wsgi_req->fd_closed) { // NOTE, if we close the socket before receiving eventually sent data, socket layer will send a RST wsgi_req->socket->proto_close(wsgi_req); } + + if (wsgi_req->post_file) { + fclose(wsgi_req->post_file); + } + + if (wsgi_req->post_read_buf) { + free(wsgi_req->post_read_buf); + } + + if (wsgi_req->post_readline_buf) { + free(wsgi_req->post_readline_buf); + } + + if (wsgi_req->proto_parser_buf) { + free(wsgi_req->proto_parser_buf); + } + uwsgi.workers[0].requests++; uwsgi.workers[uwsgi.mywid].requests++; uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].requests++; @@ -616,15 +629,13 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) { uwsgi.workers[uwsgi.mywid].delta_requests++; // after_request hook - if (uwsgi.p[wsgi_req->uh.modifier1]->after_request) - uwsgi.p[wsgi_req->uh.modifier1]->after_request(wsgi_req); + if (uwsgi.p[wsgi_req->uh->modifier1]->after_request) + uwsgi.p[wsgi_req->uh->modifier1]->after_request(wsgi_req); -#ifdef UWSGI_THREADING if (uwsgi.threads > 1) { // now the thread can die... pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &tmp_id); } -#endif // leave harakiri mode if (uwsgi.workers[uwsgi.mywid].harakiri > 0) { @@ -644,8 +655,6 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) { uwsgi.workers[uwsgi.mywid].tx += wsgi_req->headers_size; } - uwsgi_channels_leave(wsgi_req); - // defunct process reaper if (uwsgi.shared->options[UWSGI_OPTION_REAPER] == 1 || uwsgi.grunt) { while (waitpid(WAIT_ANY, &waitpid_status, WNOHANG) > 0); @@ -832,15 +841,15 @@ long uwsgi_num_from_file(char *filename, int quiet) { // setup for a new request void wsgi_req_setup(struct wsgi_request *wsgi_req, int async_id, struct uwsgi_socket *uwsgi_sock) { - wsgi_req->poll.events = POLLIN; - wsgi_req->app_id = uwsgi.default_app; wsgi_req->async_id = async_id; wsgi_req->sendfile_fd = -1; wsgi_req->hvec = uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].hvec; - wsgi_req->buffer = uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].buffer; + // skip the first 4 bytes; + wsgi_req->uh = (struct uwsgi_header *) uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].buffer; + wsgi_req->buffer = uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].buffer+4; if (uwsgi.post_buffering > 0) { wsgi_req->post_buffering_buf = uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].post_buf; @@ -865,7 +874,6 @@ cycle: } } -#ifdef UWSGI_ASYNC int wsgi_req_async_recv(struct wsgi_request *wsgi_req) { uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].in_request = 1; @@ -875,11 +883,11 @@ int wsgi_req_async_recv(struct wsgi_request *wsgi_req) { wsgi_req->start_of_request_in_sec = wsgi_req->start_of_request / 1000000; if (!wsgi_req->do_not_add_to_async_queue) { - if (event_queue_add_fd_read(uwsgi.async_queue, wsgi_req->poll.fd) < 0) + if (event_queue_add_fd_read(uwsgi.async_queue, wsgi_req->fd) < 0) return -1; async_add_timeout(wsgi_req, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); - uwsgi.async_proto_fd_table[wsgi_req->poll.fd] = wsgi_req; + uwsgi.async_proto_fd_table[wsgi_req->fd] = wsgi_req; } @@ -891,10 +899,9 @@ int wsgi_req_async_recv(struct wsgi_request *wsgi_req) { return 0; } -#endif // receive a new request -int wsgi_req_recv(struct wsgi_request *wsgi_req) { +int wsgi_req_recv(int queue, struct wsgi_request *wsgi_req) { uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].in_request = 1; uwsgi.workers[uwsgi.mywid].busy = 1; @@ -904,7 +911,13 @@ int wsgi_req_recv(struct wsgi_request *wsgi_req) { // edge triggered sockets get the whole request during accept() phase if (!wsgi_req->socket->edge_trigger) { - if (!uwsgi_parse_packet(wsgi_req, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT])) { + for(;;) { + int ret = wsgi_req->socket->proto(wsgi_req); + if (ret == UWSGI_OK) break; + if (ret == UWSGI_AGAIN) { + ret = uwsgi_wait_read_req(wsgi_req); + if (ret <= 0) return -1; + } return -1; } } @@ -919,7 +932,7 @@ int wsgi_req_recv(struct wsgi_request *wsgi_req) { return 0; #endif - wsgi_req->async_status = uwsgi.p[wsgi_req->uh.modifier1]->request(wsgi_req); + wsgi_req->async_status = uwsgi.p[wsgi_req->uh->modifier1]->request(wsgi_req); return 0; } @@ -928,15 +941,15 @@ int wsgi_req_recv(struct wsgi_request *wsgi_req) { // accept a new request int wsgi_req_simple_accept(struct wsgi_request *wsgi_req, int fd) { - wsgi_req->poll.fd = wsgi_req->socket->proto_accept(wsgi_req, fd); + wsgi_req->fd = wsgi_req->socket->proto_accept(wsgi_req, fd); - if (wsgi_req->poll.fd < 0) { + if (wsgi_req->fd < 0) { return -1; } // set close on exec (if not a new socket) if (!wsgi_req->socket->edge_trigger && uwsgi.close_on_exec) { - if (fcntl(wsgi_req->poll.fd, F_SETFD, FD_CLOEXEC) < 0) { + if (fcntl(wsgi_req->fd, F_SETFD, FD_CLOEXEC) < 0) { uwsgi_error("fcntl()"); } } @@ -1007,11 +1020,9 @@ int wsgi_req_accept(int queue, struct wsgi_request *wsgi_req) { } } -#ifdef UWSGI_THREADING // kill the thread after the request completion if (uwsgi.threads > 1) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &ret); -#endif if (uwsgi.signal_socket > -1 && (interesting_fd == uwsgi.signal_socket || interesting_fd == uwsgi.my_signal_socket)) { @@ -1019,10 +1030,8 @@ int wsgi_req_accept(int queue, struct wsgi_request *wsgi_req) { uwsgi_receive_signal(interesting_fd, "worker", uwsgi.mywid); -#ifdef UWSGI_THREADING if (uwsgi.threads > 1) pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &ret); -#endif return -1; } @@ -1030,25 +1039,24 @@ int wsgi_req_accept(int queue, struct wsgi_request *wsgi_req) { while (uwsgi_sock) { if (interesting_fd == uwsgi_sock->fd || (uwsgi_sock->retry && uwsgi_sock->retry[wsgi_req->async_id]) || (uwsgi_sock->fd_threads && interesting_fd == uwsgi_sock->fd_threads[wsgi_req->async_id])) { wsgi_req->socket = uwsgi_sock; - wsgi_req->poll.fd = wsgi_req->socket->proto_accept(wsgi_req, interesting_fd); + wsgi_req->fd = wsgi_req->socket->proto_accept(wsgi_req, interesting_fd); thunder_unlock; - if (wsgi_req->poll.fd < 0) { -#ifdef UWSGI_THREADING + if (wsgi_req->fd < 0) { if (uwsgi.threads > 1) pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &ret); -#endif return -1; } if (!uwsgi_sock->edge_trigger) { if (uwsgi.close_on_exec) { - if (fcntl(wsgi_req->poll.fd, F_SETFD, FD_CLOEXEC) < 0) { + if (fcntl(wsgi_req->fd, F_SETFD, FD_CLOEXEC) < 0) { uwsgi_error("fcntl()"); } } } + return 0; } @@ -1056,10 +1064,8 @@ int wsgi_req_accept(int queue, struct wsgi_request *wsgi_req) { } thunder_unlock; -#ifdef UWSGI_THREADING if (uwsgi.threads > 1) pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &ret); -#endif return -1; } @@ -1563,10 +1569,6 @@ add: if (op->flags & UWSGI_OPT_NO_SERVER) { uwsgi.no_server = 1; } - // requires cluster ? - if (op->flags & UWSGI_OPT_CLUSTER) { - uwsgi.cluster = value; - } // requires post_buffering ? if (op->flags & UWSGI_OPT_POST_BUFFERING) { if (!uwsgi.post_buffering) @@ -1628,7 +1630,7 @@ char *uwsgi_resolve_ip(char *domain) { he = gethostbyname(domain); if (!he || !*he->h_addr_list || (he->h_addrtype != AF_INET -#ifdef UWSGI_IPV6 +#ifdef AF_INET6 && he->h_addrtype != AF_INET6 #endif )) { @@ -3535,51 +3537,6 @@ error: return -1; } -ssize_t uwsgi_simple_request_read(struct wsgi_request *wsgi_req, char *buf, size_t len) { - if (wsgi_req->post_cl == 0) - return 0; - if ((size_t) wsgi_req->post_pos >= wsgi_req->post_cl) - return 0; - size_t remains = wsgi_req->post_cl - wsgi_req->post_pos; - remains = UMIN(len, remains); - - int fd = -1; - - if (wsgi_req->body_as_file) { - fd = fileno((FILE *) wsgi_req->async_post); - } - else if (uwsgi.post_buffering > 0) { - if (wsgi_req->post_cl > (size_t) uwsgi.post_buffering) { - fd = fileno((FILE *) wsgi_req->async_post); - } - } - else { - fd = wsgi_req->poll.fd; - } - - // data in memory ? - if (fd == -1) { - memcpy(buf, wsgi_req->post_buffering_buf + wsgi_req->post_buffering_read, remains); - wsgi_req->post_buffering_read += remains; - wsgi_req->post_pos += remains; - return remains; - } - - if (uwsgi_waitfd(fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]) <= 0) { - uwsgi_log("error waiting for request body"); - return -1; - } - - ssize_t rlen = read(fd, buf, remains); - if (rlen < 0) { - uwsgi_error("error reading request body:"); - return -1; - } - - wsgi_req->post_pos += rlen; - return rlen; -} - int uwsgi_plugin_modifier1(char *plugin) { int ret = -1; char *symbol_name = uwsgi_concat2(plugin, "_plugin"); diff --git a/core/uwsgi.c b/core/uwsgi.c index 391fc484..b8581095 100644 --- a/core/uwsgi.c +++ b/core/uwsgi.c @@ -113,7 +113,7 @@ static struct uwsgi_option uwsgi_base_options[] = { {"listen", required_argument, 'l', "set the socket listen queue size", uwsgi_opt_set_int, &uwsgi.listen_queue, 0}, {"max-vars", required_argument, 'v', "set the amount of internal iovec/vars structures", uwsgi_opt_max_vars, NULL, 0}, {"max-apps", required_argument, 0, "set the maximum number of per-worker applications", uwsgi_opt_set_int, &uwsgi.max_apps, 0}, - {"buffer-size", required_argument, 'b', "set internal buffer size", uwsgi_opt_set_int, &uwsgi.buffer_size, 0}, + {"buffer-size", required_argument, 'b', "set internal buffer size", uwsgi_opt_set_16bit, &uwsgi.buffer_size, 0}, {"memory-report", no_argument, 'm', "enable memory report", uwsgi_opt_dyn_true, (void *) UWSGI_OPTION_MEMORY_DEBUG, 0}, {"profiler", required_argument, 0, "enable the specified profiler", uwsgi_opt_set_str, &uwsgi.profiler, 0}, {"cgi-mode", no_argument, 'c', "force CGI-mode for plugins supporting it", uwsgi_opt_dyn_true, (void *) UWSGI_OPTION_CGI_MODE, 0}, @@ -126,10 +126,8 @@ static struct uwsgi_option uwsgi_base_options[] = { {"freebind", no_argument, 0, "put socket in freebind mode", uwsgi_opt_true, &uwsgi.freebind, 0}, #endif {"map-socket", required_argument, 0, "map sockets to specific workers", uwsgi_opt_add_string_list, &uwsgi.map_socket, 0}, -#ifdef UWSGI_THREADING {"enable-threads", no_argument, 'T', "enable threads", uwsgi_opt_true, &uwsgi.has_threads, 0}, {"no-threads-wait", no_argument, 0, "do not wait for threads cancellation on quit/reload", uwsgi_opt_true, &uwsgi.no_threads_wait, 0}, -#endif {"auto-procname", no_argument, 0, "automatically set processes name to something meaningful", uwsgi_opt_true, &uwsgi.auto_procname, 0}, {"procname-prefix", required_argument, 0, "add a prefix to the process names", uwsgi_opt_set_str, &uwsgi.procname_prefix, UWSGI_OPT_PROCNAME}, @@ -204,7 +202,6 @@ static struct uwsgi_option uwsgi_base_options[] = { {"queue-store", required_argument, 0, "enable persistent queue to disk", uwsgi_opt_set_str, &uwsgi.queue_store, UWSGI_OPT_MASTER}, {"queue-store-sync", required_argument, 0, "set frequency of sync for persistent queue", uwsgi_opt_set_int, &uwsgi.queue_store_sync, 0}, -#ifdef UWSGI_SPOOLER {"spooler", required_argument, 'Q', "run a spooler on the specified directory", uwsgi_opt_add_spooler, NULL, UWSGI_OPT_MASTER}, {"spooler-external", required_argument, 0, "map spoolers requests to a spooler directory managed by an external instance", uwsgi_opt_add_spooler, (void *) UWSGI_SPOOLER_EXTERNAL, UWSGI_OPT_MASTER}, {"spooler-ordered", no_argument, 0, "try to order the execution of spooler tasks", uwsgi_opt_true, &uwsgi.spooler_ordered, 0}, @@ -213,7 +210,7 @@ static struct uwsgi_option uwsgi_base_options[] = { {"spooler-quiet", no_argument, 0, "do not be verbose with spooler tasks", uwsgi_opt_true, &uwsgi.spooler_quiet, 0}, {"spooler-max-tasks", required_argument, 0, "set the maximum number of tasks to run before recycling a spooler", uwsgi_opt_set_int, &uwsgi.spooler_max_tasks, 0}, {"spooler-harakiri", required_argument, 0, "set harakiri timeout for spooler tasks", uwsgi_opt_set_dyn, (void *) UWSGI_OPTION_SPOOLER_HARAKIRI, 0}, -#endif + {"mule", optional_argument, 0, "add a mule", uwsgi_opt_add_mule, NULL, UWSGI_OPT_MASTER}, {"mules", required_argument, 0, "add the specified number of mules", uwsgi_opt_add_mules, NULL, UWSGI_OPT_MASTER}, {"farm", required_argument, 0, "add a mule farm", uwsgi_opt_add_farm, NULL, UWSGI_OPT_MASTER}, @@ -311,6 +308,7 @@ static struct uwsgi_option uwsgi_base_options[] = { {"cpu-affinity", required_argument, 0, "set cpu affinity", uwsgi_opt_set_int, &uwsgi.cpu_affinity, 0}, {"post-buffering", required_argument, 0, "enable post buffering", uwsgi_opt_set_64bit, &uwsgi.post_buffering, 0}, {"post-buffering-bufsize", required_argument, 0, "set buffer size for read() in post buffering mode", uwsgi_opt_set_64bit, &uwsgi.post_buffering_bufsize, 0}, + {"body-read-warning", required_argument, 0, "set the amount of allowed memory allocation (in megabytes) for request body before starting printing a warning", uwsgi_opt_set_64bit, &uwsgi.body_read_warning, 0}, {"upload-progress", required_argument, 0, "enable creation of .json files in the specified directory during a file upload", uwsgi_opt_set_str, &uwsgi.upload_progress, 0}, {"no-default-app", no_argument, 0, "do not fallback to default app", uwsgi_opt_true, &uwsgi.no_default_app, 0}, {"manage-script-name", no_argument, 0, "automatically rewrite SCRIPT_NAME and PATH_INFO", uwsgi_opt_true, &uwsgi.manage_script_name, 0}, @@ -320,9 +318,7 @@ static struct uwsgi_option uwsgi_base_options[] = { {"reload-on-exception-type", required_argument, 0, "reload a worker when a specific exception type is raised", uwsgi_opt_add_string_list, &uwsgi.reload_on_exception_type, 0}, {"reload-on-exception-value", required_argument, 0, "reload a worker when a specific exception value is raised", uwsgi_opt_add_string_list, &uwsgi.reload_on_exception_value, 0}, {"reload-on-exception-repr", required_argument, 0, "reload a worker when a specific exception type+value (language-specific) is raised", uwsgi_opt_add_string_list, &uwsgi.reload_on_exception_repr, 0}, -#ifdef UWSGI_UDP {"udp", required_argument, 0, "run the udp server on the specified address", uwsgi_opt_set_str, &uwsgi.udp_socket, UWSGI_OPT_MASTER}, -#endif {"stats", required_argument, 0, "enable the stats server on the specified address", uwsgi_opt_set_str, &uwsgi.stats, UWSGI_OPT_MASTER}, {"stats-server", required_argument, 0, "enable the stats server on the specified address", uwsgi_opt_set_str, &uwsgi.stats, UWSGI_OPT_MASTER}, {"stats-http", no_argument, 0, "prefix stats server json output with http headers", uwsgi_opt_true, &uwsgi.stats_http, UWSGI_OPT_MASTER}, @@ -331,15 +327,9 @@ static struct uwsgi_option uwsgi_base_options[] = { {"stats-push", required_argument, 0, "push the stats json to the specified destination", uwsgi_opt_add_string_list, &uwsgi.requested_stats_pushers, UWSGI_OPT_MASTER}, {"stats-pusher-default-freq", required_argument, 0, "set the default frequency of stats pushers", uwsgi_opt_set_int, &uwsgi.stats_pusher_default_freq, UWSGI_OPT_MASTER}, {"stats-pushers-default-freq", required_argument, 0, "set the default frequency of stats pushers", uwsgi_opt_set_int, &uwsgi.stats_pusher_default_freq, UWSGI_OPT_MASTER}, -#ifdef UWSGI_MULTICAST {"multicast", required_argument, 0, "subscribe to specified multicast group", uwsgi_opt_set_str, &uwsgi.multicast_group, UWSGI_OPT_MASTER}, {"multicast-ttl", required_argument, 0, "set multicast ttl", uwsgi_opt_set_int, &uwsgi.multicast_ttl, 0}, {"multicast-loop", required_argument, 0, "set multicast loop (default 1)", uwsgi_opt_set_int, &uwsgi.multicast_loop, 0}, - {"cluster", required_argument, 0, "join specified uWSGI cluster", uwsgi_opt_set_str, &uwsgi.cluster, UWSGI_OPT_MASTER}, - {"cluster-nodes", required_argument, 0, "get nodes list from the specified cluster", uwsgi_opt_true, &uwsgi.cluster_nodes, UWSGI_OPT_MASTER | UWSGI_OPT_CLUSTER}, - {"cluster-reload", required_argument, 0, "send a reload message to the cluster", uwsgi_opt_cluster_reload, NULL, UWSGI_OPT_IMMEDIATE}, - {"cluster-log", required_argument, 0, "send a log line to the cluster", uwsgi_opt_cluster_log, NULL, UWSGI_OPT_IMMEDIATE}, -#endif #ifdef UWSGI_SSL {"legion", required_argument, 0, "became a member of a legion", uwsgi_opt_legion, NULL, UWSGI_OPT_MASTER}, @@ -364,10 +354,8 @@ static struct uwsgi_option uwsgi_base_options[] = { {"subscribe-freq", required_argument, 0, "send subscription announce at the specified interval", uwsgi_opt_set_int, &uwsgi.subscribe_freq, 0}, {"subscription-tolerance", required_argument, 0, "set tolerance for subscription servers", uwsgi_opt_set_int, &uwsgi.subscription_tolerance, 0}, {"unsubscribe-on-graceful-reload", no_argument, 0, "force unsubscribe request even during graceful reload", uwsgi_opt_true, &uwsgi.unsubscribe_on_graceful_reload, 0}, -#ifdef UWSGI_SNMP {"snmp", optional_argument, 0, "enable the embedded snmp server", uwsgi_opt_snmp, NULL, 0}, {"snmp-community", required_argument, 0, "set the snmp community string", uwsgi_opt_snmp_community, NULL, 0}, -#endif #ifdef UWSGI_SSL {"ssl-verbose", no_argument, 0, "be verbose about SSL errors", uwsgi_opt_true, &uwsgi.ssl_verbose, 0}, // force master, as ssl sessions caching initialize locking early @@ -389,9 +377,7 @@ static struct uwsgi_option uwsgi_base_options[] = { {"unprivileged-binary-patch", required_argument, 0, "patch the uwsgi binary with a new command (after privileges drop)", uwsgi_opt_set_str, &uwsgi.unprivileged_binary_patch, 0}, {"privileged-binary-patch-arg", required_argument, 0, "patch the uwsgi binary with a new command and arguments (before privileges drop)", uwsgi_opt_set_str, &uwsgi.privileged_binary_patch_arg, 0}, {"unprivileged-binary-patch-arg", required_argument, 0, "patch the uwsgi binary with a new command and arguments (after privileges drop)", uwsgi_opt_set_str, &uwsgi.unprivileged_binary_patch_arg, 0}, -#ifdef UWSGI_ASYNC {"async", required_argument, 0, "enable async mode with specified cores", uwsgi_opt_set_int, &uwsgi.async, 0}, -#endif {"max-fd", required_argument, 0, "set maximum number of file descriptors (requires root privileges)", uwsgi_opt_set_int, &uwsgi.requested_max_fd, 0}, {"logto", required_argument, 0, "set logfile/udp address", uwsgi_opt_set_str, &uwsgi.logfile, 0}, {"logto2", required_argument, 0, "log to specified file or udp address after privileges drop", uwsgi_opt_set_str, &uwsgi.logto2, 0}, @@ -497,8 +483,6 @@ static struct uwsgi_option uwsgi_base_options[] = { {"websockets-max-size", required_argument, 0, "set the max allowed size of websocket messages (in Kbytes, default 1024)", uwsgi_opt_set_64bit, &uwsgi.websockets_max_size, 0}, {"websocket-max-size", required_argument, 0, "set the max allowed size of websocket messages (in Kbytes, default 1024)", uwsgi_opt_set_64bit, &uwsgi.websockets_max_size, 0}, - {"channel", required_argument, 0, "create a named channel for cores messaging", uwsgi_opt_add_string_list, &uwsgi.channels_list, UWSGI_OPT_MASTER}, - {"clock", required_argument, 0, "set a clock source", uwsgi_opt_set_str, &uwsgi.requested_clock, 0}, {"clock-list", no_argument, 0, "list enabled clocks", uwsgi_opt_true, &uwsgi.clock_list, 0}, @@ -845,7 +829,6 @@ void warn_pipe() { } } -#ifdef UWSGI_THREADING // in threading mode we need to use the cancel pthread subsystem void wait_for_threads() { int i, ret; @@ -882,14 +865,12 @@ end: pthread_mutex_unlock(&uwsgi.six_feet_under_lock); } -#endif void gracefully_kill(int signum) { uwsgi_log("Gracefully killing worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid); uwsgi.workers[uwsgi.mywid].manage_next_request = 0; -#ifdef UWSGI_THREADING if (uwsgi.threads > 1) { struct wsgi_request *wsgi_req = current_wsgi_req(); wait_for_threads(); @@ -899,7 +880,6 @@ void gracefully_kill(int signum) { return; // never here } -#endif // still not found a way to gracefully reload in async mode if (uwsgi.async > 1) { @@ -917,11 +897,9 @@ void end_me(int signum) { void simple_goodbye_cruel_world() { -#ifdef UWSGI_THREADING if (uwsgi.threads > 1 && !uwsgi.to_hell) { wait_for_threads(); } -#endif uwsgi.workers[uwsgi.mywid].manage_next_request = 0; uwsgi_log("...The work of process %d is done. Seeya!\n", getpid()); @@ -939,7 +917,6 @@ void goodbye_cruel_world() { } } -#ifdef UWSGI_SPOOLER static void uwsgi_signal_spoolers(int signum) { struct uwsgi_spooler *uspool = uwsgi.spoolers; @@ -952,7 +929,6 @@ static void uwsgi_signal_spoolers(int signum) { } } -#endif void kill_them_all(int signum) { int i; @@ -988,9 +964,7 @@ void kill_them_all(int signum) { kill(uwsgi.workers[i].pid, SIGINT); } -#ifdef UWSGI_SPOOLER uwsgi_signal_spoolers(SIGKILL); -#endif if (uwsgi.emperor_pid >= 0) { kill(uwsgi.emperor_pid, SIGKILL); @@ -1042,9 +1016,7 @@ void grace_them_all(int signum) { uwsgi.master_mercy = uwsgi_now() + 60; } -#ifdef UWSGI_SPOOLER uwsgi_signal_spoolers(SIGKILL); -#endif if (uwsgi.emperor_pid >= 0) { kill(uwsgi.emperor_pid, SIGKILL); @@ -1198,11 +1170,9 @@ void snapshot_me(int signum) { } uwsgi.workers[uwsgi.mywid].manage_next_request = 0; -#ifdef UWSGI_THREADING if (uwsgi.threads > 1) { wait_for_threads(); } -#endif uwsgi.snapshot = 1; uwsgi_set_processname(uwsgi.workers[uwsgi.mywid].snapshot_name); uwsgi_log("[snapshot] process %d taken\n", (int) getpid()); @@ -1291,7 +1261,7 @@ void what_i_am_doing() { pid_t masterpid; int unconfigured_hook(struct wsgi_request *wsgi_req) { - uwsgi_log("-- unavailable modifier requested: %d --\n", wsgi_req->uh.modifier1); + uwsgi_log("-- unavailable modifier requested: %d --\n", wsgi_req->uh->modifier1); return -1; } @@ -1914,9 +1884,7 @@ int main(int argc, char *argv[], char *envp[]) { // setup main loops uwsgi_register_loop("simple", simple_loop); -#ifdef UWSGI_ASYNC uwsgi_register_loop("async", async_loop); -#endif // setup cheaper algos uwsgi_register_cheaper_algo("spare", uwsgi_cheaper_algo_spare); @@ -1985,11 +1953,6 @@ int main(int argc, char *argv[], char *envp[]) { if (uwsgi.requested_clock) uwsgi_set_clock(uwsgi.requested_clock); - // call cluster initialization procedures -#ifdef UWSGI_MULTICAST - cluster_setup(); -#endif - if (uwsgi.binary_path == uwsgi.argv[0]) { uwsgi.binary_path = uwsgi_str(uwsgi.argv[0]); } @@ -2206,11 +2169,6 @@ int uwsgi_start(void *v_argv) { uwsgi_log_initial("your memory page size is %d bytes\n", uwsgi.page_size); - if (uwsgi.buffer_size > 65536) { - uwsgi_log("invalid buffer size.\n"); - exit(1); - } - // automatically fix options sanitize_args(); @@ -2299,9 +2257,7 @@ int uwsgi_start(void *v_argv) { uwsgi.sa_lock = uwsgi_rwlock_init("sharedarea"); } -#ifdef UWSGI_SNMP uwsgi.snmp_lock = uwsgi_lock_init("snmp"); -#endif // setup queue if (uwsgi.queue_size > 0) { @@ -2378,7 +2334,6 @@ int uwsgi_start(void *v_argv) { uwsgi.current_wsgi_req = simple_current_wsgi_req; -#ifdef UWSGI_THREADING if (uwsgi.has_threads) { if (uwsgi.threads > 1) uwsgi.current_wsgi_req = threaded_current_wsgi_req; @@ -2402,7 +2357,6 @@ int uwsgi_start(void *v_argv) { } } } -#endif // users of the --loop option should know what they are doing... really... #ifndef UWSGI_DEBUG @@ -2413,9 +2367,7 @@ int uwsgi_start(void *v_argv) { if (!uwsgi.sockets && !ushared->gateways_cnt && !uwsgi.no_server && -#ifdef UWSGI_UDP !uwsgi.udp_socket && -#endif !uwsgi.emperor && !uwsgi.command_mode #ifdef UWSGI_SSL @@ -2519,7 +2471,6 @@ unsafe: uwsgi_log("*** Operational MODE: threaded ***\n"); } } -#ifdef UWSGI_ASYNC else if (uwsgi.async > 1) { if (uwsgi.numproc > 1) { uwsgi_log("*** Operational MODE: preforking+async ***\n"); @@ -2528,7 +2479,6 @@ unsafe: uwsgi_log("*** Operational MODE: async ***\n"); } } -#endif else if (uwsgi.numproc > 1) { uwsgi_log("*** Operational MODE: preforking ***\n"); } @@ -2554,7 +2504,6 @@ unsafe: } } -#ifdef UWSGI_SPOOLER // initialize locks and socket as soon as possibile, as the master could enqueue tasks if (uwsgi.spoolers != NULL && (uwsgi.sockets || uwsgi.loop)) { create_signal_pipe(uwsgi.shared->spooler_signal_pipe); @@ -2569,8 +2518,6 @@ next: uspool = uspool->next; } } -#endif - // preinit apps (create the language environment) for (i = 0; i < 256; i++) { @@ -2682,7 +2629,6 @@ next: -#ifdef UWSGI_SPOOLER if (uwsgi.spoolers != NULL && (uwsgi.sockets || uwsgi.loop)) { struct uwsgi_spooler *uspool = uwsgi.spoolers; while (uspool) { @@ -2693,8 +2639,6 @@ next2: uspool = uspool->next; } } -#endif - if (!uwsgi.master_process) { if (uwsgi.numproc == 1) { @@ -2716,9 +2660,6 @@ next2: uwsgi.signal_socket = uwsgi.shared->worker_signal_pipe[1]; } - // setup channels - uwsgi_channels_init(); - // uWSGI is ready uwsgi_notify_ready(); uwsgi.current_time = uwsgi_now(); @@ -2838,11 +2779,9 @@ next2: //postpone the queue initialization as kevent //do not pass kfd after fork() -#ifdef UWSGI_ASYNC if (uwsgi.async > 1) { uwsgi_async_init(); } -#endif // setup UNIX signals for the worker if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0 && !uwsgi.master_process) { @@ -2904,12 +2843,10 @@ next2: } -#ifdef UWSGI_THREADING if (uwsgi.cores > 1) { uwsgi.workers[uwsgi.mywid].cores[0].thread_id = pthread_self(); pthread_mutex_init(&uwsgi.six_feet_under_lock, NULL); } -#endif uwsgi_ignition(); @@ -2944,7 +2881,6 @@ wait_for_call_of_duty: } } -#ifdef UWSGI_THREADING // create a pthread key, storing per-thread wsgi_request structure if (uwsgi.threads > 1) { if (pthread_key_create(&uwsgi.tur_key, NULL)) { @@ -2952,7 +2888,6 @@ wait_for_call_of_duty: exit(1); } } -#endif if (uwsgi.loop) { @@ -2971,11 +2906,9 @@ wait_for_call_of_duty: if (uwsgi.async < 2) { simple_loop(); } -#ifdef UWSGI_ASYNC else { async_loop(); } -#endif } if (uwsgi.snapshot) { @@ -3114,33 +3047,6 @@ void build_options() { } } -void uwsgi_stdin_sendto(char *socket_name, uint8_t modifier1, uint8_t modifier2) { - - char buf[4096]; - ssize_t rlen; - size_t delta = 4096 - 4; - // leave space for uwsgi header - char *ptr = buf + 4; - - rlen = read(0, ptr, delta); - while (rlen > 0) { -#ifdef UWSGI_DEBUG - uwsgi_log("%.*s\n", rlen, ptr); -#endif - ptr += rlen; - delta -= rlen; - if (delta == 0) - break; - rlen = read(0, ptr, delta); - } - - if (ptr > buf + 4) { - send_udp_message(modifier1, modifier2, socket_name, buf, (ptr - buf) - 4); - uwsgi_log("sent string \"%.*s\" to cluster node %s\n", (ptr - buf) - 4, buf + 4, socket_name); - } - -} - /* this function build the help output from the uwsgi.options structure @@ -3287,16 +3193,6 @@ void uwsgi_opt_true(char *opt, char *value, void *key) { } } -void uwsgi_opt_cluster_reload(char *opt, char *value, void *foobar) { - send_udp_message(98, 0, value, NULL, 0); - exit(0); -} - -void uwsgi_opt_cluster_log(char *opt, char *value, void *foobar) { - uwsgi_stdin_sendto(value, 96, 0); - exit(0); -} - void uwsgi_opt_set_int(char *opt, char *value, void *key) { int *ptr = (int *) key; if (value) { @@ -3334,6 +3230,18 @@ void uwsgi_opt_set_64bit(char *opt, char *value, void *key) { } } +void uwsgi_opt_set_16bit(char *opt, char *value, void *key) { + uint16_t *ptr = (uint16_t *) key; + + if (value) { + *ptr = (strtoul(value, NULL, 10)); + } + else { + *ptr = 1; + } +} + + void uwsgi_opt_set_megabytes(char *opt, char *value, void *key) { uint64_t *ptr = (uint64_t *) key; *ptr = (strtoul(value, NULL, 10)) * 1024 * 1024; @@ -3408,7 +3316,7 @@ void uwsgi_opt_add_string_list(char *opt, char *value, void *list) { void uwsgi_opt_add_addr_list(char *opt, char *value, void *list) { struct uwsgi_string_list **ptr = (struct uwsgi_string_list **) list; int af = AF_INET; -#ifdef UWSGI_IPV6 +#ifdef AF_INET6 void *ip = uwsgi_malloc(16); if (strchr(value, ':')) { af = AF_INET6; diff --git a/core/websockets.c b/core/websockets.c index e6635f09..15c950f6 100644 --- a/core/websockets.c +++ b/core/websockets.c @@ -34,10 +34,9 @@ error: } int uwsgi_websockets_ping(struct wsgi_request *wsgi_req) { - ssize_t len = uwsgi.websockets_hook_send(wsgi_req, uwsgi.websockets_ping); - if (len <= 0) { - return -1; - } + if (uwsgi_response_write_body_do(wsgi_req, uwsgi.websockets_ping->buf, uwsgi.websockets_ping->pos)) { + return -1; + } wsgi_req->websocket_last_ping = uwsgi_now(); return 0; } @@ -60,32 +59,25 @@ int uwsgi_websockets_pong(struct wsgi_request *wsgi_req) { } } } - ssize_t len = uwsgi.websockets_hook_send(wsgi_req, uwsgi.websockets_pong); - if (len <= 0) { - return -1; - } - return 0; + return uwsgi_response_write_body_do(wsgi_req, uwsgi.websockets_pong->buf, uwsgi.websockets_pong->pos); } -ssize_t uwsgi_websocket_send_do(struct wsgi_request *wsgi_req, char *msg, size_t len) { +int uwsgi_websocket_send_do(struct wsgi_request *wsgi_req, char *msg, size_t len) { struct uwsgi_buffer *ub = uwsgi_websocket_message(msg, len); if (!ub) return -1; - ssize_t ret = uwsgi.websockets_hook_send(wsgi_req, ub); + ssize_t ret = uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos); uwsgi_buffer_destroy(ub); - if (ret > 0) { - wsgi_req->response_size += ret; - } return ret; } -ssize_t uwsgi_websocket_send(struct wsgi_request *wsgi_req, char *msg, size_t len) { +int uwsgi_websocket_send(struct wsgi_request *wsgi_req, char *msg, size_t len) { if (wsgi_req->websocket_closed) { return -1; } ssize_t ret = uwsgi_websocket_send_do(wsgi_req, msg, len); - if (ret <= 0) { + if (ret < 0) { wsgi_req->websocket_closed = 1; } return ret; @@ -123,14 +115,49 @@ error: } +ssize_t uwsgi_websockets_recv_pkt(struct wsgi_request *wsgi_req) { + + int ret = -1; + + for(;;) { + ssize_t rlen = wsgi_req->socket->proto_read_body(wsgi_req, wsgi_req->websocket_buf->buf + wsgi_req->websocket_buf->pos, wsgi_req->websocket_buf->len - wsgi_req->websocket_buf->pos); + if (rlen > 0) return rlen; + if (rlen == 0) return -1; + if (rlen < 0) { + if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) { + goto wait; + } + uwsgi_error("uwsgi_websockets_recv_pkt()"); + return -1; + } + +wait: + ret = uwsgi.wait_read_hook(wsgi_req->fd, uwsgi.websockets_pong_freq); + if (ret > 0) { + rlen = wsgi_req->socket->proto_read_body(wsgi_req, wsgi_req->websocket_buf->buf + wsgi_req->websocket_buf->pos, wsgi_req->websocket_buf->len - wsgi_req->websocket_buf->pos); + if (rlen > 0) return rlen; + if (rlen <= 0) return -1; + } + if (ret < 0) { + uwsgi_error("uwsgi_websockets_recv_pkt()"); + return -1; + } + // send unsolicited pong + if (uwsgi_websockets_pong(wsgi_req)) { + return -1; + } + } + + return -1; +} + + struct uwsgi_buffer *uwsgi_websocket_recv_do(struct wsgi_request *wsgi_req) { if (!wsgi_req->websocket_buf) { // this buffer will be destroyed on connection close wsgi_req->websocket_buf = uwsgi_buffer_new(uwsgi.page_size); // need 2 byte header wsgi_req->websocket_need = 2; - // set status code - wsgi_req->status = 101; } for(;;) { @@ -230,7 +257,7 @@ struct uwsgi_buffer *uwsgi_websocket_recv_do(struct wsgi_request *wsgi_req) { // need more data else { if (uwsgi_buffer_ensure(wsgi_req->websocket_buf, uwsgi.page_size)) return NULL; - ssize_t len = uwsgi.websockets_hook_recv(wsgi_req); + ssize_t len = uwsgi_websockets_recv_pkt(wsgi_req); if (len <= 0) { return NULL; } @@ -262,128 +289,31 @@ ssize_t uwsgi_websockets_simple_send(struct wsgi_request *wsgi_req, struct uwsgi return len; } -ssize_t uwsgi_websockets_simple_recv(struct wsgi_request *wsgi_req) { - int ret = -1; - int fd = wsgi_req->poll.fd; - - int count = 0; - struct uwsgi_channel *channel = uwsgi.channels; - while(channel) { - int pos = (uwsgi.cores * (uwsgi.mywid - 1)) + wsgi_req->async_id; - if (channel->subscriptions[pos] == 2) { - count++; - } - channel = channel->next; - } - - struct pollfd *pfd = uwsgi_calloc(sizeof(struct pollfd) * (count+1)); - pfd[0].fd = fd; - pfd[0].events = POLLIN; - channel = uwsgi.channels; - count = 1; - while(channel) { - int pos = (uwsgi.cores * (uwsgi.mywid - 1)) + wsgi_req->async_id; - if (channel->subscriptions[pos] == 2) { - pfd[count].fd = channel->fd[(pos*2)+1]; - pfd[count].events = POLLIN; - count++; - } - channel = channel->next; - } - -retry: - ret = poll(pfd, count, uwsgi.websockets_pong_freq * 1000); - if (ret < 0) { - uwsgi_error("uwsgi_websockets_simple_recv()/poll()"); - free(pfd); - return -1; - } - - // send ping - if (ret == 0) { - //unsolicited pong - if (uwsgi_websockets_pong(wsgi_req)) { - free(pfd); - return -1; - } - goto retry; - } - - int i; - for(i=0;iwebsocket_buf->buf + wsgi_req->websocket_buf->pos, wsgi_req->websocket_buf->len - wsgi_req->websocket_buf->pos); - if (len <= 0) { - uwsgi_error("[uwsgi-websocket] uwsgi_websockets_simple_recv()/read()"); - } - free(pfd); - return len; - } - else { - channel = uwsgi.channels; - while(channel) { - int pos = (uwsgi.cores * (uwsgi.mywid - 1)) + wsgi_req->async_id; - int cfd = channel->fd[(pos*2)+1]; - if (cfd == pfd[i].fd) { - struct uwsgi_buffer *ub = uwsgi_buffer_new(channel->max_packet_size); - ssize_t len = read(pfd[i].fd, ub->buf, ub->len); - if (len <= 0) { - uwsgi_buffer_destroy(ub); - uwsgi_error("[uwsgi-websocket] uwsgi_websockets_simple_recv()/read()"); - free(pfd); - return -1; - } - ub->pos += len; - if (uwsgi_websocket_send(wsgi_req, ub->buf, ub->pos) <= 0) { - uwsgi_buffer_destroy(ub); - free(pfd); - return -1; - } - uwsgi_buffer_destroy(ub); - break; - } - channel = channel->next; - } - goto retry; - } - } - } - - free(pfd); - return -1; -} - int uwsgi_websocket_handshake(struct wsgi_request *wsgi_req, char *key, uint16_t key_len, char *origin, uint16_t origin_len) { #ifdef UWSGI_SSL char sha1[20]; - struct uwsgi_buffer *ub = uwsgi_buffer_new(uwsgi.page_size); - if (uwsgi_buffer_append(ub, "HTTP/1.1 101 Web Socket Protocol Handshake\r\n", 44)) goto end; - if (uwsgi_buffer_append(ub, "Upgrade: WebSocket\r\n", 20)) goto end; - if (uwsgi_buffer_append(ub, "Connection: Upgrade\r\n", 21)) goto end; - if (uwsgi_buffer_append(ub, "Sec-WebSocket-Origin: ", 22)) goto end; + if (uwsgi_response_prepare_headers(wsgi_req, "101 Web Socket Protocol Handshake", 33)) return -1; + if (uwsgi_response_add_header(wsgi_req, "Upgrade", 7, "WebSocket", 9)) return -1; + if (uwsgi_response_add_header(wsgi_req, "Connection", 10, "Upgrade", 7)) return -1; if (origin_len > 0) { - if (uwsgi_buffer_append(ub, origin, origin_len)) goto end; + if (uwsgi_response_add_header(wsgi_req, "Sec-WebSocket-Origin", 20, origin, origin_len)) return -1; } else { - if (uwsgi_buffer_append(ub, "*", 1)) goto end; + if (uwsgi_response_add_header(wsgi_req, "Sec-WebSocket-Origin", 20, "*", 1)) return -1; } - if (uwsgi_buffer_append(ub, "\r\nSec-WebSocket-Accept: ", 24)) goto end; - if (!uwsgi_sha1_2n(key, key_len, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", 36, sha1)) goto end; - if (uwsgi_buffer_append_base64(ub, sha1, 20)) goto end; - if (uwsgi_buffer_append(ub, "\r\n\r\n", 4)) goto end; + // generate websockets sha1 and encode it to base64 + if (!uwsgi_sha1_2n(key, key_len, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", 36, sha1)) return -1; + size_t b64_len = 0; + char *b64 = uwsgi_base64_encode(sha1, 20, &b64_len); + if (!b64) return -1; - ssize_t len = uwsgi.buffer_write_hook(wsgi_req, ub); - if (len <= 0) { - goto end; + if (uwsgi_response_add_header(wsgi_req, "Sec-WebSocket-Accept", 20, b64, b64_len)) { + free(b64); + return -1; } - wsgi_req->headers_size += len; - wsgi_req->header_cnt += 4; - uwsgi_buffer_destroy(ub); - return 0; -end: - uwsgi_buffer_destroy(ub); - return -1; + free(b64); + + return uwsgi_response_write_headers_do(wsgi_req); #else uwsgi_log("you need to build uWSGI with SSL support to use the websocket handshake api function !!!\n"); return -1; @@ -391,8 +321,6 @@ end: } void uwsgi_websockets_init() { - uwsgi.websockets_hook_send = uwsgi_websockets_simple_send; - uwsgi.websockets_hook_recv = uwsgi_websockets_simple_recv; uwsgi.websockets_pong = uwsgi_buffer_new(2); uwsgi_buffer_append(uwsgi.websockets_pong, "\x8A\0", 2); uwsgi.websockets_ping = uwsgi_buffer_new(2); diff --git a/core/writer.c b/core/writer.c index e5443b8a..f54aeff4 100644 --- a/core/writer.c +++ b/core/writer.c @@ -124,10 +124,13 @@ int uwsgi_response_write_headers_do(struct wsgi_request *wsgi_req) { if (ret == UWSGI_OK) { break; } - ret = uwsgi.wait_write_hook(wsgi_req); + ret = uwsgi_wait_write_req(wsgi_req); if (ret < 0) { wsgi_req->write_errors++; return -1;} - // callback based hook... - if (ret == UWSGI_AGAIN) return UWSGI_AGAIN; + if (ret == 0) { + uwsgi_log("uwsgi_response_write_headers_do() TIMEOUT !!!\n"); + wsgi_req->write_errors++; + return -1; + } } wsgi_req->headers_size += wsgi_req->write_pos; @@ -166,10 +169,13 @@ sendbody: if (ret == UWSGI_OK) { break; } - ret = uwsgi.wait_write_hook(wsgi_req); + ret = uwsgi_wait_write_req(wsgi_req); if (ret < 0) { wsgi_req->write_errors++; return -1;} - // callback based hook... - if (ret == UWSGI_AGAIN) return UWSGI_AGAIN; + if (ret == 0) { + uwsgi_log("uwsgi_response_write_body_do() TIMEOUT !!!\n"); + wsgi_req->write_errors++; + return -1; + } } wsgi_req->response_size += wsgi_req->write_pos; @@ -248,7 +254,7 @@ sendfile: if (ret == UWSGI_OK) { break; } - ret = uwsgi.wait_write_hook(wsgi_req); + ret = uwsgi_wait_write_req(wsgi_req); if (ret < 0) { wsgi_req->write_errors++; if (can_close) close(fd); @@ -267,8 +273,6 @@ sendfile: } -int uwsgi_simple_wait_write_hook(struct wsgi_request *wsgi_req) { - int ret = uwsgi_waitfd_write(wsgi_req->poll.fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); - if (ret <= 0) return -1; - return UWSGI_OK; +int uwsgi_simple_wait_write_hook(int fd, int timeout) { + return uwsgi_waitfd_write(fd, timeout); } diff --git a/plugins/cache/cache.c b/plugins/cache/cache.c index c6e70f8d..9a8f48b4 100644 --- a/plugins/cache/cache.c +++ b/plugins/cache/cache.c @@ -39,13 +39,13 @@ int uwsgi_cache_request(struct wsgi_request *wsgi_req) { uint16_t argvs[3]; uint8_t argc = 0; - switch(wsgi_req->uh.modifier2) { + switch(wsgi_req->uh->modifier2) { case 0: // get - if (wsgi_req->uh.pktsize > 0) { - value = uwsgi_cache_get(wsgi_req->buffer, wsgi_req->uh.pktsize, &vallen); + if (wsgi_req->uh->pktsize > 0) { + value = uwsgi_cache_get(wsgi_req->buffer, wsgi_req->uh->pktsize, &vallen); if (value && vallen > 0) { - wsgi_req->uh.pktsize = vallen; + wsgi_req->uh->pktsize = vallen; if (uwsgi_response_write_body_do(wsgi_req, (char *)&wsgi_req->uh, 4)) return -1; uwsgi_response_write_body_do(wsgi_req, value, vallen); } @@ -53,9 +53,9 @@ int uwsgi_cache_request(struct wsgi_request *wsgi_req) { break; case 1: // set - if (wsgi_req->uh.pktsize > 0) { + if (wsgi_req->uh->pktsize > 0) { argc = 3; - if (!uwsgi_parse_array(wsgi_req->buffer, wsgi_req->uh.pktsize, argv, argvs, &argc)) { + if (!uwsgi_parse_array(wsgi_req->buffer, wsgi_req->uh->pktsize, argv, argvs, &argc)) { if (argc > 1) { uwsgi_cache_set(argv[0], argvs[0], argv[1], argvs[1], 0, 0); } @@ -64,37 +64,37 @@ int uwsgi_cache_request(struct wsgi_request *wsgi_req) { break; case 2: // del - if (wsgi_req->uh.pktsize > 0) { - uwsgi_cache_del(wsgi_req->buffer, wsgi_req->uh.pktsize, 0, 0); + if (wsgi_req->uh->pktsize > 0) { + uwsgi_cache_del(wsgi_req->buffer, wsgi_req->uh->pktsize, 0, 0); } break; case 3: case 4: // dict - if (wsgi_req->uh.pktsize > 0) { - uwsgi_hooked_parse(wsgi_req->buffer, wsgi_req->uh.pktsize, cache_command, (void *) wsgi_req); + if (wsgi_req->uh->pktsize > 0) { + uwsgi_hooked_parse(wsgi_req->buffer, wsgi_req->uh->pktsize, cache_command, (void *) wsgi_req); } break; case 5: // get (uwsgi + stream) - if (wsgi_req->uh.pktsize > 0) { - value = uwsgi_cache_get(wsgi_req->buffer, wsgi_req->uh.pktsize, &vallen); + if (wsgi_req->uh->pktsize > 0) { + value = uwsgi_cache_get(wsgi_req->buffer, wsgi_req->uh->pktsize, &vallen); if (value && vallen > 0) { - wsgi_req->uh.pktsize = 0; - wsgi_req->uh.modifier2 = 1; + wsgi_req->uh->pktsize = 0; + wsgi_req->uh->modifier2 = 1; if (uwsgi_response_write_body_do(wsgi_req, (char *)&wsgi_req->uh, 4)) return -1; uwsgi_response_write_body_do(wsgi_req, value, vallen); } else { - wsgi_req->uh.pktsize = 0; - wsgi_req->uh.modifier2 = 0; + wsgi_req->uh->pktsize = 0; + wsgi_req->uh->modifier2 = 0; if (uwsgi_response_write_body_do(wsgi_req, (char *)&wsgi_req->uh, 4)) return -1; } } break; case 6: // dump - wsgi_req->uh.modifier2 = 7; + wsgi_req->uh->modifier2 = 7; struct uwsgi_buffer *cache_dump = uwsgi_buffer_new(4096); if (uwsgi_buffer_append_keynum(cache_dump, "items", 5, uwsgi.cache_max_items)) { uwsgi_buffer_destroy(cache_dump); @@ -105,7 +105,7 @@ int uwsgi_cache_request(struct wsgi_request *wsgi_req) { break; } - wsgi_req->uh.pktsize = cache_dump->pos; + wsgi_req->uh->pktsize = cache_dump->pos; if (uwsgi_response_write_body_do(wsgi_req, (char *)&wsgi_req->uh, 4)) { uwsgi_buffer_destroy(cache_dump); return -1; @@ -113,7 +113,7 @@ int uwsgi_cache_request(struct wsgi_request *wsgi_req) { uwsgi_response_write_body_do(wsgi_req, cache_dump->buf, cache_dump->pos); uwsgi_buffer_destroy(cache_dump); uwsgi_wlock(uwsgi.caches->lock); - int ret = uwsgi_write_nb(wsgi_req->poll.fd, (char *)uwsgi.caches->items, uwsgi.caches->filesize, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); + int ret = uwsgi_write_nb(wsgi_req->fd, (char *)uwsgi.caches->items, uwsgi.caches->filesize, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); if (!ret) { wsgi_req->response_size += uwsgi.caches->filesize; } diff --git a/plugins/corerouter/corerouter.c b/plugins/corerouter/corerouter.c index 3271d6e0..b52c4374 100644 --- a/plugins/corerouter/corerouter.c +++ b/plugins/corerouter/corerouter.c @@ -692,10 +692,6 @@ void uwsgi_corerouter_loop(int id, void *data) { else if (ucr->static_nodes) { ucr->mapper = uwsgi_cr_map_use_static_nodes; } - else if (ucr->use_cluster) { - ucr->mapper = uwsgi_cr_map_use_cluster; - } - ucr->timeouts = uwsgi_init_rb_timer(); @@ -853,8 +849,7 @@ int uwsgi_corerouter_has_backends(struct uwsgi_corerouter *ucr) { ucr->base || (ucr->code_string_code && ucr->code_string_function) || ucr->to_socket || - ucr->static_nodes || - ucr->use_cluster + ucr->static_nodes ) { return 1; } diff --git a/plugins/corerouter/cr.h b/plugins/corerouter/cr.h index da0026b5..37fd267d 100644 --- a/plugins/corerouter/cr.h +++ b/plugins/corerouter/cr.h @@ -231,8 +231,6 @@ struct uwsgi_corerouter { int socket_num; struct uwsgi_socket *to_socket; - int use_cluster; - struct uwsgi_subscribe_slot **subscriptions; struct uwsgi_string_list *fallback; diff --git a/plugins/corerouter/cr_common.c b/plugins/corerouter/cr_common.c index d4ab8824..fb8c65c3 100644 --- a/plugins/corerouter/cr_common.c +++ b/plugins/corerouter/cr_common.c @@ -75,12 +75,7 @@ void uwsgi_corerouter_setup_sockets(struct uwsgi_corerouter *ucr) { else if (ugs->subscription) { if (ugs->fd == -1) { if (strchr(ugs->name, ':')) { -#ifdef UWSGI_UDP ugs->fd = bind_to_udp(ugs->name, 0, 0); -#else - uwsgi_log("uWSGI has been built without UDP support !!!\n"); - exit(1); -#endif } else { ugs->fd = bind_to_unix_dgram(ugs->name); diff --git a/plugins/corerouter/cr_map.c b/plugins/corerouter/cr_map.c index 471aabae..28877bca 100644 --- a/plugins/corerouter/cr_map.c +++ b/plugins/corerouter/cr_map.c @@ -113,19 +113,6 @@ int uwsgi_cr_map_use_to(struct uwsgi_corerouter *ucr, struct corerouter_peer *pe return 0; } -int uwsgi_cr_map_use_cluster(struct uwsgi_corerouter *ucr, struct corerouter_peer *peer) { -#ifdef UWSGI_MULTICAST - peer->instance_address = uwsgi_cluster_best_node(); - if (peer->instance_address) { - peer->instance_address_len = strlen(peer->instance_address); - } -#else - uwsgi_log("uWSGI has been built without multicast/clustering support !!!\n"); -#endif - return 0; -} - - int uwsgi_cr_map_use_static_nodes(struct uwsgi_corerouter *ucr, struct corerouter_peer *peer) { if (!ucr->current_static_node) { ucr->current_static_node = ucr->static_nodes; diff --git a/plugins/dumbloop/dumb.c b/plugins/dumbloop/dumb.c index 204e4b27..b88fcc2e 100644 --- a/plugins/dumbloop/dumb.c +++ b/plugins/dumbloop/dumb.c @@ -22,7 +22,6 @@ static void *dumb_loop_run(void *arg1) { // get the core id (pthreads take a void pointer as argument, so we need this ugly trick) long core_id = (long) arg1; -#ifdef UWSGI_THREADING // complete threads setup (this is required for fixing things like UNIX signal handling) if (uwsgi.threads > 1) { // wsgi_request mapped to the core @@ -30,7 +29,6 @@ static void *dumb_loop_run(void *arg1) { // fix it uwsgi_setup_thread_req(core_id, wsgi_req); } -#endif // this strign will be passed to the code_string function char *str_core = uwsgi_num2str(core_id); diff --git a/plugins/fastrouter/fastrouter.c b/plugins/fastrouter/fastrouter.c index 2664d43d..16ee2925 100644 --- a/plugins/fastrouter/fastrouter.c +++ b/plugins/fastrouter/fastrouter.c @@ -30,8 +30,6 @@ static struct uwsgi_option fastrouter_options[] = { {"fastrouter-fallback", required_argument, 0, "fallback to the specified node in case of error", uwsgi_opt_add_string_list, &ufr.cr.fallback, 0}, - {"fastrouter-use-cluster", no_argument, 0, "load balance to nodes subscribed to the cluster", uwsgi_opt_true, &ufr.cr.use_cluster, 0}, - {"fastrouter-use-code-string", required_argument, 0, "use code string as hostname->server mapper for the fastrouter", uwsgi_opt_corerouter_cs, &ufr, 0}, {"fastrouter-use-socket", optional_argument, 0, "forward request to the specified uwsgi socket", uwsgi_opt_corerouter_use_socket, &ufr, 0}, {"fastrouter-to", required_argument, 0, "forward requests to the specified uwsgi server (you can specify it multiple times for load balancing)", uwsgi_opt_add_string_list, &ufr.cr.static_nodes, 0}, diff --git a/plugins/gevent/gevent.c b/plugins/gevent/gevent.c index 70d82d00..ae37b081 100644 --- a/plugins/gevent/gevent.c +++ b/plugins/gevent/gevent.c @@ -145,7 +145,7 @@ edge: set_harakiri(uwsgi.shared->options[UWSGI_OPTION_HARAKIRI]); } - // accept the connection (since uWSGI 1.5 all of teh sockets are non-blocking) + // accept the connection (since uWSGI 1.5 all of the sockets are non-blocking) if (wsgi_req_simple_accept(wsgi_req, uwsgi_sock->fd)) { free_req_queue; if (uwsgi_sock->retry && uwsgi_sock->retry[wsgi_req->async_id]) { @@ -173,489 +173,6 @@ clear: return Py_None; } -ssize_t uwsgi_gevent_hook_input_read(struct wsgi_request *wsgi_req, char *tmp_buf, size_t remains, size_t *tmp_pos) { - - /// create a watcher for reads - PyObject *watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", wsgi_req->poll.fd, 1); - if (!watcher) return -1; - - PyObject *timer = PyObject_CallMethod(ugevent.hub_loop, "timer", "i", uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); - if (!timer) { - Py_DECREF(watcher); - return -1; - } - - PyObject *current_greenlet = GET_CURRENT_GREENLET; - PyObject *current = PyObject_GetAttrString(current_greenlet, "switch"); - - while(remains) { - - PyObject *ret = PyObject_CallMethod(watcher, "start", "OO", current, watcher); - if (!ret) { - stop_the_watchers_and_clear - return -1; - } - Py_DECREF(ret); - - ret = PyObject_CallMethod(timer, "start", "OO", current, timer); - if (!ret) { - stop_the_watchers_and_clear - return -1; - } - Py_DECREF(ret); - - ret = PyObject_CallMethod(ugevent.hub, "switch", NULL); - wsgi_req->switches++; - if (!ret) { - stop_the_watchers_and_clear - return -1; - } - Py_DECREF(ret); - - if (ret == timer) { - stop_the_watchers_and_clear - return 0; - } - - UWSGI_RELEASE_GIL; - ssize_t rlen = read(wsgi_req->poll.fd, tmp_buf+*tmp_pos, remains); - if (rlen <= 0) { - if (rlen < 0) - uwsgi_error("[uwsgi-gevent] read()"); - UWSGI_GET_GIL - stop_the_watchers_and_clear - return -1; - } - *tmp_pos += rlen; - remains -= rlen; - UWSGI_GET_GIL - stop_the_watchers - } - - Py_DECREF(current); - Py_DECREF(current_greenlet); - Py_DECREF(watcher); - Py_DECREF(timer); - - return *tmp_pos; - -} - - -ssize_t uwsgi_gevent_hook_input_readline(struct wsgi_request *wsgi_req, char *readline, size_t max_size) { - ssize_t rlen = 0; - - /// create a watcher for reads - PyObject *watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", wsgi_req->poll.fd, 1); - if (!watcher) return -1; - - PyObject *timer = PyObject_CallMethod(ugevent.hub_loop, "timer", "i", uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); - if (!timer) { - Py_DECREF(watcher); - return -1; - } - - PyObject *current_greenlet = GET_CURRENT_GREENLET; - PyObject *current = PyObject_GetAttrString(current_greenlet, "switch"); - - PyObject *ret = PyObject_CallMethod(watcher, "start", "OO", current, watcher); - if (!ret) { - stop_the_watchers_and_clear - return -1; - } - Py_DECREF(ret); - - ret = PyObject_CallMethod(timer, "start", "OO", current, timer); - if (!ret) { - stop_the_watchers_and_clear - return -1; - } - Py_DECREF(ret); - - ret = PyObject_CallMethod(ugevent.hub, "switch", NULL); - wsgi_req->switches++; - if (!ret) { - stop_the_watchers_and_clear - return -1; - } - Py_DECREF(ret); - - if (ret == timer) { - stop_the_watchers_and_clear - return 0; - } - - UWSGI_RELEASE_GIL; - if (max_size > 0 && max_size < UWSGI_PY_READLINE_BUFSIZE) { - rlen = read(wsgi_req->poll.fd, readline, max_size); - } - else { - rlen = read(wsgi_req->poll.fd, readline, UWSGI_PY_READLINE_BUFSIZE); - } - UWSGI_GET_GIL; - stop_the_watchers_and_clear - return rlen; -} - -ssize_t uwsgi_websockets_gevent_recv(struct wsgi_request *wsgi_req) { - - /// create a watcher for reads - PyObject *watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", wsgi_req->poll.fd, 1); - if (!watcher) return -1; - - PyObject *timer = PyObject_CallMethod(ugevent.hub_loop, "timer", "i", uwsgi.websockets_pong_freq); - if (!timer) { - Py_DECREF(watcher); - return -1; - } - - int count = 0; - struct uwsgi_channel *channel = uwsgi.channels; - while(channel) { - int pos = (uwsgi.cores * (uwsgi.mywid - 1)) + wsgi_req->async_id; - if (channel->subscriptions[pos] == 2) { - count++; - } - channel = channel->next; - } - - - PyObject *current_greenlet = GET_CURRENT_GREENLET; - PyObject *current = PyObject_GetAttrString(current_greenlet, "switch"); - - PyObject **c_watchers = NULL; - if (count > 0) { - c_watchers = uwsgi_calloc(sizeof(PyObject *) * count); - count = 0; - channel = uwsgi.channels; - while(channel) { - int pos = (uwsgi.cores * (uwsgi.mywid - 1)) + wsgi_req->async_id; - if (channel->subscriptions[pos] == 2) { - c_watchers[count] = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", channel->fd[(pos*2)+1], 1); - if (!c_watchers[count]) { - PyObject *ret; - stop_the_c_watchers - stop_the_watchers_and_clear - return -1; - } - count++; - } - channel = channel->next; - } - } - - for(;;) { - - PyObject *ret = PyObject_CallMethod(watcher, "start", "OO", current, watcher); - if (!ret) { - stop_the_c_watchers - stop_the_watchers_and_clear - return -1; - } - Py_DECREF(ret); - - ret = PyObject_CallMethod(timer, "start", "OO", current, timer); - if (!ret) { - stop_the_c_watchers - stop_the_watchers_and_clear - return -1; - } - Py_DECREF(ret); - - if (c_watchers) { - int j; - for(j=0;jswitches++; - if (!ret) { - stop_the_c_watchers - stop_the_watchers_and_clear - return -1; - } - Py_DECREF(ret); - - if (ret == timer) { - stop_the_watchers; - // destroy the old timer - Py_DECREF(timer); - //unsolicited pong - if (uwsgi_websockets_pong(wsgi_req)) { - stop_the_c_watchers - stop_the_io_and_clear; - return -1; - } - // create a new timer - timer = PyObject_CallMethod(ugevent.hub_loop, "timer", "i", uwsgi.websockets_pong_freq); - if (!timer) { - stop_the_c_watchers - stop_the_io_and_clear; - return -1; - } - continue; - } - - if (ret == watcher) { - ssize_t len = read(wsgi_req->poll.fd, wsgi_req->websocket_buf->buf + wsgi_req->websocket_buf->pos, wsgi_req->websocket_buf->len - wsgi_req->websocket_buf->pos); - if (len <= 0) - uwsgi_error("[uwsgi-websocket] uwsgi_websockets_gevent_recv()/read()"); - stop_the_c_watchers - stop_the_watchers_and_clear - return len; - } - - - channel = uwsgi.channels; - int c_pos = 0; - while(channel) { - if (ret == c_watchers[c_pos]) { - - int pos = (uwsgi.cores * (uwsgi.mywid - 1)) + wsgi_req->async_id; - int cfd = channel->fd[(pos*2)+1]; - struct uwsgi_buffer *ub = uwsgi_buffer_new(channel->max_packet_size); - ssize_t len = read(cfd, ub->buf, ub->len); - if (len <= 0) { - uwsgi_buffer_destroy(ub); - uwsgi_error("[uwsgi-websocket] uwsgi_websockets_gevent_recv()/read()"); - stop_the_c_watchers - stop_the_watchers_and_clear - return -1; - } - ub->pos += len; - if (uwsgi_websocket_send(wsgi_req, ub->buf, ub->pos) <= 0) { - uwsgi_buffer_destroy(ub); - stop_the_c_watchers - stop_the_watchers_and_clear - return -1; - } - uwsgi_buffer_destroy(ub); - break; - - } - c_pos++; - channel = channel->next; - } - } - - return -1; - -} - -// not gil as it is called by api -struct uwsgi_buffer *uwsgi_channel_gevent_recv(struct wsgi_request *wsgi_req, int fd, struct uwsgi_buffer *ub, int timeout) { - - /// create a watcher for reads - PyObject *watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", fd, 1); - if (!watcher) return NULL; - - PyObject *timer = NULL; - - - if (timeout > 0) { - PyObject *timer = PyObject_CallMethod(ugevent.hub_loop, "timer", "i", timeout); - if (!timer) { - Py_DECREF(watcher); - return NULL; - } - } - - PyObject *current_greenlet = GET_CURRENT_GREENLET; - PyObject *current = PyObject_GetAttrString(current_greenlet, "switch"); - - - PyObject *ret = PyObject_CallMethod(watcher, "start", "OO", current, watcher); - if (!ret) { - stop_the_watchers_and_clear - return NULL; - } - Py_DECREF(ret); - - if (timer) { - ret = PyObject_CallMethod(timer, "start", "OO", current, timer); - if (!ret) { - stop_the_watchers_and_clear - return NULL; - } - Py_DECREF(ret); - } - - ret = PyObject_CallMethod(ugevent.hub, "switch", NULL); - wsgi_req->switches++; - if (!ret) { - stop_the_watchers_and_clear - return NULL; - } - Py_DECREF(ret); - - if (timer && ret == timer) { - stop_the_watchers_and_clear - return ub; - } - - ssize_t len = read(fd, ub->buf, ub->len); - stop_the_watchers_and_clear - if (len <= 0) return NULL; - ub->pos += len; - return ub; -} - - - -// no gil -ssize_t uwsgi_websockets_gevent_send(struct wsgi_request *wsgi_req, struct uwsgi_buffer *ub) { - - PyObject *ret = NULL; - - char *content = ub->buf; - size_t content_len = ub->pos; - - // do not try to write empty chunks (returns 1 for making all happy...) - if (content_len == 0) return 1; - - /// create a watcher for writes - PyObject *watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", wsgi_req->poll.fd, 2); - if (!watcher) goto error; - - PyObject *current_greenlet = GET_CURRENT_GREENLET; - PyObject *current = PyObject_GetAttrString(current_greenlet, "switch"); - - char *ptr = content; - size_t remains = content_len; - - // this is the main writing cycle, wait for writability and send... - for(;;) { - ret = PyObject_CallMethod(watcher, "start", "OO", current, watcher); - if (!ret) { - stop_the_io_and_clear - goto error; - } - Py_DECREF(ret); - - ret = PyObject_CallMethod(ugevent.hub, "switch", NULL); - wsgi_req->switches++; - if (!ret) { - stop_the_io_and_clear - goto error; - } - Py_DECREF(ret); - - // ok we can write a chunk to the socket - ssize_t len = write(wsgi_req->poll.fd, ptr, remains); - if (len > 0) { - ptr += len; - remains -= len; - wsgi_req->response_size += len; - if (remains == 0) { - break; - } - stop_the_io - continue; - } - else if (len < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) { - stop_the_io - continue; - } - } - - stop_the_io_and_clear - goto error; - } - - stop_the_io - Py_DECREF(current); Py_DECREF(current_greenlet); - Py_DECREF(watcher); - return 1; - -error: - if (PyErr_Occurred()) - PyErr_Print(); - wsgi_req->write_errors++; - return -1; -} - -//no gil -ssize_t uwsgi_buffer_gevent_write(struct wsgi_request *wsgi_req, struct uwsgi_buffer *ub) { - - PyObject *ret = NULL; - - char *content = ub->buf; - size_t content_len = ub->pos; - - // do not try to write empty chunks (returns 1 for making all happy...) - if (content_len == 0) return 1; - - /// create a watcher for writes - PyObject *watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", wsgi_req->poll.fd, 2); - if (!watcher) goto error; - - PyObject *current_greenlet = GET_CURRENT_GREENLET; - PyObject *current = PyObject_GetAttrString(current_greenlet, "switch"); - - char *ptr = content; - size_t remains = content_len; - - // this is the main writing cycle, wait for writability and send... - for(;;) { - ret = PyObject_CallMethod(watcher, "start", "OO", current, watcher); - if (!ret) { - stop_the_io_and_clear - goto error; - } - Py_DECREF(ret); - - ret = PyObject_CallMethod(ugevent.hub, "switch", NULL); - wsgi_req->switches++; - if (!ret) { - stop_the_io_and_clear - goto error; - } - Py_DECREF(ret); - - // ok we can write a chunk to the socket - ssize_t len = write(wsgi_req->poll.fd, ptr, remains); - if (len > 0) { - ptr += len; - remains -= len; - if (remains == 0) { - break; - } - stop_the_io - continue; - } - else if (len < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) { - stop_the_io - continue; - } - } - - stop_the_io_and_clear - goto error; - } - - stop_the_io - Py_DECREF(current); Py_DECREF(current_greenlet); - Py_DECREF(watcher); - return 1; - -error: - if (PyErr_Occurred()) - PyErr_Print(); - wsgi_req->write_errors++; - return -1; -} - PyObject *uwsgi_gevent_wait(PyObject *watcher, PyObject *timer, PyObject *current) { PyObject *ret; @@ -695,7 +212,7 @@ PyObject *py_uwsgi_gevent_request(PyObject * self, PyObject * args) { } // create a watcher for request socket - watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", wsgi_req->poll.fd, 1); + watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", wsgi_req->fd, 1); if (!watcher) goto clear1; // a timer to implement timeout (thanks Denis) @@ -736,7 +253,7 @@ PyObject *py_uwsgi_gevent_request(PyObject * self, PyObject * args) { request: for(;;) { - wsgi_req->async_status = uwsgi.p[wsgi_req->uh.modifier1]->request(wsgi_req); + wsgi_req->async_status = uwsgi.p[wsgi_req->uh->modifier1]->request(wsgi_req); if (wsgi_req->async_status <= UWSGI_OK) { goto clear; } @@ -802,14 +319,8 @@ static void gevent_loop() { up.gil_get = gil_gevent_get; up.gil_release = gil_gevent_release; - // change websockets hooks - uwsgi.websockets_hook_send = uwsgi_websockets_gevent_send; - uwsgi.websockets_hook_recv = uwsgi_websockets_gevent_recv; - // change channels hooks - uwsgi.channel_recv_hook = uwsgi_channel_gevent_recv; - // buffer write generic hook - uwsgi.buffer_write_hook = uwsgi_buffer_gevent_write; uwsgi.wait_write_hook = uwsgi_gevent_wait_write_hook; + uwsgi.wait_read_hook = uwsgi_gevent_wait_read_hook; struct uwsgi_socket *uwsgi_sock = uwsgi.sockets; @@ -819,8 +330,8 @@ static void gevent_loop() { } uwsgi.current_wsgi_req = uwsgi_gevent_current_wsgi_req; - up.hook_wsgi_input_read = uwsgi_gevent_hook_input_read; - up.hook_wsgi_input_readline = uwsgi_gevent_hook_input_readline; + //up.hook_wsgi_input_read = uwsgi_gevent_hook_input_read; + //up.hook_wsgi_input_readline = uwsgi_gevent_hook_input_readline; PyObject *gevent_dict = get_uwsgi_pydict("gevent"); if (!gevent_dict) uwsgi_pyexit; diff --git a/plugins/gevent/gevent.h b/plugins/gevent/gevent.h index 7da7b701..9fad52cc 100644 --- a/plugins/gevent/gevent.h +++ b/plugins/gevent/gevent.h @@ -1,6 +1,7 @@ #include "../python/uwsgi_python.h" -int uwsgi_gevent_wait_write_hook(struct wsgi_request *); +int uwsgi_gevent_wait_write_hook(int, int); +int uwsgi_gevent_wait_read_hook(int, int); #define GEVENT_SWITCH PyObject *gswitch = python_call(ugevent.greenlet_switch, ugevent.greenlet_switch_args, 0, NULL); Py_DECREF(gswitch) #define GET_CURRENT_GREENLET python_call(ugevent.get_current, ugevent.get_current_args, 0, NULL) diff --git a/plugins/gevent/hooks.c b/plugins/gevent/hooks.c index a6ed7e4b..1c213905 100644 --- a/plugins/gevent/hooks.c +++ b/plugins/gevent/hooks.c @@ -4,15 +4,15 @@ extern struct uwsgi_server uwsgi; extern struct uwsgi_gevent ugevent; -int uwsgi_gevent_wait_write_hook(struct wsgi_request *wsgi_req) { +int uwsgi_gevent_wait_write_hook(int fd, int timeout) { PyObject *ret = NULL; /// create a watcher for writes - PyObject *watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", wsgi_req->poll.fd, 2); + PyObject *watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", fd, 2); if (!watcher) return -1; - PyObject *timer = PyObject_CallMethod(ugevent.hub_loop, "timer", "i", uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); + PyObject *timer = PyObject_CallMethod(ugevent.hub_loop, "timer", "i", timeout); if (!timer) { Py_DECREF(watcher); return -1; @@ -36,7 +36,6 @@ int uwsgi_gevent_wait_write_hook(struct wsgi_request *wsgi_req) { Py_DECREF(ret); ret = PyObject_CallMethod(ugevent.hub, "switch", NULL); - wsgi_req->switches++; if (!ret) { stop_the_watchers_and_clear return -1; @@ -45,10 +44,57 @@ int uwsgi_gevent_wait_write_hook(struct wsgi_request *wsgi_req) { if (ret == timer) { stop_the_watchers_and_clear; - return -1; + return 0; } stop_the_watchers_and_clear; - return 0; + return 1; +} + +int uwsgi_gevent_wait_read_hook(int fd, int timeout) { + + PyObject *ret = NULL; + + /// create a watcher for writes + PyObject *watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", fd, 1); + if (!watcher) return -1; + + PyObject *timer = PyObject_CallMethod(ugevent.hub_loop, "timer", "i", timeout); + if (!timer) { + Py_DECREF(watcher); + return -1; + } + + PyObject *current_greenlet = GET_CURRENT_GREENLET; + PyObject *current = PyObject_GetAttrString(current_greenlet, "switch"); + + ret = PyObject_CallMethod(watcher, "start", "OO", current, watcher); + if (!ret) { + stop_the_watchers_and_clear + return -1; + } + Py_DECREF(ret); + + ret = PyObject_CallMethod(timer, "start", "OO", current, timer); + if (!ret) { + stop_the_watchers_and_clear + return -1; + } + Py_DECREF(ret); + + ret = PyObject_CallMethod(ugevent.hub, "switch", NULL); + if (!ret) { + stop_the_watchers_and_clear + return -1; + } + Py_DECREF(ret); + + if (ret == timer) { + stop_the_watchers_and_clear; + return 0; + } + + stop_the_watchers_and_clear; + return 1; } diff --git a/plugins/http/http.c b/plugins/http/http.c index 001b0831..989fff11 100644 --- a/plugins/http/http.c +++ b/plugins/http/http.c @@ -27,7 +27,6 @@ struct uwsgi_option http_options[] = { {"http-use-cache", optional_argument, 0, "use uWSGI cache as key->value virtualhost mapper", uwsgi_opt_set_str, &uhttp.cr.use_cache, 0}, {"http-use-pattern", required_argument, 0, "use the specified pattern for mapping requests to unix sockets", uwsgi_opt_corerouter_use_pattern, &uhttp, 0}, {"http-use-base", required_argument, 0, "use the specified base for mapping requests to unix sockets", uwsgi_opt_corerouter_use_base, &uhttp, 0}, - {"http-use-cluster", no_argument, 0, "load balance to nodes subscribed to the cluster", uwsgi_opt_true, &uhttp.cr.use_cluster, 0}, {"http-events", required_argument, 0, "set the number of concurrent http async events", uwsgi_opt_set_int, &uhttp.cr.nevents, 0}, {"http-subscription-server", required_argument, 0, "enable the subscription server", uwsgi_opt_corerouter_ss, &uhttp, 0}, {"http-timeout", required_argument, 0, "set internal http socket timeout", uwsgi_opt_set_int, &uhttp.cr.socket_timeout, 0}, diff --git a/plugins/lua/lua_plugin.c b/plugins/lua/lua_plugin.c index 58128f89..0774a73d 100644 --- a/plugins/lua/lua_plugin.c +++ b/plugins/lua/lua_plugin.c @@ -285,7 +285,7 @@ static int uwsgi_api_req_fd(lua_State *L) { struct wsgi_request *wsgi_req = current_wsgi_req(); - lua_pushnumber(L, wsgi_req->poll.fd); + lua_pushnumber(L, wsgi_req->fd); return 1; } @@ -294,12 +294,10 @@ static int uwsgi_api_lock(lua_State *L) { int lock_num = 0; // the spooler cannot lock resources -#ifdef UWSGI_SPOOLER if (uwsgi.i_am_a_spooler) { lua_pushstring(L, "The spooler cannot lock/unlock resources"); lua_error(L); } -#endif if (lua_gettop(L) > 0) { lock_num = lua_isnumber(L, 1) ? lua_tonumber(L, 1) : -1; @@ -320,12 +318,10 @@ static int uwsgi_api_unlock(lua_State *L) { int lock_num = 0; // the spooler cannot lock resources -#ifdef UWSGI_SPOOLER if (uwsgi.i_am_a_spooler) { lua_pushstring(L, "The spooler cannot lock/unlock resources"); lua_error(L); } -#endif if (lua_gettop(L) > 0) { lock_num = lua_isnumber(L, 1) ? lua_tonumber(L, 1) : -1; @@ -359,39 +355,23 @@ static const luaL_reg uwsgi_api[] = { static int uwsgi_lua_input(lua_State *L) { struct wsgi_request *wsgi_req = current_wsgi_req(); - int fd = wsgi_req->async_post ? - fileno(wsgi_req->async_post) : wsgi_req->poll.fd; - ssize_t sum, len, total; - char *buf, *ptr; + ssize_t sum = 0; int n = lua_gettop(L); - if (!wsgi_req->post_cl) { - lua_pushlstring(L, "", 0); - return 1; - } - - sum = lua_tonumber(L, 2); - if (n > 1) { - uwsgi_log("requested %ld bytes\n", (long) sum); + sum = lua_tonumber(L, 2); } - buf = uwsgi_malloc(sum); + ssize_t rlen = 0; - total = sum; + char *buf = uwsgi_request_body_read(wsgi_req, sum, &rlen); + if (buf) { + lua_pushlstring(L, buf, rlen); + return 1; + } - ptr = buf; - while(total) { - len = read(fd, ptr, total); - ptr += len; - total -= len; - } - - lua_pushlstring(L, buf, sum); - free(buf); - - return 1; + return 0; } int uwsgi_lua_init(){ @@ -451,7 +431,6 @@ int uwsgi_lua_request(struct wsgi_request *wsgi_req) { char *ptrbuf; lua_State *L = ulua.L[wsgi_req->async_id]; -#ifdef UWSGI_ASYNC if (wsgi_req->async_status == UWSGI_AGAIN) { if ((i = lua_pcall(L, 0, 1, 0)) == 0) { if (lua_type(L, -1) == LUA_TSTRING) { @@ -464,17 +443,15 @@ int uwsgi_lua_request(struct wsgi_request *wsgi_req) { } goto clear; } -#endif /* Standard WSAPI request */ - if (!wsgi_req->uh.pktsize) { - uwsgi_log( "Invalid WSAPI request. skip.\n"); - goto clear2; + if (!wsgi_req->uh->pktsize) { + uwsgi_log( "Empty lua request. skip.\n"); + return -1; } if (uwsgi_parse_vars(wsgi_req)) { - uwsgi_log("Invalid WSAPI request. skip.\n"); - goto clear2; + return -1; } // put function in the stack @@ -547,17 +524,13 @@ int uwsgi_lua_request(struct wsgi_request *wsgi_req) { } lua_pop(L, 1); lua_pushvalue(L, -1); -#ifdef UWSGI_ASYNC if (uwsgi.async > 1) { return UWSGI_AGAIN; } -#endif } clear: lua_pop(L, 4); -clear2: - // set frequency lua_gc(L, LUA_GCCOLLECT, 0); diff --git a/plugins/php/php_plugin.c b/plugins/php/php_plugin.c index 9fb2a852..1216918e 100644 --- a/plugins/php/php_plugin.c +++ b/plugins/php/php_plugin.c @@ -112,36 +112,17 @@ static int sapi_uwsgi_read_post(char *buffer, uint count_bytes TSRMLS_DC) struct wsgi_request *wsgi_req = (struct wsgi_request *) SG(server_context); - if (wsgi_req->body_as_file) { - fd = fileno((FILE *)wsgi_req->async_post); - } - else if (uwsgi.post_buffering > 0) { - if (wsgi_req->post_cl > (size_t) uwsgi.post_buffering) { - fd = fileno((FILE *)wsgi_req->async_post); - } - } - else { - fd = wsgi_req->poll.fd; - } - - count_bytes = MIN(count_bytes, wsgi_req->post_cl - SG(read_post_bytes)); - // data in memory - if (fd == -1) { - if (count_bytes > 0) { - memcpy(buffer, wsgi_req->post_buffering_buf + wsgi_req->post_pos, count_bytes); - wsgi_req->post_pos += count_bytes; - } - return count_bytes; - } - while (read_bytes < count_bytes) { - len = read(fd, buffer + read_bytes, count_bytes - read_bytes); - if (len <= 0) { - break; + ssize_t rlen = 0; + char *buf = uwsgi_request_body_read(wsgi_req, count_bytes - read_bytes, &rlen); + if (buf == uwsgi.empty) break; + if (buf) { + read_bytes += rlen; + continue; } - read_bytes += len; + break; } return read_bytes; diff --git a/plugins/ping/ping_plugin.c b/plugins/ping/ping_plugin.c index 6a8b06c2..1322f345 100644 --- a/plugins/ping/ping_plugin.c +++ b/plugins/ping/ping_plugin.c @@ -69,20 +69,20 @@ int uwsgi_request_ping(struct wsgi_request *wsgi_req) { char len; uwsgi_log( "PING\n"); - wsgi_req->uh.modifier2 = 1; - wsgi_req->uh.pktsize = 0; + wsgi_req->uh->modifier2 = 1; + wsgi_req->uh->pktsize = 0; len = strlen(uwsgi.shared->warning_message); if (len > 0) { // TODO: check endianess ? - wsgi_req->uh.pktsize = len; + wsgi_req->uh->pktsize = len; } - if (write(wsgi_req->poll.fd, wsgi_req, 4) != 4) { + if (write(wsgi_req->fd, wsgi_req, 4) != 4) { uwsgi_error("write()"); } if (len > 0) { - if (write(wsgi_req->poll.fd, uwsgi.shared->warning_message, len) + if (write(wsgi_req->fd, uwsgi.shared->warning_message, len) != len) { uwsgi_error("write()"); } diff --git a/plugins/psgi/psgi_loader.c b/plugins/psgi/psgi_loader.c index a4230c77..1f19165e 100644 --- a/plugins/psgi/psgi_loader.c +++ b/plugins/psgi/psgi_loader.c @@ -98,83 +98,30 @@ XS(XS_input_read) { dXSARGS; struct wsgi_request *wsgi_req = current_wsgi_req(); - int fd = -1; - char *tmp_buf; - ssize_t bytes = 0, len; - size_t remains; - SV *read_buf; psgi_check_args(3); + SV *read_buf = ST(1); + unsigned long arg_len = SvIV(ST(2)); - read_buf = ST(1); - len = SvIV(ST(2)); + ssize_t rlen = 0; - // return empty string if no post_cl or pos >= post_cl - if (!wsgi_req->post_cl || (size_t) wsgi_req->post_pos >= wsgi_req->post_cl) { - sv_setpvn(read_buf, "", 0); - goto ret; - } - - if (wsgi_req->body_as_file) { - fd = fileno((FILE *)wsgi_req->async_post); - } - else if (uwsgi.post_buffering > 0) { - fd = -1; - if (wsgi_req->post_cl > (size_t) uwsgi.post_buffering) { - fd = fileno((FILE *)wsgi_req->async_post); - } - } - else { - fd = wsgi_req->poll.fd; - } - // return the whole input - if (len <= 0) { - remains = wsgi_req->post_cl; - } - else { - remains = len ; - } - - if (remains + wsgi_req->post_pos > wsgi_req->post_cl) { - remains = wsgi_req->post_cl - wsgi_req->post_pos; - } - - if (remains <= 0) { - sv_setpvn(read_buf, "", 0); - goto ret; - } - - // data in memory ? - if (fd == -1) { - sv_setpvn(read_buf, wsgi_req->post_buffering_buf, remains); - bytes = remains; - wsgi_req->post_pos += remains; + char *buf = uwsgi_request_body_read(wsgi_req, arg_len, &rlen); + if (buf) { + sv_setpvn(read_buf, buf, rlen); goto ret; } - tmp_buf = uwsgi_malloc(remains); - - if (uwsgi_waitfd(fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]) <= 0) { - free(tmp_buf); - croak("error waiting for psgi.input data"); - goto ret; + // error ? + if (rlen < 0) { + croak("error during read(%lu) on psgi.input", arg_len); + goto ret; } - bytes = read(fd, tmp_buf, remains); - if (bytes < 0) { - free(tmp_buf); - croak("error reading psgi.input data"); - goto ret; - } - - wsgi_req->post_pos += bytes; - sv_setpvn(read_buf, tmp_buf, bytes); - - free(tmp_buf); + croak("timeout during read(%lu) on psgi.input", arg_len); ret: - XSRETURN_IV(bytes); + XSRETURN_IV(rlen); } @@ -275,9 +222,7 @@ xs_init(pTHX) nonworker: -#ifdef UWSGI_EMBEDDED init_perl_embedded_module(); -#endif } diff --git a/plugins/psgi/psgi_plugin.c b/plugins/psgi/psgi_plugin.c index 0cf2bd58..1d4b4672 100644 --- a/plugins/psgi/psgi_plugin.c +++ b/plugins/psgi/psgi_plugin.c @@ -257,18 +257,12 @@ SV *build_psgi_env(struct wsgi_request *wsgi_req) { if (!hv_store(env, "psgi.run_once", 13, newSViv(0), 0)) goto clear; -#ifdef UWSGI_ASYNC if (uwsgi.async > 1) { if (!hv_store(env, "psgi.nonblocking", 16, newSViv(1), 0)) goto clear; } else { -#else if (!hv_store(env, "psgi.nonblocking", 16, newSViv(0), 0)) goto clear; -#endif - -#ifdef UWSGI_ASYNC } -#endif if (!hv_store(env, "psgi.streaming", 14, newSViv(1), 0)) goto clear; @@ -295,7 +289,7 @@ SV *build_psgi_env(struct wsgi_request *wsgi_req) { SV *pi = uwsgi_perl_obj_new("uwsgi::input", 12); if (!hv_store(env, "psgi.input", 10, pi, 0)) goto clear; - if (!hv_store(env, "psgix.input.buffered", 20, newSViv(wsgi_req->body_as_file), 0)) goto clear; + if (!hv_store(env, "psgix.input.buffered", 20, newSViv(uwsgi.post_buffering), 0)) goto clear; if (uwsgi.threads > 1) { if (!hv_store(env, "psgix.logger", 12,newRV((SV*) ((SV **)wi->responder1)[wsgi_req->async_id]) ,0)) goto clear; @@ -384,14 +378,13 @@ int uwsgi_perl_init(){ int uwsgi_perl_request(struct wsgi_request *wsgi_req) { -#ifdef UWSGI_ASYNC if (wsgi_req->async_status == UWSGI_AGAIN) { return psgi_response(wsgi_req, wsgi_req->async_placeholder); } -#endif + /* Standard PSGI request */ - if (!wsgi_req->uh.pktsize) { - uwsgi_log("Invalid PSGI request. skip.\n"); + if (!wsgi_req->uh->pktsize) { + uwsgi_log("Empty PSGI request. skip.\n"); return -1; } @@ -469,13 +462,11 @@ int uwsgi_perl_request(struct wsgi_request *wsgi_req) { } while (psgi_response(wsgi_req, wsgi_req->async_result) != UWSGI_OK) { -#ifdef UWSGI_ASYNC if (uwsgi.async > 1) { FREETMPS; LEAVE; return UWSGI_AGAIN; } -#endif } clear2: @@ -681,12 +672,9 @@ static void uwsgi_perl_atexit() { if (uwsgi.workers[uwsgi.mywid].busy) return; -#ifdef UWSGI_ASYNC // managing atexit in async mode is a real pain...skip it for now if (uwsgi.async > 1) return; -#endif - realstuff: if (uperl.atexit) { diff --git a/plugins/psgi/psgi_response.c b/plugins/psgi/psgi_response.c index 49045a62..66b94c9b 100644 --- a/plugins/psgi/psgi_response.c +++ b/plugins/psgi/psgi_response.c @@ -11,7 +11,6 @@ int psgi_response(struct wsgi_request *wsgi_req, AV *response) { char *chitem, *chitem2; SV **harakiri; -#ifdef UWSGI_ASYNC if (wsgi_req->async_status == UWSGI_AGAIN) { wsgi_req->async_force_again = 0; @@ -58,7 +57,6 @@ int psgi_response(struct wsgi_request *wsgi_req, AV *response) { return UWSGI_AGAIN; } -#endif if (SvTYPE(response) != SVt_PVAV) { uwsgi_log("invalid PSGI response type\n"); @@ -142,14 +140,12 @@ int psgi_response(struct wsgi_request *wsgi_req, AV *response) { } chitem = SvPV( chunk, hlen); -#ifdef UWSGI_ASYNC if (uwsgi.async > 1 && wsgi_req->async_force_again) { SvREFCNT_dec(chunk); wsgi_req->async_status = UWSGI_AGAIN; wsgi_req->async_placeholder = (SV *) *hitem; return UWSGI_AGAIN; } -#endif if (hlen <= 0) { SvREFCNT_dec(chunk); break; @@ -161,13 +157,11 @@ int psgi_response(struct wsgi_request *wsgi_req, AV *response) { break; } SvREFCNT_dec(chunk); -#ifdef UWSGI_ASYNC if (uwsgi.async > 1) { wsgi_req->async_status = UWSGI_AGAIN; wsgi_req->async_placeholder = (SV *) *hitem; return UWSGI_AGAIN; } -#endif } diff --git a/plugins/psgi/uwsgi_plmodule.c b/plugins/psgi/uwsgi_plmodule.c index f3997cfa..5f77656c 100644 --- a/plugins/psgi/uwsgi_plmodule.c +++ b/plugins/psgi/uwsgi_plmodule.c @@ -4,9 +4,6 @@ extern struct uwsgi_server uwsgi; extern struct uwsgi_plugin psgi_plugin; extern struct uwsgi_perl uperl; -#ifdef UWSGI_ASYNC - - XS(XS_async_sleep) { dXSARGS; @@ -76,8 +73,6 @@ XS(XS_wait_fd_write) { XSRETURN_UNDEF; } -#endif - XS(XS_signal) { dXSARGS; diff --git a/plugins/python/pump_subhandler.c b/plugins/python/pump_subhandler.c index f53d5376..4e237d74 100644 --- a/plugins/python/pump_subhandler.c +++ b/plugins/python/pump_subhandler.c @@ -101,27 +101,12 @@ void *uwsgi_request_subhandler_pump(struct wsgi_request *wsgi_req, struct uwsgi_ PyDict_SetItemString(wsgi_req->async_environ, "headers", headers); Py_DECREF(headers); - // if async_post is mapped as a file, directly use it as wsgi.input - if (wsgi_req->async_post) { -#ifdef PYTHREE - wsgi_req->async_input = PyFile_FromFd(fileno((FILE *)wsgi_req->async_post), "pump_body", "rb", 0, NULL, NULL, NULL, 0); -#else - wsgi_req->async_input = PyFile_FromFile(wsgi_req->async_post, "pump_body", "r", NULL); -#endif - } - else { - // create wsgi.input custom object - wsgi_req->async_input = (PyObject *) PyObject_New(uwsgi_Input, &uwsgi_InputType); - ((uwsgi_Input*)wsgi_req->async_input)->wsgi_req = wsgi_req; - ((uwsgi_Input*)wsgi_req->async_input)->pos = 0; - ((uwsgi_Input*)wsgi_req->async_input)->readline_pos = 0; - ((uwsgi_Input*)wsgi_req->async_input)->readline_max_size = 0; - - } + // create wsgi.input custom object + wsgi_req->async_input = (PyObject *) PyObject_New(uwsgi_Input, &uwsgi_InputType); + ((uwsgi_Input*)wsgi_req->async_input)->wsgi_req = wsgi_req; PyDict_SetItemString(wsgi_req->async_environ, "body", wsgi_req->async_input); - if (wsgi_req->scheme_len > 0) { zero = PyString_FromStringAndSize(wsgi_req->scheme, wsgi_req->scheme_len); } @@ -153,19 +138,8 @@ void *uwsgi_request_subhandler_pump(struct wsgi_request *wsgi_req, struct uwsgi_ PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.core", PyInt_FromLong(wsgi_req->async_id)); } - // cache this ? - if (uwsgi.cluster_fd >= 0) { - zero = PyString_FromString(uwsgi.cluster); - PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.cluster", zero); - Py_DECREF(zero); - zero = PyString_FromString(uwsgi.hostname); - PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.cluster_node", zero); - Py_DECREF(zero); - } - PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.node", wi->uwsgi_node); - // call PyTuple_SetItem(wsgi_req->async_args, 0, wsgi_req->async_environ); @@ -280,11 +254,11 @@ int uwsgi_response_subhandler_pump(struct wsgi_request *wsgi_req) { if (!wsgi_req->async_placeholder) { goto clear; } -#ifdef UWSGI_ASYNC + if (uwsgi.async > 1) { return UWSGI_AGAIN; } -#endif + } else { uwsgi_log("invalid Pump response.\n"); diff --git a/plugins/python/pyloader.c b/plugins/python/pyloader.c index 04f78c46..c341f66e 100644 --- a/plugins/python/pyloader.c +++ b/plugins/python/pyloader.c @@ -15,12 +15,8 @@ extern char **environ; PyMethodDef uwsgi_sendfile_method[] = {{"uwsgi_sendfile", py_uwsgi_sendfile, METH_VARARGS, ""}}; -#ifdef UWSGI_ASYNC PyMethodDef uwsgi_eventfd_read_method[] = { {"uwsgi_eventfd_read", py_eventfd_read, METH_VARARGS, ""}}; PyMethodDef uwsgi_eventfd_write_method[] = { {"uwsgi_eventfd_write", py_eventfd_write, METH_VARARGS, ""}}; -#endif - -#ifdef UWSGI_MINTERPRETERS void set_dyn_pyhome(char *home, uint16_t pyhome_len) { @@ -68,8 +64,6 @@ void set_dyn_pyhome(char *home, uint16_t pyhome_len) { } } -#endif - int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThreadState *interpreter, int app_type) { @@ -161,7 +155,6 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre } } -#ifdef UWSGI_MINTERPRETERS if (interpreter == NULL && id) { wi->interpreter = Py_NewInterpreter(); @@ -172,10 +165,8 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre PyThreadState_Swap(wi->interpreter); init_pyargv(); -#ifdef UWSGI_EMBEDDED // we need to inizialize an embedded module for every interpreter init_uwsgi_embedded_module(); -#endif init_uwsgi_vars(); } @@ -189,9 +180,6 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre if (wsgi_req->pyhome_len) { set_dyn_pyhome(wsgi_req->pyhome, wsgi_req->pyhome_len); } -#else - wi->interpreter = up.main_thread; -#endif if (wsgi_req->touch_reload_len > 0 && wsgi_req->touch_reload_len < 0xff) { struct stat trst; @@ -245,7 +233,6 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre Py_INCREF((PyObject *)wi->callable); -#ifdef UWSGI_ASYNC wi->environ = malloc(sizeof(PyObject*)*uwsgi.cores); if (!wi->environ) { uwsgi_error("malloc()"); @@ -259,13 +246,6 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre exit(1); } } -#else - wi->environ = PyDict_New(); - if (!wi->environ) { - uwsgi_log("unable to allocate new env dictionary for app\n"); - exit(1); - } -#endif wi->argc = 1; @@ -292,7 +272,6 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre wi->response_subhandler = uwsgi_response_subhandler_pump; } -#ifdef UWSGI_ASYNC wi->args = malloc(sizeof(PyObject*)*uwsgi.cores); if (!wi->args) { uwsgi_error("malloc()"); @@ -315,27 +294,13 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre } } } -#else - - // add start_response on WSGI app - Py_INCREF((PyObject *)up.wsgi_spitout); - wi->args = PyTuple_New(wi->argc); - if (app_type == PYTHON_APP_TYPE_WSGI) { - if (PyTuple_SetItem(wi->args, 1, up.wsgi_spitout)) { - uwsgi_log("unable to set start_response in args tuple\n"); - exit(1); - } - } -#endif if (app_type == PYTHON_APP_TYPE_WSGI) { // prepare sendfile() for WSGI app wi->sendfile = PyCFunction_New(uwsgi_sendfile_method, NULL); -#ifdef UWSGI_ASYNC wi->eventfd_read = PyCFunction_New(uwsgi_eventfd_read_method, NULL); wi->eventfd_write = PyCFunction_New(uwsgi_eventfd_write_method, NULL); -#endif } // cache most used values @@ -426,7 +391,6 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre doh: if (PyErr_Occurred()) PyErr_Print(); -#ifdef UWSGI_MINTERPRETERS if (interpreter == NULL && id) { Py_EndInterpreter(wi->interpreter); if (uwsgi.threads > 1) { @@ -436,7 +400,6 @@ doh: PyThreadState_Swap(up.main_thread); } } -#endif return -1; } @@ -481,9 +444,7 @@ PyObject *uwsgi_uwsgi_loader(void *arg1) { PyObject *tmp_callable; PyObject *applications; -#ifdef UWSGI_EMBEDDED PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi"); -#endif char *module = (char *) arg1; @@ -506,10 +467,8 @@ PyObject *uwsgi_uwsgi_loader(void *arg1) { return NULL; } -#ifdef UWSGI_EMBEDDED applications = PyDict_GetItemString(uwsgi_dict, "applications"); if (applications && PyDict_Check(applications)) return applications; -#endif applications = PyDict_GetItemString(wsgi_dict, "applications"); if (applications && PyDict_Check(applications)) return applications; diff --git a/plugins/python/python_plugin.c b/plugins/python/python_plugin.c index 80d29571..8b7c93c7 100644 --- a/plugins/python/python_plugin.c +++ b/plugins/python/python_plugin.c @@ -136,7 +136,6 @@ struct uwsgi_option uwsgi_python_options[] = { {"py", required_argument, 0, "run a python script in the uWSGI environment", uwsgi_opt_pyrun, NULL, 0}, {"pyrun", required_argument, 0, "run a python script in the uWSGI environment", uwsgi_opt_pyrun, NULL, 0}, -#ifdef UWSGI_THREADING #ifndef UWSGI_PYPY {"py-tracebacker", required_argument, 0, "enable the uWSGI python tracebacker", uwsgi_opt_set_str, &up.tracebacker, UWSGI_OPT_THREADS|UWSGI_OPT_MASTER}, #endif @@ -145,7 +144,6 @@ struct uwsgi_option uwsgi_python_options[] = { {"python-auto-reload", required_argument, 0, "monitor python modules mtime to trigger reload (use only in development)", uwsgi_opt_set_int, &up.auto_reload, UWSGI_OPT_THREADS|UWSGI_OPT_MASTER}, {"python-autoreload", required_argument, 0, "monitor python modules mtime to trigger reload (use only in development)", uwsgi_opt_set_int, &up.auto_reload, UWSGI_OPT_THREADS|UWSGI_OPT_MASTER}, {"py-auto-reload-ignore", required_argument, 0, "ignore the specified module during auto-reload scan (can be specified multiple times)", uwsgi_opt_add_string_list, &up.auto_reload_ignore, UWSGI_OPT_THREADS|UWSGI_OPT_MASTER}, -#endif {"wsgi-env-behaviour", required_argument, 0, "set the strategy for allocating/deallocating the WSGI env", uwsgi_opt_set_str, &up.wsgi_env_behaviour, 0}, {"wsgi-env-behavior", required_argument, 0, "set the strategy for allocating/deallocating the WSGI env", uwsgi_opt_set_str, &up.wsgi_env_behaviour, 0}, @@ -249,9 +247,6 @@ pep405: up.wsgi_spitout = PyCFunction_New(uwsgi_spit_method, NULL); up.wsgi_writeout = PyCFunction_New(uwsgi_write_method, NULL); - up.hook_wsgi_input_read = uwsgi_python_hook_simple_input_read; - up.hook_wsgi_input_readline = uwsgi_python_hook_simple_input_readline; - up.main_thread = PyThreadState_Get(); // by default set a fake GIL (little impact on performance) @@ -307,12 +302,9 @@ void uwsgi_python_atexit() { if (uwsgi.workers[uwsgi.mywid].busy) return; -#ifdef UWSGI_ASYNC // managing atexit in async mode is a real pain...skip it for now if (uwsgi.async > 1) return; -#endif - realstuff: // this time we use this higher level function @@ -326,7 +318,6 @@ realstuff: PyGILState_Ensure(); // no need to worry about freeing memory -#ifdef UWSGI_EMBEDDED PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi"); if (uwsgi_dict) { PyObject *ae = PyDict_GetItemString(uwsgi_dict, "atexit"); @@ -334,7 +325,6 @@ realstuff: python_call(ae, PyTuple_New(0), 0, NULL); } } -#endif // this part is a 1:1 copy of mod_wsgi 3.x // it is required to fix some atexit bug with python 3 @@ -352,15 +342,12 @@ realstuff: void uwsgi_python_post_fork() { -#ifdef UWSGI_SPOOLER if (uwsgi.i_am_a_spooler) { UWSGI_GET_GIL } -#endif uwsgi_python_reset_random_seed(); -#ifdef UWSGI_EMBEDDED // call the post_fork_hook PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi"); if (uwsgi_dict) { @@ -370,10 +357,8 @@ void uwsgi_python_post_fork() { } } PyErr_Clear(); -#endif if (uwsgi.mywid > 0) { -#ifdef UWSGI_THREADING if (up.auto_reload) { // spawn the reloader thread pthread_t par_tid; @@ -385,7 +370,6 @@ void uwsgi_python_post_fork() { pthread_t ptb_tid; pthread_create(&ptb_tid, NULL, uwsgi_python_tracebacker_thread, NULL); } -#endif #endif } @@ -572,7 +556,6 @@ next: -#ifdef UWSGI_EMBEDDED PyDoc_STRVAR(uwsgi_py_doc, "uWSGI api module."); #ifdef PYTHREE @@ -671,7 +654,6 @@ void init_uwsgi_embedded_module() { } } -#ifdef UWSGI_SPOOLER if (uwsgi.spoolers) { int sc = 0; struct uwsgi_spooler *uspool = uwsgi.spoolers; @@ -693,9 +675,6 @@ void init_uwsgi_embedded_module() { exit(1); } } -#endif - - if (PyDict_SetItemString(up.embedded_dict, "SPOOL_RETRY", PyInt_FromLong(-1))) { PyErr_Print(); @@ -850,12 +829,9 @@ void init_uwsgi_embedded_module() { init_uwsgi_module_advanced(new_uwsgi_module); -#ifdef UWSGI_SPOOLER if (uwsgi.spoolers) { init_uwsgi_module_spooler(new_uwsgi_module); } -#endif - if (uwsgi.sharedareasize > 0 && uwsgi.sharedarea) { init_uwsgi_module_sharedarea(new_uwsgi_module); @@ -869,17 +845,14 @@ void init_uwsgi_embedded_module() { init_uwsgi_module_queue(new_uwsgi_module); } -#ifdef UWSGI_SNMP if (uwsgi.snmp) { init_uwsgi_module_snmp(new_uwsgi_module); } -#endif if (up.extension) { up.extension(); } } -#endif @@ -995,15 +968,9 @@ void uwsgi_python_spooler_init(void) { // from a python-programmer point of view it is a hack/cheat but it does not violate the WSGI standard // and it is a bit faster than the "holy" allocator void *uwsgi_python_create_env_cheat(struct wsgi_request *wsgi_req, struct uwsgi_app *wi) { -#ifdef UWSGI_ASYNC wsgi_req->async_args = wi->args[wsgi_req->async_id]; Py_INCREF((PyObject *)wi->environ[wsgi_req->async_id]); return wi->environ[wsgi_req->async_id]; -#else - wsgi_req->async_args = wi->args; - Py_INCREF((PyObject *)wi->environ); - return wi->environ; -#endif } void uwsgi_python_destroy_env_cheat(struct wsgi_request *wsgi_req) { @@ -1045,14 +1012,10 @@ void uwsgi_python_preinit_apps() { init_pyargv(); -#ifdef UWSGI_EMBEDDED init_uwsgi_embedded_module(); -#endif #ifdef __linux__ -#ifdef UWSGI_EMBEDDED uwsgi_init_symbol_import(); -#endif #endif if (up.test_module != NULL) { @@ -1206,7 +1169,6 @@ next: } #endif -#ifdef UWSGI_EMBEDDED PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi"); if (uwsgi_dict) { up.after_req_hook = PyDict_GetItemString(uwsgi_dict, "after_req_hook"); @@ -1216,8 +1178,6 @@ next: Py_INCREF(up.after_req_hook_args); } } -#endif - // lazy ? if (uwsgi.mywid > 0) { UWSGI_RELEASE_GIL; @@ -1319,7 +1279,6 @@ void uwsgi_python_init_thread(int core_id) { } -#ifdef UWSGI_THREADING int uwsgi_check_python_mtime(PyObject *times_dict, char *filename) { struct stat st; @@ -1463,7 +1422,6 @@ void *uwsgi_python_autoreloader_thread(void *foobar) { return NULL; } -#endif #ifndef UWSGI_PYPY void uwsgi_python_suspend(struct wsgi_request *wsgi_req) { diff --git a/plugins/python/pyutils.c b/plugins/python/pyutils.c index f2e0671d..05a1bbfe 100644 --- a/plugins/python/pyutils.c +++ b/plugins/python/pyutils.c @@ -139,11 +139,9 @@ int uwsgi_python_call(struct wsgi_request *wsgi_req, PyObject *callable, PyObjec if (wsgi_req->async_result) { while ( manage_python_response(wsgi_req) != UWSGI_OK) { -#ifdef UWSGI_ASYNC if (uwsgi.async > 1) { return UWSGI_AGAIN; } -#endif } } diff --git a/plugins/python/uwsgi_pymodule.c b/plugins/python/uwsgi_pymodule.c index fe116e2c..6e3184b4 100644 --- a/plugins/python/uwsgi_pymodule.c +++ b/plugins/python/uwsgi_pymodule.c @@ -1,5 +1,3 @@ -#ifdef UWSGI_EMBEDDED - #include "uwsgi_python.h" extern struct uwsgi_server uwsgi; @@ -556,108 +554,6 @@ PyObject *py_uwsgi_set_logvar(PyObject * self, PyObject * args) { return Py_None; } - - -PyObject *py_uwsgi_recv_frame(PyObject * self, PyObject * args) { - - struct wsgi_request *wsgi_req = current_wsgi_req(); - - char *bufptr; - char prefix = 0x00; - char suffix = 0xff; - int i; - char frame[4096]; - char *frame_ptr; - int frame_size = 0; - int fd; - int rlen; - - int found_start = 0; - char *null1, *null2; - - - if (!PyArg_ParseTuple(args, "icc:recv_frame", &fd, &null1, &null2)) { - return NULL; - } - - get_data: - frame_ptr = frame; - if (wsgi_req->frame_len > 0) { - // we have already some data buffered - // search for the prefix and adjust frame_pos - bufptr = wsgi_req->buffer + wsgi_req->frame_pos; - for (i = 0; i < wsgi_req->frame_len; i++) { - if (bufptr[i] == prefix) { - bufptr++; - found_start = 1; - break; - } - bufptr++; - wsgi_req->frame_pos++; - } - - wsgi_req->frame_len -= i; - if (found_start) { - // we have found the prefix, copy it in the frame area until suffix or end of the buffer - for (i = 0; i < wsgi_req->frame_len; i++) { - uwsgi_log("%d %d\n", bufptr[i], frame_size); - if (bufptr[i] == suffix) { - wsgi_req->frame_len -= i; - goto return_a_frame; - } - *frame_ptr++ = bufptr[i]; - frame_size++; - wsgi_req->frame_pos++; - } - } - } - - // we have already get the prefix ? - if (found_start) { - - // wait for more data - read_more_data: - rlen = uwsgi_waitfd(fd, -1); - if (rlen > 0) { - wsgi_req->frame_pos = 0; - wsgi_req->frame_len = read(fd, wsgi_req->buffer, uwsgi.buffer_size); - bufptr = wsgi_req->buffer; - for (i = 0; i < wsgi_req->frame_len; i++) { - if (bufptr[i] == suffix) { - goto return_a_frame; - } - *frame_ptr++ = bufptr[i]; - frame_size++; - } - goto read_more_data; - } - else if (rlen == 0) { - uwsgi_log("timeout waiting for frame\n"); - } - - } - else { - // read a whole frame directly from the socket - rlen = uwsgi_waitfd(fd, -1); - if (rlen > 0) { - wsgi_req->frame_pos = 0; - wsgi_req->frame_len = read(fd, wsgi_req->buffer, uwsgi.buffer_size); - uwsgi_log("read %d bytes %.*s\n", wsgi_req->frame_len, wsgi_req->frame_len, wsgi_req->buffer); - if (wsgi_req->frame_len == 0) - goto return_a_frame; - goto get_data; - } - else if (rlen == 0) { - uwsgi_log("timeout waiting for frame\n"); - } - - } - return_a_frame: - uwsgi_log("returning a frame\n"); - return PyString_FromStringAndSize(frame, frame_size); - -} - PyObject *py_uwsgi_recv_block(PyObject * self, PyObject * args) { char buf[4096]; @@ -771,7 +667,7 @@ PyObject *py_uwsgi_send(PyObject * self, PyObject * args) { struct wsgi_request *wsgi_req = current_wsgi_req(); - int uwsgi_fd = wsgi_req->poll.fd; + int uwsgi_fd = wsgi_req->fd; if (!PyArg_ParseTuple(args, "O|O:send", &arg1, &arg2)) { return NULL; @@ -897,8 +793,6 @@ PyObject *py_uwsgi_advanced_sendfile(PyObject * self, PyObject * args) { } -#ifdef UWSGI_ASYNC - PyObject *py_uwsgi_async_sleep(PyObject * self, PyObject * args) { @@ -917,7 +811,6 @@ PyObject *py_uwsgi_async_sleep(PyObject * self, PyObject * args) { return PyString_FromString(""); } -#endif PyObject *py_uwsgi_warning(PyObject * self, PyObject * args) { char *message; @@ -968,13 +861,10 @@ PyObject *py_uwsgi_set_user_harakiri(PyObject * self, PyObject * args) { } PyObject *py_uwsgi_i_am_the_spooler(PyObject * self, PyObject * args) { -#ifdef UWSGI_SPOOLER if (uwsgi.i_am_a_spooler) { Py_INCREF(Py_True); return Py_True; } -#endif - Py_INCREF(Py_None); return Py_None; } @@ -984,11 +874,9 @@ PyObject *py_uwsgi_is_locked(PyObject * self, PyObject * args) { int lock_num = 0; // the spooler cannot lock resources -#ifdef UWSGI_SPOOLER if (uwsgi.i_am_a_spooler) { return PyErr_Format(PyExc_ValueError, "The spooler cannot lock/unlock resources"); } -#endif if (!PyArg_ParseTuple(args, "|i:is_locked", &lock_num)) { return NULL; @@ -1018,11 +906,9 @@ PyObject *py_uwsgi_lock(PyObject * self, PyObject * args) { int lock_num = 0; // the spooler cannot lock resources -#ifdef UWSGI_SPOOLER if (uwsgi.i_am_a_spooler) { return PyErr_Format(PyExc_ValueError, "The spooler cannot lock/unlock resources"); } -#endif if (!PyArg_ParseTuple(args, "|i:lock", &lock_num)) { return NULL; @@ -1044,11 +930,9 @@ PyObject *py_uwsgi_unlock(PyObject * self, PyObject * args) { int lock_num = 0; -#ifdef UWSGI_SPOOLER if (uwsgi.i_am_a_spooler) { return PyErr_Format(PyExc_ValueError, "The spooler cannot lock/unlock resources"); } -#endif if (!PyArg_ParseTuple(args, "|i:unlock", &lock_num)) { return NULL; @@ -1066,7 +950,7 @@ PyObject *py_uwsgi_unlock(PyObject * self, PyObject * args) { PyObject *py_uwsgi_connection_fd(PyObject * self, PyObject * args) { struct wsgi_request *wsgi_req = current_wsgi_req(); - return PyInt_FromLong(wsgi_req->poll.fd); + return PyInt_FromLong(wsgi_req->fd); } PyObject *py_uwsgi_websocket_handshake(PyObject * self, PyObject * args) { @@ -1105,152 +989,15 @@ PyObject *py_uwsgi_websocket_send(PyObject * self, PyObject * args) { struct wsgi_request *wsgi_req = current_wsgi_req(); UWSGI_RELEASE_GIL - ssize_t len = uwsgi_websocket_send(wsgi_req, message, message_len); + int ret = uwsgi_websocket_send(wsgi_req, message, message_len); UWSGI_GET_GIL - if (len <= 0) { + if (ret < 0) { return PyErr_Format(PyExc_IOError, "unable to send websocket message"); } Py_INCREF(Py_None); return Py_None; } -PyObject *py_uwsgi_websocket_channel_join(PyObject * self, PyObject * args) { - char *c_name = NULL; - - if (!PyArg_ParseTuple(args, "s:channel_join", &c_name)) { - return NULL; - } - - struct wsgi_request *wsgi_req = current_wsgi_req(); - - struct uwsgi_channel *channel = uwsgi_channel_by_name(c_name); - if (!channel) { - return PyErr_Format(PyExc_ValueError, "unable to find channel"); - } - - // release the gil as before joining we consume items in the queue - // could be useless as channel sockets are non-blocking - UWSGI_RELEASE_GIL - uwsgi_channel_join(wsgi_req, channel, 2); - UWSGI_GET_GIL - - Py_INCREF(Py_None); - return Py_None; -} - - -PyObject *py_uwsgi_channel_join(PyObject * self, PyObject * args) { - char *c_name = NULL; - - if (!PyArg_ParseTuple(args, "s:channel_join", &c_name)) { - return NULL; - } - - struct wsgi_request *wsgi_req = current_wsgi_req(); - - struct uwsgi_channel *channel = uwsgi_channel_by_name(c_name); - if (!channel) { - return PyErr_Format(PyExc_ValueError, "unable to find channel"); - } - - // release the gil as before joining we consume items in the queue - // could be useless as channel sockets are non-blocking - UWSGI_RELEASE_GIL - uwsgi_channel_join(wsgi_req, channel, 1); - UWSGI_GET_GIL - - Py_INCREF(Py_None); - return Py_None; -} - -PyObject *py_uwsgi_channel_leave(PyObject * self, PyObject * args) { - char *c_name = NULL; - - if (!PyArg_ParseTuple(args, "s:channel_leave", &c_name)) { - return NULL; - } - - struct wsgi_request *wsgi_req = current_wsgi_req(); - - struct uwsgi_channel *channel = uwsgi_channel_by_name(c_name); - if (!channel) { - return PyErr_Format(PyExc_ValueError, "unable to find channel"); - } - - // release the gil as before joining we consume items in the queue - // could be useless as channel sockets are non-blocking - UWSGI_RELEASE_GIL - uwsgi_channel_leave(wsgi_req, channel); - UWSGI_GET_GIL - - Py_INCREF(Py_None); - return Py_None; -} - - -PyObject *py_uwsgi_channel_send(PyObject * self, PyObject * args) { - char *c_name = NULL; - char *message = NULL; - Py_ssize_t message_len = 0; - - if (!PyArg_ParseTuple(args, "ss#:channel_send", &c_name, &message, &message_len)) { - return NULL; - } - - struct uwsgi_channel *channel = uwsgi_channel_by_name(c_name); - if (!channel) { - return PyErr_Format(PyExc_ValueError, "unable to find channel"); - } - - // release the gil even if channel sockets are non-blocking - UWSGI_RELEASE_GIL - int ret = uwsgi_channel_send(channel, message, message_len); - UWSGI_GET_GIL - - if (ret) { - return PyErr_Format(PyExc_IOError, "unable to send channel message"); - } - - Py_INCREF(Py_None); - return Py_None; -} - -PyObject *py_uwsgi_channel_recv(PyObject * self, PyObject * args) { - char *c_name = NULL; - int timeout = -1; - - if (!PyArg_ParseTuple(args, "s|i:channel_recv", &c_name, &timeout)) { - return NULL; - } - - struct uwsgi_channel *channel = uwsgi_channel_by_name(c_name); - if (!channel) { - return PyErr_Format(PyExc_ValueError, "unable to find channel"); - } - - struct wsgi_request *wsgi_req = current_wsgi_req(); - UWSGI_RELEASE_GIL - struct uwsgi_buffer *ub = uwsgi_channel_recv(wsgi_req, channel, timeout); - UWSGI_GET_GIL - if (!ub) { - return PyErr_Format(PyExc_IOError, "unable to receive channel message"); - } - - // timeout ? - if (ub->pos == 0) { - uwsgi_buffer_destroy(ub); - Py_INCREF(Py_None); - return Py_None; - } - - PyObject *ret = PyString_FromStringAndSize(ub->buf, ub->pos); - uwsgi_buffer_destroy(ub); - return ret; -} - - - - PyObject *py_uwsgi_websocket_recv(PyObject * self, PyObject * args) { struct wsgi_request *wsgi_req = current_wsgi_req(); UWSGI_RELEASE_GIL @@ -1799,7 +1546,6 @@ PyObject *py_uwsgi_sharedarea_read(PyObject * self, PyObject * args) { return ret; } -#ifdef UWSGI_SPOOLER PyObject *py_uwsgi_spooler_freq(PyObject * self, PyObject * args) { if (!PyArg_ParseTuple(args, "i", &uwsgi.shared->spooler_frequency)) { @@ -2060,176 +1806,6 @@ PyObject *py_uwsgi_spooler_pid(PyObject * self, PyObject * args) { if (!uwsgi.spoolers) return PyInt_FromLong(0); return PyInt_FromLong(uspool->pid); } -#endif - -PyObject *py_uwsgi_send_multi_message(PyObject * self, PyObject * args) { - - - int i; - int clen; - int pret; - int managed; - struct pollfd *multipoll; - char *buffer; - - PyObject *arg_cluster; - - PyObject *cluster_node; - - PyObject *arg_host, *arg_port, *arg_message; - - PyObject *arg_modifier1, *arg_modifier2, *arg_timeout; - - PyObject *retobject; - - - arg_cluster = PyTuple_GetItem(args, 0); - if (!PyTuple_Check(arg_cluster)) { - Py_INCREF(Py_None); - return Py_None; - } - - - arg_modifier1 = PyTuple_GetItem(args, 1); - if (!PyInt_Check(arg_modifier1)) { - Py_INCREF(Py_None); - return Py_None; - } - - arg_modifier2 = PyTuple_GetItem(args, 2); - if (!PyInt_Check(arg_modifier2)) { - Py_INCREF(Py_None); - return Py_None; - } - - arg_timeout = PyTuple_GetItem(args, 3); - if (!PyInt_Check(arg_timeout)) { - Py_INCREF(Py_None); - return Py_None; - } - - - /* iterate cluster */ - clen = PyTuple_Size(arg_cluster); - multipoll = malloc(clen * sizeof(struct pollfd)); - if (!multipoll) { - uwsgi_error("malloc"); - Py_INCREF(Py_None); - return Py_None; - } - - - buffer = malloc(uwsgi.buffer_size * clen); - if (!buffer) { - uwsgi_error("malloc"); - free(multipoll); - Py_INCREF(Py_None); - return Py_None; - } - - - for (i = 0; i < clen; i++) { - multipoll[i].events = POLLIN; - - cluster_node = PyTuple_GetItem(arg_cluster, i); - arg_host = PyTuple_GetItem(cluster_node, 0); - if (!PyString_Check(arg_host)) { - goto clear; - } - - arg_port = PyTuple_GetItem(cluster_node, 1); - if (!PyInt_Check(arg_port)) { - goto clear; - } - - arg_message = PyTuple_GetItem(cluster_node, 2); - if (!arg_message) { - goto clear; - } - - -#ifndef UWSGI_PYPY - PyObject *marshalled; - switch (PyInt_AsLong(arg_modifier1)) { - case UWSGI_MODIFIER_MESSAGE_MARSHAL: - marshalled = PyMarshal_WriteObjectToString(arg_message, 1); - if (!marshalled) { - PyErr_Print(); - goto clear; - } - multipoll[i].fd = uwsgi_enqueue_message(PyString_AsString(arg_host), PyInt_AsLong(arg_port), PyInt_AsLong(arg_modifier1), PyInt_AsLong(arg_modifier2), PyString_AsString(marshalled), PyString_Size(marshalled), PyInt_AsLong(arg_timeout)); - Py_DECREF(marshalled); - if (multipoll[i].fd < 0) { - goto multiclear; - } - break; - } -#endif - - - } - - managed = 0; - retobject = PyTuple_New(clen); - if (!retobject) { - PyErr_Print(); - goto multiclear; - } - - while (managed < clen) { - pret = poll(multipoll, clen, PyInt_AsLong(arg_timeout) * 1000); - if (pret < 0) { - uwsgi_error("poll()"); - goto megamulticlear; - } - else if (pret == 0) { - uwsgi_log("timeout on multiple send !\n"); - goto megamulticlear; - } - else { - // TODO fix -/* - for (i = 0; i < clen; i++) { - if (multipoll[i].revents & POLLIN) { - if (!uwsgi_parse_packet(&multipoll[i], PyInt_AsLong(arg_timeout), &uh, &buffer[i], uwsgi_proto_uwsgi_parser)) { - goto megamulticlear; - } - else { - if (PyTuple_SetItem(retobject, i, PyMarshal_ReadObjectFromString(&buffer[i], uh.pktsize))) { - PyErr_Print(); - goto megamulticlear; - } - close(multipoll[i].fd); - managed++; - } - } - } -*/ - } - } - - free(buffer); - - return retobject; - - megamulticlear: - - Py_DECREF(retobject); - - multiclear: - - for (i = 0; i < clen; i++) { - close(multipoll[i].fd); - } - clear: - - free(multipoll); - free(buffer); - - Py_INCREF(Py_None); - return Py_None; - -} PyObject *py_uwsgi_get_option(PyObject * self, PyObject * args) { @@ -2254,36 +1830,6 @@ PyObject *py_uwsgi_set_option(PyObject * self, PyObject * args) { return PyInt_FromLong(value); } -#ifdef UWSGI_MULTICAST -PyObject *py_uwsgi_multicast(PyObject * self, PyObject * args) { - - char *host, *message; - Py_ssize_t message_len; - ssize_t ret; - char *uwsgi_message; - - if (!PyArg_ParseTuple(args, "ss#:send_multicast_message", &host, &message, &message_len)) { - return NULL; - } - - uwsgi_message = uwsgi_malloc(message_len+4); - memcpy(uwsgi_message+4, message, message_len); - UWSGI_RELEASE_GIL - ret = send_udp_message(UWSGI_MODIFIER_MULTICAST, 0, host, uwsgi_message, message_len); - UWSGI_GET_GIL - free(uwsgi_message); - - if (ret <= 0) { - Py_INCREF(Py_None); - return Py_None; - } - - Py_INCREF(Py_True); - return Py_True; - -} -#endif - PyObject *py_uwsgi_has_hook(PyObject * self, PyObject * args) { int modifier1; @@ -2302,162 +1848,6 @@ PyObject *py_uwsgi_has_hook(PyObject * self, PyObject * args) { return Py_None; } -struct uwsgi_Iter; - -typedef struct uwsgi_Iter { - PyObject_HEAD int fd; - int timeout; - int close; - int started; - int has_cl; - uint16_t size; - uint16_t sent; - uint8_t modifier1; - uint8_t modifier2; - PyObject *(*func) (struct uwsgi_Iter *); -} uwsgi_Iter; - - -PyObject *uwsgi_Iter_iter(PyObject * self) { - Py_INCREF(self); - return self; -} - -PyObject *py_fcgi_iterator(uwsgi_Iter * ui) { - - uint16_t size = 0; - char body[0xffff]; - size = fcgi_get_record(ui->fd, body); - - if (size) { - return PyString_FromStringAndSize(body, size); - } - - return NULL; -} - -PyObject *uwsgi_Iter_next(PyObject * self) { - int rlen; - uwsgi_Iter *ui = (uwsgi_Iter *) self; - char buf[4096]; - int i = 4; - struct uwsgi_header uh; - char *ub = (char *) &uh; - PyObject *ptr; - - UWSGI_RELEASE_GIL if (ui->func) { - - ptr = ui->func(ui); - if (ptr) { - return ptr; - } - } - - - else { - - if (!ui->started) { - memset(&uh, 0, 4); - while (i) { - rlen = uwsgi_waitfd(ui->fd, ui->timeout); - if (rlen > 0) { - rlen = read(ui->fd, ub, i); - if (rlen <= 0) { - goto clear; - } - else { - i -= rlen; - ub += rlen; - } - } - else { - goto clear; - } - } - - ui->started = 1; - - if (uh.modifier1 == 'H') { - ui->size = 0; - UWSGI_GET_GIL return PyString_FromStringAndSize((char *) &uh, 4); - } - else { - ui->has_cl = 1; - ui->size = uh.pktsize; - ui->sent = 0; - } - } - - if (ui->sent >= ui->size && ui->has_cl) { - goto clear; - } - - rlen = uwsgi_waitfd(ui->fd, ui->timeout); - if (rlen > 0) { - if (ui->has_cl) { - rlen = read(ui->fd, buf, UMIN((ui->size - ui->sent), 4096)); - } - else { - rlen = read(ui->fd, buf, 4096); - } - if (rlen < 0) { - uwsgi_error("read()"); - } - else if (rlen > 0) { - ui->sent += rlen; - UWSGI_GET_GIL return PyString_FromStringAndSize(buf, rlen); - } - } - else if (rlen == 0) { - uwsgi_log("uwsgi request timed out waiting for response\n"); - } - } - - if (ui->close) { - close(ui->fd); - } - - clear: - UWSGI_GET_GIL PyErr_SetNone(PyExc_StopIteration); - - return NULL; -} - -static PyTypeObject uwsgi_IterType = { - PyVarObject_HEAD_INIT(NULL, 0) - "uwsgi._Iter", /*tp_name */ - sizeof(uwsgi_Iter), /*tp_basicsize */ - 0, /*tp_itemsize */ - 0, /*tp_dealloc */ - 0, /*tp_print */ - 0, /*tp_getattr */ - 0, /*tp_setattr */ - 0, /*tp_compare */ - 0, /*tp_repr */ - 0, /*tp_as_number */ - 0, /*tp_as_sequence */ - 0, /*tp_as_mapping */ - 0, /*tp_hash */ - 0, /*tp_call */ - 0, /*tp_str */ - 0, /*tp_getattro */ - 0, /*tp_setattro */ - 0, /*tp_as_buffer */ -#if defined(Py_TPFLAGS_HAVE_ITER) - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, -#else - Py_TPFLAGS_DEFAULT, -#endif - "uwsgi response iterator object.", /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - uwsgi_Iter_iter, /* tp_iter: __iter__() method */ - uwsgi_Iter_next /* tp_iternext: next() method */ -}; - - PyObject *py_uwsgi_connect(PyObject * self, PyObject * args) { char *socket_name = NULL; @@ -2531,243 +1921,7 @@ PyObject *py_uwsgi_async_send_message(PyObject * self, PyObject * args) { } -PyObject *py_uwsgi_fcgi(PyObject * self, PyObject * args) { - - char *node; - PyObject *dict; - int fd; - int i; - int stdin_fd = -1; - int stdin_size = 0; - ssize_t len; - char stdin_buf[0xffff]; - uwsgi_Iter *ui; - PyObject *zero, *key, *val; - - if (!PyArg_ParseTuple(args, "sO|ii:fcgi", &node, &dict, &stdin_fd, &stdin_size)) { - return NULL; - } - - fd = uwsgi_connect(node, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], 0); - - if (fd < 0) - goto clear2; - - if (!PyDict_Check(dict)) - goto clear; - - fcgi_send_record(fd, 1, 8, FCGI_BEGIN_REQUEST); - - PyObject *vars = PyDict_Items(dict); - - if (!vars) - goto clear; - - for (i = 0; i < PyList_Size(vars); i++) { - zero = PyList_GetItem(vars, i); - if (!zero) { - PyErr_Print(); - continue; - } - - key = PyTuple_GetItem(zero, 0); - val = PyTuple_GetItem(zero, 1); - - if (!PyString_Check(key) || !PyString_Check(val)) - continue; - - fcgi_send_param(fd, PyString_AsString(key), PyString_Size(key), PyString_AsString(val), PyString_Size(val)); - } - - fcgi_send_record(fd, 4, 0, ""); - - if (stdin_fd > -1 && stdin_size) { - while (stdin_size) { - len = read(stdin_fd, stdin_buf, UMIN(0xffff, stdin_size)); - if (len < 0) { - uwsgi_error("read()"); - break; - } - fcgi_send_record(fd, 5, len, stdin_buf); - stdin_size -= len; - } - } - fcgi_send_record(fd, 5, 0, ""); - - // request sent, return the iterator response - ui = PyObject_New(uwsgi_Iter, &uwsgi_IterType); - if (!ui) { - PyErr_Print(); - goto clear; - } - - ui->fd = fd; - ui->timeout = -1; - ui->close = 1; - ui->started = 0; - ui->has_cl = 0; - ui->sent = 0; - ui->size = 0; - ui->func = py_fcgi_iterator; - - return (PyObject *) ui; - - clear: - close(fd); - - clear2: - Py_INCREF(Py_None); - return Py_None; - -} - -PyObject *py_uwsgi_route(PyObject * self, PyObject * args) { - - char *addr = NULL; - struct wsgi_request *wsgi_req = current_wsgi_req(); - - if (!PyArg_ParseTuple(args, "s:route", &addr)) { - return NULL; - } - - UWSGI_RELEASE_GIL; - - int uwsgi_fd = uwsgi_connect(addr, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], 0); - - UWSGI_GET_GIL; - - if (uwsgi_fd < 0) { - return PyErr_Format(PyExc_IOError, "unable to connect to host %s", addr); - } - - UWSGI_RELEASE_GIL - if (uwsgi_send_message(uwsgi_fd, wsgi_req->uh.modifier1, wsgi_req->uh.modifier2, wsgi_req->buffer, wsgi_req->uh.pktsize, wsgi_req->poll.fd, wsgi_req->post_cl, 0) < 0) { - UWSGI_GET_GIL - return PyErr_Format(PyExc_IOError, "unable to send uwsgi request to host %s", addr); - } - UWSGI_GET_GIL - - // request sent, return the iterator response - uwsgi_Iter *ui = PyObject_New(uwsgi_Iter, &uwsgi_IterType); - if (!ui) { - uwsgi_log("unable to create uwsgi response object, better to reap the process\n"); - exit(1); - } - - ui->fd = uwsgi_fd; - ui->timeout = uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]; - ui->close = 1; - ui->started = 0; - ui->has_cl = 0; - ui->sent = 0; - ui->size = 0; - ui->func = NULL; - - // mark a route request - wsgi_req->via = UWSGI_VIA_ROUTE; - - return (PyObject *) ui; -} - -PyObject *py_uwsgi_send_message(PyObject * self, PyObject * args) { - - PyObject *destination = NULL, *pyobj = NULL; - - int modifier1 = 0; - int modifier2 = 0; - int timeout = uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]; - int fd = -1; - int cl = 0; - - int uwsgi_fd = -1; - char *encoded; - uint16_t esize = 0; - int close_fd = 0; - - uwsgi_Iter *ui; - - if (!PyArg_ParseTuple(args, "OiiO|iii:send_message", &destination, &modifier1, &modifier2, &pyobj, &timeout, &fd, &cl)) { - return NULL; - } - - // first of all get the fd for the destination - if (PyInt_Check(destination)) { - uwsgi_fd = PyInt_AsLong(destination); - } - else if (PyString_Check(destination)) { - UWSGI_RELEASE_GIL - uwsgi_fd = uwsgi_connect(PyString_AsString(destination), timeout, 0); - UWSGI_GET_GIL - close_fd = 1; - } - - if (uwsgi_fd < 0) - goto clear; - - - // now check for the type of object to send (fallback to marshal) - if (PyDict_Check(pyobj)) { - encoded = uwsgi_encode_pydict(pyobj, &esize); - if (esize > 0) { - UWSGI_RELEASE_GIL uwsgi_send_message(uwsgi_fd, (uint8_t) modifier1, (uint8_t) modifier2, encoded, esize, fd, cl, timeout); - free(encoded); - } - } - else if (PyString_Check(pyobj)) { - encoded = PyString_AsString(pyobj); - esize = PyString_Size(pyobj); - UWSGI_RELEASE_GIL uwsgi_send_message(uwsgi_fd, (uint8_t) modifier1, (uint8_t) modifier2, encoded, esize, fd, cl, timeout); - } -#ifndef UWSGI_PYPY - else { - PyObject *marshalled = PyMarshal_WriteObjectToString(pyobj, 1); - if (!marshalled) { - PyErr_Print(); - goto clear; - } - - encoded = PyString_AsString(marshalled); - esize = PyString_Size(marshalled); - UWSGI_RELEASE_GIL uwsgi_send_message(uwsgi_fd, (uint8_t) modifier1, (uint8_t) modifier2, encoded, esize, fd, cl, timeout); - } -#endif - - UWSGI_GET_GIL - - // if it is a fd passing request, return None - if (fd >=0 && cl == -1) { - Py_INCREF(Py_None); - return Py_None; - } - // request sent, return the iterator response - ui = PyObject_New(uwsgi_Iter, &uwsgi_IterType); - if (!ui) { - PyErr_Print(); - goto clear2; - } - - ui->fd = uwsgi_fd; - ui->timeout = timeout; - ui->close = close_fd; - ui->started = 0; - ui->has_cl = 0; - ui->sent = 0; - ui->size = 0; - ui->func = NULL; - - return (PyObject *) ui; - - clear2: - if (close_fd) - close(uwsgi_fd); - clear: - - Py_INCREF(Py_None); - return Py_None; - -} - - /* uWSGI masterpid */ +/* uWSGI masterpid */ PyObject *py_uwsgi_masterpid(PyObject * self, PyObject * args) { if (uwsgi.master_process) { return PyInt_FromLong(uwsgi.workers[0].pid); @@ -3239,7 +2393,6 @@ PyObject *py_uwsgi_grunt(PyObject * self, PyObject * args) { return Py_None; } -#ifdef UWSGI_SPOOLER static PyMethodDef uwsgi_spooler_methods[] = { #ifdef PYTHREE {"send_to_spooler", (PyCFunction) py_uwsgi_send_spool, METH_VARARGS | METH_KEYWORDS, ""}, @@ -3253,7 +2406,6 @@ static PyMethodDef uwsgi_spooler_methods[] = { {"spooler_pid", py_uwsgi_spooler_pid, METH_VARARGS, ""}, {NULL, NULL}, }; -#endif PyObject *py_uwsgi_suspend(PyObject * self, PyObject * args) { @@ -3267,90 +2419,7 @@ PyObject *py_uwsgi_suspend(PyObject * self, PyObject * args) { } -#ifdef UWSGI_MULTICAST -PyObject *py_uwsgi_cluster(PyObject * self, PyObject * args) { - - if (uwsgi.cluster) { - return PyString_FromString(uwsgi.cluster); - } - - Py_INCREF(Py_None); - return Py_None; -} - -PyObject *py_uwsgi_cluster_node_name(PyObject * self, PyObject * args) { - - struct uwsgi_cluster_node *ucn; - int i; - char *node = NULL; - - if (!PyArg_ParseTuple(args, "|s:cluster_node_name", &node)) { - return NULL; - } - - if (node == NULL) { - return PyString_FromString(uwsgi.hostname); - } - - for (i = 0; i < MAX_CLUSTER_NODES; i++) { - ucn = &uwsgi.shared->nodes[i]; - if (ucn->name[0] != 0) { -#ifdef UWSGI_DEBUG - uwsgi_log("node_name: %s %s\n", node, ucn->name); -#endif - if (!strcmp(ucn->name, node)) { - return PyString_FromString(ucn->nodename); - } - } - } - - Py_INCREF(Py_None); - return Py_None; - -} -PyObject *py_uwsgi_cluster_nodes(PyObject * self, PyObject * args) { - - struct uwsgi_cluster_node *ucn; - int i; - - PyObject *clist = PyList_New(0); - - for (i = 0; i < MAX_CLUSTER_NODES; i++) { - ucn = &uwsgi.shared->nodes[i]; - if (ucn->name[0] != 0) { - if (ucn->status == UWSGI_NODE_OK) { - PyList_Append(clist, PyString_FromString(ucn->name)); - } - } - } - - return clist; - -} - -PyObject *py_uwsgi_cluster_best_node(PyObject * self, PyObject * args) { - - char *node = uwsgi_cluster_best_node(); - if (node == NULL) - goto clear; - if (node[0] == 0) - goto clear; - return PyString_FromString(node); - - clear: - - Py_INCREF(Py_None); - return Py_None; -} - - -#endif - - static PyMethodDef uwsgi_advanced_methods[] = { - {"send_message", py_uwsgi_send_message, METH_VARARGS, ""}, - {"route", py_uwsgi_route, METH_VARARGS, ""}, - {"send_multi_message", py_uwsgi_send_multi_message, METH_VARARGS, ""}, {"reload", py_uwsgi_reload, METH_VARARGS, ""}, {"stop", py_uwsgi_stop, METH_VARARGS, ""}, {"workers", py_uwsgi_workers, METH_VARARGS, ""}, @@ -3400,17 +2469,9 @@ static PyMethodDef uwsgi_advanced_methods[] = { {"mem", py_uwsgi_mem, METH_VARARGS, ""}, {"has_hook", py_uwsgi_has_hook, METH_VARARGS, ""}, {"logsize", py_uwsgi_logsize, METH_VARARGS, ""}, -#ifdef UWSGI_MULTICAST - {"send_multicast_message", py_uwsgi_multicast, METH_VARARGS, ""}, - {"cluster_nodes", py_uwsgi_cluster_nodes, METH_VARARGS, ""}, - {"cluster_node_name", py_uwsgi_cluster_node_name, METH_VARARGS, ""}, - {"cluster", py_uwsgi_cluster, METH_VARARGS, ""}, - {"cluster_best_node", py_uwsgi_cluster_best_node, METH_VARARGS, ""}, -#endif #ifdef UWSGI_SSL {"i_am_the_lord", py_uwsgi_i_am_the_lord, METH_VARARGS, ""}, #endif -#ifdef UWSGI_ASYNC {"async_sleep", py_uwsgi_async_sleep, METH_VARARGS, ""}, {"async_connect", py_uwsgi_async_connect, METH_VARARGS, ""}, {"async_send_message", py_uwsgi_async_send_message, METH_VARARGS, ""}, @@ -3419,7 +2480,6 @@ static PyMethodDef uwsgi_advanced_methods[] = { {"suspend", py_uwsgi_suspend, METH_VARARGS, ""}, {"wait_fd_read", py_eventfd_read, METH_VARARGS, ""}, {"wait_fd_write", py_eventfd_write, METH_VARARGS, ""}, -#endif {"connect", py_uwsgi_connect, METH_VARARGS, ""}, {"connection_fd", py_uwsgi_connection_fd, METH_VARARGS, ""}, @@ -3427,12 +2487,9 @@ static PyMethodDef uwsgi_advanced_methods[] = { {"send", py_uwsgi_send, METH_VARARGS, ""}, {"recv", py_uwsgi_recv, METH_VARARGS, ""}, {"recv_block", py_uwsgi_recv_block, METH_VARARGS, ""}, - {"recv_frame", py_uwsgi_recv_frame, METH_VARARGS, ""}, {"close", py_uwsgi_close, METH_VARARGS, ""}, {"i_am_the_spooler", py_uwsgi_i_am_the_spooler, METH_VARARGS, ""}, - {"fcgi", py_uwsgi_fcgi, METH_VARARGS, ""}, - {"parsefile", py_uwsgi_parse_file, METH_VARARGS, ""}, {"embedded_data", py_uwsgi_embedded_data, METH_VARARGS, ""}, {"extract", py_uwsgi_extract, METH_VARARGS, ""}, @@ -3450,14 +2507,8 @@ static PyMethodDef uwsgi_advanced_methods[] = { {"websocket_recv", py_uwsgi_websocket_recv, METH_VARARGS, ""}, {"websocket_send", py_uwsgi_websocket_send, METH_VARARGS, ""}, - {"websocket_channel_join", py_uwsgi_websocket_channel_join, METH_VARARGS, ""}, {"websocket_handshake", py_uwsgi_websocket_handshake, METH_VARARGS, ""}, - {"channel_join", py_uwsgi_channel_join, METH_VARARGS, ""}, - {"channel_leave", py_uwsgi_channel_join, METH_VARARGS, ""}, - {"channel_send", py_uwsgi_channel_send, METH_VARARGS, ""}, - {"channel_recv", py_uwsgi_channel_recv, METH_VARARGS, ""}, - {NULL, NULL}, }; @@ -3502,7 +2553,7 @@ PyObject *py_uwsgi_cache_del(PyObject * self, PyObject * args) { if (remote && strlen(remote) > 0) { UWSGI_RELEASE_GIL - uwsgi_simple_send_string(remote, 111, 2, key, keylen, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); + //uwsgi_simple_send_string(remote, 111, 2, key, keylen, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); UWSGI_GET_GIL } else if (uwsgi.caches) { @@ -3544,7 +2595,7 @@ PyObject *py_uwsgi_cache_set(PyObject * self, PyObject * args) { if (remote && strlen(remote) > 0) { UWSGI_RELEASE_GIL - uwsgi_simple_send_string2(remote, 111, 1, key, keylen, value, vallen, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); + //uwsgi_simple_send_string2(remote, 111, 1, key, keylen, value, vallen, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); UWSGI_GET_GIL } else if (uwsgi.caches) { @@ -3585,7 +2636,7 @@ PyObject *py_uwsgi_cache_update(PyObject * self, PyObject * args) { if (remote && strlen(remote) > 0) { UWSGI_RELEASE_GIL - uwsgi_simple_send_string2(remote, 111, 1, key, keylen, value, vallen, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); + //uwsgi_simple_send_string2(remote, 111, 1, key, keylen, value, vallen, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); UWSGI_GET_GIL } else if (uwsgi.caches) { @@ -3613,9 +2664,6 @@ PyObject *py_uwsgi_cache_exists(PyObject * self, PyObject * args) { char *key; Py_ssize_t keylen = 0; char *remote = NULL; - uint16_t valsize; - // TODO remove this - char buffer[0xffff]; if (!PyArg_ParseTuple(args, "s#|s:cache_exists", &key, &keylen, &remote)) { return NULL; @@ -3624,12 +2672,14 @@ PyObject *py_uwsgi_cache_exists(PyObject * self, PyObject * args) { if (remote && strlen(remote) > 0) { // TODO FIX THIS !!! UWSGI_RELEASE_GIL - uwsgi_simple_message_string(remote, 111, 0, key, keylen, buffer, &valsize, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); + //uwsgi_simple_message_string(remote, 111, 0, key, keylen, buffer, &valsize, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); UWSGI_GET_GIL +/* if (valsize > 0) { Py_INCREF(Py_True); return Py_True; } +*/ } else if (uwsgi.caches) { UWSGI_RELEASE_GIL @@ -3944,11 +2994,11 @@ PyObject *py_uwsgi_cache_get(PyObject * self, PyObject * args) { char *key; uint64_t valsize; - uint16_t valsize16; + //uint16_t valsize16; Py_ssize_t keylen = 0; char *value = NULL; char *remote = NULL; - char buffer[0xffff]; + //char buffer[0xffff]; PyObject *ret; #ifdef UWSGI_DEBUG @@ -3961,12 +3011,14 @@ PyObject *py_uwsgi_cache_get(PyObject * self, PyObject * args) { if (remote && strlen(remote) > 0) { UWSGI_RELEASE_GIL - uwsgi_simple_message_string(remote, 111, 0, key, keylen, buffer, &valsize16, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); + //uwsgi_simple_message_string(remote, 111, 0, key, keylen, buffer, &valsize16, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); UWSGI_GET_GIL +/* if (valsize16 > 0) { value = buffer; valsize = valsize16; } +*/ } else if (uwsgi.caches) { #ifdef UWSGI_DEBUG @@ -4029,7 +3081,6 @@ static PyMethodDef uwsgi_queue_methods[] = { -#ifdef UWSGI_SPOOLER void init_uwsgi_module_spooler(PyObject * current_uwsgi_module) { PyMethodDef *uwsgi_function; PyObject *uwsgi_module_dict; @@ -4046,7 +3097,6 @@ void init_uwsgi_module_spooler(PyObject * current_uwsgi_module) { Py_DECREF(func); } } -#endif void init_uwsgi_module_advanced(PyObject * current_uwsgi_module) { PyMethodDef *uwsgi_function; @@ -4058,12 +3108,6 @@ void init_uwsgi_module_advanced(PyObject * current_uwsgi_module) { exit(1); } - uwsgi_IterType.tp_new = PyType_GenericNew; - if (PyType_Ready(&uwsgi_IterType) < 0) { - PyErr_Print(); - exit(1); - } - for (uwsgi_function = uwsgi_advanced_methods; uwsgi_function->ml_name != NULL; uwsgi_function++) { PyObject *func = PyCFunction_New(uwsgi_function, NULL); PyDict_SetItemString(uwsgi_module_dict, uwsgi_function->ml_name, func); @@ -4126,7 +3170,6 @@ void init_uwsgi_module_sharedarea(PyObject * current_uwsgi_module) { } } -#ifdef UWSGI_SNMP PyObject *py_snmp_set_counter32(PyObject * self, PyObject * args) { uint8_t oid_num; @@ -4469,7 +3512,3 @@ void init_uwsgi_module_snmp(PyObject * current_uwsgi_module) { uwsgi_log( "SNMP python functions initialized.\n"); } -#endif - - -#endif diff --git a/plugins/python/uwsgi_python.h b/plugins/python/uwsgi_python.h index a7838133..92e64bfb 100644 --- a/plugins/python/uwsgi_python.h +++ b/plugins/python/uwsgi_python.h @@ -26,13 +26,8 @@ #define PYTHREE #endif -#ifdef UWSGI_THREADING #define UWSGI_GET_GIL up.gil_get(); #define UWSGI_RELEASE_GIL up.gil_release(); -#else -#define UWSGI_GET_GIL -#define UWSGI_RELEASE_GIL -#endif #ifndef PyVarObject_HEAD_INIT #define PyVarObject_HEAD_INIT(x, y) PyObject_HEAD_INIT(x) y, @@ -85,15 +80,8 @@ PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromString(char *, Py_ssize_t); #define LOADER_MAX 8 -#define UWSGI_PY_READLINE_BUFSIZE 1024 - typedef struct uwsgi_Input { PyObject_HEAD - char readline[UWSGI_PY_READLINE_BUFSIZE]; - size_t readline_size; - size_t readline_max_size; - size_t readline_pos; - size_t pos; struct wsgi_request *wsgi_req; } uwsgi_Input; @@ -153,7 +141,6 @@ struct uwsgi_python { void (*swap_ts)(struct wsgi_request *, struct uwsgi_app *); void (*reset_ts)(struct wsgi_request *, struct uwsgi_app *); -#ifdef UWSGI_THREADING pthread_key_t upt_save_key; pthread_key_t upt_gil_key; pthread_mutex_t lock_pyloaders; @@ -162,7 +149,6 @@ struct uwsgi_python { int auto_reload; char *tracebacker; struct uwsgi_string_list *auto_reload_ignore; -#endif PyObject *workers_tuple; PyObject *embedded_dict; @@ -186,9 +172,6 @@ struct uwsgi_python { char *pyrun; int start_response_nodelay; - ssize_t (*hook_wsgi_input_read)(struct wsgi_request *, char *, size_t, size_t *); - ssize_t (*hook_wsgi_input_readline)(struct wsgi_request *, char *, size_t); - char *programname; }; @@ -280,9 +263,6 @@ int uwsgi_python_do_send_headers(struct wsgi_request *); void *uwsgi_python_tracebacker_thread(void *); PyObject *uwsgi_python_setup_thread(char *); -ssize_t uwsgi_python_hook_simple_input_read(struct wsgi_request *, char *, size_t, size_t *); -ssize_t uwsgi_python_hook_simple_input_readline(struct wsgi_request *, char *, size_t); - #ifdef UWSGI_PYPY #undef UWSGI_MINTERPRETERS #endif diff --git a/plugins/python/web3_subhandler.c b/plugins/python/web3_subhandler.c index 9047a8e9..1763990f 100644 --- a/plugins/python/web3_subhandler.c +++ b/plugins/python/web3_subhandler.c @@ -28,8 +28,8 @@ void *uwsgi_request_subhandler_web3(struct wsgi_request *wsgi_req, struct uwsgi_ Py_DECREF(pydictvalue); } - if (wsgi_req->uh.modifier1 == UWSGI_MODIFIER_MANAGE_PATH_INFO) { - wsgi_req->uh.modifier1 = 0; + if (wsgi_req->uh->modifier1 == UWSGI_MODIFIER_MANAGE_PATH_INFO) { + wsgi_req->uh->modifier1 = 0; pydictkey = PyDict_GetItemString(wsgi_req->async_environ, "SCRIPT_NAME"); if (pydictkey) { if (PyString_Check(pydictkey)) { @@ -44,23 +44,9 @@ void *uwsgi_request_subhandler_web3(struct wsgi_request *wsgi_req, struct uwsgi_ } } - // if async_post is mapped as a file, directly use it as wsgi.input - if (wsgi_req->async_post) { -#ifdef PYTHREE - wsgi_req->async_input = PyFile_FromFd(fileno((FILE *)wsgi_req->async_post), "web3_input", "rb", 0, NULL, NULL, NULL, 0); -#else - wsgi_req->async_input = PyFile_FromFile(wsgi_req->async_post, "web3_input", "r", NULL); -#endif - } - else { - // create wsgi.input custom object - wsgi_req->async_input = (PyObject *) PyObject_New(uwsgi_Input, &uwsgi_InputType); - ((uwsgi_Input*)wsgi_req->async_input)->wsgi_req = wsgi_req; - ((uwsgi_Input*)wsgi_req->async_input)->pos = 0; - ((uwsgi_Input*)wsgi_req->async_input)->readline_pos = 0; - ((uwsgi_Input*)wsgi_req->async_input)->readline_max_size = 0; - - } + // create wsgi.input custom object + wsgi_req->async_input = (PyObject *) PyObject_New(uwsgi_Input, &uwsgi_InputType); + ((uwsgi_Input*)wsgi_req->async_input)->wsgi_req = wsgi_req; PyDict_SetItemString(wsgi_req->async_environ, "web3.input", wsgi_req->async_input); @@ -111,16 +97,6 @@ void *uwsgi_request_subhandler_web3(struct wsgi_request *wsgi_req, struct uwsgi_ PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.core", PyInt_FromLong(wsgi_req->async_id)); } - // cache this ? - if (uwsgi.cluster_fd >= 0) { - zero = PyString_FromString(uwsgi.cluster); - PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.cluster", zero); - Py_DECREF(zero); - zero = PyString_FromString(uwsgi.hostname); - PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.cluster_node", zero); - Py_DECREF(zero); - } - PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.node", wi->uwsgi_node); @@ -187,11 +163,9 @@ int uwsgi_response_subhandler_web3(struct wsgi_request *wsgi_req) { if (!wsgi_req->async_placeholder) { goto clear; } -#ifdef UWSGI_ASYNC if (uwsgi.async > 1) { return UWSGI_AGAIN; } -#endif } else { uwsgi_log("invalid Web3 response.\n"); diff --git a/plugins/python/wsgi_handlers.c b/plugins/python/wsgi_handlers.c index a9f77e75..36c69446 100644 --- a/plugins/python/wsgi_handlers.c +++ b/plugins/python/wsgi_handlers.c @@ -9,88 +9,37 @@ PyObject *uwsgi_Input_iter(PyObject *self) { return self; } -ssize_t uwsgi_python_hook_simple_input_readline(struct wsgi_request *wsgi_req, char *readline, size_t max_size) { - ssize_t rlen = 0; - UWSGI_RELEASE_GIL; - if (uwsgi_waitfd(wsgi_req->poll.fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]) <= 0) { - UWSGI_GET_GIL - return 0; - } - - if (max_size > 0 && max_size < UWSGI_PY_READLINE_BUFSIZE) { - rlen = read(wsgi_req->poll.fd, readline, max_size); - } - else { - rlen = read(wsgi_req->poll.fd, readline, UWSGI_PY_READLINE_BUFSIZE); - } - UWSGI_GET_GIL; - return rlen; -} - -PyObject *uwsgi_Input_getline(uwsgi_Input *self) { - size_t i; - ssize_t rlen; +PyObject *uwsgi_Input_getline(uwsgi_Input *self, long hint) { struct wsgi_request *wsgi_req = self->wsgi_req; - PyObject *res; + ssize_t rlen = 0; - char *ptr = self->readline; - - if (uwsgi.post_buffering > 0) { - ptr = wsgi_req->post_buffering_buf; - self->readline_size = wsgi_req->post_cl; - if (!self->readline_pos) { - self->pos += self->readline_size; - } + char *buf = uwsgi_request_body_readline(wsgi_req, hint, &rlen); + if (buf == uwsgi.empty) { + return PyString_FromString(""); + } + if (buf) { + return PyString_FromStringAndSize(buf, rlen); } - if (self->readline_pos > 0 || uwsgi.post_buffering) { - for(i=self->readline_pos;ireadline_size;i++) { - if (ptr[i] == '\n') { - res = PyString_FromStringAndSize(ptr+self->readline_pos, (i-self->readline_pos)+1); - self->readline_pos = i+1; - if (self->readline_pos >= self->readline_size) self->readline_pos = 0; - return res; - } - } - res = PyString_FromStringAndSize(ptr + self->readline_pos, self->readline_size - self->readline_pos); - self->readline_pos = 0; - return res; - } - - - rlen = up.hook_wsgi_input_readline(wsgi_req, self->readline, self->readline_max_size); if (rlen < 0) { - return PyErr_Format(PyExc_IOError, "error reading for wsgi.input data (readline/getline)"); + return PyErr_Format(PyExc_IOError, "error during readline(%ld) on wsgi.input", hint); } - else if (rlen == 0) { - return PyErr_Format(PyExc_IOError, "error waiting for wsgi.input data (readline/getline)"); - } - self->readline_size = rlen; - self->readline_pos = 0; - self->pos += rlen; - - for(i=0;i<(size_t)rlen;i++) { - if (self->readline[i] == '\n') { - res = PyString_FromStringAndSize(self->readline, i+1); - self->readline_pos+= i+1; - if (self->readline_pos >= self->readline_size) self->readline_pos = 0; - return res; - } - } - self->readline_pos = 0; - return PyString_FromStringAndSize(self->readline, self->readline_size); - + return PyErr_Format(PyExc_IOError, "timeout during readline(%ld) on wsgi.input", hint); } PyObject *uwsgi_Input_next(PyObject* self) { - if (!((uwsgi_Input *)self)->wsgi_req->post_cl || ((size_t) ((uwsgi_Input *)self)->pos >= ((uwsgi_Input *)self)->wsgi_req->post_cl && !((uwsgi_Input *)self)->readline_pos)) { + PyObject *line = uwsgi_Input_getline((uwsgi_Input *)self, 0); + if (!line) return NULL; + + if (PyString_Size(line) == 0) { + Py_DECREF(line); PyErr_SetNone(PyExc_StopIteration); return NULL; } - return uwsgi_Input_getline((uwsgi_Input *)self); + return line; } @@ -98,129 +47,77 @@ static void uwsgi_Input_free(uwsgi_Input *self) { PyObject_Del(self); } -ssize_t uwsgi_python_hook_simple_input_read(struct wsgi_request *wsgi_req, char *tmp_buf, size_t remains, size_t *tmp_pos) { - - UWSGI_RELEASE_GIL - - while(remains) { - if (uwsgi_waitfd(wsgi_req->poll.fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]) <= 0) { - UWSGI_GET_GIL - return 0; - } - - ssize_t rlen = read(wsgi_req->poll.fd, tmp_buf+*tmp_pos, remains); - if (rlen <= 0) { - UWSGI_GET_GIL - return -1; - } - *tmp_pos += rlen; - remains -= rlen; - } - - UWSGI_GET_GIL - return *tmp_pos; - -} - static PyObject *uwsgi_Input_read(uwsgi_Input *self, PyObject *args) { - long len = 0; - size_t remains; - size_t tmp_pos = 0; - char *tmp_buf; - PyObject *res; + long arg_len = 0; - if (!PyArg_ParseTuple(args, "|l:read", &len)) { + if (!PyArg_ParseTuple(args, "|l:read", &arg_len)) { return NULL; } - // return empty string if no post_cl or pos >= post_cl - if ((!self->wsgi_req->post_cl || (size_t) self->pos >= self->wsgi_req->post_cl ) && !self->readline_pos) { + struct wsgi_request *wsgi_req = self->wsgi_req; + ssize_t rlen = 0; + + char *buf = uwsgi_request_body_read(wsgi_req, arg_len, &rlen); + if (buf == uwsgi.empty) { return PyString_FromString(""); } - // some residual data ? - if (self->readline_pos && self->readline_size) { - if (len > 0) { - if ((size_t) len < (self->readline_size - self->readline_pos)) { - res = PyString_FromStringAndSize(self->readline + self->readline_pos, len); - self->readline_pos+=len; - if (self->readline_pos >= self->readline_size) self->readline_pos = 0; - return res; - } - } - self->readline_pos = 0; - return PyString_FromStringAndSize(self->readline + self->readline_pos, self->readline_size - self->readline_pos); + if (buf) { + return PyString_FromStringAndSize(buf, rlen); } - // return the whole input - if (len <= 0) { - remains = self->wsgi_req->post_cl; - } - else { - remains = len ; - } - - if (remains + self->pos > self->wsgi_req->post_cl) { - remains = self->wsgi_req->post_cl - self->pos; - } - - if (remains <= 0) { - return PyString_FromString(""); - } - - if (uwsgi.post_buffering > 0) { - res = PyString_FromStringAndSize( self->wsgi_req->post_buffering_buf+self->pos, remains); - self->pos += remains; - return res; - } - - tmp_buf = uwsgi_malloc(remains); - - ssize_t rlen = up.hook_wsgi_input_read(self->wsgi_req, tmp_buf, remains, &tmp_pos); + // error ? if (rlen < 0) { - free(tmp_buf); - return PyErr_Format(PyExc_IOError, "error reading for wsgi.input data: Content-Length %llu requested %llu received %llu pos %llu+%llu", (unsigned long long) self->wsgi_req->post_cl, (unsigned long long) remains, (unsigned long long) tmp_pos, (unsigned long long) self->pos, (unsigned long long) tmp_pos); - } - else if (rlen == 0) { - free(tmp_buf); - return PyErr_Format(PyExc_IOError, "error waiting for wsgi.input data: Content-Length %llu requested %llu received %llu pos %llu+%llu", (unsigned long long) self->wsgi_req->post_cl, (unsigned long long) remains, (unsigned long long) tmp_pos, (unsigned long long) self->pos, (unsigned long long) tmp_pos); + return PyErr_Format(PyExc_IOError, "error during read(%ld) on wsgi.input", arg_len); } - self->pos += tmp_pos; - res = PyString_FromStringAndSize(tmp_buf, tmp_pos); - free(tmp_buf); - return res; + // timeout ? + return PyErr_Format(PyExc_IOError, "timeout during read(%ld) on wsgi.input", arg_len); } static PyObject *uwsgi_Input_readline(uwsgi_Input *self, PyObject *args) { - if (!PyArg_ParseTuple(args, "|l:readline", &((uwsgi_Input *)self)->readline_max_size)) { + long hint = 0; + + if (!PyArg_ParseTuple(args, "|l:readline", &hint)) { return NULL; } - if (!((uwsgi_Input *)self)->wsgi_req->post_cl || ((size_t) ((uwsgi_Input *)self)->pos >= ((uwsgi_Input *)self)->wsgi_req->post_cl && !((uwsgi_Input *)self)->readline_pos)) { + PyObject *line = uwsgi_Input_getline(self, hint); + if (!line) return NULL; + + if (PyString_Size(line) == 0) { + Py_DECREF(line); return PyString_FromString(""); } - return uwsgi_Input_getline(self); + return line; } static PyObject *uwsgi_Input_readlines(uwsgi_Input *self, PyObject *args) { - PyObject *res; + long hint = 0; - if (!((uwsgi_Input *)self)->wsgi_req->post_cl || ((size_t) ((uwsgi_Input *)self)->pos >= ((uwsgi_Input *)self)->wsgi_req->post_cl && !((uwsgi_Input *)self)->readline_pos)) { - Py_INCREF(Py_None); - return Py_None; - } + if (!PyArg_ParseTuple(args, "|l:readline", &hint)) { + return NULL; + } - res = PyList_New(0); - while( ((size_t) ((uwsgi_Input *)self)->pos < ((uwsgi_Input *)self)->wsgi_req->post_cl || ((uwsgi_Input *)self)->readline_pos > 0)) { - PyObject *a_line = uwsgi_Input_getline(self); - PyList_Append(res, a_line); - Py_DECREF(a_line); + + PyObject *res = PyList_New(0); + for(;;) { + PyObject *line = uwsgi_Input_getline(self, hint); + if (!line) { + Py_DECREF(res); + return NULL; + } + if (PyString_Size(line) == 0) { + Py_DECREF(line); + return res; + } + PyList_Append(res, line); + Py_DECREF(line); } return res; @@ -234,7 +131,7 @@ static PyObject *uwsgi_Input_close(uwsgi_Input *self, PyObject *args) { static PyObject *uwsgi_Input_fileno(uwsgi_Input *self, PyObject *args) { - return PyInt_FromLong(self->wsgi_req->poll.fd); + return PyInt_FromLong(self->wsgi_req->fd); } static PyMethodDef uwsgi_Input_methods[] = { @@ -311,9 +208,6 @@ PyObject *py_uwsgi_write(PyObject * self, PyObject * args) { return Py_None; } -#ifdef UWSGI_ASYNC - - PyObject *py_eventfd_read(PyObject * self, PyObject * args) { int fd, timeout = 0; @@ -346,7 +240,6 @@ PyObject *py_eventfd_write(PyObject * self, PyObject * args) { return PyString_FromString(""); } -#endif int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) { @@ -355,7 +248,6 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) { int tmp_stderr; int free_appid = 0; -#ifdef UWSGI_ASYNC if (wsgi_req->async_status == UWSGI_AGAIN) { wi = &uwsgi_apps[wsgi_req->app_id]; UWSGI_GET_GIL @@ -380,11 +272,9 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) { UWSGI_RELEASE_GIL return ret; } -#endif - /* Standard WSGI request */ - if (!wsgi_req->uh.pktsize) { + if (!wsgi_req->uh->pktsize) { uwsgi_log( "Empty python request. skip.\n"); return -1; } @@ -477,17 +367,13 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) { while (wi->response_subhandler(wsgi_req) != UWSGI_OK) { -#ifdef UWSGI_ASYNC if (uwsgi.async > 1) { UWSGI_RELEASE_GIL return UWSGI_AGAIN; } else { -#endif wsgi_req->switches++; -#ifdef UWSGI_ASYNC } -#endif } @@ -502,7 +388,7 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) { /* sorry that is a hack to avoid the rewrite of PyErr_Print - temporarily map (using dup2) stderr to wsgi_req->poll.fd + temporarily map (using dup2) stderr to wsgi_req->fd */ tmp_stderr = dup(2); if (tmp_stderr < 0) { @@ -510,7 +396,7 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) { goto clear; } // map 2 to wsgi_req - if (dup2(wsgi_req->poll.fd, 2) < 0) { + if (dup2(wsgi_req->fd, 2) < 0) { close(tmp_stderr); uwsgi_error("dup2()"); goto clear; @@ -527,9 +413,7 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) { } // this object must be freed/cleared always -#ifdef UWSGI_ASYNC end: -#endif if (wsgi_req->async_input) { Py_DECREF((PyObject *)wsgi_req->async_input); } diff --git a/plugins/python/wsgi_subhandler.c b/plugins/python/wsgi_subhandler.c index ad2926d4..60a34e17 100644 --- a/plugins/python/wsgi_subhandler.c +++ b/plugins/python/wsgi_subhandler.c @@ -32,8 +32,8 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_ Py_DECREF(pydictvalue); } - if (wsgi_req->uh.modifier1 == UWSGI_MODIFIER_MANAGE_PATH_INFO) { - wsgi_req->uh.modifier1 = 0; + if (wsgi_req->uh->modifier1 == UWSGI_MODIFIER_MANAGE_PATH_INFO) { + wsgi_req->uh->modifier1 = 0; pydictkey = PyDict_GetItemString(wsgi_req->async_environ, "SCRIPT_NAME"); if (pydictkey) { if (PyString_Check(pydictkey)) { @@ -49,36 +49,20 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_ } - // if async_post is mapped as a file, directly use it as wsgi.input - if (wsgi_req->async_post) { -#ifdef PYTHREE - wsgi_req->async_input = PyFile_FromFd(fileno((FILE *)wsgi_req->async_post), "wsgi_input", "rb", 0, NULL, NULL, NULL, 0); -#else - wsgi_req->async_input = PyFile_FromFile(wsgi_req->async_post, "wsgi_input", "r", NULL); -#endif - } - else { - // create wsgi.input custom object - wsgi_req->async_input = (PyObject *) PyObject_New(uwsgi_Input, &uwsgi_InputType); - ((uwsgi_Input*)wsgi_req->async_input)->wsgi_req = wsgi_req; - ((uwsgi_Input*)wsgi_req->async_input)->pos = 0; - ((uwsgi_Input*)wsgi_req->async_input)->readline_pos = 0; - ((uwsgi_Input*)wsgi_req->async_input)->readline_max_size = 0; - - } + // create wsgi.input custom object + wsgi_req->async_input = (PyObject *) PyObject_New(uwsgi_Input, &uwsgi_InputType); + ((uwsgi_Input*)wsgi_req->async_input)->wsgi_req = wsgi_req; PyDict_SetItemString(wsgi_req->async_environ, "wsgi.input", wsgi_req->async_input); PyDict_SetItemString(wsgi_req->async_environ, "wsgi.file_wrapper", wi->sendfile); -#ifdef UWSGI_ASYNC if (uwsgi.async > 1) { PyDict_SetItemString(wsgi_req->async_environ, "x-wsgiorg.fdevent.readable", wi->eventfd_read); PyDict_SetItemString(wsgi_req->async_environ, "x-wsgiorg.fdevent.writable", wi->eventfd_write); PyDict_SetItemString(wsgi_req->async_environ, "x-wsgiorg.fdevent.timeout", Py_None); } -#endif PyDict_SetItemString(wsgi_req->async_environ, "wsgi.version", wi->gateway_version); @@ -134,16 +118,6 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_ Py_DECREF(zero); } - // cache this ? - if (uwsgi.cluster_fd >= 0) { - zero = PyString_FromString(uwsgi.cluster); - PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.cluster", zero); - Py_DECREF(zero); - zero = PyString_FromString(uwsgi.hostname); - PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.cluster_node", zero); - Py_DECREF(zero); - } - PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.node", wi->uwsgi_node); // call @@ -185,11 +159,9 @@ int uwsgi_response_subhandler_wsgi(struct wsgi_request *wsgi_req) { if (!wsgi_req->async_placeholder) { goto exception; } -#ifdef UWSGI_ASYNC if (uwsgi.async > 1) { return UWSGI_AGAIN; } -#endif } pychunk = PyIter_Next(wsgi_req->async_placeholder); diff --git a/plugins/rack/rack_api.c b/plugins/rack/rack_api.c index 721b5bbd..15b2af26 100644 --- a/plugins/rack/rack_api.c +++ b/plugins/rack/rack_api.c @@ -36,12 +36,9 @@ VALUE rack_uwsgi_log(VALUE *class, VALUE msg) { } VALUE rack_uwsgi_i_am_the_spooler(VALUE *class) { -#ifdef UWSGI_SPOOLER if (uwsgi.i_am_a_spooler) { return Qtrue; } -#endif - return Qfalse; } @@ -498,7 +495,6 @@ VALUE rack_uwsgi_add_file_monitor(VALUE *class, VALUE rbsignum, VALUE rbfilename } -#ifdef UWSGI_ASYNC VALUE uwsgi_ruby_wait_fd_read(VALUE *class, VALUE arg1, VALUE arg2) { Check_Type(arg1, T_FIXNUM); @@ -533,9 +529,6 @@ VALUE uwsgi_ruby_wait_fd_write(VALUE *class, VALUE arg1, VALUE arg2) { return Qtrue; } -#endif - - VALUE uwsgi_ruby_async_connect(VALUE *class, VALUE arg) { @@ -547,7 +540,6 @@ VALUE uwsgi_ruby_async_connect(VALUE *class, VALUE arg) { } -#ifdef UWSGI_ASYNC VALUE uwsgi_ruby_async_sleep(VALUE *class, VALUE arg) { Check_Type(arg, T_FIXNUM); @@ -561,7 +553,6 @@ VALUE uwsgi_ruby_async_sleep(VALUE *class, VALUE arg) { return Qtrue; } -#endif VALUE uwsgi_ruby_masterpid(VALUE *class) { @@ -887,11 +878,9 @@ void uwsgi_rack_init_api() { VALUE rb_uwsgi_embedded = rb_define_module("UWSGI"); uwsgi_rack_api("suspend", uwsgi_ruby_suspend, 0); uwsgi_rack_api("masterpid", uwsgi_ruby_masterpid, 0); -#ifdef UWSGI_ASYNC uwsgi_rack_api("async_sleep", uwsgi_ruby_async_sleep, 1); uwsgi_rack_api("wait_fd_read", uwsgi_ruby_wait_fd_read, 2); uwsgi_rack_api("wait_fd_write", uwsgi_ruby_wait_fd_write, 2); -#endif uwsgi_rack_api("async_connect", uwsgi_ruby_async_connect, 1); uwsgi_rack_api("signal", uwsgi_ruby_signal, -1); uwsgi_rack_api("register_signal", uwsgi_ruby_register_signal, 3); diff --git a/plugins/rack/rack_plugin.c b/plugins/rack/rack_plugin.c index 0aa918af..877c5af7 100644 --- a/plugins/rack/rack_plugin.c +++ b/plugins/rack/rack_plugin.c @@ -76,34 +76,15 @@ VALUE rb_uwsgi_io_init(int argc, VALUE *argv, VALUE self) { VALUE rb_uwsgi_io_gets(VALUE obj, VALUE args) { - size_t i; struct wsgi_request *wsgi_req; - VALUE line; Data_Get_Struct(obj, struct wsgi_request, wsgi_req); - char linebuf[4096]; - if (wsgi_req->async_post) { - if (fgets(linebuf, 4096, (FILE *) wsgi_req->async_post) == NULL) { - return Qnil; - } - return rb_str_new2(linebuf); - } + ssize_t rlen = 0; - // return a line of body - for(i=wsgi_req->buf_pos;ipost_cl;i++) { - if (wsgi_req->post_buffering_buf[i] == '\n') { - line = rb_str_new(wsgi_req->post_buffering_buf+wsgi_req->buf_pos, (i+1)-wsgi_req->buf_pos); - wsgi_req->buf_pos = i+1; - return line; - } + char *buf = uwsgi_request_body_readline(wsgi_req, 0, &rlen); + if (buf) { + return rb_str_new(buf, rlen); } - - if (wsgi_req->buf_pos < wsgi_req->post_cl) { - line = rb_str_new(wsgi_req->post_buffering_buf+wsgi_req->buf_pos, wsgi_req->post_cl-wsgi_req->buf_pos); - wsgi_req->buf_pos = wsgi_req->post_cl; - return line; - } - return Qnil; } @@ -128,101 +109,31 @@ VALUE rb_uwsgi_io_read(VALUE obj, VALUE args) { struct wsgi_request *wsgi_req; Data_Get_Struct(obj, struct wsgi_request, wsgi_req); - VALUE chunk; - long chunk_size; + long hint = 0; + int length_given = 0; /* When EOF is reached, this method returns nil if length is given and not nil, or "" if length is not given or is nil. If buffer is given, then the read data will be placed into buffer instead of a newly created String object. */ - // --- disk buffering --- - - if (wsgi_req->async_post) { - // 0 size, read the whole body from the file... - if (RARRAY_LEN(args) == 0) { - char *tmp_chunk = uwsgi_malloc(wsgi_req->post_cl); - size_t rlen = fread(tmp_chunk, 1, wsgi_req->post_cl, (FILE *) wsgi_req->async_post); - if (rlen == 0) { - free(tmp_chunk); - return rb_str_new("", 0); - } - // return a new string - chunk = rb_str_new(tmp_chunk, rlen); - free(tmp_chunk); - return chunk; + if (RARRAY_LEN(args) > 0) { + if (RARRAY_PTR(args)[0] != Qnil) { + hint = NUM2LONG(RARRAY_PTR(args)[0]); + length_given = 1; } - // size specified - else if (RARRAY_LEN(args) > 0) { - if (RARRAY_PTR(args)[0] == Qnil) { - chunk_size = wsgi_req->post_cl; - } - else { - chunk_size = NUM2LONG(RARRAY_PTR(args)[0]); - // hack to tolerate broken middlewares - if (chunk_size <= 0) { - chunk_size = wsgi_req->post_cl; - } - } - char *tmp_chunk = uwsgi_malloc(chunk_size); - size_t rlen = fread(tmp_chunk, 1, chunk_size, (FILE *) wsgi_req->async_post); - // error, return Qnil - if (rlen == 0) { - free(tmp_chunk); - return Qnil; - } - // push in the specified buffer - if (RARRAY_LEN(args) > 1) { - rb_str_cat(RARRAY_PTR(args)[1], tmp_chunk, rlen); - } - // return a new string - chunk = rb_str_new(tmp_chunk, rlen); - free(tmp_chunk); - return chunk; - } - // never happend... - return Qnil; } - // --- memory buffering --- - - // first check for virtual EOF - if (!wsgi_req->post_cl || wsgi_req->buf_pos >= wsgi_req->post_cl) { - if (RARRAY_LEN(args) > 0) { - if (RARRAY_PTR(args)[0] == Qnil) { - return rb_str_new("", 0); - } + ssize_t rlen = 0; + char *buf = uwsgi_request_body_read(wsgi_req, hint, &rlen); + if (buf) { + if (length_given && buf == uwsgi.empty) { return Qnil; } - - return rb_str_new("", 0); - } - - if (RARRAY_LEN(args) == 0) { - chunk = rb_str_new(wsgi_req->post_buffering_buf+wsgi_req->buf_pos, wsgi_req->post_cl-wsgi_req->buf_pos); - wsgi_req->buf_pos += (wsgi_req->post_cl-wsgi_req->buf_pos); - return chunk; - } - else if (RARRAY_LEN(args) > 0) { - if (RARRAY_PTR(args)[0] == Qnil) { - chunk_size = wsgi_req->post_cl; - } - else { - chunk_size = NUM2LONG(RARRAY_PTR(args)[0]); - // hack to tolerate broken middlewares - if (chunk_size <= 0) { - chunk_size = wsgi_req->post_cl; - } - } - if (wsgi_req->buf_pos+chunk_size > wsgi_req->post_cl) { - chunk_size = wsgi_req->post_cl-wsgi_req->buf_pos; - } if (RARRAY_LEN(args) > 1) { - rb_str_cat(RARRAY_PTR(args)[1], wsgi_req->post_buffering_buf+wsgi_req->buf_pos, chunk_size); - } - chunk = rb_str_new(wsgi_req->post_buffering_buf+wsgi_req->buf_pos, chunk_size); - wsgi_req->buf_pos+=chunk_size; - return chunk; + rb_str_cat(RARRAY_PTR(args)[1], buf, rlen); + } + return rb_str_new(buf, rlen); } return Qnil; @@ -232,19 +143,7 @@ VALUE rb_uwsgi_io_rewind(VALUE obj, VALUE args) { struct wsgi_request *wsgi_req; Data_Get_Struct(obj, struct wsgi_request, wsgi_req); - - if (!wsgi_req->post_cl) { - return Qnil; - } - - // buffered to disk ? - if (wsgi_req->async_post) { - rewind((FILE *) wsgi_req->async_post); - } - // or memory ??? - else { - wsgi_req->buf_pos = 0; - } + uwsgi_request_body_seek(wsgi_req, 0); return Qnil; } @@ -458,9 +357,7 @@ int uwsgi_rack_init(){ rb_gc_register_address(&ur.rpc_protector); -#ifdef UWSGI_EMBEDDED uwsgi_rack_init_api(); -#endif return 0; } @@ -749,8 +646,8 @@ int uwsgi_rack_request(struct wsgi_request *wsgi_req) { } /* Standard RACK request */ - if (!wsgi_req->uh.pktsize) { - uwsgi_log("Invalid RACK request. skip.\n"); + if (!wsgi_req->uh->pktsize) { + uwsgi_log("Empty RACK request. skip.\n"); return -1; } diff --git a/plugins/rawrouter/rawrouter.c b/plugins/rawrouter/rawrouter.c index d72da5d3..7c2a76f7 100644 --- a/plugins/rawrouter/rawrouter.c +++ b/plugins/rawrouter/rawrouter.c @@ -38,8 +38,6 @@ static struct uwsgi_option rawrouter_options[] = { {"rawrouter-fallback", required_argument, 0, "fallback to the specified node in case of error", uwsgi_opt_add_string_list, &urr.cr.fallback, 0}, - {"rawrouter-use-cluster", no_argument, 0, "load balance to nodes subscribed to the cluster", uwsgi_opt_true, &urr.cr.use_cluster, 0}, - {"rawrouter-use-code-string", required_argument, 0, "use code string as hostname->server mapper for the rawrouter", uwsgi_opt_corerouter_cs, &urr, 0}, {"rawrouter-use-socket", optional_argument, 0, "forward request to the specified uwsgi socket", uwsgi_opt_corerouter_use_socket, &urr, 0}, {"rawrouter-to", required_argument, 0, "forward requests to the specified uwsgi server (you can specify it multiple times for load balancing)", uwsgi_opt_add_string_list, &urr.cr.static_nodes, 0}, diff --git a/plugins/router_basicauth/router_basicauth.c b/plugins/router_basicauth/router_basicauth.c index a61dd8e4..f476805b 100644 --- a/plugins/router_basicauth/router_basicauth.c +++ b/plugins/router_basicauth/router_basicauth.c @@ -5,10 +5,8 @@ #ifdef __linux__ #include #else -#ifdef UWSGI_THREADING pthread_mutex_t ur_basicauth_crypt_mutex; #endif -#endif extern struct uwsgi_server uwsgi; diff --git a/plugins/router_http/router_http.c b/plugins/router_http/router_http.c index 444a17b8..c3521718 100644 --- a/plugins/router_http/router_http.c +++ b/plugins/router_http/router_http.c @@ -58,9 +58,9 @@ int uwsgi_routing_func_http(struct wsgi_request *wsgi_req, struct uwsgi_route *u // pipe the body if (wsgi_req->post_cl > 0) { - int post_fd = wsgi_req->poll.fd; - if (wsgi_req->async_post) { - post_fd = fileno((FILE *)wsgi_req->async_post); + int post_fd = wsgi_req->fd; + if (wsgi_req->post_file) { + post_fd = fileno((FILE *)wsgi_req->post_file); } ret = uwsgi_pipe_sized(post_fd, http_fd, wsgi_req->post_cl, 0); if (ret < 0) { @@ -72,7 +72,7 @@ int uwsgi_routing_func_http(struct wsgi_request *wsgi_req, struct uwsgi_route *u } // pipe the response - ret = uwsgi_pipe(http_fd, wsgi_req->poll.fd, 0); + ret = uwsgi_pipe(http_fd, wsgi_req->fd, 0); if (ret > 0) { wsgi_req->response_size += ret; } diff --git a/plugins/router_uwsgi/router_uwsgi.c b/plugins/router_uwsgi/router_uwsgi.c index 076fccad..1d634070 100644 --- a/plugins/router_uwsgi/router_uwsgi.c +++ b/plugins/router_uwsgi/router_uwsgi.c @@ -7,8 +7,8 @@ int uwsgi_routing_func_uwsgi_simple(struct wsgi_request *wsgi_req, struct uwsgi_ struct uwsgi_header *uh = (struct uwsgi_header *) ur->data; - wsgi_req->uh.modifier1 = uh->modifier1; - wsgi_req->uh.modifier2 = uh->modifier2; + wsgi_req->uh->modifier1 = uh->modifier1; + wsgi_req->uh->modifier2 = uh->modifier2; // set appid if (ur->data2_len > 0) { @@ -46,9 +46,9 @@ int uwsgi_routing_func_uwsgi_remote(struct wsgi_request *wsgi_req, struct uwsgi_ // ok now if have offload threads, directly use them if (wsgi_req->socket->can_offload) { - struct uwsgi_buffer *ub = uwsgi_buffer_new(4 + wsgi_req->uh.pktsize); + struct uwsgi_buffer *ub = uwsgi_buffer_new(4 + wsgi_req->uh->pktsize); if (ub) { - uh->pktsize = wsgi_req->uh.pktsize; + uh->pktsize = wsgi_req->uh->pktsize; if (uwsgi_buffer_append(ub, (char *) uh, 4)) goto bad; if (uwsgi_buffer_append(ub, wsgi_req->buffer, uh->pktsize)) goto bad; if (!uwsgi_offload_request_net_do(wsgi_req, addr, ub)) { @@ -67,17 +67,17 @@ bad: return UWSGI_ROUTE_NEXT; } - int post_fd = wsgi_req->poll.fd; - if (wsgi_req->async_post) { - post_fd = fileno((FILE*)wsgi_req->async_post); + int post_fd = wsgi_req->fd; + if (wsgi_req->post_file) { + post_fd = fileno(wsgi_req->post_file); } - if (uwsgi_send_message(uwsgi_fd, uh->modifier1, uh->modifier2, wsgi_req->buffer, wsgi_req->uh.pktsize, post_fd, wsgi_req->post_cl, 0) < 0) { + if (uwsgi_send_message(uwsgi_fd, uh->modifier1, uh->modifier2, wsgi_req->buffer, wsgi_req->uh->pktsize, post_fd, wsgi_req->post_cl, 0) < 0) { uwsgi_log("unable to send uwsgi request to host %s", addr); return UWSGI_ROUTE_NEXT; } - ssize_t ret = uwsgi_pipe(uwsgi_fd, wsgi_req->poll.fd, 0); + ssize_t ret = uwsgi_pipe(uwsgi_fd, wsgi_req->fd, 0); if (ret > 0) { wsgi_req->response_size += ret; } diff --git a/plugins/rpc/rpc_plugin.c b/plugins/rpc/rpc_plugin.c index 6eddfed4..e9877010 100644 --- a/plugins/rpc/rpc_plugin.c +++ b/plugins/rpc/rpc_plugin.c @@ -10,7 +10,7 @@ int uwsgi_rpc_request(struct wsgi_request *wsgi_req) { uint8_t argc = 0xff; /* Standard RPC request */ - if (!wsgi_req->uh.pktsize) { + if (!wsgi_req->uh->pktsize) { uwsgi_log("Invalid RPC request. skip.\n"); return -1; } @@ -22,10 +22,10 @@ int uwsgi_rpc_request(struct wsgi_request *wsgi_req) { */ #ifdef UWSGI_DEBUG - uwsgi_log("RPC pktsize %d\n", wsgi_req->uh.pktsize); + uwsgi_log("RPC pktsize %d\n", wsgi_req->uh->pktsize); #endif - if (uwsgi_parse_array(wsgi_req->buffer, wsgi_req->uh.pktsize, argv, argvs, &argc)) { + if (uwsgi_parse_array(wsgi_req->buffer, wsgi_req->uh->pktsize, argv, argvs, &argc)) { uwsgi_log("Invalid RPC request. skip.\n"); return -1; } @@ -34,12 +34,12 @@ int uwsgi_rpc_request(struct wsgi_request *wsgi_req) { uwsgi_log("RPC args %d\n", argc-1); #endif - wsgi_req->uh.pktsize = uwsgi_rpc(argv[0], argc-1, argv+1, argvs+1, wsgi_req->buffer); + wsgi_req->uh->pktsize = uwsgi_rpc(argv[0], argc-1, argv+1, argvs+1, wsgi_req->buffer); - if (wsgi_req->uh.modifier2 == 0) { - uwsgi_response_write_body_do(wsgi_req, (char *)&wsgi_req->uh, 4); + if (wsgi_req->uh->modifier2 == 0) { + uwsgi_response_write_body_do(wsgi_req, (char *) wsgi_req->uh, 4); } - uwsgi_response_write_body_do(wsgi_req, wsgi_req->buffer, wsgi_req->uh.pktsize); + uwsgi_response_write_body_do(wsgi_req, wsgi_req->buffer, wsgi_req->uh->pktsize); return 0; } diff --git a/plugins/signal/signal_plugin.c b/plugins/signal/signal_plugin.c index c572a1b1..261a5429 100644 --- a/plugins/signal/signal_plugin.c +++ b/plugins/signal/signal_plugin.c @@ -8,14 +8,14 @@ int uwsgi_request_signal(struct wsgi_request *wsgi_req) { ssize_t len; uint8_t ret_status = 1; struct uwsgi_header uh; - if (uwsgi_signal_send(uwsgi.signal_socket, wsgi_req->uh.modifier2) < 0) { + if (uwsgi_signal_send(uwsgi.signal_socket, wsgi_req->uh->modifier2) < 0) { ret_status = 0; } uh.modifier1 = 255; uh.pktsize = 0; uh.modifier2 = ret_status; - len = write(wsgi_req->poll.fd, &uh, 4); + len = write(wsgi_req->fd, &uh, 4); if (len != 4) { uwsgi_error("write()"); } diff --git a/plugins/sslrouter/sslrouter.c b/plugins/sslrouter/sslrouter.c index 2a37476c..e7a374a6 100644 --- a/plugins/sslrouter/sslrouter.c +++ b/plugins/sslrouter/sslrouter.c @@ -133,8 +133,6 @@ static struct uwsgi_option sslrouter_options[] = { {"sslrouter-fallback", required_argument, 0, "fallback to the specified node in case of error", uwsgi_opt_add_string_list, &usr.cr.fallback, 0}, - {"sslrouter-use-cluster", no_argument, 0, "load balance to nodes subscribed to the cluster", uwsgi_opt_true, &usr.cr.use_cluster, 0}, - {"sslrouter-use-code-string", required_argument, 0, "use code string as hostname->server mapper for the sslrouter", uwsgi_opt_corerouter_cs, &usr, 0}, {"sslrouter-use-socket", optional_argument, 0, "forward request to the specified uwsgi socket", uwsgi_opt_corerouter_use_socket, &usr, 0}, {"sslrouter-to", required_argument, 0, "forward requests to the specified uwsgi server (you can specify it multiple times for load balancing)", uwsgi_opt_add_string_list, &usr.cr.static_nodes, 0}, diff --git a/plugins/ugreen/ugreen.c b/plugins/ugreen/ugreen.c index 344acbe7..a1903424 100644 --- a/plugins/ugreen/ugreen.c +++ b/plugins/ugreen/ugreen.c @@ -28,7 +28,7 @@ struct uwsgi_option ugreen_options[] = { }; void u_green_request() { - uwsgi.wsgi_req->async_status = uwsgi.p[uwsgi.wsgi_req->uh.modifier1]->request(uwsgi.wsgi_req); + uwsgi.wsgi_req->async_status = uwsgi.p[uwsgi.wsgi_req->uh->modifier1]->request(uwsgi.wsgi_req); uwsgi.wsgi_req->suspended = 0; } @@ -42,14 +42,14 @@ static inline void u_green_schedule_to_req() { uwsgi.wsgi_req->suspended = 1; } - if (uwsgi.p[uwsgi.wsgi_req->uh.modifier1]->suspend) { - uwsgi.p[uwsgi.wsgi_req->uh.modifier1]->suspend(NULL); + if (uwsgi.p[uwsgi.wsgi_req->uh->modifier1]->suspend) { + uwsgi.p[uwsgi.wsgi_req->uh->modifier1]->suspend(NULL); } swapcontext(&ug.main, &ug.contexts[id] ); - if (uwsgi.p[uwsgi.wsgi_req->uh.modifier1]->resume) { - uwsgi.p[uwsgi.wsgi_req->uh.modifier1]->resume(NULL); + if (uwsgi.p[uwsgi.wsgi_req->uh->modifier1]->resume) { + uwsgi.p[uwsgi.wsgi_req->uh->modifier1]->resume(NULL); } if (uwsgi.wsgi_req->suspended) { @@ -60,14 +60,14 @@ static inline void u_green_schedule_to_req() { static inline void u_green_schedule_to_main(struct wsgi_request *wsgi_req) { - if (uwsgi.p[wsgi_req->uh.modifier1]->suspend) { - uwsgi.p[wsgi_req->uh.modifier1]->suspend(wsgi_req); + if (uwsgi.p[wsgi_req->uh->modifier1]->suspend) { + uwsgi.p[wsgi_req->uh->modifier1]->suspend(wsgi_req); } swapcontext(&ug.contexts[wsgi_req->async_id], &ug.main); - if (uwsgi.p[wsgi_req->uh.modifier1]->resume) { - uwsgi.p[wsgi_req->uh.modifier1]->resume(wsgi_req); + if (uwsgi.p[wsgi_req->uh->modifier1]->resume) { + uwsgi.p[wsgi_req->uh->modifier1]->resume(wsgi_req); } uwsgi.wsgi_req = wsgi_req; diff --git a/proto/base.c b/proto/base.c index e6635888..dc495bcb 100644 --- a/proto/base.c +++ b/proto/base.c @@ -7,7 +7,7 @@ uint16_t proto_base_add_uwsgi_header(struct wsgi_request *wsgi_req, char *key, u int i; - char *buffer = wsgi_req->buffer + wsgi_req->uh.pktsize; + char *buffer = wsgi_req->buffer + wsgi_req->uh->pktsize; char *watermark = wsgi_req->buffer + uwsgi.buffer_size; char *ptr = buffer; @@ -61,7 +61,7 @@ uint16_t proto_base_add_uwsgi_header(struct wsgi_request *wsgi_req, char *key, u uint16_t proto_base_add_uwsgi_var(struct wsgi_request * wsgi_req, char *key, uint16_t keylen, char *val, uint16_t vallen) { - char *buffer = wsgi_req->buffer + wsgi_req->uh.pktsize; + char *buffer = wsgi_req->buffer + wsgi_req->uh->pktsize; char *watermark = wsgi_req->buffer + uwsgi.buffer_size; char *ptr = buffer; @@ -105,16 +105,7 @@ int uwsgi_proto_base_accept(struct wsgi_request *wsgi_req, int fd) { } void uwsgi_proto_base_close(struct wsgi_request *wsgi_req) { - - if (wsgi_req->async_post) { - fclose(wsgi_req->async_post); - if (wsgi_req->body_as_file) { - close(wsgi_req->poll.fd); - } - } - else { - close(wsgi_req->poll.fd); - } + close(wsgi_req->fd); } struct uwsgi_buffer *uwsgi_proto_base_add_header(struct wsgi_request *wsgi_req, char *k, uint16_t kl, char *v, uint16_t vl) { @@ -164,7 +155,7 @@ end: int uwsgi_proto_base_write(struct wsgi_request * wsgi_req, char *buf, size_t len) { - ssize_t wlen = write(wsgi_req->poll.fd, buf+wsgi_req->write_pos, len-wsgi_req->write_pos); + ssize_t wlen = write(wsgi_req->fd, buf+wsgi_req->write_pos, len-wsgi_req->write_pos); if (wlen > 0) { wsgi_req->write_pos += wlen; if (wsgi_req->write_pos == len) { @@ -181,7 +172,7 @@ int uwsgi_proto_base_write(struct wsgi_request * wsgi_req, char *buf, size_t len } int uwsgi_proto_base_sendfile(struct wsgi_request * wsgi_req, int fd, size_t pos, size_t len) { - ssize_t wlen = uwsgi_sendfile_do(wsgi_req->poll.fd, fd, pos+wsgi_req->write_pos, len-wsgi_req->write_pos); + ssize_t wlen = uwsgi_sendfile_do(wsgi_req->fd, fd, pos+wsgi_req->write_pos, len-wsgi_req->write_pos); if (wlen > 0) { wsgi_req->write_pos += wlen; if (wsgi_req->write_pos == len) { @@ -201,3 +192,13 @@ int uwsgi_proto_base_fix_headers(struct wsgi_request * wsgi_req) { return uwsgi_buffer_append(wsgi_req->headers, "\r\n", 2); } +ssize_t uwsgi_proto_base_read_body(struct wsgi_request *wsgi_req, char *buf, size_t len) { + if (wsgi_req->proto_parser_remains > 0) { + size_t remains = UMIN(wsgi_req->proto_parser_remains, len); + memcpy(buf, wsgi_req->proto_parser_remains_buf, remains); + wsgi_req->proto_parser_remains -= remains; + wsgi_req->proto_parser_remains_buf += remains; + return remains; + } + return read(wsgi_req->fd, buf, len); +} diff --git a/proto/fastcgi.c b/proto/fastcgi.c index 995cef88..c0b5b1cf 100644 --- a/proto/fastcgi.c +++ b/proto/fastcgi.c @@ -23,7 +23,7 @@ int uwsgi_proto_fastcgi_parser(struct wsgi_request *wsgi_req) { } if (wsgi_req->proto_parser_status == PROTO_STATUS_RECV_HDR) { - len = read(wsgi_req->poll.fd, wsgi_req->proto_parser_buf + wsgi_req->proto_parser_pos, 8 - wsgi_req->proto_parser_pos); + len = read(wsgi_req->fd, wsgi_req->proto_parser_buf + wsgi_req->proto_parser_pos, 8 - wsgi_req->proto_parser_pos); if (len <= 0) { free(wsgi_req->proto_parser_buf); uwsgi_error("read()"); @@ -40,9 +40,8 @@ int uwsgi_proto_fastcgi_parser(struct wsgi_request *wsgi_req) { // empty STDIN ? if (fr->type == 5 && rs == 0) { wsgi_req->proto_parser_status = 0; - if (wsgi_req->async_post) { - rewind(wsgi_req->async_post); - wsgi_req->body_as_file = 1; + if (wsgi_req->post_file) { + rewind(wsgi_req->post_file); } free(wsgi_req->proto_parser_buf); return UWSGI_OK; @@ -60,7 +59,7 @@ int uwsgi_proto_fastcgi_parser(struct wsgi_request *wsgi_req) { fr = (struct fcgi_record *) wsgi_req->proto_parser_buf; rs = ntohs(fr->cl); - len = read(wsgi_req->poll.fd, wsgi_req->proto_parser_buf + 8 + wsgi_req->proto_parser_pos, (rs + fr->pad) - wsgi_req->proto_parser_pos); + len = read(wsgi_req->fd, wsgi_req->proto_parser_buf + 8 + wsgi_req->proto_parser_pos, (rs + fr->pad) - wsgi_req->proto_parser_pos); if (len <= 0) { free(wsgi_req->proto_parser_buf); uwsgi_error("read()"); @@ -121,22 +120,22 @@ int uwsgi_proto_fastcgi_parser(struct wsgi_request *wsgi_req) { #ifdef UWSGI_DEBUG uwsgi_log("keylen %d %.*s vallen %d %.*s\n", keylen, keylen, wsgi_req->proto_parser_buf + 8 + j, vallen, vallen, wsgi_req->proto_parser_buf + 8 + j + keylen); #endif - wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, wsgi_req->proto_parser_buf + 8 + j, keylen, wsgi_req->proto_parser_buf + 8 + j + keylen, vallen); + wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, wsgi_req->proto_parser_buf + 8 + j, keylen, wsgi_req->proto_parser_buf + 8 + j + keylen, vallen); } j += (keylen + vallen) - 1; } } // stdin else if (fr->type == 5) { - if (!wsgi_req->async_post) { - wsgi_req->async_post = tmpfile(); - if (!wsgi_req->async_post) { + if (!wsgi_req->post_file) { + wsgi_req->post_file = tmpfile(); + if (!wsgi_req->post_file) { free(wsgi_req->proto_parser_buf); uwsgi_error("tmpfile()"); return -1; } } - if (!fwrite(wsgi_req->proto_parser_buf + 8, rs, 1, wsgi_req->async_post)) { + if (!fwrite(wsgi_req->proto_parser_buf + 8, rs, 1, wsgi_req->post_file)) { free(wsgi_req->proto_parser_buf); uwsgi_error("fwrite()"); return -1; @@ -257,7 +256,7 @@ body: void uwsgi_proto_fastcgi_close(struct wsgi_request *wsgi_req) { - if (write(wsgi_req->poll.fd, FCGI_END_REQUEST, 24) <= 0) { + if (write(wsgi_req->fd, FCGI_END_REQUEST, 24) <= 0) { uwsgi_req_error("write()"); } diff --git a/proto/http.c b/proto/http.c index bbdd3c8a..cce0df8c 100644 --- a/proto/http.c +++ b/proto/http.c @@ -6,7 +6,7 @@ extern struct uwsgi_server uwsgi; static uint16_t http_add_uwsgi_header(struct wsgi_request *wsgi_req, char *hh, int hhlen) { - char *buffer = wsgi_req->buffer + wsgi_req->uh.pktsize; + char *buffer = wsgi_req->buffer + wsgi_req->uh->pktsize; char *watermark = wsgi_req->buffer + uwsgi.buffer_size; int i; @@ -39,35 +39,10 @@ static uint16_t http_add_uwsgi_header(struct wsgi_request *wsgi_req, char *hh, i if (!keylen) return 0; - if (uwsgi_strncmp("CONTENT_TYPE", 12, hh, keylen) && uwsgi_strncmp("CONTENT_LENGTH", 14, hh, keylen)) { - if (!uwsgi_strncmp("IF_MODIFIED_SINCE", 17, hh, keylen)) { - wsgi_req->if_modified_since = val; - wsgi_req->if_modified_since_len = vallen; - } - else if (!uwsgi_strncmp("AUTHORIZATION", 13, hh, keylen)) { - wsgi_req->authorization = val; - wsgi_req->authorization_len = vallen; - } - else if (!uwsgi_strncmp("X_FORWARDED_SSL", 15, hh, keylen)) { - if (vallen == 2 && val[0] == 'o' && val[1] == 'n') { - wsgi_req->scheme = "https"; - wsgi_req->scheme_len = 5; - } - } - else if (uwsgi.vhost_host && !uwsgi_strncmp("HOST", 4, hh, keylen)) { - wsgi_req->host = val; - wsgi_req->host_len = vallen; - } + if (uwsgi_strncmp("CONTENT_LENGTH", 14, hh, keylen) && uwsgi_strncmp("CONTENT_TYPE", 12, hh, keylen)) { keylen += 5; prefix = 1; } - else if (!uwsgi_strncmp("CONTENT_LENGTH", 14, hh, keylen)) { - wsgi_req->post_cl = uwsgi_str_num(val, vallen); - } - else if (!uwsgi_strncmp("CONTENT_TYPE", 12, hh, keylen)) { - wsgi_req->content_type = val; - wsgi_req->content_type_len = vallen; - } if (buffer + keylen + vallen + 2 + 2 >= watermark) { if (prefix) { @@ -98,10 +73,6 @@ static uint16_t http_add_uwsgi_header(struct wsgi_request *wsgi_req, char *hh, i *ptr++ = (uint8_t) ((vallen >> 8) & 0xff); memcpy(ptr, val, vallen); -#ifdef UWSGI_DEBUG - uwsgi_log("add uwsgi var: %.*s = %.*s\n", keylen - (prefix * 5), hh, vallen, val); -#endif - return 2 + keylen + 2 + vallen; } @@ -114,14 +85,10 @@ static int http_parse(struct wsgi_request *wsgi_req, char *watermark) { char ip[INET_ADDRSTRLEN+1]; struct sockaddr_in *http_sin = (struct sockaddr_in *) &wsgi_req->c_addr; - wsgi_req->path_info_pos = -1; - // REQUEST_METHOD while (ptr < watermark) { if (*ptr == ' ') { - wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "REQUEST_METHOD", 14, base, ptr - base); - wsgi_req->method = (wsgi_req->buffer + wsgi_req->uh.pktsize) - (ptr - base); - wsgi_req->method_len = ptr - base; + wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "REQUEST_METHOD", 14, base, ptr - base); ptr++; break; } @@ -133,49 +100,35 @@ static int http_parse(struct wsgi_request *wsgi_req, char *watermark) { while (ptr < watermark) { if (*ptr == '?' && !query_string) { if (watermark + (ptr - base) < (char *)(wsgi_req->proto_parser_buf + uwsgi.buffer_size)) { - wsgi_req->path_info = watermark; - wsgi_req->path_info_len = ptr - base; - http_url_decode(base, &wsgi_req->path_info_len, wsgi_req->path_info); - wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "PATH_INFO", 9, wsgi_req->path_info, wsgi_req->path_info_len); - wsgi_req->path_info = (wsgi_req->buffer + wsgi_req->uh.pktsize) - (ptr - base); - wsgi_req->path_info_len = ptr - base; + char *path_info = watermark; + uint16_t path_info_len = ptr - base; + http_url_decode(base, &path_info_len, path_info); + wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "PATH_INFO", 9, path_info, path_info_len); } else { uwsgi_log("not enough space in wsgi_req http proto_parser_buf to encode PATH_INFO, consider tuning it with --buffer-size\n"); - wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "PATH_INFO", 9, base, ptr - base); - wsgi_req->path_info = (wsgi_req->buffer + wsgi_req->uh.pktsize) - (ptr - base); - wsgi_req->path_info_len = ptr - base; + return -1; } - wsgi_req->path_info_pos = 3; query_string = ptr + 1; } else if (*ptr == ' ') { - wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "REQUEST_URI", 11, base, ptr - base); - wsgi_req->uri = (wsgi_req->buffer + wsgi_req->uh.pktsize) - (ptr - base); - wsgi_req->uri_len = ptr - base; + wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "REQUEST_URI", 11, base, ptr - base); if (!query_string) { if (watermark + (ptr - base) < (char *)(wsgi_req->proto_parser_buf + uwsgi.buffer_size)) { - wsgi_req->path_info = watermark; - wsgi_req->path_info_len = ptr - base; - http_url_decode(base, &wsgi_req->path_info_len, wsgi_req->path_info); - wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "PATH_INFO", 9, wsgi_req->path_info, wsgi_req->path_info_len); - wsgi_req->path_info = (wsgi_req->buffer + wsgi_req->uh.pktsize) - (ptr - base); - wsgi_req->path_info_len = ptr - base; + char *path_info = watermark; + uint16_t path_info_len = ptr - base; + http_url_decode(base, &path_info_len, path_info); + wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "PATH_INFO", 9, path_info, path_info_len); } else { uwsgi_log("not enough space in wsgi_req http proto_parser_buf to encode PATH_INFO, consider tuning it with --buffer-size\n"); - wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "PATH_INFO", 9, base, ptr - base); - wsgi_req->path_info = (wsgi_req->buffer + wsgi_req->uh.pktsize) - (ptr - base); - wsgi_req->path_info_len = ptr - base; + return -1; } - wsgi_req->path_info_pos = 5; - wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "QUERY_STRING", 12, "", 0); + wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "QUERY_STRING", 12, "", 0); } else { - wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "QUERY_STRING", 12, query_string, ptr - query_string); - wsgi_req->query_string = (wsgi_req->buffer + wsgi_req->uh.pktsize) - (ptr - query_string); - wsgi_req->query_string_len = ptr - query_string; + wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "QUERY_STRING", 12, query_string, ptr - query_string); } ptr++; break; @@ -188,12 +141,10 @@ static int http_parse(struct wsgi_request *wsgi_req, char *watermark) { while (ptr < watermark) { if (*ptr == '\r') { if (ptr + 1 >= watermark) - return 0; + return -1 ; if (*(ptr + 1) != '\n') - return 0; - wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "SERVER_PROTOCOL", 15, base, ptr - base); - wsgi_req->protocol = (wsgi_req->buffer + wsgi_req->uh.pktsize) - (ptr - base); - wsgi_req->protocol_len = ptr - base; + return -1; + wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "SERVER_PROTOCOL", 15, base, ptr - base); ptr += 2; break; } @@ -202,33 +153,31 @@ static int http_parse(struct wsgi_request *wsgi_req, char *watermark) { // SCRIPT_NAME if (!uwsgi.manage_script_name) { - wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "SCRIPT_NAME", 11, "", 0); + wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "SCRIPT_NAME", 11, "", 0); } // SERVER_NAME - wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "SERVER_NAME", 11, uwsgi.hostname, uwsgi.hostname_len); - wsgi_req->host = uwsgi.hostname; - wsgi_req->host_len = uwsgi.hostname_len; + wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "SERVER_NAME", 11, uwsgi.hostname, uwsgi.hostname_len); // SERVER_PORT char *server_port = strchr(wsgi_req->socket->name, ':'); if (server_port) { - wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "SERVER_PORT", 11, server_port+1, strlen(server_port+1)); + wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "SERVER_PORT", 11, server_port+1, strlen(server_port+1)); } else { - wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "SERVER_PORT", 11, "80", 2); + wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "SERVER_PORT", 11, "80", 2); } + // TODO add ipv6 support // REMOTE_ADDR memset(ip, 0, INET_ADDRSTRLEN+1); if (inet_ntop(AF_INET, (void *) &http_sin->sin_addr.s_addr, ip, INET_ADDRSTRLEN)) { - wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "REMOTE_ADDR", 11, ip, strlen(ip)); - wsgi_req->remote_addr = (wsgi_req->buffer + wsgi_req->uh.pktsize) - strlen(ip); - wsgi_req->remote_addr_len = strlen(ip); + wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "REMOTE_ADDR", 11, ip, strlen(ip)); } else { uwsgi_error("inet_ntop()"); + return -1; } //HEADERS @@ -237,9 +186,9 @@ static int http_parse(struct wsgi_request *wsgi_req, char *watermark) { while (ptr < watermark) { if (*ptr == '\r') { if (ptr + 1 >= watermark) - return 0; + return -1; if (*(ptr + 1) != '\n') - return 0; + return -1; // multiline header ? if (ptr + 2 < watermark) { if (*(ptr + 2) == ' ' || *(ptr + 2) == '\t') { @@ -247,7 +196,7 @@ static int http_parse(struct wsgi_request *wsgi_req, char *watermark) { continue; } } - wsgi_req->uh.pktsize += http_add_uwsgi_header(wsgi_req, base, ptr - base); + wsgi_req->uh->pktsize += http_add_uwsgi_header(wsgi_req, base, ptr - base); ptr++; base = ptr + 1; } @@ -262,68 +211,38 @@ static int http_parse(struct wsgi_request *wsgi_req, char *watermark) { int uwsgi_proto_http_parser(struct wsgi_request *wsgi_req) { - ssize_t len; - int j; + ssize_t j; char *ptr; - ssize_t remains; - // TODO make this buffer configurable - char post_buf[8192]; - char *post_tail = NULL; - // first round ? + // first round ? (wsgi_req->proto_parser_buf is freed at the end of the request) if (!wsgi_req->proto_parser_buf) { wsgi_req->proto_parser_buf = uwsgi_malloc(uwsgi.buffer_size); } - if (wsgi_req->post_cl) { - remains = wsgi_req->post_cl - wsgi_req->proto_parser_pos; - if (remains > 0) { - remains = UMIN(remains, 8192); - len = read(wsgi_req->poll.fd, post_buf, remains); - if (len <= 0) { - if (len < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) { - return UWSGI_AGAIN; - } - free(wsgi_req->proto_parser_buf); - uwsgi_error("read()"); - } - return -1; - } - - if (!fwrite(post_buf, len, 1, wsgi_req->async_post)) { - free(wsgi_req->proto_parser_buf); - uwsgi_error("fwrite()"); - return -1; - } - wsgi_req->proto_parser_pos += len; - - if (wsgi_req->proto_parser_pos < wsgi_req->post_cl) - return UWSGI_AGAIN; - - } - free(wsgi_req->proto_parser_buf); - rewind(wsgi_req->async_post); - wsgi_req->body_as_file = 1; - return UWSGI_OK; - } - - len = read(wsgi_req->poll.fd, wsgi_req->proto_parser_buf + wsgi_req->proto_parser_pos, uwsgi.buffer_size - wsgi_req->proto_parser_pos); - if (len <= 0) { - if (len < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) { - return UWSGI_AGAIN; - } - uwsgi_error("recv()"); - } - free(wsgi_req->proto_parser_buf); - // this is simple ping packet - if (len == 0) return -2; + if (uwsgi.buffer_size - wsgi_req->proto_parser_pos == 0) { + uwsgi_log("invalid HTTP request size (max %u)...skip\n", uwsgi.buffer_size); return -1; } - ptr = wsgi_req->proto_parser_buf + wsgi_req->proto_parser_pos; + ssize_t len = read(wsgi_req->fd, wsgi_req->proto_parser_buf + wsgi_req->proto_parser_pos, uwsgi.buffer_size - wsgi_req->proto_parser_pos); + if (len > 0) { + goto parse; + } + if (len < 0) { + if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) { + return UWSGI_AGAIN; + } + uwsgi_error("uwsgi_proto_http_parser()"); + return -1; + } + // mute on 0 len... + if (wsgi_req->proto_parser_pos > 0) { + uwsgi_error("uwsgi_proto_http_parser()"); + } + return -1; +parse: + ptr = wsgi_req->proto_parser_buf + wsgi_req->proto_parser_pos; wsgi_req->proto_parser_pos += len; for (j = 0; j < len; j++) { @@ -338,42 +257,11 @@ int uwsgi_proto_http_parser(struct wsgi_request *wsgi_req) { } else if (*ptr == '\n' && wsgi_req->proto_parser_status == 3) { ptr++; - remains = len - (j + 1); - if (remains > 0) { - post_tail = uwsgi_malloc(remains); - memcpy(post_tail, ptr, remains); + wsgi_req->proto_parser_remains = len - (j + 1); + if (wsgi_req->proto_parser_remains > 0) { + wsgi_req->proto_parser_remains_buf = (wsgi_req->proto_parser_buf + wsgi_req->proto_parser_pos) - wsgi_req->proto_parser_remains; } - http_parse(wsgi_req, ptr); - //is there a Content_Length ? - if (wsgi_req->post_cl > 0) { - wsgi_req->async_post = tmpfile(); - if (!wsgi_req->async_post) { - free(wsgi_req->proto_parser_buf); - if (post_tail) free(post_tail); - uwsgi_error("tmpfile()"); - return -1; - } - wsgi_req->proto_parser_pos = 0; - remains = UMIN((size_t) remains, wsgi_req->post_cl); - if (remains && post_tail) { - if (!fwrite(post_tail, remains, 1, wsgi_req->async_post)) { - free(post_tail); - free(wsgi_req->proto_parser_buf); - uwsgi_error("fwrite()"); - return -1; - } - free(post_tail); - wsgi_req->proto_parser_pos += remains; - if (wsgi_req->proto_parser_pos >= wsgi_req->post_cl) { - free(wsgi_req->proto_parser_buf); - rewind(wsgi_req->async_post); - wsgi_req->body_as_file = 1; - return UWSGI_OK; - } - } - return UWSGI_AGAIN; - } - free(wsgi_req->proto_parser_buf); + if (http_parse(wsgi_req, ptr)) return -1; return UWSGI_OK; } else { @@ -385,7 +273,7 @@ int uwsgi_proto_http_parser(struct wsgi_request *wsgi_req) { return UWSGI_AGAIN; } -void uwsgi_httpize_var(char *buf, size_t len) { +static void uwsgi_httpize_var(char *buf, size_t len) { size_t i; int upper = 1; for(i=0;iuh; + ssize_t len = read(wsgi_req->fd, ptr + wsgi_req->proto_parser_pos, (uwsgi.buffer_size+4) - wsgi_req->proto_parser_pos); + if (len > 0) { + wsgi_req->proto_parser_pos += len; + if (wsgi_req->proto_parser_pos >= 4) { + if ((wsgi_req->proto_parser_pos-4) == wsgi_req->uh->pktsize) { + return UWSGI_OK; + } + if ((wsgi_req->proto_parser_pos-4) > wsgi_req->uh->pktsize) { + wsgi_req->proto_parser_remains = wsgi_req->proto_parser_pos-(4+wsgi_req->uh->pktsize); + wsgi_req->proto_parser_remains_buf = wsgi_req->buffer + wsgi_req->uh->pktsize; + return UWSGI_OK; + } + if (wsgi_req->uh->pktsize > uwsgi.buffer_size) { + uwsgi_log("invalid request block size: %u (max %u)...skip\n", wsgi_req->uh->pktsize, uwsgi.buffer_size); + return -1; + } + } + return UWSGI_AGAIN; + } + if (len < 0) { + if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) { + return UWSGI_AGAIN; + } + uwsgi_error("uwsgi_proto_uwsgi_parser()"); + return -1; + } + // 0 len + if (wsgi_req->proto_parser_pos > 0) { + uwsgi_error("uwsgi_proto_uwsgi_parser()"); + } + return -1; +} + +/* +int uwsgi_proto_uwsgi_parser_unix(struct wsgi_request *wsgi_req) { uint8_t *hdr_buf = (uint8_t *) & wsgi_req->uh; ssize_t len; @@ -19,7 +52,7 @@ int uwsgi_proto_uwsgi_parser(struct wsgi_request *wsgi_req) { if (wsgi_req->proto_parser_pos > 0) { - len = read(wsgi_req->poll.fd, hdr_buf + wsgi_req->proto_parser_pos, 4 - wsgi_req->proto_parser_pos); + len = read(wsgi_req->fd, hdr_buf + wsgi_req->proto_parser_pos, 4 - wsgi_req->proto_parser_pos); } else { iov[0].iov_base = hdr_buf; @@ -33,7 +66,7 @@ int uwsgi_proto_uwsgi_parser(struct wsgi_request *wsgi_req) { wsgi_req->msg.msg_controllen = sizeof(wsgi_req->msg_control); wsgi_req->msg.msg_flags = 0; - len = recvmsg(wsgi_req->poll.fd, &wsgi_req->msg, 0); + len = recvmsg(wsgi_req->fd, &wsgi_req->msg, 0); } if (len <= 0) { @@ -52,22 +85,19 @@ int uwsgi_proto_uwsgi_parser(struct wsgi_request *wsgi_req) { if (wsgi_req->proto_parser_pos == 4) { wsgi_req->proto_parser_status = PROTO_STATUS_RECV_VARS; wsgi_req->proto_parser_pos = 0; -/* big endian ? */ #ifdef __BIG_ENDIAN__ - wsgi_req->uh.pktsize = uwsgi_swap16(wsgi_req->uh.pktsize); + wsgi_req->uh->pktsize = uwsgi_swap16(wsgi_req->uh->pktsize); #endif #ifdef UWSGI_DEBUG uwsgi_debug("uwsgi payload size: %d (0x%X) modifier1: %d modifier2: %d\n", wsgi_req->uh.pktsize, wsgi_req->uh.pktsize, wsgi_req->uh.modifier1, wsgi_req->uh.modifier2); #endif - /* check for max buffer size */ - if (wsgi_req->uh.pktsize > uwsgi.buffer_size) { - uwsgi_log("invalid request block size: %d (max %d)...skip\n", wsgi_req->uh.pktsize, uwsgi.buffer_size); + if (wsgi_req->uh->pktsize > uwsgi.buffer_size) { return -1; } - if (!wsgi_req->uh.pktsize) + if (!wsgi_req->uh->pktsize) return UWSGI_OK; } @@ -75,7 +105,7 @@ int uwsgi_proto_uwsgi_parser(struct wsgi_request *wsgi_req) { } else if (wsgi_req->proto_parser_status == PROTO_STATUS_RECV_VARS) { - len = read(wsgi_req->poll.fd, wsgi_req->buffer + wsgi_req->proto_parser_pos, wsgi_req->uh.pktsize - wsgi_req->proto_parser_pos); + len = read(wsgi_req->fd, wsgi_req->buffer + wsgi_req->proto_parser_pos, wsgi_req->uh->pktsize - wsgi_req->proto_parser_pos); if (len <= 0) { uwsgi_error("read()"); return -1; @@ -83,7 +113,7 @@ int uwsgi_proto_uwsgi_parser(struct wsgi_request *wsgi_req) { wsgi_req->proto_parser_pos += len; // body ready ? - if (wsgi_req->proto_parser_pos >= wsgi_req->uh.pktsize) { + if (wsgi_req->proto_parser_pos >= wsgi_req->uh->pktsize) { // older OSX versions make mess with CMSG_FIRSTHDR #ifdef __APPLE__ @@ -100,12 +130,12 @@ int uwsgi_proto_uwsgi_parser(struct wsgi_request *wsgi_req) { // upgrade connection to the new socket #ifdef UWSGI_DEBUG - uwsgi_log("upgrading fd %d to ", wsgi_req->poll.fd); + uwsgi_log("upgrading fd %d to ", wsgi_req->fd); #endif - close(wsgi_req->poll.fd); - memcpy(&wsgi_req->poll.fd, CMSG_DATA(cmsg), sizeof(int)); + close(wsgi_req->fd); + memcpy(&wsgi_req->fd, CMSG_DATA(cmsg), sizeof(int)); #ifdef UWSGI_DEBUG - uwsgi_log("%d\n", wsgi_req->poll.fd); + uwsgi_log("%d\n", wsgi_req->fd); #endif } cmsg = CMSG_NXTHDR(&wsgi_req->msg, cmsg); @@ -120,3 +150,5 @@ int uwsgi_proto_uwsgi_parser(struct wsgi_request *wsgi_req) { return -1; } + +*/ diff --git a/uwsgi.h b/uwsgi.h index 885415d5..89138e90 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -95,8 +95,8 @@ extern "C" { #endif #ifdef UWSGI_EMBED_CONFIG -extern char UWSGI_EMBED_CONFIG; -extern char UWSGI_EMBED_CONFIG_END; + extern char UWSGI_EMBED_CONFIG; + extern char UWSGI_EMBED_CONFIG_END; #endif #define UDEP(pname) extern struct uwsgi_plugin pname##_plugin; @@ -134,9 +134,9 @@ extern char UWSGI_EMBED_CONFIG_END; -#ifndef __need_IOV_MAX -#define __need_IOV_MAX -#endif +#ifndef __need_IOV_MAX +#define __need_IOV_MAX +#endif #include @@ -226,7 +226,7 @@ extern char UWSGI_EMBED_CONFIG_END; #include #include #endif -extern int pivot_root(const char *new_root, const char *put_old); + extern int pivot_root(const char *new_root, const char *put_old); #endif #include @@ -330,53 +330,53 @@ extern int pivot_root(const char *new_root, const char *put_old); #endif -struct uwsgi_buffer { - char *buf; - size_t pos; - size_t len; - size_t limit; -}; + struct uwsgi_buffer { + char *buf; + size_t pos; + size_t len; + size_t limit; + }; -struct uwsgi_string_list { + struct uwsgi_string_list { - char *value; - size_t len; - uint64_t custom; - uint64_t custom2; - void *custom_ptr; - struct uwsgi_string_list *next; -}; + char *value; + size_t len; + uint64_t custom; + uint64_t custom2; + void *custom_ptr; + struct uwsgi_string_list *next; + }; -struct uwsgi_custom_option { + struct uwsgi_custom_option { - char *name; - char *value; - int has_args; - struct uwsgi_custom_option *next; -}; + char *name; + char *value; + int has_args; + struct uwsgi_custom_option *next; + }; -struct uwsgi_lock_item { - char *id; - void *lock_ptr; - int rw; - pid_t pid; - int can_deadlock; - struct uwsgi_lock_item *next; -}; + struct uwsgi_lock_item { + char *id; + void *lock_ptr; + int rw; + pid_t pid; + int can_deadlock; + struct uwsgi_lock_item *next; + }; -struct uwsgi_lock_ops { - struct uwsgi_lock_item* (*lock_init)(char *); - pid_t (*lock_check)(struct uwsgi_lock_item *); - void (*lock)(struct uwsgi_lock_item *); - void (*unlock)(struct uwsgi_lock_item *); + struct uwsgi_lock_ops { + struct uwsgi_lock_item *(*lock_init) (char *); + pid_t(*lock_check) (struct uwsgi_lock_item *); + void (*lock) (struct uwsgi_lock_item *); + void (*unlock) (struct uwsgi_lock_item *); - struct uwsgi_lock_item * (*rwlock_init)(char *); - pid_t (*rwlock_check)(struct uwsgi_lock_item *); - void (*rlock)(struct uwsgi_lock_item *); - void (*wlock)(struct uwsgi_lock_item *); - void (*rwunlock)(struct uwsgi_lock_item *); -}; + struct uwsgi_lock_item *(*rwlock_init) (char *); + pid_t(*rwlock_check) (struct uwsgi_lock_item *); + void (*rlock) (struct uwsgi_lock_item *); + void (*wlock) (struct uwsgi_lock_item *); + void (*rwunlock) (struct uwsgi_lock_item *); + }; #define uwsgi_lock_init(x) uwsgi.lock_ops.lock_init(x) #define uwsgi_lock_check(x) uwsgi.lock_ops.lock_check(x) @@ -389,6 +389,9 @@ struct uwsgi_lock_ops { #define uwsgi_wlock(x) uwsgi.lock_ops.wlock(x) #define uwsgi_rwunlock(x) uwsgi.lock_ops.rwunlock(x) +#define uwsgi_wait_read_req(x) uwsgi.wait_read_hook(x->fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]) ; x->switches++ +#define uwsgi_wait_write_req(x) uwsgi.wait_write_hook(x->fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]) ; x->switches++ + #ifdef UWSGI_PCRE #include #endif @@ -397,333 +400,326 @@ struct uwsgi_lock_ops { #include #endif -struct uwsgi_dyn_dict { + struct uwsgi_dyn_dict { - char *key; - int keylen; - char *value; - int vallen; + char *key; + int keylen; + char *value; + int vallen; - uint64_t hits; - int status; + uint64_t hits; + int status; #ifdef UWSGI_PCRE - pcre *pattern; - pcre_extra *pattern_extra; + pcre *pattern; + pcre_extra *pattern_extra; #endif - struct uwsgi_dyn_dict *prev; - struct uwsgi_dyn_dict *next; -}; + struct uwsgi_dyn_dict *prev; + struct uwsgi_dyn_dict *next; + }; #ifdef UWSGI_PCRE -struct uwsgi_regexp_list { + struct uwsgi_regexp_list { - pcre *pattern; - pcre_extra *pattern_extra; + pcre *pattern; + pcre_extra *pattern_extra; - uint64_t custom; - char *custom_str; - void *custom_ptr; - struct uwsgi_regexp_list *next; -}; + uint64_t custom; + char *custom_str; + void *custom_ptr; + struct uwsgi_regexp_list *next; + }; #endif -struct uwsgi_rbtree { - struct uwsgi_rb_timer *root; - struct uwsgi_rb_timer *sentinel; -}; + struct uwsgi_rbtree { + struct uwsgi_rb_timer *root; + struct uwsgi_rb_timer *sentinel; + }; -struct uwsgi_rb_timer { - uint8_t color; - struct uwsgi_rb_timer *parent; - struct uwsgi_rb_timer *left; - struct uwsgi_rb_timer *right; - uint64_t value; - void *data; -}; + struct uwsgi_rb_timer { + uint8_t color; + struct uwsgi_rb_timer *parent; + struct uwsgi_rb_timer *left; + struct uwsgi_rb_timer *right; + uint64_t value; + void *data; + }; -struct uwsgi_rbtree *uwsgi_init_rb_timer(void); -struct uwsgi_rb_timer *uwsgi_min_rb_timer(struct uwsgi_rbtree *, struct uwsgi_rb_timer *); -struct uwsgi_rb_timer *uwsgi_add_rb_timer(struct uwsgi_rbtree *, uint64_t, void *); -void uwsgi_del_rb_timer(struct uwsgi_rbtree *, struct uwsgi_rb_timer *); + struct uwsgi_rbtree *uwsgi_init_rb_timer(void); + struct uwsgi_rb_timer *uwsgi_min_rb_timer(struct uwsgi_rbtree *, struct uwsgi_rb_timer *); + struct uwsgi_rb_timer *uwsgi_add_rb_timer(struct uwsgi_rbtree *, uint64_t, void *); + void uwsgi_del_rb_timer(struct uwsgi_rbtree *, struct uwsgi_rb_timer *); -union uwsgi_sockaddr { - struct sockaddr sa; - struct sockaddr_in sa_in; - struct sockaddr_un sa_un; -#ifdef UWSGI_IPV6 - struct sockaddr_in6 sa_in6; -#endif -}; + union uwsgi_sockaddr { + struct sockaddr sa; + struct sockaddr_in sa_in; + struct sockaddr_un sa_un; + struct sockaddr_in6 sa_in6; + }; -union uwsgi_sockaddr_ptr { - struct sockaddr *sa; - struct sockaddr_in *sa_in; - struct sockaddr_un *sa_un; -#ifdef UWSGI_IPV6 - struct sockaddr_in6 *sa_in6; -#endif -}; + union uwsgi_sockaddr_ptr { + struct sockaddr *sa; + struct sockaddr_in *sa_in; + struct sockaddr_un *sa_un; + struct sockaddr_in6 *sa_in6; + }; // Gateways are processes (managed by the master) that extends the // server core features // -- Gateways can prefork or spawn threads -- -struct uwsgi_gateway { + struct uwsgi_gateway { - char *name; - char *fullname; - void (*loop) (int, void *); - pid_t pid; - int num; - int use_signals; + char *name; + char *fullname; + void (*loop) (int, void *); + pid_t pid; + int num; + int use_signals; - int internal_subscription_pipe[2]; - uint64_t respawns; - - void *data; -}; + int internal_subscription_pipe[2]; + uint64_t respawns; -struct uwsgi_gateway_socket { + void *data; + }; - char *name; - size_t name_len; - int fd; - char *zerg; + struct uwsgi_gateway_socket { - char *port; - int port_len; + char *name; + size_t name_len; + int fd; + char *zerg; - int no_defer; + char *port; + int port_len; - void *data; - // this requires UDP - int subscription; - int shared; + int no_defer; - char *owner; - struct uwsgi_gateway *gateway; + void *data; + int subscription; + int shared; - struct uwsgi_gateway_socket *next; + char *owner; + struct uwsgi_gateway *gateway; - // could be useful for ssl - void *ctx; - // could be useful ofr plugins - int mode; - -}; + struct uwsgi_gateway_socket *next; + + // could be useful for ssl + void *ctx; + // could be useful ofr plugins + int mode; + + }; // Daemons are external processes maintained by the master -struct uwsgi_daemon { - char *command; - pid_t pid; - uint64_t respawns; - time_t born; - time_t last_spawn; - int status; - int registered; + struct uwsgi_daemon { + char *command; + pid_t pid; + uint64_t respawns; + time_t born; + time_t last_spawn; + int status; + int registered; - char *pidfile; - int daemonize; + char *pidfile; + int daemonize; - // this is incremented every time a pidfile is not found - uint64_t pidfile_checks; - // frequency of pidfile checks (default 10 secs) - int freq; + // this is incremented every time a pidfile is not found + uint64_t pidfile_checks; + // frequency of pidfile checks (default 10 secs) + int freq; - struct uwsgi_daemon *next; -}; + struct uwsgi_daemon *next; + }; -struct uwsgi_logger { - char *name; - char *id; - ssize_t (*func)(struct uwsgi_logger *, char *, size_t); - int configured; - int fd; - void *data; - union uwsgi_sockaddr addr; - socklen_t addr_len; - int count; - struct msghdr msg; - char *buf; - // used by choosen logger - char *arg; - struct uwsgi_logger *next; -}; + struct uwsgi_logger { + char *name; + char *id; + ssize_t(*func) (struct uwsgi_logger *, char *, size_t); + int configured; + int fd; + void *data; + union uwsgi_sockaddr addr; + socklen_t addr_len; + int count; + struct msghdr msg; + char *buf; + // used by choosen logger + char *arg; + struct uwsgi_logger *next; + }; #ifdef UWSGI_SSL -struct uwsgi_legion_node { - char *name; - uint16_t name_len; - uint64_t valor; - char uuid[37]; - char *scroll; - uint64_t checksum; - uint16_t scroll_len; - uint64_t lord_valor; - char lord_uuid[36]; - time_t last_seen; - struct uwsgi_legion_node *prev; - struct uwsgi_legion_node *next; -}; -struct uwsgi_legion { - char *legion; - uint16_t legion_len; - uint64_t valor; - char *addr; - char *name; - uint16_t name_len; - pid_t pid; - char uuid[37]; - int socket; + struct uwsgi_legion_node { + char *name; + uint16_t name_len; + uint64_t valor; + char uuid[37]; + char *scroll; + uint64_t checksum; + uint16_t scroll_len; + uint64_t lord_valor; + char lord_uuid[36]; + time_t last_seen; + struct uwsgi_legion_node *prev; + struct uwsgi_legion_node *next; + }; + struct uwsgi_legion { + char *legion; + uint16_t legion_len; + uint64_t valor; + char *addr; + char *name; + uint16_t name_len; + pid_t pid; + char uuid[37]; + int socket; - int quorum; - int changed; + int quorum; + int changed; - uint64_t checksum; - + uint64_t checksum; - char lord_uuid[36]; - uint64_t lord_valor; - time_t i_am_the_lord; + char lord_uuid[36]; + uint64_t lord_valor; - time_t unix_check; + time_t i_am_the_lord; - time_t last_warning; + time_t unix_check; - pthread_mutex_t lock; + time_t last_warning; - EVP_CIPHER_CTX *encrypt_ctx; - EVP_CIPHER_CTX *decrypt_ctx; + pthread_mutex_t lock; - // found nodes dynamic lists - struct uwsgi_legion_node *nodes_head; - struct uwsgi_legion_node *nodes_tail; + EVP_CIPHER_CTX *encrypt_ctx; + EVP_CIPHER_CTX *decrypt_ctx; - // static list of nodes to send announces to - struct uwsgi_string_list *nodes; - struct uwsgi_string_list *lord_hooks; - struct uwsgi_string_list *unlord_hooks; - struct uwsgi_string_list *setup_hooks; - struct uwsgi_string_list *death_hooks; - struct uwsgi_legion *next; -}; + // found nodes dynamic lists + struct uwsgi_legion_node *nodes_head; + struct uwsgi_legion_node *nodes_tail; -struct uwsgi_legion_action { - char *name; - int (*func)(struct uwsgi_legion *, char *); - struct uwsgi_legion_action *next; -}; + // static list of nodes to send announces to + struct uwsgi_string_list *nodes; + struct uwsgi_string_list *lord_hooks; + struct uwsgi_string_list *unlord_hooks; + struct uwsgi_string_list *setup_hooks; + struct uwsgi_string_list *death_hooks; + struct uwsgi_legion *next; + }; + + struct uwsgi_legion_action { + char *name; + int (*func) (struct uwsgi_legion *, char *); + struct uwsgi_legion_action *next; + }; #endif -struct uwsgi_queue_header { - uint64_t pos; - uint64_t pull_pos; -}; + struct uwsgi_queue_header { + uint64_t pos; + uint64_t pull_pos; + }; -struct uwsgi_queue_item { - uint64_t size; - time_t ts; -}; + struct uwsgi_queue_item { + uint64_t size; + time_t ts; + }; -struct uwsgi_hash_algo { - char *name; - uint32_t (*func)(char *, uint64_t); - struct uwsgi_hash_algo *next; -}; + struct uwsgi_hash_algo { + char *name; + uint32_t(*func) (char *, uint64_t); + struct uwsgi_hash_algo *next; + }; -struct uwsgi_hash_algo *uwsgi_hash_algo_get(char *); -void uwsgi_hash_algo_register(char *, uint32_t (*)(char *, uint64_t)); -void uwsgi_hash_algo_register_all(void); + struct uwsgi_hash_algo *uwsgi_hash_algo_get(char *); + void uwsgi_hash_algo_register(char *, uint32_t(*)(char *, uint64_t)); + void uwsgi_hash_algo_register_all(void); // maintain alignment here !!! -struct uwsgi_cache_item { - // item specific flags - uint64_t flags; - // size of the key - uint64_t keysize; - // hash of the key - uint64_t hash; - // size of the value (64bit) - uint64_t valsize; - // 64bit expiration (0 for immortal) - uint64_t expires; - // 64bit hits - uint64_t hits; - // previous same-hash item - uint64_t prev; - // next same-hash item - uint64_t next; - // key characters follows... - char key[]; -} __attribute__ ((__packed__)); + struct uwsgi_cache_item { + // item specific flags + uint64_t flags; + // size of the key + uint64_t keysize; + // hash of the key + uint64_t hash; + // size of the value (64bit) + uint64_t valsize; + // 64bit expiration (0 for immortal) + uint64_t expires; + // 64bit hits + uint64_t hits; + // previous same-hash item + uint64_t prev; + // next same-hash item + uint64_t next; + // key characters follows... + char key[]; + } __attribute__ ((__packed__)); -struct uwsgi_cache { - char *name; - uint16_t name_len; + struct uwsgi_cache { + char *name; + uint16_t name_len; - uint64_t keysize; - uint64_t blocks; - uint64_t blocksize; + uint64_t keysize; + uint64_t blocks; + uint64_t blocksize; - struct uwsgi_hash_algo *hash; - uint64_t *hashtable; - uint32_t hashsize; + struct uwsgi_hash_algo *hash; + uint64_t *hashtable; + uint32_t hashsize; - uint64_t first_available_block; - uint64_t *unused_blocks_stack; - uint64_t unused_blocks_stack_ptr; - uint8_t use_blocks_bitmap; - uint8_t *blocks_bitmap; + uint64_t first_available_block; + uint64_t *unused_blocks_stack; + uint64_t unused_blocks_stack_ptr; + uint8_t use_blocks_bitmap; + uint8_t *blocks_bitmap; - uint64_t max_items; - uint64_t n_items; - struct uwsgi_cache_item *items; + uint64_t max_items; + uint64_t n_items; + struct uwsgi_cache_item *items; - void *data; + void *data; - uint8_t no_expire; - uint64_t full; - uint64_t hits; - uint64_t miss; + uint8_t no_expire; + uint64_t full; + uint64_t hits; + uint64_t miss; - char *store; - uint64_t filesize; + char *store; + uint64_t filesize; - int thread_server_fd; + int thread_server_fd; - struct uwsgi_string_list *nodes; - struct uwsgi_string_list *sync_nodes; + struct uwsgi_string_list *nodes; + struct uwsgi_string_list *sync_nodes; - struct uwsgi_lock_item *lock; + struct uwsgi_lock_item *lock; - struct uwsgi_cache *next; -}; + struct uwsgi_cache *next; + }; -struct uwsgi_option { - char *name; - int type; - int shortcut; - char *help; - void (*func)(char *, char *, void *); - void *data; - uint64_t flags; -}; + struct uwsgi_option { + char *name; + int type; + int shortcut; + char *help; + void (*func) (char *, char *, void *); + void *data; + uint64_t flags; + }; -struct uwsgi_opt { - char *key; - char *value; - int configured; -}; - -#define MAX_CLUSTER_NODES 100 + struct uwsgi_opt { + char *key; + char *value; + int configured; + }; #define UWSGI_NODE_OK 0 #define UWSGI_NODE_FAILED 1 @@ -798,209 +794,214 @@ struct uwsgi_opt { #define MAX_VARS 64 -struct uwsgi_loop { - char *name; - void (*loop) (void); - struct uwsgi_loop *next; -}; + struct uwsgi_loop { + char *name; + void (*loop) (void); + struct uwsgi_loop *next; + }; -struct wsgi_request; + struct wsgi_request; -struct uwsgi_socket { - int fd; - char *name; - int name_len; - int family; - int bound; - int arg; - void *ctx; + struct uwsgi_socket { + int fd; + char *name; + int name_len; + int family; + int bound; + int arg; + void *ctx; - int queue; - int no_defer; + int queue; + int no_defer; - int auto_port; - // true if connection must be initialized for each core - int per_core; + int auto_port; + // true if connection must be initialized for each core + int per_core; - char *proto_name; + // this is the protocol internal name + char *proto_name; - int (*proto) (struct wsgi_request *); - int (*proto_accept) (struct wsgi_request *, int); - int (*proto_write) (struct wsgi_request *, char *, size_t); - int (*proto_write_headers) (struct wsgi_request *, char *, size_t); - int (*proto_sendfile) (struct wsgi_request *, int, size_t, size_t); - ssize_t(*proto_read_body) (struct wsgi_request *, char *, size_t); - struct uwsgi_buffer *(*proto_prepare_headers) (struct wsgi_request *, char *, uint16_t); - struct uwsgi_buffer *(*proto_add_header) (struct wsgi_request *, char *, uint16_t, char *, uint16_t); - int(*proto_fix_headers) (struct wsgi_request *); - void (*proto_close) (struct wsgi_request *); - void (*proto_thread_fixup) (struct uwsgi_socket *, int); - int edge_trigger; + // call that when a request is accepted + int (*proto_accept) (struct wsgi_request *, int); + // call that to parse the request (without the body) + int (*proto) (struct wsgi_request *); + // call that to write reponse + int (*proto_write) (struct wsgi_request *, char *, size_t); + // call that to write headers (if a special case is needed for them) + int (*proto_write_headers) (struct wsgi_request *, char *, size_t); + // call that when sendfile() is invoked + int (*proto_sendfile) (struct wsgi_request *, int, size_t, size_t); + // call that to read the body of a request (could map to a simple read()) + ssize_t(*proto_read_body) (struct wsgi_request *, char *, size_t); + // hook to call when a new series of response headers is created + struct uwsgi_buffer *(*proto_prepare_headers) (struct wsgi_request *, char *, uint16_t); + // hook to call when a header must be added + struct uwsgi_buffer *(*proto_add_header) (struct wsgi_request *, char *, uint16_t, char *, uint16_t); + // last function to call before sending headers to the client + int (*proto_fix_headers) (struct wsgi_request *); + // hook to call when a request is closed + void (*proto_close) (struct wsgi_request *); + // special hook to call (if needed) in multithread mode + void (*proto_thread_fixup) (struct uwsgi_socket *, int); - int *retry; + int edge_trigger; + int *retry; - int can_offload; + int can_offload; - // this is a special map for having socket->thread mapping - int *fd_threads; + // this is a special map for having socket->thread mapping + int *fd_threads; #ifdef UWSGI_UUID - char uuid[37]; + char uuid[37]; #endif - // currently used by zeromq handlers - void *pub; - void *pull; - pthread_key_t key; + // currently used by zeromq handlers + void *pub; + void *pull; + pthread_key_t key; - pthread_mutex_t lock; + pthread_mutex_t lock; - char *receiver; + char *receiver; - int disabled; - int recv_flag; + int disabled; + int recv_flag; - struct uwsgi_socket *next; - int lazy; - int shared; - int from_shared; -}; + struct uwsgi_socket *next; + int lazy; + int shared; + int from_shared; + }; -struct uwsgi_server; + struct uwsgi_server; -struct uwsgi_plugin { + struct uwsgi_plugin { - const char *name; - const char *alias; - uint8_t modifier1; - void *data; - void (*on_load) (void); - int (*init) (void); - void (*post_init) (void); - void (*post_fork) (void); - struct uwsgi_option *options; - void (*enable_threads) (void); - void (*init_thread) (int); - int (*request) (struct wsgi_request *); - void (*after_request) (struct wsgi_request *); - void (*preinit_apps) (void); - void (*init_apps) (void); - void (*postinit_apps) (void); - void (*fixup) (void); - void (*master_fixup) (int); - void (*master_cycle) (void); - int (*mount_app) (char *, char *); - int (*manage_udp) (char *, int, char *, int); - void (*suspend) (struct wsgi_request *); - void (*resume) (struct wsgi_request *); + const char *name; + const char *alias; + uint8_t modifier1; + void *data; + void (*on_load) (void); + int (*init) (void); + void (*post_init) (void); + void (*post_fork) (void); + struct uwsgi_option *options; + void (*enable_threads) (void); + void (*init_thread) (int); + int (*request) (struct wsgi_request *); + void (*after_request) (struct wsgi_request *); + void (*preinit_apps) (void); + void (*init_apps) (void); + void (*postinit_apps) (void); + void (*fixup) (void); + void (*master_fixup) (int); + void (*master_cycle) (void); + int (*mount_app) (char *, char *); + int (*manage_udp) (char *, int, char *, int); + void (*suspend) (struct wsgi_request *); + void (*resume) (struct wsgi_request *); - void (*harakiri) (int); + void (*harakiri) (int); - void (*hijack_worker) (void); - void (*spooler_init) (void); - void (*atexit) (void); + void (*hijack_worker) (void); + void (*spooler_init) (void); + void (*atexit) (void); - int (*magic) (char *, char *); + int (*magic) (char *, char *); - void *(*encode_string) (char *); - char *(*decode_string) (void *); - int (*signal_handler) (uint8_t, void *); - char *(*code_string) (char *, char *, char *, char *, uint16_t); + void *(*encode_string) (char *); + char *(*decode_string) (void *); + int (*signal_handler) (uint8_t, void *); + char *(*code_string) (char *, char *, char *, char *, uint16_t); - int (*spooler) (char *, char *, uint16_t, char *, size_t); + int (*spooler) (char *, char *, uint16_t, char *, size_t); - uint16_t(*rpc) (void *, uint8_t, char **, uint16_t *, char *); + uint16_t(*rpc) (void *, uint8_t, char **, uint16_t *, char *); - void (*jail) (int (*)(void *), char **); - void (*before_privileges_drop)(void); + void (*jail) (int (*)(void *), char **); + void (*before_privileges_drop) (void); - int (*mule)(char *); - int (*mule_msg)(char *, size_t); + int (*mule) (char *); + int (*mule_msg) (char *, size_t); - void (*master_cleanup) (void); + void (*master_cleanup) (void); -}; + }; #ifdef UWSGI_PCRE -int uwsgi_regexp_build(char *, pcre **, pcre_extra **); -int uwsgi_regexp_match(pcre *, pcre_extra *, char *, int); -int uwsgi_regexp_match_ovec(pcre *, pcre_extra *, char *, int, int *, int); -int uwsgi_regexp_ovector(pcre *, pcre_extra *); -char *uwsgi_regexp_apply_ovec(char *, int, char *, int, int *, int); + int uwsgi_regexp_build(char *, pcre **, pcre_extra **); + int uwsgi_regexp_match(pcre *, pcre_extra *, char *, int); + int uwsgi_regexp_match_ovec(pcre *, pcre_extra *, char *, int, int *, int); + int uwsgi_regexp_ovector(pcre *, pcre_extra *); + char *uwsgi_regexp_apply_ovec(char *, int, char *, int, int *, int); #endif -struct uwsgi_app { + struct uwsgi_app { - uint8_t modifier1; + uint8_t modifier1; - char mountpoint[0xff]; - int mountpoint_len; + char mountpoint[0xff]; + int mountpoint_len; - void *interpreter; - void *callable; + void *interpreter; + void *callable; -#ifdef UWSGI_ASYNC - void **args; - void **environ; -#else - void *args; - void *environ; -#endif + void **args; + void **environ; - void *sendfile; - void *input; - void *error; - void *stream; - void *responder0; - void *responder1; - void *responder2; + void *sendfile; + void *input; + void *error; + void *stream; + void *responder0; + void *responder1; + void *responder2; -#ifdef UWSGI_ASYNC - void *eventfd_read; - void *eventfd_write; -#endif + void *eventfd_read; + void *eventfd_write; - void *(*request_subhandler) (struct wsgi_request *, struct uwsgi_app *); - int (*response_subhandler) (struct wsgi_request *); + void *(*request_subhandler) (struct wsgi_request *, struct uwsgi_app *); + int (*response_subhandler) (struct wsgi_request *); - int argc; - uint64_t requests; - uint64_t exceptions; + int argc; + uint64_t requests; + uint64_t exceptions; - char chdir[0xff]; - char touch_reload[0xff]; + char chdir[0xff]; + char touch_reload[0xff]; - time_t touch_reload_mtime; + time_t touch_reload_mtime; - void *gateway_version; - void *uwsgi_version; - void *uwsgi_node; + void *gateway_version; + void *uwsgi_version; + void *uwsgi_node; - time_t started_at; - time_t startup_time; + time_t started_at; + time_t startup_time; - uint64_t avg_response_time; -}; + uint64_t avg_response_time; + }; -struct uwsgi_spooler { + struct uwsgi_spooler { - char dir[PATH_MAX]; - pid_t pid; - uint64_t respawned; - uint64_t tasks; - struct uwsgi_lock_item *lock; - time_t harakiri; + char dir[PATH_MAX]; + pid_t pid; + uint64_t respawned; + uint64_t tasks; + struct uwsgi_lock_item *lock; + time_t harakiri; - int mode; + int mode; - int running; + int running; - int signal_pipe[2]; + int signal_pipe[2]; - struct uwsgi_spooler *next; -}; + struct uwsgi_spooler *next; + }; #ifdef UWSGI_ROUTING @@ -1013,1481 +1014,1398 @@ struct uwsgi_spooler { // go to the next group of routes #define UWSGI_ROUTE_GOON 3 -struct uwsgi_route { + struct uwsgi_route { - pcre *pattern; - pcre_extra *pattern_extra; - int ovn; - int *ovector; + pcre *pattern; + pcre_extra *pattern_extra; + int ovn; + int *ovector; - size_t subject; - size_t subject_len; + size_t subject; + size_t subject_len; - int (*func)(struct wsgi_request *, struct uwsgi_route *); + int (*func) (struct wsgi_request *, struct uwsgi_route *); - void *data; - size_t data_len; + void *data; + size_t data_len; - void *data2; - size_t data2_len; + void *data2; + size_t data2_len; - void *data3; - size_t data3_len; + void *data3; + size_t data3_len; - // 64bit value for custom usage - uint64_t custom; + // 64bit value for custom usage + uint64_t custom; - // true ifthis is the last rule of this kind - int is_last; + // true ifthis is the last rule of this kind + int is_last; - struct uwsgi_route *next; + struct uwsgi_route *next; -}; + }; -struct uwsgi_router { + struct uwsgi_router { - char *name; - int (*func)(struct uwsgi_route *, char *); - struct uwsgi_router *next; + char *name; + int (*func) (struct uwsgi_route *, char *); + struct uwsgi_router *next; -}; + }; #endif #ifdef UWSGI_ALARM -struct uwsgi_alarm; -struct uwsgi_alarm_instance { - char *name; - char *arg; - void *data_ptr; - uint8_t data8; - uint16_t data16; - uint32_t data32; - uint64_t data64; + struct uwsgi_alarm; + struct uwsgi_alarm_instance { + char *name; + char *arg; + void *data_ptr; + uint8_t data8; + uint16_t data16; + uint32_t data32; + uint64_t data64; - time_t last_run; + time_t last_run; - char *last_msg; - size_t last_msg_size; + char *last_msg; + size_t last_msg_size; - struct uwsgi_alarm *alarm; - struct uwsgi_alarm_instance *next; -}; + struct uwsgi_alarm *alarm; + struct uwsgi_alarm_instance *next; + }; -struct uwsgi_alarm { - char *name; - void (*init)(struct uwsgi_alarm_instance *); - void (*func)(struct uwsgi_alarm_instance *, char *, size_t); - struct uwsgi_alarm *next; -}; + struct uwsgi_alarm { + char *name; + void (*init) (struct uwsgi_alarm_instance *); + void (*func) (struct uwsgi_alarm_instance *, char *, size_t); + struct uwsgi_alarm *next; + }; -struct uwsgi_alarm_ll { - struct uwsgi_alarm_instance *alarm; - struct uwsgi_alarm_ll *next; -}; + struct uwsgi_alarm_ll { + struct uwsgi_alarm_instance *alarm; + struct uwsgi_alarm_ll *next; + }; -struct uwsgi_alarm_log { - pcre *pattern; - pcre_extra *pattern_extra; - int negate; - struct uwsgi_alarm_ll *alarms; - struct uwsgi_alarm_log *next; -}; + struct uwsgi_alarm_log { + pcre *pattern; + pcre_extra *pattern_extra; + int negate; + struct uwsgi_alarm_ll *alarms; + struct uwsgi_alarm_log *next; + }; #endif -struct __attribute__ ((packed)) uwsgi_header { - uint8_t modifier1; - uint16_t pktsize; - uint8_t modifier2; -}; - -struct uwsgi_async_fd { - int fd; - int event; - struct uwsgi_async_fd *prev; - struct uwsgi_async_fd *next; -}; - -struct uwsgi_logvar { - char key[256]; - uint8_t keylen; - char val[256]; - uint8_t vallen; - struct uwsgi_logvar *next; -}; - -struct wsgi_request { - struct uwsgi_header uh; - //temporary attr - - int app_id; - int dynamic; - int parsed; - - char *appid; - uint16_t appid_len; - - struct pollfd poll; - - //this is big enough to contain sockaddr_in - struct sockaddr_un c_addr; - int c_len; - - //iovec - struct iovec *hvec; - - uint64_t start_of_request; - uint64_t start_of_request_in_sec; - uint64_t end_of_request; - - char *uri; - uint16_t uri_len; - char *remote_addr; - uint16_t remote_addr_len; - char *remote_user; - uint16_t remote_user_len; - char *query_string; - uint16_t query_string_len; - char *protocol; - uint16_t protocol_len; - char *method; - uint16_t method_len; - char *scheme; - uint16_t scheme_len; - char *https; - uint16_t https_len; - char *script_name; - uint16_t script_name_len; - int script_name_pos; - - char *host; - uint16_t host_len; - - char *content_type; - uint16_t content_type_len; - - char *document_root; - uint16_t document_root_len; - - char *user_agent; - uint16_t user_agent_len; - - char *encoding; - uint16_t encoding_len; - - char *referer; - uint16_t referer_len; - - char *path_info; - uint16_t path_info_len; - int path_info_pos; - - char *authorization; - uint16_t authorization_len; - - uint16_t via; - - char *script; - uint16_t script_len; - char *module; - uint16_t module_len; - char *callable; - uint16_t callable_len; - char *pyhome; - uint16_t pyhome_len; + struct __attribute__ ((packed)) uwsgi_header { + uint8_t modifier1; + uint16_t pktsize; + uint8_t modifier2; + }; + + struct uwsgi_async_fd { + int fd; + int event; + struct uwsgi_async_fd *prev; + struct uwsgi_async_fd *next; + }; + + struct uwsgi_logvar { + char key[256]; + uint8_t keylen; + char val[256]; + uint8_t vallen; + struct uwsgi_logvar *next; + }; + + struct wsgi_request { + int fd; + struct uwsgi_header *uh; + + int app_id; + int dynamic; + int parsed; + + char *appid; + uint16_t appid_len; + + //this is big enough to contain sockaddr_in + struct sockaddr_un c_addr; + int c_len; + + //iovec + struct iovec *hvec; + + uint64_t start_of_request; + uint64_t start_of_request_in_sec; + uint64_t end_of_request; + + char *uri; + uint16_t uri_len; + char *remote_addr; + uint16_t remote_addr_len; + char *remote_user; + uint16_t remote_user_len; + char *query_string; + uint16_t query_string_len; + char *protocol; + uint16_t protocol_len; + char *method; + uint16_t method_len; + char *scheme; + uint16_t scheme_len; + char *https; + uint16_t https_len; + char *script_name; + uint16_t script_name_len; + int script_name_pos; + + char *host; + uint16_t host_len; + + char *content_type; + uint16_t content_type_len; + + char *document_root; + uint16_t document_root_len; + + char *user_agent; + uint16_t user_agent_len; + + char *encoding; + uint16_t encoding_len; + + char *referer; + uint16_t referer_len; + + char *path_info; + uint16_t path_info_len; + int path_info_pos; + + char *authorization; + uint16_t authorization_len; + + uint16_t via; + + char *script; + uint16_t script_len; + char *module; + uint16_t module_len; + char *callable; + uint16_t callable_len; + char *pyhome; + uint16_t pyhome_len; + + char *file; + uint16_t file_len; + + char *paste; + uint16_t paste_len; + + char *chdir; + uint16_t chdir_len; + + char *touch_reload; + uint16_t touch_reload_len; + + char *cache_get; + uint16_t cache_get_len; + + char *if_modified_since; + uint16_t if_modified_since_len; + + int fd_closed; + + int sendfile_fd; + size_t sendfile_fd_chunk; + size_t sendfile_fd_size; + off_t sendfile_fd_pos; + void *sendfile_obj; + + uint16_t var_cnt; + uint16_t header_cnt; + + int do_not_log; + + int do_not_add_to_async_queue; + + int status; + struct uwsgi_buffer *headers; + + size_t response_size; + size_t headers_size; + + int async_id; + int async_status; + + int switches; + size_t write_pos; + + int async_timed_out; + int async_ready_fd; + int async_last_ready_fd; + struct uwsgi_rb_timer *async_timeout; + struct uwsgi_async_fd *waiting_fds; + + void *async_app; + void *async_result; + void *async_placeholder; + void *async_args; + void *async_environ; + void *async_input; + void *async_sendfile; + + int async_force_again; + + int async_plagued; - char *file; - uint16_t file_len; + int suspended; + int write_errors; - char *paste; - uint16_t paste_len; + int *ovector; + size_t post_cl; + size_t post_pos; + size_t post_readline_size; + size_t post_readline_pos; + size_t post_readline_watermark; + FILE *post_file; + char *post_readline_buf; + // this is used when no post buffering is in place + char *post_read_buf; + size_t post_read_buf_size; + char *post_buffering_buf; + // when set, do not send warnings about bad behaviours + int post_warning; + + // current socket mapped to request + struct uwsgi_socket *socket; + + // check if headers are already sent + int headers_sent; + int headers_hvec; + + uint64_t proto_parser_pos; + int proto_parser_status; + void *proto_parser_buf; + void *proto_parser_remains_buf; + size_t proto_parser_remains; + + char *buffer; + + int log_this; - char *chdir; - uint16_t chdir_len; - - char *touch_reload; - uint16_t touch_reload_len; - - char *cache_get; - uint16_t cache_get_len; - - char *if_modified_since; - uint16_t if_modified_since_len; - - int fd_closed; - - int sendfile_fd; - size_t sendfile_fd_chunk; - size_t sendfile_fd_size; - off_t sendfile_fd_pos; - void *sendfile_obj; - - uint16_t var_cnt; - uint16_t header_cnt; - - int do_not_log; - - int do_not_add_to_async_queue; - - int status; - struct uwsgi_buffer *headers; - - size_t response_size; - ssize_t headers_size; - - int async_id; - int async_status; - - int switches; - size_t write_pos; - - int async_timed_out; - int async_ready_fd; - int async_last_ready_fd; - struct uwsgi_rb_timer *async_timeout; - struct uwsgi_async_fd *waiting_fds; - - void *async_app; - void *async_result; - void *async_placeholder; - void *async_args; - void *async_environ; - void *async_post; - void *async_input; - void *async_sendfile; - - int async_force_again; - - int async_plagued; - - int suspended; - int write_errors; - - int *ovector; - size_t post_cl; - off_t post_pos; - char *post_buffering_buf; - uint64_t post_buffering_read; - - // current socket mapped to request - struct uwsgi_socket *socket; - - // check if headers are already sent - int headers_sent; - int headers_hvec; - - int body_as_file; - //for generic use - size_t buf_pos; - - uint64_t proto_parser_pos; - int proto_parser_status; - void *proto_parser_buf; - - char *buffer; - - off_t frame_pos; - int frame_len; - - int log_this; - - int sigwait; - int signal_received; - - struct uwsgi_logvar *logvars; - struct uwsgi_string_list *additional_headers; - struct uwsgi_string_list *remove_headers; - - struct uwsgi_buffer *websocket_buf; - size_t websocket_need; - int websocket_phase; - uint8_t websocket_opcode; - size_t websocket_has_mask; - size_t websocket_size; - size_t websocket_pktsize; - time_t websocket_last_ping; - time_t websocket_last_pong; - int websocket_closed; - - uint64_t stream_id; - - // avoid routing loops - int is_routing; - // internal routing vm program counter - uint32_t route_pc; - // internal routing goto instruction - uint32_t route_goto; - - struct msghdr msg; - union { - struct cmsghdr cmsg; - // should be enough... - char control[64]; - } msg_control; - - -}; - -struct uwsgi_channel { - char *name; - int write_pipe[2]; - - int *fd; - uint8_t *subscriptions; - - uint64_t max_packet_size; - char *pktbuf; - uint64_t tx; - uint64_t rx; - - struct uwsgi_channel *next; -}; - - -struct uwsgi_fmon { - char filename[0xff]; - int fd; - int id; - int registered; - uint8_t sig; -}; - -struct uwsgi_timer { - int value; - int fd; - int id; - int registered; - uint8_t sig; -}; - -struct uwsgi_signal_rb_timer { - int value; - int registered; - int iterations; - int iterations_done; - uint8_t sig; - struct uwsgi_rb_timer *uwsgi_rb_timer; -}; - -struct uwsgi_signal_probe { - - int (*func)(int, struct uwsgi_signal_probe *); - char args[1024]; - - int fd; - int state; - int bad; - int last_event; - void *data; - uint64_t cycles; - - int timeout; - int freq; - - int registered; - uint8_t sig; -}; - -struct uwsgi_probe { - - char *name; - int (*func)(int, struct uwsgi_signal_probe *); - - struct uwsgi_probe *next; -}; - -struct uwsgi_cheaper_algo { - - char *name; - int (*func)(void); - struct uwsgi_cheaper_algo *next; -}; - -struct uwsgi_emperor_scanner; - -struct uwsgi_imperial_monitor { - char *scheme; - void (*init)(struct uwsgi_emperor_scanner *); - void (*func)(struct uwsgi_emperor_scanner *); - struct uwsgi_imperial_monitor *next; -}; - -struct uwsgi_clock { - char *name; - time_t (*seconds)(void); - uint64_t (*microseconds)(void); - struct uwsgi_clock *next; -}; - -struct uwsgi_subscribe_slot; -struct uwsgi_stats_pusher; -struct uwsgi_stats_pusher_instance; + int sigwait; + int signal_received; + + struct uwsgi_logvar *logvars; + struct uwsgi_string_list *additional_headers; + struct uwsgi_string_list *remove_headers; + + struct uwsgi_buffer *websocket_buf; + size_t websocket_need; + int websocket_phase; + uint8_t websocket_opcode; + size_t websocket_has_mask; + size_t websocket_size; + size_t websocket_pktsize; + time_t websocket_last_ping; + time_t websocket_last_pong; + int websocket_closed; + + uint64_t stream_id; + + // avoid routing loops + int is_routing; + // internal routing vm program counter + uint32_t route_pc; + // internal routing goto instruction + uint32_t route_goto; + + struct msghdr msg; + union { + struct cmsghdr cmsg; + // should be enough... + char control[64]; + } msg_control; + + + }; + + + struct uwsgi_fmon { + char filename[0xff]; + int fd; + int id; + int registered; + uint8_t sig; + }; + + struct uwsgi_timer { + int value; + int fd; + int id; + int registered; + uint8_t sig; + }; + + struct uwsgi_signal_rb_timer { + int value; + int registered; + int iterations; + int iterations_done; + uint8_t sig; + struct uwsgi_rb_timer *uwsgi_rb_timer; + }; + + struct uwsgi_signal_probe { + + int (*func) (int, struct uwsgi_signal_probe *); + char args[1024]; + + int fd; + int state; + int bad; + int last_event; + void *data; + uint64_t cycles; + + int timeout; + int freq; + + int registered; + uint8_t sig; + }; + + struct uwsgi_probe { + + char *name; + int (*func) (int, struct uwsgi_signal_probe *); + + struct uwsgi_probe *next; + }; + + struct uwsgi_cheaper_algo { + + char *name; + int (*func) (void); + struct uwsgi_cheaper_algo *next; + }; + + struct uwsgi_emperor_scanner; + + struct uwsgi_imperial_monitor { + char *scheme; + void (*init) (struct uwsgi_emperor_scanner *); + void (*func) (struct uwsgi_emperor_scanner *); + struct uwsgi_imperial_monitor *next; + }; + + struct uwsgi_clock { + char *name; + time_t(*seconds) (void); + uint64_t(*microseconds) (void); + struct uwsgi_clock *next; + }; + + struct uwsgi_subscribe_slot; + struct uwsgi_stats_pusher; + struct uwsgi_stats_pusher_instance; #define UWSGI_PROTO_MIN_CHECK 4 #define UWSGI_PROTO_MAX_CHECK 23 -struct uwsgi_server { + struct uwsgi_server { - // store the machine hostname - char hostname[256]; - int hostname_len; + // store the machine hostname + char hostname[256]; + int hostname_len; - int (*proto_hooks[UWSGI_PROTO_MAX_CHECK])(struct wsgi_request *, char *, char *, uint16_t); + int (*proto_hooks[UWSGI_PROTO_MAX_CHECK]) (struct wsgi_request *, char *, char *, uint16_t); - char **orig_argv; - char **argv; - int argc; - int max_procname; - int auto_procname; - char **environ; - char *procname_prefix; - char *procname_append; - char *procname_master; - char *procname; + char **orig_argv; + char **argv; + int argc; + int max_procname; + int auto_procname; + char **environ; + char *procname_prefix; + char *procname_append; + char *procname_master; + char *procname; - char *requested_clock; - struct uwsgi_clock *clocks; - struct uwsgi_clock *clock; + char *requested_clock; + struct uwsgi_clock *clocks; + struct uwsgi_clock *clock; - // quiet startup - int no_initial_output; + char *empty; - struct uwsgi_string_list *get_list; + // quiet startup + int no_initial_output; - // enable threads - int has_threads; - int no_threads_wait; + struct uwsgi_string_list *get_list; - // default app id - int default_app; + // enable threads + int has_threads; + int no_threads_wait; - char *logto2; - char *logformat; - int logformat_strftime; - int logformat_vectors; - struct uwsgi_logchunk *logchunks; - void (*logit)(struct wsgi_request *); - struct iovec **logvectors; + // default app id + int default_app; - // autoload plugins - int autoload; - struct uwsgi_string_list *plugins_dir; - struct uwsgi_string_list *blacklist; - struct uwsgi_string_list *whitelist; + char *logto2; + char *logformat; + int logformat_strftime; + int logformat_vectors; + struct uwsgi_logchunk *logchunks; + void (*logit) (struct wsgi_request *); + struct iovec **logvectors; - int snapshot; + // autoload plugins + int autoload; + struct uwsgi_string_list *plugins_dir; + struct uwsgi_string_list *blacklist; + struct uwsgi_string_list *whitelist; - // enable auto-snapshotting - int auto_snapshot; - pid_t restore_snapshot; + int snapshot; + + // enable auto-snapshotting + int auto_snapshot; + pid_t restore_snapshot; - int respawn_workers; - unsigned int reloads; + int respawn_workers; + unsigned int reloads; - // leave master running as root - int master_as_root; - // kill the stack on SIGTERM (instead of brutal reloading) - int die_on_term; + // leave master running as root + int master_as_root; + // kill the stack on SIGTERM (instead of brutal reloading) + int die_on_term; - // disable fd passing on unix socket - int no_fd_passing; + // disable fd passing on unix socket + int no_fd_passing; - // store the current time - time_t current_time; + // store the current time + time_t current_time; - uint64_t master_cycles; + uint64_t master_cycles; - int reuse_port; - int tcp_fast_open; - int tcp_fast_open_client; + int reuse_port; + int tcp_fast_open; + int tcp_fast_open_client; - // enable lazy mode - int lazy; - // enable lazy-apps mode - int lazy_apps; - // enable cheap mode - int cheap; - // enable cheaper mode - int cheaper; - char *requested_cheaper_algo; - struct uwsgi_cheaper_algo *cheaper_algos; - int (*cheaper_algo)(void); - int cheaper_step; - uint64_t cheaper_overload; - // minimal number of running workers in cheaper mode - int cheaper_count; - int cheaper_initial; - // enable idle mode - int idle; - - // destroy the stack when idle - int die_on_idle; + // enable lazy mode + int lazy; + // enable lazy-apps mode + int lazy_apps; + // enable cheap mode + int cheap; + // enable cheaper mode + int cheaper; + char *requested_cheaper_algo; + struct uwsgi_cheaper_algo *cheaper_algos; + int (*cheaper_algo) (void); + int cheaper_step; + uint64_t cheaper_overload; + // minimal number of running workers in cheaper mode + int cheaper_count; + int cheaper_initial; + // enable idle mode + int idle; - // store the screen session - char *screen_session; + // destroy the stack when idle + int die_on_idle; - // true if run under the emperor - int has_emperor; - char *emperor_procname; - int emperor_fd; - int emperor_queue; - int emperor_tyrant; - int emperor_fd_config; - int early_emperor; - int emperor_throttle; - int emperor_freq; - int emperor_max_throttle; - int emperor_magic_exec; - int emperor_heartbeat; - time_t next_heartbeat; - int heartbeat; - struct uwsgi_string_list *emperor; - struct uwsgi_imperial_monitor *emperor_monitors; - char *emperor_absolute_dir; - char *emperor_pidfile; - pid_t emperor_pid; - int emperor_broodlord; - int emperor_broodlord_count; - char *emperor_stats; - int emperor_stats_fd; - struct uwsgi_string_list *vassals_templates; - // true if loyal to the emperor - int loyal; + // store the screen session + char *screen_session; - // emperor hook (still in development) - char *vassals_start_hook; - char *vassals_stop_hook; + // true if run under the emperor + int has_emperor; + char *emperor_procname; + int emperor_fd; + int emperor_queue; + int emperor_tyrant; + int emperor_fd_config; + int early_emperor; + int emperor_throttle; + int emperor_freq; + int emperor_max_throttle; + int emperor_magic_exec; + int emperor_heartbeat; + time_t next_heartbeat; + int heartbeat; + struct uwsgi_string_list *emperor; + struct uwsgi_imperial_monitor *emperor_monitors; + char *emperor_absolute_dir; + char *emperor_pidfile; + pid_t emperor_pid; + int emperor_broodlord; + int emperor_broodlord_count; + char *emperor_stats; + int emperor_stats_fd; + struct uwsgi_string_list *vassals_templates; + // true if loyal to the emperor + int loyal; - struct uwsgi_string_list *additional_headers; - struct uwsgi_string_list *remove_headers; + // emperor hook (still in development) + char *vassals_start_hook; + char *vassals_stop_hook; - // maximum time to wait after a reload - time_t master_mercy; + struct uwsgi_string_list *additional_headers; + struct uwsgi_string_list *remove_headers; - // set cpu affinity - int cpu_affinity; + // maximum time to wait after a reload + time_t master_mercy; - int reload_mercy; - int worker_reload_mercy; - // map reloads to death - int exit_on_reload; + // set cpu affinity + int cpu_affinity; - // store options - int dirty_config; - int option_index; - int (*logic_opt)(char *, char *); - char *logic_opt_arg; - char *logic_opt_data; - int logic_opt_running; - int logic_opt_cycles; - struct uwsgi_option *options; - struct option *long_options; - char *short_options; - struct uwsgi_opt **exported_opts; - int exported_opts_cnt; - struct uwsgi_custom_option *custom_options; + int reload_mercy; + int worker_reload_mercy; + // map reloads to death + int exit_on_reload; - // dump the whole set of options - int dump_options; - // show ini representation of the current config - int show_config; + // store options + int dirty_config; + int option_index; + int (*logic_opt) (char *, char *); + char *logic_opt_arg; + char *logic_opt_data; + int logic_opt_running; + int logic_opt_cycles; + struct uwsgi_option *options; + struct option *long_options; + char *short_options; + struct uwsgi_opt **exported_opts; + int exported_opts_cnt; + struct uwsgi_custom_option *custom_options; - // list loaded features - int cheaper_algo_list; + // dump the whole set of options + int dump_options; + // show ini representation of the current config + int show_config; + + // list loaded features + int cheaper_algo_list; #ifdef UWSGI_ROUTING - int router_list; + int router_list; #endif - int imperial_monitor_list; - int plugins_list; - int loggers_list; - int loop_list; - int clock_list; + int imperial_monitor_list; + int plugins_list; + int loggers_list; + int loop_list; + int clock_list; #ifdef UWSGI_ALARM - int alarms_list; + int alarms_list; #endif - struct wsgi_request *wsgi_req; + struct wsgi_request *wsgi_req; - char *remap_modifier; + char *remap_modifier; - // enable zerg mode - int *zerg; - char *zerg_server; - struct uwsgi_string_list *zerg_node; - int zerg_fallback; - int zerg_server_fd; + // enable zerg mode + int *zerg; + char *zerg_server; + struct uwsgi_string_list *zerg_node; + int zerg_fallback; + int zerg_server_fd; - // security - char *chroot; - gid_t gid; - uid_t uid; - char *uidname; - char *gidname; - int no_initgroups; + // security + char *chroot; + gid_t gid; + uid_t uid; + char *uidname; + char *gidname; + int no_initgroups; #ifdef UWSGI_CAP - cap_value_t *cap; - int cap_count; + cap_value_t *cap; + int cap_count; #endif #ifdef __linux__ - int unshare; + int unshare; #endif - int ignore_sigpipe; - int ignore_write_errors; - int write_errors_tolerance; - int write_errors_exception_only; - int disable_write_exception; + int ignore_sigpipe; + int ignore_write_errors; + int write_errors_tolerance; + int write_errors_exception_only; + int disable_write_exception; - // still working on it - char *profiler; + // still working on it + char *profiler; - // the weight of the instance, used by various cluster/lb components - uint64_t weight; - int auto_weight; + // the weight of the instance, used by various cluster/lb components + uint64_t weight; + int auto_weight; - // mostly useless - char *mode; + // mostly useless + char *mode; - // binary path the worker image - char *worker_exec; + // binary path the worker image + char *worker_exec; - // this must be UN-shared - struct uwsgi_gateway_socket *gateway_sockets; + // this must be UN-shared + struct uwsgi_gateway_socket *gateway_sockets; - int ignore_script_name; - int manage_script_name; - int reload_on_exception; - int catch_exceptions; - struct uwsgi_string_list *reload_on_exception_type; - struct uwsgi_string_list *reload_on_exception_value; - struct uwsgi_string_list *reload_on_exception_repr; + int ignore_script_name; + int manage_script_name; + int reload_on_exception; + int catch_exceptions; + struct uwsgi_string_list *reload_on_exception_type; + struct uwsgi_string_list *reload_on_exception_value; + struct uwsgi_string_list *reload_on_exception_repr; - int no_default_app; - // exit if no-app is loaded - int need_app; + int no_default_app; + // exit if no-app is loaded + int need_app; - int forkbomb_delay; + int forkbomb_delay; - int logdate; - int log_micros; - char *log_strftime; - int log_x_forwarded_for; + int logdate; + int log_micros; + char *log_strftime; + int log_x_forwarded_for; - int honour_stdin; - struct termios termios; - int restore_tc; + int honour_stdin; + struct termios termios; + int restore_tc; - // route all of the logs to the master process - int req_log_master; - int log_master; - char *log_master_buf; - size_t log_master_bufsize; + // route all of the logs to the master process + int req_log_master; + int log_master; + char *log_master_buf; + size_t log_master_bufsize; - int log_reopen; - int log_truncate; - off_t log_maxsize; - char *log_backupname; + int log_reopen; + int log_truncate; + off_t log_maxsize; + char *log_backupname; - int original_log_fd; - int req_log_fd; + int original_log_fd; + int req_log_fd; - // static file serving - int file_serve_mode; - int build_mime_dict; + // static file serving + int file_serve_mode; + int build_mime_dict; - struct uwsgi_string_list *mime_file; + struct uwsgi_string_list *mime_file; - struct uwsgi_probe *probes; + struct uwsgi_probe *probes; - struct uwsgi_string_list *exec_pre_jail; - struct uwsgi_string_list *exec_post_jail; - struct uwsgi_string_list *exec_in_jail; - struct uwsgi_string_list *exec_as_root; - struct uwsgi_string_list *exec_as_user; - struct uwsgi_string_list *exec_as_user_atexit; - struct uwsgi_string_list *exec_pre_app; + struct uwsgi_string_list *exec_pre_jail; + struct uwsgi_string_list *exec_post_jail; + struct uwsgi_string_list *exec_in_jail; + struct uwsgi_string_list *exec_as_root; + struct uwsgi_string_list *exec_as_user; + struct uwsgi_string_list *exec_as_user_atexit; + struct uwsgi_string_list *exec_pre_app; - char *privileged_binary_patch; - char *unprivileged_binary_patch; - char *privileged_binary_patch_arg; - char *unprivileged_binary_patch_arg; + char *privileged_binary_patch; + char *unprivileged_binary_patch; + char *privileged_binary_patch_arg; + char *unprivileged_binary_patch_arg; - struct uwsgi_logger *loggers; - struct uwsgi_logger *choosen_logger; - struct uwsgi_logger *choosen_req_logger; - struct uwsgi_string_list *requested_logger; - struct uwsgi_string_list *requested_req_logger; + struct uwsgi_logger *loggers; + struct uwsgi_logger *choosen_logger; + struct uwsgi_logger *choosen_req_logger; + struct uwsgi_string_list *requested_logger; + struct uwsgi_string_list *requested_req_logger; #ifdef UWSGI_PCRE - int pcre_jit; - struct uwsgi_regexp_list *log_drain_rules; - struct uwsgi_regexp_list *log_filter_rules; - struct uwsgi_regexp_list *log_route; - struct uwsgi_regexp_list *log_req_route; + int pcre_jit; + struct uwsgi_regexp_list *log_drain_rules; + struct uwsgi_regexp_list *log_filter_rules; + struct uwsgi_regexp_list *log_route; + struct uwsgi_regexp_list *log_req_route; #endif #ifdef UWSGI_ALARM - int alarm_freq; - struct uwsgi_string_list *alarm_list; - struct uwsgi_string_list *alarm_logs_list; - struct uwsgi_alarm *alarms; - struct uwsgi_alarm_instance *alarm_instances; - struct uwsgi_alarm_log *alarm_logs; + int alarm_freq; + struct uwsgi_string_list *alarm_list; + struct uwsgi_string_list *alarm_logs_list; + struct uwsgi_alarm *alarms; + struct uwsgi_alarm_instance *alarm_instances; + struct uwsgi_alarm_log *alarm_logs; #endif - int threaded_logger; - pthread_mutex_t threaded_logger_lock; + int threaded_logger; + pthread_mutex_t threaded_logger_lock; - struct uwsgi_daemon *daemons; - int daemons_cnt; + struct uwsgi_daemon *daemons; + int daemons_cnt; #ifdef UWSGI_SSL - char *subscriptions_sign_check_dir; - int subscriptions_sign_check_tolerance; - const EVP_MD *subscriptions_sign_check_md; + char *subscriptions_sign_check_dir; + int subscriptions_sign_check_tolerance; + const EVP_MD *subscriptions_sign_check_md; #endif - struct uwsgi_dyn_dict *static_maps; - struct uwsgi_dyn_dict *static_maps2; - struct uwsgi_dyn_dict *check_static; - struct uwsgi_dyn_dict *mimetypes; - struct uwsgi_string_list *static_skip_ext; - struct uwsgi_string_list *static_index; - struct uwsgi_string_list *static_safe; + struct uwsgi_dyn_dict *static_maps; + struct uwsgi_dyn_dict *static_maps2; + struct uwsgi_dyn_dict *check_static; + struct uwsgi_dyn_dict *mimetypes; + struct uwsgi_string_list *static_skip_ext; + struct uwsgi_string_list *static_index; + struct uwsgi_string_list *static_safe; - struct uwsgi_hash_algo *hash_algos; - int use_static_cache_paths; - char *static_cache_paths_name; - struct uwsgi_cache *static_cache_paths; - int cache_expire_freq; - int cache_report_freed_items; - int cache_no_expire; - uint64_t cache_max_items; - uint64_t cache_blocksize; - char *cache_store; - int cache_store_sync; - struct uwsgi_string_list *cache2; - int cache_setup; - int locking_setup; + struct uwsgi_hash_algo *hash_algos; + int use_static_cache_paths; + char *static_cache_paths_name; + struct uwsgi_cache *static_cache_paths; + int cache_expire_freq; + int cache_report_freed_items; + int cache_no_expire; + uint64_t cache_max_items; + uint64_t cache_blocksize; + char *cache_store; + int cache_store_sync; + struct uwsgi_string_list *cache2; + int cache_setup; + int locking_setup; - struct uwsgi_dyn_dict *static_expires_type; - struct uwsgi_dyn_dict *static_expires_type_mtime; + struct uwsgi_dyn_dict *static_expires_type; + struct uwsgi_dyn_dict *static_expires_type_mtime; - struct uwsgi_dyn_dict *static_expires; - struct uwsgi_dyn_dict *static_expires_mtime; + struct uwsgi_dyn_dict *static_expires; + struct uwsgi_dyn_dict *static_expires_mtime; - struct uwsgi_dyn_dict *static_expires_uri; - struct uwsgi_dyn_dict *static_expires_uri_mtime; + struct uwsgi_dyn_dict *static_expires_uri; + struct uwsgi_dyn_dict *static_expires_uri_mtime; - struct uwsgi_dyn_dict *static_expires_path_info; - struct uwsgi_dyn_dict *static_expires_path_info_mtime; + struct uwsgi_dyn_dict *static_expires_path_info; + struct uwsgi_dyn_dict *static_expires_path_info_mtime; - int static_gzip_all; - struct uwsgi_string_list *static_gzip_dir; - struct uwsgi_string_list *static_gzip_ext; + int static_gzip_all; + struct uwsgi_string_list *static_gzip_dir; + struct uwsgi_string_list *static_gzip_ext; #ifdef UWSGI_PCRE - struct uwsgi_regexp_list *static_gzip; + struct uwsgi_regexp_list *static_gzip; #endif - int offload_threads; - int offload_threads_events; - struct uwsgi_thread **offload_thread; + int offload_threads; + int offload_threads_events; + struct uwsgi_thread **offload_thread; - int check_static_docroot; + int check_static_docroot; - char *daemonize; - char *daemonize2; - int do_not_change_umask; - char *logfile; - int logfile_chown; + char *daemonize; + char *daemonize2; + int do_not_change_umask; + char *logfile; + int logfile_chown; - // enable vhost mode - int vhost; - int vhost_host; + // enable vhost mode + int vhost; + int vhost_host; - // async commodity - struct wsgi_request **async_waiting_fd_table; - struct wsgi_request **async_proto_fd_table; - struct uwsgi_async_request *async_runqueue; - struct uwsgi_async_request *async_runqueue_last; - int async_runqueue_cnt; + // async commodity + struct wsgi_request **async_waiting_fd_table; + struct wsgi_request **async_proto_fd_table; + struct uwsgi_async_request *async_runqueue; + struct uwsgi_async_request *async_runqueue_last; + int async_runqueue_cnt; - struct uwsgi_rbtree *rb_async_timeouts; + struct uwsgi_rbtree *rb_async_timeouts; - int async_queue_unused_ptr; - struct wsgi_request **async_queue_unused; + int async_queue_unused_ptr; + struct wsgi_request **async_queue_unused; - // store rlimit - struct rlimit rl; - struct rlimit rl_nproc; - size_t limit_post; + // store rlimit + struct rlimit rl; + struct rlimit rl_nproc; + size_t limit_post; - // set process priority - int prio; + // set process priority + int prio; - // funny reload systems - int force_get_memusage; - rlim_t reload_on_as; - rlim_t reload_on_rss; - rlim_t evil_reload_on_as; - rlim_t evil_reload_on_rss; + // funny reload systems + int force_get_memusage; + rlim_t reload_on_as; + rlim_t reload_on_rss; + rlim_t evil_reload_on_as; + rlim_t evil_reload_on_rss; - struct uwsgi_string_list *touch_reload; - struct uwsgi_string_list *touch_logrotate; - struct uwsgi_string_list *touch_logreopen; + struct uwsgi_string_list *touch_reload; + struct uwsgi_string_list *touch_logrotate; + struct uwsgi_string_list *touch_logreopen; - int propagate_touch; + int propagate_touch; - // enable grunt mode - int grunt; + // enable grunt mode + int grunt; - // store the binary path - char *binary_path; + // store the binary path + char *binary_path; - int is_a_reload; + int is_a_reload; -#ifdef UWSGI_UDP - char *udp_socket; -#endif + char *udp_socket; -#ifdef UWSGI_MULTICAST - int multicast_ttl; - int multicast_loop; - char *multicast_group; -#endif + int multicast_ttl; + int multicast_loop; + char *multicast_group; -#ifdef UWSGI_SPOOLER - struct uwsgi_spooler *spoolers; - int spooler_numproc; - struct uwsgi_spooler *i_am_a_spooler; - char *spooler_chdir; - int spooler_max_tasks; - int spooler_ordered; - int spooler_quiet; -#endif + struct uwsgi_spooler *spoolers; + int spooler_numproc; + struct uwsgi_spooler *i_am_a_spooler; + char *spooler_chdir; + int spooler_max_tasks; + int spooler_ordered; + int spooler_quiet; -#ifdef UWSGI_SNMP - int snmp; - char *snmp_addr; - char *snmp_community; - struct uwsgi_lock_item *snmp_lock; -#endif + int snmp; + char *snmp_addr; + char *snmp_community; + struct uwsgi_lock_item *snmp_lock; + int to_heaven; + int to_hell; + int to_outworld; - int to_heaven; - int to_hell; - int to_outworld; + int cleaning; - int cleaning; + int marked_workers; + int ready_to_die; + int ready_to_reload; - int marked_workers; - int ready_to_die; - int ready_to_reload; + int lazy_respawned; - int lazy_respawned; + uint16_t buffer_size; + int signal_bufsize; - int buffer_size; - int signal_bufsize; + // post buffering + size_t post_buffering; + int post_buffering_harakiri; + size_t post_buffering_bufsize; + size_t body_read_warning; - // post buffering - size_t post_buffering; - int post_buffering_harakiri; - size_t post_buffering_bufsize; + int master_process; + int master_queue; - int master_process; - int master_queue; + // mainly iseful for broodlord mode + int vassal_sos_backlog; - // mainly iseful for broodlord mode - int vassal_sos_backlog; + int no_defer_accept; + int so_keepalive; + int so_send_timeout; - int no_defer_accept; - int so_keepalive; - int so_send_timeout; + int page_size; + int cpus; - int page_size; - int cpus; + char *pidfile; + char *pidfile2; - char *pidfile; - char *pidfile2; + char *flock2; + char *flock_wait2; - char *flock2; - char *flock_wait2; + int backtrace_depth; - int backtrace_depth; + int harakiri_verbose; + int harakiri_no_arh; - int harakiri_verbose; - int harakiri_no_arh; + char *magic_table[256]; - char *magic_table[256]; + int numproc; + int async; + int async_running; + int async_queue; + int async_nevents; - int numproc; - int async; - int async_running; - int async_queue; - int async_nevents; + int max_vars; + int vec_size; - int max_vars; - int vec_size; + // shared area + char *sharedarea; + uint64_t sharedareasize; - // shared area - char *sharedarea; - uint64_t sharedareasize; + // avoid thundering herd in threaded modes + pthread_mutex_t thunder_mutex; + pthread_mutex_t six_feet_under_lock; + pthread_mutex_t lock_static; -#ifdef UWSGI_THREADING - // avoid thundering herd in threaded modes - pthread_mutex_t thunder_mutex; - pthread_mutex_t six_feet_under_lock; - pthread_mutex_t lock_static; -#endif - int use_thunder_lock; - struct uwsgi_lock_item *the_thunder_lock; + int use_thunder_lock; + struct uwsgi_lock_item *the_thunder_lock; - /* the list of workers */ - struct uwsgi_worker *workers; - int max_apps; + /* the list of workers */ + struct uwsgi_worker *workers; + int max_apps; - /* the list of mules */ - struct uwsgi_string_list *mules_patches; - struct uwsgi_mule *mules; - struct uwsgi_string_list *farms_list; - struct uwsgi_farm *farms; + /* the list of mules */ + struct uwsgi_string_list *mules_patches; + struct uwsgi_mule *mules; + struct uwsgi_string_list *farms_list; + struct uwsgi_farm *farms; - pid_t mypid; - int mywid; + pid_t mypid; + int mywid; - int muleid; - int mules_cnt; - int farms_cnt; + int muleid; + int mules_cnt; + int farms_cnt; - rlim_t requested_max_fd; - rlim_t max_fd; + rlim_t requested_max_fd; + rlim_t max_fd; - struct timeval start_tv; + struct timeval start_tv; - int abstract_socket; + int abstract_socket; #ifdef __linux__ - int freebind; + int freebind; #endif - int chmod_socket; - char *chown_socket; - mode_t chmod_socket_value; - mode_t chmod_logfile_value; - int listen_queue; + int chmod_socket; + char *chown_socket; + mode_t chmod_socket_value; + mode_t chmod_logfile_value; + int listen_queue; - char *file_config; + char *file_config; #ifdef UWSGI_ROUTING - struct uwsgi_router *routers; - struct uwsgi_route *routes; + struct uwsgi_router *routers; + struct uwsgi_route *routes; #endif - int single_interpreter; + int single_interpreter; - struct uwsgi_shared *shared; + struct uwsgi_shared *shared; - int no_orphans; - int skip_zero; + int no_orphans; + int skip_zero; - char *chdir; - char *chdir2; + char *chdir; + char *chdir2; - int vacuum; - int no_server; - int command_mode; + int vacuum; + int no_server; + int command_mode; - int xml_round2; + int xml_round2; - char *cwd; + char *cwd; - // conditional logging - int log_slow_requests; - int log_zero_headers; - int log_empty_body; - int log_high_memory; + // conditional logging + int log_slow_requests; + int log_zero_headers; + int log_empty_body; + int log_high_memory; #ifdef __linux__ - struct uwsgi_string_list *cgroup; - struct uwsgi_string_list *cgroup_opt; - char *ns; - char *ns_net; - struct uwsgi_string_list *ns_keep_mount; + struct uwsgi_string_list *cgroup; + struct uwsgi_string_list *cgroup_opt; + char *ns; + char *ns_net; + struct uwsgi_string_list *ns_keep_mount; #endif - char *protocol; + char *protocol; - int signal_socket; - int my_signal_socket; + int signal_socket; + int my_signal_socket; #ifdef UWSGI_ZEROMQ - int zeromq; - void *zmq_context; + int zeromq; + void *zmq_context; #endif - struct uwsgi_socket *sockets; - struct uwsgi_socket *shared_sockets; - int is_et; + struct uwsgi_socket *sockets; + struct uwsgi_socket *shared_sockets; + int is_et; - struct uwsgi_string_list *map_socket; + struct uwsgi_string_list *map_socket; - struct uwsgi_cron *crons; + struct uwsgi_cron *crons; - time_t respawn_delta; + time_t respawn_delta; - struct uwsgi_string_list *mounts; + struct uwsgi_string_list *mounts; - int cores; + int cores; - int threads; - pthread_attr_t threads_attr; - size_t threads_stacksize; + int threads; + pthread_attr_t threads_attr; + size_t threads_stacksize; - //this key old the u_request structure per core / thread - pthread_key_t tur_key; + //this key old the u_request structure per core / thread + pthread_key_t tur_key; - struct wsgi_request *(*current_wsgi_req) (void); + struct wsgi_request *(*current_wsgi_req) (void); - void (*notify) (char *); - void (*notify_ready) (void); - int notification_fd; - void *notification_object; + void (*notify) (char *); + void (*notify_ready) (void); + int notification_fd; + void *notification_object; - // usedby suspend/resume loops - void (*schedule_to_main) (struct wsgi_request *); - void (*schedule_to_req) (void); + // usedby suspend/resume loops + void (*schedule_to_main) (struct wsgi_request *); + void (*schedule_to_req) (void); - void (*gbcw_hook)(void); + void (*gbcw_hook) (void); - int close_on_exec; + int close_on_exec; - char *loop; - struct uwsgi_loop *loops; + char *loop; + struct uwsgi_loop *loops; - struct uwsgi_plugin *p[256]; - struct uwsgi_plugin *gp[MAX_GENERIC_PLUGINS]; - int gp_cnt; + struct uwsgi_plugin *p[256]; + struct uwsgi_plugin *gp[MAX_GENERIC_PLUGINS]; + int gp_cnt; - char *allowed_modifiers; + char *allowed_modifiers; - char *upload_progress; + char *upload_progress; - char *cluster; - int cluster_nodes; - int cluster_fd; - struct sockaddr_in mc_cluster_addr; + struct uwsgi_lock_item *registered_locks; + struct uwsgi_lock_ops lock_ops; + char *lock_engine; + char *ftok; + char *lock_id; + size_t lock_size; + size_t rwlock_size; - struct uwsgi_lock_item *registered_locks; - struct uwsgi_lock_ops lock_ops; - char *lock_engine; - char *ftok; - char *lock_id; - size_t lock_size; - size_t rwlock_size; + struct uwsgi_string_list *load_file_in_cache; + char *use_check_cache; + struct uwsgi_cache *check_cache; + struct uwsgi_cache *caches; - struct uwsgi_string_list *load_file_in_cache; - char *use_check_cache; - struct uwsgi_cache *check_cache; - struct uwsgi_cache *caches; + struct uwsgi_string_list *cache_udp_server; + struct uwsgi_string_list *cache_udp_node; + int cache_udp_node_socket; - struct uwsgi_string_list *cache_udp_server; - struct uwsgi_string_list *cache_udp_node; - int cache_udp_node_socket; + char *cache_server; + int cache_server_threads; + int cache_server_fd; + pthread_mutex_t cache_server_lock; + char *cache_sync; - char *cache_server; - int cache_server_threads; - int cache_server_fd; - pthread_mutex_t cache_server_lock; - char *cache_sync; + // the stats server + char *stats; + int stats_fd; + int stats_http; + int stats_minified; + struct uwsgi_string_list *requested_stats_pushers; + struct uwsgi_stats_pusher *stats_pushers; + struct uwsgi_stats_pusher_instance *stats_pusher_instances; + int stats_pusher_default_freq; - // the stats server - char *stats; - int stats_fd; - int stats_http; - int stats_minified; - struct uwsgi_string_list *requested_stats_pushers; - struct uwsgi_stats_pusher *stats_pushers; - struct uwsgi_stats_pusher_instance *stats_pusher_instances; - int stats_pusher_default_freq; - - uint64_t queue_size; - uint64_t queue_blocksize; - void *queue; - struct uwsgi_queue_header *queue_header; - char *queue_store; - size_t queue_filesize; - int queue_store_sync; + uint64_t queue_size; + uint64_t queue_blocksize; + void *queue; + struct uwsgi_queue_header *queue_header; + char *queue_store; + size_t queue_filesize; + int queue_store_sync; - int locks; + int locks; - struct uwsgi_lock_item *queue_lock; - struct uwsgi_lock_item **user_lock; - struct uwsgi_lock_item *signal_table_lock; - struct uwsgi_lock_item *fmon_table_lock; - struct uwsgi_lock_item *timer_table_lock; - struct uwsgi_lock_item *probe_table_lock; - struct uwsgi_lock_item *rb_timer_table_lock; - struct uwsgi_lock_item *cron_table_lock; - struct uwsgi_lock_item *rpc_table_lock; - struct uwsgi_lock_item *sa_lock; + struct uwsgi_lock_item *queue_lock; + struct uwsgi_lock_item **user_lock; + struct uwsgi_lock_item *signal_table_lock; + struct uwsgi_lock_item *fmon_table_lock; + struct uwsgi_lock_item *timer_table_lock; + struct uwsgi_lock_item *probe_table_lock; + struct uwsgi_lock_item *rb_timer_table_lock; + struct uwsgi_lock_item *cron_table_lock; + struct uwsgi_lock_item *rpc_table_lock; + struct uwsgi_lock_item *sa_lock; - // subscription client - int subscribe_freq; - int subscription_tolerance; - int unsubscribe_on_graceful_reload; - struct uwsgi_string_list *subscriptions; - struct uwsgi_string_list *subscriptions2; + // subscription client + int subscribe_freq; + int subscription_tolerance; + int unsubscribe_on_graceful_reload; + struct uwsgi_string_list *subscriptions; + struct uwsgi_string_list *subscriptions2; - struct uwsgi_subscribe_node * (*subscription_algo)(struct uwsgi_subscribe_slot *, struct uwsgi_subscribe_node *); - int subscription_dotsplit; + struct uwsgi_subscribe_node *(*subscription_algo) (struct uwsgi_subscribe_slot *, struct uwsgi_subscribe_node *); + int subscription_dotsplit; - int never_swap; + int never_swap; #ifdef UWSGI_SSL - int ssl_initialized; - int ssl_verbose; - char *ssl_sessions_use_cache; - int ssl_sessions_timeout; - struct uwsgi_cache *ssl_sessions_cache; + int ssl_initialized; + int ssl_verbose; + char *ssl_sessions_use_cache; + int ssl_sessions_timeout; + struct uwsgi_cache *ssl_sessions_cache; #ifdef UWSGI_PCRE - struct uwsgi_regexp_list *sni_regexp; + struct uwsgi_regexp_list *sni_regexp; #endif - struct uwsgi_string_list *sni; - char *sni_dir; - char *sni_dir_ciphers; + struct uwsgi_string_list *sni; + char *sni_dir; + char *sni_dir_ciphers; #endif #ifdef UWSGI_SSL - struct uwsgi_legion *legions; - struct uwsgi_legion_action *legion_actions; - int legion_queue; - int legion_freq; - int legion_tolerance; - int legion_skew_tolerance; + struct uwsgi_legion *legions; + struct uwsgi_legion_action *legion_actions; + int legion_queue; + int legion_freq; + int legion_tolerance; + int legion_skew_tolerance; #endif #ifdef __linux__ #ifdef MADV_MERGEABLE - int linux_ksm; - int ksm_buffer_size; - char *ksm_mappings_last; - char *ksm_mappings_current; - size_t ksm_mappings_last_size; - size_t ksm_mappings_current_size; + int linux_ksm; + int ksm_buffer_size; + char *ksm_mappings_last; + char *ksm_mappings_current; + size_t ksm_mappings_last_size; + size_t ksm_mappings_current_size; #endif #endif - ssize_t (*websockets_hook_send)(struct wsgi_request *, struct uwsgi_buffer *); - ssize_t (*websockets_hook_recv)(struct wsgi_request *); - struct uwsgi_buffer *websockets_ping; - struct uwsgi_buffer *websockets_pong; - int websockets_ping_freq; - int websockets_pong_freq; - uint64_t websockets_max_size; + struct uwsgi_buffer *websockets_ping; + struct uwsgi_buffer *websockets_pong; + int websockets_ping_freq; + int websockets_pong_freq; + uint64_t websockets_max_size; - struct uwsgi_string_list *channels_list; - struct uwsgi_channel *channels; - struct uwsgi_buffer *(*channel_recv_hook)(struct wsgi_request *, int, struct uwsgi_buffer *, int); + int (*wait_write_hook) (int, int); + int (*wait_read_hook) (int, int); - ssize_t (*buffer_write_hook)(struct wsgi_request *, struct uwsgi_buffer *); - int (*wait_write_hook)(struct wsgi_request *); + }; -}; + struct uwsgi_rpc { + char name[0xff]; + void *func; + uint8_t args; + uint8_t modifier1; + }; -struct uwsgi_rpc { - char name[0xff]; - void *func; - uint8_t args; - uint8_t modifier1; -}; + struct uwsgi_signal_entry { + int wid; + uint8_t modifier1; + char receiver[64]; + void *handler; + }; -struct uwsgi_lb_group { - char name[101]; - int kind; -}; + struct uwsgi_snmp_custom_value { + uint8_t type; + uint64_t val; + }; + int uwsgi_setup_snmp(void); -struct uwsgi_signal_entry { - int wid; - uint8_t modifier1; - char receiver[64]; - void *handler; -}; + struct uwsgi_snmp_server_value { + uint8_t type; + uint64_t *val; + }; -struct uwsgi_lb_node { + struct uwsgi_cron { - char name[101]; - int group; - uint64_t hits; - time_t last_choosen; + int minute; + int hour; + int day; + int month; + int week; -}; + time_t last_job; + uint8_t sig; -#define CLUSTER_NODE_STATIC 0 -#define CLUSTER_NODE_DYNAMIC 1 + char *command; -struct uwsgi_cluster_node { - char name[101]; + struct uwsgi_cron *next; + }; - char nodename[0xff]; + struct uwsgi_shared { - struct sockaddr_in ucn_addr; + //vga 80 x25 specific ! + char warning_message[81]; - int type; + uint32_t options[256]; - int workers; - int connections; - int status; + off_t logsize; - time_t last_seen; - int errors; - - time_t last_choosen; - - int requests; - -}; - -#ifdef UWSGI_SNMP -struct uwsgi_snmp_custom_value { - uint8_t type; - uint64_t val; -}; - -int uwsgi_setup_snmp(void); - -struct uwsgi_snmp_server_value { - uint8_t type; - uint64_t *val; -}; -#endif - -struct uwsgi_cron { - - int minute; - int hour; - int day; - int month; - int week; - - time_t last_job; - uint8_t sig; - - char *command; - - struct uwsgi_cron *next; -}; - -struct uwsgi_shared { - - //vga 80 x25 specific ! - char warning_message[81]; - - uint32_t options[256]; - - struct uwsgi_cluster_node nodes[MAX_CLUSTER_NODES]; - - off_t logsize; - -#ifdef UWSGI_SNMP - char snmp_community[72 + 1]; - struct uwsgi_snmp_server_value snmp_gvalue[100]; - struct uwsgi_snmp_custom_value snmp_value[100]; + char snmp_community[72 + 1]; + struct uwsgi_snmp_server_value snmp_gvalue[100]; + struct uwsgi_snmp_custom_value snmp_value[100]; #define SNMP_COUNTER32 0x41 #define SNMP_GAUGE 0x42 #define SNMP_COUNTER64 0x46 -#endif + int worker_signal_pipe[2]; + int spooler_frequency; + int spooler_signal_pipe[2]; + int mule_signal_pipe[2]; + int mule_queue_pipe[2]; - int worker_signal_pipe[2]; -#ifdef UWSGI_SPOOLER - int spooler_frequency; - int spooler_signal_pipe[2]; -#endif - int mule_signal_pipe[2]; - int mule_queue_pipe[2]; + struct uwsgi_signal_entry signal_table[256]; - struct uwsgi_signal_entry signal_table[256]; + struct uwsgi_fmon files_monitored[64]; + int files_monitored_cnt; - struct uwsgi_fmon files_monitored[64]; - int files_monitored_cnt; + struct uwsgi_signal_probe probes[MAX_PROBES]; + int probes_cnt; - struct uwsgi_signal_probe probes[MAX_PROBES]; - int probes_cnt; + struct uwsgi_timer timers[MAX_TIMERS]; + int timers_cnt; - struct uwsgi_timer timers[MAX_TIMERS]; - int timers_cnt; + struct uwsgi_signal_rb_timer rb_timers[MAX_TIMERS]; + int rb_timers_cnt; - struct uwsgi_signal_rb_timer rb_timers[MAX_TIMERS]; - int rb_timers_cnt; + struct uwsgi_rpc rpc_table[MAX_RPC]; + int rpc_count; - struct uwsgi_rpc rpc_table[MAX_RPC]; - int rpc_count; - - int worker_log_pipe[2]; - // used for request logging - int worker_req_log_pipe[2]; + int worker_log_pipe[2]; + // used for request logging + int worker_req_log_pipe[2]; #if defined(__linux__) || defined(__FreeBSD__) - struct tcp_info ti; + struct tcp_info ti; #endif - uint64_t load; - uint64_t max_load; - struct uwsgi_cron cron[MAX_CRONS]; - int cron_cnt; + uint64_t load; + uint64_t max_load; + struct uwsgi_cron cron[MAX_CRONS]; + int cron_cnt; - // gateways - struct uwsgi_gateway gateways[MAX_GATEWAYS]; - int gateways_cnt; - time_t gateways_harakiri[MAX_GATEWAYS]; + // gateways + struct uwsgi_gateway gateways[MAX_GATEWAYS]; + int gateways_cnt; + time_t gateways_harakiri[MAX_GATEWAYS]; - int ready; -}; + int ready; + }; -struct uwsgi_core { + struct uwsgi_core { - //time_t harakiri; + //time_t harakiri; - uint64_t requests; - uint64_t failed_requests; - uint64_t static_requests; - uint64_t routed_requests; - uint64_t offloaded_requests; + uint64_t requests; + uint64_t failed_requests; + uint64_t static_requests; + uint64_t routed_requests; + uint64_t offloaded_requests; -#ifdef UWSGI_THREADING - pthread_t thread_id; -#endif + pthread_t thread_id; - int offload_rr; + int offload_rr; - // one ts-perapp - void **ts; + // one ts-perapp + void **ts; - int in_request; + int in_request; - char *buffer; - struct iovec *hvec; - char *post_buf; + char *buffer; + struct iovec *hvec; + char *post_buf; - struct wsgi_request req; -}; + struct wsgi_request req; + }; -struct uwsgi_snapshot { - char *name; - pid_t pid; - time_t timestamp; -}; + struct uwsgi_snapshot { + char *name; + pid_t pid; + time_t timestamp; + }; -struct uwsgi_worker { - int id; - pid_t pid; + struct uwsgi_worker { + int id; + pid_t pid; - pid_t snapshot; - uint64_t status; + pid_t snapshot; + uint64_t status; - time_t last_spawn; - uint64_t respawn_count; + time_t last_spawn; + uint64_t respawn_count; - uint64_t requests; - uint64_t delta_requests; - uint64_t failed_requests; + uint64_t requests; + uint64_t delta_requests; + uint64_t failed_requests; - time_t harakiri; - time_t user_harakiri; - uint64_t harakiri_count; - int pending_harakiri; + time_t harakiri; + time_t user_harakiri; + uint64_t harakiri_count; + int pending_harakiri; - uint64_t vsz_size; - uint64_t rss_size; + uint64_t vsz_size; + uint64_t rss_size; - uint64_t running_time; + uint64_t running_time; - int manage_next_request; + int manage_next_request; - uint64_t exceptions; + uint64_t exceptions; - int destroy; - - int apps_cnt; - struct uwsgi_app *apps; + int destroy; - uint64_t tx; + int apps_cnt; + struct uwsgi_app *apps; - int hijacked; - uint64_t hijacked_count; - int busy; - int cheaped; - int suspended; - int sig; - uint8_t signum; + uint64_t tx; - time_t stopped_at; + int hijacked; + uint64_t hijacked_count; + int busy; + int cheaped; + int suspended; + int sig; + uint8_t signum; - // signals managed by this worker - uint64_t signals; + time_t stopped_at; - int signal_pipe[2]; + // signals managed by this worker + uint64_t signals; - uint64_t avg_response_time; + int signal_pipe[2]; - struct uwsgi_core *cores; + uint64_t avg_response_time; - char name[0xff]; - char snapshot_name[0xff]; -}; + struct uwsgi_core *cores; + + char name[0xff]; + char snapshot_name[0xff]; + }; -struct uwsgi_mule { - int id; - pid_t pid; + struct uwsgi_mule { + int id; + pid_t pid; - int signal_pipe[2]; - int queue_pipe[2]; + int signal_pipe[2]; + int queue_pipe[2]; - time_t last_spawn; - uint64_t respawn_count; + time_t last_spawn; + uint64_t respawn_count; - char *patch; + char *patch; - // signals managed by this mule - uint64_t signals; - int sig; - uint8_t signum; + // signals managed by this mule + uint64_t signals; + int sig; + uint8_t signum; - time_t harakiri; + time_t harakiri; - char name[0xff]; -}; + char name[0xff]; + }; -struct uwsgi_mule_farm { - struct uwsgi_mule *mule; - struct uwsgi_mule_farm *next; -}; + struct uwsgi_mule_farm { + struct uwsgi_mule *mule; + struct uwsgi_mule_farm *next; + }; -struct uwsgi_farm { - int id; - char name[0xff]; + struct uwsgi_farm { + int id; + char name[0xff]; - int signal_pipe[2]; - int queue_pipe[2]; + int signal_pipe[2]; + int queue_pipe[2]; - struct uwsgi_mule_farm *mules; + struct uwsgi_mule_farm *mules; -}; + }; -char *uwsgi_get_cwd(void); + char *uwsgi_get_cwd(void); void warn_pipe(void); void what_i_am_doing(void); @@ -2499,9 +2417,7 @@ void grace_them_all(int); void end_me(int); int bind_to_unix(char *, int, int, int); int bind_to_tcp(char *, int, char *); -#ifdef UWSGI_IPV6 int bind_to_tcp6(char *, int, char *); -#endif int bind_to_udp(char *, int, int); int bind_to_unix_dgram(char *); int timed_connect(struct pollfd *, const struct sockaddr *, int, int, int); @@ -2528,16 +2444,12 @@ void uwsgi_403(struct wsgi_request *); void uwsgi_404(struct wsgi_request *); void uwsgi_redirect_to_slash(struct wsgi_request *); -#ifdef UWSGI_SNMP void manage_snmp(int, uint8_t *, int, struct sockaddr_in *); void snmp_init(void); -#endif -#ifdef UWSGI_SPOOLER int spool_request(struct uwsgi_spooler *uspool, char *, int, int, char *, int, char *, time_t, char *, size_t); void spooler(struct uwsgi_spooler *); pid_t spooler_start(struct uwsgi_spooler *); -#endif void set_harakiri(int); void set_user_harakiri(int); @@ -2546,24 +2458,22 @@ void set_spooler_harakiri(int); void inc_harakiri(int); #ifdef __BIG_ENDIAN__ -uint16_t uwsgi_swap16(uint16_t); -uint32_t uwsgi_swap32(uint32_t); -uint64_t uwsgi_swap64(uint64_t); + uint16_t uwsgi_swap16(uint16_t); + uint32_t uwsgi_swap32(uint32_t); + uint64_t uwsgi_swap64(uint64_t); #endif ssize_t send_udp_message(uint8_t, uint8_t, char *, char *, uint16_t); -int uwsgi_parse_packet(struct wsgi_request *, int); +int uwsgi_parse_request(int, struct wsgi_request *, int); int uwsgi_parse_vars(struct wsgi_request *); int uwsgi_enqueue_message(char *, int, uint8_t, uint8_t, char *, int, int); void manage_opt(int, char *); -void uwsgi_cluster_add_node(struct uwsgi_cluster_node *, int); int uwsgi_ping_node(int, struct wsgi_request *); -#ifdef UWSGI_ASYNC void uwsgi_async_init(void); void async_loop(); struct wsgi_request *find_first_available_wsgi_req(void); @@ -2581,255 +2491,240 @@ void async_add_timeout(struct wsgi_request *, int); void async_expire_timeouts(void); -#endif + void uwsgi_as_root(void); -void uwsgi_as_root(void); + void uwsgi_close_request(struct wsgi_request *); -#ifdef UWSGI_NAGIOS -void nagios(void); -#endif - -void uwsgi_close_request(struct wsgi_request *); - -void wsgi_req_setup(struct wsgi_request *, int, struct uwsgi_socket *); -int wsgi_req_recv(struct wsgi_request *); -int wsgi_req_async_recv(struct wsgi_request *); -int wsgi_req_accept(int, struct wsgi_request *); -int wsgi_req_simple_accept(struct wsgi_request *, int); + void wsgi_req_setup(struct wsgi_request *, int, struct uwsgi_socket *); + int wsgi_req_recv(int, struct wsgi_request *); + int wsgi_req_async_recv(struct wsgi_request *); + int wsgi_req_accept(int, struct wsgi_request *); + int wsgi_req_simple_accept(struct wsgi_request *, int); #define current_wsgi_req() (*uwsgi.current_wsgi_req)() -void sanitize_args(void); + void sanitize_args(void); -void env_to_arg(char *, char *); -void parse_sys_envs(char **); + void env_to_arg(char *, char *); + void parse_sys_envs(char **); -void uwsgi_log(const char *, ...); -void uwsgi_log_verbose(const char *, ...); + void uwsgi_log(const char *, ...); + void uwsgi_log_verbose(const char *, ...); -void *uwsgi_load_plugin(int, char *, char *); + void *uwsgi_load_plugin(int, char *, char *); -int unconfigured_hook(struct wsgi_request *); + int unconfigured_hook(struct wsgi_request *); #ifdef UWSGI_INI -void uwsgi_ini_config(char *, char *[]); + void uwsgi_ini_config(char *, char *[]); #endif #ifdef UWSGI_YAML -void uwsgi_yaml_config(char *, char *[]); + void uwsgi_yaml_config(char *, char *[]); #endif #ifdef UWSGI_JSON -void uwsgi_json_config(char *, char *[]); + void uwsgi_json_config(char *, char *[]); #endif #ifdef UWSGI_SQLITE3 -void uwsgi_sqlite3_config(char *, char *[]); + void uwsgi_sqlite3_config(char *, char *[]); #endif #ifdef UWSGI_LDAP -void uwsgi_opt_ldap_dump(char *, char *, void *); -void uwsgi_opt_ldap_dump_ldif(char *, char *, void *); -void uwsgi_ldap_config(char *); + void uwsgi_opt_ldap_dump(char *, char *, void *); + void uwsgi_opt_ldap_dump_ldif(char *, char *, void *); + void uwsgi_ldap_config(char *); #endif -int uwsgi_strncmp(char *, int, char *, int); -int uwsgi_strnicmp(char *, int, char *, int); -int uwsgi_startswith(char *, char *, int); + int uwsgi_strncmp(char *, int, char *, int); + int uwsgi_strnicmp(char *, int, char *, int); + int uwsgi_startswith(char *, char *, int); -char *uwsgi_concat(int, ...); -char *uwsgi_concatn(int, ...); -char *uwsgi_concat2(char *, char *); -char *uwsgi_concat2n(char *, int, char *, int); -char *uwsgi_concat2nn(char *, int, char *, int, int *); -char *uwsgi_concat3(char *, char *, char *); -char *uwsgi_concat3n(char *, int, char *, int, char *, int); -char *uwsgi_concat4(char *, char *, char *, char *); -char *uwsgi_concat4n(char *, int, char *, int, char *, int, char *, int); + char *uwsgi_concat(int, ...); + char *uwsgi_concatn(int, ...); + char *uwsgi_concat2(char *, char *); + char *uwsgi_concat2n(char *, int, char *, int); + char *uwsgi_concat2nn(char *, int, char *, int, int *); + char *uwsgi_concat3(char *, char *, char *); + char *uwsgi_concat3n(char *, int, char *, int, char *, int); + char *uwsgi_concat4(char *, char *, char *, char *); + char *uwsgi_concat4n(char *, int, char *, int, char *, int, char *, int); -int uwsgi_get_app_id(char *, int, int); -char *uwsgi_strncopy(char *, int); + int uwsgi_get_app_id(char *, int, int); + char *uwsgi_strncopy(char *, int); -int master_loop(char **, char **); + int master_loop(char **, char **); -int find_worker_id(pid_t); + int find_worker_id(pid_t); -void simple_loop(); -void *simple_loop_run(void *); + void simple_loop(); + void *simple_loop_run(void *); -int uwsgi_count_options(struct uwsgi_option *); + int uwsgi_count_options(struct uwsgi_option *); -struct wsgi_request *simple_current_wsgi_req(void); -struct wsgi_request *threaded_current_wsgi_req(void); + struct wsgi_request *simple_current_wsgi_req(void); + struct wsgi_request *threaded_current_wsgi_req(void); -void build_options(void); + void build_options(void); -int uwsgi_read_whole_body(struct wsgi_request *, char *, size_t); -int uwsgi_read_whole_body_in_mem(struct wsgi_request *, char *); + int uwsgi_postbuffer_do_in_disk(struct wsgi_request *); + int uwsgi_postbuffer_do_in_mem(struct wsgi_request *); -void uwsgi_register_loop(char *, void (*)(void)); -void *uwsgi_get_loop(char *); + void uwsgi_register_loop(char *, void (*)(void)); + void *uwsgi_get_loop(char *); -void add_exported_option(char *, char *, int); + void add_exported_option(char *, char *, int); -ssize_t uwsgi_send_empty_pkt(int, char *, uint8_t, uint8_t); + ssize_t uwsgi_send_empty_pkt(int, char *, uint8_t, uint8_t); -int uwsgi_waitfd_event(int, int, int); + int uwsgi_waitfd_event(int, int, int); #define uwsgi_waitfd(a, b) uwsgi_waitfd_event(a, b, POLLIN) #define uwsgi_waitfd_write(a, b) uwsgi_waitfd_event(a, b, POLLOUT) -int uwsgi_hooked_parse_dict_dgram(int, char *, size_t, uint8_t, uint8_t, void (*)(char *, uint16_t, char *, uint16_t, void *), void *); -int uwsgi_hooked_parse(char *, size_t, void (*)(char *, uint16_t, char *, uint16_t, void *), void *); + int uwsgi_hooked_parse_dict_dgram(int, char *, size_t, uint8_t, uint8_t, void (*)(char *, uint16_t, char *, uint16_t, void *), void *); + int uwsgi_hooked_parse(char *, size_t, void (*)(char *, uint16_t, char *, uint16_t, void *), void *); -int uwsgi_get_dgram(int, struct wsgi_request *); + int uwsgi_get_dgram(int, struct wsgi_request *); -int uwsgi_cluster_join(char *); + int uwsgi_string_sendto(int, uint8_t, uint8_t, struct sockaddr *, socklen_t, char *, size_t); -int uwsgi_string_sendto(int, uint8_t, uint8_t, struct sockaddr *, socklen_t, char *, size_t); + void uwsgi_stdin_sendto(char *, uint8_t, uint8_t); -void uwsgi_stdin_sendto(char *, uint8_t, uint8_t); - -int uwsgi_cluster_add_me(void); - -char *generate_socket_name(char *); + char *generate_socket_name(char *); #define UMIN(a,b) ((a)>(b)?(b):(a)) #define UMAX(a,b) ((a)<(b)?(b):(a)) -ssize_t uwsgi_send_message(int, uint8_t, uint8_t, char *, uint16_t, int, ssize_t, int); + ssize_t uwsgi_send_message(int, uint8_t, uint8_t, char *, uint16_t, int, ssize_t, int); -char *uwsgi_cluster_best_node(void); - -int uwsgi_cache_set2(struct uwsgi_cache *, char *, uint16_t, char *, uint64_t, uint64_t, uint64_t); -int uwsgi_cache_del2(struct uwsgi_cache *, char *, uint16_t, uint64_t, uint16_t); -char *uwsgi_cache_get2(struct uwsgi_cache *, char *, uint16_t, uint64_t *); -uint32_t uwsgi_cache_exists2(struct uwsgi_cache *, char *, uint16_t); -struct uwsgi_cache *uwsgi_cache_create(char *); -struct uwsgi_cache *uwsgi_cache_by_name(char *); -void uwsgi_cache_create_all(void); -char *uwsgi_cache_safe_get2(struct uwsgi_cache *, char *, uint16_t, uint64_t *); + int uwsgi_cache_set2(struct uwsgi_cache *, char *, uint16_t, char *, uint64_t, uint64_t, uint64_t); + int uwsgi_cache_del2(struct uwsgi_cache *, char *, uint16_t, uint64_t, uint16_t); + char *uwsgi_cache_get2(struct uwsgi_cache *, char *, uint16_t, uint64_t *); + uint32_t uwsgi_cache_exists2(struct uwsgi_cache *, char *, uint16_t); + struct uwsgi_cache *uwsgi_cache_create(char *); + struct uwsgi_cache *uwsgi_cache_by_name(char *); + void uwsgi_cache_create_all(void); + char *uwsgi_cache_safe_get2(struct uwsgi_cache *, char *, uint16_t, uint64_t *); #define uwsgi_cache_set(x1, x2, x3, x4, x5, x6) uwsgi_cache_set2(uwsgi.caches, x1, x2, x3, x4, x5, x6) #define uwsgi_cache_del(x1, x2, x3, x4) uwsgi_cache_del2(uwsgi.caches, x1, x2, x3, x4) #define uwsgi_cache_get(x1, x2, x3) uwsgi_cache_get2(uwsgi.caches, x1, x2, x3) #define uwsgi_cache_exists(x1, x2) uwsgi_cache_exists2(uwsgi.caches, x1, x2) -void uwsgi_cache_sync_all(void); -void uwsgi_cache_start_sweepers(void); -void uwsgi_cache_start_sync_servers(void); + void uwsgi_cache_sync_all(void); + void uwsgi_cache_start_sweepers(void); + void uwsgi_cache_start_sync_servers(void); -void *uwsgi_malloc(size_t); -void *uwsgi_calloc(size_t); + void *uwsgi_malloc(size_t); + void *uwsgi_calloc(size_t); -int event_queue_init(void); -void *event_queue_alloc(int); -int event_queue_add_fd_read(int, int); -int event_queue_add_fd_write(int, int); -int event_queue_del_fd(int, int, int); -int event_queue_wait(int, int, int *); -int event_queue_wait_multi(int, int, void *, int); -int event_queue_interesting_fd(void *, int); -int event_queue_interesting_fd_has_error(void *, int); -int event_queue_fd_write_to_read(int, int); -int event_queue_fd_read_to_write(int, int); -int event_queue_fd_readwrite_to_read(int, int); -int event_queue_fd_readwrite_to_write(int, int); -int event_queue_fd_read_to_readwrite(int, int); -int event_queue_fd_write_to_readwrite(int, int); -int event_queue_interesting_fd_is_read(void *, int); -int event_queue_interesting_fd_is_write(void *, int); + int event_queue_init(void); + void *event_queue_alloc(int); + int event_queue_add_fd_read(int, int); + int event_queue_add_fd_write(int, int); + int event_queue_del_fd(int, int, int); + int event_queue_wait(int, int, int *); + int event_queue_wait_multi(int, int, void *, int); + int event_queue_interesting_fd(void *, int); + int event_queue_interesting_fd_has_error(void *, int); + int event_queue_fd_write_to_read(int, int); + int event_queue_fd_read_to_write(int, int); + int event_queue_fd_readwrite_to_read(int, int); + int event_queue_fd_readwrite_to_write(int, int); + int event_queue_fd_read_to_readwrite(int, int); + int event_queue_fd_write_to_readwrite(int, int); + int event_queue_interesting_fd_is_read(void *, int); + int event_queue_interesting_fd_is_write(void *, int); -int event_queue_add_timer(int, int *, int); -struct uwsgi_timer *event_queue_ack_timer(int); + int event_queue_add_timer(int, int *, int); + struct uwsgi_timer *event_queue_ack_timer(int); -int event_queue_add_file_monitor(int, char *, int *); -struct uwsgi_fmon *event_queue_ack_file_monitor(int, int); + int event_queue_add_file_monitor(int, char *, int *); + struct uwsgi_fmon *event_queue_ack_file_monitor(int, int); -int uwsgi_register_signal(uint8_t, char *, void *, uint8_t); -int uwsgi_add_file_monitor(uint8_t, char *); -int uwsgi_add_timer(uint8_t, int); -int uwsgi_signal_add_rb_timer(uint8_t, int, int); -int uwsgi_signal_handler(uint8_t); + int uwsgi_register_signal(uint8_t, char *, void *, uint8_t); + int uwsgi_add_file_monitor(uint8_t, char *); + int uwsgi_add_timer(uint8_t, int); + int uwsgi_signal_add_rb_timer(uint8_t, int, int); + int uwsgi_signal_handler(uint8_t); -void uwsgi_route_signal(uint8_t); + void uwsgi_route_signal(uint8_t); -int uwsgi_start(void *); + int uwsgi_start(void *); -int uwsgi_register_rpc(char *, uint8_t, uint8_t, void *); -uint16_t uwsgi_rpc(char *, uint8_t, char **, uint16_t *, char *); -char *uwsgi_do_rpc(char *, char *, uint8_t, char **, uint16_t *, uint16_t *); + int uwsgi_register_rpc(char *, uint8_t, uint8_t, void *); + uint16_t uwsgi_rpc(char *, uint8_t, char **, uint16_t *, char *); + char *uwsgi_do_rpc(char *, char *, uint8_t, char **, uint16_t *, uint16_t *); -char *uwsgi_cheap_string(char *, int); + char *uwsgi_cheap_string(char *, int); -int uwsgi_parse_array(char *, uint16_t, char **, uint16_t *, uint8_t *); + int uwsgi_parse_array(char *, uint16_t, char **, uint16_t *, uint8_t *); -struct uwsgi_gateway *register_gateway(char *, void (*)(int, void *), void *); -void gateway_respawn(int); + struct uwsgi_gateway *register_gateway(char *, void (*)(int, void *), void *); + void gateway_respawn(int); -void uwsgi_gateway_go_cheap(char *, int, int *); + void uwsgi_gateway_go_cheap(char *, int, int *); -char *uwsgi_open_and_read(char *, size_t *, int, char *[]); -char *uwsgi_get_last_char(char *, char); + char *uwsgi_open_and_read(char *, size_t *, int, char *[]); + char *uwsgi_get_last_char(char *, char); -struct uwsgi_twobytes { - uint8_t cl1; - uint8_t cl0; -} __attribute__ ((__packed__)); + struct uwsgi_twobytes { + uint8_t cl1; + uint8_t cl0; + } __attribute__ ((__packed__)); -struct fcgi_record { - uint8_t version; - uint8_t type; - uint8_t req1; - uint8_t req0; - union { - uint16_t cl; - struct uwsgi_twobytes cl8; - }; - uint8_t pad; - uint8_t reserved; -} __attribute__ ((__packed__)); + struct fcgi_record { + uint8_t version; + uint8_t type; + uint8_t req1; + uint8_t req0; + union { + uint16_t cl; + struct uwsgi_twobytes cl8; + }; + uint8_t pad; + uint8_t reserved; + } __attribute__ ((__packed__)); #define FCGI_BEGIN_REQUEST "\0\1\0\0\0\0\0\0" #define FCGI_END_REQUEST "\1\x06\0\1\0\0\0\0\1\3\0\1\0\x08\0\0\0\0\0\0\0\0\0\0" -ssize_t fcgi_send_record(int, uint8_t, uint16_t, char *); -ssize_t fcgi_send_param(int, char *, uint16_t, char *, uint16_t); -uint16_t fcgi_get_record(int, char *); + ssize_t fcgi_send_record(int, uint8_t, uint16_t, char *); + ssize_t fcgi_send_param(int, char *, uint16_t, char *, uint16_t); + uint16_t fcgi_get_record(int, char *); -void uwsgi_spawn_daemon(struct uwsgi_daemon *); -void uwsgi_detach_daemons(); + void uwsgi_spawn_daemon(struct uwsgi_daemon *); + void uwsgi_detach_daemons(); -void emperor_loop(void); -char *uwsgi_num2str(int); + void emperor_loop(void); + char *uwsgi_num2str(int); -char *magic_sub(char *, size_t, size_t *, char *[]); -void init_magic_table(char *[]); + char *magic_sub(char *, size_t, size_t *, char *[]); + void init_magic_table(char *[]); -char *uwsgi_simple_message_string(char *, uint8_t, uint8_t, char *, uint16_t, char *, uint16_t *, int); -int uwsgi_simple_send_string2(char *, uint8_t, uint8_t, char *, uint16_t, char *, uint16_t, int); -int uwsgi_simple_send_string(char *, uint8_t, uint8_t, char *, uint16_t, int); -char *uwsgi_req_append(struct wsgi_request *, char *, uint16_t, char *, uint16_t); + char *uwsgi_req_append(struct wsgi_request *, char *, uint16_t, char *, uint16_t); -int is_unix(char *, int); -int is_a_number(char *); + int is_unix(char *, int); + int is_a_number(char *); -char *uwsgi_resolve_ip(char *); + char *uwsgi_resolve_ip(char *); -void uwsgi_init_queue(void); -char *uwsgi_queue_get(uint64_t, uint64_t *); -char *uwsgi_queue_pull(uint64_t *); -int uwsgi_queue_push(char *, uint64_t); -char *uwsgi_queue_pop(uint64_t *); -int uwsgi_queue_set(uint64_t, char *, uint64_t); + void uwsgi_init_queue(void); + char *uwsgi_queue_get(uint64_t, uint64_t *); + char *uwsgi_queue_pull(uint64_t *); + int uwsgi_queue_push(char *, uint64_t); + char *uwsgi_queue_pop(uint64_t *); + int uwsgi_queue_set(uint64_t, char *, uint64_t); /* // maintain alignment here !!! @@ -2871,783 +2766,775 @@ struct uwsgi_dict { */ -struct uwsgi_subscribe_req { - char *key; - uint16_t keylen; + struct uwsgi_subscribe_req { + char *key; + uint16_t keylen; - char *address; - uint16_t address_len; + char *address; + uint16_t address_len; - char *auth; - uint16_t auth_len; + char *auth; + uint16_t auth_len; - uint8_t modifier1; - uint8_t modifier2; + uint8_t modifier1; + uint8_t modifier2; - uint64_t cores; - uint64_t load; - uint64_t weight; - char *sign; - uint16_t sign_len; + uint64_t cores; + uint64_t load; + uint64_t weight; + char *sign; + uint16_t sign_len; - time_t unix_check; + time_t unix_check; - char *base; - uint16_t base_len; -}; + char *base; + uint16_t base_len; + }; -void uwsgi_nuclear_blast(); + void uwsgi_nuclear_blast(); -void uwsgi_unix_signal(int, void (*)(int)); + void uwsgi_unix_signal(int, void (*)(int)); -char *uwsgi_get_exported_opt(char *); + char *uwsgi_get_exported_opt(char *); -int uwsgi_signal_add_cron(uint8_t, int, int, int, int, int); + int uwsgi_signal_add_cron(uint8_t, int, int, int, int, int); -char *uwsgi_get_optname_by_index(int); + char *uwsgi_get_optname_by_index(int); -int uwsgi_list_has_num(char *, int); + int uwsgi_list_has_num(char *, int); -int uwsgi_list_has_str(char *, char *); + int uwsgi_list_has_str(char *, char *); -void uwsgi_cache_fix(struct uwsgi_cache *); + void uwsgi_cache_fix(struct uwsgi_cache *); -struct uwsgi_async_request { + struct uwsgi_async_request { - struct wsgi_request *wsgi_req; - struct uwsgi_async_request *prev; - struct uwsgi_async_request *next; -}; + struct wsgi_request *wsgi_req; + struct uwsgi_async_request *prev; + struct uwsgi_async_request *next; + }; -int event_queue_read(void); -int event_queue_write(void); + int event_queue_read(void); + int event_queue_write(void); -void uwsgi_help(char *opt, char *val, void *); + void uwsgi_help(char *opt, char *val, void *); -int uwsgi_str2_num(char *); -int uwsgi_str3_num(char *); -int uwsgi_str4_num(char *); + int uwsgi_str2_num(char *); + int uwsgi_str3_num(char *); + int uwsgi_str4_num(char *); #ifdef __linux__ -void linux_namespace_start(void *); -void linux_namespace_jail(void); -int uwsgi_netlink_veth(char *, char *); -int uwsgi_netlink_veth_attach(char *, pid_t); -int uwsgi_netlink_ifup(char *); -int uwsgi_netlink_ip(char *, char *, int); -int uwsgi_netlink_gw(char *, char *); -int uwsgi_netlink_rt(char *, char *, int, char *); -int uwsgi_netlink_del(char *); + void linux_namespace_start(void *); + void linux_namespace_jail(void); + int uwsgi_netlink_veth(char *, char *); + int uwsgi_netlink_veth_attach(char *, pid_t); + int uwsgi_netlink_ifup(char *); + int uwsgi_netlink_ip(char *, char *, int); + int uwsgi_netlink_gw(char *, char *); + int uwsgi_netlink_rt(char *, char *, int, char *); + int uwsgi_netlink_del(char *); #endif -int uwsgi_amqp_consume_queue(int, char *, char *, char *, char *, char *, char *); -char *uwsgi_amqp_consume(int, uint64_t *, char **); + int uwsgi_amqp_consume_queue(int, char *, char *, char *, char *, char *, char *); + char *uwsgi_amqp_consume(int, uint64_t *, char **); -int uwsgi_file_serve(struct wsgi_request *, char *, uint16_t, char *, uint16_t, int); -int uwsgi_starts_with(char *, int, char *, int); -int uwsgi_static_want_gzip(struct wsgi_request *, char *, size_t, struct stat *); + int uwsgi_file_serve(struct wsgi_request *, char *, uint16_t, char *, uint16_t, int); + int uwsgi_starts_with(char *, int, char *, int); + int uwsgi_static_want_gzip(struct wsgi_request *, char *, size_t, struct stat *); #ifdef __sun__ -time_t timegm(struct tm *); + time_t timegm(struct tm *); #endif -size_t uwsgi_str_num(char *, int); + size_t uwsgi_str_num(char *, int); -int uwsgi_proto_uwsgi_parser(struct wsgi_request *); -int uwsgi_proto_base_write(struct wsgi_request *, char *, size_t); -int uwsgi_proto_base_write_header(struct wsgi_request *, char *, size_t); + int uwsgi_proto_uwsgi_parser(struct wsgi_request *); + int uwsgi_proto_base_write(struct wsgi_request *, char *, size_t); + int uwsgi_proto_base_write_header(struct wsgi_request *, char *, size_t); + ssize_t uwsgi_proto_base_read_body(struct wsgi_request *, char *, size_t); -int uwsgi_proto_http_parser(struct wsgi_request *); + int uwsgi_proto_http_parser(struct wsgi_request *); -int uwsgi_proto_fastcgi_parser(struct wsgi_request *); -int uwsgi_proto_fastcgi_write(struct wsgi_request *, char *, size_t); -int uwsgi_proto_fastcgi_write_header(struct wsgi_request *, char *, size_t); -int uwsgi_proto_fastcgi_sendfile(struct wsgi_request *, int, size_t, size_t); -void uwsgi_proto_fastcgi_close(struct wsgi_request *); + int uwsgi_proto_fastcgi_parser(struct wsgi_request *); + int uwsgi_proto_fastcgi_write(struct wsgi_request *, char *, size_t); + int uwsgi_proto_fastcgi_write_header(struct wsgi_request *, char *, size_t); + int uwsgi_proto_fastcgi_sendfile(struct wsgi_request *, int, size_t, size_t); + void uwsgi_proto_fastcgi_close(struct wsgi_request *); -int uwsgi_proto_base_accept(struct wsgi_request *, int); -void uwsgi_proto_base_close(struct wsgi_request *); -uint16_t proto_base_add_uwsgi_header(struct wsgi_request *, char *, uint16_t, char *, uint16_t); -uint16_t proto_base_add_uwsgi_var(struct wsgi_request *, char *, uint16_t, char *, uint16_t); + int uwsgi_proto_base_accept(struct wsgi_request *, int); + void uwsgi_proto_base_close(struct wsgi_request *); + uint16_t proto_base_add_uwsgi_header(struct wsgi_request *, char *, uint16_t, char *, uint16_t); + uint16_t proto_base_add_uwsgi_var(struct wsgi_request *, char *, uint16_t, char *, uint16_t); #ifdef UWSGI_ZEROMQ -void uwsgi_proto_zeromq_setup(struct uwsgi_socket *); -ssize_t uwsgi_zeromq_logger(struct uwsgi_logger *, char *, size_t len); -int uwsgi_proto_zeromq_accept(struct wsgi_request *, int); -void uwsgi_proto_zeromq_close(struct wsgi_request *); -ssize_t uwsgi_proto_zeromq_writev_header(struct wsgi_request *, struct iovec *, size_t); -ssize_t uwsgi_proto_zeromq_writev(struct wsgi_request *, struct iovec *, size_t); -ssize_t uwsgi_proto_zeromq_write(struct wsgi_request *, char *, size_t); -ssize_t uwsgi_proto_zeromq_write_header(struct wsgi_request *, char *, size_t); -ssize_t uwsgi_proto_zeromq_sendfile(struct wsgi_request *); -int uwsgi_proto_zeromq_parser(struct wsgi_request *); -void *uwsgi_zeromq_init(void); -void uwsgi_zeromq_init_sockets(void); + void uwsgi_proto_zeromq_setup(struct uwsgi_socket *); + ssize_t uwsgi_zeromq_logger(struct uwsgi_logger *, char *, size_t len); + int uwsgi_proto_zeromq_accept(struct wsgi_request *, int); + void uwsgi_proto_zeromq_close(struct wsgi_request *); + ssize_t uwsgi_proto_zeromq_writev_header(struct wsgi_request *, struct iovec *, size_t); + ssize_t uwsgi_proto_zeromq_writev(struct wsgi_request *, struct iovec *, size_t); + ssize_t uwsgi_proto_zeromq_write(struct wsgi_request *, char *, size_t); + ssize_t uwsgi_proto_zeromq_write_header(struct wsgi_request *, char *, size_t); + ssize_t uwsgi_proto_zeromq_sendfile(struct wsgi_request *); + int uwsgi_proto_zeromq_parser(struct wsgi_request *); + void *uwsgi_zeromq_init(void); + void uwsgi_zeromq_init_sockets(void); #endif -int uwsgi_num2str2(int, char *); + int uwsgi_num2str2(int, char *); -void uwsgi_add_socket_from_fd(struct uwsgi_socket *, int); + void uwsgi_add_socket_from_fd(struct uwsgi_socket *, int); -char *uwsgi_split3(char *, size_t, char, char **, size_t *, char **, size_t *, char **, size_t *); -char *uwsgi_split4(char *, size_t, char, char **, size_t *, char **, size_t *, char **, size_t *, char **, size_t *); -char *uwsgi_netstring(char *, size_t, char **, size_t *); + char *uwsgi_split3(char *, size_t, char, char **, size_t *, char **, size_t *, char **, size_t *); + char *uwsgi_split4(char *, size_t, char, char **, size_t *, char **, size_t *, char **, size_t *, char **, size_t *); + char *uwsgi_netstring(char *, size_t, char **, size_t *); -int uwsgi_get_socket_num(struct uwsgi_socket *); -struct uwsgi_socket *uwsgi_new_socket(char *); -struct uwsgi_socket *uwsgi_new_shared_socket(char *); -struct uwsgi_socket *uwsgi_del_socket(struct uwsgi_socket *); + int uwsgi_get_socket_num(struct uwsgi_socket *); + struct uwsgi_socket *uwsgi_new_socket(char *); + struct uwsgi_socket *uwsgi_new_shared_socket(char *); + struct uwsgi_socket *uwsgi_del_socket(struct uwsgi_socket *); -void uwsgi_close_all_sockets(void); + void uwsgi_close_all_sockets(void); -struct uwsgi_string_list *uwsgi_string_new_list(struct uwsgi_string_list **, char *); + struct uwsgi_string_list *uwsgi_string_new_list(struct uwsgi_string_list **, char *); #ifdef UWSGI_PCRE -struct uwsgi_regexp_list *uwsgi_regexp_custom_new_list(struct uwsgi_regexp_list **, char *, char *); + struct uwsgi_regexp_list *uwsgi_regexp_custom_new_list(struct uwsgi_regexp_list **, char *, char *); #define uwsgi_regexp_new_list(x, y) uwsgi_regexp_custom_new_list(x, y, NULL); #endif -void uwsgi_string_del_list(struct uwsgi_string_list **, struct uwsgi_string_list *); + void uwsgi_string_del_list(struct uwsgi_string_list **, struct uwsgi_string_list *); -void uwsgi_init_all_apps(void); -void uwsgi_init_worker_mount_apps(void); -void uwsgi_socket_nb(int); -void uwsgi_socket_b(int); -int uwsgi_write_nb(int, char *, size_t, int); -int uwsgi_read_nb(int, char *, size_t, int); -int uwsgi_read_uh(int fd, struct uwsgi_header *, int); + void uwsgi_init_all_apps(void); + void uwsgi_init_worker_mount_apps(void); + void uwsgi_socket_nb(int); + void uwsgi_socket_b(int); + int uwsgi_write_nb(int, char *, size_t, int); + int uwsgi_read_nb(int, char *, size_t, int); + int uwsgi_read_uh(int fd, struct uwsgi_header *, int); -void uwsgi_destroy_request(struct wsgi_request *); + void uwsgi_destroy_request(struct wsgi_request *); -void uwsgi_systemd_init(char *); + void uwsgi_systemd_init(char *); -void uwsgi_sig_pause(void); + void uwsgi_sig_pause(void); -void uwsgi_ignition(void); + void uwsgi_ignition(void); -void master_check_cluster_nodes(void); -int uwsgi_respawn_worker(int); + int uwsgi_respawn_worker(int); socklen_t socket_to_in_addr(char *, char *, int, struct sockaddr_in *); socklen_t socket_to_un_addr(char *, struct sockaddr_un *); -#ifdef UWSGI_IPV6 socklen_t socket_to_in_addr6(char *, char *, int, struct sockaddr_in6 *); -#endif -int uwsgi_get_shared_socket_fd_by_num(int); -struct uwsgi_socket *uwsgi_get_shared_socket_by_num(int); + int uwsgi_get_shared_socket_fd_by_num(int); + struct uwsgi_socket *uwsgi_get_shared_socket_by_num(int); -struct uwsgi_socket *uwsgi_get_socket_by_num(int); + struct uwsgi_socket *uwsgi_get_socket_by_num(int); -int uwsgi_get_shared_socket_num(struct uwsgi_socket *); + int uwsgi_get_shared_socket_num(struct uwsgi_socket *); #ifdef __linux__ -void uwsgi_set_cgroup(void); -long uwsgi_num_from_file(char *, int); + void uwsgi_set_cgroup(void); + long uwsgi_num_from_file(char *, int); #endif -void uwsgi_add_sockets_to_queue(int, int); -void uwsgi_del_sockets_from_queue(int); + void uwsgi_add_sockets_to_queue(int, int); + void uwsgi_del_sockets_from_queue(int); -int uwsgi_run_command_and_wait(char *, char *); + int uwsgi_run_command_and_wait(char *, char *); -void uwsgi_manage_signal_cron(time_t); -pid_t uwsgi_run_command(char *, int *, int); + void uwsgi_manage_signal_cron(time_t); + pid_t uwsgi_run_command(char *, int *, int); -void uwsgi_manage_command_cron(time_t); + void uwsgi_manage_command_cron(time_t); -int *uwsgi_attach_fd(int, int *, char *, size_t); + int *uwsgi_attach_fd(int, int *, char *, size_t); -int uwsgi_count_sockets(struct uwsgi_socket *); -int uwsgi_file_exists(char *); + int uwsgi_count_sockets(struct uwsgi_socket *); + int uwsgi_file_exists(char *); -int uwsgi_signal_registered(uint8_t); + int uwsgi_signal_registered(uint8_t); -int uwsgi_endswith(char *, char *); + int uwsgi_endswith(char *, char *); -int uwsgi_cache_server(char *, int); + int uwsgi_cache_server(char *, int); -void uwsgi_chown(char *, char *); + void uwsgi_chown(char *, char *); -char *uwsgi_get_binary_path(char *); + char *uwsgi_get_binary_path(char *); -char *uwsgi_lower(char *, size_t); -int uwsgi_num2str2n(int, char *, int); -void create_logpipe(void); + char *uwsgi_lower(char *, size_t); + int uwsgi_num2str2n(int, char *, int); + void create_logpipe(void); -char *uwsgi_str_contains(char *, int, char); + char *uwsgi_str_contains(char *, int, char); -int uwsgi_simple_parse_vars(struct wsgi_request *, char *, char *); + int uwsgi_simple_parse_vars(struct wsgi_request *, char *, char *); -void uwsgi_build_mime_dict(char *); -struct uwsgi_dyn_dict *uwsgi_dyn_dict_new(struct uwsgi_dyn_dict **, char *, int, char *, int); -void uwsgi_dyn_dict_del(struct uwsgi_dyn_dict *); + void uwsgi_build_mime_dict(char *); + struct uwsgi_dyn_dict *uwsgi_dyn_dict_new(struct uwsgi_dyn_dict **, char *, int, char *, int); + void uwsgi_dyn_dict_del(struct uwsgi_dyn_dict *); -void uwsgi_apply_config_pass(char symbol, char*(*)(char *) ); + void uwsgi_apply_config_pass(char symbol, char *(*)(char *)); -void uwsgi_mule(int); + void uwsgi_mule(int); -char *uwsgi_string_get_list(struct uwsgi_string_list **, int, size_t *); + char *uwsgi_string_get_list(struct uwsgi_string_list **, int, size_t *); -void uwsgi_fixup_fds(int, int, struct uwsgi_gateway *); + void uwsgi_fixup_fds(int, int, struct uwsgi_gateway *); -void uwsgi_set_processname(char *); + void uwsgi_set_processname(char *); -void http_url_decode(char *, uint16_t *, char *); + void http_url_decode(char *, uint16_t *, char *); -pid_t uwsgi_fork(char *); + pid_t uwsgi_fork(char *); -struct uwsgi_mule *get_mule_by_id(int); -struct uwsgi_mule_farm *uwsgi_mule_farm_new(struct uwsgi_mule_farm **, struct uwsgi_mule *); + struct uwsgi_mule *get_mule_by_id(int); + struct uwsgi_mule_farm *uwsgi_mule_farm_new(struct uwsgi_mule_farm **, struct uwsgi_mule *); -int uwsgi_farm_has_mule(struct uwsgi_farm *, int); -struct uwsgi_farm *get_farm_by_name(char *); + int uwsgi_farm_has_mule(struct uwsgi_farm *, int); + struct uwsgi_farm *get_farm_by_name(char *); -struct uwsgi_subscribe_node { + struct uwsgi_subscribe_node { - char name[0xff]; - uint16_t len; - uint8_t modifier1; - uint8_t modifier2; + char name[0xff]; + uint16_t len; + uint8_t modifier1; + uint8_t modifier2; - time_t last_check; + time_t last_check; - // absolute number of requests - uint64_t requests; - // number of requests since last subscription ping - uint64_t last_requests; + // absolute number of requests + uint64_t requests; + // number of requests since last subscription ping + uint64_t last_requests; - uint64_t transferred; + uint64_t transferred; - int death_mark; - uint64_t reference; - uint64_t cores; - uint64_t load; - uint64_t failcnt; + int death_mark; + uint64_t reference; + uint64_t cores; + uint64_t load; + uint64_t failcnt; - uint64_t weight; - uint64_t wrr; + uint64_t weight; + uint64_t wrr; - time_t unix_check; + time_t unix_check; - struct uwsgi_subscribe_slot *slot; + struct uwsgi_subscribe_slot *slot; - struct uwsgi_subscribe_node *next; -}; + struct uwsgi_subscribe_node *next; + }; -struct uwsgi_subscribe_slot { + struct uwsgi_subscribe_slot { - char key[0xff]; - uint16_t keylen; + char key[0xff]; + uint16_t keylen; - uint32_t hash; + uint32_t hash; - uint64_t hits; + uint64_t hits; #ifdef UWSGI_SSL - EVP_PKEY *sign_public_key; - EVP_MD_CTX *sign_ctx; + EVP_PKEY *sign_public_key; + EVP_MD_CTX *sign_ctx; #endif - struct uwsgi_subscribe_node *nodes; + struct uwsgi_subscribe_node *nodes; - struct uwsgi_subscribe_slot *prev; - struct uwsgi_subscribe_slot *next; -}; + struct uwsgi_subscribe_slot *prev; + struct uwsgi_subscribe_slot *next; + }; -void mule_send_msg(int, char *, size_t); + void mule_send_msg(int, char *, size_t); -uint32_t djb33x_hash(char *, uint64_t); -void create_signal_pipe(int *); -struct uwsgi_subscribe_slot *uwsgi_get_subscribe_slot(struct uwsgi_subscribe_slot **, char *, uint16_t); -struct uwsgi_subscribe_node *uwsgi_get_subscribe_node_by_name(struct uwsgi_subscribe_slot **, char *, uint16_t, char *, uint16_t); -struct uwsgi_subscribe_node *uwsgi_get_subscribe_node(struct uwsgi_subscribe_slot **, char *, uint16_t); -int uwsgi_remove_subscribe_node(struct uwsgi_subscribe_slot **, struct uwsgi_subscribe_node *); -struct uwsgi_subscribe_node *uwsgi_add_subscribe_node(struct uwsgi_subscribe_slot **, struct uwsgi_subscribe_req *); + uint32_t djb33x_hash(char *, uint64_t); + void create_signal_pipe(int *); + struct uwsgi_subscribe_slot *uwsgi_get_subscribe_slot(struct uwsgi_subscribe_slot **, char *, uint16_t); + struct uwsgi_subscribe_node *uwsgi_get_subscribe_node_by_name(struct uwsgi_subscribe_slot **, char *, uint16_t, char *, uint16_t); + struct uwsgi_subscribe_node *uwsgi_get_subscribe_node(struct uwsgi_subscribe_slot **, char *, uint16_t); + int uwsgi_remove_subscribe_node(struct uwsgi_subscribe_slot **, struct uwsgi_subscribe_node *); + struct uwsgi_subscribe_node *uwsgi_add_subscribe_node(struct uwsgi_subscribe_slot **, struct uwsgi_subscribe_req *); -ssize_t uwsgi_mule_get_msg(int, int, char *, size_t, int); + ssize_t uwsgi_mule_get_msg(int, int, char *, size_t, int); -int uwsgi_signal_wait(int); -struct uwsgi_app *uwsgi_add_app(int, uint8_t, char *, int, void *, void *); -int uwsgi_signal_send(int, uint8_t); -int uwsgi_remote_signal_send(char *, uint8_t); + int uwsgi_signal_wait(int); + struct uwsgi_app *uwsgi_add_app(int, uint8_t, char *, int, void *, void *); + int uwsgi_signal_send(int, uint8_t); + int uwsgi_remote_signal_send(char *, uint8_t); -void uwsgi_configure(); -void cluster_setup(void); -void manage_cluster_announce(char *, uint16_t, char *, uint16_t, void *); + void uwsgi_configure(); -int uwsgi_read_response(int, struct uwsgi_header *, int, char **); -char *uwsgi_simple_file_read(char *); + int uwsgi_read_response(int, struct uwsgi_header *, int, char **); + char *uwsgi_simple_file_read(char *); -void uwsgi_send_subscription(char *, char *, size_t , uint8_t, uint8_t , uint8_t, char *, char *); + void uwsgi_send_subscription(char *, char *, size_t, uint8_t, uint8_t, uint8_t, char *, char *); -void uwsgi_subscribe(char *, uint8_t); -void uwsgi_subscribe2(char *, uint8_t); + void uwsgi_subscribe(char *, uint8_t); + void uwsgi_subscribe2(char *, uint8_t); -struct uwsgi_probe *uwsgi_probe_register(struct uwsgi_probe **, char *, int (*)(int, struct uwsgi_signal_probe *)); -int uwsgi_add_probe(uint8_t sig, char *, char *, int, int); + struct uwsgi_probe *uwsgi_probe_register(struct uwsgi_probe **, char *, int (*)(int, struct uwsgi_signal_probe *)); + int uwsgi_add_probe(uint8_t sig, char *, char *, int, int); -int uwsgi_is_bad_connection(int); -int uwsgi_long2str2n(unsigned long long, char *, int); + int uwsgi_is_bad_connection(int); + int uwsgi_long2str2n(unsigned long long, char *, int); #ifdef __linux__ -void uwsgi_build_unshare(char *); + void uwsgi_build_unshare(char *); #ifdef MADV_MERGEABLE -void uwsgi_linux_ksm_map(void); + void uwsgi_linux_ksm_map(void); #endif #endif #ifdef UWSGI_CAP -void uwsgi_build_cap(char *); + void uwsgi_build_cap(char *); #endif -void uwsgi_register_logger(char *, ssize_t (*func)(struct uwsgi_logger *, char *, size_t)); -void uwsgi_append_logger(struct uwsgi_logger *); -void uwsgi_append_req_logger(struct uwsgi_logger *); -struct uwsgi_logger *uwsgi_get_logger(char *); -struct uwsgi_logger *uwsgi_get_logger_from_id(char *); + void uwsgi_register_logger(char *, ssize_t(*func) (struct uwsgi_logger *, char *, size_t)); + void uwsgi_append_logger(struct uwsgi_logger *); + void uwsgi_append_req_logger(struct uwsgi_logger *); + struct uwsgi_logger *uwsgi_get_logger(char *); + struct uwsgi_logger *uwsgi_get_logger_from_id(char *); -char *uwsgi_getsockname(int); -char *uwsgi_get_var(struct wsgi_request *, char *, uint16_t, uint16_t *); + char *uwsgi_getsockname(int); + char *uwsgi_get_var(struct wsgi_request *, char *, uint16_t, uint16_t *); -struct uwsgi_gateway_socket *uwsgi_new_gateway_socket(char *, char *); -struct uwsgi_gateway_socket *uwsgi_new_gateway_socket_from_fd(int, char *); + struct uwsgi_gateway_socket *uwsgi_new_gateway_socket(char *, char *); + struct uwsgi_gateway_socket *uwsgi_new_gateway_socket_from_fd(int, char *); -void escape_shell_arg(char *, size_t, char *); + void escape_shell_arg(char *, size_t, char *); -void *uwsgi_malloc_shared(size_t); -void *uwsgi_calloc_shared(size_t); + void *uwsgi_malloc_shared(size_t); + void *uwsgi_calloc_shared(size_t); -struct uwsgi_spooler *uwsgi_new_spooler(char *); + struct uwsgi_spooler *uwsgi_new_spooler(char *); -struct uwsgi_spooler *uwsgi_get_spooler_by_name(char *); + struct uwsgi_spooler *uwsgi_get_spooler_by_name(char *); -int uwsgi_zerg_attach(char *); + int uwsgi_zerg_attach(char *); -int uwsgi_manage_opt(char *, char *); + int uwsgi_manage_opt(char *, char *); -void uwsgi_opt_print(char *, char *, void *); -void uwsgi_opt_true(char *, char *, void *); -void uwsgi_opt_set_str(char *, char *, void *); -void uwsgi_opt_set_logger(char *, char *, void *); -void uwsgi_opt_set_req_logger(char *, char *, void *); -void uwsgi_opt_set_str_spaced(char *, char *, void *); -void uwsgi_opt_add_string_list(char *, char *, void *); -void uwsgi_opt_add_addr_list(char *, char *, void *); -void uwsgi_opt_add_string_list_custom(char *, char *, void *); -void uwsgi_opt_add_dyn_dict(char *, char *, void *); + void uwsgi_opt_print(char *, char *, void *); + void uwsgi_opt_true(char *, char *, void *); + void uwsgi_opt_set_str(char *, char *, void *); + void uwsgi_opt_set_logger(char *, char *, void *); + void uwsgi_opt_set_req_logger(char *, char *, void *); + void uwsgi_opt_set_str_spaced(char *, char *, void *); + void uwsgi_opt_add_string_list(char *, char *, void *); + void uwsgi_opt_add_addr_list(char *, char *, void *); + void uwsgi_opt_add_string_list_custom(char *, char *, void *); + void uwsgi_opt_add_dyn_dict(char *, char *, void *); #ifdef UWSGI_PCRE -void uwsgi_opt_pcre_jit(char *, char *, void *); -void uwsgi_opt_add_regexp_dyn_dict(char *, char *, void *); -void uwsgi_opt_add_regexp_list(char *, char *, void *); -void uwsgi_opt_add_regexp_custom_list(char *, char *, void *); + void uwsgi_opt_pcre_jit(char *, char *, void *); + void uwsgi_opt_add_regexp_dyn_dict(char *, char *, void *); + void uwsgi_opt_add_regexp_list(char *, char *, void *); + void uwsgi_opt_add_regexp_custom_list(char *, char *, void *); #endif -void uwsgi_opt_set_int(char *, char *, void *); -void uwsgi_opt_set_rawint(char *, char *, void *); -void uwsgi_opt_set_64bit(char *, char *, void *); -void uwsgi_opt_set_megabytes(char *, char *, void *); -void uwsgi_opt_set_dyn(char *, char *, void *); -void uwsgi_opt_dyn_true(char *, char *, void *); -void uwsgi_opt_dyn_false(char *, char *, void *); -void uwsgi_opt_set_placeholder(char *, char *, void *); -void uwsgi_opt_add_shared_socket(char *, char *, void *); -void uwsgi_opt_add_socket(char *, char *, void *); -void uwsgi_opt_add_lazy_socket(char *, char *, void *); -void uwsgi_opt_add_cron(char *, char *, void *); -void uwsgi_opt_load_plugin(char *, char *, void *); -void uwsgi_opt_load_dl(char *, char *, void *); -void uwsgi_opt_load(char *, char *, void *); -void uwsgi_opt_cluster_log(char *, char *, void *); -void uwsgi_opt_cluster_reload(char *, char *, void *); + void uwsgi_opt_set_int(char *, char *, void *); + void uwsgi_opt_set_rawint(char *, char *, void *); + void uwsgi_opt_set_16bit(char *, char *, void *); + void uwsgi_opt_set_64bit(char *, char *, void *); + void uwsgi_opt_set_megabytes(char *, char *, void *); + void uwsgi_opt_set_dyn(char *, char *, void *); + void uwsgi_opt_dyn_true(char *, char *, void *); + void uwsgi_opt_dyn_false(char *, char *, void *); + void uwsgi_opt_set_placeholder(char *, char *, void *); + void uwsgi_opt_add_shared_socket(char *, char *, void *); + void uwsgi_opt_add_socket(char *, char *, void *); + void uwsgi_opt_add_lazy_socket(char *, char *, void *); + void uwsgi_opt_add_cron(char *, char *, void *); + void uwsgi_opt_load_plugin(char *, char *, void *); + void uwsgi_opt_load_dl(char *, char *, void *); + void uwsgi_opt_load(char *, char *, void *); #ifdef UWSGI_SSL -void uwsgi_opt_sni(char *, char *, void *); -struct uwsgi_string_list *uwsgi_ssl_add_sni_item(char *, char *, char *, char *, char *); + void uwsgi_opt_sni(char *, char *, void *); + struct uwsgi_string_list *uwsgi_ssl_add_sni_item(char *, char *, char *, char *, char *); #endif -void uwsgi_opt_flock(char *, char *, void *); -void uwsgi_opt_flock_wait(char *, char *, void *); + void uwsgi_opt_flock(char *, char *, void *); + void uwsgi_opt_flock_wait(char *, char *, void *); #ifdef UWSGI_INI -void uwsgi_opt_load_ini(char *, char *, void *); + void uwsgi_opt_load_ini(char *, char *, void *); #endif #ifdef UWSGI_XML -void uwsgi_opt_load_xml(char *, char *, void *); + void uwsgi_opt_load_xml(char *, char *, void *); #endif #ifdef UWSGI_YAML -void uwsgi_opt_load_yml(char *, char *, void *); + void uwsgi_opt_load_yml(char *, char *, void *); #endif #ifdef UWSGI_SQLITE3 -void uwsgi_opt_load_sqlite3(char *, char *, void *); + void uwsgi_opt_load_sqlite3(char *, char *, void *); #endif #ifdef UWSGI_JSON -void uwsgi_opt_load_json(char *, char *, void *); + void uwsgi_opt_load_json(char *, char *, void *); #endif #ifdef UWSGI_LDAP -void uwsgi_opt_load_ldap(char *, char *, void *); + void uwsgi_opt_load_ldap(char *, char *, void *); #endif -void uwsgi_opt_set_umask(char *, char *, void *); -void uwsgi_opt_add_spooler(char *, char *, void *); -void uwsgi_opt_add_daemon(char *, char *, void *); -void uwsgi_opt_set_uid(char *, char *, void *); -void uwsgi_opt_set_gid(char *, char *, void *); -void uwsgi_opt_set_env(char *, char *, void *); -void uwsgi_opt_unset_env(char *, char *, void *); -void uwsgi_opt_pidfile_signal(char *, char *, void *); + void uwsgi_opt_set_umask(char *, char *, void *); + void uwsgi_opt_add_spooler(char *, char *, void *); + void uwsgi_opt_add_daemon(char *, char *, void *); + void uwsgi_opt_set_uid(char *, char *, void *); + void uwsgi_opt_set_gid(char *, char *, void *); + void uwsgi_opt_set_env(char *, char *, void *); + void uwsgi_opt_unset_env(char *, char *, void *); + void uwsgi_opt_pidfile_signal(char *, char *, void *); -void uwsgi_opt_check_static(char *, char *, void *); -void uwsgi_opt_fileserve_mode(char *, char *, void *); -void uwsgi_opt_static_map(char *, char *, void *); + void uwsgi_opt_check_static(char *, char *, void *); + void uwsgi_opt_fileserve_mode(char *, char *, void *); + void uwsgi_opt_static_map(char *, char *, void *); -void uwsgi_opt_add_mule(char *, char *, void *); -void uwsgi_opt_add_mules(char *, char *, void *); -void uwsgi_opt_add_farm(char *, char *, void *); + void uwsgi_opt_add_mule(char *, char *, void *); + void uwsgi_opt_add_mules(char *, char *, void *); + void uwsgi_opt_add_farm(char *, char *, void *); -void uwsgi_opt_signal(char *, char *, void *); + void uwsgi_opt_signal(char *, char *, void *); -void uwsgi_opt_snmp(char *, char *, void *); -void uwsgi_opt_snmp_community(char *, char *, void *); + void uwsgi_opt_snmp(char *, char *, void *); + void uwsgi_opt_snmp_community(char *, char *, void *); -void uwsgi_opt_logfile_chmod(char *, char *, void *); + void uwsgi_opt_logfile_chmod(char *, char *, void *); -void uwsgi_opt_log_date(char *, char *, void *); -void uwsgi_opt_chmod_socket(char *, char *, void *); + void uwsgi_opt_log_date(char *, char *, void *); + void uwsgi_opt_chmod_socket(char *, char *, void *); -void uwsgi_opt_max_vars(char *, char *, void *); -void uwsgi_opt_deprecated(char *, char *, void *); + void uwsgi_opt_max_vars(char *, char *, void *); + void uwsgi_opt_deprecated(char *, char *, void *); -void uwsgi_opt_noop(char *, char *, void *); + void uwsgi_opt_noop(char *, char *, void *); -void uwsgi_opt_logic(char *, char *, void *); -int uwsgi_logic_opt_for(char *, char *); -int uwsgi_logic_opt_if_env(char *, char *); -int uwsgi_logic_opt_if_not_env(char *, char *); -int uwsgi_logic_opt_if_opt(char *, char *); -int uwsgi_logic_opt_if_not_opt(char *, char *); -int uwsgi_logic_opt_if_exists(char *, char *); -int uwsgi_logic_opt_if_not_exists(char *, char *); -int uwsgi_logic_opt_if_file(char *, char *); -int uwsgi_logic_opt_if_not_file(char *, char *); -int uwsgi_logic_opt_if_dir(char *, char *); -int uwsgi_logic_opt_if_not_dir(char *, char *); -int uwsgi_logic_opt_if_reload(char *, char *); -int uwsgi_logic_opt_if_not_reload(char *, char *); + void uwsgi_opt_logic(char *, char *, void *); + int uwsgi_logic_opt_for(char *, char *); + int uwsgi_logic_opt_if_env(char *, char *); + int uwsgi_logic_opt_if_not_env(char *, char *); + int uwsgi_logic_opt_if_opt(char *, char *); + int uwsgi_logic_opt_if_not_opt(char *, char *); + int uwsgi_logic_opt_if_exists(char *, char *); + int uwsgi_logic_opt_if_not_exists(char *, char *); + int uwsgi_logic_opt_if_file(char *, char *); + int uwsgi_logic_opt_if_not_file(char *, char *); + int uwsgi_logic_opt_if_dir(char *, char *); + int uwsgi_logic_opt_if_not_dir(char *, char *); + int uwsgi_logic_opt_if_reload(char *, char *); + int uwsgi_logic_opt_if_not_reload(char *, char *); #ifdef UWSGI_CAP -void uwsgi_opt_set_cap(char *, char *, void *); + void uwsgi_opt_set_cap(char *, char *, void *); #endif #ifdef __linux__ -void uwsgi_opt_set_unshare(char *, char *, void *); + void uwsgi_opt_set_unshare(char *, char *, void *); #endif -char *uwsgi_tmpname(char *, char *); + char *uwsgi_tmpname(char *, char *); #ifdef UWSGI_ROUTING -struct uwsgi_router *uwsgi_register_router(char *, int (*)(struct uwsgi_route *, char *)); -void uwsgi_opt_add_route(char *, char *, void *); -int uwsgi_apply_routes(struct wsgi_request *); -int uwsgi_apply_routes_fast(struct wsgi_request *); -void uwsgi_register_embedded_routers(void); + struct uwsgi_router *uwsgi_register_router(char *, int (*)(struct uwsgi_route *, char *)); + void uwsgi_opt_add_route(char *, char *, void *); + int uwsgi_apply_routes(struct wsgi_request *); + int uwsgi_apply_routes_fast(struct wsgi_request *); + void uwsgi_register_embedded_routers(void); #endif -void uwsgi_reload(char **); + void uwsgi_reload(char **); -char *uwsgi_chomp(char *); -int uwsgi_file_to_string_list(char *, struct uwsgi_string_list **); -void uwsgi_backtrace(int); -void uwsgi_check_logrotate(void); -char *uwsgi_check_touches(struct uwsgi_string_list *); + char *uwsgi_chomp(char *); + int uwsgi_file_to_string_list(char *, struct uwsgi_string_list **); + void uwsgi_backtrace(int); + void uwsgi_check_logrotate(void); + char *uwsgi_check_touches(struct uwsgi_string_list *); -void uwsgi_manage_zerg(int, int, int *); + void uwsgi_manage_zerg(int, int, int *); -time_t uwsgi_now(void); + time_t uwsgi_now(void); -int uwsgi_calc_cheaper(void); -int uwsgi_cheaper_algo_spare(void); -int uwsgi_cheaper_algo_backlog(void); -int uwsgi_cheaper_algo_backlog2(void); + int uwsgi_calc_cheaper(void); + int uwsgi_cheaper_algo_spare(void); + int uwsgi_cheaper_algo_backlog(void); + int uwsgi_cheaper_algo_backlog2(void); -int uwsgi_master_log(void); -int uwsgi_master_req_log(void); -void uwsgi_flush_logs(void); + int uwsgi_master_log(void); + int uwsgi_master_req_log(void); + void uwsgi_flush_logs(void); -void uwsgi_register_cheaper_algo(char *, int(*) (void)); + void uwsgi_register_cheaper_algo(char *, int (*)(void)); -void uwsgi_setup_locking(void); -int uwsgi_fcntl_lock(int); -int uwsgi_fcntl_is_locked(int); + void uwsgi_setup_locking(void); + int uwsgi_fcntl_lock(int); + int uwsgi_fcntl_is_locked(int); -void uwsgi_emulate_cow_for_apps(int); + void uwsgi_emulate_cow_for_apps(int); -char *uwsgi_read_fd(int, size_t *, int); + char *uwsgi_read_fd(int, size_t *, int); -void uwsgi_setup_post_buffering(void); + void uwsgi_setup_post_buffering(void); -struct uwsgi_lock_item *uwsgi_lock_ipcsem_init(char *); + struct uwsgi_lock_item *uwsgi_lock_ipcsem_init(char *); -void uwsgi_write_pidfile(char *); -int uwsgi_manage_exception(char *, char *, char *); + void uwsgi_write_pidfile(char *); + int uwsgi_manage_exception(char *, char *, char *); -void uwsgi_protected_close(int); -ssize_t uwsgi_protected_read(int, void *, size_t); -int uwsgi_socket_uniq(struct uwsgi_socket *, struct uwsgi_socket *); -int uwsgi_socket_is_already_bound(char *name); + void uwsgi_protected_close(int); + ssize_t uwsgi_protected_read(int, void *, size_t); + int uwsgi_socket_uniq(struct uwsgi_socket *, struct uwsgi_socket *); + int uwsgi_socket_is_already_bound(char *name); -char *uwsgi_expand_path(char *, int, char *); -int uwsgi_try_autoload(char *); + char *uwsgi_expand_path(char *, int, char *); + int uwsgi_try_autoload(char *); -uint64_t uwsgi_micros(void); -int uwsgi_is_file(char *); -int uwsgi_is_link(char *); + uint64_t uwsgi_micros(void); + int uwsgi_is_file(char *); + int uwsgi_is_link(char *); -void uwsgi_receive_signal(int, char *, int); -void uwsgi_exec_atexit(void); + void uwsgi_receive_signal(int, char *, int); + void uwsgi_exec_atexit(void); -struct uwsgi_stats { - char *base; - off_t pos; - size_t tabs; - size_t chunk; - size_t size; - int minified; - int dirty; -}; + struct uwsgi_stats { + char *base; + off_t pos; + size_t tabs; + size_t chunk; + size_t size; + int minified; + int dirty; + }; -struct uwsgi_stats_pusher_instance; + struct uwsgi_stats_pusher_instance; -struct uwsgi_stats_pusher { - char *name; - void (*func)(struct uwsgi_stats_pusher_instance *, char *, size_t); - struct uwsgi_stats_pusher *next; -}; + struct uwsgi_stats_pusher { + char *name; + void (*func) (struct uwsgi_stats_pusher_instance *, char *, size_t); + struct uwsgi_stats_pusher *next; + }; -struct uwsgi_stats_pusher_instance { - struct uwsgi_stats_pusher *pusher; - char *arg; - void *data; - int configured; - int freq; - time_t last_run; - struct uwsgi_stats_pusher_instance *next; -}; + struct uwsgi_stats_pusher_instance { + struct uwsgi_stats_pusher *pusher; + char *arg; + void *data; + int configured; + int freq; + time_t last_run; + struct uwsgi_stats_pusher_instance *next; + }; -struct uwsgi_thread; -void uwsgi_stats_pusher_loop(struct uwsgi_thread *); -void uwsgi_stats_pusher_file(struct uwsgi_stats_pusher_instance *, char *, size_t); -void uwsgi_stats_pusher_socket(struct uwsgi_stats_pusher_instance *, char *, size_t); + struct uwsgi_thread; + void uwsgi_stats_pusher_loop(struct uwsgi_thread *); + void uwsgi_stats_pusher_file(struct uwsgi_stats_pusher_instance *, char *, size_t); + void uwsgi_stats_pusher_socket(struct uwsgi_stats_pusher_instance *, char *, size_t); -void uwsgi_stats_pusher_setup(void); -void uwsgi_send_stats(int, struct uwsgi_stats * (*func)(void)); -struct uwsgi_stats *uwsgi_master_generate_stats(void); -void uwsgi_register_stats_pusher(char *, void(*) (struct uwsgi_stats_pusher_instance *, char *, size_t)); + void uwsgi_stats_pusher_setup(void); + void uwsgi_send_stats(int, struct uwsgi_stats *(*func) (void)); + struct uwsgi_stats *uwsgi_master_generate_stats(void); + void uwsgi_register_stats_pusher(char *, void (*)(struct uwsgi_stats_pusher_instance *, char *, size_t)); -struct uwsgi_stats *uwsgi_stats_new(size_t); -int uwsgi_stats_symbol(struct uwsgi_stats *, char); -int uwsgi_stats_comma(struct uwsgi_stats *); -int uwsgi_stats_object_open(struct uwsgi_stats *); -int uwsgi_stats_object_close(struct uwsgi_stats *); -int uwsgi_stats_list_open(struct uwsgi_stats *); -int uwsgi_stats_list_close(struct uwsgi_stats *); -int uwsgi_stats_keyval(struct uwsgi_stats *, char *, char *); -int uwsgi_stats_keyval_comma(struct uwsgi_stats *, char *, char *); -int uwsgi_stats_keyvalnum(struct uwsgi_stats *, char *, char *, unsigned long long); -int uwsgi_stats_keyvalnum_comma(struct uwsgi_stats *, char *, char *, unsigned long long); -int uwsgi_stats_keyvaln(struct uwsgi_stats *, char *, char *, int); -int uwsgi_stats_keyvaln_comma(struct uwsgi_stats *, char *, char *, int); -int uwsgi_stats_key(struct uwsgi_stats *, char *); -int uwsgi_stats_keylong(struct uwsgi_stats *, char *, unsigned long long); -int uwsgi_stats_keylong_comma(struct uwsgi_stats *, char *, unsigned long long); -int uwsgi_stats_str(struct uwsgi_stats *, char *); + struct uwsgi_stats *uwsgi_stats_new(size_t); + int uwsgi_stats_symbol(struct uwsgi_stats *, char); + int uwsgi_stats_comma(struct uwsgi_stats *); + int uwsgi_stats_object_open(struct uwsgi_stats *); + int uwsgi_stats_object_close(struct uwsgi_stats *); + int uwsgi_stats_list_open(struct uwsgi_stats *); + int uwsgi_stats_list_close(struct uwsgi_stats *); + int uwsgi_stats_keyval(struct uwsgi_stats *, char *, char *); + int uwsgi_stats_keyval_comma(struct uwsgi_stats *, char *, char *); + int uwsgi_stats_keyvalnum(struct uwsgi_stats *, char *, char *, unsigned long long); + int uwsgi_stats_keyvalnum_comma(struct uwsgi_stats *, char *, char *, unsigned long long); + int uwsgi_stats_keyvaln(struct uwsgi_stats *, char *, char *, int); + int uwsgi_stats_keyvaln_comma(struct uwsgi_stats *, char *, char *, int); + int uwsgi_stats_key(struct uwsgi_stats *, char *); + int uwsgi_stats_keylong(struct uwsgi_stats *, char *, unsigned long long); + int uwsgi_stats_keylong_comma(struct uwsgi_stats *, char *, unsigned long long); + int uwsgi_stats_str(struct uwsgi_stats *, char *); -char *uwsgi_substitute(char *, char *, char *); + char *uwsgi_substitute(char *, char *, char *); -void manage_cluster_message(char *, int); -void uwsgi_opt_add_custom_option(char *, char *, void *); -void uwsgi_opt_cflags(char *, char *, void *); -void uwsgi_opt_connect_and_read(char *, char *, void *); -void uwsgi_opt_extract(char *, char *, void *); + void uwsgi_opt_add_custom_option(char *, char *, void *); + void uwsgi_opt_cflags(char *, char *, void *); + void uwsgi_opt_connect_and_read(char *, char *, void *); + void uwsgi_opt_extract(char *, char *, void *); -struct uwsgi_string_list *uwsgi_string_list_has_item(struct uwsgi_string_list *, char *, size_t); + struct uwsgi_string_list *uwsgi_string_list_has_item(struct uwsgi_string_list *, char *, size_t); -void trigger_harakiri(int); + void trigger_harakiri(int); -void uwsgi_setup_systemd(); -void uwsgi_setup_upstart(); -void uwsgi_setup_zerg(); -void uwsgi_setup_inherited_sockets(); + void uwsgi_setup_systemd(); + void uwsgi_setup_upstart(); + void uwsgi_setup_zerg(); + void uwsgi_setup_inherited_sockets(); #ifdef UWSGI_SSL -void uwsgi_ssl_init(void); -SSL_CTX *uwsgi_ssl_new_server_context(char *, char *, char *, char *, char *); -char *uwsgi_rsa_sign(char *, char *, size_t, unsigned int *); -char *uwsgi_sanitize_cert_filename(char *, char *, uint16_t); -void uwsgi_opt_scd(char *, char *, void *); -int uwsgi_subscription_sign_check(struct uwsgi_subscribe_slot *, struct uwsgi_subscribe_req *); + void uwsgi_ssl_init(void); + SSL_CTX *uwsgi_ssl_new_server_context(char *, char *, char *, char *, char *); + char *uwsgi_rsa_sign(char *, char *, size_t, unsigned int *); + char *uwsgi_sanitize_cert_filename(char *, char *, uint16_t); + void uwsgi_opt_scd(char *, char *, void *); + int uwsgi_subscription_sign_check(struct uwsgi_subscribe_slot *, struct uwsgi_subscribe_req *); -char *uwsgi_sha1(char *, size_t, char *); -char *uwsgi_sha1_2n(char *, size_t, char *, size_t, char *); + char *uwsgi_sha1(char *, size_t, char *); + char *uwsgi_sha1_2n(char *, size_t, char *, size_t, char *); #endif -void uwsgi_opt_ssa(char *, char *, void *); + void uwsgi_opt_ssa(char *, char *, void *); -int uwsgi_no_subscriptions(struct uwsgi_subscribe_slot **); -void uwsgi_deadlock_check(pid_t); + int uwsgi_no_subscriptions(struct uwsgi_subscribe_slot **); + void uwsgi_deadlock_check(pid_t); -char *uwsgi_setup_clusterbuf(size_t *); -struct uwsgi_logchunk { - char *ptr; - size_t len; - int vec; - long pos; - long pos_len; - int type; - int free; - ssize_t (*func)(struct wsgi_request *, char **); - struct uwsgi_logchunk *next; -}; + struct uwsgi_logchunk { + char *ptr; + size_t len; + int vec; + long pos; + long pos_len; + int type; + int free; + ssize_t(*func) (struct wsgi_request *, char **); + struct uwsgi_logchunk *next; + }; -void uwsgi_build_log_format(char *); + void uwsgi_build_log_format(char *); -void uwsgi_add_logchunk(int, int, char *, size_t); + void uwsgi_add_logchunk(int, int, char *, size_t); -void uwsgi_logit_simple(struct wsgi_request *); -void uwsgi_logit_lf(struct wsgi_request *); -void uwsgi_logit_lf_strftime(struct wsgi_request *); + void uwsgi_logit_simple(struct wsgi_request *); + void uwsgi_logit_lf(struct wsgi_request *); + void uwsgi_logit_lf_strftime(struct wsgi_request *); -struct uwsgi_logvar *uwsgi_logvar_get(struct wsgi_request *, char *, uint8_t); -void uwsgi_logvar_add(struct wsgi_request *, char *, uint8_t, char *, uint8_t); + struct uwsgi_logvar *uwsgi_logvar_get(struct wsgi_request *, char *, uint8_t); + void uwsgi_logvar_add(struct wsgi_request *, char *, uint8_t, char *, uint8_t); // scanners are instances of 'imperial_monitor' -struct uwsgi_emperor_scanner { - char *arg; - int fd; - void *data; - void (*event_func)(struct uwsgi_emperor_scanner *); - struct uwsgi_imperial_monitor *monitor; - struct uwsgi_emperor_scanner *next; -}; + struct uwsgi_emperor_scanner { + char *arg; + int fd; + void *data; + void (*event_func) (struct uwsgi_emperor_scanner *); + struct uwsgi_imperial_monitor *monitor; + struct uwsgi_emperor_scanner *next; + }; -void uwsgi_register_imperial_monitor(char *, void (*)(struct uwsgi_emperor_scanner *), void (*)(struct uwsgi_emperor_scanner *)); -int uwsgi_emperor_is_valid(char *); + void uwsgi_register_imperial_monitor(char *, void (*)(struct uwsgi_emperor_scanner *), void (*)(struct uwsgi_emperor_scanner *)); + int uwsgi_emperor_is_valid(char *); // an instance (called vassal) is a uWSGI stack running // it is identified by the name of its config file // a vassal is 'loyal' as soon as it manages a request -struct uwsgi_instance { - struct uwsgi_instance *ui_prev; - struct uwsgi_instance *ui_next; + struct uwsgi_instance { + struct uwsgi_instance *ui_prev; + struct uwsgi_instance *ui_next; - char name[0xff]; - pid_t pid; + char name[0xff]; + pid_t pid; - int status; - time_t born; - time_t last_mod; - time_t last_loyal; + int status; + time_t born; + time_t last_mod; + time_t last_loyal; - time_t last_run; - time_t first_run; + time_t last_run; + time_t first_run; - time_t last_heartbeat; + time_t last_heartbeat; - uint64_t respawns; - int use_config; + uint64_t respawns; + int use_config; - int pipe[2]; - int pipe_config[2]; + int pipe[2]; + int pipe_config[2]; - char *config; - uint32_t config_len; + char *config; + uint32_t config_len; - int loyal; + int loyal; - int zerg; + int zerg; - struct uwsgi_emperor_scanner *scanner; + struct uwsgi_emperor_scanner *scanner; - uid_t uid; - gid_t gid; -}; + uid_t uid; + gid_t gid; + }; -struct uwsgi_instance *emperor_get_by_fd(int); -struct uwsgi_instance *emperor_get(char *); -void emperor_stop(struct uwsgi_instance *); -void emperor_respawn(struct uwsgi_instance *, time_t); -void emperor_add(struct uwsgi_emperor_scanner *, char *, time_t, char *, uint32_t, uid_t, gid_t); + struct uwsgi_instance *emperor_get_by_fd(int); + struct uwsgi_instance *emperor_get(char *); + void emperor_stop(struct uwsgi_instance *); + void emperor_respawn(struct uwsgi_instance *, time_t); + void emperor_add(struct uwsgi_emperor_scanner *, char *, time_t, char *, uint32_t, uid_t, gid_t); -void uwsgi_exec_command_with_args(char *); + void uwsgi_exec_command_with_args(char *); -void uwsgi_imperial_monitor_glob_init(struct uwsgi_emperor_scanner *); -void uwsgi_imperial_monitor_directory_init(struct uwsgi_emperor_scanner *); -void uwsgi_imperial_monitor_directory(struct uwsgi_emperor_scanner *); -void uwsgi_imperial_monitor_glob(struct uwsgi_emperor_scanner *); + void uwsgi_imperial_monitor_glob_init(struct uwsgi_emperor_scanner *); + void uwsgi_imperial_monitor_directory_init(struct uwsgi_emperor_scanner *); + void uwsgi_imperial_monitor_directory(struct uwsgi_emperor_scanner *); + void uwsgi_imperial_monitor_glob(struct uwsgi_emperor_scanner *); -void uwsgi_register_clock(struct uwsgi_clock *); -void uwsgi_set_clock(char *name); + void uwsgi_register_clock(struct uwsgi_clock *); + void uwsgi_set_clock(char *name); -void uwsgi_init_default(void); -void uwsgi_setup_reload(void); -void uwsgi_autoload_plugins_by_name(char *); -void uwsgi_commandline_config(void); + void uwsgi_init_default(void); + void uwsgi_setup_reload(void); + void uwsgi_autoload_plugins_by_name(char *); + void uwsgi_commandline_config(void); -void uwsgi_setup_log(void); -void uwsgi_setup_log_master(void); + void uwsgi_setup_log(void); + void uwsgi_setup_log_master(void); -void uwsgi_setup_shared_sockets(void); + void uwsgi_setup_shared_sockets(void); -void uwsgi_setup_mules_and_farms(void); + void uwsgi_setup_mules_and_farms(void); -void uwsgi_setup_workers(void); -void uwsgi_map_sockets(void); + void uwsgi_setup_workers(void); + void uwsgi_map_sockets(void); -void uwsgi_set_cpu_affinity(void); + void uwsgi_set_cpu_affinity(void); -void uwsgi_emperor_start(void); + void uwsgi_emperor_start(void); -void uwsgi_bind_sockets(void); -void uwsgi_set_sockets_protocols(void); + void uwsgi_bind_sockets(void); + void uwsgi_set_sockets_protocols(void); -struct uwsgi_buffer *uwsgi_buffer_new(size_t); -int uwsgi_buffer_append(struct uwsgi_buffer *, char *, size_t); -int uwsgi_buffer_fix(struct uwsgi_buffer *, size_t); -int uwsgi_buffer_ensure(struct uwsgi_buffer *, size_t); -void uwsgi_buffer_destroy(struct uwsgi_buffer *); -int uwsgi_buffer_u8(struct uwsgi_buffer *, uint8_t); -int uwsgi_buffer_byte(struct uwsgi_buffer *, char); -int uwsgi_buffer_u16le(struct uwsgi_buffer *, uint16_t); -int uwsgi_buffer_u16be(struct uwsgi_buffer *, uint16_t); -int uwsgi_buffer_u32be(struct uwsgi_buffer *, uint32_t); -int uwsgi_buffer_u32le(struct uwsgi_buffer *, uint32_t); -int uwsgi_buffer_u24be(struct uwsgi_buffer *, uint32_t); -int uwsgi_buffer_u64be(struct uwsgi_buffer *, uint64_t); -int uwsgi_buffer_num64(struct uwsgi_buffer *, int64_t); -int uwsgi_buffer_append_keyval(struct uwsgi_buffer *, char *, uint16_t, char *, uint16_t); -int uwsgi_buffer_append_keyval32(struct uwsgi_buffer *, char *, uint32_t, char *, uint32_t); -int uwsgi_buffer_append_keynum(struct uwsgi_buffer *, char *, uint16_t, int64_t); -int uwsgi_buffer_append_ipv4(struct uwsgi_buffer *, void *); -int uwsgi_buffer_append_keyipv4(struct uwsgi_buffer *, char *, uint16_t, void *); -int uwsgi_buffer_decapitate(struct uwsgi_buffer *, size_t); -int uwsgi_buffer_append_base64(struct uwsgi_buffer *, char *, size_t); -int uwsgi_buffer_insert(struct uwsgi_buffer *, size_t, char *, size_t); -int uwsgi_buffer_insert_chunked(struct uwsgi_buffer *, size_t, size_t); -int uwsgi_buffer_append_chunked(struct uwsgi_buffer *, size_t); - -ssize_t uwsgi_buffer_write_simple(struct wsgi_request *, struct uwsgi_buffer *); + struct uwsgi_buffer *uwsgi_buffer_new(size_t); + int uwsgi_buffer_append(struct uwsgi_buffer *, char *, size_t); + int uwsgi_buffer_fix(struct uwsgi_buffer *, size_t); + int uwsgi_buffer_ensure(struct uwsgi_buffer *, size_t); + void uwsgi_buffer_destroy(struct uwsgi_buffer *); + int uwsgi_buffer_u8(struct uwsgi_buffer *, uint8_t); + int uwsgi_buffer_byte(struct uwsgi_buffer *, char); + int uwsgi_buffer_u16le(struct uwsgi_buffer *, uint16_t); + int uwsgi_buffer_u16be(struct uwsgi_buffer *, uint16_t); + int uwsgi_buffer_u32be(struct uwsgi_buffer *, uint32_t); + int uwsgi_buffer_u32le(struct uwsgi_buffer *, uint32_t); + int uwsgi_buffer_u24be(struct uwsgi_buffer *, uint32_t); + int uwsgi_buffer_u64be(struct uwsgi_buffer *, uint64_t); + int uwsgi_buffer_num64(struct uwsgi_buffer *, int64_t); + int uwsgi_buffer_append_keyval(struct uwsgi_buffer *, char *, uint16_t, char *, uint16_t); + int uwsgi_buffer_append_keyval32(struct uwsgi_buffer *, char *, uint32_t, char *, uint32_t); + int uwsgi_buffer_append_keynum(struct uwsgi_buffer *, char *, uint16_t, int64_t); + int uwsgi_buffer_append_ipv4(struct uwsgi_buffer *, void *); + int uwsgi_buffer_append_keyipv4(struct uwsgi_buffer *, char *, uint16_t, void *); + int uwsgi_buffer_decapitate(struct uwsgi_buffer *, size_t); + int uwsgi_buffer_append_base64(struct uwsgi_buffer *, char *, size_t); + int uwsgi_buffer_insert(struct uwsgi_buffer *, size_t, char *, size_t); + int uwsgi_buffer_insert_chunked(struct uwsgi_buffer *, size_t, size_t); + int uwsgi_buffer_append_chunked(struct uwsgi_buffer *, size_t); + + ssize_t uwsgi_buffer_write_simple(struct wsgi_request *, struct uwsgi_buffer *); -void uwsgi_httpize_var(char *, size_t); struct uwsgi_buffer *uwsgi_to_http(struct wsgi_request *, char *, uint16_t, char *, uint16_t); ssize_t uwsgi_pipe(int, int, int); @@ -3674,114 +3561,114 @@ void uwsgi_register_embedded_alarms(); void uwsgi_alarms_init(); #endif -struct uwsgi_thread { - pthread_t tid; - pthread_attr_t tattr; - int pipe[2]; - int queue; - ssize_t rlen; - void *data; - char *buf; - off_t pos; - size_t len; - uint64_t custom0; - uint64_t custom1; - uint64_t custom2; - uint64_t custom3; - // linked list for offloaded requests - struct uwsgi_offload_request *offload_requests_head; - struct uwsgi_offload_request *offload_requests_tail; - void (*func)(struct uwsgi_thread *); -}; -struct uwsgi_thread *uwsgi_thread_new(void (*)(struct uwsgi_thread *)); + struct uwsgi_thread { + pthread_t tid; + pthread_attr_t tattr; + int pipe[2]; + int queue; + ssize_t rlen; + void *data; + char *buf; + off_t pos; + size_t len; + uint64_t custom0; + uint64_t custom1; + uint64_t custom2; + uint64_t custom3; + // linked list for offloaded requests + struct uwsgi_offload_request *offload_requests_head; + struct uwsgi_offload_request *offload_requests_tail; + void (*func) (struct uwsgi_thread *); + }; + struct uwsgi_thread *uwsgi_thread_new(void (*)(struct uwsgi_thread *)); -struct uwsgi_offload_request { - // the request socket - int s; - // the peer - int fd; + struct uwsgi_offload_request { + // the request socket + int s; + // the peer + int fd; - // internal state - int status; + // internal state + int status; - off_t pos; - char *buf; - off_t buf_pos; + off_t pos; + char *buf; + off_t buf_pos; - size_t to_write; - size_t len; - size_t written; + size_t to_write; + size_t len; + size_t written; - // a uwsgi_buffer (will be destroyed at the end of the task) - struct uwsgi_buffer *ubuf; + // a uwsgi_buffer (will be destroyed at the end of the task) + struct uwsgi_buffer *ubuf; - int (*func)(struct uwsgi_thread *, struct uwsgi_offload_request *, int); + int (*func) (struct uwsgi_thread *, struct uwsgi_offload_request *, int); - struct uwsgi_offload_request *prev; - struct uwsgi_offload_request *next; -}; + struct uwsgi_offload_request *prev; + struct uwsgi_offload_request *next; + }; -struct uwsgi_thread *uwsgi_offload_thread_start(void); -int uwsgi_offload_request_sendfile_do(struct wsgi_request *, char *, int, size_t); -int uwsgi_offload_request_net_do(struct wsgi_request *, char *, struct uwsgi_buffer *); + struct uwsgi_thread *uwsgi_offload_thread_start(void); + int uwsgi_offload_request_sendfile_do(struct wsgi_request *, char *, int, size_t); + int uwsgi_offload_request_net_do(struct wsgi_request *, char *, struct uwsgi_buffer *); -void uwsgi_subscription_set_algo(char *); -struct uwsgi_subscribe_slot **uwsgi_subscription_init_ht(void); + void uwsgi_subscription_set_algo(char *); + struct uwsgi_subscribe_slot **uwsgi_subscription_init_ht(void); -int uwsgi_check_pidfile(char *); -void uwsgi_daemons_spawn_all(); + int uwsgi_check_pidfile(char *); + void uwsgi_daemons_spawn_all(); -int uwsgi_daemon_check_pid_death(pid_t); -int uwsgi_daemon_check_pid_reload(pid_t); -void uwsgi_daemons_smart_check(); + int uwsgi_daemon_check_pid_death(pid_t); + int uwsgi_daemon_check_pid_reload(pid_t); + void uwsgi_daemons_smart_check(); -void uwsgi_setup_thread_req(long, struct wsgi_request *); -void uwsgi_loop_cores_run(void *(*)(void *)); + void uwsgi_setup_thread_req(long, struct wsgi_request *); + void uwsgi_loop_cores_run(void *(*)(void *)); #ifdef UWSGI_MATHEVAL -double uwsgi_matheval(char *); -char *uwsgi_matheval_str(char *); + double uwsgi_matheval(char *); + char *uwsgi_matheval_str(char *); #endif -int uwsgi_kvlist_parse(char *, size_t, char, char, ...); -int uwsgi_send_http_stats(int); + int uwsgi_kvlist_parse(char *, size_t, char, char, ...); + int uwsgi_send_http_stats(int); -ssize_t uwsgi_simple_request_read(struct wsgi_request *, char *, size_t); -int uwsgi_plugin_modifier1(char *); + ssize_t uwsgi_simple_request_read(struct wsgi_request *, char *, size_t); + int uwsgi_plugin_modifier1(char *); -void uwsgi_cache_wlock(struct uwsgi_cache *); -void uwsgi_cache_rlock(struct uwsgi_cache *); -void uwsgi_cache_rwunlock(struct uwsgi_cache *); + void uwsgi_cache_wlock(struct uwsgi_cache *); + void uwsgi_cache_rlock(struct uwsgi_cache *); + void uwsgi_cache_rwunlock(struct uwsgi_cache *); -void *cache_udp_server_loop(void *); + void *cache_udp_server_loop(void *); -void uwsgi_user_lock(int); -void uwsgi_user_unlock(int); + void uwsgi_user_lock(int); + void uwsgi_user_unlock(int); -void simple_loop_run_int(int); + void simple_loop_run_int(int); -char *uwsgi_strip(char *); + char *uwsgi_strip(char *); #ifdef UWSGI_SSL -void uwsgi_opt_legion(char *, char *, void *); -void uwsgi_opt_legion_node(char *, char *, void *); -void uwsgi_opt_legion_quorum(char *, char *, void *); -void uwsgi_opt_legion_hook(char *, char *, void *); -void uwsgi_legion_add(struct uwsgi_legion *); -char *uwsgi_ssl_rand(size_t); -void uwsgi_start_legions(void); -int uwsgi_legion_announce(struct uwsgi_legion *); -struct uwsgi_legion_action *uwsgi_legion_action_get(char *); -void uwsgi_legion_action_register(char *, int (*)(struct uwsgi_legion *, char *)); -int uwsgi_legion_action_call(char *, struct uwsgi_legion *, struct uwsgi_string_list *); -void uwsgi_legion_atexit(void); + void uwsgi_opt_legion(char *, char *, void *); + void uwsgi_opt_legion_node(char *, char *, void *); + void uwsgi_opt_legion_quorum(char *, char *, void *); + void uwsgi_opt_legion_hook(char *, char *, void *); + void uwsgi_legion_add(struct uwsgi_legion *); + char *uwsgi_ssl_rand(size_t); + void uwsgi_start_legions(void); + int uwsgi_legion_announce(struct uwsgi_legion *); + struct uwsgi_legion_action *uwsgi_legion_action_get(char *); + void uwsgi_legion_action_register(char *, int (*)(struct uwsgi_legion *, char *)); + int uwsgi_legion_action_call(char *, struct uwsgi_legion *, struct uwsgi_string_list *); + void uwsgi_legion_atexit(void); #endif -struct uwsgi_option *uwsgi_opt_get(char *); -int uwsgi_valid_fd(int); -void uwsgi_close_all_fds(void); + struct uwsgi_option *uwsgi_opt_get(char *); + int uwsgi_valid_fd(int); + void uwsgi_close_all_fds(void); -int check_hex(char *, int); + int check_hex(char *, int); void uwsgi_uuid(char *); int uwsgi_uuid_cmp(char *, char *); @@ -3798,10 +3685,8 @@ void uwsgi_subscribe_all(uint8_t, int); #define uwsgi_unsubscribe_all() uwsgi_subscribe_all(1, 1) void uwsgi_websockets_init(void); -ssize_t uwsgi_websocket_send(struct wsgi_request *, char *, size_t); +int uwsgi_websocket_send(struct wsgi_request *, char *, size_t); struct uwsgi_buffer *uwsgi_websocket_recv(struct wsgi_request *); -ssize_t uwsgi_websockets_simple_send(struct wsgi_request *, struct uwsgi_buffer *); -ssize_t uwsgi_websockets_simple_recv(struct wsgi_request *); uint16_t uwsgi_be16(char *); uint32_t uwsgi_be32(char *); @@ -3809,17 +3694,6 @@ uint64_t uwsgi_be64(char *); int uwsgi_websockets_pong(struct wsgi_request *); -void uwsgi_channels_init(void); -struct uwsgi_channel *uwsgi_channel_new(char *); -int uwsgi_channel_send(struct uwsgi_channel *, char *msg, size_t len); -void uwsgi_channel_join(struct wsgi_request *, struct uwsgi_channel *, uint8_t); -void uwsgi_channel_leave(struct wsgi_request *, struct uwsgi_channel *); -void *uwsgi_channels_loop(void *); -struct uwsgi_channel *uwsgi_channel_by_name(char *name); -void uwsgi_channels_leave(struct wsgi_request *); -struct uwsgi_buffer *uwsgi_channel_recv(struct wsgi_request *, struct uwsgi_channel *, int); -void uwsgi_channels_reset_worker_subscriptions(int); - int uwsgi_websocket_handshake(struct wsgi_request *, char *, uint16_t, char *, uint16_t); int uwsgi_response_prepare_headers(struct wsgi_request *, char *, uint16_t); @@ -3829,8 +3703,12 @@ int uwsgi_response_sendfile_do(struct wsgi_request *, int, size_t, size_t); struct uwsgi_buffer *uwsgi_proto_base_add_header(struct wsgi_request *, char *, uint16_t, char *, uint16_t); -int uwsgi_simple_wait_write_hook(struct wsgi_request *); +int uwsgi_simple_wait_write_hook(int, int); +int uwsgi_simple_wait_read_hook(int, int); int uwsgi_response_write_headers_do(struct wsgi_request *); +char *uwsgi_request_body_read(struct wsgi_request *, ssize_t , ssize_t *); +char *uwsgi_request_body_readline(struct wsgi_request *, ssize_t, ssize_t *); +void uwsgi_request_body_seek(struct wsgi_request *, off_t); struct uwsgi_buffer *uwsgi_proto_base_prepare_headers(struct wsgi_request *, char *, uint16_t); int uwsgi_response_write_body_do(struct wsgi_request *, char *, size_t); @@ -3846,6 +3724,10 @@ int uwsgi_stats_dump_vars(struct uwsgi_stats *, struct uwsgi_core *); int uwsgi_contains_n(char *, size_t, char *, size_t); +char *uwsgi_upload_progress_create(struct wsgi_request *, int *); +int uwsgi_upload_progress_update(struct wsgi_request *, int, size_t); +void uwsgi_upload_progress_destroy(char *, int); + #define uwsgi_response_add_connection_close(x) uwsgi_response_add_header(x, "Connection", 10, "close", 5) #define uwsgi_response_add_content_type(x, y, z) uwsgi_response_add_header(x, "Content-Type", 12, y, z) @@ -3864,4 +3746,3 @@ int uwsgi_init(int, char **, char **); #ifdef __cplusplus } #endif - diff --git a/uwsgiconfig.py b/uwsgiconfig.py index 11a6bc2b..abc82f77 100644 --- a/uwsgiconfig.py +++ b/uwsgiconfig.py @@ -1,6 +1,6 @@ # uWSGI build system -uwsgi_version = '1.5-dev' +uwsgi_version = '1.9-dev' import os import re @@ -60,28 +60,21 @@ report['locking'] = False report['event'] = False report['timer'] = False report['filemonitor'] = False -report['udp'] = False report['pcre'] = False report['matheval'] = False report['routing'] = False report['alarm'] = False report['capabilities'] = False -report['async'] = False -report['minterpreters'] = False report['ini'] = False report['yaml'] = False report['json'] = False report['ldap'] = False report['ssl'] = False report['zeromq'] = False -report['snmp'] = False -report['threading'] = False report['xml'] = False report['sqlite3'] = False -report['spooler'] = False report['debug'] = False report['plugin_dir'] = False -report['ipv6'] = False report['zlib'] = False compile_queue = None @@ -453,11 +446,11 @@ class uConf(object): self.config.read(filename) self.gcc_list = ['core/utils', 'core/protocol', 'core/socket', 'core/logging', 'core/master', 'core/master_utils', 'core/emperor', - 'core/notify', 'core/mule', 'core/subscription', 'core/stats', 'core/sendfile', - 'core/offload', 'core/io', 'core/static', 'core/websockets', 'core/channels', - 'core/setup_utils', 'core/clock', 'core/init', 'core/buffer', 'core/writer', + 'core/notify', 'core/mule', 'core/subscription', 'core/stats', 'core/sendfile', 'core/async', + 'core/offload', 'core/io', 'core/static', 'core/websockets', 'core/spooler', 'core/snmp', + 'core/setup_utils', 'core/clock', 'core/init', 'core/buffer', 'core/reader', 'core/writer', 'core/plugins', 'core/lock', 'core/cache', 'core/daemons', 'core/errors', 'core/hash', - 'core/queue', 'core/event', 'core/signal', 'core/cluster', 'core/strings', + 'core/queue', 'core/event', 'core/signal', 'core/strings', 'core/progress', 'core/rpc', 'core/gateway', 'core/loop', 'core/rb_timers', 'core/uwsgi'] # add protocols self.gcc_list.append('proto/base') @@ -778,17 +771,6 @@ class uConf(object): self.ldflags.append('-dynamiclib') self.ldflags.append('-undefined dynamic_lookup') - if self.get('embedded'): - self.cflags.append('-DUWSGI_EMBEDDED') - - if self.get('udp'): - report['udp'] = True - self.cflags.append("-DUWSGI_UDP") - - if self.get('ipv6'): - report['ipv6'] = True - self.cflags.append("-DUWSGI_IPV6") - if self.get('blacklist'): self.cflags.append('-DUWSGI_BLACKLIST="\\"%s\\""' % self.get('blacklist')) @@ -942,22 +924,6 @@ class uConf(object): self.cflags.append('-DUWSGI_VERSION_REVISION="' + uver_rev + '"') self.cflags.append('-DUWSGI_VERSION_CUSTOM="\\"' + uver_custom + '\\""') - - - if self.get('async'): - self.cflags.append("-DUWSGI_ASYNC") - self.gcc_list.append('core/async') - report['async'] = True - - if self.get('multicast'): - self.depends_on('multicast', ['udp']) - self.cflags.append("-DUWSGI_MULTICAST") - report['multicast'] = True - - if self.get('minterpreters'): - self.cflags.append("-DUWSGI_MINTERPRETERS") - report['minterpreters'] = True - if self.get('ini'): self.cflags.append("-DUWSGI_INI") self.gcc_list.append('core/ini') @@ -1044,16 +1010,6 @@ class uConf(object): self.libs.append('-lzmq') report['zeromq'] = True - if self.get('snmp'): - self.depends_on("snmp", ['udp']) - self.cflags.append("-DUWSGI_SNMP") - self.gcc_list.append('core/snmp') - report['snmp'] = True - - if self.get('threading'): - self.cflags.append("-DUWSGI_THREADING") - report['threading'] = True - if self.get('xml'): if self.get('xml') == 'auto': xmlconf = spcall('xml2-config --libs') @@ -1109,12 +1065,6 @@ class uConf(object): self.cflags.append('-DUWSGI_PLUGIN_DIR=\\"%s\\"' % self.get('plugin_dir')) report['plugin_dir'] = self.get('plugin_dir') - if self.get('spooler'): - self.depends_on("spooler", ['embedded']) - self.cflags.append("-DUWSGI_SPOOLER") - self.gcc_list.append('core/spooler') - report['spooler'] = True - if self.get('debug'): self.cflags.append("-DUWSGI_DEBUG") self.cflags.append("-g")