From e0882ed8df90e79ccf33f35b764c92ca383b144a Mon Sep 17 00:00:00 2001 From: "roberto@sirius" Date: Sun, 7 Feb 2010 23:06:24 +0100 Subject: [PATCH] big update: hooks and plugins --- base.mk | 28 +- config | 3 + plugins/example/example_plugin.c | 18 + snmp.c | 436 ++++ socket.c | 94 + spooler.c | 340 +-- testapp.py | 6 +- uwsgi.c | 3315 +++++++++++++----------------- uwsgi.h | 403 ++-- uwsgi_handlers.c | 117 ++ uwsgi_pymodule.c | 64 +- wsgi_handlers.c | 483 +++++ 12 files changed, 3077 insertions(+), 2230 deletions(-) create mode 100644 config create mode 100644 plugins/example/example_plugin.c create mode 100644 snmp.c create mode 100644 uwsgi_handlers.c create mode 100644 wsgi_handlers.c diff --git a/base.mk b/base.mk index f923b066..34ffb89f 100644 --- a/base.mk +++ b/base.mk @@ -1,7 +1,20 @@ +include config + +UWSGI_CFLAGS = "" +UWSGI_LD_FLAGS = "" + +ifneq ($(SCTP), 'no') + UWSGI_CFLAGS = -DSCTP + UWSGI_LD_FLAGS = -lsctp +endif + +CFLAGS := $(CFLAGS) $(UWSGI_CFLAGS) +LD_FLAGS := $(LD_FLAGS) $(UWSGI_LD_FLAGS) + all: clean uwsgi -uwsgi: utils.o protocol.o socket.o pymodule.o spooler.o logging.o main.o - $(CC) $(LD_FLAGS) utils.o protocol.o socket.o spooler.o logging.o pymodule.o main.o -o $(PROGRAM) +uwsgi: utils.o protocol.o socket.o pymodule.o spooler.o logging.o snmp.o wsgihandlers.o basehandlers.o main.o + $(CC) $(LD_FLAGS) utils.o protocol.o socket.o spooler.o logging.o snmp.o pymodule.o wsgihandlers.o basehandlers.o main.o -o $(PROGRAM) utils.o: utils.c $(CC) -c $(CFLAGS) utils.c @@ -18,11 +31,20 @@ spooler.o: spooler.c logging.o: logging.c $(CC) -c $(CFLAGS) logging.c +snmp.o: snmp.c + $(CC) -c $(CFLAGS) snmp.c + pymodule.o: uwsgi_pymodule.c $(CC) -c $(CFLAGS) -o pymodule.o uwsgi_pymodule.c +basehandlers.o: uwsgi_handlers.c + $(CC) -c $(CFLAGS) -o basehandlers.o uwsgi_handlers.c + +wsgihandlers.o: wsgi_handlers.c + $(CC) -c $(CFLAGS) -o wsgihandlers.o wsgi_handlers.c + main.o: uwsgi.c $(CC) -c $(CFLAGS) -o main.o uwsgi.c clean: - rm -f utils.o protocol.o socket.o pymodule.o spooler.o logging.o main.o + rm -f utils.o protocol.o socket.o pymodule.o spooler.o logging.o snmp.o wsgihandlers.o basehandlers.o main.o diff --git a/config b/config new file mode 100644 index 00000000..a9e2d112 --- /dev/null +++ b/config @@ -0,0 +1,3 @@ +XML=no +SNMP=no +SCTP=yes diff --git a/plugins/example/example_plugin.c b/plugins/example/example_plugin.c new file mode 100644 index 00000000..e43bd4de --- /dev/null +++ b/plugins/example/example_plugin.c @@ -0,0 +1,18 @@ +#include "../../uwsgi.h" + +void uwsgi_init(struct uwsgi_server *uwsgi){ + fprintf(stderr,"i am the example plugin initialization function\n"); +} + +int uwsgi_request(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req, char *buffer) { + char *http = "HTTP/1.1 200 Ok\r\nContent-type: text/html\r\n\r\n

Hello World

" ; + wsgi_req->response_size += write(uwsgi->poll.fd, http, strlen(http)); + + return 0; +} + + +int uwsgi_after_request(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req, char *buffer) { + fprintf(stderr,"i am the example plugin after request function\n"); + return 0; +} diff --git a/snmp.c b/snmp.c new file mode 100644 index 00000000..77fc8187 --- /dev/null +++ b/snmp.c @@ -0,0 +1,436 @@ +#ifndef ROCK_SOLID +#ifndef UNBIT + +#include "uwsgi.h" + +extern struct uwsgi_server uwsgi; + +#define SNMP_SEQUENCE 0x30 +#define SNMP_INTEGER 0x02 +#define SNMP_STRING 0x04 +#define SNMP_GET 0xA0 +#define SNMP_OID 0x06 + +/* 1.3.6.1.4.1.35156.17.X.X */ +#define SNMP_UWSGI_BASE "\x2B\x06\x01\x04\x01\x82\x92\x54\x11" + +static int get_snmp_length(uint8_t *, uint16_t *); +static int get_snmp_integer(uint8_t *, uint64_t *); +static int get_snmp_string(uint8_t *, uint16_t *, char **); + +static uint64_t get_uwsgi_snmp_value(uint64_t); +static uint64_t get_uwsgi_custom_snmp_value(uint64_t); + + +struct uwsgi_oid { + uint64_t oid1; + uint64_t oid2; + uint64_t value; + uint64_t valuesize; + uint16_t size; + uint8_t first_byte ; +}; + +static int build_snmp_response(struct uwsgi_oid*, int, uint8_t *, int, uint64_t, uint64_t, char *, uint16_t); + +void manage_snmp(int fd, uint8_t *buffer, int size, struct sockaddr_in *client_addr) { + uint16_t asnlen; + uint16_t oidlen; + uint64_t oid_part[2]; + uint8_t what_oid_part ; + uint16_t slen; + int ptrdelta ; + uint8_t *ptr = buffer ; + + struct uwsgi_oid output_oid[10]; + int how_many_output_oid = 0; + + uint64_t snmp_int ; + uint64_t snmp_version ; + uint64_t request_id ; + char *snmp_str ; + + // skip first byte (already parsed) + ptr++; + + // check total sequence size + + ptrdelta = get_snmp_length(ptr, &asnlen); + + if (ptrdelta <= 0) + return; + + if (asnlen != size-(ptrdelta+1)) + return; + + ptr += ptrdelta ; + + // check snmp version + if (*ptr != SNMP_INTEGER) + return; + + ptr++; + + ptrdelta = get_snmp_integer(ptr, &snmp_version); + + if (ptrdelta <= 0) + return; + + if (snmp_version > 2) + return; + + if (ptr+ptrdelta >= buffer+size) + return; + + ptr += ptrdelta ; + + // check for community string (this must be set from the python vm using uwsgi.community) + if (*ptr != SNMP_STRING) + return; + + ptr++; + + ptrdelta = get_snmp_string(ptr, &slen, &snmp_str); + + if (ptrdelta <= 0) + return; + + + if (ptr+ptrdelta >= buffer+size) + return; + + // TODO check for community string + + ptr += ptrdelta ; + + // check for get request + if (*ptr != SNMP_GET) + return; + + ptr++; + + ptrdelta = get_snmp_length(ptr, &asnlen); + + if (ptrdelta <= 0) + return; + + if (ptr+ptrdelta >= buffer+size) + return; + + if (asnlen != ( (buffer+size) - (ptr+ptrdelta) )) + return; + ptr += ptrdelta ; + + // get request_id + if (*ptr != SNMP_INTEGER) + return; + ptr++; ptrdelta = get_snmp_integer(ptr, &request_id); + if (ptrdelta <= 0) + return; + if (ptr+ptrdelta >= buffer+size) + return; + ptr += ptrdelta ; + + // get error + if (*ptr != SNMP_INTEGER) + return; + ptr++; ptrdelta = get_snmp_integer(ptr, &snmp_int); + if (ptrdelta <= 0) + return; + if (ptr+ptrdelta >= buffer+size) + return; + if (snmp_int != 0) + return; + ptr += ptrdelta ; + + // get index + if (*ptr != SNMP_INTEGER) + return; + ptr++; ptrdelta = get_snmp_integer(ptr, &snmp_int); + if (ptrdelta <= 0) + return; + if (ptr+ptrdelta >= buffer+size) + return; + if (snmp_int != 0) + return; + ptr += ptrdelta ; + + // check for sequence + if (*ptr != SNMP_SEQUENCE) + return; + + ptr++; + ptrdelta = get_snmp_length(ptr, &asnlen); + + if (ptrdelta <= 0) + return; + + if (ptr+ptrdelta >= buffer+size) + return; + + if (asnlen != ( (buffer+size) - (ptr+ptrdelta) )) + return; + ptr += ptrdelta ; + + // now the interesting stuff: OID management + while(ptr < buffer+size && how_many_output_oid < 10) { + if (*ptr != SNMP_SEQUENCE) + return; + ptr++; + ptrdelta = get_snmp_length(ptr, &asnlen); + if (ptrdelta <= 0) + return; + + if (ptr+ptrdelta >= buffer+size) + return; + + // check for normal OID uWSGI size: |1.3|.6|.1|.4|.1.|35156|.17|.1/2|.x| + OID_NULL + if (asnlen < 13) + return; + + ptr += ptrdelta ; + // is it an OID ? + if (*ptr != SNMP_OID) + return; + + ptr++; + + ptrdelta = get_snmp_length(ptr, &oidlen); + if (ptrdelta <= 0) + return; + + if (ptr+ptrdelta >= buffer+size) + return; + if (oidlen > (asnlen-ptrdelta-2)) + return; + + ptr += ptrdelta ; + + // used by the output sender + output_oid[how_many_output_oid].size = oidlen ; + + // and now parse the OID !!! + if (strncmp((char *) ptr, SNMP_UWSGI_BASE, 9)) + return; + ptr+=9; + + // get the next two oid number + oidlen = oidlen - 9 ; + what_oid_part = 0; + while(oidlen > 0 && what_oid_part < 2) { + oid_part[what_oid_part] = 0 ; + while( (*ptr & 0x80) && oidlen > 0) { + oid_part[what_oid_part] += (oid_part[what_oid_part] * 0x80) + (*ptr^0x80) ; + ptr++; + oidlen--; + } + oid_part[what_oid_part] = (oid_part[what_oid_part] * 0x80) + *ptr; + ptr++; + oidlen--; + what_oid_part++; + } + + + if (oid_part[1] > 100) + return; + + // check for null + if (strncmp((char *)ptr, "\x05\x00", 2)) + return; + + + ptr+=2; + + if (oid_part[0] == 1) { + output_oid[how_many_output_oid].oid1 = oid_part[0] ; + output_oid[how_many_output_oid].oid2 = oid_part[1] ; + output_oid[how_many_output_oid].value = get_uwsgi_snmp_value(oid_part[1]); + } + else if (oid_part[0] == 2) { + output_oid[how_many_output_oid].oid1 = oid_part[0] ; + output_oid[how_many_output_oid].oid2 = oid_part[1] ; + output_oid[how_many_output_oid].value = get_uwsgi_custom_snmp_value(oid_part[1]); + } + else { + return; + + } + how_many_output_oid++; + + } + + + size = build_snmp_response(output_oid, how_many_output_oid, buffer, size, request_id, snmp_version, snmp_str, slen); + + if (size > 0) { + if (sendto(fd, buffer, size, 0, ( struct sockaddr * ) client_addr, sizeof(struct sockaddr_in)) < 0) { + perror("sendto()"); + } + } + +} + +static uint64_t get_uwsgi_snmp_value(uint64_t val) { + return val * 300 ; +} + +static uint64_t get_uwsgi_custom_snmp_value(uint64_t val) { + return val * 260 ; +} + +static int get_snmp_string(uint8_t *ptr, uint16_t *strlen, char **str) { + int delta; + + delta = get_snmp_length(ptr, strlen) ; + + if (*strlen > 0) { + *str = (char *) ptr+delta ; + return delta + *strlen ; + } + + return -1 ; +} + +static int get_snmp_integer(uint8_t *ptr, uint64_t *val) { + uint16_t tlen ; + int delta,i; + + delta = get_snmp_length(ptr, &tlen) ; + + if (tlen > 0) { + +#ifdef __BIG_ENDIAN__ + for(i=0;i=0;i--) { +#endif + val[i] = ptr[1+i]; + } + + return tlen + delta ; + } + + return -1 ; +} + + + +static int get_snmp_length(uint8_t *ptr, uint16_t *len) { + char tlen ; + int i ; + + char *blen = (char *) len ; + + *len = *ptr ; + + if (*len > 127) { + tlen = *len & 0x7f ; + if (tlen > 2) { + fprintf(stderr,"unsupported snmp length\n"); + return -1 ; + } + +#ifdef __BIG_ENDIAN__ + for(i=0;i=0;i--) { + blen[i] = ptr[1+((tlen-1)-i)]; +#endif + } + + return tlen+1 ; + } + else { + return 1 ; + } + +} + + +static int build_snmp_response(struct uwsgi_oid* output_oid, int num_output_oid, uint8_t *buffer, int size, uint64_t request_id, uint64_t version, char *community, uint16_t community_len) { + + static char *snmp_buffer = NULL ; + int i ; + int tmpptr = 0 ; + + // calc the new size without null values + uint64_t new_size = size - (2*num_output_oid) ; + uint16_t seq_size ; + + + if (snmp_buffer == NULL) { + snmp_buffer = malloc(uwsgi.buffer_size); + if (!snmp_buffer) { + perror("malloc()"); + return -1 ; + } + } + + for(i=0;i 127) { + output_oid[i].valuesize++; + output_oid[i].first_byte = 0x81 ; + if (output_oid[i].value > 0xFF) { + output_oid[i].valuesize++; + output_oid[i].first_byte = 0x82 ; + } + } + new_size += output_oid[i].valuesize ; + } + + fprintf(stderr,"the SNMP output size is : %llu\n", new_size); + + if (new_size > uwsgi.buffer_size || new_size > 0xFFFF) + return -1; + + seq_size = (uint16_t) new_size ; + + snmp_buffer[0] = buffer[0]; + if (seq_size > 127) { + if (seq_size > 0xff) { + snmp_buffer[1] = 0x81 ; + snmp_buffer[2] = (uint8_t) seq_size ; + tmpptr = 3 ; + } + else { + snmp_buffer[1] = 0x82 ; +#ifdef __BIG_ENDIAN__ + snmp_buffer[2] = ((uint8_t *) &seq_size)[0]; + snmp_buffer[3] = ((uint8_t *) &seq_size)[1]; +#else + snmp_buffer[2] = ((uint8_t *) &seq_size)[1]; + snmp_buffer[3] = ((uint8_t *) &seq_size)[0]; +#endif + tmpptr = 4 ; + + } + } + else { + tmpptr = 2 ; + snmp_buffer[1] = (uint8_t) seq_size ; + } + +/* + snmp_buffer[tmpptr] = // copy version + snmp_buffer[tmpptr] = // copy community + snmp_buffer[tmpptr] = // set response + snmp_buffer[tmpptr] = // sequence size (!!!) + snmp_buffer[tmpptr] = // request_id + snmp_buffer[tmpptr] = // error + snmp_buffer[tmpptr] = // index + + snmp_buffer[tmpptr] = // main sequence + + snmp_buffer[tmpptr] = // OID cycle -> sequence + oid + value +*/ + + return -1 ; + +} + + + +#endif +#endif diff --git a/socket.c b/socket.c index 1bbe51c6..a277c043 100644 --- a/socket.c +++ b/socket.c @@ -61,6 +61,100 @@ int bind_to_unix(char *socket_name, int listen_queue, int chmod_socket, int abst return serverfd; } +#ifdef SCTP + +#define MAX_SCTP_ADDRESS 4 +/* sctp address format sctp:127.0.0.1,192.168.0.17:3031 */ +int bind_to_sctp(char *socket_name, int listen_queue, char *sctp_port) { + int serverfd; + struct sockaddr_in uws_addr[MAX_SCTP_ADDRESS]; + int num_ip = 0 ; + + struct sctp_initmsg sctp_im ; + + + sctp_port[0] = 0 ; + memset(uws_addr, 0, sizeof(struct sockaddr_in)*MAX_SCTP_ADDRESS); + memset(&sctp_im, 0, sizeof(struct sctp_initmsg)); + + while(socket_name != NULL && num_ip < MAX_SCTP_ADDRESS) { + char *ap; + while( (ap = strsep(&socket_name, ",")) != NULL) { + if (*ap != '\0') { + uws_addr[num_ip].sin_family = AF_INET; + uws_addr[num_ip].sin_port = htons(atoi(sctp_port+1)); + uws_addr[num_ip].sin_addr.s_addr = inet_addr(ap); + num_ip++; + } + } + } + + serverfd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP); + if (serverfd < 0) { + perror("socket()"); + exit(1); + } + + fprintf(stderr,"binding on %d SCTP interfaces on port: %d\n", num_ip, ntohs(uws_addr[0].sin_port)); + + + if(sctp_bindx(serverfd, (struct sockaddr *) uws_addr, num_ip, SCTP_BINDX_ADD_ADDR) != 0) { + perror("sctp_bindx()"); + exit(1); + } + + sctp_im.sinit_max_instreams = 0xFFFF ; + sctp_im.sinit_num_ostreams = 0xFFFF ; + + if (setsockopt(serverfd, IPPROTO_SCTP, SCTP_INITMSG, &sctp_im, sizeof(sctp_im))) { + perror("setsockopt()"); + } + + if (listen(serverfd, listen_queue) != 0) { + perror("listen()"); + exit(1); + } + + return serverfd; +} +#endif + +#ifndef ROCK_SOLID +#ifndef UNBIT +int bind_to_udp(char *socket_name) { + int serverfd ; + struct sockaddr_in uws_addr; + char *udp_port ; + + udp_port = strchr(socket_name, ':'); + if (udp_port == NULL) { + return -1 ; + } + + udp_port[0] = 0 ; + memset(&uws_addr, 0, sizeof(struct sockaddr_in)); + uws_addr.sin_family = AF_INET; + uws_addr.sin_port = htons(atoi(udp_port+1)); + uws_addr.sin_addr.s_addr = inet_addr(socket_name); + + serverfd = socket(AF_INET,SOCK_DGRAM,0); + if (serverfd < 0) { + perror("socket()"); + return -1 ; + } + + if (bind(serverfd, (struct sockaddr *) &uws_addr, sizeof(uws_addr) ) != 0) { + perror("bind()"); + close(serverfd); + return -1 ; + } + + return serverfd; + +} +#endif +#endif + int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) { int serverfd; diff --git a/spooler.c b/spooler.c index 1f8f7ff5..ad2f4563 100644 --- a/spooler.c +++ b/spooler.c @@ -7,285 +7,331 @@ extern char *spool_dir; struct uwsgi_packet_header { - uint8_t modifier1; - uint16_t datasize; - uint8_t modifier2; + uint8_t modifier1; + uint16_t datasize; + uint8_t modifier2; }; -int spool_request(char *filename, int rn, char *buffer, int size) { +int spool_request (char *filename, int rn, char *buffer, int size) { - char hostname[256+1]; - struct timeval tv; + char hostname[256 + 1]; + struct timeval tv; int fd; - struct uwsgi_packet_header uh ; + struct uwsgi_packet_header uh; - if (gethostname(hostname,256)) { - perror("gethostname()"); - return 0 ; - } - - gettimeofday(&tv, NULL); - - hostname[256] = 0 ; - - if (snprintf(filename,1024,"%s/uwsgi_spoolfile_on_%s_%d_%d_%llu_%llu", spool_dir, hostname, getpid(), rn, (unsigned long long) tv.tv_sec, (unsigned long long) tv.tv_usec ) <= 0) { + if (gethostname (hostname, 256)) { + perror ("gethostname()"); return 0; } - fd = open(filename, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR); + gettimeofday (&tv, NULL); + + hostname[256] = 0; + + if (snprintf (filename, 1024, "%s/uwsgi_spoolfile_on_%s_%d_%d_%llu_%llu", spool_dir, hostname, getpid (), rn, (unsigned long long) tv.tv_sec, (unsigned long long) tv.tv_usec) <= 0) { + return 0; + } + + fd = open (filename, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR); if (fd < 0) { - perror("open()"); - return 0 ; + perror ("open()"); + return 0; } #ifdef __sun__ - if (lockf(fd, F_LOCK, 0)) { - perror("lockf()"); + if (lockf (fd, F_LOCK, 0)) { + perror ("lockf()"); #else - if (flock(fd, LOCK_EX)) { - perror("flock()"); + if (flock (fd, LOCK_EX)) { + perror ("flock()"); #endif - close(fd); + close (fd); return 0; } - uh.modifier1 = 17 ; - uh.modifier2 = 0 ; - uh.datasize = (uint16_t) size ; + uh.modifier1 = 17; + uh.modifier2 = 0; + uh.datasize = (uint16_t) size; #ifdef __BIG_ENDIAN__ - uh.datasize= uwsgi_swap16(uh.datasize); + uh.datasize = uwsgi_swap16 (uh.datasize); #endif - if (write(fd, &uh, 4) != 4) { - goto clear ; + if (write (fd, &uh, 4) != 4) { + goto clear; } - if (write(fd, buffer, size) != size) { - goto clear ; + if (write (fd, buffer, size) != size) { + goto clear; } - close(fd); + close (fd); - fprintf(stderr,"written %d bytes to spool file %s.\n",size + 4, filename); + fprintf (stderr, "written %d bytes to spool file %s.\n", size + 4, filename); return 1; - -clear: - perror("write()"); - unlink(filename); - close(fd); + clear: + + perror ("write()"); + unlink (filename); + close (fd); return 0; } -void spooler(PyObject *uwsgi_module) { - DIR *sdir ; +void spooler (PyObject * uwsgi_module) { + DIR *sdir; struct dirent *dp; - PyObject *uwsgi_module_dict, *spooler_callable, *spool_result, *spool_tuple, *spool_env ; - int spool_fd ; - uint16_t uwstrlen ; + PyObject *uwsgi_module_dict, *spooler_callable, *spool_result, *spool_tuple, *spool_env; + int spool_fd; + uint16_t uwstrlen; int rlen = 0; - int datasize ; + int datasize; - struct uwsgi_packet_header uh ; + struct uwsgi_packet_header uh; char *key; char *val; - uwsgi_module_dict = PyModule_GetDict(uwsgi_module); - if (!uwsgi_module_dict) { - fprintf(stderr,"could not get uwsgi module __dict__\n"); - exit(1); - } + uwsgi_module_dict = PyModule_GetDict (uwsgi_module); + if (!uwsgi_module_dict) { + fprintf (stderr, "could not get uwsgi module __dict__\n"); + exit (1); + } - spool_tuple = PyTuple_New(1); + spool_tuple = PyTuple_New (1); if (!spool_tuple) { - fprintf(stderr,"could not create spooler tuple.\n"); - exit(1); + fprintf (stderr, "could not create spooler tuple.\n"); + exit (1); } - spool_env = PyDict_New(); + spool_env = PyDict_New (); if (!spool_env) { - fprintf(stderr,"could not create spooler env.\n"); - exit(1); + fprintf (stderr, "could not create spooler env.\n"); + exit (1); } - if (PyTuple_SetItem(spool_tuple, 0, spool_env)) { - PyErr_Print(); - exit(1); - } - - if (chdir(spool_dir)) { - perror("chdir()"); - exit(1); + if (PyTuple_SetItem (spool_tuple, 0, spool_env)) { + PyErr_Print (); + exit (1); } - for(;;) { - sdir = opendir("."); + if (chdir (spool_dir)) { + perror ("chdir()"); + exit (1); + } + + for (;;) { + sdir = opendir ("."); if (sdir) { - while((dp = readdir(sdir)) != NULL) { + while ((dp = readdir (sdir)) != NULL) { #ifndef __sun__ - if (!strncmp("uwsgi_spoolfile_on_", dp->d_name, 19) && dp->d_type == DT_REG) { + if (!strncmp ("uwsgi_spoolfile_on_", dp->d_name, 19) && dp->d_type == DT_REG) { #else - if (!strncmp("uwsgi_spoolfile_on_", dp->d_name, 19)) { + if (!strncmp ("uwsgi_spoolfile_on_", dp->d_name, 19)) { struct stat sf_lstat; - if (lstat(dp->d_name, &sf_lstat)) { + if (lstat (dp->d_name, &sf_lstat)) { continue; } - if (!S_ISREG(sf_lstat.st_mode)) { + if (!S_ISREG (sf_lstat.st_mode)) { continue; } #endif - if (!access(dp->d_name, R_OK|W_OK)) { - fprintf(stderr,"managing spool request %s...\n", dp->d_name); + if (!access (dp->d_name, R_OK | W_OK)) { + fprintf (stderr, "managing spool request %s...\n", dp->d_name); - spooler_callable = PyDict_GetItemString(uwsgi_module_dict, "spooler"); + spooler_callable = PyDict_GetItemString (uwsgi_module_dict, "spooler"); if (!spooler_callable) { - fprintf(stderr,"you have to define uwsgi.spooler to use the spooler !!!\n"); + fprintf (stderr, "you have to define uwsgi.spooler to use the spooler !!!\n"); continue; } - spool_fd = open(dp->d_name, O_RDONLY) ; + spool_fd = open (dp->d_name, O_RDONLY); if (spool_fd < 0) { - perror("open()"); + perror ("open()"); continue; - } + } #ifdef __sun__ - if (lockf(spool_fd, F_LOCK, 0)) { - perror("lockf()"); + if (lockf (spool_fd, F_LOCK, 0)) { + perror ("lockf()"); #else - if (flock(spool_fd, LOCK_EX)) { - perror("flock()"); + if (flock (spool_fd, LOCK_EX)) { + perror ("flock()"); #endif - close(spool_fd); + close (spool_fd); continue; } - if (read(spool_fd, &uh, 4) != 4) { - perror("read()"); - close(spool_fd); + if (read (spool_fd, &uh, 4) != 4) { + perror ("read()"); + close (spool_fd); continue; } - #ifdef __BIG_ENDIAN__ - uh.datasize= uwsgi_swap16(uh.datasize); - #endif - - datasize = 0 ; +#ifdef __BIG_ENDIAN__ + uh.datasize = uwsgi_swap16 (uh.datasize); +#endif - while( datasize < uh.datasize) { - rlen = read(spool_fd, &uwstrlen, 2) ; + datasize = 0; + + while (datasize < uh.datasize) { + rlen = read (spool_fd, &uwstrlen, 2); if (rlen != 2) { - perror("read()"); - goto next_spool ; + perror ("read()"); + goto next_spool; } - datasize += rlen ; + datasize += rlen; key = NULL; val = NULL; if (uwstrlen > 0) { - key = malloc(uwstrlen+1); + key = malloc (uwstrlen + 1); if (!key) { - perror("malloc()"); + perror ("malloc()"); goto retry_later; } - rlen = read(spool_fd, key, uwstrlen); + rlen = read (spool_fd, key, uwstrlen); if (rlen != uwstrlen) { - perror("read()"); - free(key); + perror ("read()"); + free (key); goto next_spool; } - datasize += rlen ; - key[rlen] = 0 ; + datasize += rlen; + key[rlen] = 0; - rlen = read(spool_fd, &uwstrlen, 2); + rlen = read (spool_fd, &uwstrlen, 2); if (rlen != 2) { - perror("read()"); - free(key); + perror ("read()"); + free (key); goto next_spool; } - datasize += rlen ; + datasize += rlen; if (uwstrlen > 0) { - val = malloc(uwstrlen+1); + val = malloc (uwstrlen + 1); if (!val) { - free(key); - perror("malloc()"); + free (key); + perror ("malloc()"); goto retry_later; } - rlen = read(spool_fd, val, uwstrlen); + rlen = read (spool_fd, val, uwstrlen); if (rlen != uwstrlen) { - perror("read()"); - free(key); - goto next_spool; - } - datasize += rlen ; - val[rlen] = 0 ; + perror ("read()"); + free (key); + goto next_spool; + } + datasize += rlen; + val[rlen] = 0; /* ready to add item to the dict */ } - if (PyDict_SetItemString(spool_env, key, PyString_FromStringAndSize(val, uwstrlen))) { - PyErr_Print(); - free(key); - free(val); - goto retry_later ; + if (PyDict_SetItemString (spool_env, key, PyString_FromStringAndSize (val, uwstrlen))) { + PyErr_Print (); + free (key); + free (val); + goto retry_later; } - free(key); - free(val); + free (key); + free (val); } else { break; } } - - spool_result = PyEval_CallObject(spooler_callable, spool_tuple); + + spool_result = PyEval_CallObject (spooler_callable, spool_tuple); if (!spool_result) { - PyErr_Print(); - fprintf(stderr,"error detected. spool request canceled.\n"); + PyErr_Print (); + fprintf (stderr, "error detected. spool request canceled.\n"); goto next_spool; } - if (PyInt_Check(spool_result)) { - if (PyInt_AsLong(spool_result) == 17) { - Py_DECREF(spool_result); - fprintf(stderr,"retry this task later...\n"); + if (PyInt_Check (spool_result)) { + if (PyInt_AsLong (spool_result) == 17) { + Py_DECREF (spool_result); + fprintf (stderr, "retry this task later...\n"); goto retry_later; } } - Py_DECREF(spool_result); + Py_DECREF (spool_result); - fprintf(stderr,"done with task/spool %s\n", dp->d_name); -next_spool: + fprintf (stderr, "done with task/spool %s\n", dp->d_name); + next_spool: - if (unlink(dp->d_name)) { - perror("unlink"); - fprintf(stderr,"something horrible happened to the spooler. Better to kill it.\n"); - exit(1); + if (unlink (dp->d_name)) { + perror ("unlink"); + fprintf (stderr, "something horrible happened to the spooler. Better to kill it.\n"); + exit (1); } -retry_later: - PyDict_Clear(spool_env); - close(spool_fd); + retry_later: + PyDict_Clear (spool_env); + close (spool_fd); } } } - closedir(sdir); + closedir (sdir); } else { - perror("opendir()"); + perror ("opendir()"); } /* TODO spooler frequency user-configurable */ - sleep(5); + sleep (5); } } +int uwsgi_request_spooler (struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req, char *buffer) { + + int i; + char spool_filename[1024]; + + if (spool_dir == NULL) { + fprintf (stderr, "the spooler is inactive !!!...skip\n"); + wsgi_req->modifier = 255; + wsgi_req->size = 0; + wsgi_req->modifier_arg = 0; + i = write (uwsgi->poll.fd, wsgi_req, 4); + if (i != 4) { + perror ("write()"); + } + return -1 ; + } + + fprintf (stderr, "managing spool request...\n"); + i = spool_request (spool_filename, uwsgi->workers[0].requests + 1, buffer, wsgi_req->size); + wsgi_req->modifier = 255; + wsgi_req->size = 0; + if (i > 0) { + wsgi_req->modifier_arg = 1; + if (write (uwsgi->poll.fd, wsgi_req, 4) != 4) { + fprintf (stderr, "disconnected client, remove spool file.\n"); + /* client disconnect, remove spool file */ + if (unlink (spool_filename)) { + perror ("unlink()"); + fprintf (stderr, "something horrible happened !!! check your spooler ASAP !!!\n"); + goodbye_cruel_world (); + } + } + return 0; + } + else { + /* announce a failed spool request */ + wsgi_req->modifier_arg = 0; + i = write (uwsgi->poll.fd, wsgi_req, 4); + if (i != 4) { + perror ("write()"); + } + } + + return -1 ; +} + #endif diff --git a/testapp.py b/testapp.py index f69b8ee3..bfad7078 100644 --- a/testapp.py +++ b/testapp.py @@ -10,6 +10,7 @@ os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings' #import django.core.handlers.wsgi +uwsgi.load_plugin(0, "plugins/rack/rack_plugin.so") from threading import Thread @@ -89,8 +90,8 @@ def reload(env, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) - uwsgi.sorry_i_need_to_block() - time.sleep(1) + #uwsgi.sorry_i_need_to_block() + #time.sleep(1) #uwsgi.reload() @@ -154,6 +155,7 @@ def reload(env, start_response): #print w['running_time'] if w is not None: yield ''+ str(w['id']) +'' + str(w['pid']) + '' + str(w['in_request']) + '' + str(w['requests']) + '' + str(w['running_time']) + '' + str(w['vsz']) + '' + str(w['rss']) + '' + print w yield '' diff --git a/uwsgi.c b/uwsgi.c index ae38cab7..9ca444bc 100644 --- a/uwsgi.c +++ b/uwsgi.c @@ -29,11 +29,6 @@ in particular) */ -#ifndef ROCK_SOLID -#ifdef __linux__ - #include -#endif -#endif #ifndef UNBIT @@ -45,271 +40,264 @@ in particular) #endif -#include - - #include "uwsgi.h" #if PY_MINOR_VERSION < 5 - #define Py_ssize_t int +#define Py_ssize_t int #endif struct uwsgi_server uwsgi; static char *nl = "\r\n"; -static char *h_sep = ": " ; -static const char *http_protocol = "HTTP/1.1" ; +static char *h_sep = ": "; +static const char *http_protocol = "HTTP/1.1"; #ifndef ROCK_SOLID -static const char *app_slash = "/" ; +static const char *app_slash = "/"; #endif -int find_worker_id(pid_t pid) { - int i ; - for(i = 1 ; i<= uwsgi.numproc ; i++) { +int find_worker_id (pid_t pid) { + int i; + for (i = 1; i <= uwsgi.numproc; i++) { /* fprintf(stderr,"%d of %d\n", pid, uwsgi.workers[i].pid); */ if (uwsgi.workers[i].pid == pid) - return i ; + return i; } - return -1 ; + return -1; } struct wsgi_request wsgi_req; PyMethodDef null_methods[] = { - {NULL, NULL}, + {NULL, NULL}, }; #ifdef UNBIT -int save_to_disk = -1 ; -int tmp_dir_fd = -1 ; -char *tmp_filename ; -int uri_to_hex(void); -int check_for_memory_errors = 0 ; +int save_to_disk = -1; +int tmp_dir_fd = -1; +char *tmp_filename; +int uri_to_hex (void); +int check_for_memory_errors = 0; #endif -PyObject *wsgi_writeout ; +PyObject *wsgi_writeout; -// iovec -struct iovec *hvec ; #ifdef ROCK_SOLID struct uwsgi_app *wi; #endif -void warn_pipe() { - fprintf(stderr,"writing to a closed pipe/socket/fd !!!\n"); +void warn_pipe () { + fprintf (stderr, "writing to a closed pipe/socket/fd !!!\n"); } -void gracefully_kill() { - fprintf(stderr, "Gracefully killing worker %d...\n", uwsgi.mypid); +void gracefully_kill () { + fprintf (stderr, "Gracefully killing worker %d...\n", uwsgi.mypid); if (uwsgi.workers[uwsgi.mywid].in_request) { - uwsgi.workers[uwsgi.mywid].manage_next_request = 0 ; + uwsgi.workers[uwsgi.mywid].manage_next_request = 0; } else { - reload_me(); + reload_me (); } } -void reload_me() { - exit(UWSGI_RELOAD_CODE); +void reload_me () { + exit (UWSGI_RELOAD_CODE); } -void end_me() { - exit(UWSGI_END_CODE); +void end_me () { + exit (UWSGI_END_CODE); } -void goodbye_cruel_world() { - fprintf(stderr, "...The work of process %d is done. Seeya!\n", getpid()); - exit(0); +void goodbye_cruel_world () { + fprintf (stderr, "...The work of process %d is done. Seeya!\n", getpid ()); + exit (0); } -void kill_them_all() { - int i ; - uwsgi.to_hell = 1 ; - fprintf(stderr,"SIGINT/SIGQUIT received...killing workers...\n"); - for(i=1;i<=uwsgi.numproc;i++) { - kill(uwsgi.workers[i].pid, SIGINT); +void kill_them_all () { + int i; + uwsgi.to_hell = 1; + fprintf (stderr, "SIGINT/SIGQUIT received...killing workers...\n"); + for (i = 1; i <= uwsgi.numproc; i++) { + kill (uwsgi.workers[i].pid, SIGINT); } } -void grace_them_all() { - int i ; - uwsgi.to_heaven = 1 ; - fprintf(stderr,"...gracefully killing workers...\n"); - for(i=1;i<=uwsgi.numproc;i++) { - kill(uwsgi.workers[i].pid, SIGHUP); +void grace_them_all () { + int i; + uwsgi.to_heaven = 1; + fprintf (stderr, "...gracefully killing workers...\n"); + for (i = 1; i <= uwsgi.numproc; i++) { + kill (uwsgi.workers[i].pid, SIGHUP); } } -void reap_them_all() { - int i ; - fprintf(stderr,"...brutally killing workers...\n"); - for(i=1;i<=uwsgi.numproc;i++) { - kill(uwsgi.workers[i].pid, SIGTERM); +void reap_them_all () { + int i; + fprintf (stderr, "...brutally killing workers...\n"); + for (i = 1; i <= uwsgi.numproc; i++) { + kill (uwsgi.workers[i].pid, SIGTERM); } } -void harakiri() { +void harakiri () { PyThreadState *_myself; #ifndef ROCK_SOLID - struct uwsgi_app *wi = NULL ; + struct uwsgi_app *wi = NULL; if (wsgi_req.app_id >= 0) { - wi = &uwsgi.wsgi_apps[wsgi_req.app_id] ; + wi = &uwsgi.wsgi_apps[wsgi_req.app_id]; } #endif - PyGILState_Ensure(); - _myself = PyThreadState_Get(); + PyGILState_Ensure (); + _myself = PyThreadState_Get (); if (wi) { - #ifdef ROCK_SOLID - fprintf(stderr,"\nF*CK !!! i must kill myself (pid: %d) wi: %p wi->wsgi_harakiri: %p thread_state: %p frame: %p...\n", uwsgi.mypid, wi, wi->wsgi_harakiri, _myself, _myself->frame ); - #else - fprintf(stderr,"\nF*CK !!! i must kill myself (pid: %d app_id: %d) wi: %p wi->wsgi_harakiri: %p thread_state: %p frame: %p...\n", uwsgi.mypid, wsgi_req.app_id, wi, wi->wsgi_harakiri, _myself, _myself->frame ); - #endif +#ifdef ROCK_SOLID + fprintf (stderr, "\nF*CK !!! i must kill myself (pid: %d) wi: %p wi->wsgi_harakiri: %p thread_state: %p frame: %p...\n", uwsgi.mypid, wi, wi->wsgi_harakiri, _myself, _myself->frame); +#else + fprintf (stderr, "\nF*CK !!! i must kill myself (pid: %d app_id: %d) wi: %p wi->wsgi_harakiri: %p thread_state: %p frame: %p...\n", uwsgi.mypid, wsgi_req.app_id, wi, wi->wsgi_harakiri, _myself, _myself->frame); +#endif if (wi->wsgi_harakiri) { - PyEval_CallObject(wi->wsgi_harakiri, wi->wsgi_args); - if (PyErr_Occurred()) { - PyErr_Print(); - } + PyEval_CallObject (wi->wsgi_harakiri, wi->wsgi_args); + if (PyErr_Occurred ()) { + PyErr_Print (); + } } } - Py_FatalError("HARAKIRI !\n"); + Py_FatalError ("HARAKIRI !\n"); } #ifndef UNBIT #ifndef ROCK_SOLID -void stats() { +void stats () { struct uwsgi_app *ua = NULL; int i; - fprintf(stderr, "*** pid %d stats ***\n", getpid()); - fprintf(stderr, "\ttotal requests: %llu\n", uwsgi.workers[0].requests); - for(i=0;irequests); + fprintf (stderr, "\tapp %d requests: %d\n", i, ua->requests); } } - fprintf(stderr, "\n"); + fprintf (stderr, "\n"); } #endif #endif -void internal_server_error(int fd, char *message) { +void internal_server_error (int fd, char *message) { #ifndef UNBIT #ifndef ROCK_SOLID if (uwsgi.options[UWSGI_OPTION_CGI_MODE] == 0) { #endif #endif - wsgi_req.headers_size = write(fd, "HTTP/1.1 500 Internal Server Error\r\nContent-type: text/html\r\n\r\n", 63); + wsgi_req.headers_size = write (fd, "HTTP/1.1 500 Internal Server Error\r\nContent-type: text/html\r\n\r\n", 63); #ifndef UNBIT #ifndef ROCK_SOLID } else { - wsgi_req.headers_size = write(fd, "Status: 500 Internal Server Error\r\nContent-type: text/html\r\n\r\n", 62); + wsgi_req.headers_size = write (fd, "Status: 500 Internal Server Error\r\nContent-type: text/html\r\n\r\n", 62); } #endif - wsgi_req.header_cnt = 2 ; + wsgi_req.header_cnt = 2; #endif - wsgi_req.response_size = write(fd, "

