improved routing + static management

This commit is contained in:
Unbit
2013-03-10 21:30:54 +01:00
parent a76d7a1c66
commit 322a2d2365
5 changed files with 87 additions and 24 deletions
+57 -7
View File
@@ -578,7 +578,7 @@ int uwsgi_parse_vars(struct wsgi_request *wsgi_req) {
ptrbuf = buffer;
bufferend = ptrbuf + wsgi_req->uh->pktsize;
int i;
/* set an HTTP 500 status as default */
wsgi_req->status = 500;
@@ -588,12 +588,14 @@ int uwsgi_parse_vars(struct wsgi_request *wsgi_req) {
// has the protocol already parsed the request ?
if (wsgi_req->uri_len > 0) {
wsgi_req->parsed = 1;
i = uwsgi_simple_parse_vars(wsgi_req, ptrbuf, bufferend);
if (i == 0)
goto next;
return i;
}
wsgi_req->parsed = 1;
wsgi_req->script_name_pos = -1;
wsgi_req->path_info_pos = -1;
@@ -669,14 +671,8 @@ int uwsgi_parse_vars(struct wsgi_request *wsgi_req) {
}
}
// do not continue, we are still routing
if (wsgi_req->is_routing) return 0;
next:
// we can be here one time for request
wsgi_req->parsed = 1;
// manage post buffering (if needed as post_file could be created before)
if (uwsgi.post_buffering > 0 && !wsgi_req->post_file) {
// read to disk if post_cl > post_buffering (it will eventually do upload progress...)
@@ -1003,3 +999,57 @@ char *uwsgi_req_append(struct wsgi_request *wsgi_req, char *key, uint16_t keylen
return ptr;
}
int uwsgi_req_append_path_info_with_index(struct wsgi_request *wsgi_req, char *index, uint16_t index_len) {
uint8_t need_slash = 0;
if (wsgi_req->path_info_len > 0) {
if (wsgi_req->path_info[wsgi_req->path_info_len-1] != '/') {
need_slash = 1;
}
}
wsgi_req->path_info_len += need_slash + index_len;
// 2 + 9 + 2
if ((wsgi_req->uh->pktsize + (13 + wsgi_req->path_info_len)) > uwsgi.buffer_size) {
uwsgi_log("not enough buffer space to transform the PATH_INFO variable, consider increasing it with the --buffer-size option\n");
return -1;
}
if (wsgi_req->var_cnt >= uwsgi.vec_size - (4 + 2)) {
uwsgi_log("max vec size reached for PATH_INFO + index. skip this request.\n");
return -1;
}
uint16_t keylen = 9;
char *ptr = wsgi_req->buffer + wsgi_req->uh->pktsize;
*ptr++ = (uint8_t) (keylen & 0xff);
*ptr++ = (uint8_t) ((keylen >> 8) & 0xff);
memcpy(ptr, "PATH_INFO", keylen);
wsgi_req->hvec[wsgi_req->var_cnt].iov_base = ptr;
wsgi_req->hvec[wsgi_req->var_cnt].iov_len = keylen;
wsgi_req->var_cnt++;
ptr += keylen;
*ptr++ = (uint8_t) (wsgi_req->path_info_len & 0xff);
*ptr++ = (uint8_t) ((wsgi_req->path_info_len >> 8) & 0xff);
char *new_path_info = ptr;
memcpy(ptr, wsgi_req->path_info, wsgi_req->path_info_len - (need_slash + index_len));
ptr+=wsgi_req->path_info_len - (need_slash + index_len);
if (need_slash) {
*ptr ++= '/';
}
memcpy(ptr, index, index_len);
wsgi_req->hvec[wsgi_req->var_cnt].iov_base = new_path_info;
wsgi_req->hvec[wsgi_req->var_cnt].iov_len = wsgi_req->path_info_len;
wsgi_req->var_cnt++;
wsgi_req->uh->pktsize += 13 + wsgi_req->path_info_len;
wsgi_req->path_info = new_path_info;
return 0;
}
+1 -3
View File
@@ -85,7 +85,7 @@ error:
return NULL;
}
static int uwsgi_apply_routes_do(struct wsgi_request *wsgi_req, char *subject, uint16_t subject_len) {
int uwsgi_apply_routes_do(struct wsgi_request *wsgi_req, char *subject, uint16_t subject_len) {
struct uwsgi_route *routes = uwsgi.routes;
void *goon_func = NULL;
@@ -165,12 +165,10 @@ int uwsgi_apply_routes(struct wsgi_request *wsgi_req) {
if (wsgi_req->is_routing)
return UWSGI_ROUTE_CONTINUE;
wsgi_req->is_routing = 1;
if (uwsgi_parse_vars(wsgi_req)) {
wsgi_req->is_routing = 0;
return UWSGI_ROUTE_BREAK;
}
wsgi_req->is_routing = 0;
return uwsgi_apply_routes_do(wsgi_req, NULL, 0);
}
+15 -12
View File
@@ -393,7 +393,7 @@ ssize_t uwsgi_append_static_path(char *dir, size_t dir_len, char *file, size_t f
return len;
}
int uwsgi_static_stat(char *filename, size_t *filename_len, struct stat *st) {
static int uwsgi_static_stat(struct wsgi_request *wsgi_req, char *filename, size_t *filename_len, struct stat *st, struct uwsgi_string_list **index) {
int ret = stat(filename, st);
// if non-existant return -1
@@ -412,7 +412,8 @@ int uwsgi_static_stat(char *filename, size_t *filename_len, struct stat *st) {
#ifdef UWSGI_DEBUG
uwsgi_log("checking for %s\n", filename);
#endif
if (!uwsgi_static_stat(filename, filename_len, st)) {
if (uwsgi_is_file2(filename, st)) {
*index = usl;
*filename_len = new_len;
return 0;
}
@@ -521,6 +522,7 @@ int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_
char *filename = NULL;
size_t filename_len = 0;
struct uwsgi_string_list *index = NULL;
if (!is_a_file) {
filename = uwsgi_concat3n(document_root, document_root_len, "/", 1, path_info, path_info_len);
@@ -580,27 +582,28 @@ found:
safe:
if (!uwsgi_static_stat(real_filename, &real_filename_len, &st)) {
if (!uwsgi_static_stat(wsgi_req, real_filename, &real_filename_len, &st, &index)) {
if (index) {
// if we are here the PATH_INFO need to be changed, so ensure some rule does not apply to it
if (uwsgi_apply_routes_do(wsgi_req, NULL, 0) == UWSGI_ROUTE_BREAK) {
return 0;
}
if (uwsgi_req_append_path_info_with_index(wsgi_req, index->value, index->len)) {
return -1;
}
}
// skip methods other than GET and HEAD
if (uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "GET", 3) && uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "HEAD", 4)) {
#ifdef UWSGI_ROUTING
if (uwsgi_apply_routes_fast(wsgi_req, real_filename, real_filename_len) == UWSGI_ROUTE_BREAK)
return 0;
#endif
return -1;
}
// check for skippable ext
struct uwsgi_string_list *sse = uwsgi.static_skip_ext;
while (sse) {
if (real_filename_len >= sse->len) {
if (!uwsgi_strncmp(real_filename + (real_filename_len - sse->len), sse->len, sse->value, sse->len)) {
#ifdef UWSGI_ROUTING
if (uwsgi_apply_routes_fast(wsgi_req, real_filename, real_filename_len) == UWSGI_ROUTE_BREAK)
return 0;
#endif
return -1;
}
}
+10
View File
@@ -1248,6 +1248,16 @@ int uwsgi_is_file(char *filename) {
return 0;
}
int uwsgi_is_file2(char *filename, struct stat *st) {
if (stat(filename, st)) {
return 0;
}
if (S_ISREG(st->st_mode))
return 1;
return 0;
}
int uwsgi_is_dir(char *filename) {
struct stat st;
if (stat(filename, &st)) {
+4 -2
View File
@@ -2764,8 +2764,8 @@ void uwsgi_rpc_init(void);
char *magic_sub(char *, size_t, size_t *, char *[]);
void init_magic_table(char *[]);
char *uwsgi_req_append(struct wsgi_request *, char *, uint16_t, char *, uint16_t);
char *uwsgi_req_append(struct wsgi_request *, char *, uint16_t, char *, uint16_t);
int uwsgi_req_append_path_info_with_index(struct wsgi_request *, char *, uint16_t);
int is_unix(char *, int);
int is_a_number(char *);
@@ -3309,6 +3309,7 @@ struct uwsgi_router *uwsgi_register_router(char *, int (*)(struct uwsgi_route *,
void uwsgi_opt_add_route(char *, char *, void *);
int uwsgi_apply_routes(struct wsgi_request *);
int uwsgi_apply_routes_fast(struct wsgi_request *, char *, uint16_t);
int uwsgi_apply_routes_do(struct wsgi_request *, char *, uint16_t);
void uwsgi_register_embedded_routers(void);
void uwsgi_routing_dump();
struct uwsgi_buffer *uwsgi_routing_translate(struct wsgi_request *, struct uwsgi_route *, char *, uint16_t, char *, size_t);
@@ -3363,6 +3364,7 @@ void uwsgi_reload(char **);
uint64_t uwsgi_micros(void);
int uwsgi_is_file(char *);
int uwsgi_is_file2(char *, struct stat *);
int uwsgi_is_dir(char *);
int uwsgi_is_link(char *);