mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-10-04 07:58:33 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c9b6e98f7 | ||
|
|
ce33d0be5a | ||
|
|
4f0fb90bff | ||
|
|
66eff0107a | ||
|
|
82f83e610f | ||
|
|
cf7df391ad | ||
|
|
244c9f8204 | ||
|
|
26dc19df7d | ||
|
|
7b8bff1a08 | ||
|
|
0b010124ef | ||
|
|
c7bde15f39 | ||
|
|
b941e4f2f0 | ||
|
|
536c6e7e29 | ||
|
|
dfe4abec35 | ||
|
|
693b80d7d3 | ||
|
|
c9e6475ef4 | ||
|
|
b745132ebd | ||
|
|
19686cb19f | ||
|
|
e0c0593b5b | ||
|
|
415a8af363 | ||
|
|
d44777b1b4 | ||
|
|
e3ff3037b4 | ||
|
|
7add30fd31 | ||
|
|
501cd0349b | ||
|
|
7b4e3f6601 | ||
|
|
8622c2780c | ||
|
|
13de7b6d5b | ||
|
|
53cb864f9c | ||
|
|
72f693f02a | ||
|
|
fb80e32682 | ||
|
|
1db3426ee1 | ||
|
|
a44879e384 | ||
|
|
c0075c817d | ||
|
|
177dc3322b | ||
|
|
21ef4fc89b | ||
|
|
f467643f6f | ||
|
|
3db41e7e05 | ||
|
|
73151729c6 | ||
|
|
5d9c415028 | ||
|
|
b92ed4da4e | ||
|
|
2d1a9a03d2 | ||
|
|
5d6edd2321 | ||
|
|
365f4ba83f | ||
|
|
66e30ae293 | ||
|
|
728425de19 |
@@ -38,3 +38,4 @@ fb168b0b86169219aa9b8e40f0caa6297cf34dbc 0.9.9-rc1
|
||||
24f7e260ea345c2cd73e2fd8191dddbd1b039062 1.0-rc4
|
||||
043ba93dd69cf6924e98db3cb9a8759cce997367 1.0-rc5
|
||||
a2b8f25fd17ed7424d1470a287d0b3144d2a12c8 1.0-rc6
|
||||
a3ca2e8e27c5c12c44ba0cacb4de4cb51377f184 1.0-rc7
|
||||
|
||||
@@ -15,3 +15,5 @@ Luigi Scarso
|
||||
Corey Farwell
|
||||
Charles Duffy
|
||||
Lukas Lalinsky
|
||||
Steven Fernandez
|
||||
Łukasz Mierzwa
|
||||
|
||||
+39
-4
@@ -2,7 +2,7 @@
|
||||
|
||||
*** uWSGI/mod_uwsgi ***
|
||||
|
||||
Copyright 2009-2010 Unbit S.a.s. <info@unbit.it>
|
||||
Copyright 2009-2011 Unbit S.a.s. <info@unbit.it>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
@@ -73,6 +73,7 @@ typedef struct {
|
||||
char scheme[9];
|
||||
int cgi_mode ;
|
||||
int max_vars;
|
||||
int empty_remote_user;
|
||||
} uwsgi_cfg;
|
||||
|
||||
module AP_MODULE_DECLARE_DATA uwsgi_module;
|
||||
@@ -162,6 +163,7 @@ static void *uwsgi_server_config(apr_pool_t *p, server_rec *s) {
|
||||
c->cgi_mode = 0 ;
|
||||
c->max_vars = 128;
|
||||
c->script_name[0] = 0;
|
||||
c->empty_remote_user = 1;
|
||||
|
||||
return c;
|
||||
}
|
||||
@@ -177,6 +179,7 @@ static void *uwsgi_dir_config(apr_pool_t *p, char *dir) {
|
||||
c->modifier2 = 0 ;
|
||||
c->cgi_mode = 0 ;
|
||||
c->max_vars = 128;
|
||||
c->empty_remote_user = 1;
|
||||
c->script_name[0] = 0;
|
||||
if (dir) {
|
||||
if (strcmp(dir, "/")) {
|
||||
@@ -344,7 +347,15 @@ static int uwsgi_handler(request_rec *r) {
|
||||
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "SERVER_PROTOCOL", r->protocol, &pkt_size) ;
|
||||
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "REQUEST_URI", r->unparsed_uri, &pkt_size) ;
|
||||
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "REMOTE_ADDR", r->connection->remote_ip, &pkt_size) ;
|
||||
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "REMOTE_USER", r->user ? r->user : "", &pkt_size) ;
|
||||
|
||||
//
|
||||
if (r->user) {
|
||||
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "REMOTE_USER", r->user, &pkt_size) ;
|
||||
}
|
||||
else if (c->empty_remote_user) {
|
||||
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "REMOTE_USER", "", &pkt_size) ;
|
||||
}
|
||||
|
||||
if (r->user) {
|
||||
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "AUTH_TYPE", (char *) ap_auth_type(r), &pkt_size) ;
|
||||
}
|
||||
@@ -354,7 +365,8 @@ static int uwsgi_handler(request_rec *r) {
|
||||
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "UWSGI_SCHEME", c->scheme, &pkt_size) ;
|
||||
}
|
||||
|
||||
if (c->script_name[0] != 0) {
|
||||
// SCRIPT_NAME = "/" is like SCRIPT_NAME = ""
|
||||
if (c->script_name[0] != 0 && !(c->script_name[0] == '/' && c->script_name[1] == 0)) {
|
||||
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "SCRIPT_NAME", c->script_name, &pkt_size) ;
|
||||
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "PATH_INFO", r->uri+strlen(c->script_name), &pkt_size) ;
|
||||
}
|
||||
@@ -621,7 +633,7 @@ static const char * cmd_uwsgi_force_cgi_mode(cmd_parms *cmd, void *cfg, const ch
|
||||
c = ap_get_module_config(cmd->server->module_config, &uwsgi_module);
|
||||
}
|
||||
|
||||
if (!strcmp("yes", value) || !strcmp("on", value) || !strcmp("enable", value) || !strcmp("1", value)) {
|
||||
if (!strcmp("yes", value) || !strcmp("on", value) || !strcmp("enable", value) || !strcmp("1", value) || !strcmp("true", value)) {
|
||||
c->cgi_mode = 1 ;
|
||||
}
|
||||
|
||||
@@ -722,6 +734,28 @@ static const char * cmd_uwsgi_socket(cmd_parms *cmd, void *cfg, const char *path
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
static const char * cmd_uwsgi_empty_remote_user(cmd_parms *cmd, void *cfg, const char *value) {
|
||||
|
||||
uwsgi_cfg *c ;
|
||||
|
||||
if (cfg) {
|
||||
c = cfg ;
|
||||
}
|
||||
else {
|
||||
c = ap_get_module_config(cmd->server->module_config, &uwsgi_module);
|
||||
}
|
||||
|
||||
if (!strcmp("yes", value) || !strcmp("on", value) || !strcmp("enable", value) || !strcmp("1", value) || !strcmp("true", value)) {
|
||||
c->empty_remote_user = 1;
|
||||
}
|
||||
else {
|
||||
c->empty_remote_user = 0;
|
||||
}
|
||||
|
||||
return NULL ;
|
||||
|
||||
}
|
||||
|
||||
static const command_rec uwsgi_cmds[] = {
|
||||
AP_INIT_TAKE12("uWSGIsocket", cmd_uwsgi_socket, NULL, RSRC_CONF|ACCESS_CONF, "Absolute path and optional timeout in seconds of uwsgi server socket"),
|
||||
AP_INIT_TAKE1("uWSGIsocket2", cmd_uwsgi_socket2, NULL, RSRC_CONF|ACCESS_CONF, "Absolute path of failover uwsgi server socket"),
|
||||
@@ -730,6 +764,7 @@ static const command_rec uwsgi_cmds[] = {
|
||||
AP_INIT_TAKE1("uWSGIforceScriptName", cmd_uwsgi_force_script_name, NULL, ACCESS_CONF, "Fix for PATH_INFO/SCRIPT_NAME when the location has filesystem correspondence"),
|
||||
AP_INIT_TAKE1("uWSGIforceCGImode", cmd_uwsgi_force_cgi_mode, NULL, ACCESS_CONF, "Force uWSGI CGI mode for perfect integration with apache filter"),
|
||||
AP_INIT_TAKE1("uWSGIforceWSGIscheme", cmd_uwsgi_force_wsgi_scheme, NULL, ACCESS_CONF, "Force the WSGI scheme var (set by default to \"http\")"),
|
||||
AP_INIT_TAKE1("uWSGIemptyRemoteUser", cmd_uwsgi_empty_remote_user, NULL, ACCESS_CONF, "Always include REMOTE_USER in the environment, even with an empty value (default true)"),
|
||||
AP_INIT_TAKE1("uWSGImaxVars", cmd_uwsgi_max_vars, NULL, ACCESS_CONF, "Set the maximum allowed number of uwsgi variables (default 128)"),
|
||||
{NULL}
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@ xml = true
|
||||
ini = true
|
||||
yaml = true
|
||||
json = auto
|
||||
sqlite3 = false
|
||||
sqlite3 = auto
|
||||
zeromq = auto
|
||||
snmp = true
|
||||
sctp = false
|
||||
|
||||
@@ -171,7 +171,7 @@ void emperor_respawn(struct uwsgi_instance *c_ui, time_t mod) {
|
||||
c_ui->respawns++;
|
||||
c_ui->last_mod = mod;
|
||||
|
||||
uwsgi_log("reload the uwsgi instance %s\n", c_ui->name);
|
||||
uwsgi_log("[emperor] reload the uwsgi instance %s\n", c_ui->name);
|
||||
}
|
||||
|
||||
void emperor_add(char *name, time_t born, char *config, uint32_t config_size, uid_t uid, gid_t gid) {
|
||||
@@ -512,6 +512,7 @@ reconnect:
|
||||
uwsgi_error("glob()");
|
||||
exit(1);
|
||||
}
|
||||
globfree(&g);
|
||||
emperor_absolute_dir = realpath(".", NULL);
|
||||
}
|
||||
|
||||
@@ -647,7 +648,7 @@ reconnect:
|
||||
}
|
||||
}
|
||||
else {
|
||||
uwsgi_log("unrecognized event on fd %d\n", interesting_fd);
|
||||
uwsgi_log("[emperor] unrecognized vassal event on fd %d\n", interesting_fd);
|
||||
event_queue_del_fd(emperor_queue, interesting_fd, event_queue_read());
|
||||
close(interesting_fd);
|
||||
}
|
||||
@@ -746,6 +747,7 @@ reconnect:
|
||||
}
|
||||
|
||||
}
|
||||
globfree(&g);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -847,6 +849,7 @@ void emperor_send_stats(int fd) {
|
||||
|
||||
stats_send("{ \"version\": \"%s\",\n", UWSGI_VERSION);
|
||||
|
||||
fprintf(output,"\"pid\": %d,\n", (int)(getpid()));
|
||||
fprintf(output,"\"uid\": %d,\n", (int)(getuid()));
|
||||
fprintf(output,"\"gid\": %d,\n", (int)(getgid()));
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ void log_request(struct wsgi_request *wsgi_req) {
|
||||
#endif
|
||||
|
||||
// mark route() requests
|
||||
if (wsgi_req->status == -1) {
|
||||
if (wsgi_req->status == -17) {
|
||||
via = msg3;
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ void uwsgi_subscribe(char *subscription, uint8_t cmd) {
|
||||
modifier1_len = strlen(modifier1);
|
||||
keysize = strlen(key);
|
||||
}
|
||||
uwsgi_send_subscription(udp_address, key, keysize, modifier1, modifier1_len, cmd);
|
||||
uwsgi_send_subscription(udp_address, key, keysize, uwsgi_str_num(modifier1, modifier1_len), 0, cmd);
|
||||
modifier1 = NULL;
|
||||
modifier1_len = 0;
|
||||
}
|
||||
@@ -118,7 +118,7 @@ void uwsgi_subscribe(char *subscription, uint8_t cmd) {
|
||||
modifier1_len = strlen(modifier1);
|
||||
keysize = strlen(key);
|
||||
}
|
||||
uwsgi_send_subscription(udp_address, key, keysize, modifier1, modifier1_len, cmd);
|
||||
uwsgi_send_subscription(udp_address, key, keysize, uwsgi_str_num(modifier1, modifier1_len), 0, cmd);
|
||||
modifier1 = NULL;
|
||||
modifier1_len = 0;
|
||||
lines[i] = '\n';
|
||||
@@ -142,7 +142,7 @@ void uwsgi_subscribe(char *subscription, uint8_t cmd) {
|
||||
modifier1_len = strlen(modifier1);
|
||||
}
|
||||
|
||||
uwsgi_send_subscription(udp_address, subscription_key+1, strlen(subscription_key+1), modifier1, modifier1_len, cmd);
|
||||
uwsgi_send_subscription(udp_address, subscription_key+1, strlen(subscription_key+1), uwsgi_str_num(modifier1, modifier1_len), 0, cmd);
|
||||
if (modifier1)
|
||||
modifier1[-1] = ',';
|
||||
}
|
||||
@@ -163,6 +163,8 @@ void get_linux_tcp_info(int fd) {
|
||||
return;
|
||||
}
|
||||
|
||||
uwsgi.shared->load = uwsgi.shared->ti.tcpi_unacked;
|
||||
|
||||
uwsgi.shared->options[UWSGI_OPTION_BACKLOG_STATUS] = uwsgi.shared->ti.tcpi_unacked;
|
||||
if (uwsgi.vassal_sos_backlog > 0 && uwsgi.has_emperor) {
|
||||
if ((int)uwsgi.shared->ti.tcpi_unacked >= uwsgi.vassal_sos_backlog) {
|
||||
@@ -207,7 +209,7 @@ int master_loop(char **argv, char **environ) {
|
||||
|
||||
uint8_t uwsgi_signal;
|
||||
|
||||
time_t last_request_timecheck = 0;
|
||||
time_t last_request_timecheck = 0, now = 0;
|
||||
uint64_t last_request_count = 0;
|
||||
|
||||
#ifdef UWSGI_UDP
|
||||
@@ -868,12 +870,14 @@ healthy:
|
||||
}
|
||||
// TODO allow uwsgi.logger = func
|
||||
}
|
||||
goto health_cycle;
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.stats && uwsgi.stats_fd > -1) {
|
||||
if (interesting_fd == uwsgi.stats_fd) {
|
||||
uwsgi_send_stats(uwsgi.stats_fd);
|
||||
goto health_cycle;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -924,6 +928,7 @@ healthy:
|
||||
close(zerg_client);
|
||||
|
||||
free(zerg_msg_control);
|
||||
goto health_cycle;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -950,6 +955,7 @@ healthy:
|
||||
sleep(2);
|
||||
exit(1);
|
||||
}
|
||||
goto health_cycle;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -969,6 +975,7 @@ healthy:
|
||||
}
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
// here is better to continue instead going to health_cycle
|
||||
if (found) continue;
|
||||
}
|
||||
#ifdef UWSGI_SNMP
|
||||
@@ -982,7 +989,7 @@ healthy:
|
||||
else if (rlen > 0) {
|
||||
manage_snmp(snmp_fd, (uint8_t *) uwsgi.wsgi_req->buffer, rlen, &udp_client);
|
||||
}
|
||||
continue;
|
||||
goto health_cycle;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1029,14 +1036,14 @@ healthy:
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
goto health_cycle;
|
||||
}
|
||||
|
||||
#ifdef UWSGI_MULTICAST
|
||||
if (interesting_fd == uwsgi.cluster_fd) {
|
||||
|
||||
if (uwsgi_get_dgram(uwsgi.cluster_fd, uwsgi.wsgi_requests[0])) {
|
||||
continue;
|
||||
goto health_cycle;
|
||||
}
|
||||
|
||||
switch(uwsgi.wsgi_requests[0]->uh.modifier1) {
|
||||
@@ -1076,7 +1083,7 @@ healthy:
|
||||
uwsgi_log_verbose("[uWSGI cluster %s] new node available: %.*s\n", uwsgi.cluster, uwsgi.wsgi_requests[0]->uh.pktsize, uwsgi.wsgi_requests[0]->buffer);
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
goto health_cycle;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1098,7 +1105,7 @@ healthy:
|
||||
}
|
||||
|
||||
uwsgi_unlock(uwsgi.fmon_table_lock);
|
||||
if (next_iteration) continue;
|
||||
if (next_iteration) goto health_cycle;;
|
||||
|
||||
next_iteration = 0;
|
||||
|
||||
@@ -1114,7 +1121,7 @@ healthy:
|
||||
}
|
||||
}
|
||||
uwsgi_unlock(uwsgi.timer_table_lock);
|
||||
if (next_iteration) continue;
|
||||
if (next_iteration) goto health_cycle;;
|
||||
|
||||
|
||||
// check for worker signal
|
||||
@@ -1134,6 +1141,7 @@ healthy:
|
||||
close(interesting_fd);
|
||||
//uwsgi.workers[i].pipe[0] = -1;
|
||||
}
|
||||
goto health_cycle;
|
||||
}
|
||||
|
||||
#ifdef UWSGI_SPOOLER
|
||||
@@ -1154,6 +1162,7 @@ healthy:
|
||||
uwsgi_log_verbose("lost connection with the spooler\n");
|
||||
close(interesting_fd);
|
||||
}
|
||||
goto health_cycle;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1161,7 +1170,12 @@ healthy:
|
||||
|
||||
}
|
||||
|
||||
uwsgi.current_time = time(NULL);
|
||||
health_cycle:
|
||||
now = time(NULL);
|
||||
if (now - uwsgi.current_time < 1) {
|
||||
continue;
|
||||
}
|
||||
uwsgi.current_time = now;
|
||||
// checking logsize
|
||||
if (uwsgi.logfile) {
|
||||
if (uwsgi.log_master) {
|
||||
@@ -1207,6 +1221,7 @@ healthy:
|
||||
}
|
||||
|
||||
|
||||
// this will be incremented at (more or less) regular intervals
|
||||
uwsgi.master_cycles++;
|
||||
|
||||
// recalculate requests counter on race conditions risky configurations
|
||||
@@ -1244,6 +1259,7 @@ healthy:
|
||||
continue;
|
||||
}
|
||||
for(i=1;i<=uwsgi.numproc;i++) {
|
||||
uwsgi.workers[i].cheaped = 1;
|
||||
if (uwsgi.workers[i].pid == 0) continue;
|
||||
kill(uwsgi.workers[i].pid, SIGKILL);
|
||||
if (waitpid(uwsgi.workers[i].pid, &waitpid_status, 0) < 0) {
|
||||
|
||||
@@ -102,6 +102,9 @@ int uwsgi_respawn_worker(int wid) {
|
||||
uwsgi.workers[uwsgi.mywid].pid = uwsgi.mypid;
|
||||
uwsgi.workers[uwsgi.mywid].id = uwsgi.mywid;
|
||||
uwsgi.workers[uwsgi.mywid].harakiri = 0;
|
||||
|
||||
uwsgi.workers[uwsgi.mywid].rss_size = 0;
|
||||
uwsgi.workers[uwsgi.mywid].vsz_size = 0;
|
||||
// do not reset worker counters on reload !!!
|
||||
//uwsgi.workers[uwsgi.mywid].requests = 0;
|
||||
// ...but maintain a delta counter (yes this is racy in multithread)
|
||||
@@ -317,6 +320,9 @@ void uwsgi_send_stats(int fd) {
|
||||
stats_send_llu("\"listen_queue\": %llu,\n", uwsgi.shared->ti.tcpi_unacked);
|
||||
#endif
|
||||
|
||||
stats_send_llu("\"load\": %llu,\n", uwsgi.shared->load);
|
||||
|
||||
fprintf(output,"\"pid\": %d,\n", (int)(getpid()));
|
||||
fprintf(output,"\"uid\": %d,\n", (int)(getuid()));
|
||||
fprintf(output,"\"gid\": %d,\n", (int)(getgid()));
|
||||
|
||||
|
||||
Vendored
+3
-2
@@ -34,6 +34,7 @@ int uwsgi_cache_request(struct wsgi_request *wsgi_req) {
|
||||
uint64_t vallen = 0;
|
||||
char *value;
|
||||
char *argv[3];
|
||||
uint16_t argvs[3];
|
||||
uint8_t argc = 0;
|
||||
|
||||
switch(wsgi_req->uh.modifier2) {
|
||||
@@ -52,9 +53,9 @@ int uwsgi_cache_request(struct wsgi_request *wsgi_req) {
|
||||
// set
|
||||
if (wsgi_req->uh.pktsize > 0) {
|
||||
argc = 3;
|
||||
if (!uwsgi_parse_array(wsgi_req->buffer, wsgi_req->uh.pktsize, argv, &argc)) {
|
||||
if (!uwsgi_parse_array(wsgi_req->buffer, wsgi_req->uh.pktsize, argv, argvs, &argc)) {
|
||||
if (argc > 1) {
|
||||
uwsgi_cache_set(argv[0], strlen(argv[0]), argv[1], strlen(argv[1]), 0, 0);
|
||||
uwsgi_cache_set(argv[0], argvs[0], argv[1], argvs[1], 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ int uwsgi_cgi_request(struct wsgi_request *wsgi_req) {
|
||||
uwsgi_log("STARTBUF %.*s\n", 8, startbuf);
|
||||
|
||||
if (!memcmp(startbuf, "Status: ", 8)) {
|
||||
wsgi_req->socket->proto_write(wsgi_req, "HTTP/1.1 "
|
||||
// wsgi_req->socket->proto_write(wsgi_req, "HTTP/1.1 "
|
||||
}
|
||||
|
||||
// now wait for fd
|
||||
|
||||
@@ -94,7 +94,8 @@ void uwsgi_erlang_rpc(int fd, erlang_pid *from, ei_x_buff *x) {
|
||||
char *call;
|
||||
char buffer[0xffff];
|
||||
|
||||
char *argv[0xff] ;
|
||||
char *argv[256] ;
|
||||
uint16_t argvs[256] ;
|
||||
int argc = 0;
|
||||
uint16_t ret;
|
||||
ei_x_buff xr;
|
||||
@@ -215,14 +216,16 @@ void uwsgi_erlang_rpc(int fd, erlang_pid *from, ei_x_buff *x) {
|
||||
argc = 1;
|
||||
argv[0] = uwsgi_malloc(esize+1);
|
||||
ei_decode_atom(x->buff, &x->index, argv[0]);
|
||||
argvs[1] = esize;
|
||||
}
|
||||
else if (etype == ERL_STRING_EXT) {
|
||||
argc = 1;
|
||||
argv[0] = uwsgi_malloc(esize+1);
|
||||
ei_decode_string(x->buff, &x->index, argv[0]);
|
||||
argvs[1] = esize;
|
||||
}
|
||||
|
||||
ret = uwsgi_rpc(call, argc, argv, buffer);
|
||||
ret = uwsgi_rpc(call, argc, argv, argvs, buffer);
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("buffer: %.*s\n", ret, buffer);
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#define LONG_ARGS_FASTROUTER_SUBSCRIPTION_SLOT 150007
|
||||
#define LONG_ARGS_FASTROUTER_USE_CODE_STRING 150008
|
||||
#define LONG_ARGS_FASTROUTER_TOLERANCE 150009
|
||||
#define LONG_ARGS_FASTROUTER_STATS 150010
|
||||
|
||||
#define FASTROUTER_STATUS_FREE 0
|
||||
#define FASTROUTER_STATUS_CONNECTING 1
|
||||
@@ -33,6 +34,8 @@
|
||||
#define del_check_timeout(x) rb_erase(&x->rbt, ufr.timeouts);
|
||||
#define del_timeout(x) rb_erase(&x->timeout->rbt, ufr.timeouts); free(x->timeout);
|
||||
|
||||
void fastrouter_send_stats(int);
|
||||
|
||||
struct uwsgi_fastrouter_socket {
|
||||
char *name;
|
||||
int fd;
|
||||
@@ -56,6 +59,8 @@ struct uwsgi_fastrouter {
|
||||
char *base;
|
||||
int base_len;
|
||||
|
||||
char *stats_server;
|
||||
|
||||
char *subscription_server;
|
||||
struct uwsgi_subscribe_slot *subscriptions;
|
||||
int subscription_regexp;
|
||||
@@ -126,6 +131,9 @@ struct option fastrouter_options[] = {
|
||||
{"fastrouter-subscription-slot", required_argument, 0, LONG_ARGS_FASTROUTER_SUBSCRIPTION_SLOT},
|
||||
{"fastrouter-subscription-use-regexp", no_argument, &ufr.subscription_regexp, 1},
|
||||
{"fastrouter-timeout", required_argument, 0, LONG_ARGS_FASTROUTER_TIMEOUT},
|
||||
{"fastrouter-stats", required_argument, 0, LONG_ARGS_FASTROUTER_STATS},
|
||||
{"fastrouter-stats-server", required_argument, 0, LONG_ARGS_FASTROUTER_STATS},
|
||||
{"fastrouter-ss", required_argument, 0, LONG_ARGS_FASTROUTER_STATS},
|
||||
{0, 0, 0, 0},
|
||||
};
|
||||
|
||||
@@ -143,10 +151,15 @@ void fastrouter_manage_subscription(char *key, uint16_t keylen, char *val, uint1
|
||||
usr->address = val;
|
||||
usr->address_len = vallen;
|
||||
}
|
||||
|
||||
else if (!uwsgi_strncmp("modifier1", 9, key, keylen)) {
|
||||
usr->modifier1 = uwsgi_str_num(val, vallen);
|
||||
}
|
||||
else if (!uwsgi_strncmp("cores", 5, key, keylen)) {
|
||||
usr->cores = uwsgi_str_num(val, vallen);
|
||||
}
|
||||
else if (!uwsgi_strncmp("load", 4, key, keylen)) {
|
||||
usr->load = uwsgi_str_num(val, vallen);
|
||||
}
|
||||
}
|
||||
|
||||
struct fastrouter_session {
|
||||
@@ -194,6 +207,7 @@ static void close_session(struct fastrouter_session **fr_table, struct fastroute
|
||||
if (fr_session->instance_failed || fr_session->status == FASTROUTER_STATUS_CONNECTING) {
|
||||
if (fr_session->un->death_mark == 0)
|
||||
uwsgi_log("[uwsgi-fastrouter] %.*s => marking %.*s as failed\n", (int) fr_session->hostname_len, fr_session->hostname, (int) fr_session->instance_address_len,fr_session->instance_address);
|
||||
fr_session->un->failcnt++;
|
||||
fr_session->un->death_mark = 1;
|
||||
// check if i can remove the node
|
||||
if (fr_session->un->reference == 0) {
|
||||
@@ -308,6 +322,7 @@ void fastrouter_loop() {
|
||||
socklen_t solen = sizeof(int);
|
||||
|
||||
int ufr_subserver = -1;
|
||||
int ufr_stats_server = -1;
|
||||
|
||||
for(i=0;i<2048;i++) {
|
||||
fr_table[i] = NULL;
|
||||
@@ -364,6 +379,23 @@ void fastrouter_loop() {
|
||||
//ufr.subscriptions_check = add_check_timeout(10);
|
||||
}
|
||||
|
||||
if (ufr.stats_server) {
|
||||
char *tcp_port = strchr(ufr.stats_server, ':');
|
||||
if (tcp_port) {
|
||||
// disable deferred accept for this socket
|
||||
int current_defer_accept = uwsgi.no_defer_accept;
|
||||
uwsgi.no_defer_accept = 1;
|
||||
ufr_stats_server = bind_to_tcp(ufr.stats_server, uwsgi.listen_queue, tcp_port);
|
||||
uwsgi.no_defer_accept = current_defer_accept;
|
||||
}
|
||||
else {
|
||||
ufr_stats_server = bind_to_unix(ufr.stats_server, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
|
||||
}
|
||||
|
||||
event_queue_add_fd_read(ufr.queue, ufr_stats_server);
|
||||
uwsgi_log("*** FastRouter stats server enabled on %s fd: %d ***\n", ufr.stats_server, ufr_stats_server);
|
||||
}
|
||||
|
||||
if (ufr.pattern) {
|
||||
init_magic_table(magic_table);
|
||||
}
|
||||
@@ -430,7 +462,10 @@ void fastrouter_loop() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (interesting_fd == ufr_subserver) {
|
||||
if (interesting_fd == ufr_stats_server) {
|
||||
fastrouter_send_stats(ufr_stats_server);
|
||||
}
|
||||
else if (interesting_fd == ufr_subserver) {
|
||||
len = recv(ufr_subserver, bbuf, 4096, 0);
|
||||
#ifdef UWSGI_EVENT_USE_PORT
|
||||
event_queue_add_fd_read(ufr.queue, ufr_subserver);
|
||||
@@ -456,6 +491,7 @@ void fastrouter_loop() {
|
||||
if (node && node->len) {
|
||||
if (node->death_mark == 0)
|
||||
uwsgi_log("[uwsgi-fastrouter] %.*s => marking %.*s as failed\n", (int) usr.keylen, usr.key, (int) usr.address_len, usr.address);
|
||||
node->failcnt++;
|
||||
node->death_mark = 1;
|
||||
// check if i can remove the node
|
||||
if (node->reference == 0) {
|
||||
@@ -486,7 +522,8 @@ void fastrouter_loop() {
|
||||
case FASTROUTER_STATUS_RECV_HDR:
|
||||
len = recv(fr_session->fd, (char *)(&fr_session->uh) + fr_session->h_pos, 4-fr_session->h_pos, 0);
|
||||
if (len <= 0) {
|
||||
uwsgi_error("recv()");
|
||||
if (len < 0)
|
||||
uwsgi_error("recv()");
|
||||
close_session(fr_table, fr_session);
|
||||
break;
|
||||
}
|
||||
@@ -763,6 +800,9 @@ int fastrouter_opt(int i, char *optarg) {
|
||||
case LONG_ARGS_FASTROUTER_SUBSCRIPTION_SERVER:
|
||||
ufr.subscription_server = optarg;
|
||||
return 1;
|
||||
case LONG_ARGS_FASTROUTER_STATS:
|
||||
ufr.stats_server = optarg;
|
||||
return 1;
|
||||
case LONG_ARGS_FASTROUTER_EVENTS:
|
||||
ufr.nevents = atoi(optarg);
|
||||
return 1;
|
||||
@@ -813,3 +853,89 @@ struct uwsgi_plugin fastrouter_plugin = {
|
||||
.init = fastrouter_init,
|
||||
};
|
||||
|
||||
|
||||
#define stats_send_llu(x, y) fprintf(output, x, (long long unsigned int) y)
|
||||
#define stats_send(x, y) fprintf(output, x, y)
|
||||
|
||||
void fastrouter_send_stats(int fd) {
|
||||
|
||||
struct sockaddr_un client_src;
|
||||
socklen_t client_src_len = 0;
|
||||
int client_fd = accept(fd, (struct sockaddr *) &client_src, &client_src_len);
|
||||
if (client_fd < 0) {
|
||||
uwsgi_error("accept()");
|
||||
return;
|
||||
}
|
||||
|
||||
FILE *output = fdopen(client_fd, "w");
|
||||
if (!output) {
|
||||
uwsgi_error("fdopen()");
|
||||
close(client_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
stats_send("{ \"version\": \"%s\",\n", UWSGI_VERSION);
|
||||
|
||||
fprintf(output,"\"pid\": %d,\n", (int)(getpid()));
|
||||
fprintf(output,"\"uid\": %d,\n", (int)(getuid()));
|
||||
fprintf(output,"\"gid\": %d,\n", (int)(getgid()));
|
||||
|
||||
char *cwd = uwsgi_get_cwd();
|
||||
stats_send("\"cwd\": \"%s\",\n", cwd);
|
||||
free(cwd);
|
||||
|
||||
fprintf(output, "\"fastrouter\": [");
|
||||
struct uwsgi_fastrouter_socket *uwsgi_sock = ufr.sockets;
|
||||
while(uwsgi_sock) {
|
||||
if (uwsgi_sock->next) {
|
||||
stats_send("\"%s\",", uwsgi_sock->name);
|
||||
}
|
||||
else {
|
||||
stats_send("\"%s\"", uwsgi_sock->name);
|
||||
}
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
fprintf(output, "],\n");
|
||||
|
||||
if (ufr.subscription_server) {
|
||||
fprintf(output, "\"subscriptions\": [\n");
|
||||
struct uwsgi_subscribe_slot *s_slot = ufr.subscriptions;
|
||||
while(s_slot) {
|
||||
fprintf(output, "\t{ \"key\": \"%.*s\",\n", s_slot->keylen, s_slot->key);
|
||||
fprintf(output, "\t\t\"hits\": %llu,\n", (unsigned long long) s_slot->hits);
|
||||
fprintf(output, "\t\t\"nodes\": [\n");
|
||||
struct uwsgi_subscribe_node *s_node = s_slot->nodes;
|
||||
while(s_node) {
|
||||
fprintf(output, "\t\t\t{\"name\": \"%.*s\", \"modifier1\": %d, \"modifier2\": %d, \"last_check\": %llu, \"requests\": %llu, \"tx\": %llu, \"cores\": %llu, \"load\": %llu, \"ref\": %llu, \"failcnt\": %llu, \"death_mark\": %d}", s_node->len, s_node->name, s_node->modifier1, s_node->modifier2,
|
||||
(unsigned long long) s_node->last_check, (unsigned long long) s_node->requests, (unsigned long long) s_node->transferred,
|
||||
(unsigned long long) s_node->cores, (unsigned long long) s_node->load, (unsigned long long) s_node->reference,
|
||||
(unsigned long long) s_node->failcnt, s_node->death_mark);
|
||||
if (s_node->next) {
|
||||
fprintf(output, ",\n");
|
||||
}
|
||||
else {
|
||||
fprintf(output, "\n");
|
||||
}
|
||||
s_node = s_node->next;
|
||||
}
|
||||
fprintf(output, "\t\t]\n");
|
||||
if (s_slot->next) {
|
||||
fprintf(output, "\t},\n");
|
||||
}
|
||||
else {
|
||||
fprintf(output, "\t}\n");
|
||||
}
|
||||
s_slot = s_slot->next;
|
||||
// check for loopy optimization
|
||||
if (s_slot == ufr.subscriptions) break;
|
||||
}
|
||||
fprintf(output, "],\n");
|
||||
}
|
||||
|
||||
fprintf(output,"\"cheap\": %d\n", ufr.i_am_cheap);
|
||||
|
||||
fprintf(output,"}\n");
|
||||
fclose(output);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -682,7 +682,7 @@ int uwsgi_lua_signal_handler(uint8_t sig, void *handler) {
|
||||
|
||||
}
|
||||
|
||||
uint16_t uwsgi_lua_rpc(void * func, uint8_t argc, char **argv, char *buffer) {
|
||||
uint16_t uwsgi_lua_rpc(void * func, uint8_t argc, char **argv, uint16_t argvs[], char *buffer) {
|
||||
|
||||
uint8_t i;
|
||||
const char *sv;
|
||||
@@ -698,7 +698,7 @@ uint16_t uwsgi_lua_rpc(void * func, uint8_t argc, char **argv, char *buffer) {
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, ifunc);
|
||||
|
||||
for(i=0;i<argc;i++) {
|
||||
lua_pushstring(L, argv[i]);
|
||||
lua_pushlstring(L, argv[i], argvs[i]);
|
||||
}
|
||||
|
||||
if (lua_pcall(L, argc, 1, 0) != 0) {
|
||||
|
||||
@@ -147,6 +147,7 @@ int psgi_response(struct wsgi_request *wsgi_req, AV *response) {
|
||||
wsgi_req->sendfile_fd = SvIV(fn);
|
||||
SvREFCNT_dec(fn);
|
||||
wsgi_req->response_size += uwsgi_sendfile(wsgi_req);
|
||||
// no need to close here as perl GC will do the close()
|
||||
return UWSGI_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -155,26 +155,28 @@ XS(XS_call) {
|
||||
|
||||
dXSARGS;
|
||||
|
||||
char buffer[0xffff];
|
||||
char *func;
|
||||
uint16_t size = 0;
|
||||
int i;
|
||||
char *argv[0xff];
|
||||
char *argv[256];
|
||||
uint16_t argvs[256];
|
||||
STRLEN arg_len;
|
||||
|
||||
psgi_check_args(1);
|
||||
|
||||
func = SvPV_nolen(ST(0));
|
||||
|
||||
for(i=0;i<(items-1);i++) {
|
||||
argv[i] = SvPV_nolen(ST(i+1));
|
||||
argv[i] = SvPV(ST(i+1), arg_len);
|
||||
argvs[i] = arg_len;
|
||||
}
|
||||
|
||||
size = uwsgi_rpc(func, items-1, argv, buffer);
|
||||
char *response = uwsgi_do_rpc(NULL, func, items-1, argv, argvs, &size);
|
||||
|
||||
if (size > 0) {
|
||||
ST(0) = newSVpv(buffer, size);
|
||||
ST(0) = newSVpv(response, size);
|
||||
sv_2mortal(ST(0));
|
||||
|
||||
free(response);
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
|
||||
+15
-16
@@ -80,9 +80,7 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
|
||||
int id = uwsgi_apps_cnt;
|
||||
int multiapp = 0;
|
||||
|
||||
#ifdef UWSGI_ASYNC
|
||||
int i;
|
||||
#endif
|
||||
|
||||
char *mountpoint;
|
||||
|
||||
@@ -320,9 +318,9 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
|
||||
|
||||
// add start_response on WSGI app
|
||||
Py_INCREF((PyObject *)up.wsgi_spitout);
|
||||
wi->wsgi_args = PyTuple_New(wi->argc);
|
||||
wi->args = PyTuple_New(wi->argc);
|
||||
if (app_type == PYTHON_APP_TYPE_WSGI) {
|
||||
if (PyTuple_SetItem(wi->wsgi_args, 1, up.wsgi_spitout)) {
|
||||
if (PyTuple_SetItem(wi->args, 1, up.wsgi_spitout)) {
|
||||
uwsgi_log("unable to set start_response in args tuple\n");
|
||||
exit(1);
|
||||
}
|
||||
@@ -370,24 +368,25 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
|
||||
PyThreadState_Swap(up.main_thread);
|
||||
}
|
||||
|
||||
if (app_type == PYTHON_APP_TYPE_WSGI) {
|
||||
uwsgi_log( "WSGI application %d (mountpoint='%.*s') ready on interpreter %p pid: %d", id, wi->mountpoint_len, wi->mountpoint, wi->interpreter, (int) getpid());
|
||||
}
|
||||
else if (app_type == PYTHON_APP_TYPE_WEB3) {
|
||||
uwsgi_log( "Web3 application %d (mountpoint='%.*s') ready on interpreter %p pid: %d", id, wi->mountpoint_len, wi->mountpoint, wi->interpreter, (int) getpid());
|
||||
}
|
||||
else if (app_type == PYTHON_APP_TYPE_PUMP) {
|
||||
uwsgi_log( "Pump application %d (mountpoint='%.*s') ready on interpreter %p pid: %d", id, wi->mountpoint_len, wi->mountpoint, wi->interpreter, (int) getpid());
|
||||
}
|
||||
const char *default_app = "";
|
||||
|
||||
if ((wsgi_req->appid_len == 0 || (wsgi_req->appid_len = 1 && wsgi_req->appid[0] == '/')) && uwsgi.default_app == -1) {
|
||||
uwsgi_rawlog(" (default app)");
|
||||
default_app = " (default app)" ;
|
||||
uwsgi.default_app = id;
|
||||
}
|
||||
|
||||
uwsgi_apps_cnt++;
|
||||
if (app_type == PYTHON_APP_TYPE_WSGI) {
|
||||
uwsgi_log( "WSGI application %d (mountpoint='%.*s') ready on interpreter %p pid: %d%s\n", id, wi->mountpoint_len, wi->mountpoint, wi->interpreter, (int) getpid(), default_app);
|
||||
}
|
||||
else if (app_type == PYTHON_APP_TYPE_WEB3) {
|
||||
uwsgi_log( "Web3 application %d (mountpoint='%.*s') ready on interpreter %p pid: %d%s\n", id, wi->mountpoint_len, wi->mountpoint, wi->interpreter, (int) getpid(), default_app);
|
||||
}
|
||||
else if (app_type == PYTHON_APP_TYPE_PUMP) {
|
||||
uwsgi_log( "Pump application %d (mountpoint='%.*s') ready on interpreter %p pid: %d%s\n", id, wi->mountpoint_len, wi->mountpoint, wi->interpreter, (int) getpid(), default_app);
|
||||
}
|
||||
|
||||
uwsgi_rawlog("\n");
|
||||
|
||||
uwsgi_apps_cnt++;
|
||||
|
||||
if (multiapp > 1) {
|
||||
for(i=1;i<multiapp;i++) {
|
||||
|
||||
@@ -29,6 +29,10 @@ struct option uwsgi_python_options[] = {
|
||||
{"pyimport", required_argument, 0, LONG_ARGS_PYIMPORT},
|
||||
{"py-import", required_argument, 0, LONG_ARGS_PYIMPORT},
|
||||
{"python-import", required_argument, 0, LONG_ARGS_PYIMPORT},
|
||||
{"shared-import", required_argument, 0, LONG_ARGS_SHARED_PYIMPORT},
|
||||
{"shared-pyimport", required_argument, 0, LONG_ARGS_SHARED_PYIMPORT},
|
||||
{"shared-py-import", required_argument, 0, LONG_ARGS_SHARED_PYIMPORT},
|
||||
{"shared-python-import", required_argument, 0, LONG_ARGS_SHARED_PYIMPORT},
|
||||
{"spooler-import", required_argument, 0, LONG_ARGS_SPOOLER_PYIMPORT},
|
||||
{"spooler-pyimport", required_argument, 0, LONG_ARGS_SPOOLER_PYIMPORT},
|
||||
{"spooler-py-import", required_argument, 0, LONG_ARGS_SPOOLER_PYIMPORT},
|
||||
@@ -739,6 +743,9 @@ int uwsgi_python_manage_options(int i, char *optarg) {
|
||||
uwsgi.honour_stdin = 1;
|
||||
up.pyshell = 1;
|
||||
return 1;
|
||||
case LONG_ARGS_SHARED_PYIMPORT:
|
||||
uwsgi_string_new_list(&up.shared_import_list, optarg);
|
||||
return 1;
|
||||
case LONG_ARGS_PYIMPORT:
|
||||
uwsgi_string_new_list(&up.import_list, optarg);
|
||||
return 1;
|
||||
@@ -892,17 +899,8 @@ void uwsgi_python_spooler_init(void) {
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_python_init_apps() {
|
||||
|
||||
struct http_status_codes *http_sc;
|
||||
|
||||
|
||||
if (uwsgi.async > 1) {
|
||||
up.current_recursion_depth = uwsgi_malloc(sizeof(int)*uwsgi.async);
|
||||
#ifndef UWSGI_PYPY
|
||||
up.current_frame = uwsgi_malloc(sizeof(struct _frame)*uwsgi.async);
|
||||
#endif
|
||||
}
|
||||
// this hook will be executed by master (or worker1 when master is not requested, so COW is in place)
|
||||
void uwsgi_python_preinit_apps() {
|
||||
|
||||
init_pyargv();
|
||||
|
||||
@@ -912,7 +910,6 @@ void uwsgi_python_init_apps() {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __linux__
|
||||
#ifndef UWSGI_PYPY
|
||||
#ifdef UWSGI_EMBEDDED
|
||||
@@ -930,6 +927,34 @@ void uwsgi_python_init_apps() {
|
||||
|
||||
init_uwsgi_vars();
|
||||
|
||||
// load shared imports
|
||||
struct uwsgi_string_list *upli = up.shared_import_list;
|
||||
while(upli) {
|
||||
if (strchr(upli->value, '/') || uwsgi_endswith(upli->value, ".py")) {
|
||||
uwsgi_pyimport_by_filename(uwsgi_pythonize(upli->value), upli->value);
|
||||
}
|
||||
else {
|
||||
if (PyImport_ImportModule(upli->value) == NULL) {
|
||||
PyErr_Print();
|
||||
}
|
||||
}
|
||||
upli = upli->next;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_python_init_apps() {
|
||||
|
||||
struct http_status_codes *http_sc;
|
||||
|
||||
// prepare for stack suspend/resume
|
||||
if (uwsgi.async > 1) {
|
||||
up.current_recursion_depth = uwsgi_malloc(sizeof(int)*uwsgi.async);
|
||||
#ifndef UWSGI_PYPY
|
||||
up.current_frame = uwsgi_malloc(sizeof(struct _frame)*uwsgi.async);
|
||||
#endif
|
||||
}
|
||||
|
||||
// setup app loaders
|
||||
#ifdef UWSGI_MINTERPRETERS
|
||||
up.loaders[LOADER_DYN] = uwsgi_dyn_loader;
|
||||
@@ -1266,36 +1291,38 @@ clear:
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint16_t uwsgi_python_rpc(void *func, uint8_t argc, char **argv, char *buffer) {
|
||||
uint16_t uwsgi_python_rpc(void *func, uint8_t argc, char **argv, uint16_t argvs[], char *buffer) {
|
||||
|
||||
UWSGI_GET_GIL;
|
||||
|
||||
uint8_t i;
|
||||
PyObject *pyargs = PyTuple_New(argc);
|
||||
PyObject *ret;
|
||||
char *rv;
|
||||
size_t rl;
|
||||
|
||||
PyObject *pyargs = PyTuple_New(argc);
|
||||
PyObject *ret;
|
||||
|
||||
if (!pyargs)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
PyTuple_SetItem(pyargs, i, PyString_FromString(argv[i]));
|
||||
PyTuple_SetItem(pyargs, i, PyString_FromStringAndSize(argv[i], argvs[i]));
|
||||
}
|
||||
|
||||
ret = python_call((PyObject *) func, pyargs, 0, NULL);
|
||||
|
||||
Py_DECREF(pyargs);
|
||||
if (ret) {
|
||||
if (PyString_Check(ret)) {
|
||||
rv = PyString_AsString(ret);
|
||||
rl = PyString_Size(ret);
|
||||
if (rl <= 0xffff) {
|
||||
if (rl <= 65536) {
|
||||
memcpy(buffer, rv, rl);
|
||||
Py_DECREF(ret);
|
||||
UWSGI_RELEASE_GIL;
|
||||
return rl;
|
||||
}
|
||||
}
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
if (PyErr_Occurred())
|
||||
@@ -1479,6 +1506,8 @@ struct uwsgi_plugin python_plugin = {
|
||||
.short_options = "w:O:H:J:",
|
||||
.request = uwsgi_request_wsgi,
|
||||
.after_request = uwsgi_after_request_wsgi,
|
||||
|
||||
.preinit_apps = uwsgi_python_preinit_apps,
|
||||
.init_apps = uwsgi_python_init_apps,
|
||||
|
||||
.fixup = uwsgi_python_fixup,
|
||||
|
||||
@@ -294,13 +294,13 @@ PyObject *py_uwsgi_add_file_monitor(PyObject * self, PyObject * args) {
|
||||
|
||||
PyObject *py_uwsgi_call(PyObject * self, PyObject * args) {
|
||||
|
||||
char buffer[0xffff];
|
||||
char *func;
|
||||
uint16_t size = 0;
|
||||
PyObject *py_func;
|
||||
int argc = PyTuple_Size(args);
|
||||
int i;
|
||||
char *argv[0xff];
|
||||
char *argv[256];
|
||||
uint16_t argvs[256];
|
||||
|
||||
// TODO better error reporting
|
||||
if (argc < 1)
|
||||
@@ -314,19 +314,29 @@ PyObject *py_uwsgi_call(PyObject * self, PyObject * args) {
|
||||
func = PyString_AsString(py_func);
|
||||
|
||||
for (i = 0; i < (argc - 1); i++) {
|
||||
argv[i] = PyString_AsString(PyTuple_GetItem(args, i + 1));
|
||||
PyObject *py_str = PyTuple_GetItem(args, i + 1);
|
||||
if (!PyString_Check(py_str)) {
|
||||
goto clear;
|
||||
}
|
||||
argv[i] = PyString_AsString(py_str);
|
||||
argvs[i] = PyString_Size(py_str);
|
||||
}
|
||||
|
||||
size = uwsgi_rpc(func, argc - 1, argv, buffer);
|
||||
char *response = uwsgi_do_rpc(NULL, func, argc - 1, argv, argvs, &size);
|
||||
|
||||
if (size > 0) {
|
||||
return PyString_FromStringAndSize(buffer, size);
|
||||
PyObject *ret = PyString_FromStringAndSize(response, size);
|
||||
free(response);
|
||||
return ret;
|
||||
}
|
||||
|
||||
clear:
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
|
||||
clear:
|
||||
|
||||
return PyErr_Format(PyExc_ValueError, "unable to call rpc function");
|
||||
|
||||
}
|
||||
|
||||
PyObject *py_uwsgi_rpc_list(PyObject * self, PyObject * args) {
|
||||
@@ -346,19 +356,15 @@ PyObject *py_uwsgi_rpc_list(PyObject * self, PyObject * args) {
|
||||
|
||||
PyObject *py_uwsgi_rpc(PyObject * self, PyObject * args) {
|
||||
|
||||
char buffer[0xffff];
|
||||
char *node, *func;
|
||||
char *node = NULL, *func;
|
||||
uint16_t size = 0;
|
||||
PyObject *py_node, *py_func;
|
||||
struct wsgi_request rpc_req;
|
||||
int argc = PyTuple_Size(args);
|
||||
char *argv[0xff];
|
||||
int i, fd;
|
||||
uint16_t pktsize = 0, ulen;
|
||||
char *bufptr;
|
||||
int rlen;
|
||||
int rpc_args = 0;
|
||||
|
||||
int argc = PyTuple_Size(args);
|
||||
char *argv[256];
|
||||
uint16_t argvs[256];
|
||||
|
||||
int i;
|
||||
|
||||
// TODO better error reporting
|
||||
if (argc < 2)
|
||||
@@ -369,9 +375,6 @@ PyObject *py_uwsgi_rpc(PyObject * self, PyObject * args) {
|
||||
if (PyString_Check(py_node)) {
|
||||
node = PyString_AsString(py_node);
|
||||
}
|
||||
else {
|
||||
node = "";
|
||||
}
|
||||
|
||||
py_func = PyTuple_GetItem(args, 1);
|
||||
|
||||
@@ -381,87 +384,28 @@ PyObject *py_uwsgi_rpc(PyObject * self, PyObject * args) {
|
||||
func = PyString_AsString(py_func);
|
||||
|
||||
for (i = 0; i < (argc - 2); i++) {
|
||||
argv[i] = PyString_AsString(PyTuple_GetItem(args, i + 2));
|
||||
rpc_args++;
|
||||
PyObject *py_str = PyTuple_GetItem(args, i + 2);
|
||||
if (!PyString_Check(py_str))
|
||||
goto clear;
|
||||
argv[i] = PyString_AsString(py_str);
|
||||
argvs[i] = PyString_Size(py_str);
|
||||
}
|
||||
|
||||
if (!strcmp(node, "")) {
|
||||
if (!rpc_args) {
|
||||
size = uwsgi_rpc(func, 0, NULL, buffer);
|
||||
}
|
||||
else {
|
||||
size = uwsgi_rpc(func, rpc_args, argv, buffer);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
|
||||
// connect to node
|
||||
fd = uwsgi_connect(node, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], 0);
|
||||
|
||||
if (fd < 0)
|
||||
goto clear;
|
||||
// prepare a uwsgi array
|
||||
|
||||
pktsize = 2 + strlen(func);
|
||||
for (i = 0; i < argc - 2; i++) {
|
||||
pktsize += 2 + strlen(argv[i]);
|
||||
}
|
||||
|
||||
memset(&rpc_req, 0, sizeof(struct wsgi_request));
|
||||
|
||||
rpc_req.uh.modifier1 = 173;
|
||||
rpc_req.uh.pktsize = pktsize;
|
||||
rpc_req.uh.modifier2 = 0;
|
||||
|
||||
bufptr = buffer;
|
||||
|
||||
ulen = strlen(func);
|
||||
*bufptr++ = (uint8_t) (ulen & 0xff);
|
||||
*bufptr++ = (uint8_t) ((ulen >> 8) & 0xff);
|
||||
memcpy(bufptr, func, ulen);
|
||||
bufptr += ulen;
|
||||
|
||||
for (i = 0; i < argc - 2; i++) {
|
||||
ulen = strlen(argv[i]);
|
||||
*bufptr++ = (uint8_t) (ulen & 0xff);
|
||||
*bufptr++ = (uint8_t) ((ulen >> 8) & 0xff);
|
||||
memcpy(bufptr, argv[i], ulen);
|
||||
bufptr += ulen;
|
||||
}
|
||||
|
||||
if (write(fd, &rpc_req.uh, 4) != 4) {
|
||||
uwsgi_error("write()");
|
||||
close(fd);
|
||||
goto clear;
|
||||
}
|
||||
|
||||
if (write(fd, buffer, pktsize) != pktsize) {
|
||||
uwsgi_error("write()");
|
||||
close(fd);
|
||||
goto clear;
|
||||
}
|
||||
|
||||
rlen = uwsgi_waitfd(fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
||||
if (rlen > 0) {
|
||||
rpc_req.poll.fd = fd;
|
||||
rpc_req.poll.events = POLLIN;
|
||||
rpc_req.buffer = buffer;
|
||||
if (uwsgi_parse_packet(&rpc_req, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT])) {
|
||||
size = rpc_req.uh.pktsize;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
char *response = uwsgi_do_rpc(node, func, argc - 2, argv, argvs, &size);
|
||||
|
||||
if (size > 0) {
|
||||
return PyString_FromStringAndSize(buffer, size);
|
||||
}
|
||||
PyObject *ret = PyString_FromStringAndSize(response, size);
|
||||
free(response);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
|
||||
clear:
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
return PyErr_Format(PyExc_ValueError, "unable to call rpc function");
|
||||
|
||||
}
|
||||
|
||||
PyObject *py_uwsgi_register_rpc(PyObject * self, PyObject * args) {
|
||||
@@ -2345,7 +2289,7 @@ PyObject *py_uwsgi_route(PyObject * self, PyObject * args) {
|
||||
ui->func = NULL;
|
||||
|
||||
// mark a route request
|
||||
wsgi_req->status = -1;
|
||||
wsgi_req->status = -17;
|
||||
|
||||
return (PyObject *) ui;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#define LONG_ARGS_PYSHELL LONG_ARGS_PYTHON_BASE + 11
|
||||
#define LONG_ARGS_SPOOLER_PYIMPORT LONG_ARGS_PYTHON_BASE + 12
|
||||
#define LONG_ARGS_PYTHON_RUN LONG_ARGS_PYTHON_BASE + 13
|
||||
#define LONG_ARGS_SHARED_PYIMPORT LONG_ARGS_PYTHON_BASE + 14
|
||||
|
||||
#define PYTHON_APP_TYPE_WSGI 0
|
||||
#define PYTHON_APP_TYPE_WEB3 1
|
||||
@@ -133,6 +134,7 @@ struct uwsgi_python {
|
||||
|
||||
struct uwsgi_string_list *python_path;
|
||||
struct uwsgi_string_list *import_list;
|
||||
struct uwsgi_string_list *shared_import_list;
|
||||
struct uwsgi_string_list *spooler_import_list;
|
||||
struct uwsgi_string_list *post_pymodule_alias;
|
||||
|
||||
@@ -210,8 +212,6 @@ PyObject *python_call(PyObject *, PyObject *, int, struct wsgi_request *);
|
||||
|
||||
#ifdef UWSGI_SENDFILE
|
||||
PyObject *py_uwsgi_sendfile(PyObject *, PyObject *);
|
||||
ssize_t uwsgi_sendfile(struct wsgi_request *);
|
||||
ssize_t uwsgi_do_sendfile(int, int, size_t, size_t, off_t*, int);
|
||||
#endif
|
||||
|
||||
PyObject *py_uwsgi_write(PyObject *, PyObject *);
|
||||
|
||||
@@ -595,6 +595,59 @@ VALUE uwsgi_ruby_signal_registered(VALUE *class, VALUE signum) {
|
||||
return Qfalse;
|
||||
}
|
||||
|
||||
VALUE uwsgi_ruby_do_rpc(int argc, VALUE *rpc_argv, VALUE *class) {
|
||||
|
||||
char *node = NULL, *func;
|
||||
uint16_t size = 0;
|
||||
|
||||
char *argv[256];
|
||||
uint16_t argvs[256];
|
||||
|
||||
int i;
|
||||
|
||||
|
||||
// TODO better error reporting
|
||||
if (argc < 2)
|
||||
goto clear;
|
||||
|
||||
|
||||
VALUE rpc_node = rpc_argv[0];
|
||||
|
||||
if (TYPE(rpc_node) == T_STRING) {
|
||||
node = RSTRING_PTR(rpc_node);
|
||||
}
|
||||
|
||||
|
||||
VALUE rpc_func = rpc_argv[1];
|
||||
|
||||
if (TYPE(rpc_func) != T_STRING)
|
||||
goto clear;
|
||||
|
||||
func = RSTRING_PTR(rpc_func);
|
||||
|
||||
for (i = 0; i < (argc - 2); i++) {
|
||||
VALUE rpc_str = rpc_argv[i + 2];
|
||||
if (TYPE(rpc_str) != T_STRING)
|
||||
goto clear;
|
||||
argv[i] = RSTRING_PTR(rpc_str);
|
||||
argvs[i] = RSTRING_LEN(rpc_str);
|
||||
}
|
||||
|
||||
char *response = uwsgi_do_rpc(node, func, argc - 2, argv, argvs, &size);
|
||||
|
||||
if (size > 0) {
|
||||
VALUE ret = rb_str_new(response, size);
|
||||
free(response);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
clear:
|
||||
|
||||
rb_raise(rb_eRuntimeError, "unable to call rpc function");
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
VALUE uwsgi_ruby_register_rpc(int argc, VALUE *argv, VALUE *class) {
|
||||
|
||||
int rb_argc = 0;
|
||||
@@ -712,6 +765,8 @@ void uwsgi_rack_init_api() {
|
||||
|
||||
uwsgi_rack_api("set_warning_message", rack_uwsgi_warning, 1);
|
||||
|
||||
uwsgi_rack_api("rpc", uwsgi_ruby_do_rpc, -1);
|
||||
|
||||
|
||||
|
||||
if (uwsgi.cache_max_items > 0) {
|
||||
|
||||
+65
-76
@@ -149,6 +149,10 @@ VALUE require_rails(VALUE arg) {
|
||||
#endif
|
||||
}
|
||||
|
||||
VALUE require_thin(VALUE arg) {
|
||||
return rb_funcall(rb_cObject, rb_intern("require"), 1, rb_str_new2("thin"));
|
||||
}
|
||||
|
||||
VALUE init_rack_app(VALUE);
|
||||
|
||||
VALUE rack_call_rpc_handler(VALUE args) {
|
||||
@@ -157,7 +161,7 @@ VALUE rack_call_rpc_handler(VALUE args) {
|
||||
}
|
||||
|
||||
|
||||
uint16_t uwsgi_ruby_rpc(void *func, uint8_t argc, char **argv, char *buffer) {
|
||||
uint16_t uwsgi_ruby_rpc(void *func, uint8_t argc, char **argv, uint16_t argvs[], char *buffer) {
|
||||
|
||||
uint8_t i;
|
||||
VALUE rb_args = rb_ary_new2(2);
|
||||
@@ -170,7 +174,7 @@ uint16_t uwsgi_ruby_rpc(void *func, uint8_t argc, char **argv, char *buffer) {
|
||||
rb_ary_store(rb_args, 0, (VALUE) func);
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
rb_ary_store(rb_rpc_args, i, rb_str_new2(argv[i]));
|
||||
rb_ary_store(rb_rpc_args, i, rb_str_new(argv[i], argvs[i]));
|
||||
}
|
||||
rb_ary_store(rb_args, 1, rb_rpc_args);
|
||||
|
||||
@@ -280,7 +284,27 @@ void uwsgi_rack_init_apps(void) {
|
||||
uwsgi_log("rails app %s ready\n", ur.rails);
|
||||
VALUE ac = rb_const_get(rb_cObject, rb_intern("ActionController"));
|
||||
|
||||
ur.dispatcher = rb_funcall( rb_const_get(ac, rb_intern("Dispatcher")), rb_intern("new"), 0);
|
||||
ur.dispatcher = Qnil;
|
||||
if (rb_funcall(ac, rb_intern("const_defined?"), 1, ID2SYM(rb_intern("Dispatcher"))) == Qtrue) {
|
||||
VALUE ac_dispatcher = rb_const_get(ac, rb_intern("Dispatcher"));
|
||||
if (rb_respond_to(ac_dispatcher, rb_intern("call")) || rb_respond_to(ac_dispatcher, ID2SYM(rb_intern("call")))) {
|
||||
ur.dispatcher = rb_funcall( rb_const_get(ac, rb_intern("Dispatcher")), rb_intern("new"), 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (ur.dispatcher == Qnil) {
|
||||
uwsgi_log("non-rack rails version detected...loading thin adapter...\n");
|
||||
rb_protect( require_thin, 0, &error ) ;
|
||||
if (error) {
|
||||
uwsgi_ruby_exception();
|
||||
exit(1);
|
||||
}
|
||||
VALUE thin_rack = rb_const_get(rb_cObject, rb_intern("Rack"));
|
||||
VALUE thin_rack_adapter = rb_const_get(thin_rack, rb_intern("Adapter"));
|
||||
VALUE thin_rack_adapter_rails = rb_const_get(thin_rack_adapter, rb_intern("Rails"));
|
||||
ur.dispatcher = rb_funcall( thin_rack_adapter_rails, rb_intern("new"), 0);
|
||||
}
|
||||
|
||||
|
||||
if (ur.dispatcher == Qnil) {
|
||||
uwsgi_log("unable to load rails dispatcher\n");
|
||||
@@ -396,63 +420,50 @@ VALUE send_header(VALUE obj, VALUE headers) {
|
||||
}
|
||||
|
||||
if (TYPE(hkey) != T_STRING || TYPE(hval) != T_STRING) {
|
||||
goto clear2;
|
||||
goto clear;
|
||||
}
|
||||
|
||||
//uwsgi_log("header: %.*s: %.*s\n", RSTRING_LEN(hkey), RSTRING_PTR(hkey), RSTRING_LEN(hval), RSTRING_PTR(hval));
|
||||
|
||||
len = wsgi_req->socket->proto_write_header( wsgi_req, RSTRING_PTR(hkey), RSTRING_LEN(hkey));
|
||||
wsgi_req->headers_size += len;
|
||||
len = wsgi_req->socket->proto_write_header( wsgi_req, (char *)": ", 2);
|
||||
wsgi_req->headers_size += len;
|
||||
|
||||
char *header_value = RSTRING_PTR(hval);
|
||||
int header_value_len = RSTRING_LEN(hval);
|
||||
size_t header_value_len = RSTRING_LEN(hval);
|
||||
size_t i,cnt=0;
|
||||
char *this_header = header_value;
|
||||
|
||||
char *header_value_splitted = memchr(header_value, '\n', header_value_len);
|
||||
for(i=0;i<header_value_len;i++) {
|
||||
// multiline header, send it !!!
|
||||
if (header_value[i] == '\n') {
|
||||
len = wsgi_req->socket->proto_write_header( wsgi_req, RSTRING_PTR(hkey), RSTRING_LEN(hkey));
|
||||
wsgi_req->headers_size += len;
|
||||
len = wsgi_req->socket->proto_write_header( wsgi_req, (char *)": ", 2);
|
||||
wsgi_req->headers_size += len;
|
||||
len = wsgi_req->socket->proto_write_header( wsgi_req, this_header, cnt);
|
||||
wsgi_req->headers_size += len;
|
||||
len = wsgi_req->socket->proto_write_header( wsgi_req, (char *)"\r\n", 2);
|
||||
wsgi_req->headers_size += len;
|
||||
|
||||
if (!header_value_splitted) {
|
||||
len = wsgi_req->socket->proto_write_header( wsgi_req, header_value, header_value_len);
|
||||
wsgi_req->headers_size += len;
|
||||
len = wsgi_req->socket->proto_write_header( wsgi_req, (char *)"\r\n", 2);
|
||||
wsgi_req->headers_size += len;
|
||||
wsgi_req->header_cnt++;
|
||||
//uwsgi_log("(multi) --%.*s: %.*s--\n", RSTRING_LEN(hkey), RSTRING_PTR(hkey), cnt, this_header);
|
||||
|
||||
wsgi_req->header_cnt++;
|
||||
|
||||
this_header += cnt+1;
|
||||
cnt = 0;
|
||||
continue;
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
else {
|
||||
header_value_splitted[0] = 0;
|
||||
len = wsgi_req->socket->proto_write_header( wsgi_req, header_value, header_value_splitted-header_value);
|
||||
|
||||
if (cnt > 0) {
|
||||
len = wsgi_req->socket->proto_write_header( wsgi_req, RSTRING_PTR(hkey), RSTRING_LEN(hkey));
|
||||
wsgi_req->headers_size += len;
|
||||
len = wsgi_req->socket->proto_write_header( wsgi_req, (char *)": ", 2);
|
||||
wsgi_req->headers_size += len;
|
||||
len = wsgi_req->socket->proto_write_header( wsgi_req, this_header, cnt);
|
||||
wsgi_req->headers_size += len;
|
||||
len = wsgi_req->socket->proto_write_header( wsgi_req, (char *)"\r\n", 2);
|
||||
wsgi_req->headers_size += len;
|
||||
wsgi_req->header_cnt++;
|
||||
|
||||
header_value = header_value_splitted+1;
|
||||
header_value_len -= header_value_splitted-header_value;
|
||||
|
||||
while(header_value_len && (header_value_splitted = memchr(header_value, '\n', header_value_len))) {
|
||||
header_value_splitted[0] = 0;
|
||||
|
||||
len = wsgi_req->socket->proto_write( wsgi_req, RSTRING_PTR(hkey), RSTRING_LEN(hkey));
|
||||
wsgi_req->headers_size += len;
|
||||
len = wsgi_req->socket->proto_write( wsgi_req, (char *)": ", 2);
|
||||
wsgi_req->headers_size += len;
|
||||
|
||||
len = wsgi_req->socket->proto_write( wsgi_req, header_value, header_value_splitted-header_value);
|
||||
wsgi_req->headers_size += len;
|
||||
len = wsgi_req->socket->proto_write( wsgi_req, (char *)"\r\n", 2);
|
||||
wsgi_req->headers_size += len;
|
||||
wsgi_req->header_cnt++;
|
||||
|
||||
header_value = header_value_splitted+1;
|
||||
header_value_len -= header_value_splitted-header_value;
|
||||
}
|
||||
//uwsgi_log("--%.*s: %.*s--\n", RSTRING_LEN(hkey), RSTRING_PTR(hkey), cnt, this_header);
|
||||
}
|
||||
|
||||
|
||||
clear2:
|
||||
rb_gc_unregister_address(&hkey);
|
||||
rb_gc_unregister_address(&hval);
|
||||
|
||||
clear:
|
||||
|
||||
return Qnil;
|
||||
@@ -508,6 +519,8 @@ int uwsgi_rack_request(struct wsgi_request *wsgi_req) {
|
||||
) {
|
||||
rb_hash_aset(env, rb_str_new(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len),
|
||||
rb_str_new(wsgi_req->hvec[i+1].iov_base, wsgi_req->hvec[i+1].iov_len));
|
||||
|
||||
//uwsgi_log("%.*s = %.*s\n", wsgi_req->hvec[i].iov_len, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i+1].iov_len, wsgi_req->hvec[i+1].iov_base);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
@@ -553,7 +566,7 @@ int uwsgi_rack_request(struct wsgi_request *wsgi_req) {
|
||||
ret = rb_protect( call_dispatch, env, &error);
|
||||
if (error) {
|
||||
uwsgi_ruby_exception();
|
||||
//return -1;
|
||||
goto clear;
|
||||
}
|
||||
|
||||
if (TYPE(ret) == T_ARRAY) {
|
||||
@@ -603,8 +616,6 @@ int uwsgi_rack_request(struct wsgi_request *wsgi_req) {
|
||||
rb_protect( iterate_headers, headers, &error);
|
||||
if (error) {
|
||||
uwsgi_ruby_exception();
|
||||
rb_gc_unregister_address(&status);
|
||||
rb_gc_unregister_address(&headers);
|
||||
goto clear;
|
||||
}
|
||||
}
|
||||
@@ -615,8 +626,6 @@ int uwsgi_rack_request(struct wsgi_request *wsgi_req) {
|
||||
|
||||
body = RARRAY_PTR(ret)[2] ;
|
||||
|
||||
// TODO protect to_path
|
||||
|
||||
if (rb_respond_to( body, rb_intern("to_path") )) {
|
||||
VALUE sendfile_path = rb_protect( body_to_path, body, &error);
|
||||
if (error) {
|
||||
@@ -631,7 +640,8 @@ int uwsgi_rack_request(struct wsgi_request *wsgi_req) {
|
||||
wsgi_req->response_size += uwsgi_sendfile(wsgi_req);
|
||||
}
|
||||
}
|
||||
rb_gc_unregister_address(&sendfile_path);
|
||||
// we need to close it...
|
||||
close(wsgi_req->sendfile_fd);
|
||||
}
|
||||
}
|
||||
else if (rb_respond_to( body, rb_intern("each") )) {
|
||||
@@ -649,14 +659,6 @@ int uwsgi_rack_request(struct wsgi_request *wsgi_req) {
|
||||
}
|
||||
}
|
||||
|
||||
//fine:
|
||||
|
||||
/* unregister all the objects created */
|
||||
|
||||
rb_gc_unregister_address(&status);
|
||||
rb_gc_unregister_address(&headers);
|
||||
rb_gc_unregister_address(&body);
|
||||
|
||||
}
|
||||
else {
|
||||
internal_server_error(wsgi_req, (char *)"Invalid RACK response");
|
||||
@@ -664,10 +666,6 @@ int uwsgi_rack_request(struct wsgi_request *wsgi_req) {
|
||||
|
||||
clear:
|
||||
|
||||
rb_gc_unregister_address(&ret);
|
||||
|
||||
rb_gc_unregister_address(&env);
|
||||
|
||||
if (ur.gc_freq <= 1 || ur.cycles%ur.gc_freq == 0) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("calling ruby GC\n");
|
||||
@@ -916,23 +914,14 @@ int uwsgi_rack_signal_handler(uint8_t sig, void *handler) {
|
||||
rb_ary_store(args, 0, rbhandler);
|
||||
VALUE rbsig = INT2NUM(sig);
|
||||
rb_ary_store(args, 1, rbsig);
|
||||
VALUE ret = rb_protect(rack_call_signal_handler, args, &error);
|
||||
rb_protect(rack_call_signal_handler, args, &error);
|
||||
if (error) {
|
||||
uwsgi_ruby_exception();
|
||||
// free resources (useless ?)
|
||||
rb_gc_unregister_address(&args);
|
||||
rb_gc_unregister_address(&ret);
|
||||
rb_gc_unregister_address(&rbsig);
|
||||
rb_gc();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// free resources (useless ?)
|
||||
rb_gc_unregister_address(&args);
|
||||
rb_gc_unregister_address(&ret);
|
||||
rb_gc_unregister_address(&rbsig);
|
||||
rb_gc();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ extern struct uwsgi_server uwsgi;
|
||||
int uwsgi_rpc_request(struct wsgi_request *wsgi_req) {
|
||||
|
||||
char *argv[256];
|
||||
uint16_t argvs[256];
|
||||
uint8_t argc = 0xff;
|
||||
|
||||
/* Standard RPC request */
|
||||
@@ -24,7 +25,7 @@ int uwsgi_rpc_request(struct wsgi_request *wsgi_req) {
|
||||
uwsgi_log("RPC pktsize %d\n", wsgi_req->uh.pktsize);
|
||||
#endif
|
||||
|
||||
if (uwsgi_parse_array(wsgi_req->buffer, wsgi_req->uh.pktsize, argv, &argc)) {
|
||||
if (uwsgi_parse_array(wsgi_req->buffer, wsgi_req->uh.pktsize, argv, argvs, &argc)) {
|
||||
uwsgi_log("Invalid RPC request. skip.\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -33,7 +34,7 @@ int uwsgi_rpc_request(struct wsgi_request *wsgi_req) {
|
||||
uwsgi_log("RPC args %d\n", argc-1);
|
||||
#endif
|
||||
|
||||
wsgi_req->uh.pktsize = uwsgi_rpc(argv[0], argc-1, argv+1, wsgi_req->buffer);
|
||||
wsgi_req->uh.pktsize = uwsgi_rpc(argv[0], argc-1, argv+1, argvs+1, wsgi_req->buffer);
|
||||
|
||||
if (wsgi_req->uh.modifier2 == 0) {
|
||||
wsgi_req->headers_size = wsgi_req->socket->proto_write_header(wsgi_req, (char *)&wsgi_req->uh, 4);
|
||||
|
||||
+94
-39
@@ -371,7 +371,8 @@ int uwsgi_read_response(int fd, struct uwsgi_header *uh, int timeout, char **buf
|
||||
}
|
||||
|
||||
if (buf && uh->pktsize > 0) {
|
||||
*buf = uwsgi_malloc(uh->pktsize);
|
||||
if (*buf == NULL)
|
||||
*buf = uwsgi_malloc(uh->pktsize);
|
||||
remains = uh->pktsize;
|
||||
ptr = *buf;
|
||||
ret = -1;
|
||||
@@ -423,9 +424,9 @@ int uwsgi_parse_packet(struct wsgi_request *wsgi_req, int timeout) {
|
||||
}
|
||||
if (status < 0) {
|
||||
if (status == -1)
|
||||
uwsgi_log("error parsing request\n");
|
||||
uwsgi_log_verbose("error parsing request\n");
|
||||
else if (status == -2)
|
||||
uwsgi_log("open-close packet (ping/check) received\n");
|
||||
uwsgi_log_verbose("open-close packet (ping/check) received\n");
|
||||
//close(upoll->fd);
|
||||
return 0;
|
||||
}
|
||||
@@ -434,7 +435,7 @@ int uwsgi_parse_packet(struct wsgi_request *wsgi_req, int timeout) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int uwsgi_parse_array(char *buffer, uint16_t size, char **argv, uint8_t *argc) {
|
||||
int uwsgi_parse_array(char *buffer, uint16_t size, char **argv, uint16_t argvs[], uint8_t *argc) {
|
||||
|
||||
char *ptrbuf, *bufferend;
|
||||
uint16_t strsize = 0;
|
||||
@@ -459,6 +460,7 @@ int uwsgi_parse_array(char *buffer, uint16_t size, char **argv, uint8_t *argc) {
|
||||
if (ptrbuf + strsize <= bufferend) {
|
||||
// item
|
||||
argv[*argc] = uwsgi_cheap_string(ptrbuf, strsize);
|
||||
argvs[*argc] = strsize;
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("arg %s\n", argv[*argc]);
|
||||
#endif
|
||||
@@ -1462,14 +1464,17 @@ char *uwsgi_get_mime_type(char *name, int namelen, int *size) {
|
||||
int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_t document_root_len, char *path_info, uint16_t path_info_len) {
|
||||
|
||||
struct stat st;
|
||||
struct iovec headers_vec[8];
|
||||
char real_filename[PATH_MAX];
|
||||
char *filename = uwsgi_concat3n(document_root, document_root_len, "/", 1, path_info, path_info_len);
|
||||
char content_length[sizeof(UMAX64_STR)+1];
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("checking for %s\n", filename);
|
||||
uwsgi_log("[uwsgi-fileserve] checking for %s\n", filename);
|
||||
#endif
|
||||
if (!realpath(filename, real_filename)) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("unable to get realpath() of the static file\n");
|
||||
uwsgi_log("[uwsgi-fileserve] unable to get realpath() of the static file\n");
|
||||
#endif
|
||||
free(filename);
|
||||
return -1;
|
||||
@@ -1478,9 +1483,10 @@ int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_
|
||||
free(filename);
|
||||
|
||||
if (uwsgi_starts_with(real_filename, strlen(real_filename), document_root, document_root_len)) {
|
||||
uwsgi_log("security error: %s is not under %.*s\n", real_filename, document_root_len, document_root);
|
||||
uwsgi_log("[uwsgi-fileserve] security error: %s is not under %.*s\n", real_filename, document_root_len, document_root);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!stat(real_filename, &st)) {
|
||||
int mime_type_size = 0;
|
||||
char *mime_type = uwsgi_get_mime_type(path_info, path_info_len, &mime_type_size);
|
||||
@@ -1488,13 +1494,21 @@ int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_
|
||||
time_t ims = parse_http_date(wsgi_req->if_modified_since, wsgi_req->if_modified_since_len);
|
||||
if (st.st_mtime <= ims) {
|
||||
wsgi_req->status = 304;
|
||||
wsgi_req->headers_size = wsgi_req->socket->proto_write_header(wsgi_req, wsgi_req->protocol, wsgi_req->protocol_len);
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, " 304 Not Modified\r\n", 19);
|
||||
headers_vec[0].iov_base = wsgi_req->protocol;
|
||||
headers_vec[0].iov_len = wsgi_req->protocol_len;
|
||||
headers_vec[1].iov_base = " 304 Not Modified\r\n";
|
||||
headers_vec[1].iov_len = 19;
|
||||
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, headers_vec, 2);
|
||||
|
||||
struct uwsgi_string_list *ah = uwsgi.additional_headers;
|
||||
while(ah) {
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, ah->value, ah->len);
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, "\r\n", 2);
|
||||
headers_vec[0].iov_base = ah->value;
|
||||
headers_vec[0].iov_len = ah->len;
|
||||
headers_vec[1].iov_base = "\r\n";
|
||||
headers_vec[1].iov_len = 2;
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, headers_vec, 2);
|
||||
wsgi_req->header_cnt++;
|
||||
ah = ah->next;
|
||||
}
|
||||
|
||||
@@ -1505,58 +1519,99 @@ int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_
|
||||
if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
|
||||
char http_last_modified[49];
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("file %s found\n", real_filename);
|
||||
uwsgi_log("[uwsgi-fileserve] file %s found\n", real_filename);
|
||||
#endif
|
||||
// no need to set content-type/content-length, they will be fixed by the http server/router
|
||||
|
||||
wsgi_req->headers_size = wsgi_req->socket->proto_write_header(wsgi_req, wsgi_req->protocol, wsgi_req->protocol_len);
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, " 200 OK\r\n", 9);
|
||||
// HTTP status
|
||||
headers_vec[0].iov_base = wsgi_req->protocol;
|
||||
headers_vec[0].iov_len = wsgi_req->protocol_len;
|
||||
headers_vec[1].iov_base = " 200 OK\r\n";
|
||||
headers_vec[1].iov_len = 9;
|
||||
wsgi_req->headers_size = wsgi_req->socket->proto_writev_header(wsgi_req, headers_vec, 2);
|
||||
|
||||
// uWSGI additional headers
|
||||
struct uwsgi_string_list *ah = uwsgi.additional_headers;
|
||||
while(ah) {
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, ah->value, ah->len);
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, "\r\n", 2);
|
||||
headers_vec[0].iov_base = ah->value;
|
||||
headers_vec[0].iov_len = ah->len;
|
||||
headers_vec[1].iov_base = "\r\n";
|
||||
headers_vec[1].iov_len = 2;
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, headers_vec, 2);
|
||||
wsgi_req->header_cnt++;
|
||||
ah = ah->next;
|
||||
}
|
||||
|
||||
// Content-Type (if available)
|
||||
if (mime_type_size > 0 && mime_type) {
|
||||
headers_vec[0].iov_base = "Content-Type: ";
|
||||
headers_vec[0].iov_len = 14;
|
||||
headers_vec[1].iov_base = mime_type;
|
||||
headers_vec[1].iov_len = mime_type_size;
|
||||
headers_vec[2].iov_base = "\r\n";
|
||||
headers_vec[2].iov_len = 2;
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, headers_vec, 3);
|
||||
wsgi_req->header_cnt++;
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, "Content-Type: ", 14);
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, mime_type, mime_type_size);
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, "\r\n", 2);
|
||||
}
|
||||
|
||||
// nginx
|
||||
if (uwsgi.file_serve_mode == 1) {
|
||||
wsgi_req->header_cnt += 2;
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, "X-Accel-Redirect: ", 18);
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, document_root, document_root_len);
|
||||
headers_vec[0].iov_base = "X-Accel-Redirect: "; headers_vec[0].iov_len = 18 ;
|
||||
headers_vec[1].iov_base = document_root; headers_vec[1].iov_len = document_root_len;
|
||||
if (document_root[document_root_len-1] != '/') {
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, "/", 1);
|
||||
headers_vec[2].iov_base = "/"; headers_vec[2].iov_len = 1;
|
||||
headers_vec[3].iov_base = path_info; headers_vec[3].iov_len = path_info_len;
|
||||
headers_vec[4].iov_base = "\r\n"; headers_vec[4].iov_len = 2;
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, headers_vec, 5);
|
||||
}
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, path_info, path_info_len);
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, "\r\n", 2);
|
||||
else {
|
||||
headers_vec[2].iov_base = path_info; headers_vec[2].iov_len = path_info_len;
|
||||
headers_vec[3].iov_base = "\r\n"; headers_vec[3].iov_len = 2;
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, headers_vec, 4);
|
||||
}
|
||||
// this is the final header (\r\n added)
|
||||
set_http_date(st.st_mtime, http_last_modified);
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, http_last_modified, 48);
|
||||
}
|
||||
else if (uwsgi.file_serve_mode == 2) {
|
||||
wsgi_req->header_cnt += 2;
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, "X-Sendfile: ", 12);
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, document_root, document_root_len);
|
||||
if (document_root[document_root_len-1] != '/') {
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, "/", 1);
|
||||
}
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, path_info, path_info_len);
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, "\r\n", 2);
|
||||
set_http_date(st.st_mtime, http_last_modified);
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, http_last_modified, 48);
|
||||
}
|
||||
else {
|
||||
wsgi_req->header_cnt += 1;
|
||||
// apache
|
||||
else if (uwsgi.file_serve_mode == 2) {
|
||||
headers_vec[0].iov_base = "X-Sendfile: "; headers_vec[0].iov_len = 12 ;
|
||||
headers_vec[1].iov_base = document_root; headers_vec[1].iov_len = document_root_len;
|
||||
if (document_root[document_root_len-1] != '/') {
|
||||
headers_vec[2].iov_base = "/"; headers_vec[2].iov_len = 1;
|
||||
headers_vec[3].iov_base = path_info; headers_vec[3].iov_len = path_info_len;
|
||||
headers_vec[4].iov_base = "\r\n"; headers_vec[4].iov_len = 2;
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, headers_vec, 5);
|
||||
}
|
||||
else {
|
||||
headers_vec[2].iov_base = path_info; headers_vec[2].iov_len = path_info_len;
|
||||
headers_vec[3].iov_base = "\r\n"; headers_vec[3].iov_len = 2;
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, headers_vec, 4);
|
||||
}
|
||||
// this is the final header (\r\n added)
|
||||
set_http_date(st.st_mtime, http_last_modified);
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, http_last_modified, 48);
|
||||
wsgi_req->header_cnt += 2;
|
||||
}
|
||||
// raw
|
||||
else {
|
||||
// set Content-Length
|
||||
headers_vec[0].iov_base = "Content-Length: ";
|
||||
headers_vec[0].iov_len = 16;
|
||||
headers_vec[1].iov_len = uwsgi_long2str2n(st.st_size, content_length, sizeof(UMAX64_STR)+1);
|
||||
headers_vec[1].iov_base = content_length;
|
||||
headers_vec[2].iov_base = "\r\n";
|
||||
headers_vec[2].iov_len = 2;
|
||||
// this is the final header (\r\n added)
|
||||
set_http_date(st.st_mtime, http_last_modified);
|
||||
headers_vec[3].iov_base = http_last_modified;
|
||||
headers_vec[3].iov_len = 48;
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, headers_vec, 4);
|
||||
wsgi_req->header_cnt += 2;
|
||||
wsgi_req->sendfile_fd = open(real_filename, O_RDONLY);
|
||||
wsgi_req->response_size += uwsgi_sendfile(wsgi_req);
|
||||
// here we need to close the sendfile fd (no-GC involved)
|
||||
close(wsgi_req->sendfile_fd);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ int uwsgi_register_rpc(char *name, uint8_t modifier1, uint8_t args, void *func)
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint16_t uwsgi_rpc(char *name, uint8_t argc, char *argv[], char *output) {
|
||||
uint16_t uwsgi_rpc(char *name, uint8_t argc, char *argv[], uint16_t argvs[], char *output) {
|
||||
|
||||
struct uwsgi_rpc *urpc = NULL;
|
||||
int i;
|
||||
@@ -50,9 +50,93 @@ uint16_t uwsgi_rpc(char *name, uint8_t argc, char *argv[], char *output) {
|
||||
|
||||
if (urpc) {
|
||||
if (uwsgi.p[urpc->modifier1]->rpc) {
|
||||
ret = uwsgi.p[urpc->modifier1]->rpc(urpc->func, argc, argv, output);
|
||||
ret = uwsgi.p[urpc->modifier1]->rpc(urpc->func, argc, argv, argvs, output);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
char *uwsgi_do_rpc(char *node, char *func, uint8_t argc, char *argv[], uint16_t argvs[], uint16_t *len) {
|
||||
|
||||
uint8_t i;
|
||||
uint16_t ulen;
|
||||
struct uwsgi_header uh;
|
||||
char *buffer = NULL;
|
||||
|
||||
*len = 0;
|
||||
|
||||
if (node == NULL || !strcmp(node, "")) {
|
||||
// allocate the whole buffer
|
||||
buffer = uwsgi_malloc(65536);
|
||||
*len = uwsgi_rpc(func, argc, argv, argvs, buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
// connect to node
|
||||
int fd = uwsgi_connect(node, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], 0);
|
||||
|
||||
if (fd < 0) return NULL;
|
||||
|
||||
// prepare a uwsgi array
|
||||
uint16_t buffer_size = 2 + strlen(func);
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
buffer_size += 2 + argvs[i];
|
||||
}
|
||||
|
||||
// allocate the whole buffer
|
||||
buffer = uwsgi_malloc(65536);
|
||||
|
||||
uh.modifier1 = 173;
|
||||
uh.pktsize = buffer_size;
|
||||
uh.modifier2 = 0;
|
||||
|
||||
// add func to the array
|
||||
char *bufptr = buffer;
|
||||
ulen = strlen(func);
|
||||
*bufptr++ = (uint8_t) (ulen & 0xff);
|
||||
*bufptr++ = (uint8_t) ((ulen >> 8) & 0xff);
|
||||
memcpy(bufptr, func, ulen);
|
||||
bufptr += ulen;
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
ulen = argvs[i];
|
||||
*bufptr++ = (uint8_t) (ulen & 0xff);
|
||||
*bufptr++ = (uint8_t) ((ulen >> 8) & 0xff);
|
||||
memcpy(bufptr, argv[i], ulen);
|
||||
bufptr += ulen;
|
||||
}
|
||||
|
||||
if (write(fd, &uh, 4) != 4) {
|
||||
uwsgi_error("write()");
|
||||
close(fd);
|
||||
free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (write(fd, buffer, buffer_size) != buffer_size) {
|
||||
uwsgi_error("write()");
|
||||
close(fd);
|
||||
free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (uwsgi_read_response(fd, &uh, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], &buffer) < 0) {
|
||||
close(fd);
|
||||
free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
*len = uh.pktsize;
|
||||
if (*len == 0) {
|
||||
free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
return buffer;
|
||||
|
||||
}
|
||||
|
||||
+11
-1
@@ -106,6 +106,7 @@ ssize_t uwsgi_do_sendfile(int sockfd, int filefd, size_t filesize, size_t chunk,
|
||||
#else
|
||||
static size_t nosf_buf_size = 0;
|
||||
static char *nosf_buf;
|
||||
char *nosf_buf2;
|
||||
|
||||
ssize_t jlen = 0;
|
||||
ssize_t rlen = 0;
|
||||
@@ -115,7 +116,16 @@ ssize_t uwsgi_do_sendfile(int sockfd, int filefd, size_t filesize, size_t chunk,
|
||||
nosf_buf = malloc(chunk);
|
||||
}
|
||||
else if (chunk != nosf_buf_size) {
|
||||
nosf_buf = realloc(nosf_buf, chunk);
|
||||
nosf_buf2 = realloc(nosf_buf, chunk);
|
||||
if (!nosf_buf2) {
|
||||
free(nosf_buf);
|
||||
}
|
||||
nosf_buf = nosf_buf2;
|
||||
}
|
||||
|
||||
if (!nosf_buf) {
|
||||
uwsgi_error("sendfile malloc()/realloc()");
|
||||
return 0;
|
||||
}
|
||||
|
||||
nosf_buf_size = chunk;
|
||||
|
||||
@@ -10,13 +10,15 @@ from setuptools.command.install_lib import install_lib
|
||||
from setuptools.command.build_ext import build_ext
|
||||
|
||||
"""
|
||||
This is a hack allowing you installing uWSGI and uwsgidecorators via pip and easy_install
|
||||
This is a hack allowing you installing
|
||||
uWSGI and uwsgidecorators via pip and easy_install
|
||||
"""
|
||||
|
||||
uwsgi_compiled = False
|
||||
|
||||
|
||||
def get_profile():
|
||||
profile = os.environ.get('UWSGI_PROFILE','buildconf/default.ini')
|
||||
profile = os.environ.get('UWSGI_PROFILE', 'buildconf/default.ini')
|
||||
if not profile.endswith('.ini'):
|
||||
profile = "%s.ini" % profile
|
||||
if not '/' in profile:
|
||||
@@ -24,6 +26,7 @@ def get_profile():
|
||||
|
||||
return profile
|
||||
|
||||
|
||||
def patch_bin_path(cmd, conf):
|
||||
|
||||
bin_name = conf.get('bin_name')
|
||||
@@ -33,7 +36,8 @@ def patch_bin_path(cmd, conf):
|
||||
os.makedirs(cmd.install_scripts)
|
||||
if not os.path.isabs(bin_name):
|
||||
print('Patching "bin_name" to properly install_scripts dir')
|
||||
conf.set('bin_name', os.path.join(cmd.install_scripts, conf.get('bin_name')))
|
||||
conf.set('bin_name',
|
||||
os.path.join(cmd.install_scripts, conf.get('bin_name')))
|
||||
except:
|
||||
conf.set('bin_name', sys.prefix + '/bin/' + bin_name)
|
||||
|
||||
@@ -45,7 +49,7 @@ class uWSGIBuilder(build_ext):
|
||||
if not uwsgi_compiled:
|
||||
conf = uc.uConf(get_profile())
|
||||
patch_bin_path(self, conf)
|
||||
uc.build_uwsgi( conf )
|
||||
uc.build_uwsgi(conf)
|
||||
uwsgi_compiled = True
|
||||
|
||||
|
||||
@@ -56,10 +60,11 @@ class uWSGIInstall(install):
|
||||
if not uwsgi_compiled:
|
||||
conf = uc.uConf(get_profile())
|
||||
patch_bin_path(self, conf)
|
||||
uc.build_uwsgi( conf )
|
||||
uc.build_uwsgi(conf)
|
||||
uwsgi_compiled = True
|
||||
install.run(self)
|
||||
|
||||
|
||||
class uWSGIInstallLib(install_lib):
|
||||
|
||||
def run(self):
|
||||
@@ -67,10 +72,11 @@ class uWSGIInstallLib(install_lib):
|
||||
if not uwsgi_compiled:
|
||||
conf = uc.uConf(get_profile())
|
||||
patch_bin_path(self, conf)
|
||||
uc.build_uwsgi( conf )
|
||||
uc.build_uwsgi(conf)
|
||||
uwsgi_compiled = True
|
||||
install_lib.run(self)
|
||||
|
||||
|
||||
class uWSGIDistribution(Distribution):
|
||||
|
||||
def __init__(self, *attrs):
|
||||
@@ -79,6 +85,7 @@ class uWSGIDistribution(Distribution):
|
||||
self.cmdclass['install_lib'] = uWSGIInstallLib
|
||||
self.cmdclass['build_ext'] = uWSGIBuilder
|
||||
|
||||
|
||||
setup(name='uWSGI',
|
||||
version=uc.uwsgi_version,
|
||||
description='The uWSGI server',
|
||||
@@ -86,7 +93,6 @@ setup(name='uWSGI',
|
||||
author_email='info@unbit.it',
|
||||
url='http://projects.unbit.it/uwsgi/',
|
||||
license='GPL2',
|
||||
py_modules = ['uwsgidecorators'],
|
||||
distclass = uWSGIDistribution,
|
||||
py_modules=['uwsgidecorators'],
|
||||
distclass=uWSGIDistribution,
|
||||
)
|
||||
|
||||
|
||||
@@ -12,6 +12,28 @@ int uwsgi_signal_handler(uint8_t sig) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// check for COW
|
||||
if (uwsgi.master_process) {
|
||||
if (use->wid != 0 && use->wid != uwsgi.mywid) {
|
||||
uwsgi_log("[uwsgi-signal] you have registered this signal in worker %d memory area, only that process will be able to run it\n", use->wid);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
// in lazy mode (without a master), only the same worker will be able to run handlers
|
||||
else if (uwsgi.lazy) {
|
||||
if (use->wid != uwsgi.mywid) {
|
||||
uwsgi_log("[uwsgi-signal] you have registered this signal in worker %d memory area, only that process will be able to run it\n", use->wid);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// when master is not active, worker1 is the COW-leader
|
||||
if (use->wid != 1 && use->wid != uwsgi.mywid) {
|
||||
uwsgi_log("[uwsgi-signal] you have registered this signal in worker %d memory area, only that process will be able to run it\n", use->wid);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// set harakiri here (if required and if i am a worker)
|
||||
|
||||
if (uwsgi.mywid > 0) {
|
||||
@@ -81,15 +103,22 @@ int uwsgi_register_signal(uint8_t sig, char *receiver, void *handler, uint8_t mo
|
||||
|
||||
use = &uwsgi.shared->signal_table[sig];
|
||||
|
||||
if (use->handler) {
|
||||
uwsgi_log("[uwsgi-signal] you cannot re-register a signal !!!\n");
|
||||
uwsgi_unlock(uwsgi.signal_table_lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy(use->receiver, receiver);
|
||||
use->handler = handler;
|
||||
use->modifier1 = modifier1;
|
||||
use->wid = uwsgi.mywid;
|
||||
|
||||
if (use->receiver[0] == 0) {
|
||||
uwsgi_log("[uwsgi-signal] signum %d registered (modifier1: %d target: default, any worker)\n", sig, modifier1);
|
||||
uwsgi_log("[uwsgi-signal] signum %d registered (wid: %d modifier1: %d target: default, any worker)\n", sig, uwsgi.mywid, modifier1);
|
||||
}
|
||||
else {
|
||||
uwsgi_log("[uwsgi-signal] signum %d registered (modifier1: %d target: %s)\n", sig, modifier1, receiver);
|
||||
uwsgi_log("[uwsgi-signal] signum %d registered (wid: %d modifier1: %d target: %s)\n", sig, uwsgi.mywid, modifier1, receiver);
|
||||
}
|
||||
|
||||
uwsgi_unlock(uwsgi.signal_table_lock);
|
||||
|
||||
+105
-24
@@ -61,6 +61,8 @@ struct uwsgi_subscribe_slot *uwsgi_get_subscribe_slot(struct uwsgi_subscribe_slo
|
||||
}
|
||||
#endif
|
||||
current_slot = current_slot->next;
|
||||
// check for loopy optimization
|
||||
if (current_slot == *slot) break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -83,6 +85,7 @@ struct uwsgi_subscribe_node *uwsgi_get_subscribe_node(struct uwsgi_subscribe_slo
|
||||
if (current - node->last_check > uwsgi.subscription_tolerance) {
|
||||
if (node->death_mark == 0)
|
||||
uwsgi_log("[uwsgi-subscription] %.*s => marking %.*s as failed (no announce received in %d seconds)\n", (int) keylen, key, (int) node->len, node->name, uwsgi.subscription_tolerance);
|
||||
node->failcnt++;
|
||||
node->death_mark = 1;
|
||||
}
|
||||
if (node->death_mark && node->reference == 0) {
|
||||
@@ -95,7 +98,8 @@ struct uwsgi_subscribe_node *uwsgi_get_subscribe_node(struct uwsgi_subscribe_slo
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (rr_pos == current_slot->rr) {
|
||||
// only unmarked nodes can respond
|
||||
if (node->death_mark == 0 && rr_pos == current_slot->rr) {
|
||||
current_slot->rr++;
|
||||
node->reference++;
|
||||
return node;
|
||||
@@ -103,8 +107,10 @@ struct uwsgi_subscribe_node *uwsgi_get_subscribe_node(struct uwsgi_subscribe_slo
|
||||
node = node->next;
|
||||
rr_pos++;
|
||||
}
|
||||
current_slot->rr = 0;
|
||||
current_slot->rr = 1;
|
||||
if (current_slot->nodes) {
|
||||
if (current_slot->nodes->death_mark)
|
||||
return NULL;
|
||||
current_slot->nodes->reference++;
|
||||
}
|
||||
return current_slot->nodes;
|
||||
@@ -159,6 +165,20 @@ int uwsgi_remove_subscribe_node(struct uwsgi_subscribe_slot **slot, struct uwsgi
|
||||
free(node);
|
||||
// no more nodes, remove the slot too
|
||||
if (node_slot->nodes == NULL) {
|
||||
|
||||
ret = 1;
|
||||
|
||||
// first check if i am the only node
|
||||
if ((!prev_slot && !next_slot) || next_slot == node_slot) {
|
||||
free(node_slot);
|
||||
*slot = NULL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
// if i am the main entry point, set the next value
|
||||
if (node_slot == *slot) {
|
||||
*slot = next_slot;
|
||||
}
|
||||
|
||||
if (prev_slot) {
|
||||
prev_slot->next = next_slot;
|
||||
@@ -176,14 +196,16 @@ int uwsgi_remove_subscribe_node(struct uwsgi_subscribe_slot **slot, struct uwsgi
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = 1;
|
||||
free(node_slot);
|
||||
// am i the only slot ?
|
||||
if (!prev_slot && !next_slot) {
|
||||
*slot = NULL;
|
||||
struct uwsgi_subscribe_slot *x_slot = *slot;
|
||||
while(x_slot) {
|
||||
x_slot = x_slot->next;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
end:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -198,9 +220,11 @@ struct uwsgi_subscribe_node *uwsgi_add_subscribe_node(struct uwsgi_subscribe_slo
|
||||
node = current_slot->nodes;
|
||||
while(node) {
|
||||
if (!uwsgi_strncmp(node->name, node->len, usr->address, usr->address_len)) {
|
||||
// remove death mark
|
||||
// remove death mark and update cores and load
|
||||
node->death_mark = 0;
|
||||
node->last_check = time(NULL);
|
||||
node->cores = usr->cores;
|
||||
node->load = usr->load;
|
||||
return node;
|
||||
}
|
||||
old_node = node;
|
||||
@@ -211,8 +235,13 @@ struct uwsgi_subscribe_node *uwsgi_add_subscribe_node(struct uwsgi_subscribe_slo
|
||||
node->len = usr->address_len;
|
||||
node->modifier1 = usr->modifier1;
|
||||
node->modifier2 = usr->modifier2;
|
||||
node->requests = 0;
|
||||
node->transferred = 0;
|
||||
node->reference = 0;
|
||||
node->death_mark = 0;
|
||||
node->failcnt = 0;
|
||||
node->cores = usr->cores;
|
||||
node->load = usr->load;
|
||||
node->last_check = time(NULL);
|
||||
node->slot = current_slot;
|
||||
memcpy(node->name, usr->address, usr->address_len);
|
||||
@@ -247,9 +276,14 @@ struct uwsgi_subscribe_node *uwsgi_add_subscribe_node(struct uwsgi_subscribe_slo
|
||||
current_slot->nodes->slot = current_slot;
|
||||
current_slot->nodes->len = usr->address_len;
|
||||
current_slot->nodes->reference = 0;
|
||||
current_slot->nodes->requests = 0;
|
||||
current_slot->nodes->transferred = 0;
|
||||
current_slot->nodes->death_mark = 0;
|
||||
current_slot->nodes->failcnt = 0;
|
||||
current_slot->nodes->modifier1 = usr->modifier1;
|
||||
current_slot->nodes->modifier2 = usr->modifier2;
|
||||
current_slot->nodes->cores = usr->cores;
|
||||
current_slot->nodes->load = usr->load;
|
||||
memcpy(current_slot->nodes->name, usr->address, usr->address_len);
|
||||
current_slot->nodes->last_check = time(NULL);
|
||||
|
||||
@@ -325,13 +359,21 @@ struct uwsgi_subscribe_node *uwsgi_add_subscribe_node(struct uwsgi_subscribe_slo
|
||||
}
|
||||
|
||||
|
||||
void uwsgi_send_subscription(char *udp_address, char *key, size_t keysize, char *modifier1, size_t modifier1_len, uint8_t cmd) {
|
||||
void uwsgi_send_subscription(char *udp_address, char *key, size_t keysize, uint8_t modifier1, uint8_t modifier2, uint8_t cmd) {
|
||||
|
||||
size_t ssb_size = 4 + (2 + 3) + (2 + keysize) + (2 + 7) + (2 + strlen(uwsgi.sockets->name));
|
||||
char value_cores[sizeof(UMAX64_STR)+1];
|
||||
char value_load[sizeof(UMAX64_STR)+1];
|
||||
char value_modifier1[4];
|
||||
char value_modifier2[4];
|
||||
int value_cores_size = uwsgi_long2str2n(uwsgi.numproc*uwsgi.cores, value_cores, sizeof(UMAX64_STR));
|
||||
int value_load_size = uwsgi_long2str2n(uwsgi.shared->load, value_load, sizeof(UMAX64_STR));
|
||||
int value_modifier1_size = uwsgi_long2str2n(modifier1, value_modifier1, 3);
|
||||
int value_modifier2_size = uwsgi_long2str2n(modifier2, value_modifier2, 3);
|
||||
|
||||
if (modifier1) {
|
||||
ssb_size += (2 + 9) + (2 + modifier1_len);
|
||||
}
|
||||
if (!uwsgi.sockets) return;
|
||||
|
||||
size_t ssb_size = 4 + (2 + 3) + (2 + keysize) + (2 + 7) + (2 + strlen(uwsgi.sockets->name)) + (2+9 + 2+value_modifier1_size) +
|
||||
(2+9 + 2+value_modifier2_size) + (2+5 + 2+value_cores_size) + (2+4 + 2+value_load_size);
|
||||
|
||||
char *subscrbuf = uwsgi_malloc(ssb_size);
|
||||
// leave space for uwsgi header
|
||||
@@ -364,20 +406,59 @@ void uwsgi_send_subscription(char *udp_address, char *key, size_t keysize, char
|
||||
ssb+=ustrlen;
|
||||
|
||||
// modifier1 = "modifier1"
|
||||
if (modifier1) {
|
||||
ustrlen = 9;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, "modifier1", ustrlen);
|
||||
ssb+=ustrlen;
|
||||
ustrlen = 9;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, "modifier1", ustrlen);
|
||||
ssb+=ustrlen;
|
||||
|
||||
ustrlen = modifier1_len;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, modifier1, ustrlen);
|
||||
ssb+=ustrlen;
|
||||
}
|
||||
ustrlen = value_modifier1_size;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, value_modifier1, value_modifier1_size);
|
||||
ssb+=ustrlen;
|
||||
|
||||
// modifier2 = "modifier2"
|
||||
ustrlen = 9;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, "modifier2", ustrlen);
|
||||
ssb+=ustrlen;
|
||||
|
||||
ustrlen = value_modifier2_size;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, value_modifier2, value_modifier2_size);
|
||||
ssb+=ustrlen;
|
||||
|
||||
// cores = uwsgi.numproc * uwsgi.cores
|
||||
ustrlen = 5;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, "cores", ustrlen);
|
||||
ssb+=ustrlen;
|
||||
|
||||
ustrlen = value_cores_size;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, value_cores, value_cores_size);
|
||||
ssb+=ustrlen;
|
||||
|
||||
// load
|
||||
ustrlen = 4;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, "load", ustrlen);
|
||||
ssb+=ustrlen;
|
||||
|
||||
ustrlen = value_load_size;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, value_load, value_load_size);
|
||||
ssb+=ustrlen;
|
||||
|
||||
|
||||
send_udp_message(224, cmd, udp_address, subscrbuf, ssb_size-4);
|
||||
free(subscrbuf);
|
||||
}
|
||||
|
||||
|
||||
@@ -320,7 +320,11 @@ void log_socket(char *socket_name) {
|
||||
|
||||
void create_logpipe(void) {
|
||||
|
||||
#if defined(SOCK_SEQPACKET) && defined(__linux__)
|
||||
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, uwsgi.shared->worker_log_pipe)) {
|
||||
#else
|
||||
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, uwsgi.shared->worker_log_pipe)) {
|
||||
#endif
|
||||
uwsgi_error("socketpair()\n");
|
||||
exit(1);
|
||||
}
|
||||
@@ -739,81 +743,76 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
|
||||
#ifdef __linux__
|
||||
#ifdef MADV_MERGEABLE
|
||||
|
||||
unsigned long long *ksm_mappings_last = NULL;
|
||||
int ksm_mappings_last_lines = 0;
|
||||
unsigned long long *ksm_mappings_current = NULL;
|
||||
int ksm_mappings_current_lines = 0;
|
||||
|
||||
void uwsgi_linux_ksm_map(void) {
|
||||
|
||||
char map_line_buf[1024];
|
||||
unsigned long long start, end;
|
||||
int dirty = 0;
|
||||
int i;
|
||||
int errors = 0;
|
||||
unsigned long long *tmp_ptr;
|
||||
size_t i;
|
||||
unsigned long long start = 0, end = 0;
|
||||
int errors = 0; int lines = 0;
|
||||
|
||||
ksm_mappings_current = NULL;
|
||||
ksm_mappings_current_lines = 0;
|
||||
int fd = open("/proc/self/maps", O_RDONLY);
|
||||
if (fd < 0) {
|
||||
uwsgi_error_open("[uwsgi-KSM] /proc/self/maps");
|
||||
return ;
|
||||
}
|
||||
|
||||
FILE *process_maps = fopen("/proc/self/maps", "r");
|
||||
// allocate memory if not available;
|
||||
if (uwsgi.ksm_mappings_current == NULL) {
|
||||
if (!uwsgi.ksm_buffer_size) uwsgi.ksm_buffer_size = 32768;
|
||||
uwsgi.ksm_mappings_current = uwsgi_malloc(uwsgi.ksm_buffer_size);
|
||||
uwsgi.ksm_mappings_current_size = 0;
|
||||
}
|
||||
if (uwsgi.ksm_mappings_last == NULL) {
|
||||
if (!uwsgi.ksm_buffer_size) uwsgi.ksm_buffer_size = 32768;
|
||||
uwsgi.ksm_mappings_last = uwsgi_malloc(uwsgi.ksm_buffer_size);
|
||||
uwsgi.ksm_mappings_last_size = 0;
|
||||
}
|
||||
|
||||
if (process_maps) {
|
||||
while( fgets(map_line_buf, 1024, process_maps)) {
|
||||
if (fscanf(process_maps, "%llx-%llx %*s", &start, &end) == 2) {
|
||||
ksm_mappings_current_lines+=2;
|
||||
tmp_ptr = ksm_mappings_current;
|
||||
ksm_mappings_current = realloc(ksm_mappings_current, sizeof(unsigned long long) * ksm_mappings_current_lines);
|
||||
if (!ksm_mappings_current) {
|
||||
uwsgi_error("[uwsgi-KSM] /proc/self/maps realloc()");
|
||||
fclose(process_maps);
|
||||
if (tmp_ptr) {
|
||||
free(tmp_ptr);
|
||||
}
|
||||
return;
|
||||
}
|
||||
ksm_mappings_current[ksm_mappings_current_lines-2] = start;
|
||||
ksm_mappings_current[ksm_mappings_current_lines-1] = end;
|
||||
}
|
||||
}
|
||||
fclose(process_maps);
|
||||
uwsgi.ksm_mappings_current_size = read(fd, uwsgi.ksm_mappings_current, uwsgi.ksm_buffer_size);
|
||||
close(fd);
|
||||
if (uwsgi.ksm_mappings_current_size <= 0) {
|
||||
uwsgi_log("[uwsgi-KSM] unable to read /proc/self/maps data\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ksm_mappings_last == NULL || ksm_mappings_last_lines == 0 || ksm_mappings_last_lines != ksm_mappings_current_lines) {
|
||||
// we now have areas
|
||||
if (uwsgi.ksm_mappings_last_size == 0 || uwsgi.ksm_mappings_current_size == 0 || uwsgi.ksm_mappings_current_size != uwsgi.ksm_mappings_last_size) {
|
||||
dirty = 1;
|
||||
}
|
||||
else {
|
||||
if (memcmp(uwsgi.ksm_mappings_current, uwsgi.ksm_mappings_last, uwsgi.ksm_mappings_current_size) != 0) {
|
||||
dirty = 1;
|
||||
}
|
||||
else {
|
||||
for(i=0;i<ksm_mappings_current_lines;i+=2) {
|
||||
if (ksm_mappings_current[i] != ksm_mappings_last[i]) {
|
||||
dirty = 1;
|
||||
break;
|
||||
}
|
||||
if (ksm_mappings_current[i+1] != ksm_mappings_last[i+1]) {
|
||||
dirty = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// it is dirty, swap addresses and parse it
|
||||
if (dirty) {
|
||||
char *tmp = uwsgi.ksm_mappings_last;
|
||||
uwsgi.ksm_mappings_last = uwsgi.ksm_mappings_current;
|
||||
uwsgi.ksm_mappings_current = tmp;
|
||||
|
||||
size_t tmp_size = uwsgi.ksm_mappings_last_size;
|
||||
uwsgi.ksm_mappings_last_size = uwsgi.ksm_mappings_current_size;
|
||||
uwsgi.ksm_mappings_current_size = tmp_size;
|
||||
|
||||
// scan each line and call madvise on it
|
||||
char *ptr = uwsgi.ksm_mappings_last;
|
||||
for(i=0;i<uwsgi.ksm_mappings_last_size;i++) {
|
||||
if (uwsgi.ksm_mappings_last[i] == '\n') {
|
||||
lines++;
|
||||
uwsgi.ksm_mappings_last[i] = 0;
|
||||
if (sscanf(ptr, "%llx-%llx %*s", &start, &end) == 2) {
|
||||
if (madvise((void *) (long) start, (size_t) (end-start), MADV_MERGEABLE)) {
|
||||
errors ++;
|
||||
}
|
||||
}
|
||||
uwsgi.ksm_mappings_last[i] = '\n';
|
||||
ptr = uwsgi.ksm_mappings_last+i+1;
|
||||
}
|
||||
}
|
||||
|
||||
if (dirty) {
|
||||
|
||||
for(i=0;i<ksm_mappings_current_lines;i+=2) {
|
||||
if (madvise((void *) (long) ksm_mappings_current[i], (size_t) (ksm_mappings_current[i+1]-ksm_mappings_current[i]), MADV_MERGEABLE)) {
|
||||
errors += 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (ksm_mappings_last)
|
||||
free(ksm_mappings_last);
|
||||
ksm_mappings_last = ksm_mappings_current;
|
||||
ksm_mappings_last_lines = ksm_mappings_current_lines;
|
||||
|
||||
if (errors >= ksm_mappings_current_lines) {
|
||||
uwsgi_error("[uwsgi-KSM] unable to share pages");
|
||||
}
|
||||
}
|
||||
// if not dirty, free ksm_mappings_current
|
||||
else {
|
||||
free(ksm_mappings_current);
|
||||
if (errors >= lines) {
|
||||
uwsgi_error("[uwsgi-KSM] unable to share pages");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1653,11 +1652,18 @@ int uwsgi_read_whole_body(struct wsgi_request *wsgi_req, char *buf, size_t len)
|
||||
else {
|
||||
post_chunk = read(wsgi_req->poll.fd, buf, post_remains);
|
||||
}
|
||||
|
||||
if (post_chunk < 0) {
|
||||
uwsgi_error("read()");
|
||||
goto end;
|
||||
}
|
||||
if (!fwrite(buf, post_chunk, 1, wsgi_req->async_post)) {
|
||||
|
||||
if (post_chunk == 0) {
|
||||
uwsgi_log("client did not send the whole body: %s\n", strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (fwrite(buf, post_chunk, 1, wsgi_req->async_post) != 1) {
|
||||
uwsgi_error("fwrite()");
|
||||
goto end;
|
||||
}
|
||||
@@ -2145,6 +2151,7 @@ char *uwsgi_open_and_read(char *url, int *size, int add_zero, char *magic_table[
|
||||
|
||||
if (S_ISFIFO(sb.st_mode)) {
|
||||
buffer = uwsgi_read_fd(fd, size, add_zero);
|
||||
close(fd);
|
||||
goto end;
|
||||
}
|
||||
|
||||
@@ -2355,6 +2362,12 @@ int uwsgi_num2str2n(int num, char *ptr, int size) {
|
||||
return snprintf(ptr, size, "%d", num);
|
||||
}
|
||||
|
||||
int uwsgi_long2str2n(unsigned long long num, char *ptr, int size) {
|
||||
int ret = snprintf(ptr, size, "%llu", num);
|
||||
if (ret < 0) return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int is_unix(char *socket_name, int len) {
|
||||
int i;
|
||||
for (i = 0; i < len; i++) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
_socket_nb(uwsgi.shared->worker_log_pipe[1]
|
||||
|
||||
*** uWSGI ***
|
||||
|
||||
Copyright (C) 2009-2011 Unbit S.a.s. <info@unbit.it>
|
||||
@@ -272,6 +272,7 @@ static struct option long_base_options[] = {
|
||||
{"mimefile", required_argument, 0, LONG_ARGS_MIMEFILE},
|
||||
{"mime-file", required_argument, 0, LONG_ARGS_MIMEFILE},
|
||||
{"file-serve-mode", required_argument, 0, LONG_ARGS_FILE_SERVE_MODE},
|
||||
{"fileserve-mode", required_argument, 0, LONG_ARGS_FILE_SERVE_MODE},
|
||||
{"check-cache", no_argument, &uwsgi.check_cache, 1},
|
||||
{"close-on-exec", no_argument, &uwsgi.close_on_exec, 1},
|
||||
{"mode", required_argument, 0, LONG_ARGS_MODE},
|
||||
@@ -303,6 +304,22 @@ static struct option long_base_options[] = {
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
void show_config(void) {
|
||||
int i;
|
||||
fprintf(stdout, "\n;uWSGI instance configuration\n[uwsgi]\n");
|
||||
for (i = 0; i < uwsgi.exported_opts_cnt; i++) {
|
||||
if (uwsgi.exported_opts[i]->value) {
|
||||
fprintf(stdout, "%s = %s\n", uwsgi.exported_opts[i]->key, uwsgi.exported_opts[i]->value);
|
||||
}
|
||||
else {
|
||||
fprintf(stdout, "%s = true\n", uwsgi.exported_opts[i]->key);
|
||||
}
|
||||
}
|
||||
fprintf(stdout, ";end of configuration\n\n");
|
||||
|
||||
}
|
||||
|
||||
|
||||
void uwsgi_configure(void) {
|
||||
|
||||
struct option *lopt;
|
||||
@@ -765,6 +782,7 @@ void stats(int signum) {
|
||||
int i, j;
|
||||
|
||||
if (uwsgi.mywid == 0) {
|
||||
show_config();
|
||||
uwsgi_log("\tworkers total requests: %llu\n", uwsgi.workers[0].requests);
|
||||
uwsgi_log("-----------------\n");
|
||||
for(j=1;j<=uwsgi.numproc;j++) {
|
||||
@@ -992,6 +1010,9 @@ void fixup_argv_and_environ(int argc, char **argv, char **environ) {
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef UWSGI_AS_SHARED_LIBRARY
|
||||
int uwsgi_init(int argc, char *argv[], char *envp[]) {
|
||||
|
||||
@@ -1299,18 +1320,19 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
}
|
||||
else {
|
||||
int magic = 0;
|
||||
for (i = 0; i < uwsgi.gp_cnt; i++) {
|
||||
if (uwsgi.gp[i]->magic) {
|
||||
if (uwsgi.gp[i]->magic(NULL, lazy)) {
|
||||
int j;
|
||||
for (j = 0; j< uwsgi.gp_cnt; j++) {
|
||||
if (uwsgi.gp[j]->magic) {
|
||||
if (uwsgi.gp[j]->magic(NULL, lazy)) {
|
||||
magic = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!magic) {
|
||||
for (i = 0; i < 0xFF; i++) {
|
||||
if (uwsgi.p[i]->magic) {
|
||||
if (uwsgi.p[i]->magic(NULL, lazy)) {
|
||||
for (j = 0; j < 0xFF; j++) {
|
||||
if (uwsgi.p[j]->magic) {
|
||||
if (uwsgi.p[j]->magic(NULL, lazy)) {
|
||||
magic = 1;
|
||||
break;
|
||||
}
|
||||
@@ -1446,16 +1468,7 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
}
|
||||
|
||||
if (uwsgi.show_config) {
|
||||
fprintf(stdout, "\n;uWSGI instance configuration\n[uwsgi]\n");
|
||||
for (i = 0; i < uwsgi.exported_opts_cnt; i++) {
|
||||
if (uwsgi.exported_opts[i]->value) {
|
||||
fprintf(stdout, "%s = %s\n", uwsgi.exported_opts[i]->key, uwsgi.exported_opts[i]->value);
|
||||
}
|
||||
else {
|
||||
fprintf(stdout, "%s = true\n", uwsgi.exported_opts[i]->key);
|
||||
}
|
||||
}
|
||||
fprintf(stdout, ";end of configuration\n\n");
|
||||
show_config();
|
||||
}
|
||||
|
||||
|
||||
@@ -1737,6 +1750,7 @@ int uwsgi_start(void *v_argv) {
|
||||
|
||||
|
||||
uwsgi_register_loop("simple", simple_loop);
|
||||
#ifdef UWSGI_ASYNC
|
||||
uwsgi_register_loop("async", async_loop);
|
||||
|
||||
|
||||
@@ -1764,6 +1778,7 @@ int uwsgi_start(void *v_argv) {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!getrlimit(RLIMIT_NOFILE, &uwsgi.rl)) {
|
||||
uwsgi.max_fd = uwsgi.rl.rlim_cur;
|
||||
@@ -2430,6 +2445,19 @@ skipzero:
|
||||
memset(uwsgi.core[j], 0, sizeof(struct uwsgi_core));
|
||||
}
|
||||
|
||||
// preinit apps (create the language environment)
|
||||
for (i = 0; i < 0xFF; i++) {
|
||||
if (uwsgi.p[i]->preinit_apps) {
|
||||
uwsgi.p[i]->preinit_apps();
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < uwsgi.gp_cnt; i++) {
|
||||
if (uwsgi.gp[i]->preinit_apps) {
|
||||
uwsgi.gp[i]->preinit_apps();
|
||||
}
|
||||
}
|
||||
|
||||
//init apps hook (if not lazy)
|
||||
if (!uwsgi.lazy) {
|
||||
uwsgi_init_all_apps();
|
||||
@@ -2842,16 +2870,14 @@ skipzero:
|
||||
// eventually remap plugins
|
||||
if (uwsgi.remap_modifier) {
|
||||
char *map = strtok(uwsgi.remap_modifier, ",");
|
||||
struct uwsgi_plugin *up_tmp;
|
||||
while (map != NULL) {
|
||||
char *colon = strchr(map, ':');
|
||||
if (colon) {
|
||||
colon[0] = 0;
|
||||
int rm_src = atoi(map);
|
||||
int rm_dst = atoi(colon + 1);
|
||||
up_tmp = uwsgi.p[rm_dst];
|
||||
uwsgi.p[rm_dst]->request = uwsgi.p[rm_src]->request;
|
||||
uwsgi.p[rm_src]->after_request = up_tmp->after_request;
|
||||
uwsgi.p[rm_dst]->after_request = uwsgi.p[rm_src]->after_request;
|
||||
}
|
||||
map = strtok(NULL, ",");
|
||||
}
|
||||
@@ -2948,9 +2974,11 @@ void uwsgi_ignition() {
|
||||
long y = 0;
|
||||
simple_loop((void *) y);
|
||||
}
|
||||
#ifdef UWSGI_ASYNC
|
||||
else {
|
||||
async_loop(NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -656,6 +656,7 @@ struct uwsgi_plugin {
|
||||
int (*request) (struct wsgi_request *);
|
||||
void (*after_request) (struct wsgi_request *);
|
||||
void (*init_apps) (void);
|
||||
void (*preinit_apps) (void);
|
||||
void (*fixup) (void);
|
||||
void (*master_fixup) (int);
|
||||
void (*master_cycle) (void);
|
||||
@@ -677,7 +678,7 @@ struct uwsgi_plugin {
|
||||
|
||||
int (*spooler) (char *, char *, uint16_t, char *, size_t);
|
||||
|
||||
uint16_t(*rpc) (void *, uint8_t, char **, char *);
|
||||
uint16_t(*rpc) (void *, uint8_t, char **, uint16_t *, char *);
|
||||
|
||||
void (*jail) (int (*)(void *), char **);
|
||||
|
||||
@@ -1554,6 +1555,11 @@ struct uwsgi_server {
|
||||
#ifdef __linux__
|
||||
#ifdef MADV_MERGEABLE
|
||||
int linux_ksm;
|
||||
int ksm_buffer_size;
|
||||
char *ksm_mappings_last;
|
||||
char *ksm_mappings_current;
|
||||
size_t ksm_mappings_last_size;
|
||||
size_t ksm_mappings_current_size;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1573,6 +1579,7 @@ struct uwsgi_lb_group {
|
||||
|
||||
|
||||
struct uwsgi_signal_entry {
|
||||
int wid;
|
||||
uint8_t modifier1;
|
||||
char receiver[64];
|
||||
void *handler;
|
||||
@@ -1701,7 +1708,7 @@ struct uwsgi_shared {
|
||||
#ifdef __linux__
|
||||
struct tcp_info ti;
|
||||
#endif
|
||||
|
||||
uint64_t load;
|
||||
struct uwsgi_cron cron[MAX_CRONS];
|
||||
int cron_cnt;
|
||||
};
|
||||
@@ -2096,11 +2103,12 @@ void uwsgi_route_signal(uint8_t);
|
||||
int uwsgi_start(void *);
|
||||
|
||||
int uwsgi_register_rpc(char *, uint8_t, uint8_t, void *);
|
||||
uint16_t uwsgi_rpc(char *, uint8_t, char **, char *);
|
||||
uint16_t uwsgi_rpc(char *, uint8_t, char **, uint16_t *, char *);
|
||||
char *uwsgi_do_rpc(char *, char *, uint8_t, char **, uint16_t *, uint16_t *);
|
||||
|
||||
char *uwsgi_cheap_string(char *, int);
|
||||
|
||||
int uwsgi_parse_array(char *, uint16_t, char **, uint8_t *);
|
||||
int uwsgi_parse_array(char *, uint16_t, char **, uint16_t *, uint8_t *);
|
||||
|
||||
void log_syslog(char *);
|
||||
|
||||
@@ -2210,6 +2218,9 @@ struct uwsgi_subscribe_req {
|
||||
|
||||
uint8_t modifier1;
|
||||
uint8_t modifier2;
|
||||
|
||||
uint64_t cores;
|
||||
uint64_t load;
|
||||
};
|
||||
|
||||
#ifndef _NO_UWSGI_RB
|
||||
@@ -2453,6 +2464,9 @@ struct uwsgi_subscribe_node {
|
||||
|
||||
int death_mark;
|
||||
uint64_t reference;
|
||||
uint64_t cores;
|
||||
uint64_t load;
|
||||
uint64_t failcnt;
|
||||
|
||||
struct uwsgi_subscribe_slot *slot;
|
||||
|
||||
@@ -2503,7 +2517,7 @@ void manage_cluster_announce(char *, uint16_t, char *, uint16_t, void *);
|
||||
int uwsgi_read_response(int, struct uwsgi_header *, int, char **);
|
||||
char *uwsgi_simple_file_read(char *);
|
||||
|
||||
void uwsgi_send_subscription(char *, char *, size_t , char *, size_t, uint8_t);
|
||||
void uwsgi_send_subscription(char *, char *, size_t , uint8_t, uint8_t , uint8_t);
|
||||
|
||||
void uwsgi_subscribe(char *, uint8_t);
|
||||
|
||||
@@ -2513,6 +2527,7 @@ struct uwsgi_probe *uwsgi_probe_register(struct uwsgi_probe **, char *, int (*)(
|
||||
int uwsgi_add_probe(uint8_t sig, char *, char *, int, int);
|
||||
|
||||
int uwsgi_is_bad_connection(int);
|
||||
int uwsgi_long2str2n(unsigned long long, char *, int);
|
||||
|
||||
#ifdef __linux__
|
||||
#ifdef MADV_MERGEABLE
|
||||
|
||||
+6
-1
@@ -254,7 +254,7 @@ class uConf(object):
|
||||
self.gcc_list.append('lib/netlink')
|
||||
try:
|
||||
lk_ver = uwsgi_os_k.split('.')
|
||||
if int(lk_ver[0]) <= 2 and int(lk_ver[1]) <= 6 and int(lk_ver[2]):
|
||||
if int(lk_ver[0]) <= 2 and int(lk_ver[1]) <= 6 and int(lk_ver[2]) <= 9:
|
||||
self.cflags.append('-DOBSOLETE_LINUX_KERNEL')
|
||||
except:
|
||||
pass
|
||||
@@ -809,6 +809,11 @@ def build_plugin(path, uc, cflags, ldflags, libs, name = None):
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
p_cflags.remove('-Winline')
|
||||
except:
|
||||
pass
|
||||
|
||||
#for ofile in up.OBJ_LIST:
|
||||
# gcc_list.insert(0,ofile)
|
||||
|
||||
|
||||
+39
-23
@@ -8,15 +8,14 @@ except:
|
||||
|
||||
|
||||
if uwsgi.masterpid() == 0:
|
||||
raise Exception("you have to enable the uWSGI master process to use this module")
|
||||
|
||||
if uwsgi.opt.get('lazy'):
|
||||
raise Exception("uWSGI lazy mode is not supported by this module")
|
||||
raise Exception(
|
||||
"you have to enable the uWSGI master process to use this module")
|
||||
|
||||
spooler_functions = {}
|
||||
mule_functions = {}
|
||||
postfork_chain = []
|
||||
|
||||
|
||||
def get_free_signal():
|
||||
for signum in xrange(0, 256):
|
||||
if not uwsgi.signal_registered(signum):
|
||||
@@ -24,12 +23,14 @@ def get_free_signal():
|
||||
|
||||
raise Exception("No free uwsgi signal available")
|
||||
|
||||
|
||||
def manage_spool_request(vars):
|
||||
ret = spooler_functions[vars['ud_spool_func']](vars)
|
||||
if not vars.has_key('ud_spool_ret'):
|
||||
if not 'ud_spool_ret' in vars:
|
||||
return ret
|
||||
return int(vars['ud_spool_ret'])
|
||||
|
||||
|
||||
def postfork_chain_hook():
|
||||
for f in postfork_chain:
|
||||
f()
|
||||
@@ -37,10 +38,12 @@ def postfork_chain_hook():
|
||||
uwsgi.spooler = manage_spool_request
|
||||
uwsgi.post_fork_hook = postfork_chain_hook
|
||||
|
||||
|
||||
class postfork(object):
|
||||
def __init__(self, f):
|
||||
postfork_chain.append(f)
|
||||
|
||||
|
||||
class spool(object):
|
||||
|
||||
def spool(self, *args, **kwargs):
|
||||
@@ -53,12 +56,14 @@ class spool(object):
|
||||
return uwsgi.spool(arguments)
|
||||
|
||||
def __init__(self, f):
|
||||
if not uwsgi.opt.has_key('spooler'):
|
||||
raise Exception("you have to enable the uWSGI spooler to use the @spool decorator")
|
||||
if not 'spooler' in uwsgi.opt:
|
||||
raise Exception(
|
||||
"you have to enable the uWSGI spooler to use @spool decorator")
|
||||
self.f = f
|
||||
spooler_functions[f.__name__] = self.f
|
||||
self.f.spool = self.spool
|
||||
self.base_dict = {'ud_spool_func':self.f.__name__}
|
||||
self.base_dict = {'ud_spool_func': self.f.__name__}
|
||||
|
||||
|
||||
class spoolforever(spool):
|
||||
|
||||
@@ -71,6 +76,7 @@ class spoolforever(spool):
|
||||
arguments.update(kwargs)
|
||||
return uwsgi.spool(arguments)
|
||||
|
||||
|
||||
class spoolraw(spool):
|
||||
|
||||
def spool(self, *args, **kwargs):
|
||||
@@ -97,15 +103,13 @@ class mulefunc(object):
|
||||
uwsgi.mule_msg(pickle.dumps(
|
||||
{
|
||||
'service': 'uwsgi_mulefunc',
|
||||
'func':self.fname,
|
||||
'func': self.fname,
|
||||
'args': args,
|
||||
'kwargs': kwargs
|
||||
}
|
||||
), self.mule)
|
||||
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
|
||||
if not self.fname:
|
||||
self.fname = args[0].__name__
|
||||
mule_functions[self.fname] = args[0]
|
||||
@@ -117,7 +121,7 @@ class mulefunc(object):
|
||||
def mule_msg_dispatcher(message):
|
||||
msg = pickle.loads(message)
|
||||
if msg['service'] == 'uwsgi_mulefunc':
|
||||
return mule_functions[msg['func']](*msg['args'],**msg['kwargs'])
|
||||
return mule_functions[msg['func']](*msg['args'], **msg['kwargs'])
|
||||
|
||||
uwsgi.mule_msg_hook = mule_msg_dispatcher
|
||||
|
||||
@@ -131,12 +135,13 @@ class rpc(object):
|
||||
uwsgi.register_rpc(self.name, f)
|
||||
return f
|
||||
|
||||
|
||||
class farm_loop(object):
|
||||
|
||||
def __init__(self, f, farm):
|
||||
self.f = f
|
||||
self.farm = farm
|
||||
|
||||
|
||||
def __call__(self):
|
||||
if uwsgi.mule_id() == 0:
|
||||
return
|
||||
@@ -147,6 +152,7 @@ class farm_loop(object):
|
||||
if message:
|
||||
self.f(message)
|
||||
|
||||
|
||||
class farm(object):
|
||||
|
||||
def __init__(self, name=None, **kwargs):
|
||||
@@ -155,6 +161,7 @@ class farm(object):
|
||||
def __call__(self, f):
|
||||
postfork_chain.append(farm_loop(f, self.name))
|
||||
|
||||
|
||||
class mule_brain(object):
|
||||
|
||||
def __init__(self, f, num):
|
||||
@@ -165,13 +172,14 @@ class mule_brain(object):
|
||||
if uwsgi.mule_id() == self.num:
|
||||
self.f()
|
||||
|
||||
|
||||
class mule_brainloop(mule_brain):
|
||||
|
||||
def __call__(self):
|
||||
if uwsgi.mule_id() == self.num:
|
||||
while True:
|
||||
self.f()
|
||||
|
||||
|
||||
|
||||
class mule(object):
|
||||
def __init__(self, num):
|
||||
@@ -180,10 +188,12 @@ class mule(object):
|
||||
def __call__(self, f):
|
||||
postfork_chain.append(mule_brain(f, self.num))
|
||||
|
||||
|
||||
class muleloop(mule):
|
||||
def __call__(self, f):
|
||||
postfork_chain.append(mule_brainloop(f, self.num))
|
||||
|
||||
|
||||
class mulemsg_loop(object):
|
||||
|
||||
def __init__(self, f, num):
|
||||
@@ -198,6 +208,7 @@ class mulemsg_loop(object):
|
||||
if message:
|
||||
self.f(message)
|
||||
|
||||
|
||||
class mulemsg(object):
|
||||
def __init__(self, num):
|
||||
self.num = num
|
||||
@@ -205,28 +216,31 @@ class mulemsg(object):
|
||||
def __call__(self, f):
|
||||
postfork_chain.append(mulemsg_loop(f, self.num))
|
||||
|
||||
|
||||
class signal(object):
|
||||
|
||||
def __init__(self, num, **kwargs):
|
||||
self.num = num
|
||||
self.target = kwargs.get('target', '')
|
||||
self.target = kwargs.get('target', '')
|
||||
|
||||
def __call__(self, f):
|
||||
uwsgi.register_signal(self.num, self.target, f)
|
||||
return f
|
||||
|
||||
|
||||
class timer(object):
|
||||
|
||||
def __init__(self, secs, **kwargs):
|
||||
self.num = kwargs.get('signum', get_free_signal())
|
||||
self.secs = secs
|
||||
self.target = kwargs.get('target', '')
|
||||
self.target = kwargs.get('target', '')
|
||||
|
||||
def __call__(self, f):
|
||||
uwsgi.register_signal(self.num, self.target, f)
|
||||
uwsgi.add_timer(self.num, self.secs)
|
||||
return f
|
||||
|
||||
|
||||
class cron(object):
|
||||
|
||||
def __init__(self, minute, hour, day, month, dayweek, **kwargs):
|
||||
@@ -236,39 +250,41 @@ class cron(object):
|
||||
self.day = day
|
||||
self.month = month
|
||||
self.dayweek = dayweek
|
||||
self.target = kwargs.get('target', '')
|
||||
self.target = kwargs.get('target', '')
|
||||
|
||||
def __call__(self, f):
|
||||
uwsgi.register_signal(self.num, self.target, f)
|
||||
uwsgi.add_cron(self.num, self.minute, self.hour, self.day, self.month, self.dayweek)
|
||||
uwsgi.add_cron(self.num, self.minute, self.hour,
|
||||
self.day, self.month, self.dayweek)
|
||||
return f
|
||||
|
||||
|
||||
|
||||
class rbtimer(object):
|
||||
|
||||
def __init__(self, secs, **kwargs):
|
||||
self.num = kwargs.get('signum', get_free_signal())
|
||||
self.secs = secs
|
||||
self.target = kwargs.get('target', '')
|
||||
self.target = kwargs.get('target', '')
|
||||
|
||||
def __call__(self, f):
|
||||
uwsgi.register_signal(self.num, self.target, f)
|
||||
uwsgi.add_rb_timer(self.num, self.secs)
|
||||
return f
|
||||
|
||||
|
||||
class filemon(object):
|
||||
|
||||
def __init__(self, fsobj, **kwargs):
|
||||
self.num = kwargs.get('signum', get_free_signal())
|
||||
self.fsobj = fsobj
|
||||
self.target = kwargs.get('target', '')
|
||||
self.target = kwargs.get('target', '')
|
||||
|
||||
def __call__(self, f):
|
||||
uwsgi.register_signal(self.num, self.target, f)
|
||||
uwsgi.add_file_monitor(self.num, self.fsobj)
|
||||
return f
|
||||
|
||||
|
||||
class erlang(object):
|
||||
|
||||
def __init__(self, name):
|
||||
@@ -278,6 +294,7 @@ class erlang(object):
|
||||
uwsgi.erlang_register_process(self.name, f)
|
||||
return f
|
||||
|
||||
|
||||
class lock(object):
|
||||
def __init__(self, f):
|
||||
self.f = f
|
||||
@@ -292,6 +309,7 @@ class lock(object):
|
||||
finally:
|
||||
uwsgi.unlock()
|
||||
|
||||
|
||||
class thread(object):
|
||||
|
||||
def __init__(self, f):
|
||||
@@ -302,5 +320,3 @@ class thread(object):
|
||||
t.daemon = True
|
||||
t.start()
|
||||
return self.f
|
||||
|
||||
|
||||
|
||||
@@ -154,6 +154,10 @@ void uwsgi_yaml_config(char *file, char *magic_table[]) {
|
||||
case YAML_VALUE_TOKEN:
|
||||
status = 2;
|
||||
break;
|
||||
case YAML_FLOW_SEQUENCE_START_TOKEN:
|
||||
case YAML_BLOCK_SEQUENCE_START_TOKEN:
|
||||
status = 3;
|
||||
break;
|
||||
case YAML_BLOCK_MAPPING_START_TOKEN:
|
||||
if (!in_uwsgi_section) {
|
||||
if (key) {
|
||||
@@ -170,6 +174,8 @@ void uwsgi_yaml_config(char *file, char *magic_table[]) {
|
||||
}
|
||||
break;
|
||||
case YAML_SCALAR_TOKEN:
|
||||
case YAML_FLOW_ENTRY_TOKEN:
|
||||
case YAML_BLOCK_ENTRY_TOKEN:
|
||||
if (status == 1) {
|
||||
key = (char *) token.data.scalar.value;
|
||||
}
|
||||
@@ -180,6 +186,12 @@ void uwsgi_yaml_config(char *file, char *magic_table[]) {
|
||||
}
|
||||
status = 0;
|
||||
}
|
||||
else if (status == 3) {
|
||||
val = (char *) token.data.scalar.value;
|
||||
if (key && val && in_uwsgi_section) {
|
||||
add_exported_option(key, val, 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
uwsgi_log("unsupported YAML token in %s block\n", section_asked);
|
||||
parsing = 0;
|
||||
|
||||
Reference in New Issue
Block a user