uWSGI Error

", 20); - wsgi_req.response_size += write(fd, message, strlen(message)); + wsgi_req.response_size = write (fd, "

uWSGI Error

", 20); + wsgi_req.response_size += write (fd, message, strlen (message)); } #ifndef ROCK_SOLID -PyObject *py_uwsgi_sendfile(PyObject *self, PyObject *args) { +PyObject *py_uwsgi_sendfile (PyObject * self, PyObject * args) { - //PyObject *zero ; + //PyObject *zero ; - uwsgi.py_sendfile = PyTuple_GetItem(args, 0); + uwsgi.py_sendfile = PyTuple_GetItem (args, 0); #ifdef PYTHREE - if ((wsgi_req.sendfile_fd = PyObject_AsFileDescriptor(uwsgi.py_sendfile)) >= 0) { - Py_INCREF(uwsgi.py_sendfile); + if ((wsgi_req.sendfile_fd = PyObject_AsFileDescriptor (uwsgi.py_sendfile)) >= 0) { + Py_INCREF (uwsgi.py_sendfile); } #else - if (PyFile_Check(uwsgi.py_sendfile)) { - //zero = PyFile_Name(uwsgi.py_sendfile) ; - //fprintf(stderr,"->serving %s as static file...", PyString_AsString(zero)); - wsgi_req.sendfile_fd = PyObject_AsFileDescriptor(uwsgi.py_sendfile); - Py_INCREF(uwsgi.py_sendfile); - } + if (PyFile_Check (uwsgi.py_sendfile)) { + //zero = PyFile_Name(uwsgi.py_sendfile) ; + //fprintf(stderr,"->serving %s as static file...", PyString_AsString(zero)); + wsgi_req.sendfile_fd = PyObject_AsFileDescriptor (uwsgi.py_sendfile); + Py_INCREF (uwsgi.py_sendfile); + } #endif - return PyTuple_New(0); + return PyTuple_New (0); } #endif -PyObject *py_uwsgi_write(PyObject *self, PyObject *args) { - PyObject *data; - char *content ; - int len; - data = PyTuple_GetItem(args, 0); - if (PyString_Check(data)) { - content = PyString_AsString(data) ; - len = PyString_Size(data); +PyObject *py_uwsgi_write (PyObject * self, PyObject * args) { + PyObject *data; + char *content; + int len; + data = PyTuple_GetItem (args, 0); + if (PyString_Check (data)) { + content = PyString_AsString (data); + len = PyString_Size (data); #ifndef ROCK_SOLID - if (uwsgi.has_threads && uwsgi.options[UWSGI_OPTION_THREADS] == 1) { - Py_BEGIN_ALLOW_THREADS - wsgi_req.response_size = write(uwsgi.poll.fd, content, len); - Py_END_ALLOW_THREADS - } - else { + if (uwsgi.has_threads && uwsgi.options[UWSGI_OPTION_THREADS] == 1) { + Py_BEGIN_ALLOW_THREADS wsgi_req.response_size = write (uwsgi.poll.fd, content, len); + Py_END_ALLOW_THREADS} + else { #endif - wsgi_req.response_size = write(uwsgi.poll.fd, content, len); + wsgi_req.response_size = write (uwsgi.poll.fd, content, len); #ifdef UNBIT if (save_to_disk >= 0) { - if (write(save_to_disk, content, len) != len) { - perror("write()"); - close(save_to_disk); - save_to_disk = -1 ; + if (write (save_to_disk, content, len) != len) { + perror ("write()"); + close (save_to_disk); + save_to_disk = -1; } } #endif #ifndef ROCK_SOLID - } + } #endif - } + } #ifdef UNBIT if (save_to_disk >= 0) { - close(save_to_disk); - save_to_disk = -1 ; - fprintf(stderr,"[uWSGI cacher] output of request %llu (%.*s) on pid %d written to cache file %s\n",uwsgi.workers[0].requests, wsgi_req.uri_len, wsgi_req.uri, uwsgi.mypid,tmp_filename); + close (save_to_disk); + save_to_disk = -1; + fprintf (stderr, "[uWSGI cacher] output of request %llu (%.*s) on pid %d written to cache file %s\n", uwsgi.workers[0].requests, wsgi_req.uri_len, wsgi_req.uri, uwsgi.mypid, tmp_filename); } #endif - Py_INCREF(Py_None); - return Py_None; + Py_INCREF (Py_None); + return Py_None; } PyObject *wsgi_spitout; -PyObject *py_uwsgi_spit(PyObject *self, PyObject *args) { - PyObject *headers, *head ; - PyObject *h_key, *h_value; - int i,j ; +PyObject *py_uwsgi_spit (PyObject * self, PyObject * args) { + PyObject *headers, *head; + PyObject *h_key, *h_value; + int i, j; #ifndef UNBIT #ifdef ROCK_SOLID - int base = 4 ; + int base = 4; #else - int base = 0 ; + int base = 0; #endif #else - int base = 4 ; + int base = 4; #endif - // use writev() + // use writev() - head = PyTuple_GetItem(args,0) ; + head = PyTuple_GetItem (args, 0); if (!head) { goto clear; } - - if (!PyString_Check(head)) { - fprintf(stderr,"http status must be a string !\n"); + + if (!PyString_Check (head)) { + fprintf (stderr, "http status must be a string !\n"); goto clear; } @@ -317,50 +305,50 @@ PyObject *py_uwsgi_spit(PyObject *self, PyObject *args) { #ifndef UNBIT #ifndef ROCK_SOLID if (uwsgi.options[UWSGI_OPTION_CGI_MODE] == 0) { - base = 4 ; + base = 4; #endif #endif if (wsgi_req.protocol_len == 0) { - hvec[0].iov_base = (char * )http_protocol ; - wsgi_req.protocol_len = 8 ; + uwsgi.hvec[0].iov_base = (char *) http_protocol; + wsgi_req.protocol_len = 8; } else { - hvec[0].iov_base = wsgi_req.protocol ; + uwsgi.hvec[0].iov_base = wsgi_req.protocol; } - hvec[0].iov_len = wsgi_req.protocol_len ; - hvec[1].iov_base = " " ; - hvec[1].iov_len = 1 ; + uwsgi.hvec[0].iov_len = wsgi_req.protocol_len; + uwsgi.hvec[1].iov_base = " "; + uwsgi.hvec[1].iov_len = 1; #ifdef PYTHREE - hvec[2].iov_base = PyBytes_AsString(PyUnicode_AsASCIIString(head)) ; - hvec[2].iov_len = strlen(hvec[2].iov_base); + uwsgi.hvec[2].iov_base = PyBytes_AsString (PyUnicode_AsASCIIString (head)); + uwsgi.hvec[2].iov_len = strlen (uwsgi.hvec[2].iov_base); #else - hvec[2].iov_base = PyString_AsString(head) ; - hvec[2].iov_len = PyString_Size(head) ; + uwsgi.hvec[2].iov_base = PyString_AsString (head); + uwsgi.hvec[2].iov_len = PyString_Size (head); #endif - wsgi_req.status = atoi(hvec[2].iov_base) ; - hvec[3].iov_base = nl ; - hvec[3].iov_len = NL_SIZE ; + wsgi_req.status = atoi (uwsgi.hvec[2].iov_base); + uwsgi.hvec[3].iov_base = nl; + uwsgi.hvec[3].iov_len = NL_SIZE; #ifndef UNBIT #ifndef ROCK_SOLID } else { // drop http status on cgi mode - base = 3 ; - hvec[0].iov_base = "Status: " ; - hvec[0].iov_len = 8 ; + base = 3; + uwsgi.hvec[0].iov_base = "Status: "; + uwsgi.hvec[0].iov_len = 8; #ifdef PYTHREE - hvec[1].iov_base = PyBytes_AsString(PyUnicode_AsASCIIString(head)) ; - hvec[1].iov_len = strlen(hvec[1].iov_base); + uwsgi.hvec[1].iov_base = PyBytes_AsString (PyUnicode_AsASCIIString (head)); + uwsgi.hvec[1].iov_len = strlen (uwsgi.hvec[1].iov_base); #else - hvec[1].iov_base = PyString_AsString(head) ; - hvec[1].iov_len = PyString_Size(head) ; + uwsgi.hvec[1].iov_base = PyString_AsString (head); + uwsgi.hvec[1].iov_len = PyString_Size (head); #endif - wsgi_req.status = atoi(hvec[1].iov_base) ; - hvec[2].iov_base = nl ; - hvec[2].iov_len = NL_SIZE ; + wsgi_req.status = atoi (uwsgi.hvec[1].iov_base); + uwsgi.hvec[2].iov_base = nl; + uwsgi.hvec[2].iov_len = NL_SIZE; } #endif #endif @@ -369,102 +357,108 @@ PyObject *py_uwsgi_spit(PyObject *self, PyObject *args) { #ifdef UNBIT if (wsgi_req.unbit_flags & (unsigned long long) 1) { if (tmp_dir_fd >= 0 && tmp_filename[0] != 0 && wsgi_req.status == 200 && wsgi_req.method_len == 3 && wsgi_req.method[0] == 'G' && wsgi_req.method[1] == 'E' && wsgi_req.method[2] == 'T') { - save_to_disk = openat(tmp_dir_fd, tmp_filename,O_CREAT | O_TRUNC | O_WRONLY , S_IRUSR |S_IWUSR |S_IRGRP); + save_to_disk = openat (tmp_dir_fd, tmp_filename, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP); } } #endif - - headers = PyTuple_GetItem(args,1) ; + + headers = PyTuple_GetItem (args, 1); if (!headers) { goto clear; - } - if (!PyList_Check(headers)) { - fprintf(stderr,"http headers must be in a python list\n"); + } + if (!PyList_Check (headers)) { + fprintf (stderr, "http headers must be in a python list\n"); goto clear; } - wsgi_req.header_cnt = PyList_Size(headers) ; + wsgi_req.header_cnt = PyList_Size (headers); - if (wsgi_req.header_cnt > uwsgi.max_vars) { - wsgi_req.header_cnt = uwsgi.max_vars ; - } - for(i=0;i uwsgi.max_vars) { + wsgi_req.header_cnt = uwsgi.max_vars; + } + for (i = 0; i < wsgi_req.header_cnt; i++) { + j = (i * 4) + base; + head = PyList_GetItem (headers, i); if (!head) { - fprintf(stderr,"NON e' UNA LISTA\n"); goto clear; } - if (!PyTuple_Check(head)) { - fprintf(stderr,"http header must be defined in a tuple !\n"); + if (!PyTuple_Check (head)) { + fprintf (stderr, "http header must be defined in a tuple !\n"); + goto clear; + } + h_key = PyTuple_GetItem (head, 0); + if (!h_key) { + goto clear; + } + h_value = PyTuple_GetItem (head, 1); + if (!h_value) { goto clear; } - h_key = PyTuple_GetItem(head,0) ; - if (!h_key) { fprintf(stderr,"NIENTE CHIAVE\n");goto clear; } - h_value = PyTuple_GetItem(head,1) ; - if (!h_value) { fprintf(stderr,"NIENTE VALORE\n");goto clear; } #ifdef PYTHREE - hvec[j].iov_base = PyBytes_AsString(PyUnicode_AsASCIIString(h_key)) ; - hvec[j].iov_len = strlen(hvec[j].iov_base); + uwsgi.hvec[j].iov_base = PyBytes_AsString (PyUnicode_AsASCIIString (h_key)); + uwsgi.hvec[j].iov_len = strlen (uwsgi.hvec[j].iov_base); #else - hvec[j].iov_base = PyString_AsString(h_key) ; - hvec[j].iov_len = PyString_Size(h_key) ; + uwsgi.hvec[j].iov_base = PyString_AsString (h_key); + uwsgi.hvec[j].iov_len = PyString_Size (h_key); #endif - hvec[j+1].iov_base = h_sep; - hvec[j+1].iov_len = H_SEP_SIZE; + uwsgi.hvec[j + 1].iov_base = h_sep; + uwsgi.hvec[j + 1].iov_len = H_SEP_SIZE; #ifdef PYTHREE - hvec[j+2].iov_base = PyBytes_AsString(PyUnicode_AsASCIIString(h_value)) ; - hvec[j+2].iov_len = strlen(hvec[j+2].iov_base); + uwsgi.hvec[j + 2].iov_base = PyBytes_AsString (PyUnicode_AsASCIIString (h_value)); + uwsgi.hvec[j + 2].iov_len = strlen (uwsgi.hvec[j + 2].iov_base); #else - hvec[j+2].iov_base = PyString_AsString(h_value) ; - hvec[j+2].iov_len = PyString_Size(h_value) ; + uwsgi.hvec[j + 2].iov_base = PyString_AsString (h_value); + uwsgi.hvec[j + 2].iov_len = PyString_Size (h_value); #endif - hvec[j+3].iov_base = nl; - hvec[j+3].iov_len = NL_SIZE; - //fprintf(stderr, "%.*s: %.*s\n", hvec[j].iov_len, (char *)hvec[j].iov_base, hvec[j+2].iov_len, (char *) hvec[j+2].iov_base); - } + uwsgi.hvec[j + 3].iov_base = nl; + uwsgi.hvec[j + 3].iov_len = NL_SIZE; + //fprintf(stderr, "%.*s: %.*s\n", uwsgi.hvec[j].iov_len, (char *)uwsgi.hvec[j].iov_base, uwsgi.hvec[j+2].iov_len, (char *) uwsgi.hvec[j+2].iov_base); + } #ifdef UNBIT if (save_to_disk >= 0) { - for(j=0;j 0) { - uwsgi.options[UWSGI_OPTION_SOCKET_TIMEOUT] = atoi(optarg) ; - } - break; + case 'M': + uwsgi.master_process = 1; + break; + case 'R': + uwsgi.options[UWSGI_OPTION_MAX_REQUESTS] = atoi (optarg); + break; + case 'z': + if (atoi (optarg) > 0) { + uwsgi.options[UWSGI_OPTION_SOCKET_TIMEOUT] = atoi (optarg); + } + break; #ifndef ROCK_SOLID - case 'T': - uwsgi.has_threads = 1; - uwsgi.options[UWSGI_OPTION_THREADS] = 1 ; - break; - case 'P': - uwsgi.enable_profiler = 1; - break; - case 'i': - uwsgi.single_interpreter = 1; - break; + case 'T': + uwsgi.has_threads = 1; + uwsgi.options[UWSGI_OPTION_THREADS] = 1; + break; + case 'P': + uwsgi.enable_profiler = 1; + break; + case 'i': + uwsgi.single_interpreter = 1; + break; #endif #ifndef UNBIT - case 'h': - fprintf(stderr, "Usage: %s [options...]\n\ + case 'h': + fprintf (stderr, "Usage: %s [options...]\n\ \t-s|--socket \t\tpath (or name) of UNIX/TCP socket to bind to\n\ \t-l|--listen \t\tset socket listen queue to (default 64, maximum is system dependent)\n\ \t-z|--socket-timeout \tset socket timeout to seconds (default 4 seconds)\n\ @@ -872,15 +878,16 @@ int main(int argc, char *argv[], char *envp[]) { \t--pythonpath \t\tadd to PYTHONPATH\n\ \t--pyargv \t\t\tassign args to python sys.argv\n\ \t--limit-as \t\t\tlimit the address space of processes to MB megabytes\n\ +\t--udp \t\t\tbind master process to udp socket on ip:port\n\ \t-d|--daemonize \tdaemonize and log into \n", argv[0]); - exit(1); - case 0: - break; - default: - exit(1); + exit (1); + case 0: + break; + default: + exit (1); #endif - } - } + } + } #ifndef UNBIT #ifndef ROCK_SOLID @@ -888,205 +895,220 @@ int main(int argc, char *argv[], char *envp[]) { #endif #endif if (uwsgi.test_module == NULL) { - fprintf(stderr,"*** Starting uWSGI (%dbit) on [%.*s] ***\n", (int) (sizeof(void *))*8, 24, ctime( (const time_t *) &uwsgi.start_tv.tv_sec)); + fprintf (stderr, "*** Starting uWSGI (%dbit) on [%.*s] ***\n", (int) (sizeof (void *)) * 8, 24, ctime ((const time_t *) &uwsgi.start_tv.tv_sec)); } #ifndef UNBIT #ifndef ROCK_SOLID } else { - fprintf(stderr,"*** Starting uWSGI (CGI mode) (%dbit) on [%.*s] ***\n", (int) (sizeof(void *))*8, 24, ctime( (const time_t *) &uwsgi.start_tv.tv_sec)); + fprintf (stderr, "*** Starting uWSGI (CGI mode) (%dbit) on [%.*s] ***\n", (int) (sizeof (void *)) * 8, 24, ctime ((const time_t *) &uwsgi.start_tv.tv_sec)); } #endif #endif #ifdef __BIG_ENDIAN__ - fprintf(stderr,"*** big endian arch detected ***\n"); + fprintf (stderr, "*** big endian arch detected ***\n"); #endif #ifdef PYTHREE - fprintf(stderr,"*** Warning Python3.x support is experimental, do not use it in production environment ***\n"); + fprintf (stderr, "*** Warning Python3.x support is experimental, do not use it in production environment ***\n"); #endif - fprintf(stderr,"Python version: %s\n", Py_GetVersion()); + fprintf (stderr, "Python version: %s\n", Py_GetVersion ()); #ifndef UNBIT - if (!getuid()) { - fprintf(stderr,"uWSGI running as root, you can use --uid/--gid/--chroot options\n"); + if (!getuid ()) { + fprintf (stderr, "uWSGI running as root, you can use --uid/--gid/--chroot options\n"); if (uwsgi.chroot) { - fprintf(stderr,"chroot() to %s\n", uwsgi.chroot); - if (chroot(uwsgi.chroot)) { - perror("chroot()"); - exit(1); + fprintf (stderr, "chroot() to %s\n", uwsgi.chroot); + if (chroot (uwsgi.chroot)) { + perror ("chroot()"); + exit (1); } #ifdef __linux__ if (uwsgi.options[UWSGI_OPTION_MEMORY_DEBUG]) { - fprintf(stderr,"*** Warning, on linux system you have to bind-mount the /proc fs in your chroot to get memory debug/report.\n"); - } + fprintf (stderr, "*** Warning, on linux system you have to bind-mount the /proc fs in your chroot to get memory debug/report.\n"); + } #endif } if (uwsgi.gid) { - fprintf(stderr,"setgid() to %d\n", uwsgi.gid); - if (setgid(uwsgi.gid)) { - perror("setgid()"); - exit(1); + fprintf (stderr, "setgid() to %d\n", uwsgi.gid); + if (setgid (uwsgi.gid)) { + perror ("setgid()"); + exit (1); } } if (uwsgi.uid) { - fprintf(stderr,"setuid() to %d\n", uwsgi.uid); - if (setuid(uwsgi.uid)) { - perror("setuid()"); - exit(1); + fprintf (stderr, "setuid() to %d\n", uwsgi.uid); + if (setuid (uwsgi.uid)) { + perror ("setuid()"); + exit (1); } } } else { - if (uwsgi.chroot) { fprintf(stderr,"cannot chroot() as non-root user\n"); exit(1); } - if (uwsgi.gid) { fprintf(stderr,"cannot setgid() as non-root user\n"); exit(1); } - if (uwsgi.uid) { fprintf(stderr,"cannot setuid() as non-root user\n"); exit(1); } + if (uwsgi.chroot) { + fprintf (stderr, "cannot chroot() as non-root user\n"); + exit (1); + } + if (uwsgi.gid) { + fprintf (stderr, "cannot setgid() as non-root user\n"); + exit (1); + } + if (uwsgi.uid) { + fprintf (stderr, "cannot setuid() as non-root user\n"); + exit (1); + } } #endif +#ifndef UNBIT if (rl.rlim_max > 0) { - fprintf(stderr,"limiting address space of processes...\n"); - if (setrlimit(RLIMIT_AS, &rl)) { - perror("setrlimit()"); + fprintf (stderr, "limiting address space of processes...\n"); + if (setrlimit (RLIMIT_AS, &rl)) { + perror ("setrlimit()"); } } - - if (!getrlimit(RLIMIT_AS, &rl)) { +#endif + + if (!getrlimit (RLIMIT_AS, &rl)) { +#ifndef UNBIT // check for overflow - if ( (sizeof(void *) == 4 && (uint32_t) rl.rlim_max < UINT32_MAX) || (sizeof(void *) == 8 && (uint64_t) rl.rlim_max < UINT64_MAX)) { - fprintf(stderr,"your process address space limit is %lld bytes (%lld MB)\n", (long long) rl.rlim_max, (long long) rl.rlim_max/1024/1024); + if ((sizeof (void *) == 4 && (uint32_t) rl.rlim_max < UINT32_MAX) || (sizeof (void *) == 8 && (uint64_t) rl.rlim_max < UINT64_MAX)) { +#endif + fprintf (stderr, "your process address space limit is %lld bytes (%lld MB)\n", (long long) rl.rlim_max, (long long) rl.rlim_max / 1024 / 1024); +#ifndef UNBIT } +#endif } - uwsgi.page_size = getpagesize(); - fprintf(stderr,"your memory page size is %d bytes\n", uwsgi.page_size); + uwsgi.page_size = getpagesize (); + fprintf (stderr, "your memory page size is %d bytes\n", uwsgi.page_size); #ifndef UNBIT - fprintf(stderr,"your server socket listen backlog is limited to %d connections\n", uwsgi.listen_queue); + fprintf (stderr, "your server socket listen backlog is limited to %d connections\n", uwsgi.listen_queue); #endif if (uwsgi.synclog) { - fprintf(stderr,"allocating a memory page for synced logging.\n"); - uwsgi.sync_page = malloc(uwsgi.page_size); + fprintf (stderr, "allocating a memory page for synced logging.\n"); + uwsgi.sync_page = malloc (uwsgi.page_size); if (!uwsgi.sync_page) { - perror("malloc()"); - exit(1); + perror ("malloc()"); + exit (1); } } if (uwsgi.pyhome != NULL) { - fprintf(stderr,"Setting PythonHome to %s...\n", uwsgi.pyhome); + fprintf (stderr, "Setting PythonHome to %s...\n", uwsgi.pyhome); #ifdef PYTHREE - wchar_t *wpyhome ; - wpyhome = malloc((sizeof(wchar_t)*strlen(uwsgi.pyhome))+2) ; + wchar_t *wpyhome; + wpyhome = malloc ((sizeof (wchar_t) * strlen (uwsgi.pyhome)) + 2); if (!wpyhome) { - perror("malloc()"); - exit(1); + perror ("malloc()"); + exit (1); } - mbstowcs(wpyhome, uwsgi.pyhome, strlen(uwsgi.pyhome)); - Py_SetPythonHome(wpyhome); - free(wpyhome); + mbstowcs (wpyhome, uwsgi.pyhome, strlen (uwsgi.pyhome)); + Py_SetPythonHome (wpyhome); + free (wpyhome); #else - Py_SetPythonHome(uwsgi.pyhome); + Py_SetPythonHome (uwsgi.pyhome); #endif } - + #ifdef PYTHREE - wchar_t pname[6] ; - mbstowcs(pname, "uWSGI", 6); - Py_SetProgramName(pname); + wchar_t pname[6]; + mbstowcs (pname, "uWSGI", 6); + Py_SetProgramName (pname); #else - Py_SetProgramName("uWSGI"); + Py_SetProgramName ("uWSGI"); #endif - Py_Initialize() ; + Py_Initialize (); - pyargv[0] = "uwsgi" ; + pyargv[0] = "uwsgi"; if (uwsgi.pyargv != NULL) { char *ap; - while( (ap = strsep(&uwsgi.pyargv, " \t")) != NULL) { + while ((ap = strsep (&uwsgi.pyargv, " \t")) != NULL) { if (*ap != '\0') { - pyargv[pyargc] = ap ; + pyargv[pyargc] = ap; pyargc++; } - if (pyargc+1 > MAX_PYARGV) + if (pyargc + 1 > MAX_PYARGV) break; } } - PySys_SetArgv(pyargc, pyargv); + PySys_SetArgv (pyargc, pyargv); #ifndef ROCK_SOLID - uwsgi.py_apps = PyDict_New(); - if (!uwsgi.py_apps) { - PyErr_Print(); - exit(1); - } + uwsgi.py_apps = PyDict_New (); + if (!uwsgi.py_apps) { + PyErr_Print (); + exit (1); + } #endif - wsgi_spitout = PyCFunction_New(uwsgi_spit_method,NULL) ; - wsgi_writeout = PyCFunction_New(uwsgi_write_method,NULL) ; + wsgi_spitout = PyCFunction_New (uwsgi_spit_method, NULL); + wsgi_writeout = PyCFunction_New (uwsgi_write_method, NULL); #ifndef PYTHREE #ifndef ROCK_SOLID - uwsgi_module = Py_InitModule("uwsgi", null_methods); - if (uwsgi_module == NULL) { - fprintf(stderr,"could not initialize the uwsgi python module\n"); - exit(1); + uwsgi_module = Py_InitModule ("uwsgi", null_methods); + if (uwsgi_module == NULL) { + fprintf (stderr, "could not initialize the uwsgi python module\n"); + exit (1); } if (uwsgi.sharedareasize > 0) { - #ifndef __OpenBSD__ - uwsgi.sharedareamutex = mmap(NULL, sizeof(pthread_mutexattr_t) + sizeof(pthread_mutex_t), PROT_READ|PROT_WRITE , MAP_SHARED|MAP_ANON , -1, 0); +#ifndef __OpenBSD__ + uwsgi.sharedareamutex = mmap (NULL, sizeof (pthread_mutexattr_t) + sizeof (pthread_mutex_t), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); if (!uwsgi.sharedareamutex) { - perror("mmap()"); - exit(1); + perror ("mmap()"); + exit (1); } - #else - fprintf(stderr,"***WARNING*** the sharedarea on OpenBSD is not SMP-safe. Beware of race conditions !!!\n"); - #endif - uwsgi.sharedarea = mmap(NULL, uwsgi.page_size * uwsgi.sharedareasize, PROT_READ|PROT_WRITE , MAP_SHARED|MAP_ANON , -1, 0); - if (uwsgi.sharedarea) { - fprintf(stderr,"shared area mapped at %p, you can access it with uwsgi.sharedarea* functions.\n", uwsgi.sharedarea); +#else + fprintf (stderr, "***WARNING*** the sharedarea on OpenBSD is not SMP-safe. Beware of race conditions !!!\n"); +#endif + uwsgi.sharedarea = mmap (NULL, uwsgi.page_size * uwsgi.sharedareasize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); + if (uwsgi.sharedarea) { + fprintf (stderr, "shared area mapped at %p, you can access it with uwsgi.sharedarea* functions.\n", uwsgi.sharedarea); #ifdef __APPLE__ - memset(uwsgi.sharedareamutex,0, sizeof(OSSpinLock)); + memset (uwsgi.sharedareamutex, 0, sizeof (OSSpinLock)); #else - #ifndef __OpenBSD__ - if (pthread_mutexattr_init((pthread_mutexattr_t *)uwsgi.sharedareamutex)) { - fprintf(stderr,"unable to allocate mutexattr structure\n"); - exit(1); +#ifndef __OpenBSD__ + if (pthread_mutexattr_init ((pthread_mutexattr_t *) uwsgi.sharedareamutex)) { + fprintf (stderr, "unable to allocate mutexattr structure\n"); + exit (1); } - if (pthread_mutexattr_setpshared((pthread_mutexattr_t *)uwsgi.sharedareamutex, PTHREAD_PROCESS_SHARED)) { - fprintf(stderr,"unable to share mutex\n"); - exit(1); + if (pthread_mutexattr_setpshared ((pthread_mutexattr_t *) uwsgi.sharedareamutex, PTHREAD_PROCESS_SHARED)) { + fprintf (stderr, "unable to share mutex\n"); + exit (1); } - if (pthread_mutex_init((pthread_mutex_t *) uwsgi.sharedareamutex + sizeof(pthread_mutexattr_t), (pthread_mutexattr_t *)uwsgi.sharedareamutex)) { - fprintf(stderr,"unable to initialize mutex\n"); - exit(1); + if (pthread_mutex_init ((pthread_mutex_t *) uwsgi.sharedareamutex + sizeof (pthread_mutexattr_t), (pthread_mutexattr_t *) uwsgi.sharedareamutex)) { + fprintf (stderr, "unable to initialize mutex\n"); + exit (1); } - #endif #endif - +#endif + } else { - perror("mmap()"); - exit(1); + perror ("mmap()"); + exit (1); } } - init_uwsgi_embedded_module(); + init_uwsgi_embedded_module (); #endif #endif @@ -1095,97 +1117,112 @@ int main(int argc, char *argv[], char *envp[]) { #ifdef ROCK_SOLID - wi = malloc(sizeof(struct uwsgi_app)); + wi = malloc (sizeof (struct uwsgi_app)); if (wi == NULL) { - perror("malloc()"); - exit(1); + perror ("malloc()"); + exit (1); } - memset(wi, 0, sizeof(struct uwsgi_app)); + memset (wi, 0, sizeof (struct uwsgi_app)); // load wsgi module/script for (i = optind; i < argc; i++) { - init_uwsgi_vars(); - wi->wsgi_module = PyImport_ImportModule(argv[i]); + init_uwsgi_vars (); + wi->wsgi_module = PyImport_ImportModule (argv[i]); if (!wi->wsgi_module) { - PyErr_Print(); - exit(1); + PyErr_Print (); + exit (1); } - wi->wsgi_dict = PyModule_GetDict(wi->wsgi_module); + wi->wsgi_dict = PyModule_GetDict (wi->wsgi_module); if (!wi->wsgi_dict) { - PyErr_Print(); - exit(1); + PyErr_Print (); + exit (1); } - wi->wsgi_callable = PyDict_GetItemString(wi->wsgi_dict, "application"); + wi->wsgi_callable = PyDict_GetItemString (wi->wsgi_dict, "application"); if (!wi->wsgi_callable) { - PyErr_Print(); - exit(1); + PyErr_Print (); + exit (1); } - wi->wsgi_environ = PyDict_New(); + wi->wsgi_environ = PyDict_New (); if (!wi->wsgi_environ) { - PyErr_Print(); - exit(1); + PyErr_Print (); + exit (1); } - wi->wsgi_harakiri = PyDict_GetItemString(wi->wsgi_dict, "harakiri"); + wi->wsgi_harakiri = PyDict_GetItemString (wi->wsgi_dict, "harakiri"); - wi->wsgi_args = PyTuple_New(2) ; + wi->wsgi_args = PyTuple_New (2); if (!wi->wsgi_args) { - PyErr_Print(); - exit(1); + PyErr_Print (); + exit (1); } - if (PyTuple_SetItem(wi->wsgi_args,0, wi->wsgi_environ)) { - PyErr_Print(); - exit(1); + if (PyTuple_SetItem (wi->wsgi_args, 0, wi->wsgi_environ)) { + PyErr_Print (); + exit (1); } - if (PyTuple_SetItem(wi->wsgi_args,1, wsgi_spitout)) { - PyErr_Print(); - exit(1); + if (PyTuple_SetItem (wi->wsgi_args, 1, wsgi_spitout)) { + PyErr_Print (); + exit (1); } - break; + break; } if (!wi->wsgi_module) { - fprintf(stderr,"unable to find the wsgi script. Have you specified it ?\n"); - exit(1); + fprintf (stderr, "unable to find the wsgi script. Have you specified it ?\n"); + exit (1); } #endif #ifndef ROCK_SOLID Py_OptimizeFlag = uwsgi.py_optimize; - uwsgi.main_thread = PyThreadState_Get(); + uwsgi.main_thread = PyThreadState_Get (); - if (uwsgi.has_threads) { - PyEval_InitThreads() ; - fprintf(stderr, "threads support enabled\n"); - } + if (uwsgi.has_threads) { + PyEval_InitThreads (); + fprintf (stderr, "threads support enabled\n"); + } #endif if (!no_server) { #ifndef UNBIT - if (socket_name != NULL && !is_a_reload) { - char *tcp_port = strchr(socket_name, ':'); - if (tcp_port == NULL) { - serverfd = bind_to_unix(socket_name, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket); - } - else { - serverfd = bind_to_tcp(socket_name, uwsgi.listen_queue, tcp_port); - } + if (socket_name != NULL && !is_a_reload) { +#ifdef SCTP + if (!strncmp (socket_name, "sctp:", 5)) { + char *sctp_port = strchr (socket_name + 5, ':'); + if (sctp_port == NULL) { + fprintf (stderr, "invalid SCTP port ! syntax: sctp:ip1,ip2,ipN:port\n"); + exit (1); + } + serverfd = bind_to_sctp (socket_name + 5, uwsgi.listen_queue, sctp_port); + i_am_sctp = 1; + } + else { +#endif + char *tcp_port = strchr (socket_name, ':'); + if (tcp_port == NULL) { + serverfd = bind_to_unix (socket_name, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket); + } + else { + serverfd = bind_to_tcp (socket_name, uwsgi.listen_queue, tcp_port); + } - if (serverfd < 0) { - fprintf(stderr,"unable to create the server socket.\n"); - exit(1); + if (serverfd < 0) { + fprintf (stderr, "unable to create the server socket.\n"); + exit (1); + } +#ifdef SCTP + } +#endif } - } #endif - socket_type_len = sizeof(int); - if (getsockopt(serverfd, SOL_SOCKET, SO_TYPE, &socket_type, &socket_type_len)) { - perror("getsockopt()"); - exit(1); - } + socket_type_len = sizeof (int); + if (getsockopt (serverfd, SOL_SOCKET, SO_TYPE, &socket_type, &socket_type_len)) { + perror ("getsockopt()"); + exit (1); + } } @@ -1193,274 +1230,343 @@ int main(int argc, char *argv[], char *envp[]) { #ifndef ROCK_SOLID if (uwsgi.single_interpreter == 1) { - init_uwsgi_vars(); + init_uwsgi_vars (); } - memset(uwsgi.wsgi_apps, 0, sizeof(uwsgi.wsgi_apps)); + memset (uwsgi.wsgi_apps, 0, sizeof (uwsgi.wsgi_apps)); #endif - uwsgi.poll.events = POLLIN ; + uwsgi.poll.events = POLLIN; - memset(&wsgi_req, 0, sizeof(struct wsgi_request)); + memset (&wsgi_req, 0, sizeof (struct wsgi_request)); + + /* shared area for workers */ + uwsgi.workers = (struct uwsgi_worker *) mmap (NULL, sizeof (struct uwsgi_worker) * uwsgi.maxworkers + 1, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); + if (!uwsgi.workers) { + perror ("mmap()"); + exit (1); + } + memset (uwsgi.workers, 0, sizeof (struct uwsgi_worker) * uwsgi.maxworkers + 1); + + uwsgi.mypid = getpid (); + masterpid = uwsgi.mypid; + +#ifndef ROCK_SOLID +#ifndef UNBIT + if (uwsgi.pidfile) { + fprintf (stderr, "writing pidfile to %s\n", uwsgi.pidfile); + pidfile = fopen (uwsgi.pidfile, "w"); + if (!pidfile) { + perror ("fopen"); + exit (1); + } + if (fprintf (pidfile, "%d\n", masterpid) < 0) { + fprintf (stderr, "could not write pidfile.\n"); + } + fclose (pidfile); + } +#endif +#endif + + if (uwsgi.buffer_size > 65536) { + fprintf (stderr, "invalid buffer size.\n"); + exit (1); + } + buffer = malloc (uwsgi.buffer_size); + if (buffer == NULL) { + fprintf (stderr, "unable to allocate memory for buffer.\n"); + exit (1); + } + + fprintf (stderr, "request/response buffer (%d bytes) allocated.\n", uwsgi.buffer_size); + + /* save the masterpid */ + uwsgi.workers[0].pid = masterpid; + + uwsgi.workers[0].current_workers = uwsgi.numproc; + + fprintf(stderr,"initializing hooks..."); + + uwsgi.hooks[0] = uwsgi_request_wsgi ; + uwsgi.after_hooks[0] = uwsgi_after_request_wsgi ; + + uwsgi.hooks[UWSGI_MODIFIER_ADMIN_REQUEST] = uwsgi_request_admin ; //10 + uwsgi.hooks[UWSGI_MODIFIER_SPOOL_REQUEST] = uwsgi_request_spooler ; //17 + uwsgi.hooks[UWSGI_MODIFIER_FASTFUNC] = uwsgi_request_fastfunc ; //26 + + uwsgi.hooks[UWSGI_MODIFIER_MANAGE_PATH_INFO] = uwsgi_request_wsgi ; // 30 + uwsgi.after_hooks[UWSGI_MODIFIER_MANAGE_PATH_INFO] = uwsgi_after_request_wsgi; // 30 + + uwsgi.hooks[UWSGI_MODIFIER_MESSAGE_MARSHAL] = uwsgi_request_marshal ; //33 + uwsgi.hooks[UWSGI_MODIFIER_PING] = uwsgi_request_ping ; //100 + + fprintf(stderr,"done.\n"); #ifndef ROCK_SOLID if (uwsgi.wsgi_config != NULL) { - uwsgi_wsgi_config(); + uwsgi_wsgi_config (); } #endif #ifndef UNBIT #ifndef ROCK_SOLID else if (uwsgi.xml_config != NULL) { - uwsgi_xml_config(); + uwsgi_xml_config (); } #endif #endif #ifndef ROCK_SOLID else if (uwsgi.paste != NULL) { - uwsgi_paste_config(); + uwsgi_paste_config (); } #endif if (uwsgi.test_module != NULL) { - if (PyImport_ImportModule(uwsgi.test_module)) { - exit(0); + if (PyImport_ImportModule (uwsgi.test_module)) { + exit (0); } - exit(1); + exit (1); } - uwsgi.mypid = getpid(); - masterpid = uwsgi.mypid ; - -#ifndef ROCK_SOLID -#ifndef UNBIT - if (uwsgi.pidfile) { - fprintf(stderr,"writing pidfile to %s\n", uwsgi.pidfile); - pidfile = fopen(uwsgi.pidfile, "w"); - if (!pidfile) { - perror("fopen"); - exit(1); - } - if (fprintf(pidfile, "%d\n", masterpid) < 0) { - fprintf(stderr,"could not write pidfile.\n"); - } - fclose(pidfile); - } -#endif -#endif - - if (uwsgi.buffer_size > 65536) { - fprintf(stderr,"invalid buffer size.\n"); - exit(1); - } - buffer = malloc(uwsgi.buffer_size); - if (buffer == NULL) { - fprintf(stderr,"unable to allocate memory for buffer.\n"); - exit(1); - } - - fprintf(stderr,"request/response buffer (%d bytes) allocated.\n", uwsgi.buffer_size); - - - - - /* shared area for workers */ - uwsgi.workers = (struct uwsgi_worker *) mmap(NULL, sizeof(struct uwsgi_worker)*uwsgi.maxworkers+1, PROT_READ|PROT_WRITE , MAP_SHARED|MAP_ANON , -1, 0); - if (!uwsgi.workers) { - perror("mmap()"); - exit(1); - } - memset(uwsgi.workers, 0, sizeof(struct uwsgi_worker)*uwsgi.maxworkers+1); #ifndef UNBIT #ifndef ROCK_SOLID if (no_server) { - fprintf(stderr,"no-server mode requested. Goodbye.\n"); - exit(0); + fprintf (stderr, "no-server mode requested. Goodbye.\n"); + exit (0); } #endif #endif - /* preforking() */ + /* preforking() */ if (uwsgi.master_process) { if (is_a_reload) { - fprintf(stderr, "gracefully (RE)spawned uWSGI master process (pid: %d)\n", uwsgi.mypid); + fprintf (stderr, "gracefully (RE)spawned uWSGI master process (pid: %d)\n", uwsgi.mypid); } else { - fprintf(stderr, "spawned uWSGI master process (pid: %d)\n", uwsgi.mypid); + fprintf (stderr, "spawned uWSGI master process (pid: %d)\n", uwsgi.mypid); } } #ifdef UNBIT if (single_app_mode == 1) { - wsgi_req.wsgi_script = getenv("UWSGI_SCRIPT"); + wsgi_req.wsgi_script = getenv ("UWSGI_SCRIPT"); if (wsgi_req.wsgi_script) { - wsgi_req.wsgi_script_len = strlen(wsgi_req.wsgi_script); + wsgi_req.wsgi_script_len = strlen (wsgi_req.wsgi_script); } else { - fprintf(stderr, "UWSGI_SCRIPT env var not set !\n"); - exit(1); + fprintf (stderr, "UWSGI_SCRIPT env var not set !\n"); + exit (1); } - init_uwsgi_app(NULL, NULL); + init_uwsgi_app (NULL, NULL); } #endif #ifndef ROCK_SOLID #ifndef PYTHREE if (spool_dir != NULL) { - spooler_pid = spooler_start(serverfd, uwsgi_module); + spooler_pid = spooler_start (serverfd, uwsgi_module); } #endif #endif - /* save the masterpid */ - uwsgi.workers[0].pid = masterpid ; +#ifndef ROCK_SOLID +#ifndef PYTHREE +#ifndef UNBIT + if (snmp != NULL) { + //snmp_pid = snmp_start(snmp); + } +#endif +#endif +#endif + - uwsgi.workers[0].current_workers = uwsgi.numproc ; if (!uwsgi.master_process && uwsgi.numproc == 1) { - fprintf(stderr, "spawned uWSGI worker 1 (and the only) (pid: %d)\n", masterpid); - uwsgi.workers[1].pid = masterpid ; - uwsgi.workers[1].id = 1 ; - uwsgi.workers[1].last_spawn = time(NULL) ; - uwsgi.workers[1].manage_next_request = 1 ; - uwsgi.mywid = 1; - gettimeofday(&last_respawn, NULL) ; - respawn_delta = last_respawn.tv_sec; + fprintf (stderr, "spawned uWSGI worker 1 (and the only) (pid: %d)\n", masterpid); + uwsgi.workers[1].pid = masterpid; + uwsgi.workers[1].id = 1; + uwsgi.workers[1].last_spawn = time (NULL); + uwsgi.workers[1].manage_next_request = 1; + uwsgi.mywid = 1; + gettimeofday (&last_respawn, NULL); + respawn_delta = last_respawn.tv_sec; } else { - for(i=1;i= uwsgi.numproc && uwsgi.to_hell) { #ifndef ROCK_SOLID if (spool_dir && spooler_pid > 0) { - kill(spooler_pid, SIGKILL); + kill (spooler_pid, SIGKILL); + } + + if (snmp && snmp_pid > 0) { + kill (snmp_pid, SIGKILL); } #endif - fprintf(stderr,"goodbye to uWSGI.\n"); - exit(0); - } + fprintf (stderr, "goodbye to uWSGI.\n"); + exit (0); + } if (ready_to_reload >= uwsgi.numproc && uwsgi.to_heaven) { #ifndef ROCK_SOLID if (spool_dir && spooler_pid > 0) { - kill(spooler_pid, SIGKILL); + kill (spooler_pid, SIGKILL); } #endif - fprintf(stderr,"binary reloading uWSGI...\n"); - if (chdir(cwd)) { - perror("chdir()"); - exit(1); + fprintf (stderr, "binary reloading uWSGI...\n"); + if (chdir (cwd)) { + perror ("chdir()"); + exit (1); } /* check fd table (a module can obviosly open some fd on initialization...) */ - fprintf(stderr,"closing all fds > 2 (_SC_OPEN_MAX = %ld)...\n",sysconf(_SC_OPEN_MAX)); - for(i=3;i 2 (_SC_OPEN_MAX = %ld)...\n", sysconf (_SC_OPEN_MAX)); + for (i = 3; i < sysconf (_SC_OPEN_MAX); i++) { if (i == serverfd) { - continue ; + continue; } - close(i); + close (i); } if (serverfd != 3) { - if (dup2(serverfd,3) < 0) { - perror("dup2()"); - exit(1); + if (dup2 (serverfd, 3) < 0) { + perror ("dup2()"); + exit (1); } } - fprintf(stderr,"running %s\n", binary_path); - strcpy(argv[0], binary_path); - execve(binary_path, argv, envp); - perror("execve()"); - exit(1); + fprintf (stderr, "running %s\n", binary_path); + strcpy (argv[0], binary_path); + execve (binary_path, argv, envp); + perror ("execve()"); + exit (1); } - diedpid = waitpid(WAIT_ANY , &waitpid_status, WNOHANG) ; + diedpid = waitpid (WAIT_ANY, &waitpid_status, WNOHANG); if (diedpid == -1) { - perror("waitpid()"); + perror ("waitpid()"); /* here is better to reload all the uWSGI stack */ - fprintf(stderr, "something horrible happened...\n"); - reap_them_all(); - exit(1); + fprintf (stderr, "something horrible happened...\n"); + reap_them_all (); + exit (1); } else if (diedpid == 0) { /* PLEASE, do not run python threads in the master process, you can potentially destroy the world, - we support this for hyperultramegagodprogrammer and systems - */ + we support this for hyperultramegagodprogrammer and systems + */ #ifndef ROCK_SOLID - if (uwsgi.has_threads && uwsgi.options[UWSGI_OPTION_THREADS] == 1) { - _save = PyEval_SaveThread(); - i_have_gil = 0; - } + if (uwsgi.has_threads && uwsgi.options[UWSGI_OPTION_THREADS] == 1) { + uwsgi._save = PyEval_SaveThread (); + uwsgi.i_have_gil = 0; + } #endif /* all processes ok, doing status scan after N seconds */ - check_interval.tv_sec = uwsgi.options[UWSGI_OPTION_MASTER_INTERVAL] ; - if (!check_interval.tv_sec) + check_interval.tv_sec = uwsgi.options[UWSGI_OPTION_MASTER_INTERVAL]; + if (!check_interval.tv_sec) check_interval.tv_sec = 1; - select(0, NULL, NULL, NULL, &check_interval); - working_workers = 0 ; - blocking_workers = 0 ; + if (udp_poll.fd >= 0) { + rlen = poll (&udp_poll, 1, check_interval.tv_sec * 1000); + if (rlen < 0) { + perror ("poll()"); + } + else if (rlen > 0) { + udp_len = sizeof (udp_client); + rlen = recvfrom (udp_poll.fd, buffer, uwsgi.buffer_size, 0, (struct sockaddr *) &udp_client, &udp_len); + if (rlen < 0) { + perror ("recvfrom()"); + } + else if (rlen > 0) { + memset (udp_client_addr, 0, 16); + if (inet_ntop (AF_INET, &udp_client, udp_client_addr, 16)) { + fprintf (stderr, "received udp packet of %d bytes from %s:%d\n", rlen, udp_client_addr, ntohs (udp_client.sin_port)); + if (buffer[0] == 0x30) { + manage_snmp (udp_poll.fd, (uint8_t *) buffer, rlen, &udp_client); + } + } + else { + perror ("inet_ntop()"); + } + } + } + } + else { + select (0, NULL, NULL, NULL, &check_interval); + } + working_workers = 0; + blocking_workers = 0; #ifndef ROCK_SOLID - if (uwsgi.has_threads && !i_have_gil) { - PyEval_RestoreThread(_save); - i_have_gil = 1 ; - } + if (uwsgi.has_threads && !uwsgi.i_have_gil) { + PyEval_RestoreThread (uwsgi._save); + uwsgi.i_have_gil = 1; + } #endif - check_interval.tv_sec = uwsgi.options[UWSGI_OPTION_MASTER_INTERVAL] ; - if (!check_interval.tv_sec) + check_interval.tv_sec = uwsgi.options[UWSGI_OPTION_MASTER_INTERVAL]; + if (!check_interval.tv_sec) check_interval.tv_sec = 1; - for(i=1;i<=uwsgi.workers[0].current_workers;i++) { + for (i = 1; i <= uwsgi.workers[0].current_workers; i++) { /* first check for harakiri */ - if (uwsgi.workers[i].harakiri > 0) { - if (uwsgi.workers[i].harakiri < time(NULL)) { + if (uwsgi.workers[i].harakiri > 0) { + if (uwsgi.workers[i].harakiri < time (NULL)) { /* first try to invoke the harakiri() custom handler */ /* TODO */ /* then brutally kill the worker */ - kill(uwsgi.workers[i].pid, SIGKILL); + kill (uwsgi.workers[i].pid, SIGKILL); } } /* load counters */ @@ -1469,56 +1575,53 @@ int main(int argc, char *argv[], char *envp[]) { if (uwsgi.workers[i].blocking) blocking_workers++; - /* set the load */ - if (uwsgi.workers[i].last_running_time > 0 && uwsgi.workers[i].running_time > 0) { - uwsgi.workers[i].load = (((uwsgi.workers[i].running_time-uwsgi.workers[i].last_running_time)/1000) * 100)/check_interval.tv_sec ; - } - uwsgi.workers[i].last_running_time = uwsgi.workers[i].running_time ; - } + + uwsgi.workers[i].last_running_time = uwsgi.workers[i].running_time; + } /* check if i need to add a subworker */ - fprintf(stderr,"working workers: %d\n", working_workers); + //fprintf(stderr,"working workers: %d\n", working_workers); if (working_workers >= uwsgi.workers[0].current_workers) { /* ok the system is overloaded, check if some worker is in blocking mode */ if (blocking_workers > 0) { /* check if is it safe to add a new worker (for now check only for enough free memory) */ - fprintf(stderr,"adding a new subworker as there are workers in blocking mode...\n"); - uwsgi.mywid = uwsgi.workers[0].current_workers+1; - pid = fork(); + fprintf (stderr, "adding a new subworker as there are workers in blocking mode...\n"); + uwsgi.mywid = uwsgi.workers[0].current_workers + 1; + pid = fork (); if (pid < 0) { - perror("fork()"); + perror ("fork()"); } else if (pid > 0) { - fprintf(stderr, "spawned uWSGI subworker (pid: %d)\n", pid); - uwsgi.workers[uwsgi.workers[0].current_workers+1].id = uwsgi.workers[0].current_workers+1 ; - uwsgi.workers[uwsgi.workers[0].current_workers+1].pid = pid ; - uwsgi.workers[uwsgi.workers[0].current_workers+1].harakiri = 0 ; - uwsgi.workers[uwsgi.workers[0].current_workers+1].requests = 0 ; - uwsgi.workers[uwsgi.workers[0].current_workers+1].failed_requests = 0 ; - uwsgi.workers[uwsgi.workers[0].current_workers+1].respawn_count++ ; - uwsgi.workers[uwsgi.workers[0].current_workers+1].last_spawn = time(NULL) ; - uwsgi.workers[uwsgi.workers[0].current_workers+1].manage_next_request = 1 ; - uwsgi.workers[0].current_workers++ ; + fprintf (stderr, "spawned uWSGI subworker (pid: %d)\n", pid); + uwsgi.workers[uwsgi.workers[0].current_workers + 1].id = uwsgi.workers[0].current_workers + 1; + uwsgi.workers[uwsgi.workers[0].current_workers + 1].pid = pid; + uwsgi.workers[uwsgi.workers[0].current_workers + 1].harakiri = 0; + uwsgi.workers[uwsgi.workers[0].current_workers + 1].requests = 0; + uwsgi.workers[uwsgi.workers[0].current_workers + 1].failed_requests = 0; + uwsgi.workers[uwsgi.workers[0].current_workers + 1].respawn_count++; + uwsgi.workers[uwsgi.workers[0].current_workers + 1].last_spawn = time (NULL); + uwsgi.workers[uwsgi.workers[0].current_workers + 1].manage_next_request = 1; + uwsgi.workers[0].current_workers++; } else if (pid == 0) { - uwsgi.mypid = getpid(); - break; + uwsgi.mypid = getpid (); + break; } } } else { /* the system is no more overloaded, mark subworkers */ - for(i=uwsgi.numproc+1;i<=uwsgi.workers[0].current_workers;i++) { - uwsgi.workers[i].manage_next_request = 0 ; - } + for (i = uwsgi.numproc + 1; i <= uwsgi.workers[0].current_workers; i++) { + uwsgi.workers[i].manage_next_request = 0; + } } /* now check for subworkers to remove */ - for(i=uwsgi.workers[0].current_workers;i>uwsgi.numproc;i--) { + for (i = uwsgi.workers[0].current_workers; i > uwsgi.numproc; i--) { if (uwsgi.workers[i].manage_next_request) break; /* reset this worker (no interest in killing it) */ - memset(&uwsgi.workers[i], 0, sizeof(struct uwsgi_worker)); + memset (&uwsgi.workers[i], 0, sizeof (struct uwsgi_worker)); uwsgi.workers[0].current_workers--; } continue; @@ -1528,837 +1631,289 @@ int main(int argc, char *argv[], char *envp[]) { /* reload the spooler */ if (spool_dir && spooler_pid > 0) { if (diedpid == spooler_pid) { - spooler_pid = spooler_start(serverfd, uwsgi_module); + spooler_pid = spooler_start (serverfd, uwsgi_module); continue; } } +#ifndef UNBIT + + /* reload the snmp server */ + if (snmp && snmp_pid > 0) { + if (diedpid == snmp_pid) { + //snmp_pid = snmp_start(snmp); + continue; + } + } + +#endif #endif #endif /* check for reloading */ - if (WIFEXITED(waitpid_status)) { - if (WEXITSTATUS(waitpid_status) == UWSGI_RELOAD_CODE && uwsgi.to_heaven) { + if (WIFEXITED (waitpid_status)) { + if (WEXITSTATUS (waitpid_status) == UWSGI_RELOAD_CODE && uwsgi.to_heaven) { ready_to_reload++; continue; } - else if (WEXITSTATUS(waitpid_status) == UWSGI_END_CODE && uwsgi.to_hell) { + else if (WEXITSTATUS (waitpid_status) == UWSGI_END_CODE && uwsgi.to_hell) { ready_to_die++; continue; } } /* subworkers need to be respawned ? i do not think so */ - if (find_worker_id(diedpid) > uwsgi.numproc) { - fprintf(stderr,"OOPS ! process %d (subworker id %d) died :( i will not respawn it.\n", diedpid, find_worker_id(diedpid)); + if (find_worker_id (diedpid) > uwsgi.numproc) { + fprintf (stderr, "OOPS ! process %d (subworker id %d) died :( i will not respawn it.\n", diedpid, find_worker_id (diedpid)); /* decrease the number of workers */ if (uwsgi.workers[0].current_workers > uwsgi.numproc) { - uwsgi.workers[find_worker_id(diedpid)].manage_next_request = 0 ; + uwsgi.workers[find_worker_id (diedpid)].manage_next_request = 0; } continue; } - fprintf(stderr,"DAMN ! process %d died :( trying respawn ...\n", diedpid); - gettimeofday(&last_respawn, NULL) ; + fprintf (stderr, "DAMN ! process %d died :( trying respawn ...\n", diedpid); + gettimeofday (&last_respawn, NULL); if (last_respawn.tv_sec == respawn_delta) { - fprintf(stderr,"worker respawning too fast !!! i have to sleep a bit...\n"); + fprintf (stderr, "worker respawning too fast !!! i have to sleep a bit...\n"); /* TODO, user configurable fork throttler */ - sleep(2); + sleep (2); } - gettimeofday(&last_respawn, NULL) ; + gettimeofday (&last_respawn, NULL); respawn_delta = last_respawn.tv_sec; - uwsgi.mywid = find_worker_id(diedpid); - pid = fork(); - if (pid == 0 ) { - uwsgi.mypid = getpid(); + uwsgi.mywid = find_worker_id (diedpid); + pid = fork (); + if (pid == 0) { + uwsgi.mypid = getpid (); break; } - else if (pid < 1) { - perror("fork()"); + else if (pid < 1) { + perror ("fork()"); } else { - fprintf(stderr, "Respawned uWSGI worker (new pid: %d)\n", pid); + fprintf (stderr, "Respawned uWSGI worker (new pid: %d)\n", pid); if (uwsgi.mywid > 0) { - uwsgi.workers[uwsgi.mywid].pid = pid ; - uwsgi.workers[uwsgi.mywid].harakiri = 0 ; - uwsgi.workers[uwsgi.mywid].requests = 0 ; - uwsgi.workers[uwsgi.mywid].failed_requests = 0 ; - uwsgi.workers[uwsgi.mywid].respawn_count++ ; - uwsgi.workers[uwsgi.mywid].last_spawn = time(NULL) ; - uwsgi.workers[uwsgi.mywid].manage_next_request = 1 ; + uwsgi.workers[uwsgi.mywid].pid = pid; + uwsgi.workers[uwsgi.mywid].harakiri = 0; + uwsgi.workers[uwsgi.mywid].requests = 0; + uwsgi.workers[uwsgi.mywid].failed_requests = 0; + uwsgi.workers[uwsgi.mywid].respawn_count++; + uwsgi.workers[uwsgi.mywid].last_spawn = time (NULL); + uwsgi.workers[uwsgi.mywid].manage_next_request = 1; } else { - fprintf(stderr, "warning the died pid was not in the workers list. Probably you hit a BUG of uWSGI\n") ; + fprintf (stderr, "warning the died pid was not in the workers list. Probably you hit a BUG of uWSGI\n"); } } } } - - hvec = malloc(sizeof(struct iovec)*uwsgi.vec_size) ; - if (hvec == NULL) { - fprintf(stderr,"unable to allocate memory for iovec.\n"); - exit(1); + + uwsgi.hvec = malloc (sizeof (struct iovec) * uwsgi.vec_size); + if (uwsgi.hvec == NULL) { + fprintf (stderr, "unable to allocate memory for iovec.\n"); + exit (1); } - if (uwsgi.options[UWSGI_OPTION_HARAKIRI] > 0 && !uwsgi.master_process) { - signal(SIGALRM, (void *) &harakiri); - } + if (uwsgi.options[UWSGI_OPTION_HARAKIRI] > 0 && !uwsgi.master_process) { + signal (SIGALRM, (void *) &harakiri); + } /* gracefully reload */ - signal(SIGHUP, (void *) &gracefully_kill); + signal (SIGHUP, (void *) &gracefully_kill); /* close the process (useful for master INT) */ - signal(SIGINT, (void *) &end_me); + signal (SIGINT, (void *) &end_me); /* brutally reload */ - signal(SIGTERM, (void *) &reload_me); + signal (SIGTERM, (void *) &reload_me); #ifndef UNBIT #ifndef ROCK_SOLID - signal(SIGUSR1, (void *) &stats); + signal (SIGUSR1, (void *) &stats); #endif #endif #ifndef ROCK_SOLID - if (uwsgi.has_threads) { - _save = PyEval_SaveThread(); - i_have_gil = 0 ; - } + if (uwsgi.has_threads) { + uwsgi._save = PyEval_SaveThread (); + uwsgi.i_have_gil = 0; + } #endif - signal(SIGPIPE, (void *) &warn_pipe); + signal (SIGPIPE, (void *) &warn_pipe); - while(uwsgi.workers[uwsgi.mywid].manage_next_request) { - + while (uwsgi.workers[uwsgi.mywid].manage_next_request) { + + #ifndef ROCK_SOLID - wsgi_req.app_id = uwsgi.default_app ; - wsgi_req.sendfile_fd = -1 ; + wsgi_req.app_id = uwsgi.default_app; + wsgi_req.sendfile_fd = -1; #endif - uwsgi.workers[uwsgi.mywid].blocking = 0 ; - uwsgi.workers[uwsgi.mywid].in_request = 0 ; - uwsgi.poll.fd = accept(serverfd,(struct sockaddr *)&c_addr, (socklen_t *) &c_len) ; - uwsgi.workers[uwsgi.mywid].in_request = 1 ; + uwsgi.workers[uwsgi.mywid].blocking = 0; + uwsgi.workers[uwsgi.mywid].in_request = 0; + uwsgi.poll.fd = accept (serverfd, (struct sockaddr *) &c_addr, (socklen_t *) & c_len); + uwsgi.workers[uwsgi.mywid].in_request = 1; - if (uwsgi.poll.fd < 0){ - perror("accept()"); + if (uwsgi.poll.fd < 0) { + perror ("accept()"); continue; - } + } - /* - poll with timeout ; - */ + /* + poll with timeout ; + */ if (uwsgi.options[UWSGI_OPTION_LOGGING]) - gettimeofday(&wsgi_req.start_of_request, NULL) ; - - - if (!uwsgi_parse_response(&uwsgi.poll, uwsgi.options[UWSGI_OPTION_SOCKET_TIMEOUT], (struct uwsgi_header *) &wsgi_req, buffer)) { - continue; - } - + gettimeofday (&wsgi_req.start_of_request, NULL); - if (wsgi_req.modifier == UWSGI_MODIFIER_PING) { - fprintf(stderr,"PING\n"); - wsgi_req.modifier_arg = 1 ; - if (write(uwsgi.poll.fd,&wsgi_req,4) != 4) { - perror("write()"); - } - close(uwsgi.poll.fd); - memset(&wsgi_req, 0, sizeof(struct wsgi_request)); - uwsgi.workers[0].requests++; uwsgi.workers[uwsgi.mywid].requests++; - continue; - } - else if (wsgi_req.modifier == UWSGI_MODIFIER_ADMIN_REQUEST) { - uint32_t opt_value = 0 ; - if (wsgi_req.size >=4) { - memcpy(&opt_value, buffer, 4); - // TODO: check endianess - } - fprintf(stderr,"setting internal option %d to %d\n", wsgi_req.modifier_arg, opt_value); - uwsgi.options[wsgi_req.modifier_arg] = opt_value ; - wsgi_req.modifier = 255 ; - wsgi_req.size = 0 ; - wsgi_req.modifier_arg = 1 ; - i = write(uwsgi.poll.fd,&wsgi_req,4); - if (i != 4) { - perror("write()"); - } - close(uwsgi.poll.fd); - memset(&wsgi_req, 0, sizeof(struct wsgi_request)); - uwsgi.workers[0].requests++; uwsgi.workers[uwsgi.mywid].requests++; - continue; - } -#ifndef ROCK_SOLID - else if (wsgi_req.modifier == UWSGI_MODIFIER_FASTFUNC) { - zero = PyList_GetItem(uwsgi.fastfuncslist, wsgi_req.modifier_arg) ; - if (zero) { - fprintf(stderr,"managing fastfunc %d\n", wsgi_req.modifier_arg) ; - wsgi_result = PyEval_CallObject(zero, NULL); - if (PyErr_Occurred()) { - PyErr_Print(); - } - if (wsgi_result) { - wsgi_chunks = PyObject_GetIter(wsgi_result); - if (wsgi_chunks) { - while((wchunk = PyIter_Next(wsgi_chunks))) { - if (PyString_Check(wchunk)) { - wsgi_req.response_size += write(uwsgi.poll.fd, PyString_AsString(wchunk), PyString_Size(wchunk)) ; - } - Py_DECREF(wchunk); - } - Py_DECREF(wsgi_chunks); - } - Py_DECREF(wsgi_result); - } - } - PyErr_Clear(); - close(uwsgi.poll.fd); - memset(&wsgi_req, 0, sizeof(struct wsgi_request)); - uwsgi.workers[0].requests++; uwsgi.workers[uwsgi.mywid].requests++; - continue; - } - /* check for marshalled message */ - else if (wsgi_req.modifier == UWSGI_MODIFIER_MESSAGE_MARSHAL) { - PyObject *umm = PyDict_GetItemString(uwsgi.embedded_dict, "message_manager_marshal"); - if (umm) { - PyObject *ummo = PyMarshal_ReadObjectFromString(buffer, wsgi_req.size) ; - if (ummo) { - if (!PyTuple_SetItem(uwsgi.embedded_args, 0, ummo)) { - if (!PyTuple_SetItem(uwsgi.embedded_args, 1, PyInt_FromLong(wsgi_req.modifier_arg))) { - wsgi_result = PyEval_CallObject(umm, uwsgi.embedded_args); - if (PyErr_Occurred()) { - PyErr_Print(); - } - if (wsgi_result) { - PyObject *marshalled = PyMarshal_WriteObjectToString(wsgi_result, 1); - if (!marshalled) { - PyErr_Print() ; - } - else { - if (PyString_Size(marshalled) <= 0xFFFF) { - wsgi_req.size = (uint16_t) PyString_Size(marshalled) ; - if (write(uwsgi.poll.fd, &wsgi_req, 4) == 4) { - if (write(uwsgi.poll.fd, PyString_AsString(marshalled), wsgi_req.size) != wsgi_req.size) { - perror("write()"); - } - } - else { - perror("write()"); - } - } - else { - fprintf(stderr,"marshalled object is too big. skip\n"); - } - Py_DECREF(marshalled); - } - Py_DECREF(wsgi_result); - } - } - } - //Py_DECREF(ummo); - } - } - PyErr_Clear(); - close(uwsgi.poll.fd); - memset(&wsgi_req, 0, sizeof(struct wsgi_request)); - uwsgi.workers[0].requests++; uwsgi.workers[uwsgi.mywid].requests++; - continue; - } - /* check for spooler request */ - else if (wsgi_req.modifier == UWSGI_MODIFIER_SPOOL_REQUEST) { - - if (spool_dir == NULL) { - fprintf(stderr,"the spooler is inactive !!!...skip\n"); - wsgi_req.modifier = 255 ; - wsgi_req.size = 0 ; - wsgi_req.modifier_arg = 0 ; - i = write(uwsgi.poll.fd,&wsgi_req,4); - if (i != 4) { - perror("write()"); - } - close(uwsgi.poll.fd); - memset(&wsgi_req, 0, sizeof(struct wsgi_request)); - uwsgi.workers[0].requests++; uwsgi.workers[uwsgi.mywid].requests++; - continue; + +#ifdef SCTP + if (i_am_sctp == 1) { + // get stream id, and map it to uwsgi modifiers + struct sctp_status sstatus; + memset (&sstatus, 0, sizeof (sstatus)); + socklen_t slen = sizeof (sstatus); + sstatus.sstat_assoc_id = 1; + if (getsockopt (uwsgi.poll.fd, IPPROTO_SCTP, SCTP_STATUS, &sstatus, &slen)) { + perror ("getsockopt()"); } - fprintf(stderr,"managing spool request...\n"); - i = spool_request(spool_filename, uwsgi.workers[0].requests+1, buffer,wsgi_req.size) ; - wsgi_req.modifier = 255 ; - wsgi_req.size = 0 ; - if (i > 0) { - wsgi_req.modifier_arg = 1 ; - if (write(uwsgi.poll.fd,&wsgi_req,4) != 4) { - fprintf(stderr,"disconnected client, remove spool file.\n"); - /* client disconnect, remove spool file */ - if (unlink(spool_filename)) { - perror("unlink()"); - fprintf(stderr,"something horrible happened !!! check your spooler ASAP !!!\n"); - goodbye_cruel_world(); - } - } + memset (&sctp_ss, 0, sizeof (sctp_ss)); + + fprintf (stderr, "%d %d\n", sstatus.sstat_instrms, sstatus.sstat_outstrms); + + i = 0; + wsgi_req.size = sctp_recvmsg (uwsgi.poll.fd, buffer, uwsgi.buffer_size, 0, 0, &sctp_ss, 0); + if (wsgi_req.size < 0) { + perror ("sctp_recvmsg()"); } - else { - /* announce a failed spool request */ - wsgi_req.modifier_arg = 0 ; - i = write(uwsgi.poll.fd,&wsgi_req,4); - if (i != 4) { - perror("write()"); - } - } - close(uwsgi.poll.fd); - memset(&wsgi_req, 0, sizeof(struct wsgi_request)); - uwsgi.workers[0].requests++; uwsgi.workers[uwsgi.mywid].requests++; - continue; - } -#endif + fprintf (stderr, "received uwsgi message of %d bytes on stream id %d flags %d\n", wsgi_req.size, ntohs (sctp_ss.sinfo_stream), i); - else if (!wsgi_req.modifier || wsgi_req.modifier == UWSGI_MODIFIER_MANAGE_PATH_INFO) { - - /* Standard WSGI request */ - - if (!wsgi_req.size) { - fprintf(stderr,"Invalid WSGI request. skip.\n"); - close(uwsgi.poll.fd); - memset(&wsgi_req, 0, sizeof(struct wsgi_request)); - uwsgi.workers[0].requests++; uwsgi.workers[uwsgi.mywid].requests++; - continue; - } - - ptrbuf = buffer ; - bufferend = ptrbuf+wsgi_req.size ; - - - /* set an HTTP 500 status as default */ - wsgi_req.status = 500; - - - - while(ptrbuf < bufferend) { - if (ptrbuf+2 < bufferend) { - memcpy(&strsize,ptrbuf,2); - #ifdef __BIG_ENDIAN__ - strsize = uwsgi_swap16(strsize); - #endif - ptrbuf+=2; - if (ptrbuf+strsize < bufferend) { - // var key - hvec[wsgi_req.var_cnt].iov_base = ptrbuf ; - hvec[wsgi_req.var_cnt].iov_len = strsize ; - ptrbuf+=strsize; - if (ptrbuf+2 < bufferend) { - memcpy(&strsize,ptrbuf,2); - #ifdef __BIG_ENDIAN__ - strsize = uwsgi_swap16(strsize); - #endif - ptrbuf+=2 ; - if ( ptrbuf+strsize <= bufferend) { -#ifndef ROCK_SOLID - #ifdef UNBIT - if (single_app_mode == 0 && !strncmp("SCRIPT_NAME", hvec[wsgi_req.var_cnt].iov_base , hvec[wsgi_req.var_cnt].iov_len)) { - #else - if (!strncmp("SCRIPT_NAME", hvec[wsgi_req.var_cnt].iov_base , hvec[wsgi_req.var_cnt].iov_len)) { - #endif - // set the request app_id - // LOCKED SECTION - if (strsize > 0) { - if (uwsgi.has_threads && !i_have_gil) { - PyEval_RestoreThread(_save); - i_have_gil = 1; - } - zero = PyString_FromStringAndSize(ptrbuf, strsize) ; - if (PyDict_Contains(uwsgi.py_apps, zero)) { - wsgi_req.app_id = PyInt_AsLong( PyDict_GetItem(uwsgi.py_apps, zero) ); - } - else { - /* unavailable app for this SCRIPT_NAME */ - wsgi_req.app_id = -1 ; - } - Py_DECREF(zero); - if (uwsgi.has_threads && uwsgi.options[UWSGI_OPTION_THREADS] == 1) { - _save = PyEval_SaveThread(); - i_have_gil = 0; - } - } - // UNLOCK - } - else if (!strncmp("SERVER_PROTOCOL", hvec[wsgi_req.var_cnt].iov_base , hvec[wsgi_req.var_cnt].iov_len)) { -#else - if (!strncmp("SERVER_PROTOCOL", hvec[wsgi_req.var_cnt].iov_base , hvec[wsgi_req.var_cnt].iov_len)) { -#endif - wsgi_req.protocol = ptrbuf ; - wsgi_req.protocol_len = strsize ; - } - else if (!strncmp("REQUEST_URI", hvec[wsgi_req.var_cnt].iov_base, hvec[wsgi_req.var_cnt].iov_len)) { - wsgi_req.uri = ptrbuf ; - wsgi_req.uri_len = strsize ; - } - else if (!strncmp("QUERY_STRING", hvec[wsgi_req.var_cnt].iov_base, hvec[wsgi_req.var_cnt].iov_len)) { - wsgi_req.query_string = ptrbuf ; - wsgi_req.query_string_len = strsize ; - } - else if (!strncmp("REQUEST_METHOD", hvec[wsgi_req.var_cnt].iov_base, hvec[wsgi_req.var_cnt].iov_len)) { - wsgi_req.method = ptrbuf ; - wsgi_req.method_len = strsize ; - } - else if (!strncmp("REMOTE_ADDR", hvec[wsgi_req.var_cnt].iov_base, hvec[wsgi_req.var_cnt].iov_len)) { - wsgi_req.remote_addr = ptrbuf ; - wsgi_req.remote_addr_len = strsize ; - } - else if (!strncmp("REMOTE_USER", hvec[wsgi_req.var_cnt].iov_base, hvec[wsgi_req.var_cnt].iov_len)) { - wsgi_req.remote_user = ptrbuf ; - wsgi_req.remote_user_len = strsize ; - } -#ifdef UNBIT - else if (!strncmp("UNBIT_FLAGS", hvec[wsgi_req.var_cnt].iov_base, hvec[wsgi_req.var_cnt].iov_len)) { - wsgi_req.unbit_flags = *(unsigned long long *) ptrbuf ; - } -#endif - if (wsgi_req.var_cnt < uwsgi.vec_size-(4+1)) { - wsgi_req.var_cnt++ ; - } - else { - fprintf(stderr, "max vec size reached. skip this header.\n"); - break; - } - // var value - hvec[wsgi_req.var_cnt].iov_base = ptrbuf ; - hvec[wsgi_req.var_cnt].iov_len = strsize ; - if (wsgi_req.var_cnt < uwsgi.vec_size-(4+1)) { - wsgi_req.var_cnt++ ; - } - else { - fprintf(stderr, "max vec size reached. skip this header.\n"); - break; - } - ptrbuf+=strsize; - } - else { - break; - } - } - else { - break; - } - } - } - else { - break; - } - } - - - -#ifndef ROCK_SOLID - if (uwsgi.has_threads && !i_have_gil) { - PyEval_RestoreThread(_save); - i_have_gil = 1; - } -#endif - - - wsgi_file = fdopen(uwsgi.poll.fd,"r") ; - -#ifndef ROCK_SOLID - -#ifndef UNBIT - if (wsgi_req.app_id == -1 && uwsgi.xml_config == NULL) { -#else - if (wsgi_req.app_id == -1 && uwsgi.wsgi_config == NULL) { -#endif - for(i=0;i 0 || (wsgi_req.wsgi_callable_len > 0 && wsgi_req.wsgi_module_len > 0)) { - if ((wsgi_req.app_id = init_uwsgi_app(NULL, NULL)) == -1) { - internal_server_error(uwsgi.poll.fd, "wsgi application not found"); - goto clean ; - } - } - } - - - if (wsgi_req.app_id == -1) { - internal_server_error(uwsgi.poll.fd, "wsgi application not found"); - goto clean; - } - - - wi = &uwsgi.wsgi_apps[wsgi_req.app_id] ; - - if (uwsgi.single_interpreter == 0) { - if (!wi->interpreter) { - internal_server_error(uwsgi.poll.fd, "wsgi application's %d interpreter not found"); - goto clean; - } - - // set the interpreter - PyThreadState_Swap(wi->interpreter) ; - } - - -#endif - - - if (wsgi_req.protocol_len < 5) { - fprintf(stderr,"INVALID PROTOCOL: %.*s", wsgi_req.protocol_len, wsgi_req.protocol); - internal_server_error(uwsgi.poll.fd, "invalid HTTP protocol !!!"); - goto clean; - } - if (strncmp(wsgi_req.protocol, "HTTP/", 5)) { - fprintf(stderr,"INVALID PROTOCOL: %.*s", wsgi_req.protocol_len, wsgi_req.protocol); - internal_server_error(uwsgi.poll.fd, "invalid HTTP protocol !!!"); - goto clean; - } - - - - /* max 1 minute before harakiri */ - if (uwsgi.options[UWSGI_OPTION_HARAKIRI] > 0) { -#ifdef UNBIT - if (wsgi_req.modifier != 0) { - switch(wsgi_req.modifier) { - case UWSGI_MODIFIER_HT_S: - set_harakiri(wsgi_req.modifier_arg); - case UWSGI_MODIFIER_HT_M: - set_harakiri(wsgi_req.modifier_arg*60); - case UWSGI_MODIFIER_HT_H: - set_harakiri(wsgi_req.modifier_arg*3600); - } - } - else { -#endif - set_harakiri(uwsgi.options[UWSGI_OPTION_HARAKIRI]); -#ifdef UNBIT - } -#endif - } - - - for(i=0;iwsgi_environ, pydictkey, pydictvalue); - Py_DECREF(pydictkey); - Py_DECREF(pydictvalue); - } - - if (wsgi_req.modifier == UWSGI_MODIFIER_MANAGE_PATH_INFO) { - pydictkey = PyDict_GetItemString(wi->wsgi_environ,"SCRIPT_NAME"); - if (pydictkey) { - if (PyString_Check(pydictkey)) { - pydictvalue = PyDict_GetItemString(wi->wsgi_environ,"PATH_INFO"); - if (pydictvalue) { - if (PyString_Check(pydictvalue)) { - path_info = PyString_AsString(pydictvalue); - PyDict_SetItemString(wi->wsgi_environ, "PATH_INFO", PyString_FromString(path_info + PyString_Size(pydictkey))); - } - } - } - } - } - - - - - // set wsgi vars - - wsgi_socket = PyFile_FromFile(wsgi_file,"wsgi_input","r", NULL) ; - PyDict_SetItemString(wi->wsgi_environ, "wsgi.input", wsgi_socket ); - Py_DECREF(wsgi_socket) ; - -#ifndef ROCK_SOLID - PyDict_SetItemString(wi->wsgi_environ, "wsgi.file_wrapper", wi->wsgi_sendfile ); -#endif - - zero = PyTuple_New(2); - PyTuple_SetItem(zero, 0 , PyInt_FromLong(1)); - PyTuple_SetItem(zero, 1 , PyInt_FromLong(0)); - PyDict_SetItemString(wi->wsgi_environ, "wsgi.version", zero); - Py_DECREF(zero); - - zero = PyFile_FromFile(stderr, "wsgi_input","w", NULL) ; - PyDict_SetItemString(wi->wsgi_environ, "wsgi.errors", zero ); - Py_DECREF(zero) ; - - PyDict_SetItemString(wi->wsgi_environ, "wsgi.run_once", Py_False); - - PyDict_SetItemString(wi->wsgi_environ, "wsgi.multithread", Py_False); - if (uwsgi.numproc == 1) { - PyDict_SetItemString(wi->wsgi_environ, "wsgi.multiprocess", Py_False); - } - else { - PyDict_SetItemString(wi->wsgi_environ, "wsgi.multiprocess", Py_True); - } - - zero = PyString_FromString("http") ; - PyDict_SetItemString(wi->wsgi_environ, "wsgi.url_scheme", zero); - Py_DECREF(zero); - -#ifdef UNBIT - if (wsgi_req.unbit_flags & (unsigned long long) 1) { - if (uri_to_hex() <= 0) { - tmp_filename[0] = 0 ; - } - } -#endif - - - - - // call -#ifndef ROCK_SOLID - if (uwsgi.enable_profiler == 1) { - wsgi_result = PyEval_CallObject(wi->wsgi_cprofile_run, wi->wsgi_args); - if (PyErr_Occurred()) { - PyErr_Print(); - } - if (wsgi_result) { - Py_DECREF(wsgi_result); - wsgi_result = PyDict_GetItemString(wi->pymain_dict, "uwsgi_out"); - } } else { #endif - - wsgi_result = PyEval_CallObject(wi->wsgi_callable, wi->wsgi_args); - - if (PyErr_Occurred()) { - PyErr_Print(); - } -#ifndef ROCK_SOLID - } -#endif - - - - - if (wsgi_result) { - - -#ifndef ROCK_SOLID - if (wsgi_req.sendfile_fd > -1) { - rlen = lseek(wsgi_req.sendfile_fd, 0, SEEK_END) ; - if (rlen > 0) { - lseek(wsgi_req.sendfile_fd, 0, SEEK_SET) ; -#ifndef __linux__ - #if defined(__FreeBSD__) || defined(__DragonFly__) - - wsgi_req.response_size = sendfile(wsgi_req.sendfile_fd, uwsgi.poll.fd, 0, 0, NULL, (off_t *) &rlen, 0) ; - #elif __OpenBSD__ || __sun__ - char *no_sendfile_buf[4096] ; - int jlen = 0 ; - i = 0 ; - while(i < rlen) { - jlen = read(wsgi_req.sendfile_fd, no_sendfile_buf, 4096); - if (jlen<=0) { - perror("read()"); - break; - } - i += jlen; - jlen = write(uwsgi.poll.fd, no_sendfile_buf, jlen); - if (jlen<=0) { - perror("write()"); - break; - } - - } - #else - wsgi_req.response_size = sendfile(wsgi_req.sendfile_fd, uwsgi.poll.fd, 0, (off_t *) &rlen, NULL, 0) ; - #endif -#else - wsgi_req.response_size = sendfile(uwsgi.poll.fd, wsgi_req.sendfile_fd, NULL, rlen) ; -#endif - } - Py_DECREF(uwsgi.py_sendfile); - } - else { - -#endif - - wsgi_chunks = PyObject_GetIter(wsgi_result); - if (wsgi_chunks) { - while((wchunk = PyIter_Next(wsgi_chunks))) { - if (PyString_Check(wchunk)) { - if ( (i = write(uwsgi.poll.fd, PyString_AsString(wchunk), PyString_Size(wchunk))) < 0) { - perror("write()"); - } - wsgi_req.response_size += i ; -#ifdef UNBIT - if (save_to_disk >= 0) { - if (write(save_to_disk, PyString_AsString(wchunk), PyString_Size(wchunk)) < 0) { - perror("write()"); - close(save_to_disk); - save_to_disk = -1 ; - unlinkat(tmp_dir_fd, tmp_filename, 0); - } - } -#endif - } - else { - fprintf(stderr,"invalid output returned by the wsgi callable !!!\n"); - } - Py_DECREF(wchunk); - } - - if (PyErr_Occurred()) { - PyErr_Print(); - } - -#ifdef UNBIT - else if (save_to_disk >= 0) { - close(save_to_disk); - save_to_disk = -1 ; - fprintf(stderr,"[uWSGI cacher] output of request %llu (%.*s) on pid %d written to cache file %s\n",uwsgi.workers[0].requests+1, wsgi_req.uri_len, wsgi_req.uri, uwsgi.mypid,tmp_filename); - } -#endif - Py_DECREF(wsgi_chunks); - } -#ifndef ROCK_SOLID - } - if (uwsgi.enable_profiler == 0) { -#endif - Py_DECREF(wsgi_result); -#ifndef ROCK_SOLID + if (!uwsgi_parse_response (&uwsgi.poll, uwsgi.options[UWSGI_OPTION_SOCKET_TIMEOUT], (struct uwsgi_header *) &wsgi_req, buffer)) { + continue; } -#endif - } - - - - PyDict_Clear(wi->wsgi_environ); -#ifndef ROCK_SOLID - wi->requests++; -#endif - PyErr_Clear(); - if (uwsgi.options[UWSGI_OPTION_HARAKIRI] > 0) { - set_harakiri(0); - } -#ifndef ROCK_SOLID - if (uwsgi.single_interpreter == 0) { - // restoring main interpreter - PyThreadState_Swap(uwsgi.main_thread); +#ifdef SCTP } #endif -clean: - fclose(wsgi_file); -#ifndef ROCK_SOLID - if (uwsgi.has_threads && uwsgi.options[UWSGI_OPTION_THREADS] == 1) { - _save = PyEval_SaveThread(); - i_have_gil = 0 ; - } -#endif - uwsgi.workers[0].requests++; uwsgi.workers[uwsgi.mywid].requests++; - // GO LOGGING... - if (uwsgi.options[UWSGI_OPTION_LOGGING]) - log_request(&wsgi_req) ; + + ret = -1 ; + if (uwsgi.options[UWSGI_OPTION_HARAKIRI] > 0) { + set_harakiri(uwsgi.options[UWSGI_OPTION_HARAKIRI]); + } + if (uwsgi.hooks[wsgi_req.modifier] != NULL) { + ret = (*uwsgi.hooks[wsgi_req.modifier])(&uwsgi, &wsgi_req, buffer); + if (!ret) { + if (uwsgi.after_hooks[wsgi_req.modifier] != NULL) { + ret = (*uwsgi.after_hooks[wsgi_req.modifier])(&uwsgi, &wsgi_req, buffer); + } + } + } + else { + fprintf(stderr,"unknown uwsgi request type received: %d\n", wsgi_req.modifier); + } + + + if (uwsgi.workers[uwsgi.mywid].harakiri > 0) { + set_harakiri(0); + } + + close(uwsgi.poll.fd); + uwsgi.workers[0].requests++; + uwsgi.workers[uwsgi.mywid].requests++; + // defunct process reaper if (uwsgi.options[UWSGI_OPTION_REAPER] == 1) { - waitpid(-1, &waitpid_status, WNOHANG); + waitpid (-1, &waitpid_status, WNOHANG); } - // reset request - memset(&wsgi_req, 0, sizeof(struct wsgi_request)); + // reset request + memset (&wsgi_req, 0, sizeof (struct wsgi_request)); #ifdef UNBIT if (tmp_filename && tmp_dir_fd >= 0) { - tmp_filename[0] = 0 ; + tmp_filename[0] = 0; } #endif if (uwsgi.options[UWSGI_OPTION_MAX_REQUESTS] > 0 && uwsgi.workers[uwsgi.mywid].requests >= uwsgi.options[UWSGI_OPTION_MAX_REQUESTS]) { - goodbye_cruel_world(); + goodbye_cruel_world (); } #ifdef UNBIT if (check_for_memory_errors) { - if (syscall(357,&us,0) > 0) { + if (syscall (357, &us, 0) > 0) { if (us.memory_errors > 0) { - fprintf(stderr,"Unbit Kernel found a memory allocation error for process %d.\n", uwsgi.mypid); - goodbye_cruel_world(); + fprintf (stderr, "Unbit Kernel found a memory allocation error for process %d.\n", uwsgi.mypid); + goodbye_cruel_world (); } } } #endif - } - else { - fprintf(stderr,"Unsupported uwsgi modifier requested: %d\n", wsgi_req.modifier); - } +/* + } + else { + fprintf (stderr, "Unsupported uwsgi modifier requested: %d\n", wsgi_req.modifier); + } +*/ - } + } if (uwsgi.workers[uwsgi.mywid].manage_next_request == 0) { /* am i a grunt ? */ if (uwsgi.mywid > uwsgi.numproc) { - end_me() ; + end_me (); } else { - reload_me() ; + reload_me (); } } else { - goodbye_cruel_world(); + goodbye_cruel_world (); } /* never here */ - return 0 ; + return 0; } -void init_uwsgi_vars() { +void init_uwsgi_vars () { #ifndef UNBIT #ifndef ROCK_SOLID int i; #endif #endif - PyObject *pysys, *pysys_dict, *pypath ; + PyObject *pysys, *pysys_dict, *pypath; - /* add cwd to pythonpath */ - pysys = PyImport_ImportModule("sys"); - if (!pysys) { - PyErr_Print(); - exit(1); - } - pysys_dict = PyModule_GetDict(pysys); - pypath = PyDict_GetItemString(pysys_dict, "path"); - if (!pypath) { - PyErr_Print(); - exit(1); - } - if (PyList_Insert(pypath,0,PyString_FromString(".")) != 0) { - PyErr_Print(); + /* add cwd to pythonpath */ + pysys = PyImport_ImportModule ("sys"); + if (!pysys) { + PyErr_Print (); + exit (1); + } + pysys_dict = PyModule_GetDict (pysys); + pypath = PyDict_GetItemString (pysys_dict, "path"); + if (!pypath) { + PyErr_Print (); + exit (1); + } + if (PyList_Insert (pypath, 0, PyString_FromString (".")) != 0) { + PyErr_Print (); } #ifndef UNBIT #ifndef ROCK_SOLID - for(i=0; i< uwsgi.python_path_cnt; i++) { - if (PyList_Insert(pypath,0,PyString_FromString(uwsgi.python_path[i])) != 0) { - PyErr_Print(); + for (i = 0; i < uwsgi.python_path_cnt; i++) { + if (PyList_Insert (pypath, 0, PyString_FromString (uwsgi.python_path[i])) != 0) { + PyErr_Print (); } else { - fprintf(stderr, "added %s to pythonpath.\n", uwsgi.python_path[i]); + fprintf (stderr, "added %s to pythonpath.\n", uwsgi.python_path[i]); } } #endif @@ -2367,442 +1922,442 @@ void init_uwsgi_vars() { } #ifndef ROCK_SOLID -int init_uwsgi_app(PyObject *force_wsgi_dict, PyObject *my_callable) { - PyObject *wsgi_module, *wsgi_dict = NULL ; +int init_uwsgi_app (PyObject * force_wsgi_dict, PyObject * my_callable) { + PyObject *wsgi_module, *wsgi_dict = NULL; PyObject *pymain, *zero; PyObject *pycprof, *pycprof_dict; - char tmpstring[256] ; - int id ; + char tmpstring[256]; + int id; - struct uwsgi_app *wi ; + struct uwsgi_app *wi; - memset(tmpstring,0, 256) ; + memset (tmpstring, 0, 256); - if (wsgi_req.wsgi_script_len == 0 && ( (wsgi_req.wsgi_module_len == 0 || wsgi_req.wsgi_callable_len == 0) && uwsgi.wsgi_config == NULL && my_callable == NULL) ) { - fprintf(stderr, "invalid application (%.*s). skip.\n", wsgi_req.script_name_len, wsgi_req.script_name); + if (wsgi_req.wsgi_script_len == 0 && ((wsgi_req.wsgi_module_len == 0 || wsgi_req.wsgi_callable_len == 0) && uwsgi.wsgi_config == NULL && my_callable == NULL)) { + fprintf (stderr, "invalid application (%.*s). skip.\n", wsgi_req.script_name_len, wsgi_req.script_name); return -1; } if (uwsgi.wsgi_config && wsgi_req.wsgi_callable_len == 0 && my_callable == NULL) { - fprintf(stderr, "invalid application (%.*s). skip.\n", wsgi_req.script_name_len, wsgi_req.script_name); + fprintf (stderr, "invalid application (%.*s). skip.\n", wsgi_req.script_name_len, wsgi_req.script_name); return -1; } if (wsgi_req.wsgi_script_len > 255 || wsgi_req.wsgi_module_len > 255 || wsgi_req.wsgi_callable_len > 255) { - fprintf(stderr, "invalid application's string size. skip.\n"); + fprintf (stderr, "invalid application's string size. skip.\n"); return -1; } - id = uwsgi.wsgi_cnt ; + id = uwsgi.wsgi_cnt; if (wsgi_req.script_name_len == 0) { - wsgi_req.script_name_len = 1 ; - wsgi_req.script_name = (char *) app_slash ; - id = 0 ; + wsgi_req.script_name_len = 1; + wsgi_req.script_name = (char *) app_slash; + id = 0; } else if (wsgi_req.script_name_len == 1) { if (wsgi_req.script_name[0] == '/') { - id = 0 ; + id = 0; } } - zero = PyString_FromStringAndSize(wsgi_req.script_name, wsgi_req.script_name_len); + zero = PyString_FromStringAndSize (wsgi_req.script_name, wsgi_req.script_name_len); if (!zero) { - Py_FatalError("cannot get mountpoint python object !\n"); + Py_FatalError ("cannot get mountpoint python object !\n"); } - if (PyDict_GetItem(uwsgi.py_apps, zero) != NULL) { - Py_DECREF(zero); - fprintf(stderr, "mountpoint %.*s already configured. skip.\n", wsgi_req.script_name_len, wsgi_req.script_name); + if (PyDict_GetItem (uwsgi.py_apps, zero) != NULL) { + Py_DECREF (zero); + fprintf (stderr, "mountpoint %.*s already configured. skip.\n", wsgi_req.script_name_len, wsgi_req.script_name); return -1; } - Py_DECREF(zero); + Py_DECREF (zero); - wi = &uwsgi.wsgi_apps[id] ; + wi = &uwsgi.wsgi_apps[id]; - memset(wi, 0, sizeof(struct uwsgi_app)); + memset (wi, 0, sizeof (struct uwsgi_app)); if (uwsgi.single_interpreter == 0) { - wi->interpreter = Py_NewInterpreter(); + wi->interpreter = Py_NewInterpreter (); if (!wi->interpreter) { - fprintf(stderr,"unable to initialize the new interpreter\n"); - exit(1); + fprintf (stderr, "unable to initialize the new interpreter\n"); + exit (1); } - PyThreadState_Swap(wi->interpreter) ; + PyThreadState_Swap (wi->interpreter); #ifndef PYTHREE - init_uwsgi_embedded_module(); + init_uwsgi_embedded_module (); #endif - init_uwsgi_vars(); - fprintf(stderr,"interpreter for app %d initialized.\n", id); + init_uwsgi_vars (); + fprintf (stderr, "interpreter for app %d initialized.\n", id); } if (uwsgi.paste) { - wi->wsgi_callable = my_callable ; - Py_INCREF(my_callable); + wi->wsgi_callable = my_callable; + Py_INCREF (my_callable); } else { - if (uwsgi.wsgi_config == NULL) { - if (wsgi_req.wsgi_script_len > 0) { - memcpy(tmpstring, wsgi_req.wsgi_script, wsgi_req.wsgi_script_len) ; - wsgi_module = PyImport_ImportModule(tmpstring) ; - if (!wsgi_module) { - PyErr_Print(); - if (uwsgi.single_interpreter == 0) { - Py_EndInterpreter(wi->interpreter); - PyThreadState_Swap(uwsgi.main_thread) ; + if (uwsgi.wsgi_config == NULL) { + if (wsgi_req.wsgi_script_len > 0) { + memcpy (tmpstring, wsgi_req.wsgi_script, wsgi_req.wsgi_script_len); + wsgi_module = PyImport_ImportModule (tmpstring); + if (!wsgi_module) { + PyErr_Print (); + if (uwsgi.single_interpreter == 0) { + Py_EndInterpreter (wi->interpreter); + PyThreadState_Swap (uwsgi.main_thread); + } + return -1; + } + wsgi_req.wsgi_callable = "application"; + wsgi_req.wsgi_callable_len = 11; + } + else { + memcpy (tmpstring, wsgi_req.wsgi_module, wsgi_req.wsgi_module_len); + wsgi_module = PyImport_ImportModule (tmpstring); + if (!wsgi_module) { + PyErr_Print (); + if (uwsgi.single_interpreter == 0) { + Py_EndInterpreter (wi->interpreter); + PyThreadState_Swap (uwsgi.main_thread); + } + return -1; } - return -1 ; - } - wsgi_req.wsgi_callable = "application" ; - wsgi_req.wsgi_callable_len = 11; - } - else { - memcpy(tmpstring, wsgi_req.wsgi_module, wsgi_req.wsgi_module_len) ; - wsgi_module = PyImport_ImportModule(tmpstring) ; - if (!wsgi_module) { - PyErr_Print(); - if (uwsgi.single_interpreter == 0) { - Py_EndInterpreter(wi->interpreter); - PyThreadState_Swap(uwsgi.main_thread) ; - } - return -1 ; - } - } - - wsgi_dict = PyModule_GetDict(wsgi_module); - if (!wsgi_dict) { - PyErr_Print(); - if (uwsgi.single_interpreter == 0) { - Py_EndInterpreter(wi->interpreter); - PyThreadState_Swap(uwsgi.main_thread) ; } - return -1 ; - } - } - else { - wsgi_dict = force_wsgi_dict; + wsgi_dict = PyModule_GetDict (wsgi_module); + if (!wsgi_dict) { + PyErr_Print (); + if (uwsgi.single_interpreter == 0) { + Py_EndInterpreter (wi->interpreter); + PyThreadState_Swap (uwsgi.main_thread); + } + return -1; + } + + } + else { + wsgi_dict = force_wsgi_dict; + } + + + memset (tmpstring, 0, 256); + memcpy (tmpstring, wsgi_req.wsgi_callable, wsgi_req.wsgi_callable_len); + if (my_callable) { + wi->wsgi_callable = my_callable; + Py_INCREF (my_callable); + } + else if (wsgi_dict) { + wi->wsgi_callable = PyDict_GetItemString (wsgi_dict, tmpstring); + } + else { + return -1; + } + } - memset(tmpstring, 0, 256); - memcpy(tmpstring, wsgi_req.wsgi_callable, wsgi_req.wsgi_callable_len) ; - if (my_callable) { - wi->wsgi_callable = my_callable; - Py_INCREF(my_callable); - } - else if (wsgi_dict) { - wi->wsgi_callable = PyDict_GetItemString(wsgi_dict, tmpstring); - } - else { + if (!wi->wsgi_callable) { + PyErr_Print (); + if (uwsgi.single_interpreter == 0) { + Py_EndInterpreter (wi->interpreter); + PyThreadState_Swap (uwsgi.main_thread); + } return -1; } + + wi->wsgi_environ = PyDict_New (); + if (!wi->wsgi_environ) { + PyErr_Print (); + if (uwsgi.single_interpreter == 0) { + Py_EndInterpreter (wi->interpreter); + PyThreadState_Swap (uwsgi.main_thread); + } + return -1; } - - if (!wi->wsgi_callable) { - PyErr_Print(); - if (uwsgi.single_interpreter == 0) { - Py_EndInterpreter(wi->interpreter); - PyThreadState_Swap(uwsgi.main_thread) ; - } - return -1 ; - } - - - wi->wsgi_environ = PyDict_New(); - if (!wi->wsgi_environ) { - PyErr_Print(); - if (uwsgi.single_interpreter == 0) { - Py_EndInterpreter(wi->interpreter); - PyThreadState_Swap(uwsgi.main_thread) ; - } - return -1 ; - } - if (wsgi_dict) { - wi->wsgi_harakiri = PyDict_GetItemString(wsgi_dict, "harakiri"); + wi->wsgi_harakiri = PyDict_GetItemString (wsgi_dict, "harakiri"); if (wi->wsgi_harakiri) { - fprintf(stderr, "initialized Harakiri custom handler: %p.\n", wi->wsgi_harakiri); + fprintf (stderr, "initialized Harakiri custom handler: %p.\n", wi->wsgi_harakiri); } } if (uwsgi.enable_profiler) { - pymain = PyImport_AddModule("__main__"); + pymain = PyImport_AddModule ("__main__"); if (!pymain) { - PyErr_Print(); - exit(1); + PyErr_Print (); + exit (1); } - wi->pymain_dict = PyModule_GetDict(pymain); + wi->pymain_dict = PyModule_GetDict (pymain); if (!wi->pymain_dict) { - PyErr_Print(); - exit(1); + PyErr_Print (); + exit (1); } - if (PyDict_SetItem(wi->pymain_dict, PyString_FromFormat("uwsgi_application__%d", id), wi->wsgi_callable)) { - PyErr_Print(); - exit(1); + if (PyDict_SetItem (wi->pymain_dict, PyString_FromFormat ("uwsgi_application__%d", id), wi->wsgi_callable)) { + PyErr_Print (); + exit (1); } - if (PyDict_SetItem(wi->pymain_dict, PyString_FromFormat("uwsgi_environ__%d", id), wi->wsgi_environ)) { - PyErr_Print(); - exit(1); + if (PyDict_SetItem (wi->pymain_dict, PyString_FromFormat ("uwsgi_environ__%d", id), wi->wsgi_environ)) { + PyErr_Print (); + exit (1); } - if (PyDict_SetItem(wi->pymain_dict, PyString_FromFormat("uwsgi_spit__%d", id), wsgi_spitout)) { - PyErr_Print(); - exit(1); - } - - pycprof = PyImport_ImportModule("cProfile"); - if (!pycprof) { - PyErr_Print(); - fprintf(stderr, "trying old profile module... "); - pycprof = PyImport_ImportModule("profile"); - if (!pycprof) { - fprintf(stderr, "doh!!!\n"); - PyErr_Print(); - exit(1); - } - else { - fprintf(stderr, "ok and set stdout to linebuf mode.\n"); - } - } - pycprof_dict = PyModule_GetDict(pycprof); - if (!pycprof_dict) { - PyErr_Print(); - exit(1); - } - wi->wsgi_cprofile_run = PyDict_GetItemString(pycprof_dict, "run"); - if (!wi->wsgi_cprofile_run) { - PyErr_Print(); - exit(1); + if (PyDict_SetItem (wi->pymain_dict, PyString_FromFormat ("uwsgi_spit__%d", id), wsgi_spitout)) { + PyErr_Print (); + exit (1); } - wi->wsgi_args = PyTuple_New(1) ; - if (PyTuple_SetItem(wi->wsgi_args,0, PyString_FromFormat("uwsgi_out = uwsgi_application__%d(uwsgi_environ__%d,uwsgi_spit__%d)", id, id, id) )) { - PyErr_Print(); - if (uwsgi.single_interpreter == 0) { - Py_EndInterpreter(wi->interpreter); - PyThreadState_Swap(uwsgi.main_thread) ; + pycprof = PyImport_ImportModule ("cProfile"); + if (!pycprof) { + PyErr_Print (); + fprintf (stderr, "trying old profile module... "); + pycprof = PyImport_ImportModule ("profile"); + if (!pycprof) { + fprintf (stderr, "doh!!!\n"); + PyErr_Print (); + exit (1); } - return -1 ; + else { + fprintf (stderr, "ok and set stdout to linebuf mode.\n"); + } + } + pycprof_dict = PyModule_GetDict (pycprof); + if (!pycprof_dict) { + PyErr_Print (); + exit (1); + } + wi->wsgi_cprofile_run = PyDict_GetItemString (pycprof_dict, "run"); + if (!wi->wsgi_cprofile_run) { + PyErr_Print (); + exit (1); + } + + wi->wsgi_args = PyTuple_New (1); + if (PyTuple_SetItem (wi->wsgi_args, 0, PyString_FromFormat ("uwsgi_out = uwsgi_application__%d(uwsgi_environ__%d,uwsgi_spit__%d)", id, id, id))) { + PyErr_Print (); + if (uwsgi.single_interpreter == 0) { + Py_EndInterpreter (wi->interpreter); + PyThreadState_Swap (uwsgi.main_thread); + } + return -1; } } else { - wi->wsgi_args = PyTuple_New(2) ; - if (PyTuple_SetItem(wi->wsgi_args,0, wi->wsgi_environ)) { - PyErr_Print(); + wi->wsgi_args = PyTuple_New (2); + if (PyTuple_SetItem (wi->wsgi_args, 0, wi->wsgi_environ)) { + PyErr_Print (); if (uwsgi.single_interpreter == 0) { - Py_EndInterpreter(wi->interpreter); - PyThreadState_Swap(uwsgi.main_thread) ; + Py_EndInterpreter (wi->interpreter); + PyThreadState_Swap (uwsgi.main_thread); } - return -1 ; - } - if (PyTuple_SetItem(wi->wsgi_args,1, wsgi_spitout)) { - PyErr_Print(); + return -1; + } + if (PyTuple_SetItem (wi->wsgi_args, 1, wsgi_spitout)) { + PyErr_Print (); if (uwsgi.single_interpreter == 0) { - Py_EndInterpreter(wi->interpreter); - PyThreadState_Swap(uwsgi.main_thread) ; + Py_EndInterpreter (wi->interpreter); + PyThreadState_Swap (uwsgi.main_thread); } - return -1 ; - } + return -1; + } } // prepare sendfile() - wi->wsgi_sendfile = PyCFunction_New(uwsgi_sendfile_method,NULL) ; + wi->wsgi_sendfile = PyCFunction_New (uwsgi_sendfile_method, NULL); if (uwsgi.single_interpreter == 0) { - PyThreadState_Swap(uwsgi.main_thread); + PyThreadState_Swap (uwsgi.main_thread); } - memset(tmpstring, 0, 256); - memcpy(tmpstring, wsgi_req.script_name, wsgi_req.script_name_len); - PyDict_SetItemString(uwsgi.py_apps, tmpstring, PyInt_FromLong(id)); - PyErr_Print(); + memset (tmpstring, 0, 256); + memcpy (tmpstring, wsgi_req.script_name, wsgi_req.script_name_len); + PyDict_SetItemString (uwsgi.py_apps, tmpstring, PyInt_FromLong (id)); + PyErr_Print (); - fprintf(stderr,"application %d (%s) ready\n", id, tmpstring); + fprintf (stderr, "application %d (%s) ready\n", id, tmpstring); - if (id == 0){ - fprintf(stderr,"setting default application to 0\n"); - uwsgi.default_app = 0 ; - } + if (id == 0) { + fprintf (stderr, "setting default application to 0\n"); + uwsgi.default_app = 0; + } else { - uwsgi.wsgi_cnt++; + uwsgi.wsgi_cnt++; } - return id ; + return id; } -void uwsgi_paste_config() { +void uwsgi_paste_config () { PyObject *paste_module, *paste_dict, *paste_loadapp; - PyObject *paste_arg, *paste_app ; + PyObject *paste_arg, *paste_app; - fprintf(stderr,"Loading paste environment: %s\n", uwsgi.paste); - paste_module = PyImport_ImportModule("paste.deploy"); + fprintf (stderr, "Loading paste environment: %s\n", uwsgi.paste); + paste_module = PyImport_ImportModule ("paste.deploy"); if (!paste_module) { - PyErr_Print(); - exit(1); + PyErr_Print (); + exit (1); } - paste_dict = PyModule_GetDict(paste_module); + paste_dict = PyModule_GetDict (paste_module); if (!paste_dict) { - PyErr_Print(); - exit(1); - } + PyErr_Print (); + exit (1); + } - paste_loadapp = PyDict_GetItemString(paste_dict, "loadapp"); + paste_loadapp = PyDict_GetItemString (paste_dict, "loadapp"); if (!paste_loadapp) { - PyErr_Print(); - exit(1); + PyErr_Print (); + exit (1); } - paste_arg = PyTuple_New(1); + paste_arg = PyTuple_New (1); if (!paste_arg) { - PyErr_Print(); - exit(1); + PyErr_Print (); + exit (1); } - if (PyTuple_SetItem(paste_arg, 0 , PyString_FromString(uwsgi.paste))) { - PyErr_Print(); - exit(1); + if (PyTuple_SetItem (paste_arg, 0, PyString_FromString (uwsgi.paste))) { + PyErr_Print (); + exit (1); } - paste_app = PyEval_CallObject(paste_loadapp, paste_arg); + paste_app = PyEval_CallObject (paste_loadapp, paste_arg); if (!paste_app) { - PyErr_Print(); - exit(1); + PyErr_Print (); + exit (1); } - init_uwsgi_app(NULL, paste_app); + init_uwsgi_app (NULL, paste_app); } -void uwsgi_wsgi_config() { +void uwsgi_wsgi_config () { - PyObject *wsgi_module, *wsgi_dict ; + PyObject *wsgi_module, *wsgi_dict; #ifndef PYTHREE - PyObject *uwsgi_module, *uwsgi_dict ; + PyObject *uwsgi_module, *uwsgi_dict; #endif PyObject *applications; PyObject *app_list; - int ret; + int ret ; Py_ssize_t i; - PyObject *app_mnt, *app_app ; + PyObject *app_mnt, *app_app; - wsgi_module = PyImport_ImportModule(uwsgi.wsgi_config) ; - if (!wsgi_module) { - PyErr_Print(); - exit(1); + wsgi_module = PyImport_ImportModule (uwsgi.wsgi_config); + if (!wsgi_module) { + PyErr_Print (); + exit (1); } - wsgi_dict = PyModule_GetDict(wsgi_module); - if (!wsgi_dict) { - PyErr_Print(); - exit(1); + wsgi_dict = PyModule_GetDict (wsgi_module); + if (!wsgi_dict) { + PyErr_Print (); + exit (1); } - fprintf(stderr,"...getting the applications list from the '%s' module...\n", uwsgi.wsgi_config); + fprintf (stderr, "...getting the applications list from the '%s' module...\n", uwsgi.wsgi_config); #ifndef PYTHREE - uwsgi_module = PyImport_ImportModule("uwsgi") ; - if (!uwsgi_module) { - PyErr_Print(); - exit(1); + uwsgi_module = PyImport_ImportModule ("uwsgi"); + if (!uwsgi_module) { + PyErr_Print (); + exit (1); } - uwsgi_dict = PyModule_GetDict(uwsgi_module); - if (!uwsgi_dict) { - PyErr_Print(); - exit(1); + uwsgi_dict = PyModule_GetDict (uwsgi_module); + if (!uwsgi_dict) { + PyErr_Print (); + exit (1); } - - applications = PyDict_GetItemString(uwsgi_dict, "applications"); - if (!PyDict_Check(applications)) { - fprintf(stderr,"uwsgi.applications dictionary is not defined, trying with the (deprecated) \"applications\" one...\n"); + + applications = PyDict_GetItemString (uwsgi_dict, "applications"); + if (!PyDict_Check (applications)) { + fprintf (stderr, "uwsgi.applications dictionary is not defined, trying with the (deprecated) \"applications\" one...\n"); #endif - applications = PyDict_GetItemString(wsgi_dict, "applications"); + applications = PyDict_GetItemString (wsgi_dict, "applications"); if (!applications) { - fprintf(stderr,"applications dictionary is not defined, trying with the \"application\" callable.\n"); - app_app = PyDict_GetItemString(wsgi_dict, "application"); + fprintf (stderr, "applications dictionary is not defined, trying with the \"application\" callable.\n"); + app_app = PyDict_GetItemString (wsgi_dict, "application"); if (app_app) { - applications = PyDict_New(); + applications = PyDict_New (); if (!applications) { - fprintf(stderr,"could not initialize applications dictionary\n"); - exit(1); + fprintf (stderr, "could not initialize applications dictionary\n"); + exit (1); } - if (PyDict_SetItemString(applications, "/", app_app)) { - PyErr_Print(); - fprintf(stderr,"unable to set default application\n"); - exit(1); + if (PyDict_SetItemString (applications, "/", app_app)) { + PyErr_Print (); + fprintf (stderr, "unable to set default application\n"); + exit (1); } } else { - fprintf(stderr,"static applications not defined, you have to used the dynamic one...\n"); - return ; + fprintf (stderr, "static applications not defined, you have to used the dynamic one...\n"); + return; } } #ifndef PYTHREE } #endif - if (!PyDict_Check(applications)) { - fprintf(stderr,"The 'applications' object must be a dictionary.\n"); - exit(1); + if (!PyDict_Check (applications)) { + fprintf (stderr, "The 'applications' object must be a dictionary.\n"); + exit (1); } - app_list = PyDict_Keys(applications); + app_list = PyDict_Keys (applications); if (!app_list) { - PyErr_Print(); - exit(1); + PyErr_Print (); + exit (1); } - if (PyList_Size(app_list) < 1) { - fprintf(stderr,"You must define an app.\n"); - exit(1); + if (PyList_Size (app_list) < 1) { + fprintf (stderr, "You must define an app.\n"); + exit (1); } - for(i=0;iob_type->tp_name); - exit(1); - } + if (!PyString_Check (app_app) && !PyFunction_Check (app_app) && !PyCallable_Check (app_app)) { + fprintf (stderr, "the app callable must be a string, a function or a callable. (found %s)\n", app_app->ob_type->tp_name); + exit (1); + } - if (PyString_Check(app_app)) { - wsgi_req.wsgi_callable = PyString_AsString(app_app) ; - wsgi_req.wsgi_callable_len = strlen(wsgi_req.wsgi_callable); - fprintf(stderr,"initializing [%s => %s] app...\n", wsgi_req.script_name, wsgi_req.wsgi_callable); - ret = init_uwsgi_app(wsgi_dict, NULL); + if (PyString_Check (app_app)) { + wsgi_req.wsgi_callable = PyString_AsString (app_app); + wsgi_req.wsgi_callable_len = strlen (wsgi_req.wsgi_callable); + fprintf (stderr, "initializing [%s => %s] app...\n", wsgi_req.script_name, wsgi_req.wsgi_callable); + ret = init_uwsgi_app (wsgi_dict, NULL); } else { - fprintf(stderr,"initializing [%s] app...\n", wsgi_req.script_name); - ret = init_uwsgi_app(wsgi_dict, app_app); + fprintf (stderr, "initializing [%s] app...\n", wsgi_req.script_name); + ret = init_uwsgi_app (wsgi_dict, app_app); } if (ret < 0) { - fprintf(stderr,"...goodbye cruel world...\n"); - exit(1); + fprintf (stderr, "...goodbye cruel world...\n"); + exit (1); } - Py_DECREF(app_mnt); - Py_DECREF(app_app); + Py_DECREF (app_mnt); + Py_DECREF (app_app); } } @@ -2814,101 +2369,101 @@ void uwsgi_wsgi_config() { #ifndef ROCK_SOLID -void uwsgi_xml_config() { +void uwsgi_xml_config () { xmlDoc *doc = NULL; xmlNode *element = NULL; xmlNode *node = NULL; xmlNode *node2 = NULL; xmlChar *xml_uwsgi_mountpoint = NULL; - xmlChar *xml_uwsgi_script = NULL ; + xmlChar *xml_uwsgi_script = NULL; - - doc = xmlReadFile(uwsgi.xml_config, NULL, 0); + + doc = xmlReadFile (uwsgi.xml_config, NULL, 0); if (doc == NULL) { - fprintf(stderr, "could not parse file %s.\n", uwsgi.xml_config); - exit(1); + fprintf (stderr, "could not parse file %s.\n", uwsgi.xml_config); + exit (1); } - fprintf(stderr, "parsing config file %s\n", uwsgi.xml_config); + fprintf (stderr, "parsing config file %s\n", uwsgi.xml_config); - element = xmlDocGetRootElement(doc); + element = xmlDocGetRootElement (doc); if (element == NULL) { - fprintf(stderr, "invalid xml config file.\n"); - exit(1); + fprintf (stderr, "invalid xml config file.\n"); + exit (1); } - if (strcmp((char *)element->name, "uwsgi")) { - fprintf(stderr, "invalid xml root element, expected.\n"); - exit(1); + if (strcmp ((char *) element->name, "uwsgi")) { + fprintf (stderr, "invalid xml root element, expected.\n"); + exit (1); } // first check for pythonpath - for(node = element->children; node; node = node->next) { + for (node = element->children; node; node = node->next) { if (node->type == XML_ELEMENT_NODE) { - if (!strcmp((char *) node->name, "pythonpath")) { + if (!strcmp ((char *) node->name, "pythonpath")) { if (!node->children) { - fprintf(stderr, "no path defined for pythonpath. skip.\n"); - continue; - } + fprintf (stderr, "no path defined for pythonpath. skip.\n"); + continue; + } if (!node->children->content) { - fprintf(stderr, "invalid path for pythonpath. skip.\n"); - continue; + fprintf (stderr, "invalid path for pythonpath. skip.\n"); + continue; } if (uwsgi.python_path_cnt < 63) { - uwsgi.python_path[uwsgi.python_path_cnt] = malloc( strlen((char *)node->children->content) + 1 ); - memset(uwsgi.python_path[uwsgi.python_path_cnt], 0, strlen( (char *) node->children->content) + 1); - strcpy(uwsgi.python_path[uwsgi.python_path_cnt], (char *) node->children->content); + uwsgi.python_path[uwsgi.python_path_cnt] = malloc (strlen ((char *) node->children->content) + 1); + memset (uwsgi.python_path[uwsgi.python_path_cnt], 0, strlen ((char *) node->children->content) + 1); + strcpy (uwsgi.python_path[uwsgi.python_path_cnt], (char *) node->children->content); uwsgi.python_path_cnt++; } else { - fprintf(stderr, "max pythonpath element reached. skip.\n"); - continue; - } - } - } - } - - // ... then for wsgi apps - for(node = element->children; node; node = node->next) { - if (node->type == XML_ELEMENT_NODE) { - - if (!strcmp((char *) node->name, "app")) { - xml_uwsgi_mountpoint = xmlGetProp(node, (const xmlChar *)"mountpoint"); - if (xml_uwsgi_mountpoint == NULL) { - fprintf(stderr, "no mountpoint defined for app. skip.\n"); + fprintf (stderr, "max pythonpath element reached. skip.\n"); continue; } - wsgi_req.script_name = (char *) xml_uwsgi_mountpoint ; - wsgi_req.script_name_len = strlen(wsgi_req.script_name); - - for(node2 = node->children; node2; node2 = node2->next) { - if (node2->type == XML_ELEMENT_NODE) { - if (!strcmp((char *) node2->name, "script")) { - if (!node2->children) { - fprintf(stderr, "no wsgi script defined. skip.\n"); - continue; - } - xml_uwsgi_script = node2->children->content ; - if (xml_uwsgi_script == NULL) { - fprintf(stderr, "no wsgi script defined. skip.\n"); - continue; - } - wsgi_req.wsgi_script = (char *) xml_uwsgi_script ; - wsgi_req.wsgi_script_len = strlen(wsgi_req.wsgi_script); - init_uwsgi_app(NULL, NULL); - } - } - } } } } - - xmlFreeDoc(doc); - xmlCleanupParser(); + // ... then for wsgi apps + for (node = element->children; node; node = node->next) { + if (node->type == XML_ELEMENT_NODE) { - fprintf(stderr, "config file parsed.\n"); + if (!strcmp ((char *) node->name, "app")) { + xml_uwsgi_mountpoint = xmlGetProp (node, (const xmlChar *) "mountpoint"); + if (xml_uwsgi_mountpoint == NULL) { + fprintf (stderr, "no mountpoint defined for app. skip.\n"); + continue; + } + wsgi_req.script_name = (char *) xml_uwsgi_mountpoint; + wsgi_req.script_name_len = strlen (wsgi_req.script_name); + + for (node2 = node->children; node2; node2 = node2->next) { + if (node2->type == XML_ELEMENT_NODE) { + if (!strcmp ((char *) node2->name, "script")) { + if (!node2->children) { + fprintf (stderr, "no wsgi script defined. skip.\n"); + continue; + } + xml_uwsgi_script = node2->children->content; + if (xml_uwsgi_script == NULL) { + fprintf (stderr, "no wsgi script defined. skip.\n"); + continue; + } + wsgi_req.wsgi_script = (char *) xml_uwsgi_script; + wsgi_req.wsgi_script_len = strlen (wsgi_req.wsgi_script); + init_uwsgi_app (NULL, NULL); + } + } + } + } + } + } + + + xmlFreeDoc (doc); + xmlCleanupParser (); + + fprintf (stderr, "config file parsed.\n"); } @@ -2918,162 +2473,152 @@ void uwsgi_xml_config() { #ifdef UNBIT -int uri_to_hex() -{ - int i=0,j=0 ; +int uri_to_hex () { + int i = 0, j = 0; if (wsgi_req.uri_len < 1) { - return 0 ; + return 0; } - if (wsgi_req.uri_len*2 > 8192) { - return 0 ; + if (wsgi_req.uri_len * 2 > 8192) { + return 0; } - for ( i = 0;i < wsgi_req.uri_len ; i++ ) { - sprintf(tmp_filename+j, "%02X", wsgi_req.uri[i]); j+=2; + for (i = 0; i < wsgi_req.uri_len; i++) { + sprintf (tmp_filename + j, "%02X", wsgi_req.uri[i]); + j += 2; } - - return j ; + + return j; } #endif #ifndef PYTHREE #ifndef ROCK_SOLID -void init_uwsgi_embedded_module() { +void init_uwsgi_embedded_module () { PyObject *new_uwsgi_module, *zero; - int i ; + int i; /* initialize for stats */ - if (uwsgi.master_process) { - uwsgi.workers_tuple = PyTuple_New(uwsgi.maxworkers); - for(i=0;i 0 && uwsgi.sharedarea) { - init_uwsgi_module_sharedarea(new_uwsgi_module); + init_uwsgi_module_sharedarea (new_uwsgi_module); } } #endif #endif #ifndef ROCK_SOLID -pid_t spooler_start(int serverfd, PyObject *uwsgi_module) { - pid_t pid ; +pid_t spooler_start (int serverfd, PyObject * uwsgi_module) { + pid_t pid; - pid = fork(); - if (pid < 0) { - perror("fork()"); - exit(1); - } + pid = fork (); + if (pid < 0) { + perror ("fork()"); + exit (1); + } else if (pid == 0) { - close(serverfd); - spooler(uwsgi_module); + close (serverfd); + spooler (uwsgi_module); } else if (pid > 0) { - fprintf(stderr,"spawned the uWSGI spooler on dir %s with pid %d\n", spool_dir, pid); + fprintf (stderr, "spawned the uWSGI spooler on dir %s with pid %d\n", spool_dir, pid); } - return pid ; + return pid; } #endif diff --git a/uwsgi.h b/uwsgi.h index c8ac68fd..623e15e0 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -1,6 +1,7 @@ /* uWSGI */ +/* indent -i8 -br -brs -brf -l0 -npsl */ #include @@ -10,6 +11,11 @@ #include #include #include + +#ifdef SCTP +#include +#endif + #include #include #include @@ -18,6 +24,11 @@ #include +#include + +#include + + #include #include #include @@ -36,18 +47,17 @@ #ifdef __APPLE__ - #include - #include - #include +#include +#include +#include #endif #ifdef UNBIT -#undef _XOPEN_SOURCE #include "unbit.h" #endif #ifdef _POSIX_C_SOURCE - #undef _POSIX_C_SOURCE +#undef _POSIX_C_SOURCE #endif #ifdef __sun__ #undef _FILE_OFFSET_BITS @@ -56,18 +66,26 @@ #define MAX_PYARGV 10 +#ifndef ROCK_SOLID +#ifdef __linux__ +#include +#endif +#endif + +#undef _XOPEN_SOURCE #include #if PY_MINOR_VERSION == 4 && PY_MAJOR_VERSION == 2 - #define Py_ssize_t int +#define Py_ssize_t int #endif #if PY_MAJOR_VERSION > 2 - #define PYTHREE +#define PYTHREE #endif -PyAPI_FUNC(PyObject *) PyMarshal_WriteObjectToString(PyObject *, int); -PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromString(char *, Py_ssize_t); + +PyAPI_FUNC (PyObject *) PyMarshal_WriteObjectToString (PyObject *, int); +PyAPI_FUNC (PyObject *) PyMarshal_ReadObjectFromString (char *, Py_ssize_t); #define LONG_ARGS_PIDFILE 17001 @@ -79,6 +97,7 @@ PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromString(char *, Py_ssize_t); #define LONG_ARGS_CHECK_INTERVAL 17007 #define LONG_ARGS_PYARGV 17008 #define LONG_ARGS_LIMIT_AS 17009 +#define LONG_ARGS_UDP 17010 #ifdef __linux__ @@ -104,7 +123,6 @@ PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromString(char *, Py_ssize_t); #define UWSGI_MODIFIER_HT_S 1 #define UWSGI_MODIFIER_HT_M 2 #define UWSGI_MODIFIER_HT_H 3 -#undef _XOPEN_SOURCE #endif #define UWSGI_MODIFIER_ADMIN_REQUEST 10 @@ -119,16 +137,16 @@ PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromString(char *, Py_ssize_t); #define UWSGI_MODIFIER_RESPONSE 255 #ifdef PYTHREE - #define PyInt_FromLong PyLong_FromLong - #define PyInt_AsLong PyLong_AsLong - #define PyInt_Check PyLong_Check - #define PyString_Check PyUnicode_Check - #define PyString_FromStringAndSize PyUnicode_FromStringAndSize - #define PyString_FromFormat PyUnicode_FromFormat - #define PyString_FromString PyUnicode_FromString - #define PyString_Size PyUnicode_GET_DATA_SIZE - #define PyString_AsString (char *) PyUnicode_AS_UNICODE - #define PyFile_FromFile(A,B,C,D) PyFile_FromFd(fileno((A)), (B), (C), -1, NULL, NULL, NULL, 0) +#define PyInt_FromLong PyLong_FromLong +#define PyInt_AsLong PyLong_AsLong +#define PyInt_Check PyLong_Check +#define PyString_Check PyUnicode_Check +#define PyString_FromStringAndSize PyUnicode_FromStringAndSize +#define PyString_FromFormat PyUnicode_FromFormat +#define PyString_FromString PyUnicode_FromString +#define PyString_Size PyUnicode_GET_DATA_SIZE +#define PyString_AsString (char *) PyUnicode_AS_UNICODE +#define PyFile_FromFile(A,B,C,D) PyFile_FromFd(fileno((A)), (B), (C), -1, NULL, NULL, NULL, 0) #endif @@ -140,122 +158,173 @@ PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromString(char *, Py_ssize_t); #define MAX_VARS 64 -struct uwsgi_app { + struct uwsgi_app { #ifndef ROCK_SOLID - PyThreadState *interpreter ; - PyObject *pymain_dict ; + PyThreadState *interpreter; + PyObject *pymain_dict; #endif #ifdef ROCK_SOLID - PyObject *wsgi_module; - PyObject *wsgi_dict; + PyObject *wsgi_module; + PyObject *wsgi_dict; #endif - PyObject *wsgi_callable ; - PyObject *wsgi_environ ; - PyObject *wsgi_args; - PyObject *wsgi_harakiri; + PyObject *wsgi_callable; + PyObject *wsgi_environ; + PyObject *wsgi_args; + PyObject *wsgi_harakiri; #ifndef ROCK_SOLID - PyObject *wsgi_sendfile; - PyObject *wsgi_cprofile_run; - int requests ; + PyObject *wsgi_sendfile; + PyObject *wsgi_cprofile_run; + int requests; #endif -}; + }; + +struct __attribute__ ((packed)) wsgi_request { + uint8_t modifier; + uint16_t size; + uint8_t modifier_arg; + // temporary attr +#ifndef ROCK_SOLID + int app_id; +#endif + struct timeval start_of_request; + char *uri; + unsigned short uri_len; + char *remote_addr; + unsigned short remote_addr_len; + char *remote_user; + unsigned short remote_user_len; + char *query_string; + unsigned short query_string_len; + char *protocol; + unsigned short protocol_len; + char *method; + unsigned short method_len; +#ifdef UNBIT + unsigned long long unbit_flags; +#endif +#ifndef ROCK_SOLID + char *wsgi_script; + unsigned short wsgi_script_len; + char *wsgi_module; + unsigned short wsgi_module_len; + char *wsgi_callable; + unsigned short wsgi_callable_len; + char *script_name; + unsigned short script_name_len; + int sendfile_fd; +#endif + unsigned short var_cnt; + unsigned short header_cnt; + int status; + int response_size; + int headers_size; + }; -struct uwsgi_server { - char *pyhome; + + struct uwsgi_server { + char *pyhome; #ifndef ROCK_SOLID - int has_threads; - int wsgi_cnt; - int default_app; - int enable_profiler; + int has_threads; + int wsgi_cnt; + int default_app; + int enable_profiler; + int i_have_gil ; + PyThreadState *_save; #ifndef UNBIT - char *chroot; - gid_t gid; - uid_t uid; + char *chroot; + gid_t gid; + uid_t uid; #endif #endif - int to_heaven ; - int to_hell ; + int (*hooks[0xFF])(struct uwsgi_server *, struct wsgi_request*, char*) ; + int (*after_hooks[0xFF])(struct uwsgi_server *, struct wsgi_request*, char*) ; - int buffer_size; + // iovec + struct iovec *hvec; - int master_process; + int to_heaven; + int to_hell; - int no_defer_accept; + int buffer_size; - int page_size ; + int master_process; - char *sync_page ; - int synclog; + int no_defer_accept; - char *test_module; + int page_size; - char *pidfile; + char *sync_page; + int synclog; - int numproc; - int maxworkers; + char *test_module; - int max_vars ; - int vec_size ; + char *pidfile; - char *sharedarea ; + int numproc; + int maxworkers; + + int max_vars; + int vec_size; + + char *sharedarea; #ifndef __OpenBSD__ - void *sharedareamutex ; + void *sharedareamutex; #endif - int sharedareasize ; + int sharedareasize; - /* the list of workers */ - struct uwsgi_worker *workers ; - pid_t mypid; - int mywid; + /* the list of workers */ + struct uwsgi_worker *workers; + pid_t mypid; + int mywid; - struct timeval start_tv; + struct timeval start_tv; #ifndef UNBIT - int abstract_socket; - int chmod_socket; - int listen_queue; + int abstract_socket; + int chmod_socket; + int listen_queue; #ifndef ROCK_SOLID - char *xml_config; - char *python_path[64]; - int python_path_cnt; - char *pyargv ; + char *xml_config; + char *python_path[64]; + int python_path_cnt; + char *pyargv; #endif #endif #ifndef ROCK_SOLID - char *wsgi_config; - char *paste; + char *wsgi_config; + char *paste; #endif #ifndef ROCK_SOLID - int single_interpreter; - int py_optimize; + int single_interpreter; + int py_optimize; - PyObject *py_sendfile ; - PyObject *embedded_dict ; - PyObject *embedded_args ; - PyObject *fastfuncslist ; + PyObject *py_sendfile; + PyObject *embedded_dict; + PyObject *embedded_args; + PyObject *fastfuncslist; - PyObject *workers_tuple ; + PyObject *workers_tuple; - PyThreadState *main_thread ; + PyThreadState *main_thread; #endif - struct pollfd poll; + struct pollfd poll; - uint32_t *options; + uint32_t *options; #ifndef ROCK_SOLID - struct uwsgi_app wsgi_apps[64]; - PyObject *py_apps; + struct uwsgi_app wsgi_apps[64]; + PyObject *py_apps; #endif -}; + }; -struct __attribute__((packed)) uwsgi_worker { - int id ; + struct __attribute__ ((packed)) uwsgi_worker { + int id; pid_t pid; time_t last_spawn; unsigned long long requests; @@ -265,125 +334,105 @@ struct __attribute__((packed)) uwsgi_worker { unsigned long long vsz_size; unsigned long long rss_size; - double running_time ; + double running_time; - double load ; - - double last_running_time ; + double last_running_time; int in_request; int manage_next_request; - int blocking ; - int current_workers ; -}; + int blocking; + int current_workers; + }; -struct __attribute__((packed)) uwsgi_header { - uint8_t modifier1; - uint16_t pktsize ; - uint8_t modifier2; -}; + struct __attribute__ ((packed)) uwsgi_header { + uint8_t modifier1; + uint16_t pktsize; + uint8_t modifier2; + }; -struct __attribute__((packed)) wsgi_request { - uint8_t modifier; - uint16_t size ; - uint8_t modifier_arg; - // temporary attr -#ifndef ROCK_SOLID - int app_id ; + + + char *uwsgi_get_cwd (void); + + void warn_pipe (void); + void goodbye_cruel_world (void); + void gracefully_kill (void); + void reap_them_all (void); + void kill_them_all (void); + void grace_them_all (void); + void reload_me (void); + void end_me (void); + int bind_to_unix (char *, int, int, int); + int bind_to_tcp (char *, int, char *); + int bind_to_udp (char *); +#ifdef SCTP + int bind_to_sctp (char *, int, char *); #endif - struct timeval start_of_request ; - char *uri; - unsigned short uri_len; - char *remote_addr; - unsigned short remote_addr_len; - char *remote_user; - unsigned short remote_user_len; - char *query_string; - unsigned short query_string_len; - char *protocol; - unsigned short protocol_len; - char *method; - unsigned short method_len; -#ifdef UNBIT - unsigned long long unbit_flags; -#endif -#ifndef ROCK_SOLID - char *wsgi_script; - unsigned short wsgi_script_len; - char *wsgi_module; - unsigned short wsgi_module_len; - char *wsgi_callable; - unsigned short wsgi_callable_len; - char *script_name; - unsigned short script_name_len; - int sendfile_fd; -#endif - unsigned short var_cnt; - unsigned short header_cnt; - int status; - int response_size; - int headers_size; -}; - - - -char *uwsgi_get_cwd(void); - -void warn_pipe(void); -void goodbye_cruel_world(void); -void gracefully_kill(void); -void reap_them_all(void); -void kill_them_all(void); -void grace_them_all(void); -void reload_me(void); -void end_me(void); -int bind_to_unix(char *, int, int , int ); -int bind_to_tcp(char *, int , char *); #ifndef UNBIT -void daemonize(char *); + void daemonize (char *); #endif -void log_request(struct wsgi_request*) ; + void log_request (struct wsgi_request *); #ifndef ROCK_SOLID -void get_memusage(void) ; + void get_memusage (void); #endif -void harakiri(void) ; + void harakiri (void); #ifndef UNBIT -void stats(void) ; + void stats (void); #endif -void init_uwsgi_vars(void); -void init_uwsgi_embedded_module(void); + void init_uwsgi_vars (void); + void init_uwsgi_embedded_module (void); #ifndef UNBIT -void uwsgi_xml_config(void); + void uwsgi_xml_config (void); #endif #ifndef ROCK_SOLID -void uwsgi_wsgi_config(void); -void uwsgi_paste_config(void); + void uwsgi_wsgi_config (void); + void uwsgi_paste_config (void); #endif -void init_uwsgi_module_sharedarea(PyObject *); -void init_uwsgi_module_advanced(PyObject *); -void init_uwsgi_module_spooler(PyObject *); + void internal_server_error(int, char *); + + void init_uwsgi_module_sharedarea (PyObject *); + void init_uwsgi_module_advanced (PyObject *); + void init_uwsgi_module_spooler (PyObject *); #ifndef ROCK_SOLID -int spool_request(char *, int, char *, int); -void spooler(PyObject *); -pid_t spooler_start(int, PyObject *); +#ifndef UNBIT + void manage_snmp (int, uint8_t *, int, struct sockaddr_in *); +#endif #endif -void set_harakiri(int); +#ifndef ROCK_SOLID + int spool_request (char *, int, char *, int); + void spooler (PyObject *); + pid_t spooler_start (int, PyObject *); +#endif + + void set_harakiri (int); #ifdef __BIG_ENDIAN__ -uint16_t uwsgi_swap16( uint16_t ); + uint16_t uwsgi_swap16 (uint16_t); #endif #ifndef ROCK_SOLID -int init_uwsgi_app(PyObject *, PyObject *) ; + int init_uwsgi_app (PyObject *, PyObject *); #endif -PyObject *uwsgi_send_message(const char *, int, uint8_t, uint8_t, char *, int, int); + PyObject *uwsgi_send_message (const char *, int, uint8_t, uint8_t, char *, int, int); -int uwsgi_parse_response(struct pollfd*, int, struct uwsgi_header *, char *); + int uwsgi_parse_response (struct pollfd *, int, struct uwsgi_header *, char *); + + int uwsgi_enqueue_message (char *, int, uint8_t, uint8_t, char *, int, int); + + +/* included HOOKS */ +int uwsgi_request_wsgi(struct uwsgi_server*, struct wsgi_request*, char *); +int uwsgi_after_request_wsgi(struct uwsgi_server*, struct wsgi_request*, char *); + +int uwsgi_request_admin(struct uwsgi_server*, struct wsgi_request*, char *); +int uwsgi_request_spooler(struct uwsgi_server*, struct wsgi_request*, char *); +int uwsgi_request_fastfunc(struct uwsgi_server*, struct wsgi_request*, char *); +int uwsgi_request_marshal(struct uwsgi_server*, struct wsgi_request*, char *); +int uwsgi_request_ping(struct uwsgi_server*, struct wsgi_request*, char *); -int uwsgi_enqueue_message(char *, int, uint8_t, uint8_t, char *, int, int); diff --git a/uwsgi_handlers.c b/uwsgi_handlers.c new file mode 100644 index 00000000..cf7993fb --- /dev/null +++ b/uwsgi_handlers.c @@ -0,0 +1,117 @@ +#include "uwsgi.h" + +/* uwsgi PING|100 */ +int uwsgi_request_ping (struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req, char *buffer) { + fprintf (stderr, "PING\n"); + wsgi_req->modifier_arg = 1; + if (write (uwsgi->poll.fd, wsgi_req, 4) != 4) { + perror ("write()"); + } + + return 0; +} + +/* uwsgi ADMIN|10 */ +int uwsgi_request_admin (struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req, char *buffer) { + uint32_t opt_value = 0; + int i; + + if (wsgi_req->size >= 4) { + memcpy (&opt_value, buffer, 4); + // TODO: check endianess + } + fprintf (stderr, "setting internal option %d to %d\n", wsgi_req->modifier_arg, opt_value); + uwsgi->options[wsgi_req->modifier_arg] = opt_value; + wsgi_req->modifier = 255; + wsgi_req->size = 0; + wsgi_req->modifier_arg = 1; + i = write (uwsgi->poll.fd, wsgi_req, 4); + if (i != 4) { + perror ("write()"); + } + + return 0; +} + +/* uwsgi FASTFUNC|26 */ +int uwsgi_request_fastfunc (struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req, char *buffer) { + + PyObject *zero, *func_result, *fchunk, *func_chunks; + + zero = PyList_GetItem (uwsgi->fastfuncslist, wsgi_req->modifier_arg); + if (zero) { + fprintf (stderr, "managing fastfunc %d\n", wsgi_req->modifier_arg); + func_result = PyEval_CallObject (zero, NULL); + if (PyErr_Occurred ()) { + PyErr_Print (); + } + if (func_result) { + func_chunks = PyObject_GetIter (func_result); + if (func_chunks) { + while ((fchunk = PyIter_Next (func_chunks))) { + if (PyString_Check (fchunk)) { + wsgi_req->response_size += write (uwsgi->poll.fd, PyString_AsString (fchunk), PyString_Size (fchunk)); + } + Py_DECREF (fchunk); + } + Py_DECREF (func_chunks); + } + Py_DECREF (func_result); + } + } + PyErr_Clear (); + + return 0; +} + + +/* uwsgi MARSHAL|33 */ +int uwsgi_request_marshal (struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req, char *buffer) { + PyObject *func_result; + + PyObject *umm = PyDict_GetItemString (uwsgi->embedded_dict, + "message_manager_marshal"); + if (umm) { + PyObject *ummo = PyMarshal_ReadObjectFromString (buffer, + wsgi_req->size); + if (ummo) { + if (!PyTuple_SetItem (uwsgi->embedded_args, 0, ummo)) { + if (!PyTuple_SetItem (uwsgi->embedded_args, 1, PyInt_FromLong (wsgi_req->modifier_arg))) { + func_result = PyEval_CallObject (umm, uwsgi->embedded_args); + if (PyErr_Occurred ()) { + PyErr_Print (); + } + if (func_result) { + PyObject *marshalled = PyMarshal_WriteObjectToString (func_result, 1); + if (!marshalled) { + PyErr_Print (); + } + else { + if (PyString_Size (marshalled) <= 0xFFFF) { + wsgi_req->size = (uint16_t) + PyString_Size (marshalled); + if (write (uwsgi->poll.fd, wsgi_req, 4) == 4) { + if (write (uwsgi->poll.fd, PyString_AsString (marshalled), wsgi_req->size) != wsgi_req->size) { + perror ("write()"); + } + } + else { + perror ("write()"); + } + } + else { + fprintf (stderr, "marshalled object is too big. skip\n"); + } + Py_DECREF (marshalled); + } + Py_DECREF (func_result); + } + } + } + //Py_DECREF(ummo); + } + } + PyErr_Clear (); + + return 0; +} diff --git a/uwsgi_pymodule.c b/uwsgi_pymodule.c index 0f6663b8..328f41f2 100644 --- a/uwsgi_pymodule.c +++ b/uwsgi_pymodule.c @@ -546,6 +546,51 @@ PyObject *py_uwsgi_set_option(PyObject *self, PyObject *args) { return PyInt_FromLong(value); } +PyObject *py_uwsgi_load_plugin(PyObject *self, PyObject *args) { + uint8_t modifier ; + char *plugin_name = NULL ; + + void *plugin_handle; + void (*plugin_init)(struct uwsgi_server *); + int (*plugin_request)(struct uwsgi_server *, struct wsgi_request*, char*) ; + int (*plugin_after_request)(struct uwsgi_server *, struct wsgi_request*, char*) ; + + if (!PyArg_ParseTuple(args, "is:load_plugin", &modifier, &plugin_name)) { + return NULL ; + } + + if (modifier <= 255) { + plugin_handle = dlopen(plugin_name, RTLD_LAZY); + if (!plugin_handle) { + fprintf (stderr, "%s\n", dlerror()); + } + else { + plugin_init = dlsym(plugin_handle, "uwsgi_init"); + if (plugin_init) { + (*plugin_init)(&uwsgi); + } + + plugin_request = dlsym(plugin_handle, "uwsgi_request"); + if (plugin_request) { + uwsgi.hooks[modifier] = plugin_request ; + plugin_after_request = dlsym(plugin_handle, "uwsgi_after_request"); + if (plugin_after_request) { + uwsgi.after_hooks[modifier] = plugin_after_request ; + } + Py_INCREF(Py_True); + return Py_True; + + } + else { + fprintf (stderr, "%s\n", dlerror()); + } + } + } + + Py_INCREF(Py_None); + return Py_None; +} + PyObject *py_uwsgi_send_message(PyObject *self, PyObject *args) { PyObject *arg_message = NULL; @@ -620,18 +665,9 @@ PyObject *py_uwsgi_total_requests(PyObject *self, PyObject *args) { PyObject *py_uwsgi_workers(PyObject *self, PyObject *args) { PyObject *worker_dict, *zero; - int i, w ; + int i ; - if (uwsgi.master_process) { - w = uwsgi.workers[0].current_workers ; - } - else { - w = uwsgi.numproc; - } - - fprintf(stderr,"W = %d\n", w); - - for(i=0;isize) { + fprintf (stderr, "Invalid WSGI request. skip.\n"); + return -1; + } + + ptrbuf = buffer; + bufferend = ptrbuf + wsgi_req->size; + + /* set an HTTP 500 status as default */ + wsgi_req->status = 500; + + + + while (ptrbuf < bufferend) { + if (ptrbuf + 2 < bufferend) { + memcpy (&strsize, ptrbuf, 2); +#ifdef __BIG_ENDIAN__ + strsize = uwsgi_swap16 (strsize); +#endif + ptrbuf += 2; + if (ptrbuf + strsize < bufferend) { + // var key + uwsgi->hvec[wsgi_req->var_cnt].iov_base = ptrbuf; + uwsgi->hvec[wsgi_req->var_cnt].iov_len = strsize; + ptrbuf += strsize; + if (ptrbuf + 2 < bufferend) { + memcpy (&strsize, ptrbuf, 2); +#ifdef __BIG_ENDIAN__ + strsize = uwsgi_swap16 (strsize); +#endif + ptrbuf += 2; + if (ptrbuf + strsize <= bufferend) { +#ifndef ROCK_SOLID +#ifdef UNBIT + if (single_app_mode == 0 && !strncmp ("SCRIPT_NAME", uwsgi->hvec[wsgi_req->var_cnt].iov_base, uwsgi->hvec[wsgi_req->var_cnt].iov_len)) { +#else + if (!strncmp ("SCRIPT_NAME", uwsgi->hvec[wsgi_req->var_cnt].iov_base, uwsgi->hvec[wsgi_req->var_cnt].iov_len)) { +#endif + // set the request app_id + // LOCKED SECTION + if (strsize > 0) { + if (uwsgi->has_threads && !uwsgi->i_have_gil) { + PyEval_RestoreThread (uwsgi->_save); + uwsgi->i_have_gil = 1; + } + zero = PyString_FromStringAndSize (ptrbuf, strsize); + if (PyDict_Contains (uwsgi->py_apps, zero)) { + wsgi_req->app_id = PyInt_AsLong (PyDict_GetItem (uwsgi->py_apps, zero)); + } + else { + /* unavailable app for this SCRIPT_NAME */ + wsgi_req->app_id = -1; + } + Py_DECREF (zero); + if (uwsgi->has_threads && uwsgi->options[UWSGI_OPTION_THREADS] == 1) { + uwsgi->_save = PyEval_SaveThread (); + uwsgi->i_have_gil = 0; + } + } + // UNLOCK + } + else if (!strncmp ("SERVER_PROTOCOL", uwsgi->hvec[wsgi_req->var_cnt].iov_base, uwsgi->hvec[wsgi_req->var_cnt].iov_len)) { +#else + if (!strncmp ("SERVER_PROTOCOL", uwsgi->hvec[wsgi_req->var_cnt].iov_base, uwsgi->hvec[wsgi_req->var_cnt].iov_len)) { +#endif + wsgi_req->protocol = ptrbuf; + wsgi_req->protocol_len = strsize; + } + else if (!strncmp ("REQUEST_URI", uwsgi->hvec[wsgi_req->var_cnt].iov_base, uwsgi->hvec[wsgi_req->var_cnt].iov_len)) { + wsgi_req->uri = ptrbuf; + wsgi_req->uri_len = strsize; + } + else if (!strncmp ("QUERY_STRING", uwsgi->hvec[wsgi_req->var_cnt].iov_base, uwsgi->hvec[wsgi_req->var_cnt].iov_len)) { + wsgi_req->query_string = ptrbuf; + wsgi_req->query_string_len = strsize; + } + else if (!strncmp ("REQUEST_METHOD", uwsgi->hvec[wsgi_req->var_cnt].iov_base, uwsgi->hvec[wsgi_req->var_cnt].iov_len)) { + wsgi_req->method = ptrbuf; + wsgi_req->method_len = strsize; + } + else if (!strncmp ("REMOTE_ADDR", uwsgi->hvec[wsgi_req->var_cnt].iov_base, uwsgi->hvec[wsgi_req->var_cnt].iov_len)) { + wsgi_req->remote_addr = ptrbuf; + wsgi_req->remote_addr_len = strsize; + } + else if (!strncmp ("REMOTE_USER", uwsgi->hvec[wsgi_req->var_cnt].iov_base, uwsgi->hvec[wsgi_req->var_cnt].iov_len)) { + wsgi_req->remote_user = ptrbuf; + wsgi_req->remote_user_len = strsize; + } +#ifdef UNBIT + else if (!strncmp ("UNBIT_FLAGS", uwsgi->hvec[wsgi_req->var_cnt].iov_base, uwsgi->hvec[wsgi_req->var_cnt].iov_len)) { + wsgi_req->unbit_flags = *(unsigned long long *) ptrbuf; + } +#endif + if (wsgi_req->var_cnt < uwsgi->vec_size - (4 + 1)) { + wsgi_req->var_cnt++; + } + else { + fprintf (stderr, "max vec size reached. skip this header.\n"); + break; + } + // var value + uwsgi->hvec[wsgi_req->var_cnt].iov_base = ptrbuf; + uwsgi->hvec[wsgi_req->var_cnt].iov_len = strsize; + if (wsgi_req->var_cnt < uwsgi->vec_size - (4 + 1)) { + wsgi_req->var_cnt++; + } + else { + fprintf (stderr, "max vec size reached. skip this header.\n"); + break; + } + ptrbuf += strsize; + } + else { + break; + } + } + else { + break; + } + } + } + else { + break; + } + } + + + +#ifndef ROCK_SOLID + if (uwsgi->has_threads && !uwsgi->i_have_gil) { + PyEval_RestoreThread (uwsgi->_save); + uwsgi->i_have_gil = 1; + } +#endif + + + wsgi_file = fdopen (uwsgi->poll.fd, "r"); + +#ifndef ROCK_SOLID + +#ifndef UNBIT + if (wsgi_req->app_id == -1 && uwsgi->xml_config == NULL) { +#else + if (wsgi_req->app_id == -1 && uwsgi->wsgi_config == NULL) { +#endif + for (i = 0; i < wsgi_req->var_cnt; i += 2) { + if (!strncmp ("SCRIPT_NAME", uwsgi->hvec[i].iov_base, uwsgi->hvec[i].iov_len)) { + wsgi_req->script_name = uwsgi->hvec[i + 1].iov_base; + wsgi_req->script_name_len = uwsgi->hvec[i + 1].iov_len; + } + if (!strncmp ("UWSGI_SCRIPT", uwsgi->hvec[i].iov_base, uwsgi->hvec[i].iov_len)) { + wsgi_req->wsgi_script = uwsgi->hvec[i + 1].iov_base; + wsgi_req->wsgi_script_len = uwsgi->hvec[i + 1].iov_len; + } + if (!strncmp ("UWSGI_MODULE", uwsgi->hvec[i].iov_base, uwsgi->hvec[i].iov_len)) { + wsgi_req->wsgi_module = uwsgi->hvec[i + 1].iov_base; + wsgi_req->wsgi_module_len = uwsgi->hvec[i + 1].iov_len; + } + if (!strncmp ("UWSGI_CALLABLE", uwsgi->hvec[i].iov_base, uwsgi->hvec[i].iov_len)) { + wsgi_req->wsgi_callable = uwsgi->hvec[i + 1].iov_base; + wsgi_req->wsgi_callable_len = uwsgi->hvec[i + 1].iov_len; + } + } + + + + if (wsgi_req->wsgi_script_len > 0 || (wsgi_req->wsgi_callable_len > 0 && wsgi_req->wsgi_module_len > 0)) { + if ((wsgi_req->app_id = init_uwsgi_app (NULL, NULL)) == -1) { + internal_server_error (uwsgi->poll.fd, "wsgi application not found"); + goto clean; + } + } + } + + + if (wsgi_req->app_id == -1) { + internal_server_error (uwsgi->poll.fd, "wsgi application not found"); + goto clean; + } + + + wi = &uwsgi->wsgi_apps[wsgi_req->app_id]; + + if (uwsgi->single_interpreter == 0) { + if (!wi->interpreter) { + internal_server_error (uwsgi->poll.fd, "wsgi application's %d interpreter not found"); + goto clean; + } + + // set the interpreter + PyThreadState_Swap (wi->interpreter); + } + + +#endif + + + if (wsgi_req->protocol_len < 5) { + fprintf (stderr, "INVALID PROTOCOL: %.*s", wsgi_req->protocol_len, wsgi_req->protocol); + internal_server_error (uwsgi->poll.fd, "invalid HTTP protocol !!!"); + goto clean; + } + if (strncmp (wsgi_req->protocol, "HTTP/", 5)) { + fprintf (stderr, "INVALID PROTOCOL: %.*s", wsgi_req->protocol_len, wsgi_req->protocol); + internal_server_error (uwsgi->poll.fd, "invalid HTTP protocol !!!"); + goto clean; + } + + + + /* max 1 minute before harakiri */ + if (uwsgi->options[UWSGI_OPTION_HARAKIRI] > 0) { +#ifdef UNBIT + if (wsgi_req->modifier != 0) { + switch (wsgi_req->modifier) { + case UWSGI_MODIFIER_HT_S: + set_harakiri (wsgi_req->modifier_arg); + case UWSGI_MODIFIER_HT_M: + set_harakiri (wsgi_req->modifier_arg * 60); + case UWSGI_MODIFIER_HT_H: + set_harakiri (wsgi_req->modifier_arg * 3600); + } + } + else { +#endif + set_harakiri (uwsgi->options[UWSGI_OPTION_HARAKIRI]); +#ifdef UNBIT + } +#endif + } + + + for (i = 0; i < wsgi_req->var_cnt; i += 2) { + /*fprintf(stderr,"%.*s: %.*s\n", uwsgi->hvec[i].iov_len, uwsgi->hvec[i].iov_base, uwsgi->hvec[i+1].iov_len, uwsgi->hvec[i+1].iov_base); */ + pydictkey = PyString_FromStringAndSize (uwsgi->hvec[i].iov_base, uwsgi->hvec[i].iov_len); + pydictvalue = PyString_FromStringAndSize (uwsgi->hvec[i + 1].iov_base, uwsgi->hvec[i + 1].iov_len); + PyDict_SetItem (wi->wsgi_environ, pydictkey, pydictvalue); + Py_DECREF (pydictkey); + Py_DECREF (pydictvalue); + } + + if (wsgi_req->modifier == UWSGI_MODIFIER_MANAGE_PATH_INFO) { + pydictkey = PyDict_GetItemString (wi->wsgi_environ, "SCRIPT_NAME"); + if (pydictkey) { + if (PyString_Check (pydictkey)) { + pydictvalue = PyDict_GetItemString (wi->wsgi_environ, "PATH_INFO"); + if (pydictvalue) { + if (PyString_Check (pydictvalue)) { + path_info = PyString_AsString (pydictvalue); + PyDict_SetItemString (wi->wsgi_environ, "PATH_INFO", PyString_FromString (path_info + PyString_Size (pydictkey))); + } + } + } + } + } + + + + + // set wsgi vars + + wsgi_socket = PyFile_FromFile (wsgi_file, "wsgi_input", "r", NULL); + PyDict_SetItemString (wi->wsgi_environ, "wsgi.input", wsgi_socket); + Py_DECREF (wsgi_socket); + +#ifndef ROCK_SOLID + PyDict_SetItemString (wi->wsgi_environ, "wsgi.file_wrapper", wi->wsgi_sendfile); +#endif + + zero = PyTuple_New (2); + PyTuple_SetItem (zero, 0, PyInt_FromLong (1)); + PyTuple_SetItem (zero, 1, PyInt_FromLong (0)); + PyDict_SetItemString (wi->wsgi_environ, "wsgi.version", zero); + Py_DECREF (zero); + + zero = PyFile_FromFile (stderr, "wsgi_input", "w", NULL); + PyDict_SetItemString (wi->wsgi_environ, "wsgi.errors", zero); + Py_DECREF (zero); + + PyDict_SetItemString (wi->wsgi_environ, "wsgi.run_once", Py_False); + + PyDict_SetItemString (wi->wsgi_environ, "wsgi.multithread", Py_False); + if (uwsgi->numproc == 1) { + PyDict_SetItemString (wi->wsgi_environ, "wsgi.multiprocess", Py_False); + } + else { + PyDict_SetItemString (wi->wsgi_environ, "wsgi.multiprocess", Py_True); + } + + zero = PyString_FromString ("http"); + PyDict_SetItemString (wi->wsgi_environ, "wsgi.url_scheme", zero); + Py_DECREF (zero); + +#ifdef UNBIT + if (wsgi_req->unbit_flags & (unsigned long long) 1) { + if (uri_to_hex () <= 0) { + tmp_filename[0] = 0; + } + } +#endif + + + + + // call +#ifndef ROCK_SOLID + if (uwsgi->enable_profiler == 1) { + wsgi_result = PyEval_CallObject (wi->wsgi_cprofile_run, wi->wsgi_args); + if (PyErr_Occurred ()) { + PyErr_Print (); + } + if (wsgi_result) { + Py_DECREF (wsgi_result); + wsgi_result = PyDict_GetItemString (wi->pymain_dict, "uwsgi_out"); + } + } + else { +#endif + + wsgi_result = PyEval_CallObject (wi->wsgi_callable, wi->wsgi_args); + + if (PyErr_Occurred ()) { + PyErr_Print (); + } +#ifndef ROCK_SOLID + } +#endif + + + + + if (wsgi_result) { + + +#ifndef ROCK_SOLID + if (wsgi_req->sendfile_fd > -1) { + rlen = lseek (wsgi_req->sendfile_fd, 0, SEEK_END); + if (rlen > 0) { + lseek (wsgi_req->sendfile_fd, 0, SEEK_SET); +#ifndef __linux__ +#if defined(__FreeBSD__) || defined(__DragonFly__) + + wsgi_req->response_size = sendfile (wsgi_req->sendfile_fd, uwsgi->poll.fd, 0, 0, NULL, (off_t *) & rlen, 0); +#elif __OpenBSD__ || __sun__ + char *no_sendfile_buf[4096]; + int jlen = 0; + i = 0; + while (i < rlen) { + jlen = read (wsgi_req->sendfile_fd, no_sendfile_buf, 4096); + if (jlen <= 0) { + perror ("read()"); + break; + } + i += jlen; + jlen = write (uwsgi->poll.fd, no_sendfile_buf, jlen); + if (jlen <= 0) { + perror ("write()"); + break; + } + + } +#else + wsgi_req->response_size = sendfile (wsgi_req->sendfile_fd, uwsgi->poll.fd, 0, (off_t *) & rlen, NULL, 0); +#endif +#else + wsgi_req->response_size = sendfile (uwsgi->poll.fd, wsgi_req->sendfile_fd, NULL, rlen); +#endif + } + Py_DECREF (uwsgi->py_sendfile); + } + else { + +#endif + + wsgi_chunks = PyObject_GetIter (wsgi_result); + if (wsgi_chunks) { + while ((wchunk = PyIter_Next (wsgi_chunks))) { + if (PyString_Check (wchunk)) { + if ((i = write (uwsgi->poll.fd, PyString_AsString (wchunk), PyString_Size (wchunk))) < 0) { + perror ("write()"); + } + wsgi_req->response_size += i; +#ifdef UNBIT + if (save_to_disk >= 0) { + if (write (save_to_disk, PyString_AsString (wchunk), PyString_Size (wchunk)) < 0) { + perror ("write()"); + close (save_to_disk); + save_to_disk = -1; + unlinkat (tmp_dir_fd, tmp_filename, 0); + } + } +#endif + } + else { + fprintf (stderr, "invalid output returned by the wsgi callable !!!\n"); + } + Py_DECREF (wchunk); + } + + if (PyErr_Occurred ()) { + PyErr_Print (); + } + +#ifdef UNBIT + else if (save_to_disk >= 0) { + close (save_to_disk); + save_to_disk = -1; + fprintf (stderr, "[uWSGI cacher] output of request %llu (%.*s) on pid %d written to cache file %s\n", uwsgi->workers[0].requests + 1, wsgi_req->uri_len, wsgi_req->uri, uwsgi->mypid, tmp_filename); + } +#endif + Py_DECREF (wsgi_chunks); + } +#ifndef ROCK_SOLID + } + if (uwsgi->enable_profiler == 0) { +#endif + Py_DECREF (wsgi_result); +#ifndef ROCK_SOLID + } +#endif + } + + + + PyDict_Clear (wi->wsgi_environ); +#ifndef ROCK_SOLID + wi->requests++; +#endif + PyErr_Clear (); + if (uwsgi->options[UWSGI_OPTION_HARAKIRI] > 0) { + set_harakiri (0); + } +#ifndef ROCK_SOLID + if (uwsgi->single_interpreter == 0) { + // restoring main interpreter + PyThreadState_Swap (uwsgi->main_thread); + } +#endif + clean: + fclose (wsgi_file); +#ifndef ROCK_SOLID + if (uwsgi->has_threads && uwsgi->options[UWSGI_OPTION_THREADS] == 1) { + uwsgi->_save = PyEval_SaveThread (); + uwsgi->i_have_gil = 0; + } +#endif + uwsgi->workers[uwsgi->mywid].requests++; + + return 0; + +} + +int uwsgi_after_request_wsgi (struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req, char *buffer) { + + if (uwsgi->options[UWSGI_OPTION_LOGGING]) + log_request(wsgi_req) ; + + return 0; +}