mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-09-06 05:31:44 +00:00
big update: hooks and plugins
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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<h1>Hello World</h1>" ;
|
||||
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;
|
||||
}
|
||||
@@ -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<tlen;i++) {
|
||||
#else
|
||||
for(i=tlen-1;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<tlen;i++) {
|
||||
blen[i] = ptr[1+i];
|
||||
#else
|
||||
for(i=tlen-1;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<num_output_oid;i++) {
|
||||
new_size += output_oid[i].valuesize = 1 ;
|
||||
if (output_oid[i].value > 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
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
+4
-2
@@ -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 '<tr><td>'+ str(w['id']) +'</td><td>' + str(w['pid']) + '</td><td>' + str(w['in_request']) + '</td><td>' + str(w['requests']) + '</td><td>' + str(w['running_time']) + '</td><td>' + str(w['vsz']) + '</td><td>' + str(w['rss']) + '</td></tr>'
|
||||
print w
|
||||
|
||||
yield '</table>'
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* uWSGI */
|
||||
|
||||
|
||||
/* indent -i8 -br -brs -brf -l0 -npsl */
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -10,6 +11,11 @@
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
#ifdef SCTP
|
||||
#include <netinet/sctp.h>
|
||||
#endif
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/file.h>
|
||||
@@ -18,6 +24,11 @@
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
|
||||
#include <poll.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/socket.h>
|
||||
@@ -36,18 +47,17 @@
|
||||
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <libkern/OSAtomic.h>
|
||||
#include <mach/task.h>
|
||||
#include <mach/mach_init.h>
|
||||
#include <libkern/OSAtomic.h>
|
||||
#include <mach/task.h>
|
||||
#include <mach/mach_init.h>
|
||||
#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 <sys/sendfile.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#undef _XOPEN_SOURCE
|
||||
#include <Python.h>
|
||||
|
||||
#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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
+48
-16
@@ -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;i<w;i++) {
|
||||
for(i=0;i<uwsgi.numproc;i++) {
|
||||
worker_dict = PyTuple_GetItem(uwsgi.workers_tuple, i) ;
|
||||
if (!worker_dict) {
|
||||
goto clear;
|
||||
@@ -693,11 +729,6 @@ PyObject *py_uwsgi_workers(PyObject *self, PyObject *args) {
|
||||
}
|
||||
Py_DECREF(zero);
|
||||
|
||||
zero = PyFloat_FromDouble(uwsgi.workers[i+1].load);
|
||||
if (PyDict_SetItemString(worker_dict, "load", zero)) {
|
||||
goto clear;
|
||||
}
|
||||
Py_DECREF(zero);
|
||||
}
|
||||
|
||||
|
||||
@@ -781,6 +812,7 @@ static PyMethodDef uwsgi_advanced_methods[] = {
|
||||
{"worker_id", py_uwsgi_worker_id, METH_VARARGS, ""},
|
||||
{"log", py_uwsgi_log, METH_VARARGS, ""},
|
||||
{"disconnect", py_uwsgi_disconnect, METH_VARARGS, ""},
|
||||
{"load_plugin", py_uwsgi_load_plugin, METH_VARARGS, ""},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
|
||||
+483
@@ -0,0 +1,483 @@
|
||||
#include "uwsgi.h"
|
||||
|
||||
int uwsgi_request_wsgi (struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req, char *buffer) {
|
||||
|
||||
char *ptrbuf;
|
||||
char *bufferend;
|
||||
uint16_t strsize = 0;
|
||||
FILE *wsgi_file;
|
||||
int i;
|
||||
|
||||
struct uwsgi_app *wi;
|
||||
|
||||
PyObject *zero, *wsgi_socket;
|
||||
|
||||
PyObject *pydictkey, *pydictvalue;
|
||||
|
||||
char *path_info;
|
||||
|
||||
PyObject *wsgi_result, *wsgi_chunks, *wchunk;
|
||||
|
||||
int rlen;
|
||||
|
||||
/* Standard WSGI request */
|
||||
|
||||
if (!wsgi_req->size) {
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user