mirror of
https://github.com/jorisvink/kore
synced 2025-03-09 20:49:01 -04:00
Rework the way validation and param extraction works.
- Parameter validation is now done only when http_process_*() is called and upon http_argument_add(). - You MUST have defined your params in a param block or they will be filtered out. - http_argument_lookup() is dead, welcome http_argument_get() and its brothers and sisters: http_argument_get_string() http_argument_get_uint16() http_argument_get_int16() http_argument_get_uint32() http_argument_get_int32() They will automatically do bounds checking on integers for you and return proper integers or a NUL-terminated string. - The http_argument_get* functions no longer create an additional copy of the string which you need to free. Easier going. - http_multiple_args() is dead, byebye - Make some stuff we don't want to share with the modules static.
This commit is contained in:
parent
b4c54f9dc0
commit
c7dcdbcd82
116
includes/http.h
116
includes/http.h
@ -26,6 +26,14 @@
|
||||
#define HTTP_REQ_HEADER_MAX 25
|
||||
#define HTTP_MAX_QUERY_ARGS 10
|
||||
|
||||
#define HTTP_ARG_TYPE_RAW 0
|
||||
#define HTTP_ARG_TYPE_BYTE 1
|
||||
#define HTTP_ARG_TYPE_INT16 2
|
||||
#define HTTP_ARG_TYPE_UINT16 3
|
||||
#define HTTP_ARG_TYPE_INT32 4
|
||||
#define HTTP_ARG_TYPE_UINT32 5
|
||||
#define HTTP_ARG_TYPE_STRING 6
|
||||
|
||||
struct http_header {
|
||||
char *header;
|
||||
char *value;
|
||||
@ -35,11 +43,65 @@ struct http_header {
|
||||
|
||||
struct http_arg {
|
||||
char *name;
|
||||
char *value;
|
||||
void *value;
|
||||
u_int32_t len;
|
||||
|
||||
char *s_value;
|
||||
u_int32_t s_len;
|
||||
|
||||
TAILQ_ENTRY(http_arg) list;
|
||||
};
|
||||
|
||||
#define COPY_ARG_TYPE(v, l, t, o) \
|
||||
do { \
|
||||
if (l != NULL) \
|
||||
*l = sizeof(t); \
|
||||
*(t **)o = *(t **)v; \
|
||||
} while (0);
|
||||
|
||||
#define COPY_ARG_INT(min, max, type) \
|
||||
do { \
|
||||
int err; \
|
||||
int64_t nval; \
|
||||
nval = kore_strtonum(q->s_value, 10, min, max, &err); \
|
||||
if (err != KORE_RESULT_OK) \
|
||||
return (KORE_RESULT_ERROR); \
|
||||
COPY_ARG_TYPE(&nval, len, type, out); \
|
||||
} while (0);
|
||||
|
||||
#define CACHE_STRING() \
|
||||
do { \
|
||||
if (q->s_value == NULL) { \
|
||||
q->s_len = q->len + 1; \
|
||||
q->s_value = kore_malloc(q->s_len); \
|
||||
kore_strlcpy(q->s_value, q->value, q->s_len); \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
#define COPY_AS_INTTYPE(min, max, type) \
|
||||
do { \
|
||||
CACHE_STRING(); \
|
||||
COPY_ARG_INT(min, max, type); \
|
||||
} while (0);
|
||||
|
||||
#define http_argument_type(r, n, o, l, t) \
|
||||
http_argument_get(r, n, (void **)o, l, t)
|
||||
|
||||
#define http_argument_get_string(n, o, l) \
|
||||
http_argument_type(req, n, o, l, HTTP_ARG_TYPE_STRING)
|
||||
|
||||
#define http_argument_get_uint16(n, o) \
|
||||
http_argument_type(req, n, o, NULL, HTTP_ARG_TYPE_UINT16)
|
||||
|
||||
#define http_argument_get_int16(n, o) \
|
||||
http_argument_type(req, n, o, NULL, HTTP_ARG_TYPE_INT16)
|
||||
|
||||
#define http_argument_get_uint32(n, o) \
|
||||
http_argument_type(req, n, o, NULL, HTTP_ARG_TYPE_UINT32)
|
||||
|
||||
#define http_argument_get_int32(n, o) \
|
||||
http_argument_type(req, n, o, NULL, HTTP_ARG_TYPE_INT32)
|
||||
|
||||
struct http_file {
|
||||
char *name;
|
||||
char *filename;
|
||||
@ -55,22 +117,22 @@ struct http_file {
|
||||
|
||||
#define HTTP_REQUEST_COMPLETE 0x01
|
||||
#define HTTP_REQUEST_DELETE 0x02
|
||||
#define HTTP_REQUEST_PARSED_PARAMS 0x04
|
||||
|
||||
struct http_request {
|
||||
u_int8_t method;
|
||||
u_int8_t flags;
|
||||
int status;
|
||||
u_int64_t start;
|
||||
u_int64_t end;
|
||||
char host[KORE_DOMAINNAME_LEN];
|
||||
char path[HTTP_URI_LEN];
|
||||
char *agent;
|
||||
struct connection *owner;
|
||||
struct spdy_stream *stream;
|
||||
struct kore_buf *post_data;
|
||||
void *hdlr_extra;
|
||||
u_int8_t *multipart_body;
|
||||
u_int8_t method;
|
||||
u_int8_t flags;
|
||||
int status;
|
||||
u_int64_t start;
|
||||
u_int64_t end;
|
||||
char host[KORE_DOMAINNAME_LEN];
|
||||
char path[HTTP_URI_LEN];
|
||||
char *agent;
|
||||
struct connection *owner;
|
||||
struct spdy_stream *stream;
|
||||
struct kore_buf *post_data;
|
||||
void *hdlr_extra;
|
||||
u_int8_t *multipart_body;
|
||||
struct kore_module_handle *hdlr;
|
||||
|
||||
TAILQ_HEAD(, http_header) req_headers;
|
||||
TAILQ_HEAD(, http_header) resp_headers;
|
||||
@ -100,24 +162,26 @@ int http_request_new(struct connection *, struct spdy_stream *,
|
||||
int http_argument_urldecode(char *);
|
||||
int http_header_recv(struct netbuf *);
|
||||
int http_generic_404(struct http_request *);
|
||||
char *http_post_data_text(struct http_request *);
|
||||
u_int8_t *http_post_data_bytes(struct http_request *, u_int32_t *);
|
||||
int http_populate_arguments(struct http_request *);
|
||||
int http_populate_multipart_form(struct http_request *, int *);
|
||||
void http_argument_multiple_free(struct http_arg *);
|
||||
void http_file_add(struct http_request *, char *, char *,
|
||||
u_int8_t *, u_int32_t);
|
||||
void http_argument_add(struct http_request *, char *,
|
||||
char *, u_int32_t);
|
||||
int http_argument_lookup(struct http_request *,
|
||||
const char *, char **);
|
||||
int http_argument_get(struct http_request *,
|
||||
const char *, void **, u_int32_t *, int);
|
||||
int http_file_lookup(struct http_request *, char *, char **,
|
||||
u_int8_t **, u_int32_t *);
|
||||
int http_argument_multiple_lookup(struct http_request *,
|
||||
struct http_arg *);
|
||||
|
||||
void kore_accesslog(struct http_request *);
|
||||
|
||||
static inline char *
|
||||
http_argument_string(struct http_request *r, char *n)
|
||||
{
|
||||
char *str;
|
||||
|
||||
if (http_argument_get(r, n, (void **)&str, NULL, HTTP_ARG_TYPE_STRING))
|
||||
return (str);
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
enum http_status_code {
|
||||
HTTP_STATUS_CONTINUE = 100,
|
||||
HTTP_STATUS_SWITCHING_PROTOCOLS = 101,
|
||||
|
@ -349,7 +349,7 @@ void kore_strlcpy(char *, const char *, size_t);
|
||||
void kore_server_disconnect(struct connection *);
|
||||
int kore_split_string(char *, char *, char **, size_t);
|
||||
void kore_strip_chars(char *, char, char **);
|
||||
u_int64_t kore_strtonum(const char *, int, u_int64_t, u_int64_t, int *);
|
||||
long long kore_strtonum(const char *, int, long long, long long, int *);
|
||||
int kore_base64_encode(u_int8_t *, u_int32_t, char **);
|
||||
int kore_base64_decode(char *, u_int8_t **, u_int32_t *);
|
||||
void *kore_mem_find(void *, size_t, void *, u_int32_t);
|
||||
|
@ -140,10 +140,8 @@ serve_file_upload(struct http_request *req)
|
||||
|
||||
if (req->method == HTTP_METHOD_POST) {
|
||||
http_populate_multipart_form(req, &r);
|
||||
if (http_argument_lookup(req, "firstname", &name)) {
|
||||
kore_buf_replace_string(b, "$firstname$",
|
||||
name, strlen(name));
|
||||
kore_mem_free(name);
|
||||
if (http_argument_get_string("firstname", &name, &len)) {
|
||||
kore_buf_replace_string(b, "$firstname$", name, len);
|
||||
} else {
|
||||
kore_buf_replace_string(b, "$firstname$", NULL, 0);
|
||||
}
|
||||
@ -237,22 +235,22 @@ serve_params_test(struct http_request *req)
|
||||
int r, i;
|
||||
char *test, name[10];
|
||||
|
||||
http_populate_arguments(req);
|
||||
|
||||
b = kore_buf_create(static_len_html_params);
|
||||
kore_buf_append(b, static_html_params, static_len_html_params);
|
||||
|
||||
/*
|
||||
* The GET parameters will be filtered out on POST.
|
||||
*/
|
||||
if (http_argument_lookup(req, "arg1", &test)) {
|
||||
kore_buf_replace_string(b, "$arg1$", test, strlen(test));
|
||||
kore_mem_free(test);
|
||||
if (http_argument_get_string("arg1", &test, &len)) {
|
||||
kore_buf_replace_string(b, "$arg1$", test, len);
|
||||
} else {
|
||||
kore_buf_replace_string(b, "$arg1$", NULL, 0);
|
||||
}
|
||||
|
||||
if (http_argument_lookup(req, "arg2", &test)) {
|
||||
kore_buf_replace_string(b, "$arg2$", test, strlen(test));
|
||||
kore_mem_free(test);
|
||||
if (http_argument_get_string("arg2", &test, &len)) {
|
||||
kore_buf_replace_string(b, "$arg2$", test, len);
|
||||
} else {
|
||||
kore_buf_replace_string(b, "$arg2$", NULL, 0);
|
||||
}
|
||||
@ -262,6 +260,11 @@ serve_params_test(struct http_request *req)
|
||||
kore_buf_replace_string(b, "$test2$", NULL, 0);
|
||||
kore_buf_replace_string(b, "$test3$", NULL, 0);
|
||||
|
||||
if (http_argument_get_uint16("id", &r))
|
||||
kore_log(LOG_NOTICE, "id: %d", r);
|
||||
else
|
||||
kore_log(LOG_NOTICE, "No id set");
|
||||
|
||||
http_response_header_add(req, "content-type", "text/html");
|
||||
d = kore_buf_release(b, &len);
|
||||
r = http_response(req, 200, d, len);
|
||||
@ -270,16 +273,11 @@ serve_params_test(struct http_request *req)
|
||||
return (r);
|
||||
}
|
||||
|
||||
/*
|
||||
* No need to call http_populate_arguments(), it's been done
|
||||
* by the parameter validation automatically.
|
||||
*/
|
||||
for (i = 1; i < 4; i++) {
|
||||
snprintf(name, sizeof(name), "test%d", i);
|
||||
if (http_argument_lookup(req, name, &test)) {
|
||||
if (http_argument_get_string(name, &test, &len)) {
|
||||
snprintf(name, sizeof(name), "$test%d$", i);
|
||||
kore_buf_replace_string(b, name, test, strlen(test));
|
||||
kore_mem_free(test);
|
||||
kore_buf_replace_string(b, name, test, len);
|
||||
} else {
|
||||
snprintf(name, sizeof(name), "$test%d$", i);
|
||||
kore_buf_replace_string(b, name, NULL, 0);
|
||||
|
289
src/http.c
289
src/http.c
@ -25,8 +25,13 @@
|
||||
|
||||
static char *http_status_text(int);
|
||||
static int http_post_data_recv(struct netbuf *);
|
||||
static void http_validate_params(struct http_request *,
|
||||
struct kore_module_handle *);
|
||||
static char *http_post_data_text(struct http_request *);
|
||||
static u_int8_t *http_post_data_bytes(struct http_request *,
|
||||
u_int32_t *);
|
||||
static void http_argument_add(struct http_request *, char *,
|
||||
void *, u_int32_t, int);
|
||||
static void http_file_add(struct http_request *, char *, char *,
|
||||
u_int8_t *, u_int32_t);
|
||||
|
||||
static TAILQ_HEAD(, http_request) http_requests;
|
||||
static struct kore_pool http_request_pool;
|
||||
@ -141,12 +146,7 @@ http_process(void)
|
||||
if (hdlr == NULL) {
|
||||
r = http_generic_404(req);
|
||||
} else {
|
||||
if (!TAILQ_EMPTY(&(hdlr->params)) &&
|
||||
!(req->flags & HTTP_REQUEST_PARSED_PARAMS)) {
|
||||
http_validate_params(req, hdlr);
|
||||
req->flags |= HTTP_REQUEST_PARSED_PARAMS;
|
||||
}
|
||||
|
||||
req->hdlr = hdlr;
|
||||
cb = hdlr->addr;
|
||||
worker->active_hdlr = hdlr;
|
||||
r = cb(req);
|
||||
@ -225,6 +225,9 @@ http_request_free(struct http_request *req)
|
||||
|
||||
if (q->value != NULL)
|
||||
kore_mem_free(q->value);
|
||||
if (q->s_value != NULL)
|
||||
kore_mem_free(q->s_value);
|
||||
|
||||
kore_mem_free(q);
|
||||
}
|
||||
|
||||
@ -533,13 +536,12 @@ http_populate_arguments(struct http_request *req)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (val[1] == NULL)
|
||||
len = 0;
|
||||
else
|
||||
if (val[1] != NULL) {
|
||||
len = strlen(val[1]);
|
||||
|
||||
http_argument_add(req, val[0], val[1], len);
|
||||
count++;
|
||||
http_argument_add(req, val[0], val[1],
|
||||
len, HTTP_ARG_TYPE_STRING);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
kore_mem_free(query);
|
||||
@ -547,17 +549,46 @@ http_populate_arguments(struct http_request *req)
|
||||
}
|
||||
|
||||
int
|
||||
http_argument_lookup(struct http_request *req, const char *name, char **out)
|
||||
http_argument_get(struct http_request *req, const char *name,
|
||||
void **out, u_int32_t *len, int type)
|
||||
{
|
||||
struct http_arg *q;
|
||||
|
||||
if (len != NULL)
|
||||
*len = 0;
|
||||
|
||||
TAILQ_FOREACH(q, &(req->arguments), list) {
|
||||
if (!strcmp(q->name, name)) {
|
||||
if (q->value == NULL)
|
||||
switch (type) {
|
||||
case HTTP_ARG_TYPE_RAW:
|
||||
if (len != NULL)
|
||||
*len = q->len;
|
||||
*out = q->value;
|
||||
return (KORE_RESULT_OK);
|
||||
case HTTP_ARG_TYPE_BYTE:
|
||||
COPY_ARG_TYPE(q->value, len, u_int8_t, out);
|
||||
return (KORE_RESULT_OK);
|
||||
case HTTP_ARG_TYPE_INT16:
|
||||
COPY_AS_INTTYPE(SHRT_MIN, SHRT_MAX, int16_t);
|
||||
return (KORE_RESULT_OK);
|
||||
case HTTP_ARG_TYPE_UINT16:
|
||||
COPY_AS_INTTYPE(0, USHRT_MAX, u_int16_t);
|
||||
return (KORE_RESULT_OK);
|
||||
case HTTP_ARG_TYPE_INT32:
|
||||
COPY_AS_INTTYPE(INT_MIN, INT_MAX, int32_t);
|
||||
return (KORE_RESULT_OK);
|
||||
case HTTP_ARG_TYPE_UINT32:
|
||||
COPY_AS_INTTYPE(0, UINT_MAX, u_int32_t);
|
||||
return (KORE_RESULT_OK);
|
||||
case HTTP_ARG_TYPE_STRING:
|
||||
CACHE_STRING();
|
||||
*out = q->s_value;
|
||||
if (len != NULL)
|
||||
*len = q->s_len - 1;
|
||||
return (KORE_RESULT_OK);
|
||||
default:
|
||||
return (KORE_RESULT_ERROR);
|
||||
|
||||
*out = kore_strdup(q->value);
|
||||
return (KORE_RESULT_OK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -612,69 +643,6 @@ http_argument_urldecode(char *arg)
|
||||
return (KORE_RESULT_OK);
|
||||
}
|
||||
|
||||
int
|
||||
http_argument_multiple_lookup(struct http_request *req, struct http_arg *args)
|
||||
{
|
||||
int i, c;
|
||||
|
||||
c = 0;
|
||||
for (i = 0; args[i].name != NULL; i++) {
|
||||
if (!http_argument_lookup(req, args[i].name,
|
||||
&(args[i].value))) {
|
||||
args[i].value = NULL;
|
||||
} else {
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
return (c);
|
||||
}
|
||||
|
||||
void
|
||||
http_argument_multiple_free(struct http_arg *args)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; args[i].name != NULL; i++) {
|
||||
if (args[i].value != NULL)
|
||||
kore_mem_free(args[i].value);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
http_argument_add(struct http_request *req, char *name,
|
||||
char *value, u_int32_t len)
|
||||
{
|
||||
struct http_arg *q;
|
||||
|
||||
q = kore_malloc(sizeof(struct http_arg));
|
||||
q->name = kore_strdup(name);
|
||||
|
||||
if (len > 0) {
|
||||
q->value = kore_malloc(len + 1);
|
||||
kore_strlcpy(q->value, value, len + 1);
|
||||
} else {
|
||||
q->value = NULL;
|
||||
}
|
||||
|
||||
TAILQ_INSERT_TAIL(&(req->arguments), q, list);
|
||||
}
|
||||
|
||||
void
|
||||
http_file_add(struct http_request *req, char *name, char *filename,
|
||||
u_int8_t *data, u_int32_t len)
|
||||
{
|
||||
struct http_file *f;
|
||||
|
||||
f = kore_malloc(sizeof(struct http_file));
|
||||
f->len = len;
|
||||
f->data = data;
|
||||
f->name = kore_strdup(name);
|
||||
f->filename = kore_strdup(filename);
|
||||
|
||||
TAILQ_INSERT_TAIL(&(req->files), f, list);
|
||||
}
|
||||
|
||||
int
|
||||
http_file_lookup(struct http_request *req, char *name, char **fname,
|
||||
u_int8_t **data, u_int32_t *len)
|
||||
@ -798,7 +766,7 @@ http_populate_multipart_form(struct http_request *req, int *v)
|
||||
if (opt[2] == NULL) {
|
||||
*v = *v + 1;
|
||||
http_argument_add(req, name,
|
||||
(char *)data, (e - 2) - data);
|
||||
data, (e - 2) - data, HTTP_ARG_TYPE_STRING);
|
||||
kore_mem_free(name);
|
||||
continue;
|
||||
}
|
||||
@ -837,7 +805,87 @@ http_populate_multipart_form(struct http_request *req, int *v)
|
||||
return (KORE_RESULT_OK);
|
||||
}
|
||||
|
||||
char *
|
||||
int
|
||||
http_generic_404(struct http_request *req)
|
||||
{
|
||||
kore_debug("http_generic_404(%s, %d, %s)",
|
||||
req->host, req->method, req->path);
|
||||
|
||||
return (http_response(req, 404, NULL, 0));
|
||||
}
|
||||
|
||||
static void
|
||||
http_argument_add(struct http_request *req, char *name,
|
||||
void *value, u_int32_t len, int type)
|
||||
{
|
||||
struct http_arg *q;
|
||||
struct kore_handler_params *p;
|
||||
|
||||
if (len == 0 || value == NULL) {
|
||||
kore_debug("http_argument_add: with NULL value");
|
||||
return;
|
||||
}
|
||||
|
||||
TAILQ_FOREACH(p, &(req->hdlr->params), list) {
|
||||
if (p->method != req->method)
|
||||
continue;
|
||||
|
||||
if (!strcmp(p->name, name)) {
|
||||
if (type == HTTP_ARG_TYPE_STRING) {
|
||||
http_argument_urldecode(value);
|
||||
len = strlen(value);
|
||||
}
|
||||
|
||||
if (!kore_validator_check(p->validator, value)) {
|
||||
kore_log(LOG_NOTICE,
|
||||
"validator %s (%s) for %s failed",
|
||||
p->validator->name, p->name, req->path);
|
||||
} else {
|
||||
q = kore_malloc(sizeof(struct http_arg));
|
||||
q->len = len;
|
||||
q->s_value = NULL;
|
||||
q->name = kore_strdup(name);
|
||||
q->value = kore_malloc(len);
|
||||
memcpy(q->value, value, len);
|
||||
TAILQ_INSERT_TAIL(&(req->arguments), q, list);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
kore_log(LOG_NOTICE, "unexpected parameter %s for %s", name, req->path);
|
||||
}
|
||||
|
||||
static void
|
||||
http_file_add(struct http_request *req, char *name, char *filename,
|
||||
u_int8_t *data, u_int32_t len)
|
||||
{
|
||||
struct http_file *f;
|
||||
|
||||
f = kore_malloc(sizeof(struct http_file));
|
||||
f->len = len;
|
||||
f->data = data;
|
||||
f->name = kore_strdup(name);
|
||||
f->filename = kore_strdup(filename);
|
||||
|
||||
TAILQ_INSERT_TAIL(&(req->files), f, list);
|
||||
}
|
||||
|
||||
static int
|
||||
http_post_data_recv(struct netbuf *nb)
|
||||
{
|
||||
struct http_request *req = (struct http_request *)nb->extra;
|
||||
|
||||
kore_buf_append(req->post_data, nb->buf, nb->s_off);
|
||||
req->flags |= HTTP_REQUEST_COMPLETE;
|
||||
|
||||
kore_debug("post complete for request %p", req);
|
||||
|
||||
return (KORE_RESULT_OK);
|
||||
}
|
||||
|
||||
static char *
|
||||
http_post_data_text(struct http_request *req)
|
||||
{
|
||||
u_int32_t len;
|
||||
@ -855,7 +903,7 @@ http_post_data_text(struct http_request *req)
|
||||
return (text);
|
||||
}
|
||||
|
||||
u_int8_t *
|
||||
static u_int8_t *
|
||||
http_post_data_bytes(struct http_request *req, u_int32_t *len)
|
||||
{
|
||||
u_int8_t *data;
|
||||
@ -866,77 +914,6 @@ http_post_data_bytes(struct http_request *req, u_int32_t *len)
|
||||
return (data);
|
||||
}
|
||||
|
||||
int
|
||||
http_generic_404(struct http_request *req)
|
||||
{
|
||||
kore_debug("http_generic_404(%s, %d, %s)",
|
||||
req->host, req->method, req->path);
|
||||
|
||||
return (http_response(req, 404, NULL, 0));
|
||||
}
|
||||
|
||||
static int
|
||||
http_post_data_recv(struct netbuf *nb)
|
||||
{
|
||||
struct http_request *req = (struct http_request *)nb->extra;
|
||||
|
||||
kore_buf_append(req->post_data, nb->buf, nb->s_off);
|
||||
req->flags |= HTTP_REQUEST_COMPLETE;
|
||||
|
||||
kore_debug("post complete for request %p", req);
|
||||
|
||||
return (KORE_RESULT_OK);
|
||||
}
|
||||
|
||||
static void
|
||||
http_validate_params(struct http_request *req, struct kore_module_handle *hdlr)
|
||||
{
|
||||
int r;
|
||||
struct kore_handler_params *p;
|
||||
struct http_arg *q, *next;
|
||||
|
||||
if (!http_populate_multipart_form(req, &r))
|
||||
http_populate_arguments(req);
|
||||
|
||||
for (q = TAILQ_FIRST(&(req->arguments)); q != NULL; q = next) {
|
||||
next = TAILQ_NEXT(q, list);
|
||||
|
||||
p = NULL;
|
||||
TAILQ_FOREACH(p, &(hdlr->params), list) {
|
||||
if (p->method != req->method)
|
||||
continue;
|
||||
if (!strcmp(p->name, q->name))
|
||||
break;
|
||||
}
|
||||
|
||||
if (q->value != NULL)
|
||||
http_argument_urldecode(q->value);
|
||||
|
||||
r = KORE_RESULT_ERROR;
|
||||
if (p != NULL && q->value != NULL) {
|
||||
r = kore_validator_check(p->validator, q->value);
|
||||
if (r != KORE_RESULT_OK) {
|
||||
kore_log(LOG_NOTICE,
|
||||
"validator %s(%s) for %s failed",
|
||||
p->validator->name, p->name, req->path);
|
||||
}
|
||||
} else if (p == NULL) {
|
||||
kore_log(LOG_NOTICE,
|
||||
"received unexpected parameter %s for %s",
|
||||
q->name, req->path);
|
||||
}
|
||||
|
||||
if (r == KORE_RESULT_ERROR) {
|
||||
TAILQ_REMOVE(&(req->arguments), q, list);
|
||||
kore_mem_free(q->name);
|
||||
if (q->value != NULL)
|
||||
kore_mem_free(q->value);
|
||||
kore_mem_free(q);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static char *
|
||||
http_status_text(int status)
|
||||
{
|
||||
|
@ -86,10 +86,10 @@ kore_strlcpy(char *dst, const char *src, size_t len)
|
||||
}
|
||||
}
|
||||
|
||||
u_int64_t
|
||||
kore_strtonum(const char *str, int base, u_int64_t min, u_int64_t max, int *err)
|
||||
long long
|
||||
kore_strtonum(const char *str, int base, long long min, long long max, int *err)
|
||||
{
|
||||
u_int64_t l;
|
||||
long long l;
|
||||
char *ep;
|
||||
|
||||
if (min > max) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user