mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-10-05 00:18:36 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
807060706f | ||
|
|
a317f88d3c | ||
|
|
e17a7f0701 | ||
|
|
db325eb9fe | ||
|
|
b41a4c8c3b | ||
|
|
73b4d11d18 | ||
|
|
8162b87287 | ||
|
|
70e9e4f3ee | ||
|
|
e61ae376b3 | ||
|
|
2d57b0e926 | ||
|
|
ae683af07a | ||
|
|
3c4f6a9171 | ||
|
|
39986e546c | ||
|
|
2e81a80f7b | ||
|
|
fcb3aa38c8 | ||
|
|
00a38d8ec5 | ||
|
|
07a0ab4227 | ||
|
|
d4a9a2c543 | ||
|
|
2b523fc60d | ||
|
|
0c26928236 | ||
|
|
8401e56a22 | ||
|
|
5109f9ae0b | ||
|
|
c9bc06669a | ||
|
|
a83fb2672c | ||
|
|
8f9ecb44d9 | ||
|
|
bfcc09a8de | ||
|
|
f8a8c997db | ||
|
|
132b996f30 | ||
|
|
12f970cdfb | ||
|
|
9afa963225 |
@@ -328,3 +328,29 @@ int uwsgi_buffer_set_uh(struct uwsgi_buffer *ub, uint8_t modifier1, uint8_t modi
|
||||
ub->buf[3] = modifier2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct uwsgi_buffer *uwsgi_buffer_from_file(char *filename) {
|
||||
struct stat st;
|
||||
int fd = open(filename, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fstat(fd, &st)) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct uwsgi_buffer *ub = uwsgi_buffer_new(st.st_size);
|
||||
|
||||
ssize_t len = read(fd, ub->buf, st.st_size);
|
||||
close(fd);
|
||||
if (len != st.st_size) {
|
||||
uwsgi_buffer_destroy(ub);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ub->pos = len;
|
||||
return ub;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
#include <uwsgi.h>
|
||||
|
||||
/*
|
||||
|
||||
cookie management functions (mainly used by the internal routing subsystem)
|
||||
|
||||
*/
|
||||
|
||||
static char *check_cookie(char *cookie, uint16_t cookie_len, char *key, uint16_t keylen, uint16_t *vallen) {
|
||||
uint16_t orig_cookie_len = cookie_len-1;
|
||||
// first lstrip white spaces
|
||||
char *ptr = cookie;
|
||||
uint16_t i;
|
||||
for(i=0;i<cookie_len;i++) {
|
||||
if (isspace((int)ptr[i])) {
|
||||
cookie++;
|
||||
cookie_len--;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// then rstrip (skipping the first char...)
|
||||
for(i=orig_cookie_len;i>0;i--) {
|
||||
if (isspace((int)ptr[i])) {
|
||||
cookie_len--;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// now search for the first equal sign
|
||||
char *equal = memchr(cookie, '=', cookie_len);
|
||||
if (!equal) return NULL;
|
||||
|
||||
if (uwsgi_strncmp(key, keylen, cookie, equal-cookie)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cookie_len -= (equal-cookie)+1;
|
||||
if (cookie_len == 0) return NULL;
|
||||
|
||||
*vallen = cookie_len;
|
||||
return equal+1;
|
||||
}
|
||||
|
||||
char *uwsgi_get_cookie(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, uint16_t *vallen) {
|
||||
uint16_t i;
|
||||
|
||||
char *cookie = wsgi_req->cookie;
|
||||
uint16_t cookie_len = 0;
|
||||
char *ptr = wsgi_req->cookie;
|
||||
//start splitting by ;
|
||||
for(i=0;i<wsgi_req->cookie_len;i++) {
|
||||
if (!cookie) {
|
||||
cookie = ptr + i;
|
||||
}
|
||||
if (ptr[i] == ';') {
|
||||
char *value = check_cookie(cookie, cookie_len, key, keylen, vallen);
|
||||
if (value) {
|
||||
return value;
|
||||
}
|
||||
cookie_len = 0;
|
||||
cookie = NULL;
|
||||
}
|
||||
else {
|
||||
cookie_len++;
|
||||
}
|
||||
}
|
||||
|
||||
if (cookie_len > 0) {
|
||||
char *value = check_cookie(cookie, cookie_len, key, keylen, vallen);
|
||||
if (value) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
+13
-1
@@ -7,6 +7,8 @@ extern struct uwsgi_server uwsgi;
|
||||
This memory must not be freed for all the server lifecycle
|
||||
*/
|
||||
|
||||
static char *last_file = NULL;
|
||||
|
||||
void ini_rstrip(char *line) {
|
||||
|
||||
off_t i;
|
||||
@@ -104,13 +106,23 @@ void uwsgi_ini_config(char *file, char *magic_table[]) {
|
||||
if (colon[1] != 0) {
|
||||
section_asked = colon + 1;
|
||||
}
|
||||
|
||||
if (colon == file) {
|
||||
file = last_file;
|
||||
}
|
||||
}
|
||||
|
||||
if (file[0] != 0) {
|
||||
if (file[0] != 0 && file != last_file) {
|
||||
uwsgi_log_initial("[uWSGI] getting INI configuration from %s\n", file);
|
||||
}
|
||||
|
||||
ini = uwsgi_open_and_read(file, &len, 1, magic_table);
|
||||
if (file != last_file) {
|
||||
if (last_file) {
|
||||
free(last_file);
|
||||
}
|
||||
last_file = uwsgi_str(file);
|
||||
}
|
||||
|
||||
while (len) {
|
||||
ini_line = ini_get_line(ini, len);
|
||||
|
||||
@@ -354,6 +354,13 @@ static int uwsgi_proto_check_11(struct wsgi_request *wsgi_req, char *key, char *
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!uwsgi_proto_key("HTTP_COOKIE", 11)) {
|
||||
wsgi_req->cookie = buf;
|
||||
wsgi_req->cookie_len = len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if (!uwsgi_proto_key("UWSGI_APPID", 11)) {
|
||||
wsgi_req->appid = buf;
|
||||
wsgi_req->appid_len = len;
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
#include <uwsgi.h>
|
||||
|
||||
/*
|
||||
|
||||
QUERY_STRING management functions (mainly used by the internal routing subsystem)
|
||||
|
||||
*/
|
||||
|
||||
static char *check_qs(char *qs, uint16_t qs_len, char *key, uint16_t keylen, uint16_t *vallen) {
|
||||
// search for the equal sign
|
||||
char *equal = memchr(qs, '=', qs_len);
|
||||
if (!equal) return NULL;
|
||||
|
||||
if (uwsgi_strncmp(key, keylen, qs, equal-qs)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
qs_len -= (equal-qs)+1;
|
||||
if (qs_len == 0) return NULL;
|
||||
|
||||
*vallen = qs_len;
|
||||
return equal+1;
|
||||
}
|
||||
|
||||
char *uwsgi_get_qs(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, uint16_t *vallen) {
|
||||
uint16_t i;
|
||||
|
||||
char *qs = wsgi_req->query_string;
|
||||
uint16_t qs_len = 0;
|
||||
char *ptr = wsgi_req->query_string;
|
||||
//start splitting by ;
|
||||
for(i=0;i<wsgi_req->query_string_len;i++) {
|
||||
if (!qs) {
|
||||
qs = ptr + i;
|
||||
}
|
||||
if (ptr[i] == '&') {
|
||||
char *value = check_qs(qs, qs_len, key, keylen, vallen);
|
||||
if (value) {
|
||||
return value;
|
||||
}
|
||||
qs_len = 0;
|
||||
qs = NULL;
|
||||
}
|
||||
else {
|
||||
qs_len++;
|
||||
}
|
||||
}
|
||||
|
||||
if (qs_len > 0) {
|
||||
char *value = check_qs(qs, qs_len, key, keylen, vallen);
|
||||
if (value) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
+14
-14
@@ -108,64 +108,65 @@ static int consume_body_for_readline(struct wsgi_request *wsgi_req) {
|
||||
}
|
||||
}
|
||||
|
||||
remains = UMIN(wsgi_req->post_readline_size - wsgi_req->post_readline_watermark, wsgi_req->post_cl - wsgi_req->post_pos);
|
||||
|
||||
// read from a file
|
||||
if (wsgi_req->post_file) {
|
||||
size_t ret = fread(wsgi_req->post_readline_buf + wsgi_req->post_readline_watermark, wsgi_req->post_readline_size - wsgi_req->post_readline_watermark, 1, wsgi_req->post_file);
|
||||
size_t ret = fread(wsgi_req->post_readline_buf + wsgi_req->post_readline_watermark, remains, 1, wsgi_req->post_file);
|
||||
if (ret == 0) {
|
||||
uwsgi_error("consume_body_for_readline()/fread()");
|
||||
return -1;
|
||||
}
|
||||
wsgi_req->post_pos += wsgi_req->post_readline_size - wsgi_req->post_readline_watermark;
|
||||
wsgi_req->post_readline_watermark += wsgi_req->post_readline_size - wsgi_req->post_readline_watermark;
|
||||
wsgi_req->post_pos += remains;
|
||||
wsgi_req->post_readline_watermark += remains;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// read from post_buffering memory
|
||||
if (uwsgi.post_buffering) {
|
||||
wsgi_req->post_pos += wsgi_req->post_readline_size - wsgi_req->post_readline_watermark;
|
||||
memcpy(wsgi_req->post_readline_buf + wsgi_req->post_readline_watermark, wsgi_req->post_buffering_buf + wsgi_req->post_pos, wsgi_req->post_readline_size - wsgi_req->post_readline_watermark);
|
||||
wsgi_req->post_readline_watermark += wsgi_req->post_readline_size - wsgi_req->post_readline_watermark;
|
||||
memcpy(wsgi_req->post_readline_buf + wsgi_req->post_readline_watermark, wsgi_req->post_buffering_buf + wsgi_req->post_pos, remains);
|
||||
wsgi_req->post_pos += remains;
|
||||
wsgi_req->post_readline_watermark += remains;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// read from socket
|
||||
ssize_t len = wsgi_req->socket->proto_read_body(wsgi_req, wsgi_req->post_readline_buf + wsgi_req->post_readline_watermark , wsgi_req->post_readline_size - wsgi_req->post_readline_watermark);
|
||||
ssize_t len = wsgi_req->socket->proto_read_body(wsgi_req, wsgi_req->post_readline_buf + wsgi_req->post_readline_watermark , remains);
|
||||
if (len > 0) {
|
||||
wsgi_req->post_pos += len;
|
||||
wsgi_req->post_readline_watermark += len;
|
||||
return 0;
|
||||
}
|
||||
if (len == 0) {
|
||||
uwsgi_read_error(wsgi_req->post_readline_size - wsgi_req->post_readline_watermark);
|
||||
uwsgi_read_error(remains);
|
||||
return -1;
|
||||
}
|
||||
if (len < 0) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) {
|
||||
goto wait;
|
||||
}
|
||||
uwsgi_read_error(wsgi_req->post_readline_size - wsgi_req->post_readline_watermark);
|
||||
uwsgi_read_error(remains);
|
||||
return -1;
|
||||
}
|
||||
wait:
|
||||
ret = uwsgi_wait_read_req(wsgi_req);
|
||||
if (ret > 0) {
|
||||
len = wsgi_req->socket->proto_read_body(wsgi_req, wsgi_req->post_readline_buf + wsgi_req->post_readline_watermark , wsgi_req->post_readline_size - wsgi_req->post_readline_watermark);
|
||||
len = wsgi_req->socket->proto_read_body(wsgi_req, wsgi_req->post_readline_buf + wsgi_req->post_readline_watermark , remains);
|
||||
if (len > 0) {
|
||||
wsgi_req->post_pos += len;
|
||||
wsgi_req->post_readline_watermark += len;
|
||||
return 0;
|
||||
}
|
||||
uwsgi_read_error(wsgi_req->post_readline_size - wsgi_req->post_readline_watermark);
|
||||
uwsgi_read_error(remains);
|
||||
return -1;
|
||||
}
|
||||
// 0 means timeout
|
||||
else if (ret == 0) {
|
||||
uwsgi_read_timeout(wsgi_req->post_readline_size - wsgi_req->post_readline_watermark);
|
||||
uwsgi_read_timeout(remains);
|
||||
return -1;
|
||||
}
|
||||
uwsgi_read_error(wsgi_req->post_readline_size - wsgi_req->post_readline_watermark);
|
||||
uwsgi_read_error(remains);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -347,7 +348,6 @@ char *uwsgi_request_body_read(struct wsgi_request *wsgi_req, ssize_t hint, ssize
|
||||
if (wsgi_req->post_file) {
|
||||
if (fread(wsgi_req->post_read_buf + *rlen, remains, 1, wsgi_req->post_file) != 1) {
|
||||
*rlen = -1;
|
||||
uwsgi_log("%llu\n", remains);
|
||||
uwsgi_error("uwsgi_request_body_read()/fread()");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+100
-4
@@ -3,6 +3,43 @@
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
struct uwsgi_route_var *uwsgi_register_route_var(char *name, char *(*func)(struct wsgi_request *, char *, uint16_t, uint16_t *)) {
|
||||
|
||||
struct uwsgi_route_var *old_urv = NULL,*urv = uwsgi.route_vars;
|
||||
while(urv) {
|
||||
if (!strcmp(urv->name, name)) {
|
||||
return urv;
|
||||
}
|
||||
old_urv = urv;
|
||||
urv = urv->next;
|
||||
}
|
||||
|
||||
urv = uwsgi_calloc(sizeof(struct uwsgi_route_var));
|
||||
urv->name = name;
|
||||
urv->name_len = strlen(name);
|
||||
urv->func = func;
|
||||
|
||||
if (old_urv) {
|
||||
old_urv->next = urv;
|
||||
}
|
||||
else {
|
||||
uwsgi.route_vars = urv;
|
||||
}
|
||||
|
||||
return urv;
|
||||
}
|
||||
|
||||
struct uwsgi_route_var *uwsgi_get_route_var(char *name, uint16_t name_len) {
|
||||
struct uwsgi_route_var *urv = uwsgi.route_vars;
|
||||
while(urv) {
|
||||
if (!uwsgi_strncmp(urv->name, urv->name_len, name, name_len)) {
|
||||
return urv;
|
||||
}
|
||||
urv = urv->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct uwsgi_buffer *uwsgi_routing_translate(struct wsgi_request *wsgi_req, struct uwsgi_route *ur, char *subject, uint16_t subject_len, char *data, size_t data_len) {
|
||||
|
||||
char *pass1 = data;
|
||||
@@ -44,9 +81,32 @@ struct uwsgi_buffer *uwsgi_routing_translate(struct wsgi_request *wsgi_req, stru
|
||||
case 2:
|
||||
if (pass1[i] == '}') {
|
||||
uint16_t vallen = 0;
|
||||
char *value = uwsgi_get_var(wsgi_req, key, keylen, &vallen);
|
||||
int need_free = 0;
|
||||
char *value = NULL;
|
||||
char *bracket = memchr(key, '[', keylen);
|
||||
if (bracket && keylen > 0 && key[keylen-1] == ']') {
|
||||
struct uwsgi_route_var *urv = uwsgi_get_route_var(key, bracket - key);
|
||||
if (urv) {
|
||||
need_free = urv->need_free;
|
||||
value = urv->func(wsgi_req, bracket + 1, keylen - (urv->name_len+2), &vallen);
|
||||
}
|
||||
else {
|
||||
value = uwsgi_get_var(wsgi_req, key, keylen, &vallen);
|
||||
}
|
||||
}
|
||||
else {
|
||||
value = uwsgi_get_var(wsgi_req, key, keylen, &vallen);
|
||||
}
|
||||
if (value) {
|
||||
if (uwsgi_buffer_append(ub, value, vallen)) goto error;
|
||||
if (uwsgi_buffer_append(ub, value, vallen)) {
|
||||
if (need_free) {
|
||||
free(value);
|
||||
}
|
||||
goto error;
|
||||
}
|
||||
if (need_free) {
|
||||
free(value);
|
||||
}
|
||||
}
|
||||
status = 0;
|
||||
key = NULL;
|
||||
@@ -108,6 +168,11 @@ int uwsgi_apply_routes_do(struct wsgi_request *wsgi_req, char *subject, uint16_t
|
||||
wsgi_req->route_goto = 0;
|
||||
|
||||
if (!routes->if_func) {
|
||||
// could be a "run"
|
||||
if (!routes->subject) {
|
||||
n = 0;
|
||||
goto run;
|
||||
}
|
||||
if (!subject) {
|
||||
char **subject2 = (char **) (((char *) (wsgi_req)) + routes->subject);
|
||||
uint16_t *subject_len2 = (uint16_t *) (((char *) (wsgi_req)) + routes->subject_len);
|
||||
@@ -137,6 +202,7 @@ int uwsgi_apply_routes_do(struct wsgi_request *wsgi_req, char *subject, uint16_t
|
||||
}
|
||||
}
|
||||
|
||||
run:
|
||||
if (n >= 0) {
|
||||
wsgi_req->is_routing = 1;
|
||||
int ret = routes->func(wsgi_req, routes);
|
||||
@@ -197,6 +263,8 @@ static void *uwsgi_route_get_condition_func(char *name) {
|
||||
|
||||
void uwsgi_opt_add_route(char *opt, char *value, void *foobar) {
|
||||
|
||||
char *space = NULL;
|
||||
char *command = NULL;
|
||||
struct uwsgi_route *old_ur = NULL,*ur = uwsgi.routes;
|
||||
uint64_t pos = 0;
|
||||
while(ur) {
|
||||
@@ -223,7 +291,12 @@ void uwsgi_opt_add_route(char *opt, char *value, void *foobar) {
|
||||
|
||||
char *route = uwsgi_str(value);
|
||||
|
||||
char *space = strchr(route, ' ');
|
||||
if (!strcmp(foobar, "run")) {
|
||||
command = route;
|
||||
goto done;
|
||||
}
|
||||
|
||||
space = strchr(route, ' ');
|
||||
if (!space) {
|
||||
uwsgi_log("invalid route syntax\n");
|
||||
exit(1);
|
||||
@@ -299,7 +372,8 @@ void uwsgi_opt_add_route(char *opt, char *value, void *foobar) {
|
||||
}
|
||||
}
|
||||
|
||||
char *command = space + 1;
|
||||
command = space + 1;
|
||||
done:
|
||||
ur->action = uwsgi_str(command);
|
||||
|
||||
char *colon = strchr(command, ':');
|
||||
@@ -666,6 +740,20 @@ static int uwsgi_route_condition_regexp(struct wsgi_request *wsgi_req, struct uw
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int uwsgi_route_condition_empty(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
|
||||
|
||||
struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, ur->subject_str, ur->subject_str_len);
|
||||
if (!ub) return -1;
|
||||
|
||||
if (ub->pos == 0) {
|
||||
uwsgi_buffer_destroy(ub);
|
||||
return 1;
|
||||
}
|
||||
|
||||
uwsgi_buffer_destroy(ub);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int uwsgi_route_condition_equal(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
|
||||
char *semicolon = memchr(ur->subject_str, ';', ur->subject_str_len);
|
||||
@@ -806,6 +894,11 @@ void uwsgi_register_embedded_routers() {
|
||||
uwsgi_register_route_condition("endswith", uwsgi_route_condition_endswith);
|
||||
uwsgi_register_route_condition("regexp", uwsgi_route_condition_regexp);
|
||||
uwsgi_register_route_condition("re", uwsgi_route_condition_regexp);
|
||||
|
||||
uwsgi_register_route_condition("empty", uwsgi_route_condition_empty);
|
||||
|
||||
uwsgi_register_route_var("cookie", uwsgi_get_cookie);
|
||||
uwsgi_register_route_var("qs", uwsgi_get_qs);
|
||||
}
|
||||
|
||||
struct uwsgi_router *uwsgi_register_router(char *name, int (*func) (struct uwsgi_route *, char *)) {
|
||||
@@ -864,6 +957,9 @@ void uwsgi_routing_dump() {
|
||||
if (routes->label) {
|
||||
uwsgi_log("[rule: %llu] label: %s\n", (unsigned long long ) routes->pos, routes->label);
|
||||
}
|
||||
else if (!routes->subject_str && !routes->if_func) {
|
||||
uwsgi_log("[rule: %llu] action: %s\n", (unsigned long long ) routes->pos, routes->action);
|
||||
}
|
||||
else {
|
||||
uwsgi_log("[rule: %llu] subject: %s %s: %s%s action: %s\n", (unsigned long long ) routes->pos, routes->subject_str, routes->if_func ? "func" : "regexp", routes->if_negate ? "!" : "", routes->regexp, routes->action);
|
||||
}
|
||||
|
||||
@@ -622,6 +622,25 @@ 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++;
|
||||
|
||||
+8
-1
@@ -80,6 +80,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
|
||||
{"for", required_argument, 0, "(opt logic) for cycle", uwsgi_opt_logic, (void *) uwsgi_logic_opt_for, UWSGI_OPT_IMMEDIATE},
|
||||
{"for-glob", required_argument, 0, "(opt logic) for cycle (expand glob)", uwsgi_opt_logic, (void *) uwsgi_logic_opt_for_glob, UWSGI_OPT_IMMEDIATE},
|
||||
{"endfor", optional_argument, 0, "(opt logic) end for cycle", uwsgi_opt_noop, NULL, UWSGI_OPT_IMMEDIATE},
|
||||
{"end-for", optional_argument, 0, "(opt logic) end for cycle", uwsgi_opt_noop, NULL, UWSGI_OPT_IMMEDIATE},
|
||||
|
||||
{"if-opt", required_argument, 0, "(opt logic) check for option", uwsgi_opt_logic, (void *) uwsgi_logic_opt_if_opt, UWSGI_OPT_IMMEDIATE},
|
||||
{"if-not-opt", required_argument, 0, "(opt logic) check for option", uwsgi_opt_logic, (void *) uwsgi_logic_opt_if_not_opt, UWSGI_OPT_IMMEDIATE},
|
||||
@@ -108,6 +109,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
|
||||
{"if-directory", required_argument, 0, "(opt logic) check for directory existance", uwsgi_opt_logic, (void *) uwsgi_logic_opt_if_dir, UWSGI_OPT_IMMEDIATE},
|
||||
|
||||
{"endif", optional_argument, 0, "(opt logic) end if", uwsgi_opt_noop, NULL, UWSGI_OPT_IMMEDIATE},
|
||||
{"end-if", optional_argument, 0, "(opt logic) end if", uwsgi_opt_noop, NULL, UWSGI_OPT_IMMEDIATE},
|
||||
|
||||
{"blacklist", required_argument, 0, "set options blacklist context", uwsgi_opt_set_str, &uwsgi.blacklist_context, UWSGI_OPT_IMMEDIATE},
|
||||
{"end-blacklist", no_argument, 0, "clear options blacklist context", uwsgi_opt_set_null, &uwsgi.blacklist_context, UWSGI_OPT_IMMEDIATE},
|
||||
@@ -377,7 +379,6 @@ static struct uwsgi_option uwsgi_base_options[] = {
|
||||
{"legion-death", required_argument, 0, "action to call on legion death (shutdown of the instance)", uwsgi_opt_legion_hook, NULL, UWSGI_OPT_MASTER},
|
||||
{"legion-quorum", required_argument, 0, "set the quorum of a legion", uwsgi_opt_legion_quorum, NULL, UWSGI_OPT_MASTER},
|
||||
{"legion-scroll", required_argument, 0, "set the scroll of a legion", uwsgi_opt_legion_scroll, NULL, UWSGI_OPT_MASTER},
|
||||
{"legion-scroll", required_argument, 0, "set the scroll of a legion", uwsgi_opt_legion_scroll, NULL, UWSGI_OPT_MASTER},
|
||||
{"legion-scroll-max-size", required_argument, 0, "set max size of legion scroll buffer", uwsgi_opt_set_16bit, &uwsgi.legion_scroll_max_size, 0},
|
||||
{"legion-scroll-list-max-size", required_argument, 0, "set max size of legion scroll list buffer", uwsgi_opt_set_64bit, &uwsgi.legion_scroll_list_max_size, 0},
|
||||
{"subscriptions-sign-check", required_argument, 0, "set digest algorithm and certificate directory for secured subscription system", uwsgi_opt_scd, NULL, UWSGI_OPT_MASTER},
|
||||
@@ -511,6 +512,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
|
||||
{"route-label", required_argument, 0, "add a routing label (for use with goto)", uwsgi_opt_add_route, NULL, 0},
|
||||
{"route-if", required_argument, 0, "add a route based on condition", uwsgi_opt_add_route, "if", 0},
|
||||
{"route-if-not", required_argument, 0, "add a route based on condition (negate version)", uwsgi_opt_add_route, "if-not", 0},
|
||||
{"route-run", required_argument, 0, "always run the specified route action", uwsgi_opt_add_route, "run", 0},
|
||||
{"router-list", no_argument, 0, "list enabled routers", uwsgi_opt_true, &uwsgi.router_list, 0},
|
||||
{"routers-list", no_argument, 0, "list enabled routers", uwsgi_opt_true, &uwsgi.router_list, 0},
|
||||
#endif
|
||||
@@ -784,8 +786,12 @@ void config_magic_table_fill(char *filename, char **magic_table) {
|
||||
char *section = uwsgi_get_last_char(filename, ':');
|
||||
if (section) {
|
||||
*section = 0;
|
||||
if (section == filename) {
|
||||
goto reuse;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// we have a special case for symlinks
|
||||
if (uwsgi_is_link(filename)) {
|
||||
if (filename[0] != '/') {
|
||||
@@ -839,6 +845,7 @@ void config_magic_table_fill(char *filename, char **magic_table) {
|
||||
if (uwsgi_get_last_char(magic_table['s'], '.'))
|
||||
magic_table['n'] = uwsgi_concat2n(magic_table['s'], uwsgi_get_last_char(magic_table['s'], '.') - magic_table['s'], "", 0);
|
||||
|
||||
reuse:
|
||||
if (section) {
|
||||
magic_table['x'] = section+1;
|
||||
*section = ':';
|
||||
|
||||
@@ -141,6 +141,7 @@ int uwsgi_response_write_headers_do(struct wsgi_request *wsgi_req) {
|
||||
return UWSGI_OK;
|
||||
}
|
||||
|
||||
// this is the function called by all request plugins to send chunks to the client
|
||||
int uwsgi_response_write_body_do(struct wsgi_request *wsgi_req, char *buf, size_t len) {
|
||||
|
||||
if (wsgi_req->write_errors) return -1;
|
||||
@@ -182,6 +183,18 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
extern struct uwsgi_rack ur;
|
||||
extern struct uwsgi_plugin rack_plugin;
|
||||
|
||||
struct ufib {
|
||||
int enabled;
|
||||
@@ -45,7 +46,7 @@ static void fiber_schedule_to_req() {
|
||||
int error = 0;
|
||||
rb_protect(rb_fiber_schedule_to_req, 0, &error);
|
||||
if (error) {
|
||||
uwsgi_ruby_exception();
|
||||
rack_plugin.exception_log(NULL);
|
||||
rb_gc_unregister_address(&ufiber.fib[id]);
|
||||
uwsgi.wsgi_req->async_status = UWSGI_OK;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
#include <uwsgi.h>
|
||||
|
||||
#include <GeoIP.h>
|
||||
#include <GeoIPCity.h>
|
||||
|
||||
struct uwsgi_geoip {
|
||||
char *country_db;
|
||||
char *city_db;
|
||||
GeoIP *country;
|
||||
GeoIP *city;
|
||||
|
||||
} ugeoip;
|
||||
|
||||
struct uwsgi_option uwsgi_geoip_options[] = {
|
||||
{"geoip-country", required_argument, 0, "load the specified geoip country database", uwsgi_opt_set_str, &ugeoip.country_db, 0},
|
||||
{"geoip-city", required_argument, 0, "load the specified geoip city database", uwsgi_opt_set_str, &ugeoip.city_db, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
static int uwsgi_geoip_init() {
|
||||
if (ugeoip.country_db) {
|
||||
ugeoip.country = GeoIP_open(ugeoip.country_db, GEOIP_MEMORY_CACHE);
|
||||
if (!ugeoip.country) {
|
||||
uwsgi_log("unable to open GeoIP country database: %s\n", ugeoip.country_db);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (ugeoip.city_db) {
|
||||
ugeoip.city = GeoIP_open(ugeoip.city_db, GEOIP_MEMORY_CACHE);
|
||||
if (!ugeoip.city) {
|
||||
uwsgi_log("unable to open GeoIP city database: %s\n", ugeoip.city_db);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *uwsgi_route_var_geoip(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, uint16_t *vallen) {
|
||||
uint32_t ip;
|
||||
char ip_str[16];
|
||||
// should be enough for geo coords
|
||||
char lonlat[64];
|
||||
memset(ip_str, 0, 16);
|
||||
memcpy(ip_str, wsgi_req->remote_addr, wsgi_req->remote_addr_len);
|
||||
if (inet_pton(AF_INET, ip_str, &ip) <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
ip = htonl(ip);
|
||||
char *value = NULL;
|
||||
// always prefer the city database;
|
||||
GeoIP *g = ugeoip.city;
|
||||
if (!g) {
|
||||
g = ugeoip.country;
|
||||
if (g) {
|
||||
if (!uwsgi_strncmp(key, keylen, "country_code", 12)) {
|
||||
value = (char *) GeoIP_country_code_by_ipnum(g, ip);
|
||||
}
|
||||
else if (!uwsgi_strncmp(key, keylen, "country_code3", 13)) {
|
||||
value = (char *) GeoIP_country_code3_by_ipnum(g, ip);
|
||||
}
|
||||
else if (!uwsgi_strncmp(key, keylen, "country_name", 12)) {
|
||||
value = (char *) GeoIP_country_name_by_ipnum(g, ip);
|
||||
}
|
||||
|
||||
if (value) {
|
||||
*vallen = strlen(value);
|
||||
return uwsgi_str(value);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GeoIPRecord *gr = GeoIP_record_by_ipnum(g, ip);
|
||||
if (!gr) return NULL;
|
||||
|
||||
// ok let's generate the output
|
||||
if (!uwsgi_strncmp(key, keylen, "continent", 9)) {
|
||||
value = gr->continent_code;
|
||||
}
|
||||
else if (!uwsgi_strncmp(key, keylen, "country_code", 12)) {
|
||||
value = gr->country_code;
|
||||
}
|
||||
else if (!uwsgi_strncmp(key, keylen, "country_code3", 13)) {
|
||||
value = gr->country_code3;
|
||||
}
|
||||
else if (!uwsgi_strncmp(key, keylen, "country_name", 12)) {
|
||||
value = gr->country_name;
|
||||
}
|
||||
else if (!uwsgi_strncmp(key, keylen, "region", 6)) {
|
||||
value = gr->region;
|
||||
}
|
||||
else if (!uwsgi_strncmp(key, keylen, "region_name", 11)) {
|
||||
value = (char *) GeoIP_region_name_by_code(gr->country_code, gr->region);
|
||||
}
|
||||
else if (!uwsgi_strncmp(key, keylen, "city", 4)) {
|
||||
value = gr->city;
|
||||
}
|
||||
else if (!uwsgi_strncmp(key, keylen, "postal_code", 11)) {
|
||||
value = gr->postal_code;
|
||||
}
|
||||
else if (!uwsgi_strncmp(key, keylen, "latitude", 8) || !uwsgi_strncmp(key, keylen, "lat", 3)) {
|
||||
snprintf(lonlat, 64, "%f", gr->latitude);
|
||||
value = lonlat;
|
||||
}
|
||||
else if (!uwsgi_strncmp(key, keylen, "longitude", 9) || !uwsgi_strncmp(key, keylen, "lon", 3)) {
|
||||
snprintf(lonlat, 64, "%f", gr->longitude);
|
||||
value = lonlat;
|
||||
}
|
||||
else if (!uwsgi_strncmp(key, keylen, "dma", 3)) {
|
||||
snprintf(lonlat, 64, "%d", gr->dma_code);
|
||||
value = lonlat;
|
||||
}
|
||||
else if (!uwsgi_strncmp(key, keylen, "area", 4)) {
|
||||
snprintf(lonlat, 64, "%d", gr->area_code);
|
||||
value = lonlat;
|
||||
}
|
||||
|
||||
|
||||
if (value) {
|
||||
*vallen = strlen(value);
|
||||
char *ret = uwsgi_str(value);
|
||||
GeoIPRecord_delete(gr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
GeoIPRecord_delete(gr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void register_route_vars_geoip() {
|
||||
struct uwsgi_route_var *urv = uwsgi_register_route_var("geoip", uwsgi_route_var_geoip);
|
||||
urv->need_free = 1;
|
||||
}
|
||||
|
||||
struct uwsgi_plugin geoip_plugin = {
|
||||
.name = "geoip",
|
||||
.options = uwsgi_geoip_options,
|
||||
.init = uwsgi_geoip_init,
|
||||
.on_load = register_route_vars_geoip,
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
NAME='geoip'
|
||||
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = ['-lGeoIP']
|
||||
|
||||
GCC_LIST = ['geoip']
|
||||
|
||||
@@ -58,11 +58,12 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
|
||||
char *status_line = NULL;
|
||||
size_t status_line_len = 0;
|
||||
#ifdef PYTHREE
|
||||
PyObject *zero = NULL;
|
||||
PyObject *zero2 = NULL;
|
||||
if (self != Py_None) {
|
||||
PyObject *zero = PyUnicode_AsASCIIString(head);
|
||||
zero = PyUnicode_AsASCIIString(head);
|
||||
status_line = PyBytes_AsString(zero);
|
||||
status_line_len = PyBytes_Size(zero);
|
||||
Py_DECREF(zero);
|
||||
}
|
||||
else {
|
||||
status_line = PyBytes_AsString(head);
|
||||
@@ -73,9 +74,15 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
|
||||
status_line_len = PyString_Size(head);
|
||||
#endif
|
||||
if (uwsgi_response_prepare_headers(wsgi_req, status_line, status_line_len)) {
|
||||
#ifdef PYTHREE
|
||||
Py_DECREF(zero);
|
||||
#endif
|
||||
return PyErr_Format(PyExc_TypeError, "unable to set HTTP status line");
|
||||
}
|
||||
|
||||
#ifdef PYTHREE
|
||||
Py_DECREF(zero);
|
||||
#endif
|
||||
|
||||
headers = PyTuple_GetItem(args, 1);
|
||||
if (!headers) {
|
||||
@@ -125,10 +132,9 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
|
||||
|
||||
#ifdef PYTHREE
|
||||
if (self != Py_None) {
|
||||
PyObject *zero = PyUnicode_AsASCIIString(h_key);
|
||||
zero = PyUnicode_AsASCIIString(h_key);
|
||||
k = PyBytes_AsString(zero);
|
||||
kl = PyBytes_Size(zero);
|
||||
Py_DECREF(zero);
|
||||
}
|
||||
else {
|
||||
k = PyBytes_AsString(h_key);
|
||||
@@ -141,10 +147,9 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
|
||||
|
||||
#ifdef PYTHREE
|
||||
if (self != Py_None) {
|
||||
PyObject *zero = PyUnicode_AsASCIIString(h_value);
|
||||
v = PyBytes_AsString(zero);
|
||||
vl = PyBytes_Size(zero);
|
||||
Py_DECREF(zero);
|
||||
zero2 = PyUnicode_AsASCIIString(h_value);
|
||||
v = PyBytes_AsString(zero2);
|
||||
vl = PyBytes_Size(zero2);
|
||||
}
|
||||
else {
|
||||
v = PyBytes_AsString(h_value);
|
||||
@@ -156,9 +161,18 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
|
||||
#endif
|
||||
|
||||
if (uwsgi_response_add_header(wsgi_req, k, kl, v, vl)) {
|
||||
#ifdef PYTHREE
|
||||
Py_DECREF(zero);
|
||||
Py_DECREF(zero2);
|
||||
#endif
|
||||
return PyErr_Format(PyExc_TypeError, "unable to add header to the response");
|
||||
}
|
||||
|
||||
#ifdef PYTHREE
|
||||
Py_DECREF(zero);
|
||||
Py_DECREF(zero2);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
if (up.start_response_nodelay) {
|
||||
|
||||
@@ -10,7 +10,7 @@ extern struct uwsgi_server uwsgi;
|
||||
|
||||
syntax:
|
||||
|
||||
route = /^foobar1(.*)/ cache:key=foo$1poo,type=body,content_type=text/html,name=foobar
|
||||
route = /^foobar1(.*)/ cache:key=foo$1poo,content_type=text/html,name=foobar
|
||||
|
||||
*/
|
||||
|
||||
@@ -18,21 +18,57 @@ struct uwsgi_router_cache_conf {
|
||||
|
||||
// the name of the cache
|
||||
char *name;
|
||||
size_t name_len;
|
||||
|
||||
char *key;
|
||||
size_t key_len;
|
||||
|
||||
char *type;
|
||||
|
||||
char *content_type;
|
||||
size_t content_type_len;
|
||||
|
||||
// 0 -> full, 1 -> body
|
||||
int type_num;
|
||||
struct uwsgi_cache *cache;
|
||||
|
||||
char *expires_str;
|
||||
uint64_t expires;
|
||||
|
||||
};
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
wsgi_req->cache_it_expires = urcc->expires;
|
||||
|
||||
return UWSGI_ROUTE_NEXT;
|
||||
|
||||
}
|
||||
|
||||
static int uwsgi_routing_func_cache(struct wsgi_request *wsgi_req, struct uwsgi_route *ur){
|
||||
|
||||
struct uwsgi_router_cache_conf *urcc = (struct uwsgi_router_cache_conf *) ur->data2;
|
||||
@@ -46,12 +82,9 @@ static int uwsgi_routing_func_cache(struct wsgi_request *wsgi_req, struct uwsgi_
|
||||
char *value = uwsgi_cache_magic_get(ub->buf, ub->pos, &valsize, urcc->name);
|
||||
uwsgi_buffer_destroy(ub);
|
||||
if (value) {
|
||||
if (urcc->type_num == 1) {
|
||||
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 (uwsgi_response_add_content_length(wsgi_req, valsize)) goto error;
|
||||
}
|
||||
// body only
|
||||
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 (uwsgi_response_add_content_length(wsgi_req, valsize)) goto error;
|
||||
uwsgi_response_write_body_do(wsgi_req, value, valsize);
|
||||
free(value);
|
||||
if (ur->custom)
|
||||
@@ -65,6 +98,45 @@ error:
|
||||
return UWSGI_ROUTE_BREAK;
|
||||
}
|
||||
|
||||
static int uwsgi_router_cache_store(struct uwsgi_route *ur, char *args) {
|
||||
ur->func = uwsgi_routing_func_cache_store;
|
||||
ur->data = args;
|
||||
ur->data_len = strlen(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,
|
||||
"name", &urcc->name,
|
||||
"expires", &urcc->expires_str, NULL)) {
|
||||
uwsgi_log("invalid cachestore route syntax: %s\n", args);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (urcc->key) {
|
||||
urcc->key_len = strlen(urcc->key);
|
||||
}
|
||||
|
||||
if (urcc->name) {
|
||||
urcc->name_len = strlen(urcc->name);
|
||||
}
|
||||
|
||||
if (!urcc->key) {
|
||||
uwsgi_log("invalid cachestore route syntax: you need to specify a cache key\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (urcc->expires_str) {
|
||||
urcc->expires = strtoul(urcc->expires_str, NULL, 10);
|
||||
}
|
||||
|
||||
ur->data2 = urcc;
|
||||
return 0;
|
||||
error:
|
||||
if (urcc->key) free(urcc->key);
|
||||
if (urcc->name) free(urcc->name);
|
||||
if (urcc->expires_str) free(urcc->expires_str);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int uwsgi_router_cache(struct uwsgi_route *ur, char *args) {
|
||||
ur->func = uwsgi_routing_func_cache;
|
||||
ur->data = args;
|
||||
@@ -74,7 +146,7 @@ static int uwsgi_router_cache(struct uwsgi_route *ur, char *args) {
|
||||
"key", &urcc->key,
|
||||
"content_type", &urcc->content_type,
|
||||
"name", &urcc->name,
|
||||
"type", &urcc->type, NULL)) {
|
||||
NULL)) {
|
||||
uwsgi_log("invalid route syntax: %s\n", args);
|
||||
exit(1);
|
||||
}
|
||||
@@ -88,15 +160,10 @@ static int uwsgi_router_cache(struct uwsgi_route *ur, char *args) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!urcc->type) urcc->type = "full";
|
||||
if (!urcc->content_type) urcc->content_type = "text/html";
|
||||
|
||||
urcc->content_type_len = strlen(urcc->content_type);
|
||||
|
||||
if (!strcmp(urcc->type, "body")) {
|
||||
urcc->type_num = 1;
|
||||
}
|
||||
|
||||
ur->data2 = urcc;
|
||||
return 0;
|
||||
}
|
||||
@@ -110,6 +177,8 @@ static int uwsgi_router_cache_continue(struct uwsgi_route *ur, char *args) {
|
||||
static void router_cache_register() {
|
||||
uwsgi_register_router("cache", uwsgi_router_cache);
|
||||
uwsgi_register_router("cache-continue", uwsgi_router_cache_continue);
|
||||
uwsgi_register_router("cachestore", uwsgi_router_cache_store);
|
||||
uwsgi_register_router("cache-store", uwsgi_router_cache_store);
|
||||
}
|
||||
|
||||
struct uwsgi_plugin router_cache_plugin = {
|
||||
|
||||
@@ -0,0 +1,526 @@
|
||||
#include <uwsgi.h>
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
#define UWSGI_SSI_MAX_ARGS 8
|
||||
|
||||
/*
|
||||
|
||||
uWSGI server side includes implementation
|
||||
|
||||
*/
|
||||
|
||||
|
||||
struct uwsgi_ssi_arg {
|
||||
char *key;
|
||||
size_t key_len;
|
||||
char *value;
|
||||
size_t val_len;
|
||||
};
|
||||
|
||||
struct uwsgi_ssi_cmd {
|
||||
char *name;
|
||||
size_t name_len;
|
||||
struct uwsgi_buffer *(*func)(struct wsgi_request *, struct uwsgi_ssi_arg *, int);
|
||||
struct uwsgi_ssi_cmd *next;
|
||||
};
|
||||
|
||||
struct uwsgi_ssi_cmd *uwsgi_ssi_commands = NULL;
|
||||
|
||||
static struct uwsgi_ssi_cmd* uwsgi_ssi_get_cmd(char *name, size_t name_len) {
|
||||
struct uwsgi_ssi_cmd *usc = uwsgi_ssi_commands;
|
||||
while(usc) {
|
||||
if (!uwsgi_strncmp(usc->name, usc->name_len, name, name_len)) {
|
||||
return usc;
|
||||
}
|
||||
usc = usc->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct uwsgi_ssi_cmd *uwsgi_register_ssi_command(char *name, struct uwsgi_buffer *(*func)(struct wsgi_request *, struct uwsgi_ssi_arg *, int)) {
|
||||
struct uwsgi_ssi_cmd *old_usc = NULL,*usc = uwsgi_ssi_commands;
|
||||
while(usc) {
|
||||
if (!strcmp(usc->name, name)) {
|
||||
return usc;
|
||||
}
|
||||
old_usc = usc;
|
||||
usc = usc->next;
|
||||
}
|
||||
|
||||
usc = uwsgi_calloc(sizeof(struct uwsgi_ssi_cmd));
|
||||
usc->name = name;
|
||||
usc->name_len = strlen(name);
|
||||
usc->func = func;
|
||||
|
||||
if (old_usc) {
|
||||
old_usc->next = usc;
|
||||
}
|
||||
else {
|
||||
uwsgi_ssi_commands = usc;
|
||||
}
|
||||
|
||||
return usc;
|
||||
}
|
||||
|
||||
static int uwsgi_ssi_parse_args(struct wsgi_request *wsgi_req, char *buf, size_t len, struct uwsgi_ssi_arg *argv, int *argc) {
|
||||
// status [0]null/= [1]" [2]" [3]\s
|
||||
size_t i;
|
||||
uint8_t status = 0;
|
||||
char *key = buf;
|
||||
size_t key_len = 0;
|
||||
char *value = NULL;
|
||||
size_t val_len = 0;
|
||||
for(i=0;i<len;i++) {
|
||||
switch(status) {
|
||||
case 0:
|
||||
if (buf[i] == '=') {
|
||||
status = 1;
|
||||
}
|
||||
else {
|
||||
key_len++;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (buf[i] == '"') {
|
||||
status = 2;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (buf[i] == '"') {
|
||||
status = 3;
|
||||
argv[*argc].key = key; argv[*argc].key_len = key_len;
|
||||
argv[*argc].value = value; argv[*argc].val_len = val_len;
|
||||
*argc = *argc+1;
|
||||
if (*argc >= UWSGI_SSI_MAX_ARGS) {
|
||||
return -1;
|
||||
}
|
||||
key = NULL;
|
||||
key_len = 0;
|
||||
value = NULL;
|
||||
val_len = 0;
|
||||
}
|
||||
else {
|
||||
if (!value) {
|
||||
value = buf + i;
|
||||
}
|
||||
val_len++;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (!isspace((int)buf[i])) {
|
||||
key = buf + i;
|
||||
key_len = 1;
|
||||
status = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct uwsgi_buffer *uwsgi_ssi_parse_command(struct wsgi_request *wsgi_req, char *buf, size_t len) {
|
||||
|
||||
// storage for arguments
|
||||
struct uwsgi_ssi_arg argv[UWSGI_SSI_MAX_ARGS];
|
||||
int argc = 0;
|
||||
|
||||
// first remove white spaces from the begin and the end
|
||||
char *cmd = buf;
|
||||
size_t cmd_len = len;
|
||||
size_t i;
|
||||
for(i=0;i<len;i++) {
|
||||
if (isspace((int)buf[i])) {
|
||||
cmd++;
|
||||
cmd_len--;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// then rstrip (skipping the first char...)
|
||||
for(i=(len-1);i>0;i--) {
|
||||
if (isspace((int)buf[i])) {
|
||||
cmd_len--;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// now get the command
|
||||
char *ssi_cmd = cmd;
|
||||
size_t ssi_cmd_len = 0;
|
||||
int found = 0;
|
||||
|
||||
for(i=0;i<cmd_len;i++) {
|
||||
if (isspace(cmd[i])) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
ssi_cmd_len++;
|
||||
}
|
||||
|
||||
struct uwsgi_ssi_cmd *usc = uwsgi_ssi_get_cmd(ssi_cmd, ssi_cmd_len);
|
||||
if (!usc) return NULL ;
|
||||
|
||||
if (!found) goto run;
|
||||
|
||||
// now split the args
|
||||
char *cmd_args = cmd + ssi_cmd_len + 1;
|
||||
size_t cmd_args_len = cmd_len - (ssi_cmd_len + 1);
|
||||
|
||||
for(i=(ssi_cmd_len + 1);i<cmd_len;i++) {
|
||||
if (isspace((int)cmd[i])) {
|
||||
cmd_args++;
|
||||
cmd_args_len--;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi_ssi_parse_args(wsgi_req, cmd_args, cmd_args_len, argv, &argc)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
run:
|
||||
return usc->func(wsgi_req, argv, argc);
|
||||
}
|
||||
|
||||
static struct uwsgi_buffer *uwsgi_ssi_parse(struct wsgi_request *wsgi_req, char *buf, size_t len) {
|
||||
size_t i;
|
||||
uint8_t status = 0;
|
||||
char *cmd = NULL;
|
||||
size_t cmd_len = 0;
|
||||
struct uwsgi_buffer *ub = uwsgi_buffer_new(len);
|
||||
// parsing status 0[null] 1[<] 2[!] 3[-] 4[-] 5[#/-] 6[-] 7[>]
|
||||
// on status 6-7-8 the reset action come back to 5 instead of 0
|
||||
for(i=0;i<len;i++) {
|
||||
switch(status) {
|
||||
case 0:
|
||||
if (buf[i] == '<') {
|
||||
status = 1;
|
||||
}
|
||||
else {
|
||||
if (uwsgi_buffer_append(ub, &buf[i], 1)) goto error;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
status = 0;
|
||||
if (buf[i] == '!') {
|
||||
status = 2;
|
||||
}
|
||||
else {
|
||||
if (uwsgi_buffer_append(ub, "<", 1)) goto error;
|
||||
if (uwsgi_buffer_append(ub, &buf[i], 1)) goto error;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
status = 0;
|
||||
if (buf[i] == '-') {
|
||||
status = 3;
|
||||
}
|
||||
else {
|
||||
if (uwsgi_buffer_append(ub, "<!", 2)) goto error;
|
||||
if (uwsgi_buffer_append(ub, &buf[i], 1)) goto error;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
status = 0;
|
||||
if (buf[i] == '-') {
|
||||
status = 4;
|
||||
}
|
||||
else {
|
||||
if (uwsgi_buffer_append(ub, "<!-", 3)) goto error;
|
||||
if (uwsgi_buffer_append(ub, &buf[i], 1)) goto error;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
status = 0;
|
||||
if (buf[i] == '#') {
|
||||
status = 5;
|
||||
}
|
||||
else {
|
||||
if (uwsgi_buffer_append(ub, "<!--", 4)) goto error;
|
||||
if (uwsgi_buffer_append(ub, &buf[i], 1)) goto error;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if (buf[i] == '-') {
|
||||
status = 6;
|
||||
break;
|
||||
}
|
||||
if (!cmd) {
|
||||
cmd = buf+i;
|
||||
}
|
||||
cmd_len++;
|
||||
break;
|
||||
case 6:
|
||||
status = 5;
|
||||
if (buf[i] == '-') {
|
||||
status = 7;
|
||||
}
|
||||
else {
|
||||
cmd_len+=2;
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
status = 5;
|
||||
if (buf[i] == '>') {
|
||||
status = 0;
|
||||
struct uwsgi_buffer *ub_cmd = uwsgi_ssi_parse_command(wsgi_req, cmd, cmd_len);
|
||||
if (ub_cmd) {
|
||||
if (uwsgi_buffer_append(ub, ub_cmd->buf, ub_cmd->pos)) {
|
||||
uwsgi_buffer_destroy(ub_cmd);
|
||||
goto error;
|
||||
}
|
||||
uwsgi_buffer_destroy(ub_cmd);
|
||||
}
|
||||
cmd = NULL;
|
||||
cmd_len = 0;
|
||||
}
|
||||
else {
|
||||
cmd_len+=3;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
return ub;
|
||||
|
||||
error:
|
||||
uwsgi_buffer_destroy(ub);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int uwsgi_ssi_request(struct wsgi_request *wsgi_req) {
|
||||
struct uwsgi_buffer *ub = NULL;
|
||||
|
||||
if (uwsgi_parse_vars(wsgi_req)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!wsgi_req->document_root_len || !wsgi_req->path_info_len) {
|
||||
uwsgi_log("[uwsgi-ssi] DOCUMENT_ROOT and PATH_INFO must be defined !!!\n");
|
||||
uwsgi_500(wsgi_req);
|
||||
return UWSGI_OK;
|
||||
}
|
||||
|
||||
char *filename = uwsgi_concat3n(wsgi_req->document_root, wsgi_req->document_root_len, "/", 1, wsgi_req->path_info, wsgi_req->path_info_len);
|
||||
size_t filename_len = wsgi_req->document_root_len + 1 + wsgi_req->path_info_len;
|
||||
|
||||
// we expand the path for future security implementations
|
||||
char *real_filename = uwsgi_expand_path(filename, filename_len, NULL);
|
||||
free(filename);
|
||||
if (!real_filename) {
|
||||
uwsgi_404(wsgi_req);
|
||||
return UWSGI_OK;
|
||||
}
|
||||
|
||||
struct uwsgi_buffer *ub_ssi = uwsgi_buffer_from_file(real_filename);
|
||||
free(real_filename);
|
||||
if (!ub_ssi) {
|
||||
uwsgi_500(wsgi_req);
|
||||
return UWSGI_OK;
|
||||
}
|
||||
|
||||
ub = uwsgi_ssi_parse(wsgi_req, ub_ssi->buf, ub_ssi->pos);
|
||||
uwsgi_buffer_destroy(ub_ssi);
|
||||
if (!ub) {
|
||||
uwsgi_500(wsgi_req);
|
||||
return UWSGI_OK;
|
||||
}
|
||||
// prepare headers
|
||||
if (uwsgi_response_prepare_headers(wsgi_req, "200 OK", 6)) {
|
||||
uwsgi_500(wsgi_req);
|
||||
goto end;
|
||||
}
|
||||
// content_length
|
||||
if (uwsgi_response_add_content_length(wsgi_req, ub->pos)) {
|
||||
uwsgi_500(wsgi_req);
|
||||
goto end;
|
||||
}
|
||||
// content_type
|
||||
if (uwsgi_response_add_content_type(wsgi_req, "text/html", 9)) {
|
||||
uwsgi_500(wsgi_req);
|
||||
goto end;
|
||||
}
|
||||
|
||||
uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);
|
||||
end:
|
||||
if (ub) {
|
||||
uwsgi_buffer_destroy(ub);
|
||||
}
|
||||
return UWSGI_OK;
|
||||
}
|
||||
|
||||
static char *uwsgi_ssi_get_arg(struct uwsgi_ssi_arg *argv, int argc, char *key, size_t key_len, size_t *val_len) {
|
||||
int i;
|
||||
for(i=0;i<argc;i++) {
|
||||
struct uwsgi_ssi_arg *arg = &argv[i];
|
||||
if (!uwsgi_strncmp(arg->key, arg->key_len, key, key_len)) {
|
||||
*val_len = arg->val_len;
|
||||
return arg->value;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// echo command
|
||||
static struct uwsgi_buffer *ssi_cmd_echo(struct wsgi_request *wsgi_req, struct uwsgi_ssi_arg *argv, int argc) {
|
||||
size_t var_len = 0;
|
||||
char *var = uwsgi_ssi_get_arg(argv, argc, "var", 3, &var_len);
|
||||
|
||||
if (!var || var_len == 0) return NULL;
|
||||
|
||||
uint16_t rlen = 0;
|
||||
char *value = uwsgi_get_var(wsgi_req, var, var_len, &rlen);
|
||||
if (!value) return NULL;
|
||||
if (rlen == 0) return NULL;
|
||||
|
||||
struct uwsgi_buffer *ub = uwsgi_buffer_new(rlen);
|
||||
if (uwsgi_buffer_append(ub, value, rlen)) {
|
||||
uwsgi_buffer_destroy(ub);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ub;
|
||||
};
|
||||
|
||||
// printenv command
|
||||
static struct uwsgi_buffer *ssi_cmd_printenv(struct wsgi_request *wsgi_req, struct uwsgi_ssi_arg *argv, int argc) {
|
||||
struct uwsgi_buffer *ub = uwsgi_buffer_new(uwsgi.page_size);
|
||||
int i;
|
||||
for (i = 0; i < wsgi_req->var_cnt; i += 2) {
|
||||
if (uwsgi_buffer_append(ub, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len)) goto error;
|
||||
if (uwsgi_buffer_append(ub, "=", 1)) goto error;
|
||||
if (uwsgi_buffer_append(ub, wsgi_req->hvec[i+1].iov_base, wsgi_req->hvec[i+1].iov_len)) goto error;
|
||||
if (uwsgi_buffer_append(ub, "\n", 1)) goto error;
|
||||
}
|
||||
|
||||
return ub;
|
||||
error:
|
||||
uwsgi_buffer_destroy(ub);
|
||||
return NULL;
|
||||
};
|
||||
|
||||
// include command
|
||||
static struct uwsgi_buffer *ssi_cmd_include(struct wsgi_request *wsgi_req, struct uwsgi_ssi_arg *argv, int argc) {
|
||||
size_t var_len = 0;
|
||||
char *var = uwsgi_ssi_get_arg(argv, argc, "file", 4, &var_len);
|
||||
if (!var || var_len == 0) return NULL;
|
||||
|
||||
char *filename = uwsgi_concat2n(var, var_len, "", 0);
|
||||
|
||||
struct uwsgi_buffer *ub = uwsgi_buffer_from_file(filename);
|
||||
|
||||
free(filename);
|
||||
|
||||
return ub;
|
||||
}
|
||||
|
||||
// cache command (uWSGI specific)
|
||||
static struct uwsgi_buffer *ssi_cmd_cache(struct wsgi_request *wsgi_req, struct uwsgi_ssi_arg *argv, int argc) {
|
||||
size_t var_len = 0;
|
||||
char *var = uwsgi_ssi_get_arg(argv, argc, "key", 3, &var_len);
|
||||
if (!var || var_len == 0) return NULL;
|
||||
|
||||
size_t cache_len = 0;
|
||||
char *cache = uwsgi_ssi_get_arg(argv, argc, "name", 4, &cache_len);
|
||||
char *cache_name = NULL;
|
||||
|
||||
if (cache && cache_len) {
|
||||
cache_name = uwsgi_concat2n(cache, cache_len, "", 0);
|
||||
}
|
||||
|
||||
uint64_t rlen = 0;
|
||||
char *value = uwsgi_cache_magic_get(var, var_len, &rlen, cache_name);
|
||||
if (cache_name) free(cache_name);
|
||||
struct uwsgi_buffer *ub = NULL;
|
||||
if (value) {
|
||||
ub = uwsgi_buffer_new(rlen);
|
||||
if (uwsgi_buffer_append(ub, value, rlen)) {
|
||||
free(value);
|
||||
uwsgi_buffer_destroy(ub);
|
||||
return NULL;
|
||||
}
|
||||
free(value);
|
||||
}
|
||||
|
||||
return ub;
|
||||
}
|
||||
|
||||
|
||||
static int uwsgi_routing_func_ssi(struct wsgi_request *wsgi_req, struct uwsgi_route *ur){
|
||||
|
||||
struct uwsgi_buffer *ub = NULL;
|
||||
|
||||
char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
|
||||
uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
|
||||
|
||||
struct uwsgi_buffer *ub_filename = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
|
||||
if (!ub_filename) goto end;
|
||||
|
||||
struct uwsgi_buffer *ub_ssi = uwsgi_buffer_from_file(ub_filename->buf);
|
||||
uwsgi_buffer_destroy(ub_filename);
|
||||
if (!ub_ssi) goto end;
|
||||
|
||||
ub = uwsgi_ssi_parse(wsgi_req, ub_ssi->buf, ub_ssi->pos);
|
||||
uwsgi_buffer_destroy(ub_ssi);
|
||||
if (!ub) goto end;
|
||||
|
||||
if (uwsgi_response_prepare_headers(wsgi_req, "200 OK", 6)) goto end;
|
||||
if (uwsgi_response_add_content_length(wsgi_req, ub->pos)) goto end;
|
||||
if (uwsgi_response_add_content_type(wsgi_req, "text/html", 9)) goto end;
|
||||
|
||||
uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);
|
||||
|
||||
end:
|
||||
if (ub) uwsgi_buffer_destroy(ub);
|
||||
return UWSGI_ROUTE_BREAK;
|
||||
}
|
||||
|
||||
|
||||
static int uwsgi_router_ssi(struct uwsgi_route *ur, char *args) {
|
||||
ur->func = uwsgi_routing_func_ssi;
|
||||
ur->data = args;
|
||||
ur->data_len = strlen(args);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int uwsgi_ssi_init() {
|
||||
uwsgi_register_ssi_command("echo", ssi_cmd_echo);
|
||||
uwsgi_register_ssi_command("printenv", ssi_cmd_printenv);
|
||||
uwsgi_register_ssi_command("include", ssi_cmd_include);
|
||||
uwsgi_register_ssi_command("cache", ssi_cmd_cache);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void uwsgi_ssi_register_router() {
|
||||
uwsgi_register_router("ssi", uwsgi_router_ssi);
|
||||
}
|
||||
|
||||
static void uwsgi_ssi_log(struct wsgi_request *wsgi_req) {
|
||||
log_request(wsgi_req);
|
||||
}
|
||||
|
||||
struct uwsgi_plugin ssi_plugin = {
|
||||
.name = "ssi",
|
||||
.modifier1 = 19,
|
||||
.init = uwsgi_ssi_init,
|
||||
.request = uwsgi_ssi_request,
|
||||
.after_request = uwsgi_ssi_log,
|
||||
.on_load = uwsgi_ssi_register_router,
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
NAME='ssi'
|
||||
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = []
|
||||
GCC_LIST = ['ssi']
|
||||
+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-03-02'
|
||||
s.date = '2013-03-26'
|
||||
s.summary = "uWSGI"
|
||||
s.description = "The uWSGI server for Ruby/Rack"
|
||||
s.authors = ["Unbit"]
|
||||
|
||||
@@ -1106,6 +1106,14 @@ struct uwsgi_route_condition {
|
||||
struct uwsgi_route_condition *next;
|
||||
};
|
||||
|
||||
struct uwsgi_route_var {
|
||||
char *name;
|
||||
uint16_t name_len;
|
||||
char *(*func)(struct wsgi_request *, char *, uint16_t, uint16_t *);
|
||||
int need_free;
|
||||
struct uwsgi_route_var *next;
|
||||
};
|
||||
|
||||
struct uwsgi_router {
|
||||
char *name;
|
||||
int (*func) (struct uwsgi_route *, char *);
|
||||
@@ -1236,6 +1244,9 @@ struct uwsgi_router {
|
||||
char *referer;
|
||||
uint16_t referer_len;
|
||||
|
||||
char *cookie;
|
||||
uint16_t cookie_len;
|
||||
|
||||
char *path_info;
|
||||
uint16_t path_info_len;
|
||||
int path_info_pos;
|
||||
@@ -1383,6 +1394,11 @@ struct uwsgi_router {
|
||||
// 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 msghdr msg;
|
||||
union {
|
||||
struct cmsghdr cmsg;
|
||||
@@ -2068,6 +2084,7 @@ struct uwsgi_server {
|
||||
struct uwsgi_router *routers;
|
||||
struct uwsgi_route *routes;
|
||||
struct uwsgi_route_condition *route_conditions;
|
||||
struct uwsgi_route_var *route_vars;
|
||||
#endif
|
||||
|
||||
int single_interpreter;
|
||||
@@ -3585,6 +3602,7 @@ int uwsgi_buffer_insert_chunked(struct uwsgi_buffer *, size_t, size_t);
|
||||
int uwsgi_buffer_append_chunked(struct uwsgi_buffer *, size_t);
|
||||
int uwsgi_buffer_append_json(struct uwsgi_buffer *, char *, size_t);
|
||||
int uwsgi_buffer_set_uh(struct uwsgi_buffer *, uint8_t, uint8_t);
|
||||
struct uwsgi_buffer *uwsgi_buffer_from_file(char *);
|
||||
|
||||
ssize_t uwsgi_buffer_write_simple(struct wsgi_request *, struct uwsgi_buffer *);
|
||||
|
||||
@@ -3904,6 +3922,12 @@ char *uwsgi_deflate(z_stream *, char *, size_t, size_t *);
|
||||
void uwsgi_crc32(uint32_t *, char *, size_t);
|
||||
#endif
|
||||
|
||||
char *uwsgi_get_cookie(struct wsgi_request *, char *, uint16_t, uint16_t *);
|
||||
char *uwsgi_get_qs(struct wsgi_request *, char *, uint16_t, uint16_t *);
|
||||
|
||||
struct uwsgi_route_var *uwsgi_get_route_var(char *, uint16_t);
|
||||
struct uwsgi_route_var *uwsgi_register_route_var(char *, char *(*)(struct wsgi_request *, char *, uint16_t, uint16_t *));
|
||||
|
||||
void uwsgi_check_emperor(void);
|
||||
#ifdef UWSGI_AS_SHARED_LIBRARY
|
||||
int uwsgi_init(int, char **, char **);
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
# uWSGI build system
|
||||
|
||||
uwsgi_version = '1.9.1'
|
||||
uwsgi_version = '1.9.2'
|
||||
|
||||
import os
|
||||
import re
|
||||
@@ -461,7 +461,7 @@ class uConf(object):
|
||||
'core/setup_utils', 'core/clock', 'core/init', 'core/buffer', 'core/reader', 'core/writer', 'core/alarm',
|
||||
'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/rb_timers', 'core/uwsgi']
|
||||
'core/rpc', 'core/gateway', 'core/loop', 'core/cookie', 'core/querystring', 'core/rb_timers', 'core/uwsgi']
|
||||
# add protocols
|
||||
self.gcc_list.append('proto/base')
|
||||
self.gcc_list.append('proto/uwsgi')
|
||||
|
||||
Reference in New Issue
Block a user