Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

added math route var

  • Loading branch information...
commit 59d1a45ef0330baa47d8603574bbae40f0f51d98 1 parent 0b5f9fc
@unbit authored
Showing with 43 additions and 16 deletions.
  1. +37 −9 core/routing.c
  2. +6 −7 core/utils.c
View
46 core/routing.c
@@ -1066,15 +1066,43 @@ static int uwsgi_route_condition_isexec(struct wsgi_request *wsgi_req, struct uw
#ifdef UWSGI_MATHEVAL
static char *uwsgi_route_var_math(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, uint16_t *vallen) {
- // we only supports variables (not regexp group as we have no context)
- struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, NULL, NULL, 0, key, keylen);
- if (!ub) return NULL;
- char *value = ub->buf;
- *vallen = ub->pos;
- // trick to avoid destroying the buffer
- ub->buf = NULL;
- uwsgi_buffer_destroy(ub);
- return value;
+ char *ret = NULL;
+ // avoid crash
+ if (!wsgi_req->var_cnt) return NULL;
+ // we make a bit of fun here, we do a copy of the vars buffer (+1 byte for final zero) and zeor-pad all of the strings
+ char *vars_buf = uwsgi_malloc(wsgi_req->uh->pktsize + keylen + 1);
+ char **names = uwsgi_malloc(sizeof(char *) * (wsgi_req->var_cnt/2));
+ double *values = uwsgi_calloc(sizeof(double) * (wsgi_req->var_cnt/2));
+ int i,j = 0;
+ char *ptr = vars_buf;
+ for (i = wsgi_req->var_cnt-1; i > 0; i -= 2) {
+ memcpy(ptr, wsgi_req->hvec[i-1].iov_base, wsgi_req->hvec[i-1].iov_len);
+ names[j] = ptr;
+ ptr += wsgi_req->hvec[i-1].iov_len;
+ *ptr++=0;
+ char *num = ptr;
+ memcpy(ptr, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len);
+ ptr += wsgi_req->hvec[i-1].iov_len;
+ *ptr++=0;
+ values[j] = strtod(num, NULL);
+ j++;
+ }
+
+ char *expr = ptr;
+ memcpy(ptr, key, keylen); ptr += keylen;
+ *ptr++=0;
+
+ void *e = evaluator_create(expr);
+ if (!e) goto end;
+ double n = evaluator_evaluate(e, j, names, values);
+ evaluator_destroy(e);
+ ret = uwsgi_num2str((int)n);
+ *vallen = strlen(ret);
+end:
+ free(vars_buf);
+ free(names);
+ free(values);
+ return ret;
}
#endif
View
13 core/utils.c
@@ -3055,21 +3055,20 @@ void http_url_decode(char *buf, uint16_t * len, char *dst) {
}
/*
- we have to scan the whole table as new vars could be added during the request
+ we scan the table in reverse, as updated values are at the end
*/
char *uwsgi_get_var(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, uint16_t * len) {
int i;
- char *found_ptr = NULL;
- for (i = 0; i < wsgi_req->var_cnt; i += 2) {
- if (!uwsgi_strncmp(key, keylen, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len)) {
- *len = wsgi_req->hvec[i + 1].iov_len;
- found_ptr = wsgi_req->hvec[i + 1].iov_base;
+ for (i = wsgi_req->var_cnt-1; i > 0; i -= 2) {
+ if (!uwsgi_strncmp(key, keylen, wsgi_req->hvec[i-1].iov_base, wsgi_req->hvec[i-1].iov_len)) {
+ *len = wsgi_req->hvec[i].iov_len;
+ return wsgi_req->hvec[i].iov_base;
}
}
- return found_ptr;
+ return NULL;
}
struct uwsgi_app *uwsgi_add_app(int id, uint8_t modifier1, char *mountpoint, int mountpoint_len, void *interpreter, void *callable) {
Please sign in to comment.
Something went wrong with that request. Please try again.