Compare commits

..
68 Commits
Author SHA1 Message Date
Unbit 7108ee1ba0 improved xclient 2013-06-22 11:50:45 +02:00
Unbit cf8e68f7a0 another attempt to fix xclient 2013-06-22 11:18:25 +02:00
Unbit a9510c2209 fixed xclient 2013-06-22 10:51:17 +02:00
Unbit b2be5943a8 added router_xmldir plugin 2013-06-21 06:54:05 +02:00
Unbit 8f19fe292e added --add-cache-item 2013-06-20 15:12:48 +02:00
Unbit d3e7668d0a better clang detection 2013-06-20 11:00:05 +02:00
Unbit 88e67a74e5 fixed #321 2013-06-20 08:59:18 +02:00
Roberta Giordano 7fecda1a23 fixed #324 2013-06-20 06:15:35 +02:00
unbit 56b6fa88f9 Merge pull request #323 from jbert/master
Fix infinite loop in psgi/coroae
2013-06-19 07:47:52 -07:00
John Berthels e847cfe4bc fix infinite loop in coroae/psgi
Perl PSGI app infinite loops since f20213ff10

Looking at that change, other loop termination conditions are '<= UWSGI_OK'.
Using gdb to inspect the app while looping shows thats ->request is returning
UWSGI_OK in this case. However, the numeric value of this is zero, so we
never exit the for(;;) loop.

Cargo culting loop escape conditions from core/async.c (or gevent/gevent.c)
fixes the inf loop for psgi/coroae.
2013-06-19 15:27:31 +01:00
Roberta Giordano 1a854ae3ba varios osx build workaround 2013-06-19 07:14:54 +02:00
unbit c75180bf95 Create logo_uWSGI.svg 2013-06-17 10:26:59 +02:00
Unbit d496450b84 added seturi and setpathinfo routing actions 2013-06-16 07:52:59 +02:00
Unbit d2636ed133 better compiler detection 2013-06-16 07:13:19 +02:00
unbit 59de0c2085 Merge pull request #317 from anaconda/fix-gcc-darwin-llvm
Fix GCC on Darwin for Python 3.
2013-06-15 22:11:11 -07:00
anaconda 4b7df29bd1 Fix GCC on Darwin for Python 3.
distutils.sysconfig.get_config_var('CC') returns the compiler used to
build Python, which may be not installed on the system where uWSGI is
being built.

