diff --git a/Makefile b/Makefile index 0a4be68..4511c77 100644 --- a/Makefile +++ b/Makefile @@ -257,6 +257,8 @@ REGRESS = regress/test-abort-validator \ regress/test-ping \ regress/test-ping-double \ regress/test-post \ + regress/test-post-charset \ + regress/test-post-charset2 \ regress/test-returncode \ regress/test-template \ regress/test-upload \ diff --git a/child.c b/child.c index a003a98..e864daf 100644 --- a/child.c +++ b/child.c @@ -1468,8 +1468,16 @@ kworker_child_body(struct env *env, int fd, size_t envsz, } if (cp != NULL) { + /* + * The application/x-www-form-urlencoded can take + * arbitrary parameters (usually "charset", but really + * anything) after the type and subtype. XXX: should + * these be passed into the front-end in any way? + */ if (strcasecmp(cp, "application/x-www-form-urlencoded") == 0) parse_pairs_urlenc(pp, b); + else if (strncasecmp(cp, "application/x-www-form-urlencoded;", 34) == 0) + parse_pairs_urlenc(pp, b); else if (strncasecmp(cp, "multipart/form-data", 19) == 0) parse_multi(pp, cp + 19, b, bsz); else if (meth == KMETHOD_POST && strcasecmp(cp, "text/plain") == 0) diff --git a/regress/test-post-charset.c b/regress/test-post-charset.c new file mode 100644 index 0000000..ce424e5 --- /dev/null +++ b/regress/test-post-charset.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) Kristaps Dzonsons + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "../config.h" + +#include +#include +#include +#include +#include + +#include + +#include "../kcgi.h" +#include "regress.h" + +static int +parent(CURL *curl) +{ + const char *data = "foo=bar"; + struct curl_slist *list = NULL; + int c; + + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data); + list = curl_slist_append(list, "Content-Type: " + "application/x-www-form-urlencoded;charset=UTF-8"); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list); + curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:17123/"); + c = curl_easy_perform(curl); + curl_slist_free_all(list); + return c == CURLE_OK; +} + +static int +child(void) +{ + struct kreq r; + const char *page = "index"; + + if (khttp_parse(&r, NULL, 0, &page, 1, 0) != KCGI_OK) + return 0; + if (r.fieldsz != 1 || + strcmp(r.fields[0].key, "foo") != 0 || + strcmp(r.fields[0].val, "bar") != 0) + return 0; + khttp_head(&r, kresps[KRESP_STATUS], "%s", khttps[KHTTP_200]); + khttp_head(&r, kresps[KRESP_CONTENT_TYPE], "%s", + kmimetypes[KMIME_TEXT_HTML]); + khttp_body(&r); + khttp_free(&r); + return 1; +} + +int +main(int argc, char *argv[]) +{ + + return regress_cgi(parent, child) ? 0 : 1; +} diff --git a/regress/test-post-charset2.c b/regress/test-post-charset2.c new file mode 100644 index 0000000..9e92c0e --- /dev/null +++ b/regress/test-post-charset2.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) Kristaps Dzonsons + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "../config.h" + +#include +#include +#include +#include +#include + +#include + +#include "../kcgi.h" +#include "regress.h" + +static int +parent(CURL *curl) +{ + const char *data = "foo=bar"; + struct curl_slist *list = NULL; + int c; + + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data); + list = curl_slist_append(list, "Content-Type: " + "application/x-www-form-urlencoded;"); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list); + curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:17123/"); + c = curl_easy_perform(curl); + curl_slist_free_all(list); + return c == CURLE_OK; +} + +static int +child(void) +{ + struct kreq r; + const char *page = "index"; + + if (khttp_parse(&r, NULL, 0, &page, 1, 0) != KCGI_OK) + return 0; + if (r.fieldsz != 1 || + strcmp(r.fields[0].key, "foo") != 0 || + strcmp(r.fields[0].val, "bar") != 0) + return 0; + khttp_head(&r, kresps[KRESP_STATUS], "%s", khttps[KHTTP_200]); + khttp_head(&r, kresps[KRESP_CONTENT_TYPE], "%s", + kmimetypes[KMIME_TEXT_HTML]); + khttp_body(&r); + khttp_free(&r); + return 1; +} + +int +main(int argc, char *argv[]) +{ + + return regress_cgi(parent, child) ? 0 : 1; +} diff --git a/regress/test-post.c b/regress/test-post.c index 2d3e1fd..00f8017 100644 --- a/regress/test-post.c +++ b/regress/test-post.c @@ -1,6 +1,5 @@ -/* $Id$ */ /* - * Copyright (c) 2016 Kristaps Dzonsons + * Copyright (c) Kristaps Dzonsons * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -44,20 +43,24 @@ child(void) struct kreq r; const char *page = "index"; - if (KCGI_OK != khttp_parse(&r, NULL, 0, &page, 1, 0)) - return(0); + if (khttp_parse(&r, NULL, 0, &page, 1, 0) != KCGI_OK) + return 0; + if (r.fieldsz != 1 || + strcmp(r.fields[0].key, "foo") != 0 || + strcmp(r.fields[0].val, "bar") != 0) + return 0; khttp_head(&r, kresps[KRESP_STATUS], "%s", khttps[KHTTP_200]); khttp_head(&r, kresps[KRESP_CONTENT_TYPE], "%s", kmimetypes[KMIME_TEXT_HTML]); khttp_body(&r); khttp_free(&r); - return(1); + return 1; } int main(int argc, char *argv[]) { - return(regress_cgi(parent, child) ? EXIT_SUCCESS : EXIT_FAILURE); + return regress_cgi(parent, child) ? 0 : 1; }