diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2020-03-01 09:28:52 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2020-03-01 09:28:52 +0200 |
commit | 3000780b55437ef04db32ec860719d16cd08978b (patch) | |
tree | 0fc1aac0623a58924ecf0981eba885c8df1e6ded | |
parent | 7aa8fc1f4a39dcad0cb5330aa4ac47afc924ecb0 (diff) | |
download | ping903-3000780b55437ef04db32ec860719d16cd08978b.tar.gz ping903-3000780b55437ef04db32ec860719d16cd08978b.tar.bz2 |
/config,/id: Return a json object when a particular attribute is requested
* src/ping903.c (auth_flt): Fix memory overrun.
(http_json_flt_response): New function.
(ident_to_json,ept_config): Rewrite using http_json_flt_response.
(try_auth): Squash repeated '/' characters.
-rw-r--r-- | src/ping903.c | 162 |
1 files changed, 68 insertions, 94 deletions
diff --git a/src/ping903.c b/src/ping903.c index 5ab3f4d..549f42e 100644 --- a/src/ping903.c +++ b/src/ping903.c @@ -310,7 +310,7 @@ auth_flt(char const *kw, struct json_value *val, void *data) { int rc; struct auth_flt_data *adata = data; - char *url = malloc(strlen(adata->url) + strlen(kw) + 1); + char *url = malloc(strlen(adata->url) + strlen(kw) + 2); if (!url) { adata->err = 1; return 0; @@ -323,6 +323,55 @@ auth_flt(char const *kw, struct json_value *val, void *data) return rc; } +static int +attr_flt(char const *kw, struct json_value *val, void *data) +{ + return strcmp(kw, (char*)data); +} + +static int +http_json_flt_response(struct MHD_Connection *conn, + const char *url, const char *method, + struct json_value *val, const char *suffix) +{ + int ret; + + if (!val) + return http_response(conn, method, url, + MHD_HTTP_INTERNAL_SERVER_ERROR); + while (*suffix == '/') + suffix++; + if (*suffix) { + if (json_object_filter(val, attr_flt, (void*)suffix)) { + ret = http_response(conn, method, url, + MHD_HTTP_INTERNAL_SERVER_ERROR); + json_value_free(val); + return ret; + } + if (!val->v.o->head) { + ret = http_response(conn, method, url, + MHD_HTTP_NOT_FOUND); + json_value_free(val); + return ret; + } + } else { + struct auth_flt_data adata = { + .conn = conn, + .url = url, + .method = method, + .err = 0 + }; + if (json_object_filter(val, auth_flt, &adata) || adata.err) { + ret = http_response(conn, method, url, + MHD_HTTP_INTERNAL_SERVER_ERROR); + json_value_free(val); + return ret; + } + } + + return httpd_json_response(conn, url, method, MHD_HTTP_OK, val); +} + static struct json_value * ident_to_json(void) { @@ -352,49 +401,8 @@ ept_ident(struct MHD_Connection *conn, const char *url, const char *method, const char *suffix, struct json_value *unused) { - int ret; - struct json_value *obj; - - while (*suffix == '/') - suffix++; - obj = ident_to_json(); - if (!obj) - return http_response(conn, method, url, - MHD_HTTP_INTERNAL_SERVER_ERROR); - if (*suffix) { - struct json_value *jv, *cp; - if (json_object_get(obj, suffix, &jv)) { - ret = http_response(conn, method, url, - (errno == ENOENT) - ? MHD_HTTP_NOT_FOUND - : MHD_HTTP_INTERNAL_SERVER_ERROR); - json_value_free(obj); - return ret; - } - - if (json_value_copy(jv, &cp)) { - ret = http_response(conn, method, url, - MHD_HTTP_INTERNAL_SERVER_ERROR); - json_value_free(obj); - return ret; - } - json_value_free(obj); - obj = cp; - } else { - struct auth_flt_data adata = { - .conn = conn, - .url = url, - .method = method, - .err = 0 - }; - if (json_object_filter(obj, auth_flt, &adata) || adata.err) { - int ret = http_response(conn, method, url, - MHD_HTTP_INTERNAL_SERVER_ERROR); - json_value_free(obj); - return ret; - } - } - return httpd_json_response(conn, url, method, MHD_HTTP_OK, obj); + return http_json_flt_response(conn, url, method, + ident_to_json(), suffix); } static int @@ -402,53 +410,8 @@ ept_config(struct MHD_Connection *conn, const char *url, const char *method, const char *suffix, struct json_value *unused) { - struct json_value *val; - - while (*suffix == '/') - suffix++; - - val = config_to_json(); - if (!val) - return http_response(conn, method, url, - MHD_HTTP_INTERNAL_SERVER_ERROR); - - if (*suffix) { - struct json_value *jv, *cp; - int ret; - - if (json_object_get(val, suffix, &jv)) { - ret = http_response(conn, method, url, - (errno == ENOENT) - ? MHD_HTTP_NOT_FOUND - : MHD_HTTP_INTERNAL_SERVER_ERROR); - json_value_free(val); - return ret; - } - - if (json_value_copy(jv, &cp)) { - ret = http_response(conn, method, url, - MHD_HTTP_INTERNAL_SERVER_ERROR); - json_value_free(val); - return ret; - } - json_value_free(val); - val = cp; - } else { - struct auth_flt_data adata = { - .conn = conn, - .url = url, - .method = method, - .err = 0 - }; - if (json_object_filter(val, auth_flt, &adata) || adata.err) { - int ret = http_response(conn, method, url, - MHD_HTTP_INTERNAL_SERVER_ERROR); - json_value_free(val); - return ret; - } - } - - return httpd_json_response(conn, url, method, MHD_HTTP_OK, val); + return http_json_flt_response(conn, url, method, + config_to_json(), suffix); } static int @@ -873,7 +836,9 @@ try_auth(struct MHD_Connection *conn, const char *url, const char *method, struct auth_location *loc; size_t url_len; char *url_buf; - + char *p; + char const *q; + url_len = strcspn(url, "?"); while (url_len > 1 && url[url_len-1] == '/') --url_len; @@ -884,8 +849,17 @@ try_auth(struct MHD_Connection *conn, const char *url, const char *method, MHD_HTTP_INTERNAL_SERVER_ERROR); return 1; } - memcpy(url_buf, url, url_len); - url_buf[url_len] = 0; + + /* Copy url to url_buf squashing repeated '/' into a single slash */ + p = url_buf; + q = url; + while (*q) { + if (!(*q == '/' && q > url && q[-1] == '/')) + *p++ = *q; + q++; + } + *p = 0; + for (loc = auth_head; loc; loc = loc->next) { if (fnmatch(loc->method, method, 0)) continue; |