In my case, I grabbed Python 3.3.2 from python.org: it was apparently
compiled with 'gcc-4.2', but my system only has 'gcc' (symlink) and
'llvm-gcc-4.2'.  This change tries to detect this situation (only on
Darwin) and sets GCC to 'llvm-' + compiler returned by sysconfig.
2013-06-16 01:59:48 +02:00
unbit b099ba6a29 Merge pull request #316 from anaconda/spool-decorator-call
Implement __call__ for @spool* decorators.
2013-06-15 07:09:51 -07:00
anaconda 164069e194 Implement __call__ for @spool* decorators.
Also removed duplicate code.
2013-06-15 15:05:39 +02:00
Unbit b3e4ff8613 cosmetic fix for fastcgi 2013-06-15 14:37:50 +02:00
Unbit 3eb5ec3543 better fastcgi handling 2013-06-15 14:36:18 +02:00
unbit c3c698a615 Update uwsgi.conf 2013-06-15 15:09:22 +03:00
Unbit ac6d2f3e83 rack api functions are now static 2013-06-15 11:55:48 +02:00
Unbit d1f1b8a43a another tests cleanup 2013-06-15 08:03:34 +02:00
Unbit 85586a621c the official API list is now in uwsgi-docs 2013-06-15 08:01:53 +02:00
Unbit 1a384a334f remove mercurial files 2013-06-15 08:00:16 +02:00
Unbit 8901afded5 moved lanunchd examples to contrib 2013-06-15 07:59:27 +02:00
Roberta Giordano ab12703a11 added new set_user_harakiri to python,pypy,perl and ruby 2013-06-15 07:04:53 +02:00
Roberta Giordano 9992b4c964 improved set_user_harakiri to support mules and spoolers 2013-06-15 06:50:10 +02:00
unbit 9a2dbd08cd Merge pull request #315 from prymitive/curl_bug
fix curl crashing master on slow dns responses
2013-06-14 06:48:03 -07:00
Łukasz Mierzwa 5f92a00b71 fix curl crashing master on slow dns responses 2013-06-14 09:24:00 +02:00
Unbit 7bd9d51217 added mule support to pypy 2013-06-12 16:39:10 +02:00
unbit 80c649aa40 Create emperor.conf 2013-06-11 13:47:34 +03:00
Unbit 6c8fe2cc53 improved ready_fd call 2013-06-10 23:01:19 +02:00
Unbit dcc7167d75 added uwsgi[lq] routing var 2013-06-10 02:48:52 +02:00
Unbit e3a52e4039 added --use-abort 2013-06-09 23:14:52 +02:00
Unbit 498f6162f7 fixed debug 2013-06-09 23:00:22 +02:00
Unbit 33d85d3670 added coroae build profile 2013-06-09 22:58:18 +02:00
Unbit afbf5b9633 fixed typo doc 2013-06-09 22:54:42 +02:00
Unbit a8505be6c0 standardized uwsgi.disconnect() 2013-06-09 22:47:44 +02:00
Unbit 4a07632569 uwsgi.add_cron does not return a value 2013-06-09 22:35:52 +02:00
Unbit d4f0589c39 fixed uwsgi.fd_ready() 2013-06-09 22:22:59 +02:00
Roberta Giordano a9989d46fc set default lock to 0 in pypy uwsgi.lock/uwsgi.unlock 2013-06-10 06:08:15 +02:00
Unbit 99cf598c0c added chunked input support to pypy 2013-06-09 08:47:50 +02:00
Unbit a6af22b8f0 ported websockets api to pypy 2013-06-09 08:35:12 +02:00
Unbit 0961d61a88 added chunked async support 2013-06-09 08:06:45 +02:00
Unbit 7b76a2d749 first test for chunked input 2013-06-09 03:25:46 +02:00
Unbit b516f1d3ec added --chunked-input-limit and --chunked-input-timeout 2013-06-09 03:06:12 +02:00
Unbit 8fdef7a1f9 added chunked input api 2013-06-09 03:02:16 +02:00
Unbit 10258db4ae removed python 3 need for 'imp' module 2013-06-08 23:36:49 +02:00
unbit 621c9523cf fixed python3 compilation and added UWSGI_INCLUDES 2013-06-09 07:01:34 +02:00
Unbit c415adab28 added setmethod routing action 2013-06-08 01:05:44 +02:00
Unbit 7fef1048b3 added pypy greenlet contrib module 2013-06-07 10:15:25 +02:00
Unbit 1e7aaeeeed fix harakiri routing 2013-06-07 09:11:54 +02:00
Unbit c5b4564001 added 2 example of continulets 2013-06-06 18:16:01 +02:00
Unbit a9127c8d79 added support for pypy uwsgi.async_sleep 2013-06-06 17:25:03 +02:00
Unbit a0f7a5c70f added support for pypy continulets 2013-06-06 17:17:51 +02:00
Unbit ecf3cae35b use ffi.string instead of ffi.buffer in pypy 2013-06-06 16:05:20 +02:00
Unbit d553bc8014 let's start with 1.9.13 2013-06-06 15:49:51 +02:00
Unbit a1553d3632 removed debug print from pypy_setup.py 2013-06-06 14:54:39 +02:00
Unbit bb42ae1b4a fixed cron and alarm in pypy_setup.py 2013-06-06 14:16:38 +02:00
Unbit 61ac2efe0e added user_lock/unlock to new pypy setup 2013-06-06 14:15:02 +02:00
Unbit 1c0a3ec413 refactored the pypy plugin to make best use of cffi and to avoid the need of helpers 2013-06-06 14:10:34 +02:00
Unbit 8b7e93385b missing newline in --cflags 2013-06-06 11:27:14 +02:00
Unbit c742624054 added uwsgi_get_cflags() 2013-06-06 11:25:17 +02:00
Unbit 8011f0615d added --dot-h infrastructure 2013-06-06 11:18:25 +02:00
Unbit 8096b2198f fixed --print-sym and embed uwsgi.h in the server binary 2013-06-06 10:06:40 +02:00
Unbit 3556bd5283 removed PTRACE check, was an old stupid attempt 2013-06-06 09:42:08 +02:00
Unbit 26710694af fixed #306 2013-06-05 15:19:21 +02:00
48 changed files with 1662 additions and 377 deletions
-4
View File
@@ -1,4 +0,0 @@
syntax: glob
*.o
*.pyc
-58
View File
@@ -1,58 +0,0 @@
d3850b52334a91d005b0fe45e1e38ba0997a1fb8 no_server mode
2d8a617299153ed2efa6ecee7920e9d36c29e0f5 0.9.5beta1
04722a2d0121080d14a64df097c278860db5ce8a 0.9.5rc1
820cc64ab296dc4589ef72a33a6b804c22a0430c 0.9.5rc2
b0db39cfad5ac6d4f00bbb3f9c57cf73206e2afb 0.9.5
9f8b98ad1dfa51b86b13fa624c65f73523075fc4 0.9.5.1
a83e7a482e65befcfbb0e24af8cd5d15190acdd7 0.9.6-rc1
b8f67c6cd0d62f864db9b2b265b4e260ad7d873c 0.9.6-rc2
35918dd4b3771158b2b57410613ef029e08bbd60 0.9.6
5f25d1f97f9dde3e391a668c1c610a52a5db8244 0.9.6.1
ef31fc61ac48018c464f28ebfdf865b96bf83f18 0.9.6.2
9e100c1f085034396cec586f0c76ad3f9800d1a5 0.9.7-beta1
ff4111eb8f55b958ec91c70163e10f3372a9b94d 0.9.7-rc1
eb8aff2926230bb114fb90f67203440a2c534bf1 0.9.7-rc2
311eef929ec8fd0a5dc8c16531afb7bb42d36d01 0.9.7-rc3
4b50c04e414f1d9ab8b0b5910aba83d09ac21abb 0.9.7
d9b9b540f7dce8cb05d2e61ca8b4d75f2ea25f62 0.9.7.1
d9b9b540f7dce8cb05d2e61ca8b4d75f2ea25f62 0.9.7.1
0000000000000000000000000000000000000000 0.9.7.1
0000000000000000000000000000000000000000 0.9.7.1
486e7760bcbc2191ddb9b4aee6c98dbd5fc4c754 0.9.7.1
a5f13497b39269621f8f1e56e14d2cc141452e79 0.9.7.2
d1e57707f6317f134fea7d12f6588d8690f74f3f 0.9.8-rc1
e91bc724325e14c13b8f548c0b6a315c48a1c32a 0.9.8-rc2
4fb424d52f226a0a087fea89709f5eb540e03f25 0.9.8-rc3
0f1f3924ee5309a9990d9af1ffc68846e3dfb31b 0.9.8-rc4
42efe1f329005618c8b44f901979ebcecd5216fb 0.9.8
fd8477b6348faf16588106055ca59df1c488f76a 0.9.8.1
7169ef1d68d3dab4737bcc3f9e082839e5a06cc1 0.9.8.2
f4d3c4dcd7a63e21fcc9d8d567374c69935178bd 0.9.8.3
6945ee03c7ea95eb19217ef1e1fb17d9ae26adbc 0.9.9-beta1
fb168b0b86169219aa9b8e40f0caa6297cf34dbc 0.9.9-rc1
6aa667612019fcff8e68af9469f73aff6fa378a8 0.9.9-rc2
376ffd8f190623e5e2521fe9fa64bf03c31e71be 0.9.9
7048ae11cfc8453c6bb599af3c0dfacd7ebae43c 1.0-rc1
7a4e021ea7ba2953e474326612c3bb82d6817f0e 1.0-rc2
4e4e781ef89ac33e71a7e92741d54549240ed156 1.0-rc3
24f7e260ea345c2cd73e2fd8191dddbd1b039062 1.0-rc4
043ba93dd69cf6924e98db3cb9a8759cce997367 1.0-rc5
a2b8f25fd17ed7424d1470a287d0b3144d2a12c8 1.0-rc6
a3ca2e8e27c5c12c44ba0cacb4de4cb51377f184 1.0-rc7
365e2514cc19f0366365318f12a1d63113b02924 1.0-rc8
5da6fe43a8c29056bc9442c684615e11a3699795 1.0-rc9
af490b8c30f83bc5fb6f3837a760981474647755 1.0-rc10
3c70927335856883283fe4db448e092cecc0ccdb 1.0
8fe7bb792399cb6e6a24e20551f4149409660363 1.0.1
1d1702789710ec1c20613d2490b14f70756e67ec 1.1-rc1
901f0cb5de36ea907b26d64ac9ce54605ec531d2 1.1-rc2
ede5c664978bb40e476e8d4a5789562928f28507 1.1-rc3
ef99144291f06822d026e981d5d856cbec14d867 1.1-rc4
e1568fd16b7b586cc72deb4dfccbbe64ae0b84df 1.1
24c8fe5a26e557db41cf1cee45b8964d5885e484 1.2-rc1
29de0fb320bc0a1ce84972f9f249360e315d3c10 1.2-rc2
c3cdecbf2bac591336baddd14f9ac22e18d6e200 1.2
14524da00a8b382dffb1d16a0e70cdf4a946f369 1.3-rc2
883b946db9038372cb1d76cb1d328a3093140e7b 1.3-rc3
aeea5a5d2e8b62ad55e23d539e1be02f2b6962af 1.3-rc4
620e0cb6ccdb0ce27561b4240cb3a0ef4c3527fd 1.3
+3
View File
@@ -0,0 +1,3 @@
[uwsgi]
main_plugin = psgi,coroae
inherit = base
+1
View File
@@ -1,3 +1,4 @@
[uwsgi]
main_plugin = python,gevent
inherit = base
debug = false
+61
View File
@@ -0,0 +1,61 @@
"""
Greenlets support
simply --pypy-exec this file to enable PyPy's greenlet mode
Example:
uwsgi --http-socket :9090 --pypy-home /opt/pypy --pypy-wsgi werkzeug.testapp:test_app --pypy-exec contrib/pypy/uwsgi_pypy_greenlets.py --async 8
"""
import greenlet
uwsgi_pypy_greenlets = {}
def uwsgi_pypy_greenlet_wrapper():
lib.async_schedule_to_req_green()
@ffi.callback("void()")
def uwsgi_pypy_greenlet_schedule():
id = lib.uwsgi.wsgi_req.async_id
modifier1 = lib.uwsgi.wsgi_req.uh.modifier1;
# generate a new greenlet
if not lib.uwsgi.wsgi_req.suspended:
uwsgi_pypy_greenlets[id] = greenlet.greenlet(uwsgi_pypy_greenlet_wrapper)
lib.uwsgi.wsgi_req.suspended = 1
# this is called in the main stack
if lib.uwsgi.p[modifier1].suspend:
lib.uwsgi.p[modifier1].suspend(ffi.NULL)
# let's switch
uwsgi_pypy_greenlets[id].switch()
# back to the main stack
if lib.uwsgi.p[modifier1].resume:
lib.uwsgi.p[modifier1].resume(ffi.NULL)
@ffi.callback("void(struct wsgi_request *)")
def uwsgi_pypy_greenlet_switch(wsgi_req):
id = wsgi_req.async_id
modifier1 = wsgi_req.uh.modifier1;
# this is called in the current greenlet
if lib.uwsgi.p[modifier1].suspend:
lib.uwsgi.p[modifier1].suspend(wsgi_req)
uwsgi_pypy_main_greenlet.switch()
# back to the greenlet
if lib.uwsgi.p[modifier1].resume:
lib.uwsgi.p[modifier1].resume(wsgi_req)
# update current running greenlet
lib.uwsgi.wsgi_req = wsgi_req
if lib.uwsgi.async <= 1:
raise Exception("pypy greenlets require async mode !!!")
lib.uwsgi.schedule_to_main = uwsgi_pypy_greenlet_switch
lib.uwsgi.schedule_to_req = uwsgi_pypy_greenlet_schedule
uwsgi_pypy_main_greenlet = greenlet.getcurrent()
+15
View File
@@ -0,0 +1,15 @@
# uWSGI - Emperor
#
description "uWSGI Emperor"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
env LOGTO=/tmp/uwsgi.log
env BINPATH=/home/foo/uwsgi/uwsgi
env VASSALS=/etc/uwsgi
exec $BINPATH --emperor $VASSALS --logto $LOGTO
+2 -3
View File
@@ -11,7 +11,6 @@ respawn
env LOGTO=/tmp/uwsgi.log
env BINPATH=/home/foo/uwsgi/uwsgi
# --no-orphans avoid workers without master
# --die-on-term could be a good idea
exec $BINPATH --no-orphans --socket :3033 --uid 1001 --gid 1001 --limit-as 256 -w simple_app --logto $LOGTO -M -p 4
# --die-on-term is upstart friendly
exec $BINPATH --die-on-term --socket :3033 --uid 1001 --gid 1001 --limit-as 256 -w simple_app --logto $LOGTO -M -p 4
+9
View File
@@ -206,7 +206,11 @@ int async_add_fd_read(struct wsgi_request *wsgi_req, int fd, int timeout) {
}
static int async_wait_fd_read(int fd, int timeout) {
struct wsgi_request *wsgi_req = current_wsgi_req();
wsgi_req->async_ready_fd = 0;
if (async_add_fd_read(wsgi_req, fd, timeout)) {
return -1;
}
@@ -222,6 +226,8 @@ static int async_wait_fd_read(int fd, int timeout) {
void async_add_timeout(struct wsgi_request *wsgi_req, int timeout) {
wsgi_req->async_ready_fd = 0;
if (timeout > 0 && wsgi_req->async_timeout == NULL) {
wsgi_req->async_timeout = uwsgi_add_rb_timer(uwsgi.rb_async_timeouts, uwsgi_now() + timeout, wsgi_req);
}
@@ -265,6 +271,9 @@ int async_add_fd_write(struct wsgi_request *wsgi_req, int fd, int timeout) {
static int async_wait_fd_write(int fd, int timeout) {
struct wsgi_request *wsgi_req = current_wsgi_req();
wsgi_req->async_ready_fd = 0;
if (async_add_fd_write(wsgi_req, fd, timeout)) {
return -1;
}
+37
View File
@@ -171,6 +171,41 @@ static void cache_sync_hook(char *k, uint16_t kl, char *v, uint16_t vl, void *da
}
}
static void uwsgi_cache_add_items(struct uwsgi_cache *uc) {
struct uwsgi_string_list *usl = uwsgi.add_cache_item;
while(usl) {
char *space = strchr(usl->value, ' ');
char *key = usl->value;
uint16_t key_len = usl->len;
if (space) {
// need to skip ?
if (uwsgi_strncmp(uc->name, uc->name_len, usl->value, space-usl->value)) {
goto next;
}
key = space+1;
key_len = usl->len - ((space-usl->value)+1);
}
char *value = strchr(key, '=');
if (!value) {
uwsgi_log("[cache] unable to store item %s\n", usl->value);
goto next;
}
key_len = value - key;
value++;
uint64_t len = (usl->value + usl->len) - value;
uwsgi_wlock(uc->lock);
if (!uwsgi_cache_set2(uc, key, key_len, value, len, 0, 0)) {
uwsgi_log("[cache] stored \"%.*s\" in \"%s\"\n", key_len, key, uc->name);
}
else {
uwsgi_log("[cache-error] unable to store \"%.*s\" in \"%s\"\n", key_len, key, uc->name);
}
uwsgi_rwunlock(uc->lock);
next:
usl = usl->next;
}
}
static void uwsgi_cache_load_files(struct uwsgi_cache *uc) {
struct uwsgi_string_list *usl = uwsgi.load_file_in_cache;
@@ -341,6 +376,8 @@ void uwsgi_cache_init(struct uwsgi_cache *uc) {
uwsgi_cache_load_files(uc);
uwsgi_cache_add_items(uc);
}
static uint64_t uwsgi_cache_get_index(struct uwsgi_cache *uc, char *key, uint16_t keylen) {
+159
View File
@@ -0,0 +1,159 @@
#include <uwsgi.h>
extern struct uwsgi_server uwsgi;
/*
Chunked input implementation
--chunked-input-limit <bytes> (default 1MB)
--chunked-input-timeout <s> (default --socket-timeout)
chunk = uwsgi.chunked_read([timeout])
timeout = -1 (wait forever)
timeout = 0 (default)
*/
static ssize_t uwsgi_chunked_input_recv(struct wsgi_request *wsgi_req, int timeout, int nb) {
if (timeout == 0) timeout = uwsgi.chunked_input_timeout;
if (timeout == 0) timeout = uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT];
int ret = -1;
for(;;) {
ssize_t rlen = wsgi_req->socket->proto_read_body(wsgi_req, wsgi_req->chunked_input_buf->buf + wsgi_req->chunked_input_buf->pos, wsgi_req->chunked_input_buf->len - wsgi_req->chunked_input_buf->pos);
if (rlen > 0) return rlen;
if (rlen == 0) return -1;
if (rlen < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) {
if (nb) return -1;
goto wait;
}
uwsgi_error("uwsgi_chunked_input_recv()");
return -1;
}
wait:
ret = uwsgi.wait_read_hook(wsgi_req->fd, timeout);
if (ret > 0) {
rlen = wsgi_req->socket->proto_read_body(wsgi_req, wsgi_req->chunked_input_buf->buf + wsgi_req->chunked_input_buf->pos, wsgi_req->chunked_input_buf->len - wsgi_req->chunked_input_buf->pos);
if (rlen > 0) return rlen;
if (rlen <= 0) return -1;
}
if (ret < 0) {
uwsgi_error("uwsgi_chunked_input_recv()");
}
return -1;
}
return -1;
}
static ssize_t uwsgi_chunked_readline(struct wsgi_request *wsgi_req) {
size_t i;
int found = 0;
for(i=0;i<wsgi_req->chunked_input_buf->pos;i++) {
if (found) {
if (wsgi_req->chunked_input_buf->buf[i] == '\n') {
// strtoul will stop at \r
size_t num = strtoul(wsgi_req->chunked_input_buf->buf, NULL, 16);
if (uwsgi_buffer_decapitate(wsgi_req->chunked_input_buf, i+1)) return -1;
return num;
}
return -1;
}
if ((wsgi_req->chunked_input_buf->buf[i] >= '0' && wsgi_req->chunked_input_buf->buf[i] <= '9') ||
(wsgi_req->chunked_input_buf->buf[i] >= 'a' && wsgi_req->chunked_input_buf->buf[i] <= 'z') ||
(wsgi_req->chunked_input_buf->buf[i] >= 'A' && wsgi_req->chunked_input_buf->buf[i] <= 'Z')) continue;
if (wsgi_req->chunked_input_buf->buf[i] == '\r') { found = 1; continue; }
return -1;
}
return -2;
}
/*
0 -> waiting for \r\n
1 -> waiting for whole body
*/
char *uwsgi_chunked_read(struct wsgi_request *wsgi_req, size_t *len, int timeout, int nb) {
char *ret;
if (!wsgi_req->chunked_input_buf) {
wsgi_req->chunked_input_buf = uwsgi_buffer_new(uwsgi.page_size);
wsgi_req->chunked_input_buf->limit = uwsgi.chunked_input_limit;
}
// the whole chunk stream has been consumed
if (wsgi_req->chunked_input_complete) {
*len = 0;
return wsgi_req->chunked_input_buf->buf;
}
for(;;) {
if (wsgi_req->chunked_input_need > 0 || wsgi_req->chunked_input_buf->pos == 0) {
if (uwsgi_buffer_fix(wsgi_req->chunked_input_buf, uwsgi.page_size)) return NULL;
ssize_t rlen = uwsgi_chunked_input_recv(wsgi_req, timeout, nb);
if (rlen <= 0) return NULL;
// update buffer position
wsgi_req->chunked_input_buf->pos += rlen;
if (wsgi_req->chunked_input_need > 0) {
if ((size_t)rlen > wsgi_req->chunked_input_need) {
wsgi_req->chunked_input_need = 0;
}
else {
wsgi_req->chunked_input_need -= rlen;
}
}
}
if (wsgi_req->chunked_input_need > 0) continue;
// ok we have a frame, let's parse it
if (wsgi_req->chunked_input_buf->pos > 0) {
switch(wsgi_req->chunked_input_parser_status) {
case 0:
wsgi_req->chunked_input_chunk_len = uwsgi_chunked_readline(wsgi_req);
if (wsgi_req->chunked_input_chunk_len == -2) {
break;
}
else if (wsgi_req->chunked_input_chunk_len < 0) {
return NULL;
}
else if (wsgi_req->chunked_input_chunk_len == 0) {
*len = 0;
wsgi_req->chunked_input_complete = 1;
return wsgi_req->chunked_input_buf->buf;
}
// if here the buffer has been already decapitated
if ((size_t)(wsgi_req->chunked_input_chunk_len+2) > wsgi_req->chunked_input_buf->pos) {
wsgi_req->chunked_input_need = (wsgi_req->chunked_input_chunk_len+2) - wsgi_req->chunked_input_buf->pos;
wsgi_req->chunked_input_parser_status = 1;
break;
}
*len = wsgi_req->chunked_input_chunk_len;
ret = wsgi_req->chunked_input_buf->buf;
if (uwsgi_buffer_decapitate(wsgi_req->chunked_input_buf, wsgi_req->chunked_input_chunk_len+2)) return NULL;
return ret;
case 1:
if ((size_t)(wsgi_req->chunked_input_chunk_len+2) > wsgi_req->chunked_input_buf->pos) {
wsgi_req->chunked_input_need = (wsgi_req->chunked_input_chunk_len+2) - wsgi_req->chunked_input_buf->pos;
break;
}
*len = wsgi_req->chunked_input_chunk_len;
ret = wsgi_req->chunked_input_buf->buf;
if (uwsgi_buffer_decapitate(wsgi_req->chunked_input_buf, wsgi_req->chunked_input_chunk_len+2)) return NULL;
wsgi_req->chunked_input_parser_status = 0;
return ret;
}
}
}
}
+1
View File
@@ -0,0 +1 @@
int main() {}
+3
View File
@@ -169,6 +169,9 @@ void uwsgi_init_default() {
uwsgi.wait_write_hook = uwsgi_simple_wait_write_hook;
uwsgi_websockets_init();
// 1 MB default limit
uwsgi.chunked_input_limit = 1024*1024;
}
void uwsgi_setup_reload() {
+19
View File
@@ -1078,3 +1078,22 @@ void uwsgi_add_safe_fd(int fd) {
uwsgi.safe_fds[uwsgi.safe_fds_cnt] = fd;
uwsgi.safe_fds_cnt++;
}
int uwsgi_is_again() {
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) {
return 1;
}
return 0;
}
void uwsgi_disconnect(struct wsgi_request *wsgi_req) {
if (wsgi_req->socket) {
wsgi_req->socket->proto_close(wsgi_req);
}
wsgi_req->fd_closed = 1;
}
int uwsgi_ready_fd(struct wsgi_request *wsgi_req) {
if (wsgi_req->async_ready_fd) return wsgi_req->async_last_ready_fd;
return -1;
}
+13
View File
@@ -197,6 +197,14 @@ void uwsgi_master_check_mules_deadline() {
uwsgi.mules[i].harakiri = 0;
}
}
// user harakiri
if (uwsgi.mules[i].user_harakiri > 0) {
if (uwsgi.mules[i].user_harakiri < (time_t) uwsgi.current_time) {
uwsgi_log("*** HARAKIRI ON MULE %d (pid: %d) ***\n", i + 1, uwsgi.mules[i].pid);
kill(uwsgi.mules[i].pid, SIGKILL);
uwsgi.mules[i].user_harakiri = 0;
}
}
}
}
@@ -208,6 +216,11 @@ void uwsgi_master_check_spoolers_deadline() {
kill(uspool->pid, SIGKILL);
uspool->harakiri = 0;
}
if (uspool->user_harakiri > 0 && uspool->user_harakiri < (time_t) uwsgi.current_time) {
uwsgi_log("*** HARAKIRI ON THE SPOOLER (pid: %d) ***\n", uspool->pid);
kill(uspool->pid, SIGKILL);
uspool->user_harakiri = 0;
}
uspool = uspool->next;
}
}
+80 -1
View File
@@ -564,7 +564,7 @@ static int uwsgi_router_harakiri_func(struct wsgi_request *wsgi_req, struct uwsg
if (route->custom > 0) {
set_user_harakiri(route->custom);
}
return UWSGI_ROUTE_CONTINUE;
return UWSGI_ROUTE_NEXT;
}
static int uwsgi_router_harakiri(struct uwsgi_route *ur, char *arg) {
@@ -889,6 +889,77 @@ static int uwsgi_router_setscriptname(struct uwsgi_route *ur, char *arg) {
return 0;
}
// setmethod route
static int uwsgi_router_setmethod_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
if (!ub) return UWSGI_ROUTE_BREAK;
char *ptr = uwsgi_req_append(wsgi_req, "REQUEST_METHOD", 14, ub->buf, ub->pos);
if (!ptr) {
uwsgi_buffer_destroy(ub);
return UWSGI_ROUTE_BREAK;
}
wsgi_req->method = ptr;
wsgi_req->method_len = ub->pos;
uwsgi_buffer_destroy(ub);
return UWSGI_ROUTE_NEXT;
}
static int uwsgi_router_setmethod(struct uwsgi_route *ur, char *arg) {
ur->func = uwsgi_router_setmethod_func;
ur->data = arg;
ur->data_len = strlen(arg);
return 0;
}
// seturi route
static int uwsgi_router_seturi_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
if (!ub) return UWSGI_ROUTE_BREAK;
char *ptr = uwsgi_req_append(wsgi_req, "REQUEST_URI", 11, ub->buf, ub->pos);
if (!ptr) {
uwsgi_buffer_destroy(ub);
return UWSGI_ROUTE_BREAK;
}
wsgi_req->uri = ptr;
wsgi_req->uri_len = ub->pos;
uwsgi_buffer_destroy(ub);
return UWSGI_ROUTE_NEXT;
}
static int uwsgi_router_seturi(struct uwsgi_route *ur, char *arg) {
ur->func = uwsgi_router_seturi_func;
ur->data = arg;
ur->data_len = strlen(arg);
return 0;
}
// setpathinfo route
static int uwsgi_router_setpathinfo_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
if (!ub) return UWSGI_ROUTE_BREAK;
char *ptr = uwsgi_req_append(wsgi_req, "PATH_INFO", 9, ub->buf, ub->pos);
if (!ptr) {
uwsgi_buffer_destroy(ub);
return UWSGI_ROUTE_BREAK;
}
wsgi_req->path_info = ptr;
wsgi_req->path_info_len = ub->pos;
uwsgi_buffer_destroy(ub);
return UWSGI_ROUTE_NEXT;
}
static int uwsgi_router_setpathinfo(struct uwsgi_route *ur, char *arg) {
ur->func = uwsgi_router_setpathinfo_func;
ur->data = arg;
ur->data_len = strlen(arg);
return 0;
}
// setuser route
static int uwsgi_router_setuser_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
@@ -1389,6 +1460,11 @@ static char *uwsgi_route_var_uwsgi(struct wsgi_request *wsgi_req, char *key, uin
*vallen = strlen(ret);
}
else if (!uwsgi_strncmp(key, keylen, "lq", 2)) {
ret = uwsgi_num2str(uwsgi.shared->load);
*vallen = strlen(ret);
}
return ret;
}
@@ -1514,6 +1590,9 @@ void uwsgi_register_embedded_routers() {
uwsgi_register_router("sethome", uwsgi_router_sethome);
uwsgi_register_router("setfile", uwsgi_router_setfile);
uwsgi_register_router("setscriptname", uwsgi_router_setscriptname);
uwsgi_register_router("setmethod", uwsgi_router_setmethod);
uwsgi_register_router("seturi", uwsgi_router_seturi);
uwsgi_register_router("setpathinfo", uwsgi_router_setpathinfo);
uwsgi_register_router("setprocname", uwsgi_router_setprocname);
uwsgi_register_router("alarm", uwsgi_router_alarm);
+2
View File
@@ -82,6 +82,8 @@ int uwsgi_apply_final_transformations(struct wsgi_request *wsgi_req) {
found_nostream = 1;
}
else {
// stop the chain if no chunk is available
if (!ut->chunk) return 0;
t_buf = ut->chunk->buf;
t_len = ut->chunk->pos;
goto next;
+39 -16
View File
@@ -71,11 +71,30 @@ void set_user_harakiri(int sec) {
uwsgi_log("!!! unable to set user harakiri without the master process !!!\n");
return;
}
// a 0 seconds value, reset the timer
if (sec == 0) {
uwsgi.workers[uwsgi.mywid].user_harakiri = 0;
if (uwsgi.muleid > 0) {
uwsgi.mules[uwsgi.muleid-1].user_harakiri = 0;
}
else if (uwsgi.i_am_a_spooler) {
struct uwsgi_spooler *uspool = uwsgi.i_am_a_spooler;
uspool->user_harakiri = 0;
}
else {
uwsgi.workers[uwsgi.mywid].user_harakiri = 0;
}
}
else {
uwsgi.workers[uwsgi.mywid].user_harakiri = uwsgi_now() + sec;
if (uwsgi.muleid > 0) {
uwsgi.mules[uwsgi.muleid-1].user_harakiri = uwsgi_now() + sec;
}
else if (uwsgi.i_am_a_spooler) {
struct uwsgi_spooler *uspool = uwsgi.i_am_a_spooler;
uspool->user_harakiri = uwsgi_now() + sec;
}
else {
uwsgi.workers[uwsgi.mywid].user_harakiri = uwsgi_now() + sec;
}
}
}
@@ -708,6 +727,11 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
free(ptr);
}
// free chunked input
if (wsgi_req->chunked_input_buf) {
uwsgi_buffer_destroy(wsgi_req->chunked_input_buf);
}
// free websocket engine
if (wsgi_req->websocket_buf) {
uwsgi_buffer_destroy(wsgi_req->websocket_buf);
@@ -1147,7 +1171,6 @@ int uwsgi_get_app_id(struct wsgi_request *wsgi_req, char *key, uint16_t key_len,
int i;
struct stat st;
int found;
int free_appname = 0;
char *app_name = key;
uint16_t app_name_len = key_len;
@@ -1162,13 +1185,20 @@ int uwsgi_get_app_id(struct wsgi_request *wsgi_req, char *key, uint16_t key_len,
}
if (uwsgi.vhost) {
app_name = uwsgi_concat3n(wsgi_req->host, wsgi_req->host_len, "|",1, wsgi_req->script_name, wsgi_req->script_name_len);
char *vhost_name = uwsgi_concat3n(wsgi_req->host, wsgi_req->host_len, "|",1, wsgi_req->script_name, wsgi_req->script_name_len);
app_name_len = wsgi_req->host_len + 1 + wsgi_req->script_name_len;
app_name = uwsgi_req_append(wsgi_req, "UWSGI_APPID", 11, vhost_name, app_name_len);
free(vhost_name);
if (!app_name) {
uwsgi_log("unable to add UWSGI_APPID to the uwsgi buffer, consider increasing it\n");
return -1;
}
#ifdef UWSGI_DEBUG
uwsgi_debug("VirtualHost KEY=%.*s\n", wsgi_req->appid_len, wsgi_req->appid);
uwsgi_debug("VirtualHost KEY=%.*s\n", app_name_len, app_name);
#endif
free_appname = 1;
}
wsgi_req->appid = app_name;
wsgi_req->appid_len = app_name_len;
}
}
@@ -1203,18 +1233,11 @@ int uwsgi_get_app_id(struct wsgi_request *wsgi_req, char *key, uint16_t key_len,
}
}
}
if (modifier1 == -1) {
if (free_appname) free(app_name);
return i;
}
if (modifier1 == uwsgi_apps[i].modifier1) {
if (free_appname) free(app_name);
return i;
}
if (modifier1 == -1) return i;
if (modifier1 == uwsgi_apps[i].modifier1) return i;
}
}
if (free_appname) free(app_name);
return -1;
}
@@ -1952,7 +1975,7 @@ int uwsgi_list_has_str(char *list, char *str) {
return 0;
}
char hex2num(char *str) {
static char hex2num(char *str) {
char val = 0;
+69 -14
View File
@@ -236,6 +236,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"cache-sync", required_argument, 0, "copy the whole content of another uWSGI cache server on server startup", uwsgi_opt_set_str, &uwsgi.cache_sync, 0},
{"cache-use-last-modified", no_argument, 0, "update last_modified_at timestamp on every cache item modification (default is disabled)", uwsgi_opt_true, &uwsgi.cache_use_last_modified, 0},
{"add-cache-item", required_argument, 0, "add an item in the cache", uwsgi_opt_add_string_list, &uwsgi.add_cache_item, 0},
{"load-file-in-cache", required_argument, 0, "load a static file in the cache", uwsgi_opt_add_string_list, &uwsgi.load_file_in_cache, 0},
#ifdef UWSGI_ZLIB
{"load-file-in-cache-gzip", required_argument, 0, "load a static file in the cache with gzip compression", uwsgi_opt_add_string_list, &uwsgi.load_file_in_cache_gzip, 0},
@@ -460,6 +461,9 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"log-route", required_argument, 0, "log to the specified named logger if regexp applied on logline matches", uwsgi_opt_add_regexp_custom_list, &uwsgi.log_route, UWSGI_OPT_MASTER | UWSGI_OPT_LOG_MASTER},
{"log-req-route", required_argument, 0, "log requests to the specified named logger if regexp applied on logline matches", uwsgi_opt_add_regexp_custom_list, &uwsgi.log_req_route, UWSGI_OPT_REQ_LOG_MASTER},
#endif
{"use-abort", no_argument, 0, "call abort() on segfault/fpe, could be useful for generating a core dump", uwsgi_opt_true, &uwsgi.use_abort, 0},
{"alarm", required_argument, 0, "create a new alarm, syntax: <alarm> <plugin:args>", uwsgi_opt_add_string_list, &uwsgi.alarm_list, UWSGI_OPT_MASTER},
{"alarm-freq", required_argument, 0, "tune the anti-loop alam system (default 3 seconds)", uwsgi_opt_set_int, &uwsgi.alarm_freq, 0},
{"alarm-fd", required_argument, 0, "raise the specified alarm when an fd is read for read (by default it reads 1 byte, set 8 for eventfd)", uwsgi_opt_add_string_list, &uwsgi.alarm_fd_list, UWSGI_OPT_MASTER},
@@ -580,6 +584,9 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"websockets-max-size", required_argument, 0, "set the max allowed size of websocket messages (in Kbytes, default 1024)", uwsgi_opt_set_64bit, &uwsgi.websockets_max_size, 0},
{"websocket-max-size", required_argument, 0, "set the max allowed size of websocket messages (in Kbytes, default 1024)", uwsgi_opt_set_64bit, &uwsgi.websockets_max_size, 0},
{"chunked-input-limit", required_argument, 0, "set the max size of a chunked input part (default 1MB, in bytes)", uwsgi_opt_set_64bit, &uwsgi.chunked_input_limit, 0},
{"chunked-input-timeout", required_argument, 0, "set default timeout for chunked input", uwsgi_opt_set_int, &uwsgi.chunked_input_timeout, 0},
{"clock", required_argument, 0, "set a clock source", uwsgi_opt_set_str, &uwsgi.requested_clock, 0},
{"clock-list", no_argument, 0, "list enabled clocks", uwsgi_opt_true, &uwsgi.clock_list, 0},
@@ -694,6 +701,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"show-config", no_argument, 0, "show the current config reformatted as ini", uwsgi_opt_true, &uwsgi.show_config, 0},
{"print", required_argument, 0, "simple print", uwsgi_opt_print, NULL, 0},
{"cflags", no_argument, 0, "report uWSGI CFLAGS (useful for building external plugins)", uwsgi_opt_cflags, NULL, UWSGI_OPT_IMMEDIATE},
{"dot-h", no_argument, 0, "dump the uwsgi.h used for building the core (useful for building external plugins)", uwsgi_opt_dot_h, NULL, UWSGI_OPT_IMMEDIATE},
{"version", no_argument, 0, "print uWSGI version", uwsgi_opt_print, UWSGI_VERSION, 0},
{0, 0, 0, 0, 0, 0, 0}
};
@@ -1528,6 +1536,8 @@ void uwsgi_segfault(int signum) {
uwsgi_log("!!! uWSGI process %d got Segmentation Fault !!!\n", (int) getpid());
uwsgi_backtrace(uwsgi.backtrace_depth);
if (uwsgi.use_abort) abort();
// restore default handler to generate core
signal(signum, SIG_DFL);
kill(getpid(), signum);
@@ -1541,6 +1551,8 @@ void uwsgi_fpe(int signum) {
uwsgi_log("!!! uWSGI process %d got Floating Point Exception !!!\n", (int) getpid());
uwsgi_backtrace(uwsgi.backtrace_depth);
if (uwsgi.use_abort) abort();
// restore default handler to generate core
signal(signum, SIG_DFL);
kill(getpid(), signum);
@@ -3387,7 +3399,9 @@ void uwsgi_opt_set_16bit(char *opt, char *value, void *key) {
uint16_t *ptr = (uint16_t *) key;
if (value) {
*ptr = (strtoul(value, NULL, 10));
unsigned long n = strtoul(value, NULL, 10);
if (n > 65535) n = 65535;
*ptr = n;
}
else {
*ptr = 1;
@@ -4058,20 +4072,61 @@ void uwsgi_opt_flock_wait(char *opt, char *filename, void *none) {
// report CFLAGS used for compiling the server
// use that values to build external plugins
void uwsgi_opt_cflags(char *opt, char *filename, void *foobar) {
size_t len = sizeof(UWSGI_CFLAGS);
char *src = UWSGI_CFLAGS;
char *ptr = uwsgi_malloc(len / 2);
char *base = ptr;
size_t i;
unsigned int u;
for (i = 0; i < len; i += 2) {
sscanf(src + i, "%2x", &u);
*ptr++ = (char) u;
}
fprintf(stdout, "%.*s\n", (int) len / 2, base);
fprintf(stdout, "%s\n", uwsgi_get_cflags());
exit(0);
}
char *uwsgi_get_cflags() {
size_t len = sizeof(UWSGI_CFLAGS);
char *src = UWSGI_CFLAGS;
char *ptr = uwsgi_malloc((len / 2) + 1);
char *base = ptr;
size_t i;
unsigned int u;
for (i = 0; i < len; i += 2) {
sscanf(src + i, "%2x", &u);
*ptr++ = (char) u;
}
*ptr ++= 0;
return base;
}
// report uwsgi.h used for compiling the server
// use that values to build external plugins
extern char *uwsgi_dot_h;
char *uwsgi_get_dot_h() {
char *src = uwsgi_dot_h;
size_t len = strlen(src);
char *ptr = uwsgi_malloc(len / 2);
char *base = ptr;
size_t i;
unsigned int u;
for (i = 0; i < len; i += 2) {
sscanf(src + i, "%2x", &u);
*ptr++ = (char) u;
}
#ifdef UWSGI_ZLIB
struct uwsgi_buffer *ub = uwsgi_zlib_decompress(base, ptr-base);
if (!ub) {
free(base);
return "";
}
// add final null byte
uwsgi_buffer_append(ub, "\0", 1);
free(base);
// base is the final blob
base = ub->buf;
ub->buf = NULL;
uwsgi_buffer_destroy(ub);
#endif
return base;
}
void uwsgi_opt_dot_h(char *opt, char *filename, void *foobar) {
fprintf(stdout, "%s\n", uwsgi_get_dot_h());
exit(0);
}
void uwsgi_opt_connect_and_read(char *opt, char *address, void *foobar) {
char buf[8192];
@@ -4108,9 +4163,9 @@ void uwsgi_opt_extract(char *opt, char *address, void *foobar) {
}
void uwsgi_print_sym(char *opt, char *symbol, void *foobar) {
char *sym = dlsym(RTLD_DEFAULT, symbol);
char **sym = dlsym(RTLD_DEFAULT, symbol);
if (sym) {
uwsgi_log("%s", sym);
uwsgi_log("%s", *sym);
exit(0);
}
+56
View File
@@ -2,6 +2,8 @@
char gzheader[10] = { 0x1f, 0x8b, Z_DEFLATED, 0, 0, 0, 0, 0, 0, 3 };
extern struct uwsgi_server uwsgi;
char *uwsgi_gzip_chunk(z_stream *z, uint32_t *crc32, char *buf, size_t len, size_t *dlen) {
uwsgi_crc32(crc32, buf, len);
return uwsgi_deflate(z, buf, len, dlen);
@@ -38,6 +40,45 @@ end:
return ub;
}
struct uwsgi_buffer *uwsgi_zlib_decompress(char *buf, size_t len) {
z_stream z;
z.zalloc = Z_NULL;
z.zfree = Z_NULL;
z.opaque = Z_NULL;
if (inflateInit(&z) != Z_OK) {
return NULL;
}
struct uwsgi_buffer *ub = uwsgi_buffer_new(uwsgi.page_size);
unsigned char out[8192];
z.next_in = (unsigned char *)buf;
z.avail_in = len;
z.next_out = out;
do {
z.avail_out = 8192;
z.next_out = out;
int ret = inflate(&z, Z_NO_FLUSH);
if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT || ret == Z_DATA_ERROR || ret == Z_MEM_ERROR) {
uwsgi_buffer_destroy(ub);
ub = NULL;
goto end;
}
if (uwsgi_buffer_append(ub, (char *)out, 8192 - z.avail_out)) {
uwsgi_buffer_destroy(ub);
ub = NULL;
goto end;
}
}
while (z.avail_out == 0);
end:
inflateEnd(&z);
return ub;
}
int uwsgi_deflate_init(z_stream *z, char *dict, size_t dict_len) {
z->zalloc = Z_NULL;
z->zfree = Z_NULL;
@@ -54,6 +95,21 @@ int uwsgi_deflate_init(z_stream *z, char *dict, size_t dict_len) {
return 0;
}
int uwsgi_inflate_init(z_stream *z, char *dict, size_t dict_len) {
z->zalloc = Z_NULL;
z->zfree = Z_NULL;
z->opaque = Z_NULL;
if (inflateInit2(z, 16+MAX_WBITS) != Z_OK) {
return -1;
}
if (dict && dict_len) {
if (inflateSetDictionary(z, (Bytef *) dict, dict_len) != Z_OK) {
return -1;
}
}
return 0;
}
int uwsgi_gzip_prepare(z_stream *z, char *dict, size_t dict_len, uint32_t *crc32) {
uwsgi_crc32(crc32, NULL, 0);
if (uwsgi_deflate_init(z, NULL, 0)) return -1;
+52
View File
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Livello_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="768px" height="272.667px" viewBox="0 0 768 272.667" enable-background="new 0 0 768 272.667" xml:space="preserve">
<g>
<path fill="#AEC84D" d="M170.667,41.334"/>
<path fill="#AEC84D" d="M46.167,106.667v92.5c0,0-0.667,52.667,48.5,51.5c7.667-0.333,36,1,43-21c0-0.5,0,17,0,17h34l0.062-140h-34
l-0.062,86.5c0,0,1,31-28,29.5s-28.5-27-28.5-27l-0.167-89H46.167z"/>
<polygon fill="#141215" points="227,250.334 241,250.334 286.667,137.334 332.333,250.001 346.333,250.001 403,41.334
368.667,32.667 334.333,161.667 293.667,60.001 279.333,60.001 240,160.667 204.667,32.667 170.667,41.334 "/>
<path fill="#141215" d="M402,203c0,0,8.667,26.001,23,35.334s38.666,12.999,50.333,12.666s71.001-1.333,71.667-56.333
c5-28-19.333-48.334-26-52.334s-28.334-18-45.667-23s-34.334-16-35.667-24.666s0.001-34,37.334-34.334
c26,2.668,27,13.668,31,19.668l7,14.332l28.666-13.332c0,0-11.334-27-14-29.334s-13.333-19-55.333-18.666
c-42,0.332-66.666,17.666-68.333,47.666s4.666,44,35.333,62.666c19,10.334,39.001,12.667,59.667,28.334
c14.333,11.667,11.334,25.001,11,30.667s-7.334,21.666-36.334,20.333S441,209.668,439,206.334s-9-17-9-17L402,203z"/>
<rect x="710.667" y="36.334" fill="#141215" width="35.333" height="211.333"/>
<path fill="#141215" d="M636.333,135.001v27.666h27.333v56c0,0-8.334,5.001-26.667,4.334s-47.332,1.666-49.666-81.667
s37.334-80.667,42-80.667s28,0.334,40,33.334C669.667,94.334,698,80.667,698,80.667s-12.334-50.333-67-47.666
c-54.666,2.666-75.666,30.999-78.666,102c-3,71,21.999,117.334,81.666,115s64-7.334,64-7.334l-0.083-107.583L636.333,135.001z"/>
<g>
<circle fill="#AEC84D" cx="521.333" cy="71.001" r="11.667"/>
<circle fill="#252326" cx="521.333" cy="71.001" r="3.5"/>
</g>
<g>
<path fill="none" d="M81.147,185.163L81,106.667H46.167v90.88C56.139,192.016,68.027,187.752,81.147,185.163z"/>
<path fill="none" d="M171.729,106.667h-34l-0.057,78.023c12.606,2.254,24.141,6.043,34.017,11.019L171.729,106.667z"/>
<path opacity="0.1" fill="#FFFFFF" d="M46.167,199.167c0,0-0.667,52.667,48.5,51.5c7.667-0.333,36,1,43-21c0-0.5,0,17,0,17h34
l0.023-50.958c-9.876-4.976-21.411-8.765-34.017-11.019l-0.006,8.477c0,0,1,31-28,29.5s-28.5-27-28.5-27l-0.02-10.504
c-13.12,2.589-25.008,6.853-34.98,12.384V199.167z"/>
</g>
<g>
<path fill="none" d="M342.89,129.517l-8.557,32.15l-13.896-34.738c-22.89-2.918-44.071-6.524-63.071-10.708L240,160.667
l-14.526-52.621c-16.399-4.896-30.286-10.312-41.175-16.132L227,250.334h14l45.667-113l45.667,112.667h14l31.898-117.459
C366.127,131.707,354.33,130.695,342.89,129.517z"/>
<path opacity="0.1" fill="#FFFFFF" d="M403,41.334l-34.333-8.667l-25.776,96.85c11.44,1.178,23.237,2.19,35.341,3.025L403,41.334z
"/>
<path opacity="0.1" fill="#FFFFFF" d="M204.667,32.667l-34,8.667l13.633,50.58c10.889,5.82,24.775,11.236,41.175,16.132
L204.667,32.667z"/>
<path opacity="0.1" fill="#FFFFFF" d="M293.667,60.001h-14.333l-21.967,56.22c19,4.185,40.182,7.79,63.071,10.708L293.667,60.001z
"/>
</g>
<path opacity="0.1" fill="#FFFFFF" d="M474.333,33.001c-42,0.332-66.666,17.666-68.333,47.666
c-1.409,25.351,2.897,39.276,22.77,54.247c10.646,0.275,21.452,0.419,32.396,0.419c15.9,0,31.514-0.299,46.756-0.872
c-9.466-5.486-21.856-12.032-32.589-15.128c-17.333-5-34.334-16-35.667-24.666s0.001-34,37.334-34.334
c26,2.668,27,13.668,31,19.668l7,14.332l28.666-13.332c0,0-11.334-27-14-29.334S516.333,32.667,474.333,33.001z"/>
<path opacity="0.1" fill="#FFFFFF" d="M631,33.001c-53.87,2.627-75.047,30.182-78.522,98.93c11.947-0.916,23.576-2.007,34.838-3.26
c1.845-70.377,37.603-68.004,42.019-68.004c4.666,0,28,0.334,40,33.334C669.667,94.334,698,80.667,698,80.667
S685.666,30.334,631,33.001z"/>
<path opacity="0.1" fill="#FFFFFF" d="M710.667,103.59c14.42-5.033,26.342-10.521,35.333-16.36V36.334h-35.333V103.59z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

+1
View File
@@ -229,6 +229,7 @@ static void uwsgi_airbrake_loop(struct uwsgi_thread *ut) {
curl_easy_setopt(curl, CURLOPT_POST, 1L);
struct curl_slist *expect = NULL; expect = curl_slist_append(expect, "Expect:");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, expect);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
struct uwsgi_airbrake_config *uacc = (struct uwsgi_airbrake_config *) ut->data;
char *opts = uwsgi_str(uacc->arg);
+1
View File
@@ -154,6 +154,7 @@ static void uwsgi_alarm_curl_loop(struct uwsgi_thread *ut) {
curl_easy_setopt(curl, CURLOPT_POST, 1L);
struct curl_slist *expect = NULL; expect = curl_slist_append(expect, "Expect:");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, expect);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
struct uwsgi_alarm_curl_config *uacc = (struct uwsgi_alarm_curl_config *) ut->data;
char *opts = uwsgi_str(uacc->arg);
+2 -2
View File
@@ -23,13 +23,13 @@
}\
peer->out_pos += len;
#define cr_write_buf(peer, buf, f) write(peer->fd, buf + buf##_pos, buf->pos - buf##_pos);\
#define cr_write_buf(peer, ubuf, f) write(peer->fd, ubuf->buf + ubuf##_pos, ubuf->pos - ubuf##_pos);\
if (len < 0) {\
cr_try_again;\
uwsgi_cr_error(peer, f);\
return -1;\
}\
buf##_pos += len;
ubuf##_pos += len;
#define cr_write_complete(peer) peer->out_pos == peer->out->pos
+1 -1
View File
@@ -161,7 +161,7 @@ request:
#endif
for(;;) {
if (uwsgi.p[wsgi_req->uh->modifier1]->request(wsgi_req)) {
if (uwsgi.p[wsgi_req->uh->modifier1]->request(wsgi_req) <= UWSGI_OK) {
goto end;
}
wsgi_req->switches++;
+5
View File
@@ -0,0 +1,5 @@
#include <uwsgi.h>
struct uwsgi_plugin objc_gc_plugin = {
.name = "objc_gc",
};
+5
View File
@@ -0,0 +1,5 @@
NAME="objc_gc"
CFLAGS=["-fobjc-gc"]
LDFLAGS=[]
LIBS=[]
GCC_LIST=['objc_gc.m']
+12
View File
@@ -81,6 +81,16 @@ XS(XS_signal) {
XSRETURN_UNDEF;
}
XS(XS_set_user_harakiri) {
dXSARGS;
psgi_check_args(1);
set_user_harakiri( SvIV(ST(0)) );
XSRETURN_UNDEF;
}
XS(XS_reload) {
dXSARGS;
@@ -549,5 +559,7 @@ void init_perl_embedded_module() {
psgi_xs(add_timer);
psgi_xs(add_rb_timer);
psgi_xs(set_user_harakiri);
}
+15 -41
View File
@@ -41,47 +41,6 @@ void (*uwsgi_pypy_post_fork_hook)(void);
extern struct uwsgi_server uwsgi;
struct uwsgi_plugin pypy_plugin;
int uwsgi_pypy_helper_masterpid() {
if (uwsgi.master_process) {
return uwsgi.workers[0].pid;
}
return 0;
}
int uwsgi_pypy_helper_worker_id() {
return uwsgi.mywid;
}
int uwsgi_pypy_helper_mule_id() {
return uwsgi.muleid;
}
void uwsgi_pypy_helper_signal(int signum) {
uwsgi_signal_send(uwsgi.signal_socket, signum);
}
struct uwsgi_opt **uwsgi_pypy_helper_opts(int *n) {
*n = uwsgi.exported_opts_cnt;
return uwsgi.exported_opts;
}
char *uwsgi_pypy_helper_version() {
return UWSGI_VERSION;
}
int uwsgi_pypy_helper_register_signal(int signum, char *kind, void *handler) {
return uwsgi_register_signal(signum, kind, handler, pypy_plugin.modifier1);
}
int uwsgi_pypy_helper_register_rpc(char *name, int argc, void *func) {
return uwsgi_register_rpc(name, &pypy_plugin, argc, func);
}
struct iovec *uwsgi_pypy_helper_environ(struct wsgi_request *wsgi_req, uint16_t *len) {
*len = wsgi_req->var_cnt;
return wsgi_req->hvec;
}
static int uwsgi_pypy_init() {
size_t rlen = 0;
@@ -342,6 +301,20 @@ static void uwsgi_pypy_onload() {
#endif
}
static int uwsgi_pypy_mule(char *opt) {
if (uwsgi_endswith(opt, ".py")) {
size_t rlen = 0;
char *buffer = uwsgi_open_and_read(opt, &rlen, 1, NULL);
pypy_execute_source(buffer);
free(buffer);
return 1;
}
return 0;
}
struct uwsgi_plugin pypy_plugin = {
.name = "pypy",
.modifier1 = 0,
@@ -357,4 +330,5 @@ struct uwsgi_plugin pypy_plugin = {
.enable_threads = uwsgi_pypy_enable_threads,
.rpc = uwsgi_pypy_rpc,
.post_fork = uwsgi_pypy_post_fork,
.mule = uwsgi_pypy_mule,
};
+508 -72
View File
@@ -14,69 +14,230 @@ import cffi
# this is a list holding object we do not want to be freed (like callback and handlers)
uwsgi_gc = []
# the main ffi
ffi = cffi.FFI()
defines = '''
# the hooks we need to patch
hooks = '''
void free(void *);
ssize_t read(int, void *, size_t);
ssize_t write(int, const void *, size_t);
int close(int);
void (*uwsgi_pypy_hook_loader)(char *);
void (*uwsgi_pypy_hook_file_loader)(char *);
void (*uwsgi_pypy_hook_pythonpath)(char *);
void (*uwsgi_pypy_hook_request)(void *, int);
void (*uwsgi_pypy_hook_request)(struct wsgi_request *);
void (*uwsgi_pypy_post_fork_hook)(void);
'''
# here we load CFLAGS and uwsgi.h from the binary
defines0 = '''
char *uwsgi_get_cflags();
char *uwsgi_get_dot_h();
'''
ffi.cdef(defines0)
lib0 = ffi.verify(defines0)
# this is ugly, we should find a better approach
# basically it build a list of #define from binary CFLAGS
uwsgi_cdef = []
uwsgi_defines = []
uwsgi_cflags = ffi.string(lib0.uwsgi_get_cflags()).split()
for cflag in uwsgi_cflags:
if cflag.startswith('-D'):
line = cflag[2:]
if '=' in line:
(key, value) = line.split('=', 1)
uwsgi_cdef.append('#define %s ...' % key)
uwsgi_defines.append('#define %s %s' % (key, value.replace('\\"','"').replace('""','"')))
else:
uwsgi_cdef.append('#define %s ...' % line)
uwsgi_defines.append('#define %s 1' % line)
uwsgi_dot_h = ffi.string(lib0.uwsgi_get_dot_h())
# uwsgi definitions
cdefines = '''
%s
struct iovec {
char *iov_base;
uint64_t iov_len;
void *iov_base;
size_t iov_len;
...;
};
struct uwsgi_header {
uint8_t modifier1;
...;
};
struct wsgi_request {
int fd;
int async_id;
uint16_t var_cnt;
struct iovec *hvec;
int async_ready_fd;
int async_last_ready_fd;
int suspended;
struct uwsgi_header *uh;
...;
};
struct uwsgi_opt {
char *key;
char *value;
int configured;
char *key;
char *value;
...;
};
struct uwsgi_worker {
int id;
int pid;
uint64_t requests;
uint64_t delta_requests;
uint64_t signals;
int cheaped;
int suspended;
int sig;
uint8_t signum;
uint64_t running_time;
uint64_t avg_response_time;
uint64_t tx;
...;
};
struct uwsgi_plugin {
uint8_t modifier1;
void (*suspend) (struct wsgi_request *);
void (*resume) (struct wsgi_request *);
...;
};
struct uwsgi_buffer {
char *buf;
size_t pos;
...;
};
struct uwsgi_server {
char hostname[];
int mywid;
int muleid;
int master_process;
struct uwsgi_opt **exported_opts;
int exported_opts_cnt;
struct uwsgi_worker *workers;
int signal_socket;
int numproc;
int async;
void (*schedule_to_main) (struct wsgi_request *);
void (*schedule_to_req) (void);
struct wsgi_request *(*current_wsgi_req) (void);
struct wsgi_request *wsgi_req;
struct uwsgi_plugin *p[];
...;
};
struct uwsgi_server uwsgi;
struct uwsgi_plugin *pypy_plugin;
const char *uwsgi_pypy_version;
char *uwsgi_binary_path();
void uwsgi_set_processname(char *);
void uwsgi_alarm_trigger(char *, char *, uint64_t);
int uwsgi_signal_registered(uint8_t);
int uwsgi_response_write_body_do(void *, char *, uint64_t);
int uwsgi_response_sendfile_do_can_close(void *, int, uint64_t, uint64_t, int);
int uwsgi_response_prepare_headers(void *, char *, uint16_t);
int uwsgi_response_add_header(void *, char *, uint16_t, char *, uint16_t);
char *uwsgi_request_body_read(void *, uint64_t, int64_t *);
char *uwsgi_request_body_readline(void *, uint64_t, int64_t *);
int uwsgi_response_prepare_headers(struct wsgi_request *, char *, size_t);
int uwsgi_response_add_header(struct wsgi_request *, char *, uint16_t, char *, uint16_t);
int uwsgi_response_write_body_do(struct wsgi_request *, char *, size_t);
int uwsgi_response_sendfile_do_can_close(struct wsgi_request *, int, size_t, size_t, int);
struct iovec *uwsgi_pypy_helper_environ(void *, uint16_t *);
char *uwsgi_request_body_read(struct wsgi_request *, ssize_t , ssize_t *);
char *uwsgi_request_body_readline(struct wsgi_request *, ssize_t, ssize_t *);
char *uwsgi_pypy_helper_version();
int uwsgi_pypy_helper_register_signal(int, char *, void *);
int uwsgi_pypy_helper_register_rpc(char *, int, void *);
void uwsgi_pypy_helper_signal(int);
struct uwsgi_opt** uwsgi_pypy_helper_opts(int *);
int uwsgi_pypy_helper_masterpid();
int uwsgi_pypy_helper_worker_id();
int uwsgi_pypy_helper_mule_id();
void uwsgi_buffer_destroy(struct uwsgi_buffer *);
int uwsgi_is_again();
int uwsgi_register_rpc(char *, struct uwsgi_plugin *, uint8_t, void *);
int uwsgi_register_signal(uint8_t, char *, void *, uint8_t);
char *uwsgi_cache_magic_get(char *, uint64_t, uint64_t *, uint64_t *, char *);
int uwsgi_cache_magic_set(char *, uint64_t, char *, uint64_t, uint64_t, uint64_t, char *);
int uwsgi_cache_magic_del(char *, uint64_t, char *);
int uwsgi_add_timer(uint8_t, int);
int uwsgi_add_rb_timer(uint8_t, int, int);
int uwsgi_add_file_monitor(uint8_t, char *);
char *uwsgi_do_rpc(char *, char *, uint8_t, char **, uint16_t *, uint16_t *);
int uwsgi_signal_add_cron(uint8_t, int, int, int, int, int);
void uwsgi_set_processname(char *);
int uwsgi_signal_send(int, uint8_t);
uint64_t uwsgi_worker_exceptions(int);
int uwsgi_worker_is_busy(int);
char *uwsgi_cache_magic_get(char *, uint16_t, uint64_t *, uint64_t *, char *);
int uwsgi_cache_magic_set(char *, uint16_t, char *, uint64_t, uint64_t, uint64_t, char *);
int uwsgi_cache_magic_del(char *, uint16_t, char *);
int uwsgi_cache_magic_exists(char *, uint16_t, char *);
int uwsgi_cache_magic_clear(char *);
int uwsgi_add_file_monitor(uint8_t, char *);
int uwsgi_add_timer(uint8_t, int);
int uwsgi_signal_add_rb_timer(uint8_t, int, int);
int uwsgi_user_lock(int);
int uwsgi_user_unlock(int);
'''
int uwsgi_signal_registered(uint8_t);
ffi = cffi.FFI()
ffi.cdef(defines)
lib = ffi.verify(defines)
int uwsgi_signal_add_cron(uint8_t, int, int, int, int, int);
void uwsgi_alarm_trigger(char *, char *, size_t);
void async_schedule_to_req_green(void);
void async_add_timeout(struct wsgi_request *, int);
int async_add_fd_write(struct wsgi_request *, int, int);
int async_add_fd_read(struct wsgi_request *, int, int);
int uwsgi_connect(char *, int, int);
int uwsgi_websocket_handshake(struct wsgi_request *, char *, uint16_t, char *, uint16_t);
int uwsgi_websocket_send(struct wsgi_request *, char *, size_t);
struct uwsgi_buffer *uwsgi_websocket_recv(struct wsgi_request *);
struct uwsgi_buffer *uwsgi_websocket_recv_nb(struct wsgi_request *);
char *uwsgi_chunked_read(struct wsgi_request *, size_t *, int, int);
void uwsgi_disconnect(struct wsgi_request *);
int uwsgi_ready_fd(struct wsgi_request *);
void set_user_harakiri(int);
%s
''' % ('\n'.join(uwsgi_cdef), hooks)
cverify = '''
%s
const char *uwsgi_pypy_version = UWSGI_VERSION;
%s
extern struct uwsgi_server uwsgi;
extern struct uwsgi_plugin *pypy_plugin;
%s
''' % ('\n'.join(uwsgi_defines), uwsgi_dot_h, hooks)
ffi.cdef(cdefines)
lib = ffi.verify(cverify)
libc = ffi.dlopen(None)
"""
this is a global object point the the WSGI callable
it sucks, i will fix it in the near future...
@@ -115,7 +276,7 @@ def uwsgi_pypy_file_loader(filename):
wsgi_application = getattr(mod, c)
"""
.post_fork_hokk
.post_fork_hook
"""
@ffi.callback("void()")
def uwsgi_pypy_post_fork_hook():
@@ -180,7 +341,7 @@ class WSGIinput(object):
raise IOError("error waiting for wsgi.input")
def getline(self, hint=0):
rlen = ffi.new('int64_t*')
rlen = ffi.new('ssize_t*')
chunk = lib.uwsgi_request_body_readline(self.wsgi_req, hint, rlen)
if chunk != ffi.NULL:
return ffi.string(chunk, rlen[0])
@@ -213,8 +374,9 @@ class WSGIinput(object):
"""
the WSGI request handler
"""
@ffi.callback("void(void *, int)")
def uwsgi_pypy_wsgi_handler(wsgi_req, core):
@ffi.callback("void(struct wsgi_request *)")
def uwsgi_pypy_wsgi_handler(wsgi_req):
import uwsgi
global wsgi_application
def writer(data):
@@ -229,10 +391,9 @@ def uwsgi_pypy_wsgi_handler(wsgi_req, core):
return writer
environ = {}
nv = ffi.new("uint16_t*")
iov = lib.uwsgi_pypy_helper_environ(wsgi_req, nv)
for i in range(0, nv[0], 2):
environ[ffi.string(iov[i].iov_base, iov[i].iov_len)] = ffi.string(iov[i+1].iov_base, iov[i+1].iov_len)
iov = wsgi_req.hvec
for i in range(0, wsgi_req.var_cnt, 2):
environ[ffi.string(ffi.cast("char*", iov[i].iov_base), iov[i].iov_len)] = ffi.string(ffi.cast("char*", iov[i+1].iov_base), iov[i+1].iov_len)
environ['wsgi.version'] = (1, 0)
scheme = 'http'
@@ -247,7 +408,8 @@ def uwsgi_pypy_wsgi_handler(wsgi_req, core):
environ['wsgi.multithread'] = True
environ['wsgi.multiprocess'] = True
environ['uwsgi.core'] = core
environ['uwsgi.core'] = wsgi_req.async_id
environ['uwsgi.node'] = uwsgi.hostname
response = wsgi_application(environ, start_response)
if type(response) is str:
@@ -281,13 +443,13 @@ Here we define the "uwsgi" virtual module
uwsgi = imp.new_module('uwsgi')
sys.modules['uwsgi'] = uwsgi
uwsgi.version = ffi.string(lib.uwsgi_pypy_helper_version())
uwsgi.version = ffi.string(lib.uwsgi_pypy_version)
uwsgi.hostname = ffi.string(lib.uwsgi.hostname)
def uwsgi_pypy_uwsgi_register_signal(signum, kind, handler):
cb = ffi.callback('void(int)', handler)
uwsgi_gc.append(cb)
if lib.uwsgi_pypy_helper_register_signal(signum, ffi.new("char[]", kind), cb) < 0:
if lib.uwsgi_register_signal(signum, ffi.new("char[]", kind), cb, lib.pypy_plugin.modifier1) < 0:
raise Exception("unable to register signal %d" % signum)
uwsgi.register_signal = uwsgi_pypy_uwsgi_register_signal
@@ -311,7 +473,7 @@ def uwsgi_pypy_uwsgi_register_rpc(name, func, argc=0):
rpc_func = uwsgi_pypy_RPC(func)
cb = ffi.callback("int(int, char*[], int[], char*)", rpc_func)
uwsgi_gc.append(cb)
if lib.uwsgi_pypy_helper_register_rpc(ffi.new("char[]", name), argc, cb) < 0:
if lib.uwsgi_register_rpc(ffi.new("char[]", name), lib.pypy_plugin, argc, cb) < 0:
raise Exception("unable to register rpc func %s" % name)
uwsgi.register_rpc = uwsgi_pypy_uwsgi_register_rpc
@@ -350,9 +512,7 @@ def uwsgi_pypy_call(func, *args):
return uwsgi_pypy_rpc(node, func, *args)
uwsgi.call = uwsgi_pypy_call
def uwsgi_pypy_uwsgi_signal(signum):
lib.uwsgi_pypy_helper_signal(signum)
uwsgi.signal = uwsgi_pypy_uwsgi_signal
uwsgi.signal = lambda x: lib.uwsgi_signal_send(lib.uwsgi.signal_socket, x)
def uwsgi_pypy_uwsgi_cache_get(key, cache=ffi.NULL):
@@ -387,7 +547,7 @@ def uwsgi_pypy_uwsgi_add_timer(signum, secs):
uwsgi.add_timer = uwsgi_pypy_uwsgi_add_timer
def uwsgi_pypy_uwsgi_add_rb_timer(signum, secs):
if lib.uwsgi_add_rb_timer(signum, secs, 0) < 0:
if lib.uwsgi_signal_add_rb_timer(signum, secs, 0) < 0:
raise Exception("unable to register redblack timer")
uwsgi.add_rb_timer = uwsgi_pypy_uwsgi_add_rb_timer
@@ -397,27 +557,25 @@ def uwsgi_pypy_uwsgi_add_file_monitor(signum, filename):
raise Exception("unable to register file monitor")
uwsgi.add_file_monitor = uwsgi_pypy_uwsgi_add_file_monitor
def uwsgi_pypy_lock(num):
def uwsgi_pypy_lock(num=0):
if lib.uwsgi_user_lock(num) < 0:
raise Exception("invalid lock")
uwsgi.lock = uwsgi_pypy_lock
def uwsgi_pypy_unlock(num):
def uwsgi_pypy_unlock(num=0):
if lib.uwsgi_user_unlock(num) < 0:
raise Exception("invalid lock")
uwsgi.unlock = uwsgi_pypy_unlock
def uwsgi_pypy_masterpid():
return lib.uwsgi_pypy_helper_masterpid()
if lib.uwsgi.master_process:
return lib.uwsgi.workers[0].pid
return 0
uwsgi.masterpid = uwsgi_pypy_masterpid
def uwsgi_pypy_worker_id():
return lib.uwsgi_pypy_helper_worker_id()
uwsgi.worker_id = uwsgi_pypy_worker_id
uwsgi.worker_id = lambda: lib.uwsgi.mywid
def uwsgi_pypy_mule_id():
return lib.uwsgi_pypy_helper_mule_id()
uwsgi.mule_id = uwsgi_pypy_mule_id
uwsgi.mule_id = lambda: lib.uwsgi.muleid
def uwsgi_pypy_signal_registered(signum):
if lib.uwsgi_signal_registered(signum) > 0:
@@ -429,28 +587,24 @@ def uwsgi_pypy_alarm(alarm, msg):
lib.uwsgi_alarm_trigger(ffi.new('char[]', alarm), ffi.new('char[]', msg), len(msg))
uwsgi.alarm = uwsgi_pypy_alarm
def uwsgi_pypy_setprocname(name):
lib.uwsgi_set_processname(ffi.new('char[]',name))
uwsgi.setprocname = uwsgi_pypy_setprocname
uwsgi.setprocname = lambda name: lib.uwsgi_set_processname(ffi.new('char[]', name))
def uwsgi_pypy_add_cron(signum, minute, hour, day, month, week):
if lib.uwsgi_signal_add_cron(signum, minute, hour, day, month, week) < 0:
raise Exception("unable to register cron")
return True
uwsgi.add_cron = uwsgi_pypy_add_cron
"""
populate uwsgi.opt
"""
uwsgi.opt = {}
n_opts = ffi.new('int*')
u_opts = lib.uwsgi_pypy_helper_opts(n_opts)
for i in range(0, n_opts[0]):
k = ffi.string(u_opts[i].key)
if u_opts[i].value == ffi.NULL:
for i in range(0, lib.uwsgi.exported_opts_cnt):
uo = lib.uwsgi.exported_opts[i]
k = ffi.string(uo.key)
if uo.value == ffi.NULL:
v = True
else:
v = ffi.string(u_opts[i].value)
v = ffi.string(uo.value)
if k in uwsgi.opt:
if type(uwsgi.opt[k]) is list:
uwsgi.opt[k].append(v)
@@ -459,5 +613,287 @@ for i in range(0, n_opts[0]):
else:
uwsgi.opt[k] = v
def uwsgi_pypy_current_wsgi_req():
wsgi_req = lib.uwsgi.current_wsgi_req()
if wsgi_req == ffi.NULL:
raise Exception("unable to get current wsgi_request, check your setup !!!")
return wsgi_req
"""
uwsgi.suspend()
"""
def uwsgi_pypy_suspend():
wsgi_req = uwsgi_pypy_current_wsgi_req()
if lib.uwsgi.schedule_to_main:
lib.uwsgi.schedule_to_main(wsgi_req);
uwsgi.suspend = uwsgi_pypy_suspend
"""
uwsgi.workers()
"""
def uwsgi_pypy_workers():
workers = []
for i in range(1, lib.uwsgi.numproc+1):
worker = {}
worker['id'] = lib.uwsgi.workers[i].id
worker['pid'] = lib.uwsgi.workers[i].pid
worker['requests'] = lib.uwsgi.workers[i].requests
worker['delta_requests'] = lib.uwsgi.workers[i].delta_requests
worker['signals'] = lib.uwsgi.workers[i].signals
worker['exceptions'] = lib.uwsgi_worker_exceptions(i);
worker['apps'] = []
if lib.uwsgi.workers[i].cheaped:
worker['status'] == 'cheap'
elif lib.uwsgi.workers[i].suspended and not lib.uwsgi_worker_is_busy(i):
worker['status'] == 'pause'
else:
if lib.uwsgi.workers[i].sig:
worker['status'] = 'sig%d' % lib.uwsgi.workers[i].signum
elif lib.uwsgi_worker_is_busy(i):
worker['status'] = 'busy'
else:
worker['status'] = 'idle'
worker['running_time'] = lib.uwsgi.workers[i].running_time
worker['avg_rt'] = lib.uwsgi.workers[i].avg_response_time
worker['tx'] = lib.uwsgi.workers[i].tx
workers.append(worker)
return workers
uwsgi.workers = uwsgi_pypy_workers
"""
uwsgi.async_sleep(timeout)
"""
def uwsgi_pypy_async_sleep(timeout):
if timeout > 0:
wsgi_req = uwsgi_pypy_current_wsgi_req();
lib.async_add_timeout(wsgi_req, timeout);
uwsgi.async_sleep = uwsgi_pypy_async_sleep
"""
uwsgi.async_connect(addr)
"""
def uwsgi_pypy_async_connect(addr):
fd = lib.uwsgi_connect(ffi.new('char[]', addr), 0, 1)
if fd < 0:
raise Exception("unable to connect to %s" % addr)
return fd
uwsgi.async_connect = uwsgi_pypy_async_connect
uwsgi.connection_fd = lambda: uwsgi_pypy_current_wsgi_req().fd
"""
uwsgi.wait_fd_read(fd, timeout=0)
"""
def uwsgi_pypy_wait_fd_read(fd, timeout=0):
wsgi_req = uwsgi_pypy_current_wsgi_req();
if lib.async_add_fd_read(wsgi_req, fd, timeout) < 0:
raise Exception("unable to add fd %d to the event queue" % fd)
uwsgi.wait_fd_read = uwsgi_pypy_wait_fd_read
"""
uwsgi.wait_fd_write(fd, timeout=0)
"""
def uwsgi_pypy_wait_fd_write(fd, timeout=0):
wsgi_req = uwsgi_pypy_current_wsgi_req();
if lib.async_add_fd_write(wsgi_req, fd, timeout) < 0:
raise Exception("unable to add fd %d to the event queue" % fd)
uwsgi.wait_fd_write = uwsgi_pypy_wait_fd_write
"""
uwsgi.ready_fd()
"""
def uwsgi_pypy_ready_fd():
wsgi_req = uwsgi_pypy_current_wsgi_req();
return lib.uwsgi_ready_fd(wsgi_req)
uwsgi.ready_fd = uwsgi_pypy_ready_fd
"""
uwsgi.send(fd=None,data)
"""
def uwsgi_pypy_send(*args):
if len(args) == 0:
raise ValueError("uwsgi.send() takes at least 1 argument")
elif len(args) == 1:
wsgi_req = uwsgi_pypy_current_wsgi_req();
fd = wsgi_req.fd
data = args[0]
else:
fd = args[0]
data = args[1]
rlen = libc.write(fd, data, len(data))
if rlen <= 0:
raise IOError("unable to send data")
return rlen
uwsgi.send = uwsgi_pypy_send
"""
uwsgi.recv(fd=None,len)
"""
def uwsgi_pypy_recv(*args):
if len(args) == 0:
raise ValueError("uwsgi.recv() takes at least 1 argument")
elif len(args) == 1:
wsgi_req = uwsgi_pypy_current_wsgi_req();
fd = wsgi_req.fd
l = args[0]
else:
fd = args[0]
l = args[1]
data = ffi.new('char[%d]' % l)
rlen = libc.read(fd, data, l)
if rlen <= 0:
raise IOError("unable to receive data")
return ffi.string(data[0:rlen])
uwsgi.recv = uwsgi_pypy_recv
"""
uwsgi.close(fd)
"""
uwsgi.close = lambda fd: lib.close(fd)
"""
uwsgi.disconnect()
"""
uwsgi.disconnect = lambda: lib.uwsgi_disconnect(uwsgi_pypy_current_wsgi_req())
"""
uwsgi.websocket_recv()
"""
def uwsgi_pypy_websocket_recv():
wsgi_req = uwsgi_pypy_current_wsgi_req();
ub = lib.uwsgi_websocket_recv(wsgi_req);
if ub == ffi.NULL:
raise IOError("unable to receive websocket message")
ret = ffi.string(ub.buf, ub.pos)
lib.uwsgi_buffer_destroy(ub)
return ret
uwsgi.websocket_recv = uwsgi_pypy_websocket_recv
"""
uwsgi.websocket_recv_nb()
"""
def uwsgi_pypy_websocket_recv_nb():
wsgi_req = uwsgi_pypy_current_wsgi_req();
ub = lib.uwsgi_websocket_recv_nb(wsgi_req);
if ub == ffi.NULL:
raise IOError("unable to receive websocket message")
ret = ffi.string(ub.buf, ub.pos)
lib.uwsgi_buffer_destroy(ub)
return ret
uwsgi.websocket_recv_nb = uwsgi_pypy_websocket_recv_nb
"""
uwsgi.websocket_handshake(key, origin)
"""
def uwsgi_pypy_websocket_handshake(key, origin=''):
wsgi_req = uwsgi_pypy_current_wsgi_req();
if lib.uwsgi_websocket_handshake(wsgi_req, ffi.new('char[]', key), len(key), ffi.new('char[]',origin), len(origin)) < 0:
raise IOError("unable to complete websocket handshake")
uwsgi.websocket_handshake = uwsgi_pypy_websocket_handshake
"""
uwsgi.websocket_send(msg)
"""
def uwsgi_pypy_websocket_send(msg):
wsgi_req = uwsgi_pypy_current_wsgi_req();
if lib.uwsgi_websocket_send(wsgi_req, ffi.new('char[]', msg), len(msg)) < 0:
raise IOError("unable to send websocket message")
uwsgi.websocket_send = uwsgi_pypy_websocket_send
"""
uwsgi.chunked_read(timeout=0)
"""
def uwsgi_pypy_chunked_read(timeout=0):
wsgi_req = uwsgi_pypy_current_wsgi_req();
rlen = ffi.new("size_t*")
chunk = lib.uwsgi_chunked_read(wsgi_req, rlen, timeout, 0)
if chunk == ffi.NULL:
raise IOError("unable to receive chunked part")
return ffi.string(chunk, rlen[0])
uwsgi.chunked_read = uwsgi_pypy_chunked_read
"""
uwsgi.chunked_read_nb()
"""
def uwsgi_pypy_chunked_read_nb():
wsgi_req = uwsgi_pypy_current_wsgi_req();
rlen = ffi.new("size_t*")
chunk = lib.uwsgi_chunked_read(wsgi_req, rlen, 0, 1)
if chunk == ffi.NULL:
if lib.uwsgi_is_again() > 0:
return None
raise IOError("unable to receive chunked part")
return ffi.string(chunk, rlen[0])
uwsgi.chunked_read_nb = uwsgi_pypy_chunked_read_nb
"""
uwsgi.set_user_harakiri(sec)
"""
uwsgi.set_user_harakiri = lambda x: lib.set_user_harakiri(x)
print "Initialized PyPy with Python", sys.version
print "PyPy Home:", sys.prefix
"""
Continulets support
"""
# this is the dictionary of continulets (one per-core)
uwsgi_pypy_continulets = {}
def uwsgi_pypy_continulet_wrapper(cont):
lib.async_schedule_to_req_green()
@ffi.callback("void()")
def uwsgi_pypy_continulet_schedule():
id = lib.uwsgi.wsgi_req.async_id
modifier1 = lib.uwsgi.wsgi_req.uh.modifier1;
# generate a new continulet
if not lib.uwsgi.wsgi_req.suspended:
from _continuation import continulet
uwsgi_pypy_continulets[id] = continulet(uwsgi_pypy_continulet_wrapper)
lib.uwsgi.wsgi_req.suspended = 1
# this is called in the main stack
if lib.uwsgi.p[modifier1].suspend:
lib.uwsgi.p[modifier1].suspend(ffi.NULL)
# let's switch
uwsgi_pypy_continulets[id].switch()
# back to the main stack
if lib.uwsgi.p[modifier1].resume:
lib.uwsgi.p[modifier1].resume(ffi.NULL)
@ffi.callback("void(struct wsgi_request *)")
def uwsgi_pypy_continulet_switch(wsgi_req):
id = wsgi_req.async_id
modifier1 = wsgi_req.uh.modifier1;
# this is called in the current continulet
if lib.uwsgi.p[modifier1].suspend:
lib.uwsgi.p[modifier1].suspend(wsgi_req)
uwsgi_pypy_continulets[id].switch()
# back to the continulet
if lib.uwsgi.p[modifier1].resume:
lib.uwsgi.p[modifier1].resume(wsgi_req)
# update current running continulet
lib.uwsgi.wsgi_req = wsgi_req
def uwsgi_pypy_setup_continulets():
if lib.uwsgi.async <= 1:
raise Exception("pypy continulets require async mode !!!")
lib.uwsgi.schedule_to_main = uwsgi_pypy_continulet_switch
lib.uwsgi.schedule_to_req = uwsgi_pypy_continulet_schedule
print "*** PyPy Continulets engine loaded ***"
+48 -9
View File
@@ -1063,6 +1063,42 @@ PyObject *py_uwsgi_websocket_send(PyObject * self, PyObject * args) {
return Py_None;
}
PyObject *py_uwsgi_chunked_read(PyObject * self, PyObject * args) {
int timeout = 0;
if (!PyArg_ParseTuple(args, "|i:chunked_read", &timeout)) {
return NULL;
}
size_t len = 0;
struct wsgi_request *wsgi_req = py_current_wsgi_req();
UWSGI_RELEASE_GIL
char *chunk = uwsgi_chunked_read(wsgi_req, &len, timeout, 0);
UWSGI_GET_GIL
if (!chunk) {
return PyErr_Format(PyExc_IOError, "unable to receive chunked part");
}
return PyString_FromStringAndSize(chunk, len);
}
PyObject *py_uwsgi_chunked_read_nb(PyObject * self, PyObject * args) {
size_t len = 0;
struct wsgi_request *wsgi_req = py_current_wsgi_req();
UWSGI_RELEASE_GIL
char *chunk = uwsgi_chunked_read(wsgi_req, &len, 0, 1);
UWSGI_GET_GIL
if (!chunk) {
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) {
Py_INCREF(Py_None);
return Py_None;
}
return PyErr_Format(PyExc_IOError, "unable to receive chunked part");
}
return PyString_FromStringAndSize(chunk, len);
}
PyObject *py_uwsgi_websocket_recv(PyObject * self, PyObject * args) {
struct wsgi_request *wsgi_req = py_current_wsgi_req();
UWSGI_RELEASE_GIL
@@ -2234,17 +2270,15 @@ PyObject *py_uwsgi_disconnect(PyObject * self, PyObject * args) {
struct wsgi_request *wsgi_req = py_current_wsgi_req();
#ifdef UWSGI_DEBUG
uwsgi_log("disconnecting worker %d (pid :%d) from session...\n", uwsgi.mywid, uwsgi.mypid);
#endif
uwsgi_disconnect(wsgi_req);
if (wsgi_req->socket) {
wsgi_req->socket->proto_close(wsgi_req);
}
wsgi_req->fd_closed = 1;
Py_INCREF(Py_None);
return Py_None;
}
Py_INCREF(Py_True);
return Py_True;
PyObject *py_uwsgi_ready_fd(PyObject * self, PyObject * args) {
struct wsgi_request *wsgi_req = py_current_wsgi_req();
return PyInt_FromLong(uwsgi_ready_fd(wsgi_req));
}
PyObject *py_uwsgi_parse_file(PyObject * self, PyObject * args) {
@@ -2484,6 +2518,11 @@ static PyMethodDef uwsgi_advanced_methods[] = {
{"websocket_send", py_uwsgi_websocket_send, METH_VARARGS, ""},
{"websocket_handshake", py_uwsgi_websocket_handshake, METH_VARARGS, ""},
{"chunked_read", py_uwsgi_chunked_read, METH_VARARGS, ""},
{"chunked_read_nb", py_uwsgi_chunked_read_nb, METH_VARARGS, ""},
{"ready_fd", py_uwsgi_ready_fd, METH_VARARGS, ""},
{NULL, NULL},
};
+60 -51
View File
@@ -7,7 +7,7 @@ extern struct uwsgi_plugin rack_plugin;
#define uwsgi_rack_api(x, y, z) rb_define_module_function(rb_uwsgi_embedded, x, y, z)
VALUE rack_uwsgi_warning(VALUE *class, VALUE rbmessage) {
static VALUE rack_uwsgi_warning(VALUE *class, VALUE rbmessage) {
Check_Type(rbmessage, T_STRING);
char *message = RSTRING_PTR(rbmessage);
@@ -26,7 +26,14 @@ VALUE rack_uwsgi_warning(VALUE *class, VALUE rbmessage) {
return Qnil;
}
VALUE rack_uwsgi_log(VALUE *class, VALUE msg) {
static VALUE rack_uwsgi_user_harakiri(VALUE *class, VALUE sec) {
Check_Type(sec, T_FIXNUM);
set_user_harakiri(NUM2INT(sec));
return Qnil;
}
static VALUE rack_uwsgi_log(VALUE *class, VALUE msg) {
Check_Type(msg, T_STRING);
@@ -35,7 +42,7 @@ VALUE rack_uwsgi_log(VALUE *class, VALUE msg) {
return Qnil;
}
VALUE rack_uwsgi_i_am_the_spooler(VALUE *class) {
static VALUE rack_uwsgi_i_am_the_spooler(VALUE *class) {
if (uwsgi.i_am_a_spooler) {
return Qtrue;
}
@@ -43,7 +50,7 @@ VALUE rack_uwsgi_i_am_the_spooler(VALUE *class) {
}
#ifdef UWSGI_SSL
VALUE rack_uwsgi_i_am_the_lord(VALUE *class, VALUE legion_name) {
static VALUE rack_uwsgi_i_am_the_lord(VALUE *class, VALUE legion_name) {
Check_Type(legion_name, T_STRING);
if (uwsgi_legion_i_am_the_lord(RSTRING_PTR(legion_name))) {
return Qtrue;
@@ -54,7 +61,7 @@ VALUE rack_uwsgi_i_am_the_lord(VALUE *class, VALUE legion_name) {
VALUE rack_uwsgi_setprocname(VALUE *class, VALUE rbname) {
static VALUE rack_uwsgi_setprocname(VALUE *class, VALUE rbname) {
Check_Type(rbname, T_STRING);
char *name = RSTRING_PTR(rbname);
@@ -63,7 +70,7 @@ VALUE rack_uwsgi_setprocname(VALUE *class, VALUE rbname) {
return Qnil;
}
VALUE rack_uwsgi_mem(VALUE *class) {
static VALUE rack_uwsgi_mem(VALUE *class) {
uint64_t rss=0, vsz = 0;
VALUE ml = rb_ary_new2(2);
@@ -77,23 +84,23 @@ VALUE rack_uwsgi_mem(VALUE *class) {
}
VALUE rack_uwsgi_request_id(VALUE *class) {
static VALUE rack_uwsgi_request_id(VALUE *class) {
return ULONG2NUM(uwsgi.workers[uwsgi.mywid].requests);
}
VALUE rack_uwsgi_worker_id(VALUE *class) {
static VALUE rack_uwsgi_worker_id(VALUE *class) {
return INT2NUM(uwsgi.mywid);
}
VALUE rack_uwsgi_mule_id(VALUE *class) {
static VALUE rack_uwsgi_mule_id(VALUE *class) {
return INT2NUM(uwsgi.muleid);
}
VALUE rack_uwsgi_logsize(VALUE *class) {
static VALUE rack_uwsgi_logsize(VALUE *class) {
return ULONG2NUM(uwsgi.shared->logsize);
}
VALUE rack_uwsgi_mule_msg(int argc, VALUE *argv, VALUE *class) {
static VALUE rack_uwsgi_mule_msg(int argc, VALUE *argv, VALUE *class) {
int fd = -1;
int mule_id = -1;
@@ -151,7 +158,7 @@ VALUE rack_uwsgi_mule_msg(int argc, VALUE *argv, VALUE *class) {
int uwsgi_ruby_hash_mule_callback(VALUE key, VALUE val, VALUE arg_array) {
static int uwsgi_ruby_hash_mule_callback(VALUE key, VALUE val, VALUE arg_array) {
Check_Type(key, T_SYMBOL);
ID key_id = SYM2ID(key);
const char *key_name = rb_id2name(key_id);
@@ -172,7 +179,7 @@ int uwsgi_ruby_hash_mule_callback(VALUE key, VALUE val, VALUE arg_array) {
return 0;
}
VALUE rack_uwsgi_mule_get_msg(int argc, VALUE *argv, VALUE *class) {
static VALUE rack_uwsgi_mule_get_msg(int argc, VALUE *argv, VALUE *class) {
int manage_signals = 1;
int manage_farms = 1;
@@ -228,7 +235,7 @@ VALUE rack_uwsgi_mule_get_msg(int argc, VALUE *argv, VALUE *class) {
}
VALUE rack_uwsgi_lock(int argc, VALUE *argv, VALUE *class) {
static VALUE rack_uwsgi_lock(int argc, VALUE *argv, VALUE *class) {
int lock_num = 0;
@@ -246,7 +253,7 @@ VALUE rack_uwsgi_lock(int argc, VALUE *argv, VALUE *class) {
return Qnil;
}
VALUE rack_uwsgi_unlock(int argc, VALUE *argv, VALUE *class) {
static VALUE rack_uwsgi_unlock(int argc, VALUE *argv, VALUE *class) {
int lock_num = 0;
@@ -268,7 +275,7 @@ VALUE rack_uwsgi_unlock(int argc, VALUE *argv, VALUE *class) {
VALUE rack_uwsgi_cache_set(int argc, VALUE *argv, VALUE *class) {
static VALUE rack_uwsgi_cache_set(int argc, VALUE *argv, VALUE *class) {
if (argc < 2) goto error;
@@ -304,7 +311,7 @@ error:
}
VALUE rack_uwsgi_cache_update(int argc, VALUE *argv, VALUE *class) {
static VALUE rack_uwsgi_cache_update(int argc, VALUE *argv, VALUE *class) {
if (argc < 2) goto error;
@@ -341,7 +348,7 @@ error:
}
VALUE rack_uwsgi_cache_set_exc(int argc, VALUE *argv, VALUE *class) {
static VALUE rack_uwsgi_cache_set_exc(int argc, VALUE *argv, VALUE *class) {
VALUE ret = rack_uwsgi_cache_set(argc, argv, class);
if (ret == Qnil) {
rb_raise(rb_eRuntimeError, "unable to set value in uWSGI cache");
@@ -349,7 +356,7 @@ VALUE rack_uwsgi_cache_set_exc(int argc, VALUE *argv, VALUE *class) {
return ret;
}
VALUE rack_uwsgi_cache_update_exc(int argc, VALUE *argv, VALUE *class) {
static VALUE rack_uwsgi_cache_update_exc(int argc, VALUE *argv, VALUE *class) {
VALUE ret = rack_uwsgi_cache_update(argc, argv, class);
if (ret == Qnil) {
rb_raise(rb_eRuntimeError, "unable to update value in uWSGI cache");
@@ -357,7 +364,7 @@ VALUE rack_uwsgi_cache_update_exc(int argc, VALUE *argv, VALUE *class) {
return ret;
}
VALUE rack_uwsgi_cache_del(int argc, VALUE *argv, VALUE *class) {
static VALUE rack_uwsgi_cache_del(int argc, VALUE *argv, VALUE *class) {
if (argc == 0) goto error;
@@ -383,7 +390,7 @@ error:
return Qnil;
}
VALUE rack_uwsgi_cache_del_exc(int argc, VALUE *argv, VALUE *class) {
static VALUE rack_uwsgi_cache_del_exc(int argc, VALUE *argv, VALUE *class) {
VALUE ret = rack_uwsgi_cache_del(argc, argv, class);
if (ret == Qnil) {
rb_raise(rb_eRuntimeError, "unable to delete object from uWSGI cache");
@@ -393,7 +400,7 @@ VALUE rack_uwsgi_cache_del_exc(int argc, VALUE *argv, VALUE *class) {
VALUE rack_uwsgi_cache_exists(int argc, VALUE *argv, VALUE *class) {
static VALUE rack_uwsgi_cache_exists(int argc, VALUE *argv, VALUE *class) {
if (argc == 0) goto error;
@@ -421,7 +428,7 @@ error:
VALUE rack_uwsgi_cache_clear(int argc, VALUE *argv, VALUE *class) {
static VALUE rack_uwsgi_cache_clear(int argc, VALUE *argv, VALUE *class) {
char *cache = NULL;
@@ -437,7 +444,7 @@ VALUE rack_uwsgi_cache_clear(int argc, VALUE *argv, VALUE *class) {
return Qnil;
}
VALUE rack_uwsgi_cache_clear_exc(int argc, VALUE *argv, VALUE *class) {
static VALUE rack_uwsgi_cache_clear_exc(int argc, VALUE *argv, VALUE *class) {
VALUE ret = rack_uwsgi_cache_clear(argc, argv, class);
if (ret == Qnil) {
rb_raise(rb_eRuntimeError, "unable to clear the uWSGI cache");
@@ -447,7 +454,7 @@ VALUE rack_uwsgi_cache_clear_exc(int argc, VALUE *argv, VALUE *class) {
VALUE rack_uwsgi_cache_get(int argc, VALUE *argv, VALUE *class) {
static VALUE rack_uwsgi_cache_get(int argc, VALUE *argv, VALUE *class) {
if (argc == 0) goto error;
@@ -477,7 +484,7 @@ error:
}
VALUE rack_uwsgi_cache_get_exc(int argc, VALUE *argv, VALUE *class) {
static VALUE rack_uwsgi_cache_get_exc(int argc, VALUE *argv, VALUE *class) {
VALUE ret = rack_uwsgi_cache_get(argc, argv, class);
if (ret == Qnil) {
rb_raise(rb_eRuntimeError, "unable to get value from uWSGI cache");
@@ -488,7 +495,7 @@ VALUE rack_uwsgi_cache_get_exc(int argc, VALUE *argv, VALUE *class) {
VALUE rack_uwsgi_add_cron(VALUE *class, VALUE rbsignum, VALUE rbmin, VALUE rbhour, VALUE rbday, VALUE rbmon, VALUE rbweek) {
static VALUE rack_uwsgi_add_cron(VALUE *class, VALUE rbsignum, VALUE rbmin, VALUE rbhour, VALUE rbday, VALUE rbmon, VALUE rbweek) {
Check_Type(rbsignum, T_FIXNUM);
Check_Type(rbmin, T_FIXNUM);
@@ -514,7 +521,7 @@ VALUE rack_uwsgi_add_cron(VALUE *class, VALUE rbsignum, VALUE rbmin, VALUE rbhou
VALUE rack_uwsgi_add_timer(VALUE *class, VALUE rbsignum, VALUE secs) {
static VALUE rack_uwsgi_add_timer(VALUE *class, VALUE rbsignum, VALUE secs) {
Check_Type(rbsignum, T_FIXNUM);
Check_Type(secs, T_FIXNUM);
@@ -532,7 +539,7 @@ VALUE rack_uwsgi_add_timer(VALUE *class, VALUE rbsignum, VALUE secs) {
VALUE rack_uwsgi_add_rb_timer(VALUE *class, VALUE rbsignum, VALUE secs) {
static VALUE rack_uwsgi_add_rb_timer(VALUE *class, VALUE rbsignum, VALUE secs) {
Check_Type(rbsignum, T_FIXNUM);
Check_Type(secs, T_FIXNUM);
@@ -550,7 +557,7 @@ VALUE rack_uwsgi_add_rb_timer(VALUE *class, VALUE rbsignum, VALUE secs) {
}
VALUE rack_uwsgi_alarm(VALUE *class, VALUE alarm, VALUE msg) {
static VALUE rack_uwsgi_alarm(VALUE *class, VALUE alarm, VALUE msg) {
Check_Type(alarm, T_STRING);
Check_Type(msg, T_STRING);
@@ -560,7 +567,7 @@ VALUE rack_uwsgi_alarm(VALUE *class, VALUE alarm, VALUE msg) {
return Qnil;
}
VALUE rack_uwsgi_add_file_monitor(VALUE *class, VALUE rbsignum, VALUE rbfilename) {
static VALUE rack_uwsgi_add_file_monitor(VALUE *class, VALUE rbsignum, VALUE rbfilename) {
Check_Type(rbsignum, T_FIXNUM);
Check_Type(rbfilename, T_STRING);
@@ -577,7 +584,7 @@ VALUE rack_uwsgi_add_file_monitor(VALUE *class, VALUE rbsignum, VALUE rbfilename
}
VALUE uwsgi_ruby_wait_fd_read(VALUE *class, VALUE arg1, VALUE arg2) {
static VALUE uwsgi_ruby_wait_fd_read(VALUE *class, VALUE arg1, VALUE arg2) {
Check_Type(arg1, T_FIXNUM);
Check_Type(arg2, T_FIXNUM);
@@ -595,7 +602,7 @@ VALUE uwsgi_ruby_wait_fd_read(VALUE *class, VALUE arg1, VALUE arg2) {
return Qtrue;
}
VALUE uwsgi_ruby_wait_fd_write(VALUE *class, VALUE arg1, VALUE arg2) {
static VALUE uwsgi_ruby_wait_fd_write(VALUE *class, VALUE arg1, VALUE arg2) {
Check_Type(arg1, T_FIXNUM);
Check_Type(arg2, T_FIXNUM);
@@ -612,7 +619,7 @@ VALUE uwsgi_ruby_wait_fd_write(VALUE *class, VALUE arg1, VALUE arg2) {
return Qtrue;
}
VALUE uwsgi_ruby_async_connect(VALUE *class, VALUE arg) {
static VALUE uwsgi_ruby_async_connect(VALUE *class, VALUE arg) {
Check_Type(arg, T_STRING);
@@ -622,7 +629,7 @@ VALUE uwsgi_ruby_async_connect(VALUE *class, VALUE arg) {
}
VALUE uwsgi_ruby_async_sleep(VALUE *class, VALUE arg) {
static VALUE uwsgi_ruby_async_sleep(VALUE *class, VALUE arg) {
Check_Type(arg, T_FIXNUM);
@@ -636,7 +643,7 @@ VALUE uwsgi_ruby_async_sleep(VALUE *class, VALUE arg) {
return Qtrue;
}
VALUE uwsgi_ruby_masterpid(VALUE *class) {
static VALUE uwsgi_ruby_masterpid(VALUE *class) {
if (uwsgi.master_process) {
return INT2NUM(uwsgi.workers[0].pid);
@@ -644,7 +651,7 @@ VALUE uwsgi_ruby_masterpid(VALUE *class) {
return INT2NUM(0);
}
VALUE uwsgi_ruby_suspend(VALUE *class) {
static VALUE uwsgi_ruby_suspend(VALUE *class) {
struct wsgi_request *wsgi_req = current_wsgi_req();
@@ -655,7 +662,7 @@ VALUE uwsgi_ruby_suspend(VALUE *class) {
}
VALUE uwsgi_ruby_signal_wait(int argc, VALUE *argv, VALUE *class) {
static VALUE uwsgi_ruby_signal_wait(int argc, VALUE *argv, VALUE *class) {
struct wsgi_request *wsgi_req = current_wsgi_req();
int wait_for_specific_signal = 0;
@@ -687,7 +694,7 @@ VALUE uwsgi_ruby_signal_wait(int argc, VALUE *argv, VALUE *class) {
return Qnil;
}
VALUE uwsgi_ruby_signal_received(VALUE *class) {
static VALUE uwsgi_ruby_signal_received(VALUE *class) {
struct wsgi_request *wsgi_req = current_wsgi_req();
@@ -695,7 +702,7 @@ VALUE uwsgi_ruby_signal_received(VALUE *class) {
}
VALUE uwsgi_ruby_signal_registered(VALUE *class, VALUE signum) {
static VALUE uwsgi_ruby_signal_registered(VALUE *class, VALUE signum) {
Check_Type(signum, T_FIXNUM);
@@ -708,7 +715,7 @@ VALUE uwsgi_ruby_signal_registered(VALUE *class, VALUE signum) {
return Qfalse;
}
VALUE uwsgi_ruby_do_rpc(int argc, VALUE *rpc_argv, VALUE *class) {
static VALUE uwsgi_ruby_do_rpc(int argc, VALUE *rpc_argv, VALUE *class) {
char *node = NULL, *func;
uint16_t size = 0;
@@ -759,7 +766,7 @@ clear:
return Qnil;
}
VALUE uwsgi_ruby_register_rpc(int argc, VALUE *argv, VALUE *class) {
static VALUE uwsgi_ruby_register_rpc(int argc, VALUE *argv, VALUE *class) {
int rb_argc = 0;
@@ -785,7 +792,7 @@ clear:
return Qtrue;
}
VALUE uwsgi_ruby_register_signal(VALUE *class, VALUE signum, VALUE sigkind, VALUE rbhandler) {
static VALUE uwsgi_ruby_register_signal(VALUE *class, VALUE signum, VALUE sigkind, VALUE rbhandler) {
Check_Type(signum, T_FIXNUM);
Check_Type(sigkind, T_STRING);
@@ -805,7 +812,7 @@ VALUE uwsgi_ruby_register_signal(VALUE *class, VALUE signum, VALUE sigkind, VALU
}
VALUE uwsgi_ruby_signal(int argc, VALUE *argv, VALUE *class) {
static VALUE uwsgi_ruby_signal(int argc, VALUE *argv, VALUE *class) {
if (argc < 1) {
rb_raise(rb_eRuntimeError, "you have to specify a signum");
@@ -872,7 +879,7 @@ int rack_uwsgi_build_spool(VALUE rbkey, VALUE rbval, VALUE argv) {
}
VALUE rack_uwsgi_send_spool(VALUE *class, VALUE args) {
static VALUE rack_uwsgi_send_spool(VALUE *class, VALUE args) {
char spool_filename[1024];
struct wsgi_request *wsgi_req = current_wsgi_req();
@@ -926,10 +933,10 @@ VALUE rack_uwsgi_send_spool(VALUE *class, VALUE args) {
rb_hash_foreach(args, rack_uwsgi_build_spool, (VALUE) argv);
if (numprio) {
priority = uwsgi_num2str(numprio);
priority = uwsgi_num2str((int)numprio);
}
int ret = spool_request(uwsgi.spoolers, spool_filename, uwsgi.workers[0].requests + 1, wsgi_req->async_id, spool_buffer, argv[0] - spool_buffer, priority, at, body, body_len);
int ret = spool_request(uwsgi.spoolers, spool_filename, (int)(uwsgi.workers[0].requests + 1), wsgi_req->async_id, spool_buffer, (int)(argv[0] - spool_buffer), priority, at, body, body_len);
if (priority) {
free(priority);
@@ -950,7 +957,7 @@ VALUE rack_uwsgi_send_spool(VALUE *class, VALUE args) {
}
VALUE uwsgi_ruby_websocket_handshake(int argc, VALUE *argv, VALUE *class) {
static VALUE uwsgi_ruby_websocket_handshake(int argc, VALUE *argv, VALUE *class) {
struct wsgi_request *wsgi_req = current_wsgi_req();
@@ -978,7 +985,7 @@ VALUE uwsgi_ruby_websocket_handshake(int argc, VALUE *argv, VALUE *class) {
return Qnil;
}
VALUE uwsgi_ruby_websocket_send(VALUE *class, VALUE *msg) {
static VALUE uwsgi_ruby_websocket_send(VALUE *class, VALUE *msg) {
Check_Type(msg, T_STRING);
char *message = RSTRING_PTR(msg);
size_t message_len = RSTRING_LEN(msg);
@@ -989,7 +996,7 @@ VALUE uwsgi_ruby_websocket_send(VALUE *class, VALUE *msg) {
return Qnil;
}
VALUE uwsgi_ruby_websocket_recv(VALUE *class) {
static VALUE uwsgi_ruby_websocket_recv(VALUE *class) {
struct wsgi_request *wsgi_req = current_wsgi_req();
struct uwsgi_buffer *ub = uwsgi_websocket_recv(wsgi_req);
@@ -1003,7 +1010,7 @@ VALUE uwsgi_ruby_websocket_recv(VALUE *class) {
}
VALUE uwsgi_ruby_websocket_recv_nb(VALUE *class) {
static VALUE uwsgi_ruby_websocket_recv_nb(VALUE *class) {
struct wsgi_request *wsgi_req = current_wsgi_req();
struct uwsgi_buffer *ub = uwsgi_websocket_recv_nb(wsgi_req);
@@ -1069,6 +1076,8 @@ void uwsgi_rack_init_api() {
uwsgi_rack_api("set_warning_message", rack_uwsgi_warning, 1);
uwsgi_rack_api("set_user_harakiri", rack_uwsgi_user_harakiri, 1);
uwsgi_rack_api("rpc", uwsgi_ruby_do_rpc, -1);
+4 -4
View File
@@ -141,13 +141,13 @@ static struct uwsgi_buffer *uwsgi_ruby_backtrace(struct wsgi_request *wsgi_req)
// ok let's start the C dance to parse the backtrace
char *colon = strchr(bt, ':');
if (!colon) continue;
filename = uwsgi_concat2n(bt, colon-bt, "", 0);
filename = uwsgi_concat2n(bt, (int) (colon-bt), "", 0);
uint16_t filename_len = colon-bt;
colon++; if (*colon == 0) goto error;
char *lineno_ptr = colon;
colon = strchr(lineno_ptr, ':');
if (!colon) goto error;
int64_t lineno = uwsgi_str_num(lineno_ptr, colon-lineno_ptr);
int64_t lineno = uwsgi_str_num(lineno_ptr, (int) (colon-lineno_ptr));
colon++; if (*colon == 0) goto error;
colon = strchr(lineno_ptr, '`');
if (!colon) goto error;
@@ -155,7 +155,7 @@ static struct uwsgi_buffer *uwsgi_ruby_backtrace(struct wsgi_request *wsgi_req)
char *function_ptr = colon;
char *function_end = strchr(function_ptr, '\'');
if (!function_end) goto error;
function = uwsgi_concat2n(function_ptr, function_end-function_ptr, "", 0);
function = uwsgi_concat2n(function_ptr, (int) (function_end-function_ptr), "", 0);
uint16_t function_len = function_end-function_ptr;
if (uwsgi_buffer_u16le(ub, filename_len)) goto error;
@@ -312,7 +312,7 @@ VALUE init_rack_app(VALUE);
VALUE rack_call_rpc_handler(VALUE args) {
VALUE rpc_args = rb_ary_entry(args, 1);
return rb_funcall2(rb_ary_entry(args, 0), rb_intern("call"), RARRAY_LEN(rpc_args), RARRAY_PTR(rpc_args));
return rb_funcall2(rb_ary_entry(args, 0), rb_intern("call"), (int) RARRAY_LEN(rpc_args), RARRAY_PTR(rpc_args));
}
+6 -4
View File
@@ -112,13 +112,15 @@ static ssize_t rr_xclient_write(struct corerouter_peer *peer) {
if (!len) return 0;
if (cr_write_complete_buf(peer, rr->xclient)) {
if (peer->session->main_peer->out) {
if (peer->session->main_peer->out_pos > 0) {
// (eventually) send previous data
peer->last_hook_read = rr_instance_read;
cr_write_to_main(peer, rr_write);
}
else {
// reset to standard behaviour
cr_reset_hooks(peer);
peer->in->pos = 0;
cr_reset_hooks_and_read(peer, rr_instance_read);
}
}
@@ -140,10 +142,10 @@ static ssize_t rr_xclient_read(struct corerouter_peer *peer) {
return -1;
}
// banner received (skip it, will be sent later)
size_t remains = peer->in->pos - (len - (i+1));
size_t remains = len - (i+1);
if (remains > 0) {
peer->session->main_peer->out = peer->in;
peer->session->main_peer->out_pos = remains;
peer->session->main_peer->out_pos = (peer->in->pos - remains) ;
}
cr_write_to_backend(peer, rr_xclient_write);
return len;
+75
View File
@@ -0,0 +1,75 @@
#include <uwsgi.h>
#ifndef UWSGI_XML_LIBXML2
#error you need a libxml2-enabled build of uWSGI to use the router_xmldir plugin
#endif
#include <libxml/tree.h>
static int uwsgi_routing_func_xmldir(struct wsgi_request *wsgi_req, struct uwsgi_route *ur){
char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
if (!ub) return UWSGI_ROUTE_BREAK;
struct dirent **tasklist;
int n = scandir(ub->buf, &tasklist, 0, versionsort);
uwsgi_buffer_destroy(ub);
if (n < 0) return UWSGI_ROUTE_BREAK;
int i;
xmlDoc *rdoc = xmlNewDoc(BAD_CAST "1.0");
xmlNode *rtree = xmlNewNode(NULL, BAD_CAST "tree");
xmlDocSetRootElement(rdoc, rtree);
for(i=0;i<n;i++) {
if (tasklist[i]->d_name[0] == '.') goto next;
switch (tasklist[i]->d_type) {
case DT_DIR:
xmlNewTextChild(rtree, NULL, BAD_CAST "directory", BAD_CAST tasklist[i]->d_name);
break;
case DT_LNK:
xmlNewTextChild(rtree, NULL, BAD_CAST "link", BAD_CAST tasklist[i]->d_name);
break;
case DT_REG:
xmlNewTextChild(rtree, NULL, BAD_CAST "file", BAD_CAST tasklist[i]->d_name);
break;
default:
xmlNewTextChild(rtree, NULL, BAD_CAST "unknown", BAD_CAST tasklist[i]->d_name);
break;
}
next:
free(tasklist[i]);
}
free(tasklist);
xmlChar *xmlbuf;
int xlen = 0;
xmlDocDumpFormatMemory(rdoc, &xmlbuf, &xlen, 1);
uwsgi_response_prepare_headers(wsgi_req,"200 OK", 6);
uwsgi_response_write_body_do(wsgi_req, (char *) xmlbuf, xlen);
xmlFreeDoc(rdoc);
xmlFree(xmlbuf);
return UWSGI_ROUTE_BREAK;
}
static int uwsgi_router_xmldir(struct uwsgi_route *ur, char *args) {
ur->func = uwsgi_routing_func_xmldir;
ur->data = args;
ur->data_len = strlen(args);
return 0;
}
static void router_xmldir_register() {
uwsgi_register_router("xmldir", uwsgi_router_xmldir);
}
struct uwsgi_plugin router_xmldir_plugin = {
.name = "router_xmldir",
.on_load = router_xmldir_register,
};
+5
View File
@@ -0,0 +1,5 @@
NAME='router_xmldir'
CFLAGS = []
LDFLAGS = []
LIBS = []
GCC_LIST = ['router_xmldir']
+5 -1
View File
@@ -150,6 +150,7 @@ parse:
ssize_t uwsgi_proto_fastcgi_read_body(struct wsgi_request *wsgi_req, char *buf, size_t len) {
int has_read = 0;
if (wsgi_req->proto_parser_remains > 0) {
size_t remains = UMIN(wsgi_req->proto_parser_remains, len);
memcpy(buf, wsgi_req->proto_parser_remains_buf, remains);
@@ -204,12 +205,15 @@ ssize_t uwsgi_proto_fastcgi_read_body(struct wsgi_request *wsgi_req, char *buf,
wsgi_req->proto_parser_buf = tmp_buf;
wsgi_req->proto_parser_buf_size += fcgi_all_len - (wsgi_req->proto_parser_buf_size - wsgi_req->proto_parser_pos);
}
goto gather;
if (!has_read) goto gather;
errno = EAGAIN;
return -1;
}
else {
gather:
rlen = read(wsgi_req->fd, wsgi_req->proto_parser_buf + wsgi_req->proto_parser_pos, wsgi_req->proto_parser_buf_size - wsgi_req->proto_parser_pos);
if (rlen > 0) {
has_read = 1;
wsgi_req->proto_parser_pos += rlen;
continue;
}
+40
View File
@@ -0,0 +1,40 @@
"""
simplified test for continulet without checking for partial writes
to enable continulets you only need to call uwsgi_pypy_setup_continulets() soon after startup:
uwsgi --pypy-wsgi-file t/pypy/t_continulet1.py --http-socket :9090 --pypy-home /opt/pypy --pypy-eval "uwsgi_pypy_setup_continulets()" --async 8
"""
import uwsgi
def application(e, sr):
sr('200 OK', [('Content-Type','text/plain')])
# call suspend 10 times and yield some value
for i in range(0,10):
print i
uwsgi.suspend()
yield str(i)
# connect to a memcached server
fd = uwsgi.async_connect('127.0.0.1:11211')
try:
# start waiting for socket availability (4 seconds max)
uwsgi.wait_fd_write(fd, 4)
# suspend execution 'til event
uwsgi.suspend()
uwsgi.send(fd, "get /foobar\r\n")
# now wait for memcached response
uwsgi.wait_fd_read(fd, 4)
uwsgi.suspend()
# read the response
data = uwsgi.recv(fd, 4096)
# return to the client
yield data
finally:
uwsgi.close(fd)
print "sleeping for 3 seconds..."
uwsgi.async_sleep(3)
uwsgi.suspend()
yield "done"
+47
View File
@@ -0,0 +1,47 @@
"""
safer test for continulet with partial writes check
to enable continulets you only need to call uwsgi_pypy_setup_continulets() soon after startup:
uwsgi --pypy-wsgi-file t/pypy/t_continulet2.py --http-socket :9090 --pypy-home /opt/pypy --pypy-eval "uwsgi_pypy_setup_continulets()" --async 8
"""
import uwsgi
def application(e, sr):
sr('200 OK', [('Content-Type','text/plain')])
# suspend 10 times and yield a value
for i in range(1,10):
print i
uwsgi.suspend()
yield str(i)
# connect to a memcached server
fd = uwsgi.async_connect('127.0.0.1:11211')
try:
command = "get /foobar\r\n"
remains = len(command)
while remains > 0:
# start waiting for socket availability (4 seconds max)
uwsgi.wait_fd_write(fd, 4)
# suspend execution 'til event
uwsgi.suspend()
pos = len(command) - remains
written = uwsgi.send(fd, command[pos:])
remains -= written
# now wait for memcached response
uwsgi.wait_fd_read(fd, 4)
uwsgi.suspend()
# read a chunk of data
data = uwsgi.recv(fd, 4096)
# .. and yield it
yield data
finally:
# always ensure sockets are closed
uwsgi.close(fd)
print "sleeping for 3 seconds..."
uwsgi.async_sleep(3)
uwsgi.suspend()
yield "done"
+14
View File
@@ -0,0 +1,14 @@
import socket
import sys
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
(addr, port) = sys.argv[1].split(':')
s.connect((addr, int(port)))
s.send("POST /send HTTP/1.1\r\n")
s.send("Transfer-Encoding: chunked\r\n\r\n")
while True:
msg = raw_input("msg >> ")
s.send("%X\r\n%s\r\n" % (len(msg), msg))
+81
View File
@@ -0,0 +1,81 @@
#!./uwsgi --http-socket :9090 --async 100 ...
# same chat example but using uwsgi async api
# for pypy + continulets just run:
# uwsgi --http-socket :9090 --pypy-home /opt/pypy --pypy-wsgi-file tests/websockets_chat_async.py --pypy-eval "uwsgi_pypy_setup_continulets()" --async 100
import uwsgi
import time
import redis
def application(env, sr):
ws_scheme = 'ws'
if 'HTTPS' in env or env['wsgi.url_scheme'] == 'https':
ws_scheme = 'wss'
if env['PATH_INFO'] == '/':
sr('200 OK', [('Content-Type','text/html')])
return """
<html>
<head>
<script language="Javascript">
var s = new WebSocket("%s://%s/foobar/");
s.onopen = function() {
alert("connected !!!");
s.send("ciao");
};
s.onmessage = function(e) {
var bb = document.getElementById('blackboard')
var html = bb.innerHTML;
bb.innerHTML = html + '<br/>' + e.data;
};
s.onerror = function(e) {
alert(e);
}
s.onclose = function(e) {
alert("connection closed");
}
function invia() {
var value = document.getElementById('testo').value;
s.send(value);
}
</script>
</head>
<body>
<h1>WebSocket</h1>
<input type="text" id="testo"/>
<input type="button" value="invia" onClick="invia();"/>
<div id="blackboard" style="width:640px;height:480px;background-color:black;color:white;border: solid 2px red;overflow:auto">
</div>
</body>
</html>
""" % (ws_scheme, env['HTTP_HOST'])
elif env['PATH_INFO'] == '/favicon.ico':
return ""
elif env['PATH_INFO'] == '/foobar/':
uwsgi.websocket_handshake(env['HTTP_SEC_WEBSOCKET_KEY'], env.get('HTTP_ORIGIN', ''))
print "websockets..."
r = redis.StrictRedis(host='localhost', port=6379, db=0)
channel = r.pubsub()
channel.subscribe('foobar')
websocket_fd = uwsgi.connection_fd()
redis_fd = channel.connection._sock.fileno()
while True:
uwsgi.wait_fd_read(websocket_fd)
uwsgi.wait_fd_read(redis_fd)
uwsgi.suspend()
fd = uwsgi.ready_fd()
if fd > -1:
if fd == websocket_fd:
msg = uwsgi.websocket_recv_nb()
if msg:
r.publish('foobar', msg)
elif fd == redis_fd:
msg = channel.parse_response()
# only interested in user messages
if msg[0] == 'message':
uwsgi.websocket_send("[%s] %s" % (time.time(), msg))
+26 -5
View File
@@ -218,11 +218,6 @@ extern "C" {
#include <sys/prctl.h>
#include <linux/limits.h>
#include <sys/mount.h>
#ifdef UWSGI_PTRACE
#include <sys/ptrace.h>
#include <sys/user.h>
#include <sys/reg.h>
#endif
extern int pivot_root(const char *new_root, const char *put_old);
#endif
@@ -1050,6 +1045,7 @@ struct uwsgi_spooler {
uint64_t tasks;
struct uwsgi_lock_item *lock;
time_t harakiri;
time_t user_harakiri;
int mode;
@@ -1433,6 +1429,12 @@ struct wsgi_request {
time_t websocket_last_pong;
int websocket_closed;
struct uwsgi_buffer *chunked_input_buf;
uint8_t chunked_input_parser_status;
ssize_t chunked_input_chunk_len;
size_t chunked_input_need;
uint8_t chunked_input_complete;
uint64_t stream_id;
// avoid routing loops
@@ -1877,6 +1879,8 @@ struct uwsgi_server {
struct uwsgi_regexp_list *log_req_route;
#endif
int use_abort;
int alarm_freq;
uint64_t alarm_msg_size;
struct uwsgi_string_list *alarm_list;
@@ -2246,6 +2250,7 @@ struct uwsgi_server {
size_t lock_size;
size_t rwlock_size;
struct uwsgi_string_list *add_cache_item;
struct uwsgi_string_list *load_file_in_cache;
#ifdef UWSGI_ZLIB
struct uwsgi_string_list *load_file_in_cache_gzip;
@@ -2348,6 +2353,9 @@ struct uwsgi_server {
int websockets_pong_tolerance;
uint64_t websockets_max_size;
int chunked_input_timeout;
uint64_t chunked_input_limit;
int (*wait_write_hook) (int, int);
int (*wait_read_hook) (int, int);
@@ -2577,6 +2585,7 @@ struct uwsgi_mule {
uint8_t signum;
time_t harakiri;
time_t user_harakiri;
char name[0xff];
};
@@ -3501,9 +3510,13 @@ char *uwsgi_substitute(char *, char *, char *);
void uwsgi_opt_add_custom_option(char *, char *, void *);
void uwsgi_opt_cflags(char *, char *, void *);
void uwsgi_opt_dot_h(char *, char *, void *);
void uwsgi_opt_connect_and_read(char *, char *, void *);
void uwsgi_opt_extract(char *, char *, void *);
char *uwsgi_get_dot_h();
char *uwsgi_get_cflags();
struct uwsgi_string_list *uwsgi_string_list_has_item(struct uwsgi_string_list *, char *, size_t);
void trigger_harakiri(int);
@@ -3867,6 +3880,8 @@ int uwsgi_websocket_send(struct wsgi_request *, char *, size_t);
struct uwsgi_buffer *uwsgi_websocket_recv(struct wsgi_request *);
struct uwsgi_buffer *uwsgi_websocket_recv_nb(struct wsgi_request *);
char *uwsgi_chunked_read(struct wsgi_request *, size_t *, int, int);
uint16_t uwsgi_be16(char *);
uint32_t uwsgi_be32(char *);
uint64_t uwsgi_be64(char *);
@@ -4010,9 +4025,11 @@ int uwsgi_emperor_vassal_start(struct uwsgi_instance *);
#ifdef UWSGI_ZLIB
#include <zlib.h>
int uwsgi_deflate_init(z_stream *, char *, size_t);
int uwsgi_inflate_init(z_stream *, char *, size_t);
char *uwsgi_deflate(z_stream *, char *, size_t, size_t *);
void uwsgi_crc32(uint32_t *, char *, size_t);
struct uwsgi_buffer *uwsgi_gzip(char *, size_t);
struct uwsgi_buffer *uwsgi_zlib_decompress(char *, size_t);
int uwsgi_gzip_fix(z_stream *, uint32_t, struct uwsgi_buffer *, size_t);
char *uwsgi_gzip_chunk(z_stream *, uint32_t *, char *, size_t, size_t *);
int uwsgi_gzip_prepare(z_stream *, char *, size_t, uint32_t *);
@@ -4055,6 +4072,10 @@ void uwsgi_takeover(void);
char *uwsgi_binary_path(void);
int uwsgi_is_again();
void uwsgi_disconnect(struct wsgi_request *);
int uwsgi_ready_fd(struct wsgi_request *);
void uwsgi_check_emperor(void);
#ifdef UWSGI_AS_SHARED_LIBRARY
int uwsgi_init(int, char **, char **);
-55
View File
@@ -1,55 +0,0 @@
send_message()
send_multi_message()
reload()
workers()
masterpid()
total_requests()
getoption(id)
get_option(id)
setoption(id, value)
set_option(id, value)
sorry_i_need_to_block()
request_id()
worker_id()
log(message)
disconnect()
grunt()
load_plugin()
lock()
unlock()
send()
cl()
req_fd()
signal(num)
sendfile()
set_warning_message()
mem()
has_hook()
logsize()
send_multicast_message
cluster_nodes
cluster_best_node
async_sleep
async_connect
async_send_message
green_schedule
suspend
wait_fd_read(fd, [timeout])
wait_fd_write(fd, timeout)
is_connected()
send
recv()
recv_block
recv_frame
close
parsefile
sharedarea_read
sharedarea_write
sharedarea_readbyte
sharedarea_writebyte
sharedarea_readlong
sharedarea_writelong
sharedarea_inclong
register_signal(num, targer, handler)
register_rpc(name, func[,args])
rpc(node, name[,args,...])
+61 -12
View File
@@ -1,6 +1,6 @@
# uWSGI build system
uwsgi_version = '1.9.12'
uwsgi_version = '1.9.13'
import os
import re
@@ -25,13 +25,17 @@ try:
import ConfigParser
except:
import configparser as ConfigParser
from imp import reload
GCC = os.environ.get('CC', sysconfig.get_config_var('CC'))
if not GCC:
GCC = 'gcc'
CPP = os.environ.get('CPP', 'cpp')
def get_preprocessor():
if 'clang' in GCC:
return 'clang -xc core/clang_fake.c'
return 'cpp'
CPP = os.environ.get('CPP', get_preprocessor())
try:
CPUCOUNT = int(os.environ.get('CPUCOUNT', -1))
@@ -245,11 +249,11 @@ def build_uwsgi(uc, print_only=False):
print("detected CPU cores: %d" % CPUCOUNT)
print("configured CFLAGS: %s" % ' '.join(cflags))
try:
uwsgi_cflags = ' '.join(cflags).encode('hex')
except:
if sys.version_info[0] >= 3:
import binascii
uwsgi_cflags = binascii.b2a_hex(' '.join(cflags).encode('ascii')).decode('ascii')
else:
uwsgi_cflags = ' '.join(cflags).encode('hex')
last_cflags_ts = 0
@@ -267,6 +271,27 @@ def build_uwsgi(uc, print_only=False):
ulc.write(uwsgi_cflags)
ulc.close()
# embed uwsgi.h in the server binary. It increases the binary size, but will be very useful
# for various tricks (like cffi integration)
# if possibile, the blob is compressed
if sys.version_info[0] >= 3:
uwsgi_dot_h_content = open('uwsgi.h', 'rb').read()
else:
uwsgi_dot_h_content = open('uwsgi.h').read()
if report['zlib']:
import zlib
# maximum level of compression
uwsgi_dot_h_content = zlib.compress(uwsgi_dot_h_content, 9)
if sys.version_info[0] >= 3:
import binascii
uwsgi_dot_h = binascii.b2a_hex(uwsgi_dot_h_content).decode('ascii')
else:
uwsgi_dot_h = uwsgi_dot_h_content.encode('hex')
open('core/dot_h.c', 'w').write('char *uwsgi_dot_h = "%s";\n' % uwsgi_dot_h);
gcc_list.append('core/dot_h')
cflags.append('-DUWSGI_CFLAGS=\\"%s\\"' % uwsgi_cflags)
cflags.append('-DUWSGI_BUILD_DATE="\\"%s\\""' % time.strftime("%d %B %Y %H:%M:%S"))
@@ -317,6 +342,13 @@ def build_uwsgi(uc, print_only=False):
except:
pass
if GCC in ('clang',):
try:
p_cflags.remove('-fno-fast-math')
p_cflags.remove('-ggdb3')
except:
pass
try:
p_cflags.remove('-Wdeclaration-after-statement')
except:
@@ -456,6 +488,8 @@ def open_profile(filename):
class uConf(object):
def __init__(self, filename, mute=False):
global GCC
self.config = ConfigParser.ConfigParser()
if not mute:
print("using profile: %s" % filename)
@@ -476,7 +510,7 @@ class uConf(object):
'core/notify', 'core/mule', 'core/subscription', 'core/stats', 'core/sendfile', 'core/async', 'core/master_checks',
'core/offload', 'core/io', 'core/static', 'core/websockets', 'core/spooler', 'core/snmp', 'core/exceptions', 'core/config',
'core/setup_utils', 'core/clock', 'core/init', 'core/buffer', 'core/reader', 'core/writer', 'core/alarm', 'core/cron',
'core/plugins', 'core/lock', 'core/cache', 'core/daemons', 'core/errors', 'core/hash', 'core/master_events',
'core/plugins', 'core/lock', 'core/cache', 'core/daemons', 'core/errors', 'core/hash', 'core/master_events', 'core/chunked',
'core/queue', 'core/event', 'core/signal', 'core/strings', 'core/progress', 'core/timebomb', 'core/ini',
'core/rpc', 'core/gateway', 'core/loop', 'core/cookie', 'core/querystring', 'core/rb_timers', 'core/transformations', 'core/uwsgi']
# add protocols
@@ -487,6 +521,10 @@ class uConf(object):
self.gcc_list.append('proto/scgi')
self.include_path = []
if 'UWSGI_INCLUDES' in os.environ:
self.include_path += os.environ['UWSGI_INCLUDES'].split(',')
self.cflags = ['-O2', '-I.', '-Wall', '-Werror', '-D_LARGEFILE_SOURCE', '-D_FILE_OFFSET_BITS=64'] + os.environ.get("CFLAGS", "").split() + self.get('cflags','').split()
report['kernel'] = uwsgi_os
@@ -504,11 +542,13 @@ class uConf(object):
if uwsgi_os == 'GNU':
self.cflags.append('-D__HURD__')
try:
gcc_version = str(spcall("%s -dumpversion" % GCC))
except:
print("*** you need a c compiler to build uWSGI ***")
sys.exit(1)
gcc_version = spcall("%s -dumpversion" % GCC)
if not gcc_version and GCC.startswith('gcc'):
if uwsgi_os == 'Darwin':
GCC = 'llvm-' + GCC
else:
GCC = 'gcc'
gcc_version = spcall("%s -dumpversion" % GCC)
try:
add_it = False
@@ -655,6 +695,8 @@ class uConf(object):
if uwsgi_os == 'Darwin':
self.cflags.append('-mmacosx-version-min=10.5')
if GCC in ('clang',):
self.libs.remove('-rdynamic')
# compile extras
extras = self.get('extras', None)
@@ -1197,6 +1239,13 @@ def build_plugin(path, uc, cflags, ldflags, libs, name = None):
except:
pass
if GCC in ('clang',):
try:
p_cflags.remove('-fno-fast-math')
p_cflags.remove('-ggdb3')
except:
pass
if uwsgi_os.startswith('CYGWIN'):
try:
p_cflags.remove('-fstack-protector')
+19 -24
View File
@@ -1,4 +1,3 @@
import uwsgi
import sys
from threading import Thread
@@ -7,6 +6,7 @@ try:
except:
import pickle
import uwsgi
if uwsgi.masterpid() == 0:
raise Exception(
@@ -45,48 +45,43 @@ class postfork(object):
postfork_chain.append(f)
class spool(object):
class spoolraw(object):
def spool(self, *args, **kwargs):
def __call__(self, *args, **kwargs):
arguments = self.base_dict
arguments['ud_spool_ret'] = str(uwsgi.SPOOL_OK)
if len(args) > 0:
arguments.update(args[0])
if kwargs:
arguments.update(kwargs)
return uwsgi.spool(arguments)
# For backward compatibility (uWSGI < 1.9.13)
def spool(self, *args, **kwargs):
return self.__class__.__call__(self, *args, **kwargs)
def __init__(self, f):
if not 'spooler' in uwsgi.opt:
raise Exception(
"you have to enable the uWSGI spooler to use @spool decorator")
"you have to enable the uWSGI spooler to use @%s decorator" % self.__class__.__name__)
self.f = f
spooler_functions[f.__name__] = self.f
self.f.spool = self.spool
spooler_functions[self.f.__name__] = self.f
# For backward compatibility (uWSGI < 1.9.13)
self.f.spool = self.__call__
self.base_dict = {'ud_spool_func': self.f.__name__}
class spoolforever(spool):
class spool(spoolraw):
def spool(self, *args, **kwargs):
arguments = self.base_dict
arguments['ud_spool_ret'] = str(uwsgi.SPOOL_RETRY)
if len(args) > 0:
arguments.update(args[0])
if kwargs:
arguments.update(kwargs)
return uwsgi.spool(arguments)
def __call__(self, *args, **kwargs):
self.base_dict['ud_spool_ret'] = str(uwsgi.SPOOL_OK)
return spoolraw.__call__(self, *args, **kwargs)
class spoolraw(spool):
class spoolforever(spoolraw):
def spool(self, *args, **kwargs):
arguments = self.base_dict
if len(args) > 0:
arguments.update(args[0])
if kwargs:
arguments.update(kwargs)
return uwsgi.spool(arguments)
def __call__(self, *args, **kwargs):
self.base_dict['ud_spool_ret'] = str(uwsgi.SPOOL_RETRY)
return spoolraw.__call__(self, *args, **kwargs)
class mulefunc(object):