Compare commits

...
9 Commits
10 changed files with 178 additions and 49 deletions
+1
View File
@@ -5,3 +5,4 @@ d3850b52334a91d005b0fe45e1e38ba0997a1fb8 no_server mode
b0db39cfad5ac6d4f00bbb3f9c57cf73206e2afb 0.9.5
9f8b98ad1dfa51b86b13fa624c65f73523075fc4 0.9.5.1
a83e7a482e65befcfbb0e24af8cd5d15190acdd7 0.9.6-rc1
b8f67c6cd0d62f864db9b2b265b4e260ad7d873c 0.9.6-rc2
+26
View File
@@ -1,3 +1,29 @@
*** august 2010 ***
* 0.9.6 [20100829]
- better handling of SCRIPT_NAME
- vacuum option for deleting unix sockets and pidfiles after usage
- advanced XML configuration
- new configuration systems: INI files and LDAP
- embedded HTTP server for development/testing
- better signal handling
- PSGI plugin improved
- usability fixes and new commodities options for root startup
- grunt processes (detached workers)
- preliminary integrated virtualhosting mode
- new option catch-exceptions can redirect python exceptions to your browser
- logging improvements (--logto and --logdate options)
- Full PEP 333 compliant usage of wsgi.file_wrapper
- re-initialize random seed after every fork() [security fix]
- fix Spooler's usage of stdin
- export WSGI environment in uwsgi.env (for doing evil things)
- logsize tracking (uwsgi.logsize) for future embedded log rotation
*** july 2010 ***
* 0.9.5.4 [20100706]
*** june 2010 ***
* 0.9.5.3 [20100628]
+51 -9
View File
@@ -30,6 +30,14 @@ void http_end() {
exit(0);
}
void http_wait_end() {
pid_t wp_p;
int wp_c;
wp_p = waitpid(-1, &wp_c, 0);
uwsgi_log("closing uWSGI embedded HTTP server.\n");
exit(0);
}
static char *add_uwsgi_var(char *up, char *key, uint16_t keylen, char *val, uint16_t vallen, int header, char *watermark)
{
@@ -51,7 +59,7 @@ static char *add_uwsgi_var(char *up, char *key, uint16_t keylen, char *val, uint
if (key[i] == '-') {
key[i] = '_';
} else {
key[i] = toupper(key[i]);
key[i] = toupper( (int) key[i]);
}
}
@@ -103,10 +111,29 @@ void http_loop(struct uwsgi_server * uwsgi)
exit(1);
}
// ignore broken pipes;
signal(SIGPIPE, SIG_IGN);
if (!uwsgi->http_only) {
signal(SIGCHLD, &http_end);
signal(SIGINT, &http_wait_end);
}
else {
signal(SIGINT, &http_end);
}
uwsgi->http_server_name = malloc(256);
if (!uwsgi->http_server_name) {
uwsgi_error("malloc()");
exit(1);
}
memset(uwsgi->http_server_name, 0, 256);
if (gethostname(uwsgi->http_server_name, 255)) {
uwsgi_error("gethostname()");
memcpy(uwsgi->http_server_name, "localhost", 9);
}
uwsgi_log("starting HTTP loop on %s (pid: %d)\n", uwsgi->http_server_name, (int) getpid());
for(;;) {
if (!uwsgi->http_only) {
@@ -133,6 +160,7 @@ void http_loop(struct uwsgi_server * uwsgi)
if (ret) {
uwsgi_log("pthread_create() = %d\n", ret);
free(ur);
// sleep a bit to allow some resource gaining
sleep(1);
continue;
}
@@ -163,8 +191,7 @@ static void *http_request(void *u_h_r)
size_t len;
int i,
j;
int i, j;
char HTTP_header_key[1024];
@@ -177,6 +204,7 @@ static void *http_request(void *u_h_r)
up = uwsgipkt;
char *watermark = up + 4096 ;
char *watermark2 = tmp_buf + 4096 ;
up[0] = 0;
up[3] = 0;
@@ -224,6 +252,7 @@ static void *http_request(void *u_h_r)
} else if (state == uwsgi_http_header_key_colon) {
if (ptr+1 > watermark2) { close(uwsgi_fd); goto clear;}
*ptr++ = 0;
memset(HTTP_header_key, 0, sizeof(HTTP_header_key));
@@ -232,6 +261,7 @@ static void *http_request(void *u_h_r)
state = uwsgi_http_header_val;
} else {
//check for overflow
if (ptr+1 > watermark2) { close(uwsgi_fd); goto clear;}
*ptr++ = buf[i];
}
@@ -251,6 +281,7 @@ static void *http_request(void *u_h_r)
up = add_uwsgi_var(up, HTTP_header_key, strlen(HTTP_header_key), tmp_buf, ptr - tmp_buf, 1, watermark);
if (!strcmp("CONTENT_LENGTH", HTTP_header_key)) {
if (ptr+1 > watermark2) { close(uwsgi_fd); goto clear;}
*ptr++ = 0;
http_body_len = atoi(tmp_buf);
}
@@ -265,20 +296,29 @@ static void *http_request(void *u_h_r)
need_to_read = 0;
if (uwsgi.http_server_name) {
up = add_uwsgi_var(up, "SERVER_NAME", 11, uwsgi.http_server_name, strlen(uwsgi.http_server_name), 0, watermark);
} else {
up = add_uwsgi_var(up, "SERVER_NAME", 11, "localhost", 9, 0, watermark);
}
up = add_uwsgi_var(up, "SERVER_NAME", 11, uwsgi.http_server_name, strlen(uwsgi.http_server_name), 0, watermark);
up = add_uwsgi_var(up, "SERVER_PORT", 11, uwsgi.http_server_port, strlen(uwsgi.http_server_port), 0, watermark);
up = add_uwsgi_var(up, "SCRIPT_NAME", 11, "", 0, 0, watermark);
char *ip = inet_ntoa(ur->c_addr.sin_addr);
up = add_uwsgi_var(up, "REMOTE_ADDR", 11, ip, strlen(ip), 0, watermark);
//up = add_uwsgi_var(up, "REMOTE_ADDR", 11, "127.0.0.1", 9, 0, watermark);
//up = add_uwsgi_var(up, "REMOTE_USER", 11, "unknown", 7, 0);
for(j=0;j<uwsgi.http_vars_cnt;j++) {
char *separator;
separator = strchr(uwsgi.http_vars[j], '=');
if (separator) {
up = add_uwsgi_var(up, uwsgi.http_vars[j], separator - uwsgi.http_vars[j], separator + 1, strlen(separator + 1), 0, watermark);
}
else {
up = add_uwsgi_var(up, uwsgi.http_vars[j], strlen(uwsgi.http_vars[j]), NULL, 0, 0, watermark);
}
}
uwsgi_fd = uwsgi_connect(uwsgi.socket_name, 10);
if (uwsgi_fd >= 0) {
ulen = (up - uwsgipkt) - 4;
@@ -322,11 +362,13 @@ static void *http_request(void *u_h_r)
state = uwsgi_http_header_key_colon;
} else {
//check for overflow
if (ptr+1 > watermark2) { close(uwsgi_fd); goto clear;}
*ptr++ = buf[i];
}
} else {
//check for overflow
if (ptr+1 > watermark2) { close(uwsgi_fd); goto clear;}
*ptr++ = buf[i];
}
+6 -2
View File
@@ -83,7 +83,7 @@ void uwsgi_ini_config(char *file, struct option *long_options) {
char *ini_line;
char *section;
char *section = "";
char *key;
char *val;
@@ -96,7 +96,9 @@ void uwsgi_ini_config(char *file, struct option *long_options) {
colon = strchr(file, ':');
if (colon) {
colon[0] = 0;
section_asked = colon+1 ;
if (colon[1] != 0) {
section_asked = colon+1 ;
}
}
fd = open(file, O_RDONLY);
@@ -174,6 +176,8 @@ void uwsgi_ini_config(char *file, struct option *long_options) {
sb.st_size -= (ini_line - ini);
}
close(fd);
}
+7 -7
View File
@@ -11,9 +11,9 @@ void ldap2uwsgi(char *ldapname, char *uwsginame) {
int i;
for(i=0;i<strlen(ldapname);i++) {
if (isupper(ldapname[i])) {
if (isupper( (int)ldapname[i])) {
*ptr++= '-';
*ptr++= tolower(ldapname[i]);
*ptr++= tolower( (int) ldapname[i]);
}
else {
*ptr++= ldapname[i] ;
@@ -29,7 +29,7 @@ int calc_ldap_name(char *name) {
int counter = 0;
for(i=0;i<strlen(name);i++) {
if (isupper(name[i])) {
if (isupper( (int) name[i])) {
counter++;
}
}
@@ -73,7 +73,7 @@ void uwsgi_ldap_schema_dump_ldif(struct option *lo) {
for(i=0;i<strlen(aopt->name);i++) {
if (aopt->name[i] == '-') {
i++;
uwsgi_log("%c", toupper(aopt->name[i]));
uwsgi_log("%c", toupper( (int) aopt->name[i]));
}
else {
uwsgi_log("%c", aopt->name[i]);
@@ -113,7 +113,7 @@ next:
for(i=0;i<strlen(aopt->name);i++) {
if (aopt->name[i] == '-') {
i++;
uwsgi_log("%c", toupper(aopt->name[i]));
uwsgi_log("%c", toupper( (int) aopt->name[i]));
}
else {
uwsgi_log("%c", aopt->name[i]);
@@ -163,7 +163,7 @@ void uwsgi_ldap_schema_dump(struct option *lo) {
for(i=0;i<strlen(aopt->name);i++) {
if (aopt->name[i] == '-') {
i++;
uwsgi_log("%c", toupper(aopt->name[i]));
uwsgi_log("%c", toupper( (int) aopt->name[i]));
}
else {
uwsgi_log("%c", aopt->name[i]);
@@ -203,7 +203,7 @@ next:
for(i=0;i<strlen(aopt->name);i++) {
if (aopt->name[i] == '-') {
i++;
uwsgi_log("%c", toupper(aopt->name[i]));
uwsgi_log("%c", toupper( (int) aopt->name[i]));
}
else {
uwsgi_log("%c", aopt->name[i]);
+1 -1
View File
@@ -34,7 +34,7 @@ class uWSGIDistribution(Distribution):
setup(name='uWSGI',
version='0.9.6-dev',
version='0.9.6',
description='The uWSGI server',
author='Unbit',
author_email='info@unbit.it',
+7 -1
View File
@@ -410,6 +410,12 @@ void sanitize_args(struct uwsgi_server *uwsgi) {
uwsgi_log(" *** WARNING: you have enabled harakiri without post buffering. Slow upload could be rejected on post-unbuffered webservers *** \n");
}
}
#ifdef UWSGI_HTTP
if (uwsgi->http && !uwsgi->http_only) {
uwsgi->vacuum = 1;
}
#endif
}
void env_to_arg(char *src, char *dst) {
@@ -424,7 +430,7 @@ void env_to_arg(char *src, char *dst) {
dst[i] = src[i];
}
else {
dst[i] = tolower(src[i]);
dst[i] = tolower( (int) src[i]);
if (dst[i] == '_') {
dst[i] = '-';
}
+69 -26
View File
@@ -159,6 +159,7 @@ static struct option long_options[] = {
#ifdef UWSGI_HTTP
{"http", required_argument, 0, LONG_ARGS_HTTP},
{"http-only", no_argument, &uwsgi.http_only, 1},
{"http-var", required_argument, 0, LONG_ARGS_HTTP_VAR},
#endif
{"catch-exceptions", no_argument, &uwsgi.catch_exceptions, 1},
{"mode", required_argument, 0, LONG_ARGS_MODE},
@@ -271,6 +272,7 @@ void grace_them_all() {
void reap_them_all() {
int i;
uwsgi.to_heaven = 1;
uwsgi_log("...brutally killing workers...\n");
for (i = 1; i <= uwsgi.numproc; i++) {
kill(uwsgi.workers[i].pid, SIGTERM);
@@ -351,14 +353,23 @@ static void unconfigured_after_hook(struct uwsgi_server *uwsgi, struct wsgi_requ
static void vacuum(void) {
struct sockaddr_un sa;
socklen_t sa_len = sizeof(struct sockaddr_un);
if (uwsgi.vacuum) {
if (getpid() == masterpid) {
if (uwsgi.socket_name && uwsgi.bind_to_unix) {
if (unlink(uwsgi.socket_name)) {
uwsgi_error("unlink()");
}
else {
uwsgi_log("VACUUM: unix socket removed.\n");
if (chdir(uwsgi.cwd)) {
uwsgi_error("chdir()");
}
memset(&sa, 0, sa_len);
if (!getsockname(uwsgi.serverfd, (struct sockaddr*)&sa, &sa_len)) {
if (sa.sun_family == AF_UNIX) {
if (unlink(sa.sun_path)) {
uwsgi_error("unlink()");
}
else {
uwsgi_log("VACUUM: unix socket removed.\n");
}
}
}
if (uwsgi.pidfile && !uwsgi.uid) {
@@ -403,7 +414,6 @@ int main(int argc, char *argv[], char *envp[]) {
int working_workers = 0;
int blocking_workers = 0;
char *cwd = NULL;
int ready_to_reload = 0;
int ready_to_die = 0;
@@ -423,9 +433,13 @@ int main(int argc, char *argv[], char *envp[]) {
signal(SIGHUP, SIG_IGN);
signal(SIGTERM, SIG_IGN);
atexit(vacuum);
// initialize masterpid with a default value
masterpid = getpid();
memset(&uwsgi, 0, sizeof(struct uwsgi_server));
uwsgi.cwd = uwsgi_get_cwd();
atexit(vacuum);
#ifdef UWSGI_DEBUG
@@ -526,6 +540,11 @@ int main(int argc, char *argv[], char *envp[]) {
if (optind < argc) {
char *lazy = argv[optind];
char *qc = strchr(lazy, ':');
if (qc) {
qc[0] = 0 ;
uwsgi.callable = qc + 1;
}
if (!strcmp(lazy+strlen(lazy)-3, ".py")) {
uwsgi.file_config = lazy;
}
@@ -556,7 +575,6 @@ int main(int argc, char *argv[], char *envp[]) {
}
if (uwsgi.binary_path == argv[0]) {
cwd = uwsgi_get_cwd();
uwsgi.binary_path = malloc(strlen(argv[0]) + 1);
if (uwsgi.binary_path == NULL) {
uwsgi_error("malloc()");
@@ -648,7 +666,7 @@ int main(int argc, char *argv[], char *envp[]) {
sanitize_args(&uwsgi);
#ifdef UWSGI_HTTP
if (uwsgi.http) {
if (uwsgi.http && !uwsgi.is_a_reload) {
char *tcp_port = strchr(uwsgi.http, ':');
if (tcp_port) {
uwsgi.http_server_port = tcp_port+1;
@@ -681,7 +699,6 @@ int main(int argc, char *argv[], char *envp[]) {
if (uwsgi.http_only) {
signal(SIGINT, (void *) &end_me);
http_loop(&uwsgi);
// never here
exit(1);
@@ -690,7 +707,7 @@ int main(int argc, char *argv[], char *envp[]) {
pid_t http_pid = fork();
if (http_pid > 0) {
signal(SIGINT, (void *) &end_me);
masterpid = http_pid;
http_loop(&uwsgi);
// never here
exit(1);
@@ -699,6 +716,20 @@ int main(int argc, char *argv[], char *envp[]) {
uwsgi_error("fork()");
exit(1);
}
if (uwsgi.pidfile && !uwsgi.is_a_reload) {
uwsgi_log( "updating pidfile with pid %d\n", (int) getpid());
pidfile = fopen(uwsgi.pidfile, "w");
if (!pidfile) {
uwsgi_error("fopen");
exit(1);
}
if (fprintf(pidfile, "%d\n", (int) getpid()) < 0) {
uwsgi_log( "could not update pidfile.\n");
}
fclose(pidfile);
}
close(uwsgi.http_fd);
}
#endif
@@ -902,7 +933,6 @@ int main(int argc, char *argv[], char *envp[]) {
char *tcp_port = strchr(uwsgi.socket_name, ':');
if (tcp_port == NULL) {
uwsgi.serverfd = bind_to_unix(uwsgi.socket_name, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
uwsgi.bind_to_unix = 1;
}
else {
uwsgi.serverfd = bind_to_tcp(uwsgi.socket_name, uwsgi.listen_queue, tcp_port);
@@ -1263,11 +1293,9 @@ int main(int argc, char *argv[], char *envp[]) {
}
#endif
uwsgi_log( "binary reloading uWSGI...\n");
if (cwd) {
if (chdir(cwd)) {
uwsgi_error("chdir()");
exit(1);
}
if (chdir(uwsgi.cwd)) {
uwsgi_error("chdir()");
exit(1);
}
/* check fd table (a module can obviosly open some fd on initialization...) */
uwsgi_log( "closing all fds > 2 (_SC_OPEN_MAX = %ld)...\n", sysconf(_SC_OPEN_MAX));
@@ -2344,7 +2372,7 @@ void uwsgi_wsgi_config(char *filename) {
PyObject *app_list;
int ret;
Py_ssize_t i;
PyObject *app_mnt, *app_app;
PyObject *app_mnt, *app_app = NULL;
FILE *uwsgifile;
char *quick_callable = NULL;
@@ -2352,6 +2380,11 @@ void uwsgi_wsgi_config(char *filename) {
uwsgi.single_interpreter = 1;
if (filename) {
if (uwsgi.callable) {
quick_callable = uwsgi.callable ;
}
uwsgifile = fopen(filename, "r");
if (!uwsgifile) {
uwsgi_error("fopen()");
@@ -2895,6 +2928,17 @@ void manage_opt(int i, char *optarg) {
case LONG_ARGS_ERLANG_COOKIE:
uwsgi.erlang_cookie = optarg;
break;
#endif
#ifdef UWSGI_HTTP
case LONG_ARGS_HTTP_VAR:
if (uwsgi.http_vars_cnt < 63) {
uwsgi.http_vars[uwsgi.http_vars_cnt] = optarg;
uwsgi.http_vars_cnt++;
}
else {
uwsgi_log( "you can specify at most 64 --http-var options\n");
}
break;
#endif
case LONG_ARGS_PYTHONPATH:
if (uwsgi.python_path_cnt < 63) {
@@ -2928,18 +2972,16 @@ void manage_opt(int i, char *optarg) {
case LONG_ARGS_INI_PASTE:
uwsgi.ini = optarg;
if (uwsgi.ini[0] != '/') {
char *paste_cwd = uwsgi_get_cwd();
uwsgi.paste = malloc( 7 + strlen(paste_cwd) + 1 + strlen(uwsgi.ini) + 1);
uwsgi.paste = malloc( 7 + strlen(uwsgi.cwd) + 1 + strlen(uwsgi.ini) + 1);
if (uwsgi.paste == NULL) {
uwsgi_error("malloc()");
exit(1);
}
memset(uwsgi.paste, 0, 7 + strlen(paste_cwd) + strlen(uwsgi.ini) + 1);
memset(uwsgi.paste, 0, 7 + strlen(uwsgi.cwd) + strlen(uwsgi.ini) + 1);
memcpy(uwsgi.paste, "config:", 7);
memcpy(uwsgi.paste + 7, paste_cwd, strlen(paste_cwd));
uwsgi.paste[7 + strlen(paste_cwd)] = '/';
memcpy(uwsgi.paste + 7 + strlen(paste_cwd) + 1, uwsgi.ini, strlen(uwsgi.ini));
free(paste_cwd);
memcpy(uwsgi.paste + 7, uwsgi.cwd, strlen(uwsgi.cwd));
uwsgi.paste[7 + strlen(uwsgi.cwd)] = '/';
memcpy(uwsgi.paste + 7 + strlen(uwsgi.cwd) + 1, uwsgi.ini, strlen(uwsgi.ini));
}
else {
uwsgi.paste = malloc( 7 + strlen(uwsgi.ini) + 1);
@@ -3163,6 +3205,7 @@ void manage_opt(int i, char *optarg) {
\t--routing\t\t\tenable uWSGI advanced routing\n\
\t--http <addr>\t\t\tstart embedded HTTP server on <addr>\n\
\t--http-only\t\t\tstart only the embedded HTTP server\n\
\t--http-var KEY[=VALUE]\t\tadd var KEY to uwsgi requests made by the embedded HTTP server\n\
\t--catch-exceptions\t\tprint exceptions in the browser\n\
\t--mode\t\t\t\tset configuration mode\n\
\t--env KEY=VALUE\t\t\tset environment variable\n\
+9 -2
View File
@@ -2,7 +2,7 @@
/* indent -i8 -br -brs -brf -l0 -npsl -nip -npcs -npsl -di1 */
#define UWSGI_VERSION "0.9.6-dev"
#define UWSGI_VERSION "0.9.6"
#define uwsgi_error(x) uwsgi_log("%s: %s [%s line %d]\n", x, strerror(errno), __FILE__, __LINE__);
#define uwsgi_debug(x, ...) uwsgi_log("[uWSGI DEBUG] " x, __VA_ARGS__);
@@ -176,6 +176,7 @@ PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromString(char *, Py_ssize_t);
#define LONG_ARGS_PING_TIMEOUT 17040
#define LONG_ARGS_INI_PASTE 17041
#define LONG_ARGS_CALLABLE 17042
#define LONG_ARGS_HTTP_VAR 17043
@@ -450,11 +451,16 @@ struct uwsgi_server {
uid_t uid;
char *mode;
#ifdef UWSGI_HTTP
char *http;
char *http_server_name;
char *http_server_port;
int http_only;
int http_fd;
char *http_vars[64];
int http_vars_cnt;
#endif
int ignore_script_name;
int logdate;
@@ -667,7 +673,6 @@ struct uwsgi_server {
int catch_exceptions;
int vacuum;
int bind_to_unix;
int no_server;
#ifdef UWSGI_LDAP
@@ -680,6 +685,8 @@ struct uwsgi_server {
char *callable;
int xml_round2;
char *cwd;
};
struct uwsgi_cluster_node {
+1 -1
View File
@@ -28,7 +28,7 @@ STACKLESS=False
PLUGINS = []
USWALLOW=False
UNBIT=False
DEBUG=True
DEBUG=False
EMBED_PLUGINS=True
UWSGI_BIN_NAME = 'uwsgi'
UWSGI_PLUGIN_DIR = '.'