mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-10-04 16:08:31 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ccf298a148 | ||
|
|
914b600af4 | ||
|
|
4944994667 | ||
|
|
3a487578a5 | ||
|
|
39eeccb16a | ||
|
|
32acd3b9d1 | ||
|
|
c57baae477 | ||
|
|
4a6ed633b9 | ||
|
|
2ab1845547 | ||
|
|
f4d2e1f20c | ||
|
|
81dca1f690 | ||
|
|
2b331fd68f | ||
|
|
cc77e4dba7 | ||
|
|
620a13a308 | ||
|
|
42d4ba09d7 | ||
|
|
ca071fa52f | ||
|
|
d38e5dec7b | ||
|
|
e5db38f7c0 | ||
|
|
68a29730c0 | ||
|
|
5c33c4d341 | ||
|
|
a1d6270089 | ||
|
|
1968175b00 | ||
|
|
cf1e2aeeba | ||
|
|
199b0b9f57 | ||
|
|
87a0daa465 | ||
|
|
c2af90b58f | ||
|
|
62f01453af | ||
|
|
375d6ee331 | ||
|
|
222ca2915b | ||
|
|
5ca848f9fe | ||
|
|
68d878ff6b | ||
|
|
782a7b418a | ||
|
|
724d7854ad | ||
|
|
f8e64d17e8 | ||
|
|
3b40799000 | ||
|
|
709964ca92 | ||
|
|
d2cdedc610 | ||
|
|
b7d0730343 | ||
|
|
30b4ea7d49 | ||
|
|
546dadbd06 | ||
|
|
76edf902de | ||
|
|
068024134c | ||
|
|
538ab57b6e | ||
|
|
fd6d9148f3 | ||
|
|
f033f59755 | ||
|
|
7168c6dd69 | ||
|
|
f121d41c2f | ||
|
|
e56e774eac | ||
|
|
6d9b0918a3 | ||
|
|
d445418611 | ||
|
|
6d15a51c9a | ||
|
|
42a615efdd | ||
|
|
54cd1f79a6 | ||
|
|
8ed8f46374 | ||
|
|
dd3a2996a4 | ||
|
|
bf1f90a96a | ||
|
|
2d6200231a | ||
|
|
032cd23304 | ||
|
|
de4c0a9e1c | ||
|
|
e33f8e8920 | ||
|
|
22615c7921 | ||
|
|
9d8809c580 | ||
|
|
96b92c98ff | ||
|
|
07939acecd | ||
|
|
30abcb2563 | ||
|
|
35ce8f2b8d | ||
|
|
d6453eab38 | ||
|
|
e0964d07ea | ||
|
|
fc359f1956 | ||
|
|
322261d65d | ||
|
|
bd1163c439 | ||
|
|
e203a8c706 | ||
|
|
6a1ba2af74 | ||
|
|
22569e64df | ||
|
|
dcafe41cde | ||
|
|
dd2adc08a3 | ||
|
|
d7534d2673 | ||
|
|
0a59920025 | ||
|
|
77602a8de4 | ||
|
|
65b3fde97c | ||
|
|
b690148452 | ||
|
|
4c7bc9ada6 | ||
|
|
432651489f | ||
|
|
82aa232a37 | ||
|
|
19b13bf7a7 | ||
|
|
f7e25d807d | ||
|
|
cf05316b95 | ||
|
|
001c4386b5 | ||
|
|
572527f8cb | ||
|
|
b4252beda6 |
@@ -0,0 +1,3 @@
|
||||
[uwsgi]
|
||||
main_plugin = python,gevent,psgi,lua,php,rack,jvm,jwsgi,ring,mono,transformation_toupper,coroae,v8,cgi
|
||||
inherit = base
|
||||
+1
-1
@@ -16,7 +16,7 @@ plugins =
|
||||
bin_name = uwsgi
|
||||
append_version =
|
||||
plugin_dir = .
|
||||
embedded_plugins = %(main_plugin)s, ping, cache, nagios, rrdtool, carbon, rpc, corerouter, fastrouter, http, ugreen, signal, syslog, rsyslog, logsocket, router_uwsgi, router_redirect, router_basicauth, zergpool, redislog, mongodblog, router_rewrite, router_http, logfile, router_cache, rawrouter, router_static, sslrouter
|
||||
embedded_plugins = %(main_plugin)s, ping, cache, nagios, rrdtool, carbon, rpc, corerouter, fastrouter, http, ugreen, signal, syslog, rsyslog, logsocket, router_uwsgi, router_redirect, router_basicauth, zergpool, redislog, mongodblog, router_rewrite, router_http, logfile, router_cache, rawrouter, router_static, sslrouter, spooler, cheaper_busyness, symcall, transformation_tofile, transformation_gzip
|
||||
as_shared_library = false
|
||||
|
||||
locking = auto
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
the uwsgi handler is included in the official Cherokee distribution
|
||||
+139
-10
@@ -11,6 +11,29 @@ void uwsgi_alarm_func_signal(struct uwsgi_alarm_instance *uai, char *msg, size_t
|
||||
uwsgi_route_signal(uai->data8);
|
||||
}
|
||||
|
||||
// simply log an alarm
|
||||
void uwsgi_alarm_init_log(struct uwsgi_alarm_instance *uai) {
|
||||
}
|
||||
|
||||
void uwsgi_alarm_func_log(struct uwsgi_alarm_instance *uai, char *msg, size_t len) {
|
||||
if (msg[len-1] != '\n') {
|
||||
if (uai->arg && strlen(uai->arg) > 0) {
|
||||
uwsgi_log_alarm("] %s %.*s\n", uai->arg, len, msg);
|
||||
}
|
||||
else {
|
||||
uwsgi_log_alarm("] %.*s\n", len, msg);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (uai->arg && strlen(uai->arg) > 0) {
|
||||
uwsgi_log_alarm("] %s %.*s", uai->arg, len, msg);
|
||||
}
|
||||
else {
|
||||
uwsgi_log_alarm("] %.*s", len, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// run a command on alarm
|
||||
void uwsgi_alarm_init_cmd(struct uwsgi_alarm_instance *uai) {
|
||||
uai->data_ptr = uai->arg;
|
||||
@@ -86,6 +109,7 @@ void uwsgi_register_embedded_alarms() {
|
||||
uwsgi_register_alarm("signal", uwsgi_alarm_init_signal, uwsgi_alarm_func_signal);
|
||||
uwsgi_register_alarm("cmd", uwsgi_alarm_init_cmd, uwsgi_alarm_func_cmd);
|
||||
uwsgi_register_alarm("mule", uwsgi_alarm_init_mule, uwsgi_alarm_func_mule);
|
||||
uwsgi_register_alarm("log", uwsgi_alarm_init_log, uwsgi_alarm_func_log);
|
||||
}
|
||||
|
||||
static int uwsgi_alarm_add(char *name, char *plugin, char *arg) {
|
||||
@@ -189,21 +213,54 @@ static int uwsgi_alarm_log_add(char *alarms, char *regexp, int negate) {
|
||||
#endif
|
||||
|
||||
static void uwsgi_alarm_thread_loop(struct uwsgi_thread *ut) {
|
||||
// add uwsgi_alarm_fd;
|
||||
struct uwsgi_alarm_fd *uafd = uwsgi.alarm_fds;
|
||||
while(uafd) {
|
||||
event_queue_add_fd_read(ut->queue, uafd->fd);
|
||||
uafd = uafd->next;
|
||||
}
|
||||
char *buf = uwsgi_malloc(uwsgi.alarm_msg_size + sizeof(long));
|
||||
for (;;) {
|
||||
int interesting_fd = -1;
|
||||
int ret = event_queue_wait(ut->queue, -1, &interesting_fd);
|
||||
if (ret > 0) {
|
||||
ssize_t len = read(ut->pipe[1], buf, uwsgi.alarm_msg_size + sizeof(long));
|
||||
if (len > (ssize_t)(sizeof(long) + 1)) {
|
||||
size_t msg_size = len - sizeof(long);
|
||||
char *msg = buf + sizeof(long);
|
||||
long ptr = 0;
|
||||
memcpy(&ptr, buf, sizeof(long));
|
||||
struct uwsgi_alarm_instance *uai = (struct uwsgi_alarm_instance *) ptr;
|
||||
if (!uai)
|
||||
break;
|
||||
uwsgi_alarm_run(uai, msg, msg_size);
|
||||
if (interesting_fd == ut->pipe[1]) {
|
||||
ssize_t len = read(ut->pipe[1], buf, uwsgi.alarm_msg_size + sizeof(long));
|
||||
if (len > (ssize_t)(sizeof(long) + 1)) {
|
||||
size_t msg_size = len - sizeof(long);
|
||||
char *msg = buf + sizeof(long);
|
||||
long ptr = 0;
|
||||
memcpy(&ptr, buf, sizeof(long));
|
||||
struct uwsgi_alarm_instance *uai = (struct uwsgi_alarm_instance *) ptr;
|
||||
if (!uai)
|
||||
break;
|
||||
uwsgi_alarm_run(uai, msg, msg_size);
|
||||
}
|
||||
}
|
||||
// check for alarm_fd
|
||||
else {
|
||||
uafd = uwsgi.alarm_fds;
|
||||
int fd_read = 0;
|
||||
while(uafd) {
|
||||
if (interesting_fd == uafd->fd) {
|
||||
if (fd_read) goto raise;
|
||||
size_t remains = uafd->buf_len;
|
||||
while(remains) {
|
||||
ssize_t len = read(uafd->fd, uafd->buf + (uafd->buf_len-remains), remains);
|
||||
if (len <= 0) {
|
||||
uwsgi_error("[uwsgi-alarm-fd]/read()");
|
||||
uwsgi_log("[uwsgi-alarm-fd] i will stop monitoring fd %d\n", uafd->fd);
|
||||
event_queue_del_fd(ut->queue, uafd->fd, event_queue_read());
|
||||
break;
|
||||
}
|
||||
remains-=len;
|
||||
}
|
||||
fd_read = 1;
|
||||
raise:
|
||||
uwsgi_alarm_run(uafd->alarm, uafd->msg, uafd->msg_len);
|
||||
}
|
||||
uafd = uafd->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -243,6 +300,37 @@ void uwsgi_alarms_init() {
|
||||
|
||||
if (!uwsgi.alarm_instances) return;
|
||||
|
||||
// map alarm file descriptors
|
||||
usl = uwsgi.alarm_fd_list;
|
||||
while(usl) {
|
||||
char *space0 = strchr(usl->value, ' ');
|
||||
if (!space0) {
|
||||
uwsgi_log("invalid alarm-fd syntax: %s\n", usl->value);
|
||||
exit(1);
|
||||
}
|
||||
*space0 = 0;
|
||||
size_t buf_len = 1;
|
||||
char *space1 = strchr(space0+1, ' ');
|
||||
if (!space1) {
|
||||
uwsgi_log("invalid alarm-fd syntax: %s\n", usl->value);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char *colon = strchr(space0+1, ':');
|
||||
if (colon) {
|
||||
buf_len = strtoul(colon+1, NULL, 10);
|
||||
*colon = 0;
|
||||
}
|
||||
int fd = atoi(space0+1);
|
||||
uwsgi_add_alarm_fd(fd, usl->value, buf_len, space1+1, strlen(space1+1));
|
||||
*space0 = ' ';
|
||||
*space1 = ' ';
|
||||
if (colon) {
|
||||
*colon = ':';
|
||||
}
|
||||
usl = usl->next;
|
||||
}
|
||||
|
||||
#ifdef UWSGI_PCRE
|
||||
// then map log-alarm
|
||||
usl = uwsgi.alarm_logs_list;
|
||||
@@ -340,3 +428,44 @@ void uwsgi_alarm_trigger(char *alarm_instance_name, char *msg, size_t len) {
|
||||
uwsgi_error("[uwsgi-alarm-error] uwsgi_alarm_trigger()/writev()");
|
||||
}
|
||||
}
|
||||
|
||||
struct uwsgi_alarm_fd *uwsgi_add_alarm_fd(int fd, char *alarm, size_t buf_len, char *msg, size_t msg_len) {
|
||||
struct uwsgi_alarm_fd *old_uafd = NULL, *uafd = uwsgi.alarm_fds;
|
||||
struct uwsgi_alarm_instance *uai = uwsgi_alarm_get_instance(alarm);
|
||||
if (!uai) {
|
||||
uwsgi_log("unable to find alarm \"%s\"\n", alarm);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!buf_len) buf_len = 1;
|
||||
|
||||
while(uafd) {
|
||||
// check if an equal alarm has been added
|
||||
if (uafd->fd == fd && uafd->alarm == uai) {
|
||||
return uafd;
|
||||
}
|
||||
old_uafd = uafd;
|
||||
uafd = uafd->next;
|
||||
}
|
||||
|
||||
uafd = uwsgi_calloc(sizeof(struct uwsgi_alarm_fd));
|
||||
uafd->fd = fd;
|
||||
uafd->buf = uwsgi_malloc(buf_len);
|
||||
uafd->buf_len = buf_len;
|
||||
uafd->msg = msg;
|
||||
uafd->msg_len = msg_len;
|
||||
uafd->alarm = uai;
|
||||
|
||||
if (!old_uafd) {
|
||||
uwsgi.alarm_fds = uafd;
|
||||
}
|
||||
else {
|
||||
old_uafd->next = uafd;
|
||||
}
|
||||
|
||||
// avoid the fd to be closed
|
||||
uwsgi_add_safe_fd(fd);
|
||||
uwsgi_log("[uwsgi-alarm] added fd %d\n", fd);
|
||||
|
||||
return uafd;
|
||||
}
|
||||
|
||||
+11
-16
@@ -52,7 +52,7 @@ static void runqueue_remove(struct uwsgi_async_request *u_request) {
|
||||
child->prev = parent;
|
||||
}
|
||||
|
||||
if (parent == NULL) {
|
||||
if (u_request == uwsgi.async_runqueue) {
|
||||
uwsgi.async_runqueue = child;
|
||||
}
|
||||
|
||||
@@ -67,25 +67,22 @@ static void runqueue_remove(struct uwsgi_async_request *u_request) {
|
||||
|
||||
static void runqueue_push(struct wsgi_request *wsgi_req) {
|
||||
|
||||
struct uwsgi_async_request *uar;
|
||||
struct uwsgi_async_request *uar = uwsgi_malloc(sizeof(struct uwsgi_async_request));
|
||||
uar->prev = NULL;
|
||||
uar->next = NULL;
|
||||
uar->wsgi_req = wsgi_req;
|
||||
|
||||
if (uwsgi.async_runqueue == NULL) {
|
||||
// empty runqueue, create a new one
|
||||
uwsgi.async_runqueue = uwsgi_malloc(sizeof(struct uwsgi_async_request));
|
||||
uwsgi.async_runqueue->next = NULL;
|
||||
uwsgi.async_runqueue->prev = NULL;
|
||||
uwsgi.async_runqueue->wsgi_req = wsgi_req;
|
||||
uwsgi.async_runqueue_last = uwsgi.async_runqueue;
|
||||
uwsgi.async_runqueue = uar;
|
||||
}
|
||||
else {
|
||||
uar = uwsgi_malloc(sizeof(struct uwsgi_async_request));
|
||||
uar->prev = uwsgi.async_runqueue_last;
|
||||
uar->next = NULL;
|
||||
uar->wsgi_req = wsgi_req;
|
||||
uwsgi.async_runqueue_last->next = uar;
|
||||
uwsgi.async_runqueue_last = uar;
|
||||
uar->prev = uwsgi.async_runqueue_last;
|
||||
}
|
||||
|
||||
if (uwsgi.async_runqueue_last) {
|
||||
uwsgi.async_runqueue_last->next = uar;
|
||||
}
|
||||
uwsgi.async_runqueue_last = uar;
|
||||
uwsgi.async_runqueue_cnt++;
|
||||
|
||||
}
|
||||
@@ -393,8 +390,6 @@ void async_loop() {
|
||||
continue;
|
||||
}
|
||||
else if (proto_parser_status < 0) {
|
||||
if (proto_parser_status == -1)
|
||||
uwsgi_log("error parsing request\n");
|
||||
uwsgi.async_proto_fd_table[interesting_fd] = NULL;
|
||||
close(interesting_fd);
|
||||
continue;
|
||||
|
||||
+86
-12
@@ -156,14 +156,14 @@ static void cache_send_udp_command(struct uwsgi_cache *, char *, uint16_t, char
|
||||
static void cache_sync_hook(char *k, uint16_t kl, char *v, uint16_t vl, void *data) {
|
||||
struct uwsgi_cache *uc = (struct uwsgi_cache *) data;
|
||||
if (!uwsgi_strncmp(k, kl, "items", 5)) {
|
||||
size_t num = uwsgi_str_num(v, vl);
|
||||
size_t num = uwsgi_str_num(v, vl);
|
||||
if (num != uc->max_items) {
|
||||
uwsgi_log("[cache-sync] invalid cache size, expected %llu received %llu\n", (unsigned long long) uc->max_items, (unsigned long long) num);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (!uwsgi_strncmp(k, kl, "blocksize", 9)) {
|
||||
size_t num = uwsgi_str_num(v, vl);
|
||||
size_t num = uwsgi_str_num(v, vl);
|
||||
if (num != uc->blocksize) {
|
||||
uwsgi_log("[cache-sync] invalid cache block size, expected %llu received %llu\n", (unsigned long long) uc->blocksize, (unsigned long long) num);
|
||||
exit(1);
|
||||
@@ -200,6 +200,40 @@ static void uwsgi_cache_load_files(struct uwsgi_cache *uc) {
|
||||
next:
|
||||
usl = usl->next;
|
||||
}
|
||||
|
||||
#ifdef UWSGI_ZLIB
|
||||
usl = uwsgi.load_file_in_cache_gzip;
|
||||
while(usl) {
|
||||
size_t len = 0;
|
||||
char *value = NULL;
|
||||
char *key = usl->value;
|
||||
uint16_t key_len = usl->len;
|
||||
char *space = strchr(usl->value, ' ');
|
||||
if (space) {
|
||||
// need to skip ?
|
||||
if (uwsgi_strncmp(uc->name, uc->name_len, usl->value, space-usl->value)) {
|
||||
goto next2;
|
||||
}
|
||||
key = space+1;
|
||||
key_len = usl->len - ((space-usl->value)+1);
|
||||
}
|
||||
value = uwsgi_open_and_read(key, &len, 0, NULL);
|
||||
if (value) {
|
||||
struct uwsgi_buffer *gzipped = uwsgi_gzip(value, len);
|
||||
if (gzipped) {
|
||||
uwsgi_wlock(uc->lock);
|
||||
if (!uwsgi_cache_set2(uc, key, key_len, gzipped->buf, gzipped->len, 0, 0)) {
|
||||
uwsgi_log("[cache-gzip] stored \"%.*s\" in \"%s\"\n", key_len, key, uc->name);
|
||||
}
|
||||
uwsgi_rwunlock(uc->lock);
|
||||
uwsgi_buffer_destroy(gzipped);
|
||||
}
|
||||
free(value);
|
||||
}
|
||||
next2:
|
||||
usl = usl->next;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -382,6 +416,28 @@ char *uwsgi_cache_get2(struct uwsgi_cache *uc, char *key, uint16_t keylen, uint6
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *uwsgi_cache_get3(struct uwsgi_cache *uc, char *key, uint16_t keylen, uint64_t * valsize, uint64_t *expires) {
|
||||
|
||||
uint64_t index = uwsgi_cache_get_index(uc, key, keylen);
|
||||
|
||||
if (index) {
|
||||
struct uwsgi_cache_item *uci = cache_item(index);
|
||||
if (uci->flags & UWSGI_CACHE_FLAG_UNGETTABLE)
|
||||
return NULL;
|
||||
*valsize = uci->valsize;
|
||||
if (expires)
|
||||
*expires = uci->expires;
|
||||
uci->hits++;
|
||||
uc->hits++;
|
||||
return uc->data + (uci->first_block * uc->blocksize);
|
||||
}
|
||||
|
||||
uc->miss++;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int uwsgi_cache_del2(struct uwsgi_cache *uc, char *key, uint16_t keylen, uint64_t index, uint16_t flags) {
|
||||
|
||||
struct uwsgi_cache_item *uci;
|
||||
@@ -427,6 +483,10 @@ int uwsgi_cache_del2(struct uwsgi_cache *uc, char *key, uint16_t keylen, uint64_
|
||||
uci->expires = 0;
|
||||
|
||||
uc->n_items--;
|
||||
|
||||
if (uc->use_last_modified) {
|
||||
uc->last_modified_at = uwsgi_now();
|
||||
}
|
||||
}
|
||||
|
||||
if (uc->nodes && ret == 0 && !(flags & UWSGI_CACHE_FLAG_LOCAL)) {
|
||||
@@ -473,6 +533,7 @@ int uwsgi_cache_set2(struct uwsgi_cache *uc, char *key, uint16_t keylen, char *v
|
||||
uint8_t rollback_mode = 0;
|
||||
|
||||
int ret = -1;
|
||||
time_t now = 0;
|
||||
|
||||
if (!keylen || !vallen)
|
||||
return -1;
|
||||
@@ -518,13 +579,13 @@ int uwsgi_cache_set2(struct uwsgi_cache *uc, char *key, uint16_t keylen, char *v
|
||||
uc->unused_blocks_stack_ptr++;
|
||||
}
|
||||
else if (rollback_mode == 2) {
|
||||
uc->first_available_block--;
|
||||
uc->first_available_block--;
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
// mark used blocks;
|
||||
uint64_t needed_blocks = cache_mark_blocks(uc, uci->first_block, vallen);
|
||||
// optimize teh scan
|
||||
uint64_t needed_blocks = cache_mark_blocks(uc, uci->first_block, vallen);
|
||||
// optimize the scan
|
||||
if (uc->blocks_bitmap_pos + (needed_blocks+1) > uc->blocks) {
|
||||
uc->blocks_bitmap_pos = 0;
|
||||
}
|
||||
@@ -532,8 +593,10 @@ int uwsgi_cache_set2(struct uwsgi_cache *uc, char *key, uint16_t keylen, char *v
|
||||
uc->blocks_bitmap_pos = uci->first_block + needed_blocks + 1;
|
||||
}
|
||||
}
|
||||
if (expires && !(flags & UWSGI_CACHE_FLAG_ABSEXPIRE))
|
||||
expires += uwsgi_now();
|
||||
if (expires && !(flags & UWSGI_CACHE_FLAG_ABSEXPIRE)) {
|
||||
now = uwsgi_now();
|
||||
expires += now;
|
||||
}
|
||||
uci->expires = expires;
|
||||
uci->hash = uc->hash->func(key, keylen);
|
||||
uci->hits = 0;
|
||||
@@ -572,7 +635,8 @@ int uwsgi_cache_set2(struct uwsgi_cache *uc, char *key, uint16_t keylen, char *v
|
||||
else if (flags & UWSGI_CACHE_FLAG_UPDATE) {
|
||||
uci = cache_item(index);
|
||||
if (expires && !(flags & UWSGI_CACHE_FLAG_ABSEXPIRE)) {
|
||||
expires += uwsgi_now();
|
||||
now = uwsgi_now();
|
||||
expires += now;
|
||||
uci->expires = expires;
|
||||
}
|
||||
if (uc->blocks_bitmap) {
|
||||
@@ -601,7 +665,11 @@ int uwsgi_cache_set2(struct uwsgi_cache *uc, char *key, uint16_t keylen, char *v
|
||||
uci->valsize = vallen;
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
|
||||
if (uc->use_last_modified) {
|
||||
uc->last_modified_at = (now ? now : uwsgi_now());
|
||||
}
|
||||
|
||||
if (uc->nodes && ret == 0 && !(flags & UWSGI_CACHE_FLAG_LOCAL)) {
|
||||
cache_send_udp_command(uc, key, keylen, val, vallen, expires, 10);
|
||||
}
|
||||
@@ -879,6 +947,7 @@ struct uwsgi_cache *uwsgi_cache_create(char *arg) {
|
||||
uc->nodes = uwsgi.cache_udp_node;
|
||||
uc->udp_servers = uwsgi.cache_udp_server;
|
||||
uc->store_sync = uwsgi.cache_store_sync;
|
||||
uc->use_last_modified = (uint8_t) uwsgi.cache_use_last_modified;
|
||||
|
||||
if (uwsgi.cache_sync) {
|
||||
uwsgi_string_new_list(&uc->sync_nodes, uwsgi.cache_sync);
|
||||
@@ -898,6 +967,7 @@ struct uwsgi_cache *uwsgi_cache_create(char *arg) {
|
||||
char *c_sync = NULL;
|
||||
char *c_udp_servers = NULL;
|
||||
char *c_bitmap = NULL;
|
||||
char *c_use_last_modified = NULL;
|
||||
|
||||
if (uwsgi_kvlist_parse(arg, strlen(arg), ',', '=',
|
||||
"name", &c_name,
|
||||
@@ -923,6 +993,7 @@ struct uwsgi_cache *uwsgi_cache_create(char *arg) {
|
||||
"udpservers", &c_udp_servers,
|
||||
"udpserver", &c_udp_servers,
|
||||
"bitmap", &c_bitmap,
|
||||
"lastmod", &c_use_last_modified,
|
||||
NULL)) {
|
||||
uwsgi_log("unable to parse cache definition\n");
|
||||
exit(1);
|
||||
@@ -967,6 +1038,7 @@ struct uwsgi_cache *uwsgi_cache_create(char *arg) {
|
||||
uc->use_blocks_bitmap = 1;
|
||||
uc->max_item_size = uc->blocksize * uc->blocks;
|
||||
}
|
||||
if (c_use_last_modified) uc->use_last_modified = 1;
|
||||
|
||||
uc->store_sync = uwsgi.cache_store_sync;
|
||||
if (c_store_sync) { uc->store_sync = uwsgi_n64(c_store_sync); }
|
||||
@@ -1233,7 +1305,7 @@ static int cache_magic_send_and_manage(int fd, struct uwsgi_buffer *ub, char *st
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *uwsgi_cache_magic_get(char *key, uint16_t keylen, uint64_t *vallen, char *cache) {
|
||||
char *uwsgi_cache_magic_get(char *key, uint16_t keylen, uint64_t *vallen, uint64_t *expires, char *cache) {
|
||||
struct uwsgi_cache_magic_context ucmc;
|
||||
struct uwsgi_cache *uc = NULL;
|
||||
char *cache_server = NULL;
|
||||
@@ -1258,7 +1330,7 @@ char *uwsgi_cache_magic_get(char *key, uint16_t keylen, uint64_t *vallen, char *
|
||||
// we have a local cache !!!
|
||||
if (uc) {
|
||||
uwsgi_rlock(uc->lock);
|
||||
char *value = uwsgi_cache_get2(uc, key, keylen, vallen);
|
||||
char *value = uwsgi_cache_get3(uc, key, keylen, vallen, expires);
|
||||
if (!value) {
|
||||
uwsgi_rwunlock(uc->lock);
|
||||
return NULL;
|
||||
@@ -1328,6 +1400,9 @@ char *uwsgi_cache_magic_get(char *key, uint16_t keylen, uint64_t *vallen, char *
|
||||
ub->buf = NULL;
|
||||
uwsgi_buffer_destroy(ub);
|
||||
*vallen = ucmc.size;
|
||||
if (expires) {
|
||||
*expires = ucmc.expires;
|
||||
}
|
||||
return value;
|
||||
|
||||
}
|
||||
@@ -1625,7 +1700,6 @@ int uwsgi_cache_magic_clear(char *cache) {
|
||||
|
||||
void uwsgi_cache_sync_from_nodes(struct uwsgi_cache *uc) {
|
||||
struct uwsgi_string_list *usl = uc->sync_nodes;
|
||||
usl = uc->sync_nodes;
|
||||
while(usl) {
|
||||
uwsgi_log("[cache-sync] getting cache dump from %s ...\n", usl->value);
|
||||
int fd = uwsgi_connect(usl->value, 0, 0);
|
||||
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
#include <uwsgi.h>
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
struct uwsgi_cron *uwsgi_cron_add(char *crontab) {
|
||||
int i;
|
||||
struct uwsgi_cron *old_uc, *uc = uwsgi.crons;
|
||||
if (!uc) {
|
||||
uc = uwsgi_malloc(sizeof(struct uwsgi_cron));
|
||||
uwsgi.crons = uc;
|
||||
}
|
||||
else {
|
||||
old_uc = uc;
|
||||
while (uc->next) {
|
||||
uc = uc->next;
|
||||
old_uc = uc;
|
||||
}
|
||||
|
||||
old_uc->next = uwsgi_malloc(sizeof(struct uwsgi_cron));
|
||||
uc = old_uc->next;
|
||||
}
|
||||
|
||||
memset(uc, 0, sizeof(struct uwsgi_cron));
|
||||
|
||||
if (sscanf(crontab, "%d %d %d %d %d %n", &uc->minute, &uc->hour, &uc->day, &uc->month, &uc->week, &i) != 5) {
|
||||
uwsgi_log("invalid cron syntax\n");
|
||||
exit(1);
|
||||
}
|
||||
uc->command = crontab + i;
|
||||
return uc;
|
||||
}
|
||||
|
||||
void uwsgi_opt_add_cron(char *opt, char *value, void *foobar) {
|
||||
uwsgi_cron_add(value);
|
||||
}
|
||||
|
||||
#ifdef UWSGI_SSL
|
||||
void uwsgi_opt_add_legion_cron(char *opt, char *value, void *foobar) {
|
||||
char *space = strchr(value, ' ');
|
||||
if (!space) {
|
||||
uwsgi_log("invalid %s syntax, must be prefixed with a legion name\n", opt);
|
||||
exit(1);
|
||||
}
|
||||
char *legion = uwsgi_concat2n(value, space-value, "", 0);
|
||||
struct uwsgi_cron *uc = uwsgi_cron_add(space+1);
|
||||
uc->legion = legion;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int uwsgi_signal_add_cron(uint8_t sig, int minute, int hour, int day, int month, int week) {
|
||||
|
||||
if (!uwsgi.master_process)
|
||||
return -1;
|
||||
|
||||
uwsgi_lock(uwsgi.cron_table_lock);
|
||||
|
||||
if (ushared->cron_cnt < MAX_CRONS) {
|
||||
|
||||
ushared->cron[ushared->cron_cnt].sig = sig;
|
||||
ushared->cron[ushared->cron_cnt].minute = minute;
|
||||
ushared->cron[ushared->cron_cnt].hour = hour;
|
||||
ushared->cron[ushared->cron_cnt].day = day;
|
||||
ushared->cron[ushared->cron_cnt].month = month;
|
||||
ushared->cron[ushared->cron_cnt].week = week;
|
||||
ushared->cron_cnt++;
|
||||
}
|
||||
else {
|
||||
uwsgi_log("you can register max %d cron !!!\n", MAX_CRONS);
|
||||
uwsgi_unlock(uwsgi.cron_table_lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uwsgi_unlock(uwsgi.cron_table_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void uwsgi_manage_signal_cron(time_t now) {
|
||||
|
||||
struct tm *uwsgi_cron_delta;
|
||||
int i;
|
||||
|
||||
uwsgi_cron_delta = localtime(&now);
|
||||
|
||||
if (uwsgi_cron_delta) {
|
||||
|
||||
// fix month
|
||||
uwsgi_cron_delta->tm_mon++;
|
||||
|
||||
uwsgi_lock(uwsgi.cron_table_lock);
|
||||
for (i = 0; i < ushared->cron_cnt; i++) {
|
||||
|
||||
struct uwsgi_cron *ucron = &ushared->cron[i];
|
||||
|
||||
int run_task = uwsgi_cron_task_needs_execution(uwsgi_cron_delta, ucron->minute, ucron->hour, ucron->day, ucron->month, ucron->week);
|
||||
|
||||
if (run_task == 1) {
|
||||
// date match, signal it ?
|
||||
if (now - ucron->last_job >= 60) {
|
||||
uwsgi_route_signal(ucron->sig);
|
||||
ucron->last_job = now;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
uwsgi_unlock(uwsgi.cron_table_lock);
|
||||
}
|
||||
else {
|
||||
uwsgi_error("localtime()");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_manage_command_cron(time_t now) {
|
||||
|
||||
struct tm *uwsgi_cron_delta;
|
||||
|
||||
struct uwsgi_cron *current_cron = uwsgi.crons;
|
||||
|
||||
uwsgi_cron_delta = localtime(&now);
|
||||
|
||||
|
||||
if (!uwsgi_cron_delta) {
|
||||
uwsgi_error("uwsgi_manage_command_cron()/localtime()");
|
||||
return;
|
||||
}
|
||||
|
||||
// fix month
|
||||
uwsgi_cron_delta->tm_mon++;
|
||||
|
||||
while (current_cron) {
|
||||
|
||||
#ifdef UWSGI_SSL
|
||||
// check for legion cron
|
||||
if (current_cron->legion) {
|
||||
if (!uwsgi_legion_i_am_the_lord(current_cron->legion)) {
|
||||
current_cron = current_cron->next;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int run_task = uwsgi_cron_task_needs_execution(uwsgi_cron_delta, current_cron->minute, current_cron->hour, current_cron->day, current_cron->month, current_cron->week);
|
||||
|
||||
if (run_task == 1) {
|
||||
|
||||
// date match, run command ?
|
||||
if (now - current_cron->last_job >= 60) {
|
||||
//call command
|
||||
if (current_cron->command) {
|
||||
if (current_cron->func) {
|
||||
current_cron->func(current_cron, now);
|
||||
}
|
||||
else {
|
||||
if (uwsgi_run_command(current_cron->command, NULL, -1) >= 0) {
|
||||
uwsgi_log_verbose("[uwsgi-cron] running %s\n", current_cron->command);
|
||||
}
|
||||
}
|
||||
}
|
||||
current_cron->last_job = now;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
current_cron = current_cron->next;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -322,7 +322,7 @@ void uwsgi_manage_exception(struct wsgi_request *wsgi_req,int catch) {
|
||||
|
||||
if (do_exit) goto check_catch;
|
||||
|
||||
if (wsgi_req && uwsgi.exception_handlers_instance) {
|
||||
if (uwsgi.exception_handlers_instance) {
|
||||
struct uwsgi_buffer *ehi = uwsgi_exception_handler_object(wsgi_req);
|
||||
if (ehi) {
|
||||
uwsgi_exception_run_handlers(ehi);
|
||||
@@ -442,7 +442,7 @@ static void uwsgi_exception_handler_thread_loop(struct uwsgi_thread *ut) {
|
||||
int interesting_fd = -1;
|
||||
int ret = event_queue_wait(ut->queue, -1, &interesting_fd);
|
||||
if (ret > 0) {
|
||||
ssize_t len = read(ut->pipe[1], buf, uwsgi.alarm_msg_size + sizeof(long));
|
||||
ssize_t len = read(ut->pipe[1], buf, uwsgi.exception_handler_msg_size + sizeof(long));
|
||||
if (len > (ssize_t)(sizeof(long) + 1)) {
|
||||
size_t msg_size = len - sizeof(long);
|
||||
char *msg = buf + sizeof(long);
|
||||
@@ -488,7 +488,7 @@ void uwsgi_exception_setup_handlers() {
|
||||
}
|
||||
|
||||
void uwsgi_exceptions_handler_thread_start() {
|
||||
|
||||
if (!uwsgi.exception_handlers_instance) return;
|
||||
// start the exception_handler_thread
|
||||
uwsgi.exception_handler_thread = uwsgi_thread_new(uwsgi_exception_handler_thread_loop);
|
||||
if (!uwsgi.exception_handler_thread) {
|
||||
|
||||
@@ -28,10 +28,17 @@ struct uwsgi_gateway *register_gateway(char *name, void (*loop) (int, void *), v
|
||||
ug->fullname = fullname;
|
||||
ug->data = data;
|
||||
|
||||
#if defined(SOCK_SEQPACKET) && defined(__linux__)
|
||||
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, ug->internal_subscription_pipe)) {
|
||||
#else
|
||||
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, ug->internal_subscription_pipe)) {
|
||||
#endif
|
||||
uwsgi_error("socketpair()");
|
||||
}
|
||||
|
||||
uwsgi_socket_nb(ug->internal_subscription_pipe[0]);
|
||||
uwsgi_socket_nb(ug->internal_subscription_pipe[1]);
|
||||
|
||||
if (!uwsgi.master_process)
|
||||
gateway_respawn(ushared->gateways_cnt);
|
||||
|
||||
|
||||
@@ -955,6 +955,8 @@ readok2:
|
||||
|
||||
int uwsgi_proxy_nb(struct wsgi_request *wsgi_req, char *addr, struct uwsgi_buffer *ub, size_t remains, int timeout) {
|
||||
|
||||
struct uwsgi_buffer *headers = NULL;
|
||||
|
||||
int fd = uwsgi_connect(addr, 0, 1);
|
||||
if (fd < 0) {
|
||||
return -1;
|
||||
@@ -988,21 +990,91 @@ int uwsgi_proxy_nb(struct wsgi_request *wsgi_req, char *addr, struct uwsgi_buffe
|
||||
}
|
||||
|
||||
// read the response
|
||||
headers = uwsgi_buffer_new(8192);
|
||||
// max 64k headers
|
||||
ub->limit = UMAX16;
|
||||
for(;;) {
|
||||
char buf[8192];
|
||||
ssize_t rlen = uwsgi_read_true_nb(fd, buf, 8192, timeout);
|
||||
if (rlen > 0) {
|
||||
if (uwsgi_response_write_body_do(wsgi_req, buf, rlen)) {
|
||||
break;
|
||||
}
|
||||
if (headers) {
|
||||
if (uwsgi_buffer_append(headers, buf, rlen)) {
|
||||
goto end;
|
||||
}
|
||||
// check if we have a full HTTP response
|
||||
if (uwsgi_is_full_http(headers)) {
|
||||
int ret = uwsgi_blob_to_response(wsgi_req, headers->buf, headers->pos);
|
||||
if (ret) continue;
|
||||
uwsgi_buffer_destroy(headers);
|
||||
headers = NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (uwsgi_response_write_body_do(wsgi_req, buf, rlen)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (headers) uwsgi_buffer_destroy(headers);
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
end:
|
||||
if (headers) uwsgi_buffer_destroy(headers);
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void uwsgi_file_write_do(struct uwsgi_string_list *usl) {
|
||||
|
||||
struct uwsgi_string_list *fl = usl;
|
||||
while(fl) {
|
||||
char *equal = strchr(fl->value, '=');
|
||||
if (equal) {
|
||||
*equal = 0;
|
||||
FILE *f = fopen(fl->value, "w");
|
||||
if (!f) {
|
||||
uwsgi_error_open("uwsgi_file_write_do()");
|
||||
exit(1);
|
||||
}
|
||||
uwsgi_log("writing \"%s\" to \"%s\" ...\n", equal+1, fl->value);
|
||||
if (fprintf(f, "%s\n", equal+1) <= 0 || ferror(f) || fclose(f)) {
|
||||
uwsgi_error("uwsgi_file_write_do()");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
uwsgi_log("unable to write empty value for \"%s\"\n", fl->value);
|
||||
exit(1);
|
||||
}
|
||||
*equal = '=';
|
||||
fl = fl->next;
|
||||
}
|
||||
}
|
||||
|
||||
int uwsgi_fd_is_safe(int fd) {
|
||||
int i;
|
||||
for(i=0;i<uwsgi.safe_fds_cnt;i++) {
|
||||
if (uwsgi.safe_fds[i] == fd) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void uwsgi_add_safe_fd(int fd) {
|
||||
// check if the fd is already safe
|
||||
if (uwsgi_fd_is_safe(fd)) return;
|
||||
|
||||
size_t len = sizeof(int) * (uwsgi.safe_fds_cnt+1);
|
||||
int *tmp = realloc(uwsgi.safe_fds, len);
|
||||
if (!tmp) {
|
||||
uwsgi_error("uwsgi_add_safe_fd()/realloc()");
|
||||
exit(1);
|
||||
}
|
||||
uwsgi.safe_fds = tmp;
|
||||
uwsgi.safe_fds[uwsgi.safe_fds_cnt] = fd;
|
||||
uwsgi.safe_fds_cnt++;
|
||||
}
|
||||
|
||||
+47
-10
@@ -206,7 +206,7 @@ static void legions_check_nodes() {
|
||||
if (now - node->last_seen > uwsgi.legion_tolerance) {
|
||||
struct uwsgi_legion_node *tmp_node = node;
|
||||
node = node->next;
|
||||
uwsgi_log("[uwsgi-legion] node: %.*s valor: %llu uuid: %.*s left Legion %s\n", tmp_node->name_len, tmp_node->name, tmp_node->valor, 36, tmp_node->uuid, legion->legion);
|
||||
uwsgi_log("[uwsgi-legion] %s: %.*s valor: %llu uuid: %.*s left Legion %s\n", tmp_node->valor > 0 ? "node" : "arbiter", tmp_node->name_len, tmp_node->name, tmp_node->valor, 36, tmp_node->uuid, legion->legion);
|
||||
uwsgi_wlock(legion->lock);
|
||||
uwsgi_legion_remove_node(legion, tmp_node);
|
||||
uwsgi_rwunlock(legion->lock);
|
||||
@@ -232,12 +232,12 @@ struct uwsgi_legion_node *uwsgi_legion_get_lord(struct uwsgi_legion *);
|
||||
|
||||
static void legions_report_quorum(struct uwsgi_legion *ul, uint64_t best_valor, char *best_uuid, int votes) {
|
||||
struct uwsgi_legion_node *nodes = ul->nodes_head;
|
||||
uwsgi_log("\n[uwsgi-legion] --- WE HAVE QUORUM FOR LEGION %s !!! (valor: %llu uuid: %.*s checksum: %llu votes: %d) ---\n", ul->legion, best_valor, 36, best_uuid, ul->checksum, votes);
|
||||
uwsgi_log("[uwsgi-legion] --- WE HAVE QUORUM FOR LEGION %s !!! (valor: %llu uuid: %.*s checksum: %llu votes: %d) ---\n", ul->legion, best_valor, 36, best_uuid, ul->checksum, votes);
|
||||
while (nodes) {
|
||||
uwsgi_log("[uwsgi-legion-node] node: %.*s valor: %llu uuid: %.*s last_seen: %d vote_valor: %llu vote_uuid: %.*s\n", nodes->name_len, nodes->name, nodes->valor, 36, nodes->uuid, nodes->last_seen, nodes->lord_valor, 36, nodes->lord_uuid);
|
||||
uwsgi_log("[uwsgi-legion-node] %s: %.*s valor: %llu uuid: %.*s last_seen: %d vote_valor: %llu vote_uuid: %.*s\n", nodes->valor > 0 ? "node" : "arbiter", nodes->name_len, nodes->name, nodes->valor, 36, nodes->uuid, nodes->last_seen, nodes->lord_valor, 36, nodes->lord_uuid);
|
||||
nodes = nodes->next;
|
||||
}
|
||||
uwsgi_log("[uwsgi-legion] --- END OF QUORUM REPORT ---\n\n");
|
||||
uwsgi_log("[uwsgi-legion] --- END OF QUORUM REPORT ---\n");
|
||||
}
|
||||
|
||||
uint64_t uwsgi_legion_checksum(struct uwsgi_legion *ul) {
|
||||
@@ -273,12 +273,17 @@ static void legions_check_nodes_step2() {
|
||||
best_valor = node->valor;
|
||||
memcpy(best_uuid, node->uuid, 36);
|
||||
}
|
||||
else {
|
||||
// go on if i am not an arbiter
|
||||
else if (ul->valor > 0) {
|
||||
// no potential Lord is available, i will propose myself
|
||||
best_valor = ul->valor;
|
||||
memcpy(best_uuid, ul->uuid, 36);
|
||||
i_am_the_best = 1;
|
||||
}
|
||||
else {
|
||||
// empty lord
|
||||
memset(best_uuid, 0, 36);
|
||||
}
|
||||
|
||||
// calculate the checksum
|
||||
uint64_t new_checksum = uwsgi_legion_checksum(ul);
|
||||
@@ -357,9 +362,9 @@ static void legions_check_nodes_step2() {
|
||||
if (ul->i_am_the_lord) {
|
||||
uwsgi_log("[uwsgi-legion] a new Lord (valor: %llu uuid: %.*s) raised for Legion %s...\n", ul->lord_valor, 36, ul->lord_uuid, ul->legion);
|
||||
if (ul->lord_scroll_len > 0) {
|
||||
uwsgi_log("*********** The New Lord Scroll ***********\n\n");
|
||||
uwsgi_log("*********** The New Lord Scroll ***********\n");
|
||||
uwsgi_log("%.*s\n", ul->lord_scroll_len, ul->lord_scroll);
|
||||
uwsgi_log("\n*********** End of the New Lord Scroll ***********\n\n");
|
||||
uwsgi_log("*********** End of the New Lord Scroll ***********\n");
|
||||
}
|
||||
// no more lord, trigger unlord hooks
|
||||
struct uwsgi_string_list *usl = ul->unlord_hooks;
|
||||
@@ -376,6 +381,20 @@ static void legions_check_nodes_step2() {
|
||||
}
|
||||
else if (votes > 0 && votes < ul->quorum && (uwsgi_now() - ul->last_warning >= 60)) {
|
||||
uwsgi_log("[uwsgi-legion] no quorum: only %d vote(s) for Legion %s, %d needed to elect a Lord\n", votes, ul->legion, ul->quorum);
|
||||
// no more quorum, leave the Lord state
|
||||
if (ul->i_am_the_lord) {
|
||||
uwsgi_log("[uwsgi-legion] i cannot be The Lord of The Legion %s without a quorum ...\n", ul->legion);
|
||||
// no more lord, trigger unlord hooks
|
||||
struct uwsgi_string_list *usl = ul->unlord_hooks;
|
||||
while (usl) {
|
||||
int ret = uwsgi_legion_action_call("unlord", ul, usl);
|
||||
if (ret) {
|
||||
uwsgi_log("[uwsgi-legion] ERROR, unlord hook returned: %d\n", ret);
|
||||
}
|
||||
usl = usl->next;
|
||||
}
|
||||
ul->i_am_the_lord = 0;
|
||||
}
|
||||
ul->last_warning = uwsgi_now();
|
||||
}
|
||||
|
||||
@@ -395,6 +414,8 @@ struct uwsgi_legion_node *uwsgi_legion_get_lord(struct uwsgi_legion *ul) {
|
||||
|
||||
struct uwsgi_legion_node *nodes = ul->nodes_head;
|
||||
while (nodes) {
|
||||
// skip arbiters
|
||||
if (nodes->valor == 0) goto next;
|
||||
if (nodes->valor > best_valor) {
|
||||
best_node = nodes;
|
||||
best_valor = nodes->valor;
|
||||
@@ -407,11 +428,12 @@ struct uwsgi_legion_node *uwsgi_legion_get_lord(struct uwsgi_legion *ul) {
|
||||
memcpy(best_uuid, nodes->uuid, 36);
|
||||
}
|
||||
}
|
||||
next:
|
||||
nodes = nodes->next;
|
||||
}
|
||||
|
||||
// first round ?
|
||||
if (ul->lord_valor == 0) {
|
||||
// first round ? (skip first round if arbiter)
|
||||
if (ul->valor > 0 && ul->lord_valor == 0) {
|
||||
ul->changed = 1;
|
||||
}
|
||||
else if (best_valor != ul->lord_valor) {
|
||||
@@ -578,7 +600,7 @@ static void *legion_loop(void *foobar) {
|
||||
// we are still locked (and safe), let's rebuild the scrolls list
|
||||
legion_rebuild_scrolls(ul);
|
||||
uwsgi_rwunlock(ul->lock);
|
||||
uwsgi_log("[uwsgi-legion] node: %.*s valor: %llu uuid: %.*s joined Legion %s\n", node->name_len, node->name, node->valor, 36, node->uuid, ul->legion);
|
||||
uwsgi_log("[uwsgi-legion] %s: %.*s valor: %llu uuid: %.*s joined Legion %s\n", node->valor > 0 ? "node" : "arbiter", node->name_len, node->name, node->valor, 36, node->uuid, ul->legion);
|
||||
// trigger node_joined hooks
|
||||
struct uwsgi_string_list *usl = ul->node_joined_hooks;
|
||||
while (usl) {
|
||||
@@ -775,6 +797,21 @@ err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void uwsgi_opt_legion_mcast(char *opt, char *value, void *foobar) {
|
||||
uwsgi_opt_legion(opt, value, foobar);
|
||||
char *legion = uwsgi_str(value);
|
||||
char *space = strchr(legion, ' ');
|
||||
// over engineering
|
||||
if (!space) exit(1);
|
||||
*space = 0;
|
||||
struct uwsgi_legion *ul = uwsgi_legion_get_by_name(legion);
|
||||
if (!ul) {
|
||||
uwsgi_log("unknown legion: %s\n", legion);
|
||||
exit(1);
|
||||
}
|
||||
uwsgi_legion_register_node(ul, uwsgi_str(ul->addr));
|
||||
}
|
||||
|
||||
void uwsgi_opt_legion_node(char *opt, char *value, void *foobar) {
|
||||
|
||||
char *legion = uwsgi_str(value);
|
||||
|
||||
@@ -474,8 +474,6 @@ void uwsgi_rwunlock_fast(struct uwsgi_lock_item *uli) {
|
||||
|
||||
#define UWSGI_LOCK_ENGINE_NAME "ipcsem"
|
||||
|
||||
#define UWSGI_IPCSEM_ATEXIT 1
|
||||
|
||||
#endif
|
||||
|
||||
struct uwsgi_lock_item *uwsgi_lock_ipcsem_init(char *id) {
|
||||
|
||||
+69
-173
@@ -351,6 +351,9 @@ void uwsgi_reload(char **argv) {
|
||||
/* check fd table (a module can obviosly open some fd on initialization...) */
|
||||
uwsgi_log("closing all non-uwsgi socket fds > 2 (max_fd = %d)...\n", (int) uwsgi.max_fd);
|
||||
for (i = 3; i < (int) uwsgi.max_fd; i++) {
|
||||
|
||||
if (uwsgi_fd_is_safe(i)) continue;
|
||||
|
||||
int found = 0;
|
||||
|
||||
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
|
||||
@@ -413,6 +416,13 @@ void uwsgi_reload(char **argv) {
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef UWSGI_IPCSEM_ATEXIT
|
||||
// free ipc semaphores if in use
|
||||
if (uwsgi.lock_engine && !strcmp(uwsgi.lock_engine, "ipcsem")) {
|
||||
uwsgi_ipcsem_clear();
|
||||
}
|
||||
#endif
|
||||
|
||||
uwsgi_log("running %s\n", uwsgi.binary_path);
|
||||
uwsgi_flush_logs();
|
||||
argv[0] = uwsgi.binary_path;
|
||||
@@ -630,178 +640,6 @@ int uwsgi_respawn_worker(int wid) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uwsgi_manage_signal_cron(time_t now) {
|
||||
|
||||
struct tm *uwsgi_cron_delta;
|
||||
int i;
|
||||
|
||||
uwsgi_cron_delta = localtime(&now);
|
||||
|
||||
if (uwsgi_cron_delta) {
|
||||
|
||||
// fix month
|
||||
uwsgi_cron_delta->tm_mon++;
|
||||
|
||||
uwsgi_lock(uwsgi.cron_table_lock);
|
||||
for (i = 0; i < ushared->cron_cnt; i++) {
|
||||
|
||||
struct uwsgi_cron *ucron = &ushared->cron[i];
|
||||
int uc_minute, uc_hour, uc_day, uc_month, uc_week;
|
||||
|
||||
uc_minute = ucron->minute;
|
||||
uc_hour = ucron->hour;
|
||||
uc_day = ucron->day;
|
||||
uc_month = ucron->month;
|
||||
uc_week = ucron->week;
|
||||
|
||||
// negative values as interval -1 = * , -5 = */5
|
||||
if (ucron->minute < 0) {
|
||||
if ((uwsgi_cron_delta->tm_min % abs(ucron->minute)) == 0) {
|
||||
uc_minute = uwsgi_cron_delta->tm_min;
|
||||
}
|
||||
}
|
||||
if (ucron->hour < 0) {
|
||||
if ((uwsgi_cron_delta->tm_hour % abs(ucron->hour)) == 0) {
|
||||
uc_hour = uwsgi_cron_delta->tm_hour;
|
||||
}
|
||||
}
|
||||
if (ucron->month < 0) {
|
||||
if ((uwsgi_cron_delta->tm_mon % abs(ucron->month)) == 0) {
|
||||
uc_month = uwsgi_cron_delta->tm_mon;
|
||||
}
|
||||
}
|
||||
if (ucron->day < 0) {
|
||||
if ((uwsgi_cron_delta->tm_mday % abs(ucron->day)) == 0) {
|
||||
uc_day = uwsgi_cron_delta->tm_mday;
|
||||
}
|
||||
}
|
||||
if (ucron->week < 0) {
|
||||
if ((uwsgi_cron_delta->tm_wday % abs(ucron->week)) == 0) {
|
||||
uc_week = uwsgi_cron_delta->tm_wday;
|
||||
}
|
||||
}
|
||||
|
||||
int run_task = 0;
|
||||
// mday and wday are ORed
|
||||
if (ucron->day >= 0 && ucron->week >= 0) {
|
||||
if (uwsgi_cron_delta->tm_min == uc_minute && uwsgi_cron_delta->tm_hour == uc_hour && uwsgi_cron_delta->tm_mon == uc_month && (uwsgi_cron_delta->tm_mday == uc_day || uwsgi_cron_delta->tm_wday == uc_week)) {
|
||||
run_task = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (uwsgi_cron_delta->tm_min == uc_minute && uwsgi_cron_delta->tm_hour == uc_hour && uwsgi_cron_delta->tm_mon == uc_month && uwsgi_cron_delta->tm_mday == uc_day && uwsgi_cron_delta->tm_wday == uc_week) {
|
||||
run_task = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (run_task == 1) {
|
||||
// date match, signal it ?
|
||||
if (now - ucron->last_job > 60) {
|
||||
uwsgi_route_signal(ucron->sig);
|
||||
ucron->last_job = now;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
uwsgi_unlock(uwsgi.cron_table_lock);
|
||||
}
|
||||
else {
|
||||
uwsgi_error("localtime()");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_manage_command_cron(time_t now) {
|
||||
|
||||
struct tm *uwsgi_cron_delta;
|
||||
|
||||
struct uwsgi_cron *current_cron = uwsgi.crons;
|
||||
int uc_minute, uc_hour, uc_day, uc_month, uc_week;
|
||||
|
||||
uwsgi_cron_delta = localtime(&now);
|
||||
|
||||
|
||||
if (!uwsgi_cron_delta) {
|
||||
uwsgi_error("localtime()");
|
||||
return;
|
||||
}
|
||||
|
||||
// fix month
|
||||
uwsgi_cron_delta->tm_mon++;
|
||||
|
||||
while (current_cron) {
|
||||
|
||||
uc_minute = current_cron->minute;
|
||||
uc_hour = current_cron->hour;
|
||||
uc_day = current_cron->day;
|
||||
uc_month = current_cron->month;
|
||||
uc_week = current_cron->week;
|
||||
|
||||
// negative values as interval -1 = * , -5 = */5
|
||||
if (current_cron->minute < 0) {
|
||||
if ((uwsgi_cron_delta->tm_min % abs(current_cron->minute)) == 0) {
|
||||
uc_minute = uwsgi_cron_delta->tm_min;
|
||||
}
|
||||
}
|
||||
if (current_cron->hour < 0) {
|
||||
if ((uwsgi_cron_delta->tm_hour % abs(current_cron->hour)) == 0) {
|
||||
uc_hour = uwsgi_cron_delta->tm_hour;
|
||||
}
|
||||
}
|
||||
if (current_cron->month < 0) {
|
||||
if ((uwsgi_cron_delta->tm_mon % abs(current_cron->month)) == 0) {
|
||||
uc_month = uwsgi_cron_delta->tm_mon;
|
||||
}
|
||||
}
|
||||
if (current_cron->day < 0) {
|
||||
if ((uwsgi_cron_delta->tm_mday % abs(current_cron->day)) == 0) {
|
||||
uc_day = uwsgi_cron_delta->tm_mday;
|
||||
}
|
||||
}
|
||||
if (current_cron->week < 0) {
|
||||
if ((uwsgi_cron_delta->tm_wday % abs(current_cron->week)) == 0) {
|
||||
uc_week = uwsgi_cron_delta->tm_wday;
|
||||
}
|
||||
}
|
||||
|
||||
int run_task = 0;
|
||||
// mday and wday are ORed
|
||||
if (current_cron->day >= 0 && current_cron->week >= 0) {
|
||||
if (uwsgi_cron_delta->tm_min == uc_minute && uwsgi_cron_delta->tm_hour == uc_hour && uwsgi_cron_delta->tm_mon == uc_month && (uwsgi_cron_delta->tm_mday == uc_day || uwsgi_cron_delta->tm_wday == uc_week)) {
|
||||
run_task = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (uwsgi_cron_delta->tm_min == uc_minute && uwsgi_cron_delta->tm_hour == uc_hour && uwsgi_cron_delta->tm_mon == uc_month && uwsgi_cron_delta->tm_mday == uc_day && uwsgi_cron_delta->tm_wday == uc_week) {
|
||||
run_task = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (run_task == 1) {
|
||||
|
||||
// date match, run command ?
|
||||
if (now - current_cron->last_job > 60) {
|
||||
//call command
|
||||
if (current_cron->command) {
|
||||
if (uwsgi_run_command(current_cron->command, NULL, -1) >= 0) {
|
||||
uwsgi_log_verbose("[uWSGI-cron] running %s\n", current_cron->command);
|
||||
}
|
||||
}
|
||||
current_cron->last_job = now;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
current_cron = current_cron->next;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
struct uwsgi_stats *uwsgi_master_generate_stats() {
|
||||
|
||||
int i;
|
||||
@@ -940,7 +778,10 @@ struct uwsgi_stats *uwsgi_master_generate_stats() {
|
||||
if (uwsgi_stats_keylong_comma(us, "miss", (unsigned long long) uc->miss))
|
||||
goto end;
|
||||
|
||||
if (uwsgi_stats_keylong(us, "full", (unsigned long long) uc->full))
|
||||
if (uwsgi_stats_keylong_comma(us, "full", (unsigned long long) uc->full))
|
||||
goto end;
|
||||
|
||||
if (uwsgi_stats_keylong(us, "last_modified_at", (unsigned long long) uc->last_modified_at))
|
||||
goto end;
|
||||
|
||||
if (uwsgi_stats_object_close(us))
|
||||
@@ -1485,3 +1326,58 @@ void uwsgi_master_fix_request_counters() {
|
||||
uwsgi.workers[0].requests = total_counter;
|
||||
}
|
||||
|
||||
|
||||
int uwsgi_cron_task_needs_execution(struct tm *uwsgi_cron_delta, int minute, int hour, int day, int month, int week) {
|
||||
|
||||
int uc_minute, uc_hour, uc_day, uc_month, uc_week;
|
||||
|
||||
uc_minute = minute;
|
||||
uc_hour = hour;
|
||||
uc_day = day;
|
||||
uc_month = month;
|
||||
uc_week = week;
|
||||
|
||||
// negative values as interval -1 = * , -5 = */5
|
||||
if (minute < 0) {
|
||||
if ((uwsgi_cron_delta->tm_min % abs(minute)) == 0) {
|
||||
uc_minute = uwsgi_cron_delta->tm_min;
|
||||
}
|
||||
}
|
||||
if (hour < 0) {
|
||||
if ((uwsgi_cron_delta->tm_hour % abs(hour)) == 0) {
|
||||
uc_hour = uwsgi_cron_delta->tm_hour;
|
||||
}
|
||||
}
|
||||
if (month < 0) {
|
||||
if ((uwsgi_cron_delta->tm_mon % abs(month)) == 0) {
|
||||
uc_month = uwsgi_cron_delta->tm_mon;
|
||||
}
|
||||
}
|
||||
if (day < 0) {
|
||||
if ((uwsgi_cron_delta->tm_mday % abs(day)) == 0) {
|
||||
uc_day = uwsgi_cron_delta->tm_mday;
|
||||
}
|
||||
}
|
||||
if (week < 0) {
|
||||
if ((uwsgi_cron_delta->tm_wday % abs(week)) == 0) {
|
||||
uc_week = uwsgi_cron_delta->tm_wday;
|
||||
}
|
||||
}
|
||||
|
||||
int run_task = 0;
|
||||
// mday and wday are ORed
|
||||
if (day >= 0 && week >= 0) {
|
||||
if (uwsgi_cron_delta->tm_min == uc_minute && uwsgi_cron_delta->tm_hour == uc_hour && uwsgi_cron_delta->tm_mon == uc_month && (uwsgi_cron_delta->tm_mday == uc_day || uwsgi_cron_delta->tm_wday == uc_week)) {
|
||||
run_task = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (uwsgi_cron_delta->tm_min == uc_minute && uwsgi_cron_delta->tm_hour == uc_hour && uwsgi_cron_delta->tm_mon == uc_month && uwsgi_cron_delta->tm_mday == uc_day && uwsgi_cron_delta->tm_wday == uc_week) {
|
||||
run_task = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return run_task;
|
||||
|
||||
}
|
||||
|
||||
|
||||
+29
-3
@@ -77,9 +77,14 @@ struct uwsgi_metric {
|
||||
|
||||
// ABSOLUTE/COUNTER/GAUGE
|
||||
uint8_t type;
|
||||
|
||||
// the value of the metric
|
||||
int64_t value;
|
||||
|
||||
// MANUAL/PTR/FUNC/FILE
|
||||
uint8_t collect_way
|
||||
|
||||
// this could be taken from a file storage and must laways be added to value when reporting (default 0)
|
||||
int64_t initial_value;
|
||||
// the value of the metric (point to a shared memory area)
|
||||
*int64_t value;
|
||||
|
||||
// a custom blob you can attach to a metric
|
||||
void *custom;
|
||||
@@ -110,3 +115,24 @@ void uwsgi_metric_loop() {
|
||||
// every second scan the whole metrics tree
|
||||
time_t now = uwsgi_now();
|
||||
}
|
||||
|
||||
int64_t uwsgi_metric_get(char *name, char *oid) {
|
||||
struct uwsgi_metric *um = NULL;
|
||||
if (name) {
|
||||
um = uwsgi_metric_find_by_name(name);
|
||||
}
|
||||
else if (oid) {
|
||||
um = uwsgi_metric_find_by_oid(oid);
|
||||
}
|
||||
if (!um) return 0;
|
||||
|
||||
//
|
||||
switch(um->collect_way) {
|
||||
case UWSGI_METRIC_MANUAL:
|
||||
return um->initial_value+*um->value;
|
||||
case UWSGI_METRIC_PTR:
|
||||
return um->initial_value+*um->ptr;
|
||||
case UWSGI_METRIC_FUNC:
|
||||
case UWSGI_METRIC_FILE:
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@ int u_offload_transfer_prepare(struct wsgi_request *wsgi_req, struct uwsgi_offlo
|
||||
return -1;
|
||||
}
|
||||
|
||||
uor->fd = uwsgi_connect(uor->ubuf->buf, 0, 1);
|
||||
uor->fd = uwsgi_connect(uor->name, 0, 1);
|
||||
if (uor->fd < 0) {
|
||||
uwsgi_error("u_offload_transfer_prepare()/connect()");
|
||||
return -1;
|
||||
|
||||
+2
-2
@@ -739,7 +739,7 @@ next:
|
||||
// check if data are available in the local cache
|
||||
if (wsgi_req->cache_get_len > 0) {
|
||||
uint64_t cache_value_size;
|
||||
char *cache_value = uwsgi_cache_magic_get(wsgi_req->cache_get, wsgi_req->cache_get_len, &cache_value_size, NULL);
|
||||
char *cache_value = uwsgi_cache_magic_get(wsgi_req->cache_get, wsgi_req->cache_get_len, &cache_value_size, NULL, NULL);
|
||||
if (cache_value && cache_value_size > 0) {
|
||||
uwsgi_response_write_body_do(wsgi_req, cache_value, cache_value_size);
|
||||
free(cache_value);
|
||||
@@ -750,7 +750,7 @@ next:
|
||||
if (uwsgi.check_cache && wsgi_req->uri_len && wsgi_req->method_len == 3 && wsgi_req->method[0] == 'G' && wsgi_req->method[1] == 'E' && wsgi_req->method[2] == 'T') {
|
||||
|
||||
uint64_t cache_value_size;
|
||||
char *cache_value = uwsgi_cache_magic_get(wsgi_req->uri, wsgi_req->uri_len, &cache_value_size, NULL);
|
||||
char *cache_value = uwsgi_cache_magic_get(wsgi_req->uri, wsgi_req->uri_len, &cache_value_size, NULL, NULL);
|
||||
if (cache_value && cache_value_size > 0) {
|
||||
uwsgi_response_write_body_do(wsgi_req, cache_value, cache_value_size);
|
||||
free(cache_value);
|
||||
|
||||
@@ -485,6 +485,28 @@ static int uwsgi_router_goon(struct uwsgi_route *ur, char *arg) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// flush response
|
||||
static int transform_flush(struct wsgi_request *wsgi_req, struct uwsgi_buffer *ub, struct uwsgi_buffer **foobar, void *data) {
|
||||
wsgi_req->flush = 1;
|
||||
return uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);
|
||||
return 0;
|
||||
}
|
||||
static int uwsgi_router_flush_func(struct wsgi_request *wsgi_req, struct uwsgi_route *route) {
|
||||
// if there are no transformations defined, set the flush right now
|
||||
if (!wsgi_req->transformations) {
|
||||
wsgi_req->flush = 1;
|
||||
}
|
||||
else {
|
||||
// otherwise push it in the chain
|
||||
uwsgi_add_transformation(wsgi_req, transform_flush, NULL);
|
||||
}
|
||||
return UWSGI_ROUTE_NEXT;
|
||||
}
|
||||
static int uwsgi_router_flush(struct uwsgi_route *ur, char *arg) {
|
||||
ur->func = uwsgi_router_flush_func;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// log route
|
||||
static int uwsgi_router_log_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
|
||||
|
||||
@@ -1067,6 +1089,29 @@ static int uwsgi_route_condition_startswith(struct wsgi_request *wsgi_req, struc
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int uwsgi_route_condition_contains(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
|
||||
char *semicolon = memchr(ur->subject_str, ';', ur->subject_str_len);
|
||||
if (!semicolon) return 0;
|
||||
|
||||
struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, ur->subject_str, semicolon - ur->subject_str);
|
||||
if (!ub) return -1;
|
||||
|
||||
struct uwsgi_buffer *ub2 = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, semicolon+1, ur->subject_str_len - ((semicolon+1) - ur->subject_str));
|
||||
if (!ub2) {
|
||||
uwsgi_buffer_destroy(ub);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(uwsgi_contains_n(ub->buf, ub->pos, ub2->buf, ub2->pos)) {
|
||||
uwsgi_buffer_destroy(ub);
|
||||
uwsgi_buffer_destroy(ub2);
|
||||
return 1;
|
||||
}
|
||||
uwsgi_buffer_destroy(ub);
|
||||
uwsgi_buffer_destroy(ub2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int uwsgi_route_condition_endswith(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
|
||||
char *semicolon = memchr(ur->subject_str, ';', ur->subject_str_len);
|
||||
if (!semicolon) return 0;
|
||||
@@ -1143,6 +1188,19 @@ static char *uwsgi_route_var_uwsgi(struct wsgi_request *wsgi_req, char *key, uin
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *uwsgi_route_var_mime(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, uint16_t *vallen) {
|
||||
char *ret = NULL;
|
||||
uint16_t var_vallen = 0;
|
||||
char *var_value = uwsgi_get_var(wsgi_req, key, keylen, &var_vallen);
|
||||
if (var_value) {
|
||||
size_t mime_type_len = 0;
|
||||
char *ret = uwsgi_get_mime_type(key, keylen, &mime_type_len);
|
||||
if (ret) *vallen = mime_type_len;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static char *uwsgi_route_var_time(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, uint16_t *vallen) {
|
||||
char *ret = NULL;
|
||||
if (!uwsgi_strncmp(key, keylen, "unix", 4)) {
|
||||
@@ -1152,6 +1210,29 @@ static char *uwsgi_route_var_time(struct wsgi_request *wsgi_req, char *key, uint
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *uwsgi_route_var_base64(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, uint16_t *vallen) {
|
||||
char *ret = NULL;
|
||||
uint16_t var_vallen = 0;
|
||||
char *var_value = uwsgi_get_var(wsgi_req, key, keylen, &var_vallen);
|
||||
if (var_value) {
|
||||
size_t b64_len = 0;
|
||||
ret = uwsgi_base64_encode(var_value, var_vallen, &b64_len);
|
||||
*vallen = b64_len;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *uwsgi_route_var_hex(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, uint16_t *vallen) {
|
||||
char *ret = NULL;
|
||||
uint16_t var_vallen = 0;
|
||||
char *var_value = uwsgi_get_var(wsgi_req, key, keylen, &var_vallen);
|
||||
if (var_value) {
|
||||
ret = uwsgi_str_to_hex(var_value, var_vallen);
|
||||
*vallen = var_vallen*2;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef UWSGI_MATHEVAL
|
||||
static char *uwsgi_route_var_math(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, uint16_t *vallen) {
|
||||
char *ret = NULL;
|
||||
@@ -1217,6 +1298,8 @@ void uwsgi_register_embedded_routers() {
|
||||
uwsgi_register_router("setprocname", uwsgi_router_setprocname);
|
||||
uwsgi_register_router("alarm", uwsgi_router_alarm);
|
||||
|
||||
uwsgi_register_router("flush", uwsgi_router_flush);
|
||||
|
||||
uwsgi_register_route_condition("exists", uwsgi_route_condition_exists);
|
||||
uwsgi_register_route_condition("isfile", uwsgi_route_condition_isfile);
|
||||
uwsgi_register_route_condition("isdir", uwsgi_route_condition_isdir);
|
||||
@@ -1238,6 +1321,8 @@ void uwsgi_register_embedded_routers() {
|
||||
uwsgi_register_route_condition(">=", uwsgi_route_condition_higherequal);
|
||||
uwsgi_register_route_condition("islowerequal", uwsgi_route_condition_lowerequal);
|
||||
uwsgi_register_route_condition("<=", uwsgi_route_condition_lowerequal);
|
||||
uwsgi_register_route_condition("contains", uwsgi_route_condition_contains);
|
||||
uwsgi_register_route_condition("contain", uwsgi_route_condition_contains);
|
||||
#ifdef UWSGI_SSL
|
||||
uwsgi_register_route_condition("lord", uwsgi_route_condition_lord);
|
||||
#endif
|
||||
@@ -1246,6 +1331,7 @@ void uwsgi_register_embedded_routers() {
|
||||
|
||||
uwsgi_register_route_var("cookie", uwsgi_get_cookie);
|
||||
uwsgi_register_route_var("qs", uwsgi_get_qs);
|
||||
uwsgi_register_route_var("mime", uwsgi_route_var_mime);
|
||||
struct uwsgi_route_var *urv = uwsgi_register_route_var("uwsgi", uwsgi_route_var_uwsgi);
|
||||
urv->need_free = 1;
|
||||
urv = uwsgi_register_route_var("time", uwsgi_route_var_time);
|
||||
@@ -1254,6 +1340,11 @@ void uwsgi_register_embedded_routers() {
|
||||
urv = uwsgi_register_route_var("math", uwsgi_route_var_math);
|
||||
urv->need_free = 1;
|
||||
#endif
|
||||
urv = uwsgi_register_route_var("base64", uwsgi_route_var_base64);
|
||||
urv->need_free = 1;
|
||||
|
||||
urv = uwsgi_register_route_var("hex", uwsgi_route_var_hex);
|
||||
urv->need_free = 1;
|
||||
}
|
||||
|
||||
struct uwsgi_router *uwsgi_register_router(char *name, int (*func) (struct uwsgi_route *, char *)) {
|
||||
|
||||
+5
-5
@@ -1,8 +1,8 @@
|
||||
#include "uwsgi.h"
|
||||
#include <uwsgi.h>
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
int uwsgi_register_rpc(char *name, uint8_t modifier1, uint8_t args, void *func) {
|
||||
int uwsgi_register_rpc(char *name, struct uwsgi_plugin *plugin, uint8_t args, void *func) {
|
||||
|
||||
struct uwsgi_rpc *urpc;
|
||||
int ret = -1;
|
||||
@@ -30,7 +30,7 @@ int uwsgi_register_rpc(char *name, uint8_t modifier1, uint8_t args, void *func)
|
||||
uwsgi.shared->rpc_count[uwsgi.mywid]++;
|
||||
already:
|
||||
memcpy(urpc->name, name, strlen(name));
|
||||
urpc->modifier1 = modifier1;
|
||||
urpc->plugin = plugin;
|
||||
urpc->args = args;
|
||||
urpc->func = func;
|
||||
urpc->shared = uwsgi.mywid == 0 ? 1 : 0;
|
||||
@@ -77,8 +77,8 @@ uint16_t uwsgi_rpc(char *name, uint8_t argc, char *argv[], uint16_t argvs[], cha
|
||||
}
|
||||
|
||||
if (urpc) {
|
||||
if (uwsgi.p[urpc->modifier1]->rpc) {
|
||||
ret = uwsgi.p[urpc->modifier1]->rpc(urpc->func, argc, argv, argvs, output);
|
||||
if (urpc->plugin->rpc) {
|
||||
ret = urpc->plugin->rpc(urpc->func, argc, argv, argvs, output);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -106,6 +106,9 @@ void uwsgi_setup_inherited_sockets() {
|
||||
//now close all the unbound fd
|
||||
for (j = 3; j < (int) uwsgi.max_fd; j++) {
|
||||
int useless = 1;
|
||||
|
||||
if (uwsgi_fd_is_safe(j)) continue;
|
||||
|
||||
if (uwsgi.has_emperor) {
|
||||
if (j == uwsgi.emperor_fd)
|
||||
continue;
|
||||
|
||||
@@ -203,63 +203,6 @@ int uwsgi_add_timer(uint8_t sig, int secs) {
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_opt_add_cron(char *opt, char *value, void *foobar) {
|
||||
|
||||
int i;
|
||||
|
||||
struct uwsgi_cron *old_uc, *uc = uwsgi.crons;
|
||||
if (!uc) {
|
||||
uc = uwsgi_malloc(sizeof(struct uwsgi_cron));
|
||||
uwsgi.crons = uc;
|
||||
}
|
||||
else {
|
||||
old_uc = uc;
|
||||
while (uc->next) {
|
||||
uc = uc->next;
|
||||
old_uc = uc;
|
||||
}
|
||||
|
||||
old_uc->next = uwsgi_malloc(sizeof(struct uwsgi_cron));
|
||||
uc = old_uc->next;
|
||||
}
|
||||
|
||||
memset(uc, 0, sizeof(struct uwsgi_cron));
|
||||
|
||||
if (sscanf(value, "%d %d %d %d %d %n", &uc->minute, &uc->hour, &uc->day, &uc->month, &uc->week, &i) != 5) {
|
||||
uwsgi_log("invalid cron syntax\n");
|
||||
exit(1);
|
||||
}
|
||||
uc->command = value + i;
|
||||
}
|
||||
|
||||
int uwsgi_signal_add_cron(uint8_t sig, int minute, int hour, int day, int month, int week) {
|
||||
|
||||
if (!uwsgi.master_process)
|
||||
return -1;
|
||||
|
||||
uwsgi_lock(uwsgi.cron_table_lock);
|
||||
|
||||
if (ushared->cron_cnt < MAX_CRONS) {
|
||||
|
||||
ushared->cron[ushared->cron_cnt].sig = sig;
|
||||
ushared->cron[ushared->cron_cnt].minute = minute;
|
||||
ushared->cron[ushared->cron_cnt].hour = hour;
|
||||
ushared->cron[ushared->cron_cnt].day = day;
|
||||
ushared->cron[ushared->cron_cnt].month = month;
|
||||
ushared->cron[ushared->cron_cnt].week = week;
|
||||
ushared->cron_cnt++;
|
||||
}
|
||||
else {
|
||||
uwsgi_log("you can register max %d cron !!!\n", MAX_CRONS);
|
||||
uwsgi_unlock(uwsgi.cron_table_lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uwsgi_unlock(uwsgi.cron_table_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uwsgi_signal_add_rb_timer(uint8_t sig, int secs, int iterations) {
|
||||
|
||||
if (!uwsgi.master_process)
|
||||
|
||||
+8
-2
@@ -252,8 +252,14 @@ SSL_CTX *uwsgi_ssl_new_server_context(char *name, char *crt, char *key, char *ci
|
||||
|
||||
uwsgi.ssl_sessions_cache = uwsgi_cache_by_name(uwsgi.ssl_sessions_use_cache);
|
||||
if (!uwsgi.ssl_sessions_cache) {
|
||||
uwsgi_log("unable to find cache \"%s\"\n", uwsgi.ssl_sessions_use_cache ? uwsgi.ssl_sessions_use_cache : "default");
|
||||
exit(1);
|
||||
// check for default cache
|
||||
if (!strcmp(uwsgi.ssl_sessions_use_cache, "true") && uwsgi.caches) {
|
||||
uwsgi.ssl_sessions_cache = uwsgi.caches;
|
||||
}
|
||||
else {
|
||||
uwsgi_log("unable to find cache \"%s\"\n", uwsgi.ssl_sessions_use_cache ? uwsgi.ssl_sessions_use_cache : "default");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!uwsgi.ssl_sessions_cache->max_items) {
|
||||
|
||||
+31
-23
@@ -55,7 +55,7 @@ gzip:
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int set_http_date(time_t t, char *dst) {
|
||||
int uwsgi_http_date(time_t t, char *dst) {
|
||||
|
||||
static char *week[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
|
||||
static char *months[] = {
|
||||
@@ -179,7 +179,7 @@ int uwsgi_add_expires_type(struct wsgi_request *wsgi_req, char *mime_type, int m
|
||||
while (udd) {
|
||||
if (!uwsgi_strncmp(udd->key, udd->keylen, mime_type, mime_type_len)) {
|
||||
int delta = uwsgi_str_num(udd->value, udd->vallen);
|
||||
int size = set_http_date(now + delta, expires);
|
||||
int size = uwsgi_http_date(now + delta, expires);
|
||||
if (size > 0) {
|
||||
if (uwsgi_response_add_header(wsgi_req, "Expires", 7, expires, size)) return -1;
|
||||
}
|
||||
@@ -192,7 +192,7 @@ int uwsgi_add_expires_type(struct wsgi_request *wsgi_req, char *mime_type, int m
|
||||
while (udd) {
|
||||
if (!uwsgi_strncmp(udd->key, udd->keylen, mime_type, mime_type_len)) {
|
||||
int delta = uwsgi_str_num(udd->value, udd->vallen);
|
||||
int size = set_http_date(st->st_mtime + delta, expires);
|
||||
int size = uwsgi_http_date(st->st_mtime + delta, expires);
|
||||
if (size > 0) {
|
||||
if (uwsgi_response_add_header(wsgi_req, "Expires", 7, expires, size)) return -1;
|
||||
}
|
||||
@@ -215,7 +215,7 @@ int uwsgi_add_expires(struct wsgi_request *wsgi_req, char *filename, int filenam
|
||||
while (udd) {
|
||||
if (uwsgi_regexp_match(udd->pattern, udd->pattern_extra, filename, filename_len) >= 0) {
|
||||
int delta = uwsgi_str_num(udd->value, udd->vallen);
|
||||
int size = set_http_date(now + delta, expires);
|
||||
int size = uwsgi_http_date(now + delta, expires);
|
||||
if (size > 0) {
|
||||
if (uwsgi_response_add_header(wsgi_req, "Expires", 7, expires, size)) return -1;
|
||||
}
|
||||
@@ -228,7 +228,7 @@ int uwsgi_add_expires(struct wsgi_request *wsgi_req, char *filename, int filenam
|
||||
while (udd) {
|
||||
if (uwsgi_regexp_match(udd->pattern, udd->pattern_extra, filename, filename_len) >= 0) {
|
||||
int delta = uwsgi_str_num(udd->value, udd->vallen);
|
||||
int size = set_http_date(st->st_mtime + delta, expires);
|
||||
int size = uwsgi_http_date(st->st_mtime + delta, expires);
|
||||
if (size > 0) {
|
||||
if (uwsgi_response_add_header(wsgi_req, "Expires", 7, expires, size)) return -1;
|
||||
}
|
||||
@@ -250,7 +250,7 @@ int uwsgi_add_expires_path_info(struct wsgi_request *wsgi_req, struct stat *st)
|
||||
while (udd) {
|
||||
if (uwsgi_regexp_match(udd->pattern, udd->pattern_extra, wsgi_req->path_info, wsgi_req->path_info_len) >= 0) {
|
||||
int delta = uwsgi_str_num(udd->value, udd->vallen);
|
||||
int size = set_http_date(now + delta, expires);
|
||||
int size = uwsgi_http_date(now + delta, expires);
|
||||
if (size > 0) {
|
||||
if (uwsgi_response_add_header(wsgi_req, "Expires", 7, expires, size)) return -1;
|
||||
}
|
||||
@@ -263,7 +263,7 @@ int uwsgi_add_expires_path_info(struct wsgi_request *wsgi_req, struct stat *st)
|
||||
while (udd) {
|
||||
if (uwsgi_regexp_match(udd->pattern, udd->pattern_extra, wsgi_req->path_info, wsgi_req->path_info_len) >= 0) {
|
||||
int delta = uwsgi_str_num(udd->value, udd->vallen);
|
||||
int size = set_http_date(st->st_mtime + delta, expires);
|
||||
int size = uwsgi_http_date(st->st_mtime + delta, expires);
|
||||
if (size > 0) {
|
||||
if (uwsgi_response_add_header(wsgi_req, "Expires", 7, expires, size)) return -1;
|
||||
}
|
||||
@@ -285,7 +285,7 @@ int uwsgi_add_expires_uri(struct wsgi_request *wsgi_req, struct stat *st) {
|
||||
while (udd) {
|
||||
if (uwsgi_regexp_match(udd->pattern, udd->pattern_extra, wsgi_req->uri, wsgi_req->uri_len) >= 0) {
|
||||
int delta = uwsgi_str_num(udd->value, udd->vallen);
|
||||
int size = set_http_date(now + delta, expires);
|
||||
int size = uwsgi_http_date(now + delta, expires);
|
||||
if (size > 0) {
|
||||
if (uwsgi_response_add_header(wsgi_req, "Expires", 7, expires, size)) return -1;
|
||||
}
|
||||
@@ -298,7 +298,7 @@ int uwsgi_add_expires_uri(struct wsgi_request *wsgi_req, struct stat *st) {
|
||||
while (udd) {
|
||||
if (uwsgi_regexp_match(udd->pattern, udd->pattern_extra, wsgi_req->uri, wsgi_req->uri_len) >= 0) {
|
||||
int delta = uwsgi_str_num(udd->value, udd->vallen);
|
||||
int size = set_http_date(st->st_mtime + delta, expires);
|
||||
int size = uwsgi_http_date(st->st_mtime + delta, expires);
|
||||
if (size > 0) {
|
||||
if (uwsgi_response_add_header(wsgi_req, "Expires", 7, expires, size)) return -1;
|
||||
}
|
||||
@@ -333,6 +333,10 @@ char *uwsgi_get_mime_type(char *name, int namelen, size_t *size) {
|
||||
if (!ext)
|
||||
return NULL;
|
||||
|
||||
|
||||
if (uwsgi.threads > 1)
|
||||
pthread_mutex_lock(&uwsgi.lock_static);
|
||||
|
||||
struct uwsgi_dyn_dict *udd = uwsgi.mimetypes;
|
||||
while (udd) {
|
||||
if (!uwsgi_strncmp(ext, count, udd->key, udd->keylen)) {
|
||||
@@ -361,11 +365,16 @@ char *uwsgi_get_mime_type(char *name, int namelen, size_t *size) {
|
||||
}
|
||||
}
|
||||
*size = udd->vallen;
|
||||
if (uwsgi.threads > 1)
|
||||
pthread_mutex_unlock(&uwsgi.lock_static);
|
||||
return udd->value;
|
||||
}
|
||||
udd = udd->next;
|
||||
}
|
||||
|
||||
if (uwsgi.threads > 1)
|
||||
pthread_mutex_unlock(&uwsgi.lock_static);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -431,14 +440,12 @@ int uwsgi_real_file_serve(struct wsgi_request *wsgi_req, char *real_filename, si
|
||||
|
||||
size_t mime_type_size = 0;
|
||||
char http_last_modified[49];
|
||||
|
||||
if (uwsgi.threads > 1)
|
||||
pthread_mutex_lock(&uwsgi.lock_static);
|
||||
int use_gzip = 0;
|
||||
|
||||
char *mime_type = uwsgi_get_mime_type(real_filename, real_filename_len, &mime_type_size);
|
||||
|
||||
if (uwsgi.threads > 1)
|
||||
pthread_mutex_unlock(&uwsgi.lock_static);
|
||||
// here we need to choose if we want the gzip variant;
|
||||
if (uwsgi_static_want_gzip(wsgi_req, real_filename, real_filename_len, st)) use_gzip = 1;
|
||||
|
||||
if (wsgi_req->if_modified_since_len) {
|
||||
time_t ims = parse_http_date(wsgi_req->if_modified_since, wsgi_req->if_modified_since_len);
|
||||
@@ -451,6 +458,7 @@ int uwsgi_real_file_serve(struct wsgi_request *wsgi_req, char *real_filename, si
|
||||
uwsgi_log("[uwsgi-fileserve] file %s found\n", real_filename);
|
||||
#endif
|
||||
|
||||
|
||||
size_t fsize = st->st_size;
|
||||
if (wsgi_req->range_to) {
|
||||
fsize = wsgi_req->range_to - wsgi_req->range_from;
|
||||
@@ -462,7 +470,7 @@ int uwsgi_real_file_serve(struct wsgi_request *wsgi_req, char *real_filename, si
|
||||
// reset in case of inconsistent size
|
||||
if (wsgi_req->range_from > fsize) {
|
||||
wsgi_req->range_from = 0;
|
||||
fsize = 0 ;
|
||||
fsize = 0;
|
||||
}
|
||||
else {
|
||||
fsize -= wsgi_req->range_from;
|
||||
@@ -483,6 +491,10 @@ int uwsgi_real_file_serve(struct wsgi_request *wsgi_req, char *real_filename, si
|
||||
uwsgi_add_expires_uri(wsgi_req, st);
|
||||
#endif
|
||||
|
||||
if (use_gzip) {
|
||||
if (uwsgi_response_add_header(wsgi_req, "Content-Encoding", 16, "gzip", 4)) return -1;
|
||||
}
|
||||
|
||||
// Content-Type (if available)
|
||||
if (mime_type_size > 0 && mime_type) {
|
||||
if (uwsgi_response_add_content_type(wsgi_req, mime_type, mime_type_size)) return -1;
|
||||
@@ -497,29 +509,25 @@ int uwsgi_real_file_serve(struct wsgi_request *wsgi_req, char *real_filename, si
|
||||
if (uwsgi.file_serve_mode == 1) {
|
||||
if (uwsgi_response_add_header(wsgi_req, "X-Accel-Redirect", 16, real_filename, real_filename_len)) return -1;
|
||||
// this is the final header (\r\n added)
|
||||
int size = set_http_date(st->st_mtime, http_last_modified);
|
||||
int size = uwsgi_http_date(st->st_mtime, http_last_modified);
|
||||
if (uwsgi_response_add_header(wsgi_req, "Last-Modified", 13, http_last_modified, size)) return -1;
|
||||
}
|
||||
// apache
|
||||
else if (uwsgi.file_serve_mode == 2) {
|
||||
if (uwsgi_response_add_header(wsgi_req, "X-Sendfile", 10, real_filename, real_filename_len)) return -1;
|
||||
// this is the final header (\r\n added)
|
||||
int size = set_http_date(st->st_mtime, http_last_modified);
|
||||
int size = uwsgi_http_date(st->st_mtime, http_last_modified);
|
||||
if (uwsgi_response_add_header(wsgi_req, "Last-Modified", 13, http_last_modified, size)) return -1;
|
||||
}
|
||||
// raw
|
||||
else {
|
||||
// here we need to choose if we want the gzip variant;
|
||||
if (uwsgi_static_want_gzip(wsgi_req, real_filename, real_filename_len, st)) {
|
||||
if (uwsgi_response_add_header(wsgi_req, "Content-Encoding", 16, "gzip", 4)) return -1;
|
||||
}
|
||||
// set Content-Length (to fsize NOT st->st_size)
|
||||
if (uwsgi_response_add_content_length(wsgi_req, fsize)) return -1;
|
||||
if (fsize > 0 && (wsgi_req->range_from || wsgi_req->range_to)) {
|
||||
// here use teh original size !!!
|
||||
// here use the original size !!!
|
||||
if (uwsgi_response_add_content_range(wsgi_req, wsgi_req->range_from, wsgi_req->range_to, st->st_size)) return -1;
|
||||
}
|
||||
int size = set_http_date(st->st_mtime, http_last_modified);
|
||||
int size = uwsgi_http_date(st->st_mtime, http_last_modified);
|
||||
if (uwsgi_response_add_header(wsgi_req, "Last-Modified", 13, http_last_modified, size)) return -1;
|
||||
|
||||
// if it is a HEAD request just skip transfer
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
#include <uwsgi.h>
|
||||
|
||||
/*
|
||||
|
||||
uWSGI transformations
|
||||
|
||||
responses can be buffered in the wsgi_request structure (instead of being sent to the client)
|
||||
Before closing the request, the transformations are applied in chain to the response buffer
|
||||
|
||||
Finally the resulting buffer is sent to the client
|
||||
|
||||
Transformations (if required) could completely swallow already set headers
|
||||
|
||||
*/
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
int uwsgi_apply_transformations(struct wsgi_request *wsgi_req) {
|
||||
int ret = 0;
|
||||
struct uwsgi_transformation *ut = wsgi_req->transformations;
|
||||
while(ut) {
|
||||
struct uwsgi_buffer *new_ub = NULL;
|
||||
if (ut->func(wsgi_req, wsgi_req->response_buffer, &new_ub, ut->data)) {
|
||||
ret = -1;
|
||||
goto end;
|
||||
}
|
||||
if (new_ub) {
|
||||
uwsgi_buffer_destroy(wsgi_req->response_buffer);
|
||||
wsgi_req->response_buffer = new_ub;
|
||||
}
|
||||
ut = ut->next;
|
||||
}
|
||||
|
||||
end:
|
||||
ut = wsgi_req->transformations;
|
||||
while(ut) {
|
||||
struct uwsgi_transformation *current_ut = ut;
|
||||
ut = ut->next;
|
||||
free(current_ut);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct uwsgi_transformation *uwsgi_add_transformation(struct wsgi_request *wsgi_req, int (*func)(struct wsgi_request *, struct uwsgi_buffer *, struct uwsgi_buffer **, void *), void *data) {
|
||||
struct uwsgi_transformation *old_ut = NULL, *ut = wsgi_req->transformations;
|
||||
while(ut) {
|
||||
old_ut = ut;
|
||||
ut = ut->next;
|
||||
}
|
||||
|
||||
ut = uwsgi_malloc(sizeof(struct uwsgi_transformation));
|
||||
ut->func = func;
|
||||
ut->next = NULL;
|
||||
ut->data = data;
|
||||
|
||||
if (old_ut) {
|
||||
old_ut->next = ut;
|
||||
}
|
||||
else {
|
||||
wsgi_req->transformations = ut;
|
||||
}
|
||||
|
||||
// start buffering
|
||||
if (!wsgi_req->response_buffer) {
|
||||
wsgi_req->response_buffer = uwsgi_buffer_new(uwsgi.page_size);
|
||||
}
|
||||
|
||||
return ut;
|
||||
}
|
||||
+86
-30
@@ -222,12 +222,11 @@ void uwsgi_set_cgroup() {
|
||||
uwsgi_error_open(cgroup_taskfile);
|
||||
exit(1);
|
||||
}
|
||||
if (fprintf(cgroup, "%d", (int) getpid()) <= 0) {
|
||||
uwsgi_log("could not set cgroup\n");
|
||||
if (fprintf(cgroup, "%d\n", (int) getpid()) <= 0 || ferror(cgroup) || fclose(cgroup)) {
|
||||
uwsgi_error("could not set cgroup");
|
||||
exit(1);
|
||||
}
|
||||
uwsgi_log("assigned process %d to cgroup %s\n", (int) getpid(), cgroup_taskfile);
|
||||
fclose(cgroup);
|
||||
free(cgroup_taskfile);
|
||||
|
||||
|
||||
@@ -248,11 +247,10 @@ void uwsgi_set_cgroup() {
|
||||
cgroup_taskfile = uwsgi_concat3(usl->value, "/", uslo->value);
|
||||
cgroup = fopen(cgroup_taskfile, "w");
|
||||
if (cgroup) {
|
||||
if (fprintf(cgroup, "%s\n", cgroup_opt) < 0) {
|
||||
if (fprintf(cgroup, "%s\n", cgroup_opt) <= 0 || ferror(cgroup) || fclose(cgroup)) {
|
||||
uwsgi_log("could not set cgroup option %s to %s\n", uslo->value, cgroup_opt);
|
||||
exit(1);
|
||||
}
|
||||
fclose(cgroup);
|
||||
uwsgi_log("set %s to %s\n", cgroup_opt, cgroup_taskfile);
|
||||
}
|
||||
free(cgroup_taskfile);
|
||||
@@ -576,6 +574,25 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
|
||||
int tmp_id;
|
||||
uint64_t tmp_rt, rss = 0, vsz = 0;
|
||||
|
||||
// flush the response buf (if any)
|
||||
if (wsgi_req->response_buffer) {
|
||||
// send the body only if transformations are successfull
|
||||
struct uwsgi_buffer *ub = wsgi_req->response_buffer;
|
||||
if (uwsgi_apply_transformations(wsgi_req) == 0) {
|
||||
// the response_buffer could be changed by translations
|
||||
ub = wsgi_req->response_buffer;
|
||||
// force true write (take flushing into account)
|
||||
wsgi_req->response_buffer = NULL;
|
||||
if (wsgi_req->response_size == 0) {
|
||||
uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);
|
||||
}
|
||||
}
|
||||
else {
|
||||
wsgi_req->write_errors++;
|
||||
}
|
||||
uwsgi_buffer_destroy(ub);
|
||||
}
|
||||
|
||||
// check if headers should be sent
|
||||
if (wsgi_req->headers) {
|
||||
if (!wsgi_req->headers_sent && !wsgi_req->headers_size && !wsgi_req->response_size) {
|
||||
@@ -599,7 +616,6 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
|
||||
uwsgi.workers[uwsgi.mywid].rss_size = rss;
|
||||
}
|
||||
|
||||
|
||||
// close the connection with the client
|
||||
if (!wsgi_req->fd_closed) {
|
||||
// NOTE, if we close the socket before receiving eventually sent data, socket layer will send a RST
|
||||
@@ -622,25 +638,6 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
|
||||
free(wsgi_req->proto_parser_buf);
|
||||
}
|
||||
|
||||
// do we need to store the response in the cache
|
||||
if (wsgi_req->cache_it) {
|
||||
// only response with a body and a status code of 200 can be cached (TODO allows it to be configurable)
|
||||
if (wsgi_req->cached_response && wsgi_req->status == 200 && wsgi_req->response_size > 0) {
|
||||
uwsgi_cache_magic_set(wsgi_req->cache_it->buf, wsgi_req->cache_it->pos,
|
||||
wsgi_req->cached_response->buf, wsgi_req->cached_response->pos, wsgi_req->cache_it_expires, UWSGI_CACHE_FLAG_UPDATE, wsgi_req->cache_it_to ? wsgi_req->cache_it_to->buf : NULL);
|
||||
}
|
||||
uwsgi_buffer_destroy(wsgi_req->cache_it);
|
||||
|
||||
}
|
||||
|
||||
if (wsgi_req->cache_it_to) {
|
||||
uwsgi_buffer_destroy(wsgi_req->cache_it_to);
|
||||
}
|
||||
|
||||
if (wsgi_req->cached_response) {
|
||||
uwsgi_buffer_destroy(wsgi_req->cached_response);
|
||||
}
|
||||
|
||||
if (!wsgi_req->do_not_account) {
|
||||
uwsgi.workers[0].requests++;
|
||||
uwsgi.workers[uwsgi.mywid].requests++;
|
||||
@@ -1141,11 +1138,36 @@ void parse_sys_envs(char **envs) {
|
||||
}
|
||||
|
||||
// get the application id
|
||||
int uwsgi_get_app_id(char *app_name, int app_name_len, int modifier1) {
|
||||
int uwsgi_get_app_id(struct wsgi_request *wsgi_req, char *key, uint16_t key_len, int modifier1) {
|
||||
|
||||
int i;
|
||||
struct stat st;
|
||||
int found;
|
||||
int free_appname = 0;
|
||||
|
||||
char *app_name = key;
|
||||
uint16_t app_name_len = key_len;
|
||||
|
||||
if (!app_name && wsgi_req) {
|
||||
app_name = wsgi_req->appid;
|
||||
app_name_len = wsgi_req->appid_len;
|
||||
if (app_name_len == 0) {
|
||||
if (!uwsgi.ignore_script_name) {
|
||||
app_name = wsgi_req->script_name;
|
||||
app_name_len = wsgi_req->script_name_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);
|
||||
app_name_len = wsgi_req->host_len + 1 + wsgi_req->script_name_len;
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_debug("VirtualHost KEY=%.*s\n", wsgi_req->appid_len, wsgi_req->appid);
|
||||
#endif
|
||||
free_appname = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < uwsgi_apps_cnt; i++) {
|
||||
// reset check
|
||||
@@ -1177,14 +1199,19 @@ int uwsgi_get_app_id(char *app_name, int app_name_len, int modifier1) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (modifier1 == -1)
|
||||
if (modifier1 == -1) {
|
||||
if (free_appname) free(app_name);
|
||||
return i;
|
||||
if (modifier1 == uwsgi_apps[i].modifier1)
|
||||
}
|
||||
if (modifier1 == uwsgi_apps[i].modifier1) {
|
||||
if (free_appname) free(app_name);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!uwsgi.no_default_app) {
|
||||
if (free_appname) free(app_name);
|
||||
return uwsgi.default_app;
|
||||
}
|
||||
|
||||
@@ -3236,10 +3263,9 @@ void uwsgi_write_pidfile(char *pidfile_name) {
|
||||
uwsgi_error_open(pidfile_name);
|
||||
exit(1);
|
||||
}
|
||||
if (fprintf(pidfile, "%d\n", (int) getpid()) < 0) {
|
||||
if (fprintf(pidfile, "%d\n", (int) getpid()) <= 0 || ferror(pidfile) || fclose(pidfile)) {
|
||||
uwsgi_log("could not write pidfile.\n");
|
||||
}
|
||||
fclose(pidfile);
|
||||
}
|
||||
|
||||
char *uwsgi_expand_path(char *dir, int dir_len, char *ptr) {
|
||||
@@ -3851,3 +3877,33 @@ char *uwsgi_get_header(struct wsgi_request *wsgi_req, char *hh, uint16_t len, ui
|
||||
return value;
|
||||
|
||||
}
|
||||
|
||||
static char *uwsgi_hex_table[] = {
|
||||
"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F",
|
||||
"10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1A", "1B", "1C", "1D", "1E", "1F",
|
||||
"20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F",
|
||||
"30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3A", "3B", "3C", "3D", "3E", "3F",
|
||||
"40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4A", "4B", "4C", "4D", "4E", "4F",
|
||||
"50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5A", "5B", "5C", "5D", "5E", "5F",
|
||||
"60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6A", "6B", "6C", "6D", "6E", "6F",
|
||||
"70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7A", "7B", "7C", "7D", "7E", "7F",
|
||||
"80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8A", "8B", "8C", "8D", "8E", "8F",
|
||||
"90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9A", "9B", "9C", "9D", "9E", "9F",
|
||||
"A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "AA", "AB", "AC", "AD", "AE", "AF",
|
||||
"B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF",
|
||||
"C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CA", "CB", "CC", "CD", "CE", "CF",
|
||||
"D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF",
|
||||
"E0", "E1", "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "EA", "EB", "EC", "ED", "EE", "EF",
|
||||
"F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF",
|
||||
};
|
||||
|
||||
char *uwsgi_str_to_hex(char *src, size_t slen) {
|
||||
char *dst = uwsgi_malloc(slen*2);
|
||||
char *ptr = dst;
|
||||
size_t i;
|
||||
for(i=0;i<slen;i++) {
|
||||
memcpy(ptr, uwsgi_hex_table[ (int) src[i] ], 2);
|
||||
ptr+=2;
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
+40
-3
@@ -24,6 +24,7 @@
|
||||
#include <uwsgi.h>
|
||||
|
||||
struct uwsgi_server uwsgi;
|
||||
pid_t masterpid;
|
||||
|
||||
#if defined(__APPLE__) && defined(UWSGI_AS_SHARED_LIBRARY)
|
||||
#include <crt_externs.h>
|
||||
@@ -73,6 +74,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
|
||||
{"config", required_argument, 0, "load configuration using the pluggable system", uwsgi_opt_load_config, NULL, UWSGI_OPT_IMMEDIATE},
|
||||
|
||||
{"skip-zero", no_argument, 0, "skip check of file descriptor 0", uwsgi_opt_true, &uwsgi.skip_zero, 0},
|
||||
{"skip-atexit", no_argument, 0, "skip atexit hooks (ignored by the master)", uwsgi_opt_true, &uwsgi.skip_atexit, 0},
|
||||
|
||||
{"set", required_argument, 'S', "set a custom placeholder", uwsgi_opt_set_placeholder, NULL, UWSGI_OPT_IMMEDIATE},
|
||||
{"get", required_argument, 0, "print the specified option value and exit", uwsgi_opt_add_string_list, &uwsgi.get_list, UWSGI_OPT_NO_INITIAL},
|
||||
@@ -216,6 +218,9 @@ static struct uwsgi_option uwsgi_base_options[] = {
|
||||
{"ftok", required_argument, 0, "set the ipcsem key via ftok() for avoiding duplicates", uwsgi_opt_set_str, &uwsgi.ftok, 0},
|
||||
{"sharedarea", required_argument, 'A', "create a raw shared memory area of specified pages", uwsgi_opt_set_int, &uwsgi.sharedareasize, 0},
|
||||
|
||||
{"safe-fd", no_argument, 0, "do not close the specified file descriptor", uwsgi_opt_safe_fd, NULL, 0},
|
||||
{"fd-safe", no_argument, 0, "do not close the specified file descriptor", uwsgi_opt_safe_fd, NULL, 0},
|
||||
|
||||
{"cache", required_argument, 0, "create a shared cache containing given elements", uwsgi_opt_set_64bit, &uwsgi.cache_max_items, 0},
|
||||
{"cache-blocksize", required_argument, 0, "set cache blocksize", uwsgi_opt_set_64bit, &uwsgi.cache_blocksize, 0},
|
||||
{"cache-store", required_argument, 0, "enable persistent cache to disk", uwsgi_opt_set_str, &uwsgi.cache_store, UWSGI_OPT_MASTER},
|
||||
@@ -226,8 +231,12 @@ static struct uwsgi_option uwsgi_base_options[] = {
|
||||
{"cache-udp-server", required_argument, 0, "bind the cache udp server (used only for set/update/delete) to the specified socket", uwsgi_opt_add_string_list, &uwsgi.cache_udp_server, UWSGI_OPT_MASTER},
|
||||
{"cache-udp-node", required_argument, 0, "send cache update/deletion to the specified cache udp server", uwsgi_opt_add_string_list, &uwsgi.cache_udp_node, UWSGI_OPT_MASTER},
|
||||
{"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},
|
||||
|
||||
{"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},
|
||||
#endif
|
||||
|
||||
{"cache2", required_argument, 0, "create a new generation shared cache (keyval syntax)", uwsgi_opt_add_string_list, &uwsgi.cache2, 0},
|
||||
|
||||
@@ -370,6 +379,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
|
||||
|
||||
#ifdef UWSGI_SSL
|
||||
{"legion", required_argument, 0, "became a member of a legion", uwsgi_opt_legion, NULL, UWSGI_OPT_MASTER},
|
||||
{"legion-mcast", required_argument, 0, "became a member of a legion (shortcut for multicast)", uwsgi_opt_legion_mcast, NULL, UWSGI_OPT_MASTER},
|
||||
{"legion-node", required_argument, 0, "add a node to a legion", uwsgi_opt_legion_node, NULL, UWSGI_OPT_MASTER},
|
||||
{"legion-freq", required_argument, 0, "set the frequency of legion packets", uwsgi_opt_set_int, &uwsgi.legion_freq, UWSGI_OPT_MASTER},
|
||||
{"legion-tolerance", required_argument, 0, "set the tolerance of legion subsystem", uwsgi_opt_set_int, &uwsgi.legion_tolerance, UWSGI_OPT_MASTER},
|
||||
@@ -446,6 +456,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
|
||||
#endif
|
||||
{"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},
|
||||
#ifdef UWSGI_PCRE
|
||||
{"log-alarm", required_argument, 0, "raise the specified alarm when a log line matches the specified regexp, syntax: <alarm>[,alarm...] <regexp>", uwsgi_opt_add_string_list, &uwsgi.alarm_logs_list, UWSGI_OPT_MASTER | UWSGI_OPT_LOG_MASTER},
|
||||
{"alarm-log", required_argument, 0, "raise the specified alarm when a log line matches the specified regexp, syntax: <alarm>[,alarm...] <regexp>", uwsgi_opt_add_string_list, &uwsgi.alarm_logs_list, UWSGI_OPT_MASTER | UWSGI_OPT_LOG_MASTER},
|
||||
@@ -586,6 +597,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
|
||||
{"env", required_argument, 0, "set environment variable", uwsgi_opt_set_env, NULL, 0},
|
||||
{"unenv", required_argument, 0, "unset environment variable", uwsgi_opt_unset_env, NULL, 0},
|
||||
{"vacuum", no_argument, 0, "try to remove all of the generated file/sockets", uwsgi_opt_true, &uwsgi.vacuum, 0},
|
||||
{"file-write", required_argument, 0, "write the specified content to the specified file (syntax: file=value) before privileges drop", uwsgi_opt_add_string_list, &uwsgi.file_write_list, 0},
|
||||
#ifdef __linux__
|
||||
{"cgroup", required_argument, 0, "put the processes in the specified cgroup", uwsgi_opt_add_string_list, &uwsgi.cgroup, 0},
|
||||
{"cgroup-opt", required_argument, 0, "set value in specified cgroup option", uwsgi_opt_add_string_list, &uwsgi.cgroup_opt, 0},
|
||||
@@ -605,6 +617,10 @@ static struct uwsgi_option uwsgi_base_options[] = {
|
||||
{"zerg-server", required_argument, 0, "enable the zerg server on the specified UNIX socket", uwsgi_opt_set_str, &uwsgi.zerg_server, UWSGI_OPT_MASTER},
|
||||
|
||||
{"cron", required_argument, 0, "add a cron task", uwsgi_opt_add_cron, NULL, UWSGI_OPT_MASTER},
|
||||
#ifdef UWSGI_SSL
|
||||
{"legion-cron", required_argument, 0, "add a cron task runnable only when the instance is a lord of the specified legion", uwsgi_opt_add_legion_cron, NULL, UWSGI_OPT_MASTER},
|
||||
{"cron-legion", required_argument, 0, "add a cron task runnable only when the instance is a lord of the specified legion", uwsgi_opt_add_legion_cron, NULL, UWSGI_OPT_MASTER},
|
||||
#endif
|
||||
{"loop", required_argument, 0, "select the uWSGI loop engine", uwsgi_opt_set_str, &uwsgi.loop, 0},
|
||||
{"loop-list", no_argument, 0, "list enabled loop engines", uwsgi_opt_true, &uwsgi.loop_list, 0},
|
||||
{"loops-list", no_argument, 0, "list enabled loop engines", uwsgi_opt_true, &uwsgi.loop_list, 0},
|
||||
@@ -944,6 +960,10 @@ void gracefully_kill(int signum) {
|
||||
}
|
||||
|
||||
void end_me(int signum) {
|
||||
if (getpid() != masterpid && uwsgi.skip_atexit) {
|
||||
_exit(UWSGI_END_CODE);
|
||||
// never here
|
||||
}
|
||||
exit(UWSGI_END_CODE);
|
||||
}
|
||||
|
||||
@@ -1200,7 +1220,6 @@ void what_i_am_doing() {
|
||||
}
|
||||
|
||||
|
||||
pid_t masterpid;
|
||||
|
||||
int unconfigured_hook(struct wsgi_request *wsgi_req) {
|
||||
uwsgi_log("-- unavailable modifier requested: %d --\n", wsgi_req->uh->modifier1);
|
||||
@@ -2048,6 +2067,8 @@ int uwsgi_start(void *v_argv) {
|
||||
}
|
||||
#endif
|
||||
|
||||
uwsgi_file_write_do(uwsgi.file_write_list);
|
||||
|
||||
if (!uwsgi.master_as_root && !uwsgi.chown_socket) {
|
||||
uwsgi_as_root();
|
||||
}
|
||||
@@ -2352,7 +2373,8 @@ int uwsgi_start(void *v_argv) {
|
||||
!uwsgi.udp_socket &&
|
||||
!uwsgi.emperor &&
|
||||
!uwsgi.command_mode &&
|
||||
!uwsgi.daemons_cnt
|
||||
!uwsgi.daemons_cnt &&
|
||||
!uwsgi.crons
|
||||
#ifdef UWSGI_SSL
|
||||
&& !uwsgi.legions
|
||||
#endif
|
||||
@@ -2415,7 +2437,14 @@ unsafe:
|
||||
if (uwsgi.crons) {
|
||||
struct uwsgi_cron *ucron = uwsgi.crons;
|
||||
while (ucron) {
|
||||
uwsgi_log("command \"%s\" registered as uWSGI-cron task\n", ucron->command);
|
||||
#ifdef UWSGI_SSL
|
||||
if (ucron->legion) {
|
||||
uwsgi_log("[uwsgi-cron] command \"%s\" registered as cron task for legion \"%s\"\n", ucron->command, ucron->legion);
|
||||
ucron = ucron->next;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
uwsgi_log("[uwsgi-cron] command \"%s\" registered as cron task\n", ucron->command);
|
||||
ucron = ucron->next;
|
||||
}
|
||||
}
|
||||
@@ -3244,6 +3273,14 @@ void uwsgi_opt_set_immediate_uid(char *opt, char *value, void *none) {
|
||||
uwsgi_log("immediate uid: %d\n", (int) uid);
|
||||
}
|
||||
|
||||
void uwsgi_opt_safe_fd(char *opt, char *value, void *foobar) {
|
||||
int fd = atoi(value);
|
||||
if (fd < 0) {
|
||||
uwsgi_log("invalid file descriptor: %d\n", fd);
|
||||
exit(1);
|
||||
}
|
||||
uwsgi_add_safe_fd(fd);
|
||||
}
|
||||
|
||||
void uwsgi_opt_set_int(char *opt, char *value, void *key) {
|
||||
int *ptr = (int *) key;
|
||||
|
||||
+37
-15
@@ -12,6 +12,17 @@ int uwsgi_response_add_content_length(struct wsgi_request *wsgi_req, uint64_t cl
|
||||
return uwsgi_response_add_header(wsgi_req, "Content-Length", 14, buf, ret);
|
||||
}
|
||||
|
||||
int uwsgi_response_add_expires(struct wsgi_request *wsgi_req, uint64_t t) {
|
||||
// 30+1
|
||||
char expires[31];
|
||||
int len = uwsgi_http_date((time_t) t, expires);
|
||||
if (!len) {
|
||||
wsgi_req->write_errors++;
|
||||
return -1;
|
||||
}
|
||||
return uwsgi_response_add_header(wsgi_req, "Expires", 7, expires, len);
|
||||
}
|
||||
|
||||
int uwsgi_response_add_content_range(struct wsgi_request *wsgi_req, uint64_t start, uint64_t end, uint64_t cl) {
|
||||
char buf[6+(sizeof(UMAX64_STR)*3)+4];
|
||||
if (end == 0) {
|
||||
@@ -25,6 +36,12 @@ int uwsgi_response_add_content_range(struct wsgi_request *wsgi_req, uint64_t sta
|
||||
return uwsgi_response_add_header(wsgi_req, "Content-Range", 13, buf, ret);
|
||||
}
|
||||
|
||||
int uwsgi_response_prepare_headers_int(struct wsgi_request *wsgi_req, int status) {
|
||||
char status_str[11];
|
||||
uwsgi_num2str2(status, status_str);
|
||||
return uwsgi_response_prepare_headers(wsgi_req, status_str, 3);
|
||||
}
|
||||
|
||||
// status could be NNN or NNN message
|
||||
int uwsgi_response_prepare_headers(struct wsgi_request *wsgi_req, char *status, uint16_t status_len) {
|
||||
|
||||
@@ -159,7 +176,8 @@ int uwsgi_response_write_body_do(struct wsgi_request *wsgi_req, char *buf, size_
|
||||
|
||||
if (wsgi_req->write_errors) return -1;
|
||||
|
||||
if (!wsgi_req->headers_sent) {
|
||||
// do not commit headers until a response_buffer is available (take in account flushing)
|
||||
if ((wsgi_req->flush || !wsgi_req->response_buffer) && !wsgi_req->headers_sent) {
|
||||
int ret = uwsgi_response_write_headers_do(wsgi_req);
|
||||
if (ret == UWSGI_OK) goto sendbody;
|
||||
if (ret == UWSGI_AGAIN) return UWSGI_AGAIN;
|
||||
@@ -170,6 +188,15 @@ int uwsgi_response_write_body_do(struct wsgi_request *wsgi_req, char *buf, size_
|
||||
sendbody:
|
||||
|
||||
if (len == 0) return UWSGI_OK;
|
||||
|
||||
if (wsgi_req->response_buffer) {
|
||||
if (uwsgi_buffer_append(wsgi_req->response_buffer, buf, len)) {
|
||||
wsgi_req->write_errors++;
|
||||
return -1;
|
||||
}
|
||||
if (!wsgi_req->flush)
|
||||
return UWSGI_OK;
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
int ret = wsgi_req->socket->proto_write(wsgi_req, buf, len);
|
||||
@@ -196,18 +223,6 @@ sendbody:
|
||||
// reset for the next write
|
||||
wsgi_req->write_pos = 0;
|
||||
|
||||
// now we need to check if the chunk must be stored
|
||||
if (wsgi_req->cache_it) {
|
||||
if (!wsgi_req->cached_response) {
|
||||
wsgi_req->cached_response = uwsgi_buffer_new(len);
|
||||
}
|
||||
// if we are unable to append the buffer, we just stop caching it
|
||||
if (uwsgi_buffer_append(wsgi_req->cached_response, buf, len)) {
|
||||
uwsgi_buffer_destroy(wsgi_req->cache_it);
|
||||
wsgi_req->cache_it = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return UWSGI_OK;
|
||||
}
|
||||
|
||||
@@ -217,7 +232,10 @@ int uwsgi_response_sendfile_do(struct wsgi_request *wsgi_req, int fd, size_t pos
|
||||
|
||||
if (fd == wsgi_req->sendfile_fd) can_close = 0;
|
||||
|
||||
if (wsgi_req->write_errors) return -1;
|
||||
if (wsgi_req->write_errors) {
|
||||
if (can_close) close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!wsgi_req->headers_sent) {
|
||||
int ret = uwsgi_response_write_headers_do(wsgi_req);
|
||||
@@ -238,7 +256,10 @@ sendfile:
|
||||
if (can_close) close(fd);
|
||||
return -1;
|
||||
}
|
||||
if (pos >= (size_t)st.st_size) return UWSGI_OK;
|
||||
if (pos >= (size_t)st.st_size) {
|
||||
if (can_close) close(fd);
|
||||
return UWSGI_OK;
|
||||
}
|
||||
len = st.st_size;
|
||||
}
|
||||
|
||||
@@ -290,6 +311,7 @@ sendfile:
|
||||
if (ret == 0) {
|
||||
uwsgi_log("uwsgi_response_sendfile_do() TIMEOUT !!!\n");
|
||||
wsgi_req->write_errors++;
|
||||
if (can_close) close(fd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
+32
@@ -1,5 +1,37 @@
|
||||
#include <uwsgi.h>
|
||||
|
||||
static char gzheader[10] = { 0x1f, 0x8b, Z_DEFLATED, 0, 0, 0, 0, 0, 0, 3 };
|
||||
|
||||
struct uwsgi_buffer *uwsgi_gzip(char *buf, size_t len) {
|
||||
z_stream z;
|
||||
struct uwsgi_buffer *ub = NULL;
|
||||
uint32_t gzip_crc32 = 0;
|
||||
char *gzipped = NULL;
|
||||
char *gzipped0 = NULL;
|
||||
size_t dlen = 0;
|
||||
size_t dlen0 = 0;
|
||||
|
||||
uwsgi_crc32(&gzip_crc32, NULL, 0);
|
||||
if (uwsgi_deflate_init(&z, NULL, 0)) return NULL;
|
||||
uwsgi_crc32(&gzip_crc32, buf, len);
|
||||
|
||||
gzipped = uwsgi_deflate(&z, buf, len, &dlen);
|
||||
if (!gzipped) goto end;
|
||||
gzipped0 = uwsgi_deflate(&z, NULL, 0, &dlen0);
|
||||
if (!gzipped0) goto end;
|
||||
|
||||
ub = uwsgi_buffer_new(10 + dlen + dlen0 + 8);
|
||||
if (uwsgi_buffer_append(ub, gzheader, 10)) goto end;
|
||||
if (uwsgi_buffer_append(ub, gzipped, dlen)) goto end;
|
||||
if (uwsgi_buffer_append(ub, gzipped0, dlen0)) goto end;
|
||||
if (uwsgi_buffer_u32le(ub, gzip_crc32)) goto end;
|
||||
if (uwsgi_buffer_u32le(ub, len)) goto end;
|
||||
end:
|
||||
if (gzipped) free(gzipped);
|
||||
if (gzipped0) free(gzipped0);
|
||||
deflateEnd(&z);
|
||||
return ub;
|
||||
}
|
||||
|
||||
int uwsgi_deflate_init(z_stream *z, char *dict, size_t dict_len) {
|
||||
z->zalloc = Z_NULL;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,3 +0,0 @@
|
||||
ngx_addon_name=ngx_http_uwsgi_module
|
||||
HTTP_MODULES="$HTTP_MODULES ngx_http_uwsgi_module"
|
||||
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_uwsgi_module.c"
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,16 +0,0 @@
|
||||
|
||||
uwsgi_param QUERY_STRING $query_string;
|
||||
uwsgi_param REQUEST_METHOD $request_method;
|
||||
uwsgi_param CONTENT_TYPE $content_type;
|
||||
uwsgi_param CONTENT_LENGTH $content_length;
|
||||
|
||||
uwsgi_param REQUEST_URI $request_uri;
|
||||
uwsgi_param PATH_INFO $document_uri;
|
||||
uwsgi_param DOCUMENT_ROOT $document_root;
|
||||
uwsgi_param SERVER_PROTOCOL $server_protocol;
|
||||
|
||||
uwsgi_param REMOTE_ADDR $remote_addr;
|
||||
uwsgi_param REMOTE_PORT $remote_port;
|
||||
uwsgi_param SERVER_ADDR $server_addr;
|
||||
uwsgi_param SERVER_PORT $server_port;
|
||||
uwsgi_param SERVER_NAME $server_name;
|
||||
Vendored
+9
-5
@@ -40,7 +40,7 @@ static void cache_simple_command(char *key, uint16_t keylen, char *val, uint16_t
|
||||
if (vallen > 0) {
|
||||
if (!uwsgi_strncmp(key, keylen, "key", 3)) {
|
||||
uint64_t vallen = 0;
|
||||
char *value = uwsgi_cache_magic_get(val, vallen, &vallen, NULL);
|
||||
char *value = uwsgi_cache_magic_get(val, vallen, &vallen, NULL, NULL);
|
||||
if (value) {
|
||||
uwsgi_response_write_body_do(wsgi_req, value, vallen);
|
||||
free(value);
|
||||
@@ -49,7 +49,7 @@ static void cache_simple_command(char *key, uint16_t keylen, char *val, uint16_t
|
||||
}
|
||||
else if (!uwsgi_strncmp(key, keylen, "get", 3)) {
|
||||
uint64_t vallen = 0;
|
||||
char *value = uwsgi_cache_magic_get(val, vallen, &vallen, NULL);
|
||||
char *value = uwsgi_cache_magic_get(val, vallen, &vallen, NULL, NULL);
|
||||
if (value) {
|
||||
uwsgi_response_write_body_do(wsgi_req, value, vallen);
|
||||
free(value);
|
||||
@@ -77,8 +77,9 @@ static void manage_magic_context(struct wsgi_request *wsgi_req, struct uwsgi_cac
|
||||
// cache get
|
||||
if (!uwsgi_strncmp(ucmc->cmd, ucmc->cmd_len, "get", 3)) {
|
||||
uint64_t vallen = 0;
|
||||
uint64_t expires = 0;
|
||||
uwsgi_rlock(uc->lock);
|
||||
char *value = uwsgi_cache_get2(uc, ucmc->key, ucmc->key_len, &vallen);
|
||||
char *value = uwsgi_cache_get3(uc, ucmc->key, ucmc->key_len, &vallen, &expires);
|
||||
if (!value) {
|
||||
uwsgi_rwunlock(uc->lock);
|
||||
return;
|
||||
@@ -88,6 +89,9 @@ static void manage_magic_context(struct wsgi_request *wsgi_req, struct uwsgi_cac
|
||||
ub->pos = 4;
|
||||
if (uwsgi_buffer_append_keyval(ub, "status", 6, "ok", 2)) goto error;
|
||||
if (uwsgi_buffer_append_keynum(ub, "size", 4, vallen)) goto error;
|
||||
if (expires) {
|
||||
if (uwsgi_buffer_append_keynum(ub, "expires", 7, expires)) goto error;
|
||||
}
|
||||
if (uwsgi_buffer_set_uh(ub, 111, 17)) goto error;
|
||||
if (uwsgi_buffer_append(ub, value, vallen)) goto error;
|
||||
// unlock !!!
|
||||
@@ -205,7 +209,7 @@ static int uwsgi_cache_request(struct wsgi_request *wsgi_req) {
|
||||
case 0:
|
||||
// get
|
||||
if (wsgi_req->uh->pktsize > 0) {
|
||||
value = uwsgi_cache_magic_get(wsgi_req->buffer, wsgi_req->uh->pktsize, &vallen, NULL);
|
||||
value = uwsgi_cache_magic_get(wsgi_req->buffer, wsgi_req->uh->pktsize, &vallen, NULL, NULL);
|
||||
if (value) {
|
||||
wsgi_req->uh->pktsize = vallen;
|
||||
if (uwsgi_response_write_body_do(wsgi_req, (char *)&wsgi_req->uh, 4)) { free(value) ; return -1;}
|
||||
@@ -242,7 +246,7 @@ static int uwsgi_cache_request(struct wsgi_request *wsgi_req) {
|
||||
case 5:
|
||||
// get (uwsgi + stream)
|
||||
if (wsgi_req->uh->pktsize > 0) {
|
||||
value = uwsgi_cache_magic_get(wsgi_req->buffer, wsgi_req->uh->pktsize, &vallen, NULL);
|
||||
value = uwsgi_cache_magic_get(wsgi_req->buffer, wsgi_req->uh->pktsize, &vallen, NULL, NULL);
|
||||
if (value) {
|
||||
wsgi_req->uh->pktsize = 0;
|
||||
wsgi_req->uh->modifier2 = 1;
|
||||
|
||||
@@ -701,7 +701,8 @@ void uwsgi_corerouter_loop(int id, void *data) {
|
||||
if (ucr->use_cache) {
|
||||
ucr->cache = uwsgi_cache_by_name(ucr->use_cache);
|
||||
if (!ucr->cache) {
|
||||
uwsgi_log("unable to find cache \"%s\"\n", ucr->use_cache);
|
||||
uwsgi_log("!!! unable to find cache \"%s\" !!!\n", ucr->use_cache);
|
||||
exit(1);
|
||||
}
|
||||
ucr->mapper = uwsgi_cr_map_use_cache;
|
||||
}
|
||||
@@ -899,7 +900,7 @@ int uwsgi_corerouter_init(struct uwsgi_corerouter *ucr) {
|
||||
|
||||
if (ucr->has_sockets) {
|
||||
|
||||
if (ucr->use_cache && !uwsgi.cache_max_items) {
|
||||
if (ucr->use_cache && !uwsgi.caches) {
|
||||
uwsgi_log("you need to create a uwsgi cache to use the %s (add --cache <n>)\n", ucr->name);
|
||||
exit(1);
|
||||
}
|
||||
@@ -945,7 +946,7 @@ void corerouter_send_stats(struct uwsgi_corerouter *ucr) {
|
||||
|
||||
int client_fd = accept(ucr->cr_stats_server, (struct sockaddr *) &client_src, &client_src_len);
|
||||
if (client_fd < 0) {
|
||||
uwsgi_error("accept()");
|
||||
uwsgi_error("corerouter_send_stats()/accept()");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -173,7 +173,7 @@ void uwsgi_corerouter_manage_subscription(struct uwsgi_corerouter *ucr, int id,
|
||||
continue;
|
||||
if (!strcmp(ushared->gateways[i].name, ucr->name)) {
|
||||
if (send(ushared->gateways[i].internal_subscription_pipe[0], bbuf, len, 0) != len) {
|
||||
uwsgi_error("send()");
|
||||
uwsgi_error("uwsgi_corerouter_manage_subscription()/send()");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,7 +171,7 @@ end:
|
||||
}
|
||||
|
||||
XS(XS_coroae_sighandler) {
|
||||
int sigfd = (int) XSANY.any_ptr;
|
||||
int sigfd = (long) XSANY.any_ptr;
|
||||
uwsgi_receive_signal(sigfd, "worker", uwsgi.mywid);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
#include <uwsgi.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
static void curl_cron_func(struct uwsgi_cron *uc, time_t now) {
|
||||
CURL *curl = curl_easy_init();
|
||||
// ARGH !!!
|
||||
if (!curl) return;
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, uc->command);
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
||||
// use 1 minute as the cron resolution
|
||||
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60);
|
||||
uwsgi_log("[uwsgi-curl-cron] requesting %s\n", uc->command);
|
||||
CURLcode res = curl_easy_perform(curl);
|
||||
if (res != CURLE_OK) {
|
||||
uwsgi_log("[uwsgi-curl-cron] curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
|
||||
}
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
static void uwsgi_opt_add_cron_curl(char *opt, char *value, void *foobar) {
|
||||
struct uwsgi_cron *uc = uwsgi_cron_add(value);
|
||||
uc->func = curl_cron_func;
|
||||
}
|
||||
|
||||
#ifdef UWSGI_SSL
|
||||
static void uwsgi_opt_add_legion_cron_curl(char *opt, char *value, void *foobar) {
|
||||
char *space = strchr(value, ' ');
|
||||
if (!space) {
|
||||
uwsgi_log("invalid %s syntax, must be prefixed with a legion name\n", opt);
|
||||
exit(1);
|
||||
}
|
||||
char *legion = uwsgi_concat2n(value, space-value, "", 0);
|
||||
struct uwsgi_cron *uc = uwsgi_cron_add(space+1);
|
||||
uc->legion = legion;
|
||||
uc->func = curl_cron_func;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct uwsgi_option curl_cron_options[] = {
|
||||
{"curl-cron", required_argument, 0, "add a cron task invoking the specified url via CURL", uwsgi_opt_add_cron_curl, NULL, UWSGI_OPT_MASTER},
|
||||
{"cron-curl", required_argument, 0, "add a cron task invoking the specified url via CURL", uwsgi_opt_add_cron_curl, NULL, UWSGI_OPT_MASTER},
|
||||
#ifdef UWSGI_SSL
|
||||
{"legion-curl-cron", required_argument, 0, "add a cron task invoking the specified url via CURL runnable only when the instance is a lord of the specified legion", uwsgi_opt_add_legion_cron_curl, NULL, UWSGI_OPT_MASTER},
|
||||
{"legion-cron-curl", required_argument, 0, "add a cron task invoking the specified url via CURL runnable only when the instance is a lord of the specified legion", uwsgi_opt_add_legion_cron_curl, NULL, UWSGI_OPT_MASTER},
|
||||
{"curl-cron-legion", required_argument, 0, "add a cron task invoking the specified url via CURL runnable only when the instance is a lord of the specified legion", uwsgi_opt_add_legion_cron_curl, NULL, UWSGI_OPT_MASTER},
|
||||
{"cron-curl-legion", required_argument, 0, "add a cron task invoking the specified url via CURL runnable only when the instance is a lord of the specified legion", uwsgi_opt_add_legion_cron_curl, NULL, UWSGI_OPT_MASTER},
|
||||
#endif
|
||||
{ 0, 0, 0, 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
struct uwsgi_plugin curl_cron_plugin = {
|
||||
.name = "curl_cron",
|
||||
.options = curl_cron_options,
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
NAME='curl_cron'
|
||||
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = ['-lcurl']
|
||||
GCC_LIST = ['curl_cron']
|
||||
@@ -150,7 +150,7 @@ func CacheGet(key string, cache string) []byte {
|
||||
|
||||
var p []byte
|
||||
|
||||
c_value := C.uwsgi_cache_magic_get(k, C.uint16_t(kl), &vl, c)
|
||||
c_value := C.uwsgi_cache_magic_get(k, C.uint16_t(kl), &vl, (*C.uint64_t)(nil), c)
|
||||
|
||||
if c_value != nil {
|
||||
p = C.GoBytes((unsafe.Pointer)(c_value), C.int(vl))
|
||||
|
||||
@@ -197,14 +197,7 @@ extern "C" int uwsgi_gridfs_request(struct wsgi_request *wsgi_req) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (wsgi_req->appid_len == 0) {
|
||||
if (!uwsgi.ignore_script_name) {
|
||||
wsgi_req->appid = wsgi_req->script_name;
|
||||
wsgi_req->appid_len = wsgi_req->script_name_len;
|
||||
}
|
||||
}
|
||||
|
||||
wsgi_req->app_id = uwsgi_get_app_id(wsgi_req->appid, wsgi_req->appid_len, gridfs_plugin.modifier1);
|
||||
wsgi_req->app_id = uwsgi_get_app_id(wsgi_req, wsgi_req->appid, wsgi_req->appid_len, gridfs_plugin.modifier1);
|
||||
if (ugridfs.debug) {
|
||||
uwsgi_log("[uwsgi-gridfs-debug] app_id = %d\n", wsgi_req->app_id);
|
||||
}
|
||||
@@ -238,6 +231,9 @@ extern "C" int uwsgi_gridfs_request(struct wsgi_request *wsgi_req) {
|
||||
|
||||
|
||||
extern "C" void uwsgi_gridfs_mount() {
|
||||
if (!uwsgi.skip_atexit) {
|
||||
uwsgi_log("*** WARNING libmongoclient could have a bug with atexit() hooks, if you get segfault on end/reload, add --skip-atexit ***\n");
|
||||
}
|
||||
struct uwsgi_string_list *usl = ugridfs.mountpoints;
|
||||
while(usl) {
|
||||
if (uwsgi_apps_cnt >= uwsgi.max_apps) {
|
||||
|
||||
+13
-8
@@ -90,31 +90,35 @@ int http_add_uwsgi_header(struct corerouter_peer *peer, char *hh, uint16_t hhlen
|
||||
if (!keylen)
|
||||
return -1;
|
||||
|
||||
if (!uwsgi_strncmp("HOST", 4, hh, keylen)) {
|
||||
peer->key = val;
|
||||
peer->key_len = vallen;
|
||||
}
|
||||
|
||||
else if (hr->websockets) {
|
||||
if (hr->websockets) {
|
||||
if (!uwsgi_strncmp("UPGRADE", 7, hh, keylen)) {
|
||||
if (!uwsgi_strnicmp(val, vallen, "websocket", 9)) {
|
||||
hr->websockets++;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
else if (!uwsgi_strncmp("CONNECTION", 10, hh, keylen)) {
|
||||
if (!uwsgi_strnicmp(val, vallen, "Upgrade", 7)) {
|
||||
hr->websockets++;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
else if (!uwsgi_strncmp("SEC_WEBSOCKET_VERSION", 21, hh, keylen)) {
|
||||
hr->websockets++;
|
||||
hr->websockets++;
|
||||
goto done;
|
||||
}
|
||||
else if (!uwsgi_strncmp("SEC_WEBSOCKET_KEY", 17, hh, keylen)) {
|
||||
hr->websocket_key = val;
|
||||
hr->websocket_key_len = vallen;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (!uwsgi_strncmp("HOST", 4, hh, keylen)) {
|
||||
peer->key = val;
|
||||
peer->key_len = vallen;
|
||||
}
|
||||
|
||||
else if (!uwsgi_strncmp("CONTENT_LENGTH", 14, hh, keylen)) {
|
||||
hr->content_length = uwsgi_str_num(val, vallen);
|
||||
hr->session.can_keepalive = 0;
|
||||
@@ -139,12 +143,13 @@ int http_add_uwsgi_header(struct corerouter_peer *peer, char *hh, uint16_t hhlen
|
||||
}
|
||||
#endif
|
||||
|
||||
done:
|
||||
|
||||
if (uwsgi_strncmp("CONTENT_TYPE", 12, hh, keylen) && uwsgi_strncmp("CONTENT_LENGTH", 14, hh, keylen)) {
|
||||
keylen += 5;
|
||||
prefix = 1;
|
||||
}
|
||||
|
||||
|
||||
if (uwsgi_buffer_u16le(out, keylen)) return -1;
|
||||
|
||||
if (prefix) {
|
||||
|
||||
@@ -41,7 +41,7 @@ JNIEXPORT void JNICALL uwsgi_jvm_api_register_signal(JNIEnv *env, jclass c, jint
|
||||
JNIEXPORT void JNICALL uwsgi_jvm_api_register_rpc(JNIEnv *env, jclass c, jstring name, jobject func) {
|
||||
// no need to release it
|
||||
char *n = uwsgi_jvm_str2c(name);
|
||||
if (uwsgi_register_rpc(n, jvm_plugin.modifier1, 0, uwsgi_jvm_ref(func))) {
|
||||
if (uwsgi_register_rpc(n, &jvm_plugin, 0, uwsgi_jvm_ref(func))) {
|
||||
uwsgi_jvm_throw("unable to register rpc function");
|
||||
}
|
||||
}
|
||||
@@ -79,7 +79,7 @@ JNIEXPORT jobject JNICALL uwsgi_jvm_api_cache_get(JNIEnv *env, jclass c, jstring
|
||||
size_t keylen = uwsgi_jvm_strlen(jkey);
|
||||
char *key = uwsgi_jvm_str2c(jkey);
|
||||
uint64_t vallen = 0;
|
||||
char *value = uwsgi_cache_magic_get(key, keylen, &vallen, NULL);
|
||||
char *value = uwsgi_cache_magic_get(key, keylen, &vallen, NULL, NULL);
|
||||
uwsgi_jvm_release_chars(jkey, key);
|
||||
if (value) {
|
||||
jobject o = uwsgi_jvm_bytearray(value, vallen);
|
||||
@@ -99,7 +99,7 @@ JNIEXPORT jobject JNICALL uwsgi_jvm_api_cache_get_name(JNIEnv *env, jclass c, js
|
||||
char *key = uwsgi_jvm_str2c(jkey);
|
||||
char *cache = uwsgi_jvm_str2c(jcache);
|
||||
uint64_t vallen = 0;
|
||||
char *value = uwsgi_cache_magic_get(key, keylen, &vallen, cache);
|
||||
char *value = uwsgi_cache_magic_get(key, keylen, &vallen, NULL, cache);
|
||||
uwsgi_jvm_release_chars(jkey, key);
|
||||
uwsgi_jvm_release_chars(jcache, cache);
|
||||
if (value) {
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
#include <uwsgi.h>
|
||||
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
|
||||
static int legion_action_cache_fetch_from_legion(struct uwsgi_legion *ul, char *arg) {
|
||||
uwsgi_log("[legion-cache-fetch] getting cache '%s' dump from legion '%s' nodes\n", arg, ul->legion);
|
||||
|
||||
struct uwsgi_cache *uc = uwsgi_cache_by_name(arg);
|
||||
if (!uc) {
|
||||
uwsgi_log("[legion-cache-fetch] cannot sync, cache '%s' not found\n", arg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct uwsgi_string_list *dump_from_nodes = NULL;
|
||||
|
||||
uwsgi_rlock(ul->lock);
|
||||
struct uwsgi_legion_node *legion_nodes = ul->nodes_head;
|
||||
while (legion_nodes) {
|
||||
char *dump_socket = NULL;
|
||||
if (uwsgi_kvlist_parse(legion_nodes->scroll, legion_nodes->scroll_len, ',', '=',
|
||||
"dump-socket", &dump_socket,
|
||||
NULL)) {
|
||||
uwsgi_log("[legion-cache-fetch] cannot sync from %.*s, cache socket address not found in legion scroll: %.*s\n",
|
||||
legion_nodes->name_len, legion_nodes->name, legion_nodes->scroll_len, legion_nodes->scroll);
|
||||
}
|
||||
else {
|
||||
if (dump_socket) {
|
||||
uwsgi_string_new_list(&dump_from_nodes, dump_socket);
|
||||
}
|
||||
else {
|
||||
uwsgi_log("[legion-cache-fetch] cannot sync from %.*s, cache socket address not found in legion scroll: %.*s\n",
|
||||
legion_nodes->name_len, legion_nodes->name, legion_nodes->scroll_len, legion_nodes->scroll);
|
||||
}
|
||||
}
|
||||
legion_nodes = legion_nodes->next;
|
||||
}
|
||||
|
||||
// update uc->sync_nodes list
|
||||
struct uwsgi_string_list *usl = uc->sync_nodes;
|
||||
struct uwsgi_string_list *next;
|
||||
while (usl) {
|
||||
next = usl->next;
|
||||
free(usl->value);
|
||||
free(usl);
|
||||
usl = next;
|
||||
}
|
||||
uwsgi_rwunlock(ul->lock);
|
||||
|
||||
uwsgi_rlock(uc->lock);
|
||||
uc->sync_nodes = dump_from_nodes;
|
||||
uwsgi_rwunlock(uc->lock);
|
||||
|
||||
// call sync
|
||||
uwsgi_cache_sync_from_nodes(uc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void legion_cache_register() {
|
||||
uwsgi_legion_action_register("legion-cache-fetch", legion_action_cache_fetch_from_legion);
|
||||
}
|
||||
|
||||
|
||||
struct uwsgi_plugin legion_cache_fetch_plugin = {
|
||||
.name = "legion_cache_fetch",
|
||||
.on_load = legion_cache_register,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
NAME = 'legion_cache_fetch'
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = []
|
||||
|
||||
GCC_LIST = ['legion_cache_fetch']
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "../../uwsgi.h"
|
||||
#include <uwsgi.h>
|
||||
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
@@ -13,6 +13,8 @@ struct uwsgi_lua {
|
||||
struct uwsgi_string_list *load;
|
||||
} ulua;
|
||||
|
||||
struct uwsgi_plugin lua_plugin;
|
||||
|
||||
#define lca(L, n) ulua_check_args(L, __FUNCTION__, n)
|
||||
|
||||
static void uwsgi_opt_luashell(char *opt, char *value, void *foobar) {
|
||||
@@ -88,7 +90,7 @@ static int uwsgi_api_register_rpc(lua_State *L) {
|
||||
uwsgi_log("registered function %d in Lua global table\n", func);
|
||||
lfunc = func;
|
||||
|
||||
if (uwsgi_register_rpc((char *)name, 6, 0, (void *) lfunc)) {
|
||||
if (uwsgi_register_rpc((char *)name, &lua_plugin, 0, (void *) lfunc)) {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
else {
|
||||
@@ -276,7 +278,7 @@ static int uwsgi_api_cache_get(lua_State *L) {
|
||||
if (argc > 1) {
|
||||
cache = lua_tolstring(L, 2, NULL);
|
||||
}
|
||||
value = uwsgi_cache_magic_get((char *)key, keylen, &valsize, (char *)cache);
|
||||
value = uwsgi_cache_magic_get((char *)key, keylen, &valsize, NULL, (char *)cache);
|
||||
if (value) {
|
||||
lua_pushlstring(L, value, valsize);
|
||||
free(value);
|
||||
|
||||
@@ -267,7 +267,7 @@ static MonoArray *uwsgi_mono_method_api_CacheGet(MonoString *key, MonoString *ca
|
||||
c_cache = mono_string_to_utf8(cache);
|
||||
}
|
||||
uint64_t vallen = 0 ;
|
||||
char *value = uwsgi_cache_magic_get(c_key, c_keylen, &vallen, c_cache);
|
||||
char *value = uwsgi_cache_magic_get(c_key, c_keylen, &vallen, NULL, c_cache);
|
||||
if (value) {
|
||||
MonoArray *ret = mono_array_new(mono_domain_get(), umono.byte_class, vallen);
|
||||
char *buf = mono_array_addr(ret, char, 0);
|
||||
@@ -540,7 +540,7 @@ static int uwsgi_mono_request(struct wsgi_request *wsgi_req) {
|
||||
key_len = 0;
|
||||
}
|
||||
|
||||
wsgi_req->app_id = uwsgi_get_app_id(key, key_len, mono_plugin.modifier1);
|
||||
wsgi_req->app_id = uwsgi_get_app_id(NULL, key, key_len, mono_plugin.modifier1);
|
||||
// if it is -1, try to load a dynamic app
|
||||
if (wsgi_req->app_id == -1) {
|
||||
if (uwsgi.threads > 1) {
|
||||
@@ -548,7 +548,7 @@ static int uwsgi_mono_request(struct wsgi_request *wsgi_req) {
|
||||
}
|
||||
|
||||
// check if the mean time, something changed
|
||||
wsgi_req->app_id = uwsgi_get_app_id(key, key_len, mono_plugin.modifier1);
|
||||
wsgi_req->app_id = uwsgi_get_app_id(NULL, key, key_len, mono_plugin.modifier1);
|
||||
|
||||
if (wsgi_req->app_id == -1) {
|
||||
wsgi_req->app_id = uwsgi_mono_create_app(key, key_len, key, key_len, 0);
|
||||
|
||||
@@ -309,7 +309,7 @@ PHP_FUNCTION(uwsgi_cache_get) {
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
char *value = uwsgi_cache_magic_get(key, keylen, &valsize, cache);
|
||||
char *value = uwsgi_cache_magic_get(key, keylen, &valsize, NULL, cache);
|
||||
if (value) {
|
||||
char *ret = estrndup(value, valsize);
|
||||
free(value);
|
||||
|
||||
@@ -17,7 +17,7 @@ try:
|
||||
except:
|
||||
pass
|
||||
|
||||
CFLAGS = [os.popen(PHPPATH + ' --includes').read().rstrip(), '-Wno-error=sign-compare']
|
||||
CFLAGS = [os.popen(PHPPATH + ' --includes').read().rstrip(), '-Wno-sign-compare']
|
||||
|
||||
LDFLAGS = os.popen(PHPPATH + ' --ldflags').read().rstrip().split()
|
||||
if ld_run_path:
|
||||
|
||||
@@ -394,7 +394,7 @@ int uwsgi_perl_request(struct wsgi_request *wsgi_req) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
wsgi_req->app_id = uwsgi_get_app_id(wsgi_req->appid, wsgi_req->appid_len, psgi_plugin.modifier1);
|
||||
wsgi_req->app_id = uwsgi_get_app_id(wsgi_req, wsgi_req->appid, wsgi_req->appid_len, psgi_plugin.modifier1);
|
||||
// if it is -1, try to load a dynamic app
|
||||
if (wsgi_req->app_id == -1) {
|
||||
if (wsgi_req->dynamic) {
|
||||
@@ -621,7 +621,7 @@ void uwsgi_perl_enable_threads(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
int uwsgi_perl_signal_handler(uint8_t sig, void *handler) {
|
||||
static int uwsgi_perl_signal_handler(uint8_t sig, void *handler) {
|
||||
|
||||
int ret = 0;
|
||||
|
||||
@@ -688,6 +688,41 @@ realstuff:
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t uwsgi_perl_rpc(void *func, uint8_t argc, char **argv, uint16_t argvs[], char *buffer) {
|
||||
|
||||
int i;
|
||||
uint16_t ret = 0;
|
||||
|
||||
dSP;
|
||||
ENTER;
|
||||
SAVETMPS;
|
||||
PUSHMARK(SP);
|
||||
for(i=0;i<argc;i++) {
|
||||
XPUSHs( sv_2mortal(newSVpv(argv[i], argvs[i])));
|
||||
}
|
||||
PUTBACK;
|
||||
|
||||
call_sv( SvRV((SV*)func), G_SCALAR | G_EVAL);
|
||||
|
||||
SPAGAIN;
|
||||
if(SvTRUE(ERRSV)) {
|
||||
uwsgi_log("[uwsgi-perl error] %s", SvPV_nolen(ERRSV));
|
||||
}
|
||||
else {
|
||||
STRLEN rlen;
|
||||
SV *response = POPs;
|
||||
char *value = SvPV(response, rlen );
|
||||
ret = UMIN(UMAX16, rlen);
|
||||
memcpy(buffer, value, ret);
|
||||
}
|
||||
|
||||
PUTBACK;
|
||||
FREETMPS;
|
||||
LEAVE;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct uwsgi_plugin psgi_plugin = {
|
||||
|
||||
.name = "psgi",
|
||||
@@ -700,6 +735,7 @@ struct uwsgi_plugin psgi_plugin = {
|
||||
|
||||
.init_thread = uwsgi_perl_init_thread,
|
||||
.signal_handler = uwsgi_perl_signal_handler,
|
||||
.rpc = uwsgi_perl_rpc,
|
||||
|
||||
.mule = uwsgi_perl_mule,
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ XS(XS_cache_get) {
|
||||
cache = SvPV_nolen(ST(1));
|
||||
}
|
||||
|
||||
char *value = uwsgi_cache_magic_get(key, (uint16_t) keylen, &vallen, cache);
|
||||
char *value = uwsgi_cache_magic_get(key, (uint16_t) keylen, &vallen, NULL, cache);
|
||||
if (value) {
|
||||
ST(0) = newSVpv(value, vallen);
|
||||
free(value);
|
||||
@@ -233,6 +233,21 @@ XS(XS_register_signal) {
|
||||
|
||||
}
|
||||
|
||||
XS(XS_register_rpc) {
|
||||
dXSARGS;
|
||||
|
||||
psgi_check_args(2);
|
||||
|
||||
char *name = SvPV_nolen(ST(0));
|
||||
|
||||
if (uwsgi_register_rpc(name, &psgi_plugin, 0, (void *) newRV_inc(ST(1)))) {
|
||||
XSRETURN_NO;
|
||||
}
|
||||
|
||||
XSRETURN_YES;
|
||||
}
|
||||
|
||||
|
||||
XS(XS_postfork) {
|
||||
dXSARGS;
|
||||
|
||||
@@ -519,6 +534,7 @@ void init_perl_embedded_module() {
|
||||
psgi_xs(suspend);
|
||||
psgi_xs(signal);
|
||||
psgi_xs(register_signal);
|
||||
psgi_xs(register_rpc);
|
||||
psgi_xs(signal_wait);
|
||||
#ifdef UWSGI_SSL
|
||||
psgi_xs(i_am_the_lord);
|
||||
|
||||
@@ -86,7 +86,7 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
|
||||
|
||||
time_t now = uwsgi_now();
|
||||
|
||||
if (uwsgi_get_app_id(wsgi_req->appid, wsgi_req->appid_len, -1) != -1) {
|
||||
if (uwsgi_get_app_id(NULL, wsgi_req->appid, wsgi_req->appid_len, -1) != -1) {
|
||||
uwsgi_log( "mountpoint %.*s already configured. skip.\n", wsgi_req->appid_len, wsgi_req->appid);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
extern struct uwsgi_python up;
|
||||
extern struct uwsgi_plugin python_plugin;
|
||||
|
||||
PyObject *py_uwsgi_signal_wait(PyObject * self, PyObject * args) {
|
||||
|
||||
@@ -394,7 +395,7 @@ PyObject *py_uwsgi_register_rpc(PyObject * self, PyObject * args) {
|
||||
}
|
||||
|
||||
|
||||
if (uwsgi_register_rpc(name, 0, argc, func)) {
|
||||
if (uwsgi_register_rpc(name, &python_plugin, argc, func)) {
|
||||
return PyErr_Format(PyExc_ValueError, "unable to register rpc function");
|
||||
}
|
||||
|
||||
@@ -2925,7 +2926,7 @@ PyObject *py_uwsgi_cache_get(PyObject * self, PyObject * args) {
|
||||
|
||||
uint64_t vallen = 0;
|
||||
UWSGI_RELEASE_GIL
|
||||
char *value = uwsgi_cache_magic_get(key, keylen, &vallen, cache);
|
||||
char *value = uwsgi_cache_magic_get(key, keylen, &vallen, NULL, cache);
|
||||
UWSGI_GET_GIL
|
||||
if (value) {
|
||||
// in python 3.x we return bytes
|
||||
|
||||
@@ -293,8 +293,6 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
|
||||
|
||||
struct uwsgi_app *wi;
|
||||
|
||||
int free_appid = 0;
|
||||
|
||||
if (wsgi_req->async_status == UWSGI_AGAIN) {
|
||||
wi = &uwsgi_apps[wsgi_req->app_id];
|
||||
UWSGI_GET_GIL
|
||||
@@ -330,28 +328,7 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (wsgi_req->appid_len == 0) {
|
||||
if (!uwsgi.ignore_script_name) {
|
||||
wsgi_req->appid = wsgi_req->script_name;
|
||||
wsgi_req->appid_len = wsgi_req->script_name_len;
|
||||
}
|
||||
|
||||
if (uwsgi.vhost) {
|
||||
wsgi_req->appid = uwsgi_concat3n(wsgi_req->host, wsgi_req->host_len, "|",1, wsgi_req->script_name, wsgi_req->script_name_len);
|
||||
wsgi_req->appid_len = wsgi_req->host_len + 1 + wsgi_req->script_name_len;
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_debug("VirtualHost KEY=%.*s\n", wsgi_req->appid_len, wsgi_req->appid);
|
||||
#endif
|
||||
free_appid = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( (wsgi_req->app_id = uwsgi_get_app_id(wsgi_req->appid, wsgi_req->appid_len, 0)) == -1) {
|
||||
wsgi_req->app_id = uwsgi.default_app;
|
||||
if (uwsgi.no_default_app) {
|
||||
wsgi_req->app_id = -1;
|
||||
}
|
||||
if ( (wsgi_req->app_id = uwsgi_get_app_id(wsgi_req, wsgi_req->appid, wsgi_req->appid_len, 0)) == -1) {
|
||||
if (wsgi_req->dynamic) {
|
||||
// this part must be heavy locked in threaded modes
|
||||
if (uwsgi.threads > 1) {
|
||||
@@ -372,10 +349,6 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
|
||||
}
|
||||
}
|
||||
|
||||
if (free_appid) {
|
||||
free(wsgi_req->appid);
|
||||
}
|
||||
|
||||
if (wsgi_req->app_id == -1) {
|
||||
uwsgi_500(wsgi_req);
|
||||
uwsgi_log("--- no python application found, check your startup logs for errors ---\n");
|
||||
|
||||
@@ -62,6 +62,9 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
|
||||
PyObject *zero2 = NULL;
|
||||
if (self != Py_None) {
|
||||
zero = PyUnicode_AsASCIIString(head);
|
||||
if (!zero) {
|
||||
return PyErr_Format(PyExc_TypeError, "http status string must be encodable in latin1");
|
||||
}
|
||||
status_line = PyBytes_AsString(zero);
|
||||
status_line_len = PyBytes_Size(zero);
|
||||
}
|
||||
@@ -133,6 +136,9 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
|
||||
#ifdef PYTHREE
|
||||
if (self != Py_None) {
|
||||
zero = PyUnicode_AsASCIIString(h_key);
|
||||
if (!zero) {
|
||||
return PyErr_Format(PyExc_TypeError, "http header must be encodable in latin1");
|
||||
}
|
||||
k = PyBytes_AsString(zero);
|
||||
kl = PyBytes_Size(zero);
|
||||
}
|
||||
@@ -148,6 +154,9 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
|
||||
#ifdef PYTHREE
|
||||
if (self != Py_None) {
|
||||
zero2 = PyUnicode_AsASCIIString(h_value);
|
||||
if (!zero2) {
|
||||
return PyErr_Format(PyExc_TypeError, "http header must be encodable in latin1");
|
||||
}
|
||||
v = PyBytes_AsString(zero2);
|
||||
vl = PyBytes_Size(zero2);
|
||||
}
|
||||
|
||||
@@ -463,7 +463,7 @@ VALUE rack_uwsgi_cache_get(int argc, VALUE *argv, VALUE *class) {
|
||||
}
|
||||
|
||||
uint64_t vallen = 0;;
|
||||
char *value = uwsgi_cache_magic_get(key, keylen, &vallen, cache);
|
||||
char *value = uwsgi_cache_magic_get(key, keylen, &vallen, NULL, cache);
|
||||
if (value) {
|
||||
VALUE res = rb_str_new(value, vallen);
|
||||
free(value);
|
||||
@@ -774,7 +774,7 @@ VALUE uwsgi_ruby_register_rpc(int argc, VALUE *argv, VALUE *class) {
|
||||
void *func = (void *) argv[1];
|
||||
|
||||
|
||||
if (uwsgi_register_rpc(name, rack_plugin.modifier1, rb_argc, func)) {
|
||||
if (uwsgi_register_rpc(name, &rack_plugin, rb_argc, func)) {
|
||||
clear:
|
||||
rb_raise(rb_eRuntimeError, "unable to register rpc function");
|
||||
return Qnil;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "../../uwsgi.h"
|
||||
#include <uwsgi.h>
|
||||
|
||||
#ifdef UWSGI_ROUTING
|
||||
|
||||
@@ -23,54 +23,113 @@ struct uwsgi_router_cache_conf {
|
||||
char *key;
|
||||
size_t key_len;
|
||||
|
||||
// use mime types ?
|
||||
char *mime;
|
||||
|
||||
#ifdef UWSGI_ZLIB
|
||||
char *gzip;
|
||||
size_t gzip_len;
|
||||
#endif
|
||||
|
||||
char *content_type;
|
||||
size_t content_type_len;
|
||||
|
||||
char *content_encoding;
|
||||
size_t content_encoding_len;
|
||||
|
||||
struct uwsgi_cache *cache;
|
||||
|
||||
char *expires_str;
|
||||
uint64_t expires;
|
||||
|
||||
};
|
||||
|
||||
// this is allocated for each transformation
|
||||
struct uwsgi_transformation_cache_conf {
|
||||
struct uwsgi_buffer *cache_it;
|
||||
#ifdef UWSGI_ZLIB
|
||||
struct uwsgi_buffer *cache_it_gzip;
|
||||
#endif
|
||||
|
||||
struct uwsgi_buffer *cache_it_to;
|
||||
uint64_t cache_it_expires;
|
||||
};
|
||||
|
||||
static int transform_cache(struct wsgi_request *wsgi_req, struct uwsgi_buffer *ub, struct uwsgi_buffer **new, void *data) {
|
||||
struct uwsgi_transformation_cache_conf *utcc = (struct uwsgi_transformation_cache_conf *) data;
|
||||
|
||||
// store only successfull response
|
||||
if (wsgi_req->write_errors == 0 && wsgi_req->status == 200 && ub->pos > 0) {
|
||||
if (utcc->cache_it) {
|
||||
uwsgi_cache_magic_set(utcc->cache_it->buf, utcc->cache_it->pos, ub->buf, ub->pos, utcc->cache_it_expires,
|
||||
UWSGI_CACHE_FLAG_UPDATE, utcc->cache_it_to ? utcc->cache_it_to->buf : NULL);
|
||||
#ifdef UWSGI_ZLIB
|
||||
if (utcc->cache_it_gzip) {
|
||||
struct uwsgi_buffer *gzipped = uwsgi_gzip(ub->buf, ub->pos);
|
||||
if (gzipped) {
|
||||
uwsgi_cache_magic_set(utcc->cache_it_gzip->buf, utcc->cache_it_gzip->pos, gzipped->buf, gzipped->pos, utcc->cache_it_expires,
|
||||
UWSGI_CACHE_FLAG_UPDATE, utcc->cache_it_to ? utcc->cache_it_to->buf : NULL);
|
||||
uwsgi_buffer_destroy(gzipped);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// free resources
|
||||
if (utcc->cache_it) uwsgi_buffer_destroy(utcc->cache_it);
|
||||
#ifdef UWSGI_ZLIB
|
||||
if (utcc->cache_it_gzip) uwsgi_buffer_destroy(utcc->cache_it_gzip);
|
||||
#endif
|
||||
if (utcc->cache_it_to) uwsgi_buffer_destroy(utcc->cache_it_to);
|
||||
free(utcc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// be tolerant on errors
|
||||
static int uwsgi_routing_func_cache_store(struct wsgi_request *wsgi_req, struct uwsgi_route *ur){
|
||||
struct uwsgi_router_cache_conf *urcc = (struct uwsgi_router_cache_conf *) ur->data2;
|
||||
|
||||
// overwrite previous run
|
||||
if (wsgi_req->cache_it) {
|
||||
uwsgi_buffer_destroy(wsgi_req->cache_it);
|
||||
wsgi_req->cache_it = NULL;
|
||||
}
|
||||
|
||||
if (wsgi_req->cache_it_to) {
|
||||
uwsgi_buffer_destroy(wsgi_req->cache_it_to);
|
||||
wsgi_req->cache_it_to = NULL;
|
||||
}
|
||||
struct uwsgi_transformation_cache_conf *utcc = uwsgi_calloc(sizeof(struct uwsgi_transformation_cache_conf));
|
||||
|
||||
// build key and name
|
||||
char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
|
||||
uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
|
||||
|
||||
wsgi_req->cache_it = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urcc->key, urcc->key_len);
|
||||
if (!wsgi_req->cache_it) return UWSGI_ROUTE_NEXT;
|
||||
utcc->cache_it = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urcc->key, urcc->key_len);
|
||||
if (!utcc->cache_it) goto error;
|
||||
|
||||
if (urcc->name) {
|
||||
wsgi_req->cache_it_to = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urcc->name, urcc->name_len);
|
||||
if (!wsgi_req->cache_it_to) {
|
||||
uwsgi_buffer_destroy(wsgi_req->cache_it);
|
||||
wsgi_req->cache_it = NULL;
|
||||
}
|
||||
utcc->cache_it_to = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urcc->name, urcc->name_len);
|
||||
if (!utcc->cache_it_to) goto error;
|
||||
}
|
||||
|
||||
wsgi_req->cache_it_expires = urcc->expires;
|
||||
#ifdef UWSGI_ZLIB
|
||||
if (urcc->gzip) {
|
||||
utcc->cache_it_gzip = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urcc->gzip, urcc->gzip_len);
|
||||
if (!utcc->cache_it_gzip) goto error;
|
||||
}
|
||||
#endif
|
||||
utcc->cache_it_expires = urcc->expires;
|
||||
|
||||
uwsgi_add_transformation(wsgi_req, transform_cache, utcc);
|
||||
|
||||
return UWSGI_ROUTE_NEXT;
|
||||
|
||||
|
||||
error:
|
||||
if (utcc->cache_it) uwsgi_buffer_destroy(utcc->cache_it);
|
||||
#ifdef UWSGI_ZLIB
|
||||
if (utcc->cache_it_gzip) uwsgi_buffer_destroy(utcc->cache_it_gzip);
|
||||
#endif
|
||||
if (utcc->cache_it_to) uwsgi_buffer_destroy(utcc->cache_it_to);
|
||||
free(utcc);
|
||||
return UWSGI_ROUTE_NEXT;
|
||||
}
|
||||
|
||||
static int uwsgi_routing_func_cache(struct wsgi_request *wsgi_req, struct uwsgi_route *ur){
|
||||
|
||||
char *mime_type = NULL;
|
||||
size_t mime_type_len = 0;
|
||||
struct uwsgi_router_cache_conf *urcc = (struct uwsgi_router_cache_conf *) ur->data2;
|
||||
|
||||
char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
|
||||
@@ -79,11 +138,26 @@ static int uwsgi_routing_func_cache(struct wsgi_request *wsgi_req, struct uwsgi_
|
||||
if (!ub) return UWSGI_ROUTE_BREAK;
|
||||
|
||||
uint64_t valsize = 0;
|
||||
char *value = uwsgi_cache_magic_get(ub->buf, ub->pos, &valsize, urcc->name);
|
||||
uint64_t expires = 0;
|
||||
char *value = uwsgi_cache_magic_get(ub->buf, ub->pos, &valsize, &expires, urcc->name);
|
||||
if (urcc->mime && value) {
|
||||
mime_type = uwsgi_get_mime_type(ub->buf, ub->pos, &mime_type_len);
|
||||
}
|
||||
uwsgi_buffer_destroy(ub);
|
||||
if (value) {
|
||||
if (uwsgi_response_prepare_headers(wsgi_req, "200 OK", 6)) goto error;
|
||||
if (uwsgi_response_add_content_type(wsgi_req, urcc->content_type, urcc->content_type_len)) goto error;
|
||||
if (mime_type) {
|
||||
uwsgi_response_add_content_type(wsgi_req, mime_type, mime_type_len);
|
||||
}
|
||||
else {
|
||||
if (uwsgi_response_add_content_type(wsgi_req, urcc->content_type, urcc->content_type_len)) goto error;
|
||||
}
|
||||
if (urcc->content_encoding_len) {
|
||||
if (uwsgi_response_add_header(wsgi_req, "Content-Encoding", 16, urcc->content_encoding, urcc->content_encoding_len)) goto error;
|
||||
}
|
||||
if (expires) {
|
||||
if (uwsgi_response_add_expires(wsgi_req, expires)) goto error;
|
||||
}
|
||||
if (uwsgi_response_add_content_length(wsgi_req, valsize)) goto error;
|
||||
uwsgi_response_write_body_do(wsgi_req, value, valsize);
|
||||
free(value);
|
||||
@@ -105,6 +179,9 @@ static int uwsgi_router_cache_store(struct uwsgi_route *ur, char *args) {
|
||||
struct uwsgi_router_cache_conf *urcc = uwsgi_calloc(sizeof(struct uwsgi_router_cache_conf));
|
||||
if (uwsgi_kvlist_parse(ur->data, ur->data_len, ',', '=',
|
||||
"key", &urcc->key,
|
||||
#ifdef UWSGI_ZLIB
|
||||
"gzip", &urcc->gzip,
|
||||
#endif
|
||||
"name", &urcc->name,
|
||||
"expires", &urcc->expires_str, NULL)) {
|
||||
uwsgi_log("invalid cachestore route syntax: %s\n", args);
|
||||
@@ -115,6 +192,12 @@ static int uwsgi_router_cache_store(struct uwsgi_route *ur, char *args) {
|
||||
urcc->key_len = strlen(urcc->key);
|
||||
}
|
||||
|
||||
#ifdef UWSGI_ZLIB
|
||||
if (urcc->gzip) {
|
||||
urcc->gzip_len = strlen(urcc->gzip);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (urcc->name) {
|
||||
urcc->name_len = strlen(urcc->name);
|
||||
}
|
||||
@@ -146,6 +229,8 @@ static int uwsgi_router_cache(struct uwsgi_route *ur, char *args) {
|
||||
if (uwsgi_kvlist_parse(ur->data, ur->data_len, ',', '=',
|
||||
"key", &urcc->key,
|
||||
"content_type", &urcc->content_type,
|
||||
"content_encoding", &urcc->content_encoding,
|
||||
"mime", &urcc->mime,
|
||||
"name", &urcc->name,
|
||||
NULL)) {
|
||||
uwsgi_log("invalid route syntax: %s\n", args);
|
||||
@@ -165,6 +250,10 @@ static int uwsgi_router_cache(struct uwsgi_route *ur, char *args) {
|
||||
|
||||
urcc->content_type_len = strlen(urcc->content_type);
|
||||
|
||||
if (urcc->content_encoding) {
|
||||
urcc->content_encoding_len = strlen(urcc->content_encoding);
|
||||
}
|
||||
|
||||
ur->data2 = urcc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ static int uwsgi_routing_func_http(struct wsgi_request *wsgi_req, struct uwsgi_r
|
||||
// append remaining body...
|
||||
if (wsgi_req->proto_parser_remains > 0) {
|
||||
if (uwsgi_buffer_append(ub, wsgi_req->proto_parser_remains_buf, wsgi_req->proto_parser_remains)) {
|
||||
uwsgi_buffer_destroy(ub);
|
||||
uwsgi_log("unable to generate http request for %s\n", addr);
|
||||
return UWSGI_ROUTE_NEXT;
|
||||
}
|
||||
@@ -43,9 +44,18 @@ static int uwsgi_routing_func_http(struct wsgi_request *wsgi_req, struct uwsgi_r
|
||||
}
|
||||
|
||||
// ok now if have offload threads, directly use them
|
||||
if (wsgi_req->socket->can_offload) {
|
||||
if (!wsgi_req->post_file && !ur->custom && wsgi_req->socket->can_offload) {
|
||||
// append buffered body
|
||||
if (uwsgi.post_buffering > 0 && wsgi_req->post_cl > 0) {
|
||||
if (uwsgi_buffer_append(ub, wsgi_req->post_buffering_buf, wsgi_req->post_cl)) {
|
||||
uwsgi_buffer_destroy(ub);
|
||||
uwsgi_log("unable to generate http request for %s\n", addr);
|
||||
return UWSGI_ROUTE_NEXT;
|
||||
}
|
||||
}
|
||||
if (!uwsgi_offload_request_net_do(wsgi_req, addr, ub)) {
|
||||
wsgi_req->via = UWSGI_VIA_OFFLOAD;
|
||||
wsgi_req->status = 202;
|
||||
return UWSGI_ROUTE_BREAK;
|
||||
}
|
||||
}
|
||||
@@ -82,10 +92,16 @@ static int uwsgi_router_http(struct uwsgi_route *ur, char *args) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int uwsgi_router_proxyhttp(struct uwsgi_route *ur, char *args) {
|
||||
ur->custom = 1;
|
||||
return uwsgi_router_http(ur, args);
|
||||
}
|
||||
|
||||
|
||||
static void router_http_register(void) {
|
||||
|
||||
uwsgi_register_router("http", uwsgi_router_http);
|
||||
uwsgi_register_router("proxyhttp", uwsgi_router_proxyhttp);
|
||||
}
|
||||
|
||||
struct uwsgi_plugin router_http_plugin = {
|
||||
|
||||
@@ -58,9 +58,16 @@ static int uwsgi_routing_func_uwsgi_remote(struct wsgi_request *wsgi_req, struct
|
||||
}
|
||||
|
||||
// ok now if have offload threads, directly use them
|
||||
if (wsgi_req->socket->can_offload) {
|
||||
if (!wsgi_req->post_file && !ur->custom && wsgi_req->socket->can_offload) {
|
||||
// append buffered body
|
||||
if (uwsgi.post_buffering > 0 && wsgi_req->post_cl > 0) {
|
||||
if (uwsgi_buffer_append(ub, wsgi_req->post_buffering_buf, wsgi_req->post_cl)) {
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if (!uwsgi_offload_request_net_do(wsgi_req, addr, ub)) {
|
||||
wsgi_req->via = UWSGI_VIA_OFFLOAD;
|
||||
wsgi_req->status = 202;
|
||||
return UWSGI_ROUTE_BREAK;
|
||||
}
|
||||
}
|
||||
@@ -140,10 +147,15 @@ static int uwsgi_router_uwsgi(struct uwsgi_route *ur, char *args) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int uwsgi_router_proxyuwsgi(struct uwsgi_route *ur, char *args) {
|
||||
ur->custom = 1;
|
||||
return uwsgi_router_uwsgi(ur, args);
|
||||
}
|
||||
|
||||
static void router_uwsgi_register(void) {
|
||||
|
||||
uwsgi_register_router("uwsgi", uwsgi_router_uwsgi);
|
||||
uwsgi_register_router("proxyuwsgi", uwsgi_router_proxyuwsgi);
|
||||
}
|
||||
|
||||
struct uwsgi_plugin router_uwsgi_plugin = {
|
||||
|
||||
@@ -36,7 +36,7 @@ int uwsgi_request_spooler(struct wsgi_request *wsgi_req) {
|
||||
uwsgi_log("disconnected client, remove spool file.\n");
|
||||
/* client disconnect, remove spool file */
|
||||
if (unlink(spool_filename)) {
|
||||
uwsgi_error("unlink()");
|
||||
uwsgi_error("uwsgi_request_spooler()/unlink()");
|
||||
uwsgi_log("something horrible happened !!! check your spooler ASAP !!!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
+1
-1
@@ -444,7 +444,7 @@ static struct uwsgi_buffer *ssi_cmd_cache(struct wsgi_request *wsgi_req, struct
|
||||
}
|
||||
|
||||
uint64_t rlen = 0;
|
||||
char *value = uwsgi_cache_magic_get(var, var_len, &rlen, cache_name);
|
||||
char *value = uwsgi_cache_magic_get(var, var_len, &rlen, NULL, cache_name);
|
||||
if (cache_name) free(cache_name);
|
||||
struct uwsgi_buffer *ub = NULL;
|
||||
if (value) {
|
||||
|
||||
@@ -1,33 +1,80 @@
|
||||
#include "../../uwsgi.h"
|
||||
#include <uwsgi.h>
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
int (*symcall_function)(struct wsgi_request *);
|
||||
|
||||
int uwsgi_symcall_init(){
|
||||
symcall_function = dlsym(RTLD_DEFAULT, "pypy_uwsgi_request");
|
||||
uwsgi_log("symcall function ptr: %p\n", symcall_function);
|
||||
return 0;
|
||||
struct uwsgi_symcall {
|
||||
char *symcall_function_name;
|
||||
int (*symcall_function)(struct wsgi_request *);
|
||||
|
||||
struct uwsgi_string_list *rpc;
|
||||
} usym;
|
||||
|
||||
struct uwsgi_plugin symcall_plugin;
|
||||
|
||||
static struct uwsgi_option uwsgi_symcall_options[] = {
|
||||
{"symcall", required_argument, 0, "load the specified C symbol as the symcall request handler", uwsgi_opt_set_str, &usym.symcall_function_name, 0},
|
||||
{"symcall-register-rpc", required_argument, 0, "load the specified C symbol as an RPC function (syntax: name function)", uwsgi_opt_add_string_list, &usym.rpc, 0},
|
||||
{0, 0, 0, 0},
|
||||
};
|
||||
|
||||
static void uwsgi_symcall_init(){
|
||||
if (usym.symcall_function_name) {
|
||||
usym.symcall_function = dlsym(RTLD_DEFAULT, usym.symcall_function_name);
|
||||
if (!usym.symcall_function) {
|
||||
uwsgi_log("unable to find symbol \"%s\" in process address space\n", usym.symcall_function_name);
|
||||
exit(1);
|
||||
}
|
||||
uwsgi_log("symcall function ptr: %p\n", usym.symcall_function);
|
||||
}
|
||||
|
||||
struct uwsgi_string_list *usl = usym.rpc;
|
||||
while(usl) {
|
||||
char *space = strchr(usl->value, ' ');
|
||||
if (!space) {
|
||||
uwsgi_log("invalid symcall RPC syntax, must be: rpcname symbol\n");
|
||||
exit(1);
|
||||
}
|
||||
*space = 0;
|
||||
void *func = dlsym(RTLD_DEFAULT, space+1);
|
||||
if (!func) {
|
||||
uwsgi_log("unable to find symbol \"%s\" in process address space\n", space+1);
|
||||
exit(1);
|
||||
}
|
||||
if (uwsgi_register_rpc(usl->value, &symcall_plugin, 0, func)) {
|
||||
uwsgi_log("unable to register rpc function");
|
||||
exit(1);
|
||||
}
|
||||
*space = ' ';
|
||||
usl = usl->next;
|
||||
}
|
||||
}
|
||||
|
||||
int uwsgi_symcall_request(struct wsgi_request *wsgi_req) {
|
||||
|
||||
return symcall_function(wsgi_req);
|
||||
|
||||
static int uwsgi_symcall_request(struct wsgi_request *wsgi_req) {
|
||||
if (usym.symcall_function) {
|
||||
return usym.symcall_function(wsgi_req);
|
||||
}
|
||||
return UWSGI_OK;
|
||||
}
|
||||
|
||||
|
||||
void uwsgi_symcall_after_request(struct wsgi_request *wsgi_req) {
|
||||
// TODO
|
||||
static void uwsgi_symcall_after_request(struct wsgi_request *wsgi_req) {
|
||||
log_request(wsgi_req);
|
||||
}
|
||||
|
||||
static uint16_t uwsgi_symcall_rpc(void *func, uint8_t argc, char **argv, uint16_t argvs[], char *buffer) {
|
||||
uint16_t (*casted_func)(uint8_t, char **, uint16_t *, char *) = (uint16_t (*)(uint8_t, char **, uint16_t *, char *)) func;
|
||||
return casted_func(argc, argv, argvs, buffer);
|
||||
}
|
||||
|
||||
struct uwsgi_plugin symcall_plugin = {
|
||||
|
||||
.name = "symcall",
|
||||
.modifier1 = 18,
|
||||
.init = uwsgi_symcall_init,
|
||||
.options = uwsgi_symcall_options,
|
||||
.init_apps = uwsgi_symcall_init,
|
||||
.request = uwsgi_symcall_request,
|
||||
.after_request = uwsgi_symcall_after_request,
|
||||
.rpc = uwsgi_symcall_rpc,
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
#include <uwsgi.h>
|
||||
|
||||
#if defined(UWSGI_ROUTING) && defined(UWSGI_ZLIB)
|
||||
|
||||
/*
|
||||
|
||||
gzip transformations reset your headers !!!
|
||||
|
||||
remember to re-add the content type via routing rules
|
||||
|
||||
*/
|
||||
|
||||
static int transform_gzip(struct wsgi_request *wsgi_req, struct uwsgi_buffer *ub, struct uwsgi_buffer **new, void *data) {
|
||||
struct uwsgi_buffer *gzipped = uwsgi_gzip(ub->buf, ub->pos);
|
||||
if (!gzipped) {
|
||||
return -1;
|
||||
}
|
||||
// use this new buffer
|
||||
*new = gzipped;
|
||||
if (uwsgi_response_prepare_headers_int(wsgi_req, wsgi_req->status)) return -1;
|
||||
if (uwsgi_response_add_header(wsgi_req, "Content-Encoding", 16, "gzip", 4)) return -1;
|
||||
if (uwsgi_response_add_content_length(wsgi_req, gzipped->pos)) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int uwsgi_routing_func_gzip(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
|
||||
uwsgi_add_transformation(wsgi_req, transform_gzip, NULL);
|
||||
return UWSGI_ROUTE_NEXT;
|
||||
}
|
||||
|
||||
static int uwsgi_router_gzip(struct uwsgi_route *ur, char *args) {
|
||||
ur->func = uwsgi_routing_func_gzip;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void router_gzip_register(void) {
|
||||
uwsgi_register_router("gzip", uwsgi_router_gzip);
|
||||
}
|
||||
|
||||
struct uwsgi_plugin transformation_gzip_plugin = {
|
||||
.name = "transformation_gzip",
|
||||
.on_load = router_gzip_register,
|
||||
};
|
||||
#else
|
||||
struct uwsgi_plugin transformation_gzip_plugin = {
|
||||
.name = "transformation_gzip",
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,6 @@
|
||||
NAME='transformation_gzip'
|
||||
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = []
|
||||
GCC_LIST = ['gzip']
|
||||
@@ -0,0 +1,125 @@
|
||||
#include <uwsgi.h>
|
||||
|
||||
#ifdef UWSGI_ROUTING
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
struct uwsgi_router_tofile_conf {
|
||||
|
||||
// the name of the file
|
||||
char *filename;
|
||||
size_t filename_len;
|
||||
|
||||
// the mode of the file
|
||||
char *mode;
|
||||
size_t mode_len;
|
||||
};
|
||||
|
||||
// this is allocated for each transformation
|
||||
struct uwsgi_transformation_tofile_conf {
|
||||
struct uwsgi_buffer *filename;
|
||||
};
|
||||
|
||||
static int transform_tofile(struct wsgi_request *wsgi_req, struct uwsgi_buffer *ub, struct uwsgi_buffer **new, void *data) {
|
||||
struct uwsgi_transformation_tofile_conf *uttc = (struct uwsgi_transformation_tofile_conf *) data;
|
||||
|
||||
// store only successfull response
|
||||
if (wsgi_req->write_errors == 0 && wsgi_req->status == 200 && ub->pos > 0) {
|
||||
if (uttc->filename) {
|
||||
int fd = open(uttc->filename->buf, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
|
||||
if (fd < 0) {
|
||||
uwsgi_error_open(uttc->filename->buf);
|
||||
goto end;
|
||||
}
|
||||
// lock the file
|
||||
if (uwsgi_fcntl_lock(fd)) {
|
||||
close(fd);
|
||||
goto end;
|
||||
}
|
||||
// write to it
|
||||
size_t remains = ub->pos;
|
||||
while(remains) {
|
||||
ssize_t rlen = write(fd, ub->buf + (ub->pos - remains), remains);
|
||||
if (rlen <= 0) {
|
||||
uwsgi_error("transform_tofile()/write()");
|
||||
unlink(uttc->filename->buf);
|
||||
break;
|
||||
}
|
||||
remains -= rlen;
|
||||
}
|
||||
// unlock/close
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
// free resources
|
||||
if (uttc->filename) uwsgi_buffer_destroy(uttc->filename);
|
||||
free(uttc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// be tolerant on errors
|
||||
static int uwsgi_routing_func_tofile(struct wsgi_request *wsgi_req, struct uwsgi_route *ur){
|
||||
struct uwsgi_router_tofile_conf *urtc = (struct uwsgi_router_tofile_conf *) ur->data2;
|
||||
|
||||
struct uwsgi_transformation_tofile_conf *uttc = uwsgi_calloc(sizeof(struct uwsgi_transformation_tofile_conf));
|
||||
|
||||
// build key and name
|
||||
char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
|
||||
uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
|
||||
|
||||
uttc->filename = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urtc->filename, urtc->filename_len);
|
||||
if (!uttc->filename) goto error;
|
||||
|
||||
uwsgi_add_transformation(wsgi_req, transform_tofile, uttc);
|
||||
return UWSGI_ROUTE_NEXT;
|
||||
|
||||
error:
|
||||
if (uttc->filename) uwsgi_buffer_destroy(uttc->filename);
|
||||
free(uttc);
|
||||
return UWSGI_ROUTE_NEXT;
|
||||
}
|
||||
|
||||
static int uwsgi_router_tofile(struct uwsgi_route *ur, char *args) {
|
||||
ur->func = uwsgi_routing_func_tofile;
|
||||
ur->data = args;
|
||||
ur->data_len = strlen(args);
|
||||
struct uwsgi_router_tofile_conf *urtc = uwsgi_calloc(sizeof(struct uwsgi_router_tofile_conf));
|
||||
if (uwsgi_kvlist_parse(ur->data, ur->data_len, ',', '=',
|
||||
"filename", &urtc->filename,
|
||||
"name", &urtc->filename,
|
||||
"mode", &urtc->mode, NULL)) {
|
||||
uwsgi_log("invalid tofile route syntax: %s\n", args);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!urtc->filename) {
|
||||
uwsgi_log("invalid tofile route syntax, you need to specify a filename\n");
|
||||
goto error;
|
||||
}
|
||||
urtc->filename_len = strlen(urtc->filename);
|
||||
ur->data2 = urtc;
|
||||
return 0;
|
||||
error:
|
||||
if (urtc->filename) free(urtc->filename);
|
||||
free(urtc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void router_tofile_register() {
|
||||
uwsgi_register_router("tofile", uwsgi_router_tofile);
|
||||
uwsgi_register_router("to-file", uwsgi_router_tofile);
|
||||
}
|
||||
|
||||
struct uwsgi_plugin transformation_tofile_plugin = {
|
||||
.name = "transformation_tofile",
|
||||
.on_load = router_tofile_register,
|
||||
};
|
||||
|
||||
#else
|
||||
struct uwsgi_plugin transformation_tofile_plugin = {
|
||||
.name = "transformation_tofile",
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,6 @@
|
||||
NAME='transformation_tofile'
|
||||
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = []
|
||||
GCC_LIST = ['tofile']
|
||||
@@ -0,0 +1,28 @@
|
||||
#include <uwsgi.h>
|
||||
|
||||
static int transform_toupper(struct wsgi_request *wsgi_req, struct uwsgi_buffer *ub, struct uwsgi_buffer **foobar, void *data) {
|
||||
size_t i;
|
||||
for(i=0;i<ub->pos;i++) {
|
||||
ub->buf[i] = toupper((int) ub->buf[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int uwsgi_routing_func_toupper(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
|
||||
uwsgi_add_transformation(wsgi_req, transform_toupper, NULL);
|
||||
return UWSGI_ROUTE_NEXT;
|
||||
}
|
||||
|
||||
static int uwsgi_router_toupper(struct uwsgi_route *ur, char *args) {
|
||||
ur->func = uwsgi_routing_func_toupper;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void router_toupper_register(void) {
|
||||
uwsgi_register_router("toupper", uwsgi_router_toupper);
|
||||
}
|
||||
|
||||
struct uwsgi_plugin transformation_toupper_plugin = {
|
||||
.name = "transformation_toupper",
|
||||
.on_load = router_toupper_register,
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
NAME='transformation_toupper'
|
||||
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = []
|
||||
GCC_LIST = ['toupper']
|
||||
@@ -41,6 +41,7 @@ static v8::Handle < v8::Value > uwsgi_v8_commonjs_require(const v8::Arguments &
|
||||
}
|
||||
return v8::Undefined();
|
||||
}
|
||||
TeaJS_uWSGI app;
|
||||
#else
|
||||
static v8::Handle < v8::Value > uwsgi_v8_commonjs_require(const v8::Arguments &);
|
||||
static v8::Handle < v8::Value > uwsgi_v8_commonjs_require_do(char *);
|
||||
@@ -49,11 +50,10 @@ static v8::Handle < v8::Value > uwsgi_v8_commonjs_require_do(char *);
|
||||
extern struct uwsgi_v8 uv8;
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
TeaJS_uWSGI app;
|
||||
|
||||
v8::Persistent<v8::Context> uwsgi_v8_setup_context() {
|
||||
#ifdef UWSGI_V8_TEAJS
|
||||
v8::HandleScope handle_scope;
|
||||
#ifdef UWSGI_V8_TEAJS
|
||||
try {
|
||||
app.init();
|
||||
app.getContext()->Global()->Set(v8::String::New("require"), v8::FunctionTemplate::New(uwsgi_v8_commonjs_require)->GetFunction());
|
||||
|
||||
@@ -85,7 +85,7 @@ static v8::Handle<v8::Value> uwsgi_v8_api_register_rpc(const v8::Arguments& args
|
||||
uvrt->func[core_id] = func;
|
||||
|
||||
// we can safely call register_rpc here as it will check for already registered funcs
|
||||
if (uwsgi_register_rpc(*name, v8_plugin.modifier1, j_argc, uvrt)) {
|
||||
if (uwsgi_register_rpc(*name, &v8_plugin, j_argc, uvrt)) {
|
||||
uwsgi_log("[uwsgi-v8] unable to register RPC function \"%s\"\n", *name);
|
||||
return v8::Undefined();
|
||||
}
|
||||
@@ -179,6 +179,7 @@ extern "C" int uwsgi_v8_init(){
|
||||
|
||||
pthread_key_create(&uv8.current_core, NULL);
|
||||
pthread_setspecific(uv8.current_core, (void *) 0);
|
||||
|
||||
uv8.contexts[0] = uwsgi_v8_new_isolate(0);
|
||||
|
||||
return 0;
|
||||
|
||||
+119
-16
@@ -15,6 +15,10 @@
|
||||
|
||||
xslt:doc=<path1>,stylesheet=<path2>,params=<params>
|
||||
|
||||
As transformation
|
||||
|
||||
toxslt:stylesheet=<path2>,params=<params>
|
||||
|
||||
*/
|
||||
|
||||
struct uwsgi_xslt_config {
|
||||
@@ -37,6 +41,12 @@ struct uwsgi_router_xslt_conf {
|
||||
uint16_t content_type_len;
|
||||
};
|
||||
|
||||
struct uwsgi_transformation_xslt_conf {
|
||||
struct uwsgi_buffer *stylesheet;
|
||||
struct uwsgi_buffer *params;
|
||||
struct uwsgi_buffer *content_type;
|
||||
};
|
||||
|
||||
struct uwsgi_option uwsgi_xslt_options[] = {
|
||||
{"xslt-docroot", required_argument, 0, "add a document_root for xslt processing", uwsgi_opt_add_string_list, &uxslt.docroot, 0},
|
||||
{"xslt-ext", required_argument, 0, "search for xslt stylesheets with the specified extension", uwsgi_opt_add_string_list, &uxslt.ext, 0},
|
||||
@@ -46,7 +56,7 @@ struct uwsgi_option uwsgi_xslt_options[] = {
|
||||
{NULL, 0, 0, NULL, NULL, NULL, 0},
|
||||
};
|
||||
|
||||
static char *uwsgi_xslt_apply(char *xmlfile, char *xsltfile, char *params, int *rlen) {
|
||||
static char *uwsgi_xslt_apply(xmlDoc *doc, char *xsltfile, char *params, int *rlen) {
|
||||
|
||||
char **vparams = NULL;
|
||||
char *tmp_params = NULL;
|
||||
@@ -79,19 +89,8 @@ static char *uwsgi_xslt_apply(char *xmlfile, char *xsltfile, char *params, int *
|
||||
xmlSubstituteEntitiesDefault(1);
|
||||
xmlLoadExtDtdDefaultValue = 1;
|
||||
|
||||
xmlDocPtr doc = xmlParseFile(xmlfile);
|
||||
if (!doc) {
|
||||
if (vparams) {
|
||||
int i; for(i=1;i<(count*2);i+=2) free(vparams[i]);
|
||||
free(tmp_params);
|
||||
free(vparams);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
xsltStylesheetPtr ss = xsltParseStylesheetFile((const xmlChar *) xsltfile);
|
||||
if (!ss) {
|
||||
xmlFreeDoc(doc);
|
||||
if (vparams) {
|
||||
int i; for(i=1;i<(count*2);i+=2) free(vparams[i]);
|
||||
free(tmp_params);
|
||||
@@ -103,7 +102,6 @@ static char *uwsgi_xslt_apply(char *xmlfile, char *xsltfile, char *params, int *
|
||||
xmlDocPtr res = xsltApplyStylesheet(ss, doc, (const char **) vparams);
|
||||
if (!res) {
|
||||
xsltFreeStylesheet(ss);
|
||||
xmlFreeDoc(doc);
|
||||
if (vparams) {
|
||||
int i; for(i=1;i<(count*2);i+=2) free(vparams[i]);
|
||||
free(tmp_params);
|
||||
@@ -116,7 +114,6 @@ static char *uwsgi_xslt_apply(char *xmlfile, char *xsltfile, char *params, int *
|
||||
int ret = xsltSaveResultToString(&output, rlen, res, ss);
|
||||
xsltFreeStylesheet(ss);
|
||||
xmlFreeDoc(res);
|
||||
xmlFreeDoc(doc);
|
||||
if (vparams) {
|
||||
int i; for(i=1;i<(count*2);i+=2) free(vparams[i]);
|
||||
free(tmp_params);
|
||||
@@ -279,7 +276,13 @@ apply:
|
||||
params = uwsgi_concat2n(wsgi_req->query_string, wsgi_req->query_string_len, "", 0);
|
||||
}
|
||||
// we have both the file and the stylesheet, let's run the engine
|
||||
output = uwsgi_xslt_apply(filename, stylesheet, params, &output_rlen);
|
||||
xmlDoc *doc = xmlParseFile(xmlfile);
|
||||
if (!doc) {
|
||||
uwsgi_500(wsgi_req);
|
||||
return UWSGI_OK;
|
||||
}
|
||||
output = uwsgi_xslt_apply(doc, stylesheet, params, &output_rlen);
|
||||
xmlFree(doc);
|
||||
if (params) free(params);
|
||||
if (!output) {
|
||||
uwsgi_500(wsgi_req);
|
||||
@@ -313,6 +316,72 @@ static void uwsgi_xslt_log(struct wsgi_request *wsgi_req) {
|
||||
log_request(wsgi_req);
|
||||
}
|
||||
|
||||
static int transform_toxslt(struct wsgi_request *wsgi_req, struct uwsgi_buffer *ub, struct uwsgi_buffer **new, void *data) {
|
||||
int ret = -1;
|
||||
struct uwsgi_transformation_xslt_conf *utxc = (struct uwsgi_transformation_xslt_conf *) data;
|
||||
|
||||
xmlDoc *doc = xmlReadMemory(ub->buf, ub->pos, NULL, NULL, 0);
|
||||
if (!doc) goto end;
|
||||
|
||||
int rlen;
|
||||
char *output = uwsgi_xslt_apply( doc, utxc->stylesheet->buf, utxc->params ? utxc->params->buf : NULL, &rlen);
|
||||
if (!output) goto end;
|
||||
|
||||
if (uwsgi_response_prepare_headers_int(wsgi_req, wsgi_req->status)) goto end;
|
||||
if (uwsgi_response_add_content_length(wsgi_req, rlen)) goto end;
|
||||
if (uwsgi_response_add_content_type(wsgi_req, utxc->content_type->buf, utxc->content_type->pos)) goto end;
|
||||
|
||||
*new = uwsgi_buffer_new(rlen);
|
||||
if (uwsgi_buffer_append(*new, output, rlen)) {
|
||||
xmlFree(output);
|
||||
uwsgi_buffer_destroy(*new);
|
||||
*new = NULL;
|
||||
goto end;
|
||||
}
|
||||
xmlFree(output);
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
if (doc) xmlFreeDoc(doc);
|
||||
if (utxc->stylesheet) uwsgi_buffer_destroy(utxc->stylesheet);
|
||||
if (utxc->params) uwsgi_buffer_destroy(utxc->params);
|
||||
if (utxc->content_type) uwsgi_buffer_destroy(utxc->content_type);
|
||||
free(utxc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int uwsgi_routing_func_toxslt(struct wsgi_request *wsgi_req, struct uwsgi_route *ur){
|
||||
|
||||
struct uwsgi_router_xslt_conf *urxc = (struct uwsgi_router_xslt_conf *) ur->data2;
|
||||
struct uwsgi_transformation_xslt_conf *utxc = uwsgi_calloc(sizeof(struct uwsgi_transformation_xslt_conf));
|
||||
|
||||
char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
|
||||
uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
|
||||
|
||||
utxc->stylesheet = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urxc->stylesheet, urxc->stylesheet_len);
|
||||
if (!utxc->stylesheet) goto end;
|
||||
|
||||
if (urxc->params) {
|
||||
utxc->params = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urxc->params, urxc->params_len);
|
||||
if (!utxc->params) goto end;
|
||||
}
|
||||
|
||||
if (urxc->content_type) {
|
||||
utxc->content_type = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urxc->content_type, urxc->content_type_len);
|
||||
if (!utxc->content_type) goto end;
|
||||
}
|
||||
|
||||
uwsgi_add_transformation(wsgi_req, transform_toxslt, utxc);
|
||||
return UWSGI_ROUTE_NEXT;
|
||||
end:
|
||||
if (utxc->stylesheet) uwsgi_buffer_destroy(utxc->stylesheet);
|
||||
if (utxc->params) uwsgi_buffer_destroy(utxc->params);
|
||||
if (utxc->content_type) uwsgi_buffer_destroy(utxc->content_type);
|
||||
free(utxc);
|
||||
return UWSGI_ROUTE_BREAK;
|
||||
}
|
||||
|
||||
|
||||
static int uwsgi_routing_func_xslt(struct wsgi_request *wsgi_req, struct uwsgi_route *ur){
|
||||
|
||||
struct uwsgi_router_xslt_conf *urxc = (struct uwsgi_router_xslt_conf *) ur->data2;
|
||||
@@ -341,7 +410,10 @@ static int uwsgi_routing_func_xslt(struct wsgi_request *wsgi_req, struct uwsgi_r
|
||||
}
|
||||
|
||||
int rlen;
|
||||
char *output = uwsgi_xslt_apply( ub_doc->buf, ub_stylesheet->buf, ub_params ? ub_params->buf : NULL, &rlen);
|
||||
xmlDoc *doc = xmlParseFile(ub_doc->buf) ;
|
||||
if (!doc) goto end;
|
||||
char *output = uwsgi_xslt_apply(doc, ub_stylesheet->buf, ub_params ? ub_params->buf : NULL, &rlen);
|
||||
xmlFree(doc);
|
||||
if (!output) goto end;
|
||||
|
||||
if (uwsgi_response_prepare_headers(wsgi_req, "200 OK", 6)) goto end;
|
||||
@@ -390,9 +462,40 @@ static int uwsgi_router_xslt(struct uwsgi_route *ur, char *args) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int uwsgi_router_toxslt(struct uwsgi_route *ur, char *args) {
|
||||
ur->func = uwsgi_routing_func_toxslt;
|
||||
ur->data = args;
|
||||
ur->data_len = strlen(args);
|
||||
struct uwsgi_router_xslt_conf *urxc = uwsgi_calloc(sizeof(struct uwsgi_router_xslt_conf));
|
||||
if (uwsgi_kvlist_parse(ur->data, ur->data_len, ',', '=',
|
||||
"stylesheet", &urxc->stylesheet,
|
||||
"content_type", &urxc->content_type,
|
||||
"params", &urxc->params,
|
||||
NULL)) {
|
||||
uwsgi_log("invalid route syntax: %s\n", args);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!urxc->stylesheet) {
|
||||
uwsgi_log("invalid route/transformation syntax: you need to specify a stylesheet\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
urxc->stylesheet_len = strlen(urxc->stylesheet);
|
||||
|
||||
if (urxc->params) urxc->params_len = strlen(urxc->params);
|
||||
if (!urxc->content_type) urxc->content_type = "text/html";
|
||||
urxc->content_type_len = strlen(urxc->content_type);
|
||||
ur->data2 = urxc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void router_xslt_register() {
|
||||
uwsgi_register_router("xslt", uwsgi_router_xslt);
|
||||
uwsgi_register_router("toxslt", uwsgi_router_toxslt);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+52
-1
@@ -310,13 +310,14 @@ struct uwsgi_buffer *uwsgi_to_http(struct wsgi_request *wsgi_req, char *host, ui
|
||||
if (uwsgi_buffer_append(ub, wsgi_req->uri, wsgi_req->uri_len)) goto clear;
|
||||
}
|
||||
|
||||
// force HTTP/1.0
|
||||
if (uwsgi_buffer_append(ub, " HTTP/1.0\r\n", 11)) goto clear;
|
||||
|
||||
int i;
|
||||
char *x_forwarded_for = NULL;
|
||||
size_t x_forwarded_for_len = 0;
|
||||
|
||||
// starting adding headers
|
||||
// start adding headers
|
||||
for(i=0;i<wsgi_req->var_cnt;i++) {
|
||||
if (!uwsgi_starts_with(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len, "HTTP_", 5)) {
|
||||
|
||||
@@ -325,8 +326,17 @@ struct uwsgi_buffer *uwsgi_to_http(struct wsgi_request *wsgi_req, char *host, ui
|
||||
|
||||
if (host && !uwsgi_strncmp(header, header_len, "HOST", 4)) goto next;
|
||||
|
||||
// remove dangerous headers
|
||||
if (!uwsgi_strncmp(header, header_len, "CONNECTION", 10)) goto next;
|
||||
if (!uwsgi_strncmp(header, header_len, "KEEP_ALIVE", 10)) goto next;
|
||||
if (!uwsgi_strncmp(header, header_len, "ACCEPT_ENCODING", 15)) goto next;
|
||||
if (!uwsgi_strncmp(header, header_len, "TE", 2)) goto next;
|
||||
if (!uwsgi_strncmp(header, header_len, "TRAILER", 7)) goto next;
|
||||
if (!uwsgi_strncmp(header, header_len, "IF_MATCH", 8)) goto next;
|
||||
if (!uwsgi_strncmp(header, header_len, "IF_MODIFIED_SINCE", 17)) goto next;
|
||||
if (!uwsgi_strncmp(header, header_len, "IF_RANGE", 8)) goto next;
|
||||
if (!uwsgi_strncmp(header, header_len, "IF_UNMODIFIED_SINCE", 19)) goto next;
|
||||
if (!uwsgi_strncmp(header, header_len, "IF_NONE_MATCH", 13)) goto next;
|
||||
if (!uwsgi_strncmp(header, header_len, "X_FORWARDED_FOR", 15)) {
|
||||
x_forwarded_for = wsgi_req->hvec[i+1].iov_base;
|
||||
x_forwarded_for_len = wsgi_req->hvec[i+1].iov_len;
|
||||
@@ -386,3 +396,44 @@ clear:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int uwsgi_is_full_http(struct uwsgi_buffer *ub) {
|
||||
size_t i;
|
||||
int status = 0;
|
||||
for(i=0;i<ub->pos;i++) {
|
||||
switch(status) {
|
||||
// \r
|
||||
case 0:
|
||||
if (ub->buf[i] == '\r') status = 1;
|
||||
break;
|
||||
// \r\n
|
||||
case 1:
|
||||
if (ub->buf[i] == '\n') {
|
||||
status = 2;
|
||||
break;
|
||||
}
|
||||
status = 0;
|
||||
break;
|
||||
// \r\n\r
|
||||
case 2:
|
||||
if (ub->buf[i] == '\r') {
|
||||
status = 3;
|
||||
break;
|
||||
}
|
||||
status = 0;
|
||||
break;
|
||||
// \r\n\r\n
|
||||
case 3:
|
||||
if (ub->buf[i] == '\n') {
|
||||
return 1;
|
||||
}
|
||||
status = 0;
|
||||
break;
|
||||
default:
|
||||
status = 0;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
uwsgi::register_rpc('hello', sub {
|
||||
my ($one, $two, $three) = @_;
|
||||
unless($one) {
|
||||
return "passed no args to RPC func";
|
||||
}
|
||||
return $three.'-'.$two.'-'.$one;
|
||||
});
|
||||
|
||||
my $rpc_value = uwsgi::call('hello', 'foo', 'bar', 'test');
|
||||
|
||||
if ($rpc_value) {
|
||||
+1
-1
@@ -2,7 +2,7 @@ Gem::Specification.new do |s|
|
||||
s.name = 'uwsgi'
|
||||
s.license = 'GPL-2'
|
||||
s.version = `python -c "import uwsgiconfig as uc; print uc.uwsgi_version"`.sub(/-dev-.*/,'')
|
||||
s.date = '2013-04-04'
|
||||
s.date = '2013-04-23'
|
||||
s.summary = "uWSGI"
|
||||
s.description = "The uWSGI server for Ruby/Rack"
|
||||
s.authors = ["Unbit"]
|
||||
|
||||
@@ -713,6 +713,9 @@ struct uwsgi_cache {
|
||||
uint64_t n_items;
|
||||
struct uwsgi_cache_item *items;
|
||||
|
||||
uint8_t use_last_modified;
|
||||
time_t last_modified_at;
|
||||
|
||||
void *data;
|
||||
|
||||
uint8_t no_expire;
|
||||
@@ -1143,6 +1146,18 @@ struct uwsgi_alarm {
|
||||
struct uwsgi_alarm *next;
|
||||
};
|
||||
|
||||
struct uwsgi_alarm_fd {
|
||||
int fd;
|
||||
size_t buf_len;
|
||||
void *buf;
|
||||
char *msg;
|
||||
size_t msg_len;
|
||||
struct uwsgi_alarm_instance *alarm;
|
||||
struct uwsgi_alarm_fd *next;
|
||||
};
|
||||
|
||||
struct uwsgi_alarm_fd *uwsgi_add_alarm_fd(int, char *, size_t, char *, size_t);
|
||||
|
||||
#ifdef UWSGI_PCRE
|
||||
struct uwsgi_alarm_ll {
|
||||
struct uwsgi_alarm_instance *alarm;
|
||||
@@ -1179,6 +1194,12 @@ struct uwsgi_logvar {
|
||||
struct uwsgi_logvar *next;
|
||||
};
|
||||
|
||||
struct uwsgi_transformation {
|
||||
int (*func)(struct wsgi_request *, struct uwsgi_buffer *, struct uwsgi_buffer **, void *);
|
||||
void *data;
|
||||
struct uwsgi_transformation *next;
|
||||
};
|
||||
|
||||
struct wsgi_request {
|
||||
int fd;
|
||||
struct uwsgi_header *uh;
|
||||
@@ -1392,10 +1413,11 @@ struct wsgi_request {
|
||||
// internal routing goto instruction
|
||||
uint32_t route_goto;
|
||||
|
||||
struct uwsgi_buffer *cache_it;
|
||||
struct uwsgi_buffer *cache_it_to;
|
||||
uint64_t cache_it_expires;
|
||||
struct uwsgi_buffer *cached_response;
|
||||
struct uwsgi_buffer *response_buffer;
|
||||
struct uwsgi_transformation *transformations;
|
||||
|
||||
// if set ignore buffering and directly send the body
|
||||
int flush;
|
||||
|
||||
struct msghdr msg;
|
||||
union {
|
||||
@@ -1823,6 +1845,8 @@ struct uwsgi_server {
|
||||
uint64_t alarm_msg_size;
|
||||
struct uwsgi_string_list *alarm_list;
|
||||
struct uwsgi_string_list *alarm_logs_list;
|
||||
struct uwsgi_alarm_fd *alarm_fds;
|
||||
struct uwsgi_string_list *alarm_fd_list;
|
||||
struct uwsgi_alarm *alarms;
|
||||
struct uwsgi_alarm_instance *alarm_instances;
|
||||
struct uwsgi_alarm_log *alarm_logs;
|
||||
@@ -1831,6 +1855,9 @@ struct uwsgi_server {
|
||||
int threaded_logger;
|
||||
pthread_mutex_t threaded_logger_lock;
|
||||
|
||||
int *safe_fds;
|
||||
int safe_fds_cnt;
|
||||
|
||||
int daemons_honour_stdin;
|
||||
struct uwsgi_daemon *daemons;
|
||||
int daemons_cnt;
|
||||
@@ -1863,6 +1890,7 @@ struct uwsgi_server {
|
||||
struct uwsgi_string_list *cache2;
|
||||
int cache_setup;
|
||||
int locking_setup;
|
||||
int cache_use_last_modified;
|
||||
|
||||
struct uwsgi_dyn_dict *static_expires_type;
|
||||
struct uwsgi_dyn_dict *static_expires_type_mtime;
|
||||
@@ -2079,6 +2107,7 @@ struct uwsgi_server {
|
||||
|
||||
int no_orphans;
|
||||
int skip_zero;
|
||||
int skip_atexit;
|
||||
|
||||
char *chdir;
|
||||
char *chdir2;
|
||||
@@ -2104,6 +2133,7 @@ struct uwsgi_server {
|
||||
char *ns_net;
|
||||
struct uwsgi_string_list *ns_keep_mount;
|
||||
#endif
|
||||
struct uwsgi_string_list *file_write_list;
|
||||
|
||||
char *protocol;
|
||||
|
||||
@@ -2172,6 +2202,9 @@ struct uwsgi_server {
|
||||
size_t rwlock_size;
|
||||
|
||||
struct uwsgi_string_list *load_file_in_cache;
|
||||
#ifdef UWSGI_ZLIB
|
||||
struct uwsgi_string_list *load_file_in_cache_gzip;
|
||||
#endif
|
||||
char *use_check_cache;
|
||||
struct uwsgi_cache *check_cache;
|
||||
struct uwsgi_cache *caches;
|
||||
@@ -2279,8 +2312,8 @@ struct uwsgi_rpc {
|
||||
char name[UMAX8];
|
||||
void *func;
|
||||
uint8_t args;
|
||||
uint8_t modifier1;
|
||||
uint8_t shared;
|
||||
struct uwsgi_plugin *plugin;
|
||||
};
|
||||
|
||||
struct uwsgi_signal_entry {
|
||||
@@ -2314,6 +2347,10 @@ struct uwsgi_cron {
|
||||
uint8_t sig;
|
||||
|
||||
char *command;
|
||||
#ifdef UWSGI_SSL
|
||||
char *legion;
|
||||
#endif
|
||||
void (*func)(struct uwsgi_cron *, time_t);
|
||||
|
||||
struct uwsgi_cron *next;
|
||||
};
|
||||
@@ -2646,7 +2683,7 @@ char *uwsgi_concat4(char *, char *, char *, char *);
|
||||
char *uwsgi_concat4n(char *, int, char *, int, char *, int, char *, int);
|
||||
|
||||
|
||||
int uwsgi_get_app_id(char *, int, int);
|
||||
int uwsgi_get_app_id(struct wsgi_request *, char *, uint16_t, int);
|
||||
char *uwsgi_strncopy(char *, int);
|
||||
|
||||
int master_loop(char **, char **);
|
||||
@@ -2698,6 +2735,7 @@ ssize_t uwsgi_send_message(int, uint8_t, uint8_t, char *, uint16_t, int, ssize_t
|
||||
int uwsgi_cache_set2(struct uwsgi_cache *, char *, uint16_t, char *, uint64_t, uint64_t, uint64_t);
|
||||
int uwsgi_cache_del2(struct uwsgi_cache *, char *, uint16_t, uint64_t, uint16_t);
|
||||
char *uwsgi_cache_get2(struct uwsgi_cache *, char *, uint16_t, uint64_t *);
|
||||
char *uwsgi_cache_get3(struct uwsgi_cache *, char *, uint16_t, uint64_t *, uint64_t *);
|
||||
uint32_t uwsgi_cache_exists2(struct uwsgi_cache *, char *, uint16_t);
|
||||
struct uwsgi_cache *uwsgi_cache_create(char *);
|
||||
struct uwsgi_cache *uwsgi_cache_by_name(char *);
|
||||
@@ -2750,7 +2788,7 @@ void uwsgi_route_signal(uint8_t);
|
||||
|
||||
int uwsgi_start(void *);
|
||||
|
||||
int uwsgi_register_rpc(char *, uint8_t, uint8_t, void *);
|
||||
int uwsgi_register_rpc(char *, struct uwsgi_plugin *, uint8_t, void *);
|
||||
uint16_t uwsgi_rpc(char *, uint8_t, char **, uint16_t *, char *);
|
||||
char *uwsgi_do_rpc(char *, char *, uint8_t, char **, uint16_t *, uint16_t *);
|
||||
void uwsgi_rpc_init(void);
|
||||
@@ -2824,6 +2862,7 @@ void uwsgi_unix_signal(int, void (*)(int));
|
||||
char *uwsgi_get_exported_opt(char *);
|
||||
|
||||
int uwsgi_signal_add_cron(uint8_t, int, int, int, int, int);
|
||||
int uwsgi_cron_task_needs_execution(struct tm *, int, int, int, int, int);
|
||||
|
||||
char *uwsgi_get_optname_by_index(int);
|
||||
|
||||
@@ -3180,7 +3219,9 @@ void uwsgi_opt_add_cron(char *, char *, void *);
|
||||
void uwsgi_opt_load_plugin(char *, char *, void *);
|
||||
void uwsgi_opt_load_dl(char *, char *, void *);
|
||||
void uwsgi_opt_load(char *, char *, void *);
|
||||
void uwsgi_opt_safe_fd(char *, char *, void *);
|
||||
#ifdef UWSGI_SSL
|
||||
void uwsgi_opt_add_legion_cron(char *, char *, void *);
|
||||
void uwsgi_opt_sni(char *, char *, void *);
|
||||
struct uwsgi_string_list *uwsgi_ssl_add_sni_item(char *, char *, char *, char *, char *);
|
||||
#endif
|
||||
@@ -3704,6 +3745,7 @@ char *uwsgi_strip(char *);
|
||||
|
||||
#ifdef UWSGI_SSL
|
||||
void uwsgi_opt_legion(char *, char *, void *);
|
||||
void uwsgi_opt_legion_mcast(char *, char *, void *);
|
||||
struct uwsgi_legion *uwsgi_legion_register(char *, char *, char *, char *, char *);
|
||||
void uwsgi_opt_legion_node(char *, char *, void *);
|
||||
void uwsgi_legion_register_node(struct uwsgi_legion *, char *);
|
||||
@@ -3755,6 +3797,7 @@ uint64_t uwsgi_be64(char *);
|
||||
int uwsgi_websocket_handshake(struct wsgi_request *, char *, uint16_t, char *, uint16_t);
|
||||
|
||||
int uwsgi_response_prepare_headers(struct wsgi_request *, char *, uint16_t);
|
||||
int uwsgi_response_prepare_headers_int(struct wsgi_request *, int);
|
||||
int uwsgi_response_add_header(struct wsgi_request *, char *, uint16_t, char *, uint16_t);
|
||||
int uwsgi_response_commit_headers(struct wsgi_request *);
|
||||
int uwsgi_response_sendfile_do(struct wsgi_request *, int, size_t, size_t);
|
||||
@@ -3778,6 +3821,7 @@ ssize_t uwsgi_sendfile_do(int, int, size_t, size_t);
|
||||
int uwsgi_proto_base_fix_headers(struct wsgi_request *);
|
||||
int uwsgi_response_add_content_length(struct wsgi_request *, uint64_t);
|
||||
int uwsgi_response_add_content_range(struct wsgi_request *, uint64_t, uint64_t, uint64_t);
|
||||
int uwsgi_response_add_expires(struct wsgi_request *, uint64_t);
|
||||
|
||||
const char *uwsgi_http_status_msg(char *, uint16_t *);
|
||||
int uwsgi_stats_dump_vars(struct uwsgi_stats *, struct uwsgi_core *);
|
||||
@@ -3871,7 +3915,7 @@ struct uwsgi_cache_magic_context {
|
||||
uint16_t cache_len;
|
||||
};
|
||||
|
||||
char *uwsgi_cache_magic_get(char *, uint16_t, uint64_t *, char *);
|
||||
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 *);
|
||||
@@ -3886,6 +3930,7 @@ int uwsgi_emperor_vassal_start(struct uwsgi_instance *);
|
||||
int uwsgi_deflate_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);
|
||||
#endif
|
||||
|
||||
char *uwsgi_get_cookie(struct wsgi_request *, char *, uint16_t, uint16_t *);
|
||||
@@ -3899,6 +3944,21 @@ char *uwsgi_get_mime_type(char *, int, size_t *);
|
||||
void config_magic_table_fill(char *, char *[]);
|
||||
|
||||
int uwsgi_blob_to_response(struct wsgi_request *, char *, size_t);
|
||||
struct uwsgi_cron *uwsgi_cron_add(char *);
|
||||
int uwsgi_is_full_http(struct uwsgi_buffer *);
|
||||
|
||||
int uwsgi_http_date(time_t t, char *);
|
||||
|
||||
int uwsgi_apply_transformations(struct wsgi_request *wsgi_req);
|
||||
struct uwsgi_transformation *uwsgi_add_transformation(struct wsgi_request *wsgi_req, int (*func)(struct wsgi_request *, struct uwsgi_buffer *, struct uwsgi_buffer **, void *), void *);
|
||||
|
||||
void uwsgi_file_write_do(struct uwsgi_string_list *);
|
||||
|
||||
int uwsgi_fd_is_safe(int);
|
||||
void uwsgi_add_safe_fd(int);
|
||||
|
||||
void uwsgi_ipcsem_clear(void);
|
||||
char *uwsgi_str_to_hex(char *, size_t);
|
||||
|
||||
void uwsgi_check_emperor(void);
|
||||
#ifdef UWSGI_AS_SHARED_LIBRARY
|
||||
|
||||
+9
-4
@@ -1,6 +1,6 @@
|
||||
# uWSGI build system
|
||||
|
||||
uwsgi_version = '1.9.6'
|
||||
uwsgi_version = '1.9.8'
|
||||
|
||||
import os
|
||||
import re
|
||||
@@ -216,6 +216,9 @@ def build_uwsgi(uc, print_only=False):
|
||||
|
||||
gcc_list, cflags, ldflags, libs = uc.get_gcll()
|
||||
|
||||
if 'UWSGI_EMBED_PLUGINS' in os.environ:
|
||||
uc.set('embedded_plugins', uc.get('embedded_plugins') + ',' + os.environ['UWSGI_EMBED_PLUGINS'])
|
||||
|
||||
if uc.get('embedded_plugins'):
|
||||
ep = uc.get('embedded_plugins').split(',')
|
||||
epc = "-DUWSGI_DECLARE_EMBEDDED_PLUGINS=\""
|
||||
@@ -456,10 +459,10 @@ class uConf(object):
|
||||
self.gcc_list = ['core/utils', 'core/protocol', 'core/socket', 'core/logging', 'core/master', 'core/master_utils', 'core/emperor',
|
||||
'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/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/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/uwsgi']
|
||||
'core/rpc', 'core/gateway', 'core/loop', 'core/cookie', 'core/querystring', 'core/rb_timers', 'core/transformations', 'core/uwsgi']
|
||||
# add protocols
|
||||
self.gcc_list.append('proto/base')
|
||||
self.gcc_list.append('proto/uwsgi')
|
||||
@@ -669,6 +672,8 @@ class uConf(object):
|
||||
self.cflags.append('-DUWSGI_LOCK_USE_OSX_SPINLOCK')
|
||||
elif locking_mode == 'windows_mutex':
|
||||
self.cflags.append('-DUWSGI_LOCK_USE_WINDOWS_MUTEX')
|
||||
else:
|
||||
self.cflags.append('-DUWSGI_IPCSEM_ATEXIT')
|
||||
|
||||
if locking_mode == 'auto':
|
||||
report['locking'] = 'sysv semaphores'
|
||||
@@ -730,7 +735,7 @@ class uConf(object):
|
||||
if int(sun_minor) >= 10:
|
||||
timer_mode = 'port'
|
||||
|
||||
elif uwsgi_os in ('Darwin', 'FreeBSD'):
|
||||
elif uwsgi_os in ('Darwin', 'FreeBSD', 'OpenBSD', 'NetBSD', 'DragonFly'):
|
||||
timer_mode = 'kqueue'
|
||||
|
||||
if timer_mode == 'timerfd':
|
||||
|
||||
Reference in New Issue
Block a user