int uwsgi_routing_func_rewrite(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) { char *tmp_qs = NULL; char **subject = (char **) (((char *)(wsgi_req))+ur->subject); uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len); char *path_info = uwsgi_regexp_apply_ovec(*subject, *subject_len, ur->data, ur->data_len, ur->ovector, ur->ovn); uint16_t path_info_len = strlen(path_info); uint16_t query_string_len = 0; char *query_string = strchr(path_info, '?'); if (query_string) { path_info_len = query_string - path_info; query_string++; query_string_len = strlen(query_string); if (wsgi_req->query_string_len > 0) { tmp_qs = uwsgi_concat4n(query_string, query_string_len, "&", 1, wsgi_req->query_string, wsgi_req->query_string_len, "", 0); query_string = tmp_qs; query_string_len = strlen(query_string); } } // over engineering, could be required in the future... else { if (wsgi_req->query_string_len > 0) { query_string = wsgi_req->query_string; query_string_len = wsgi_req->query_string_len; } else { query_string = ""; } } char *ptr = uwsgi_req_append(wsgi_req, "PATH_INFO", 9, path_info, path_info_len); if (!ptr) goto clear; // set new path_info wsgi_req->path_info = ptr; wsgi_req->path_info_len = path_info_len; ptr = uwsgi_req_append(wsgi_req, "QUERY_STRING", 12, query_string, query_string_len); if (!ptr) goto clear; // set new query_string wsgi_req->query_string = ptr; wsgi_req->query_string_len = query_string_len; free(path_info); if (tmp_qs) free(tmp_qs); if (ur->custom) return UWSGI_ROUTE_CONTINUE; return UWSGI_ROUTE_NEXT; clear: free(path_info); if (tmp_qs) free(tmp_qs); return UWSGI_ROUTE_BREAK; }
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; if (!uwsgi.cache_max_items) return UWSGI_ROUTE_NEXT; char *c_k = NULL; uint16_t c_k_len = 0; struct uwsgi_buffer *ub = NULL; int k_need_free = 0; if (urcc->key) { char **subject = (char **) (((char *)(wsgi_req))+ur->subject); uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len); c_k = uwsgi_regexp_apply_ovec(*subject, *subject_len, urcc->key, urcc->key_len, ur->ovector, ur->ovn); c_k_len = strlen(c_k); k_need_free = 1; } else { char **key = (char **) (((char *) wsgi_req) + urcc->var_offset); uint16_t *keylen = (uint16_t *) (((char *) wsgi_req) + urcc->var_offset_len); c_k = *key; c_k_len = *keylen; } uint64_t valsize = 0; char *value = uwsgi_cache_get(c_k, c_k_len, &valsize); if (value) { ub = uwsgi_buffer_new(uwsgi.page_size); if (urcc->type_num == 1) { wsgi_req->status = 200; if (uwsgi_buffer_append(ub, "HTTP/1.0 200 OK\r\nConnection: close\r\nContent-Type: ", 50)) goto error; if (uwsgi_buffer_append(ub, urcc->content_type, urcc->content_type_len)) goto error; if (uwsgi_buffer_append(ub, "\r\nContent-Length: ", 18 )) goto error; if (uwsgi_buffer_num64(ub, valsize)) goto error; if (uwsgi_buffer_append(ub, "\r\n\r\n", 4 )) goto error; wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, ub->buf, ub->pos); uwsgi_buffer_destroy(ub); wsgi_req->header_cnt = 3; } // body only wsgi_req->response_size += wsgi_req->socket->proto_write(wsgi_req, value, valsize); if (k_need_free) free(c_k); if (ur->custom) return UWSGI_ROUTE_NEXT; return UWSGI_ROUTE_BREAK; } if (k_need_free) free(c_k); return UWSGI_ROUTE_NEXT; error: uwsgi_buffer_destroy(ub); if (k_need_free) free(c_k); return UWSGI_ROUTE_BREAK; }
int uwsgi_routing_func_static(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) { char **subject = (char **) (((char *)(wsgi_req))+ur->subject); uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len); char *filename = uwsgi_regexp_apply_ovec(*subject, *subject_len, ur->data, ur->data_len, ur->ovector, ur->ovn); uint16_t filename_len = strlen(filename); uwsgi_file_serve(wsgi_req, filename, filename_len, NULL, 0, 1); free(filename); return UWSGI_ROUTE_BREAK; }
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) { // cannot fail char *pass1 = uwsgi_regexp_apply_ovec(subject, subject_len, data, data_len, ur->ovector, ur->ovn); size_t pass1_len = strlen(pass1); struct uwsgi_buffer *ub = uwsgi_buffer_new(pass1_len); size_t i; int status = 0; char *key = NULL; size_t keylen = 0; for(i=0;i<pass1_len;i++) { switch(status) { case 0: if (pass1[i] == '$') { status = 1; break; } if (uwsgi_buffer_append(ub, pass1 + i, 1)) goto error; break; case 1: if (pass1[i] == '{') { status = 2; key = pass1+i+1; keylen = 0; break; } status = 0; key = NULL; keylen = 0; if (uwsgi_buffer_append(ub, "$", 1)) goto error; if (uwsgi_buffer_append(ub, pass1 + i, 1)) goto error; break; case 2: if (pass1[i] == '}') { uint16_t vallen = 0; char *value = uwsgi_get_var(wsgi_req, key, keylen, &vallen); if (value) { if (uwsgi_buffer_append(ub, value, vallen)) goto error; } status = 0; key = NULL; keylen = 0; break; } keylen++; break; default: break; } } // fix the buffer if (status == 1) { if (uwsgi_buffer_append(ub, "$", 1)) goto error; } else if (status == 2) { if (uwsgi_buffer_append(ub, "${", 2)) goto error; if (keylen > 0) { if (uwsgi_buffer_append(ub, key, keylen)) goto error; } } free(pass1); return ub; error: uwsgi_buffer_destroy(ub); return NULL; }