| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038 |
- /* _
- * ___ __ _ __ _ _ _(_)
- * / __|/ _` |/ _` | | | | |
- * \__ \ (_| | (_| | |_| | |
- * |___/\__,_|\__, |\__,_|_|
- * |___/
- *
- * Cross-platform library which helps to develop web servers or frameworks.
- *
- * Copyright (C) 2016-2021 Silvio Clecio <[email protected]>
- *
- * Sagui library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Sagui library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sagui library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
- #define SG_EXTERN
- #include "sg_assert.h"
- #include <string.h>
- #include "sg_httpres.c"
- #include <sagui.h>
- #ifndef TEST_HTTPRES_BASE_PATH
- #ifdef __ANDROID__
- #define TEST_HTTPRES_BASE_PATH SG_ANDROID_TESTS_DEST_DIR "/"
- #else /* __ANDROID__ */
- #ifdef _WIN32
- #define TEST_HTTPRES_BASE_PATH BINARY_DIR "/"
- #else /* _WIN32 */
- #define TEST_HTTPRES_BASE_PATH "/tmp/"
- #endif /* _WIN32 */
- #endif /* __ANDROID__ */
- #endif /* TEST_HTTPRES_BASE_PATH */
- static ssize_t dummy_read_cb(void *handle, uint64_t offset, char *buf,
- size_t size) {
- (void) handle;
- (void) offset;
- (void) buf;
- (void) size;
- return 0;
- }
- static void dummy_free_cb(void *handle) {
- *((int *) handle) = 0;
- }
- static void test__httpres_new(void) {
- struct sg_httpres *res = sg__httpres_new(NULL);
- ASSERT(res);
- ASSERT(res->status == 500);
- sg__httpres_free(res);
- }
- static void test__httpres_free(void) {
- sg__httpres_free(NULL);
- }
- static void test__httpres_dispatch(struct sg_httpres *res) {
- ASSERT(sg__httpres_dispatch(res) == 0);
- }
- static void test_httpres_headers(struct sg_httpres *res) {
- struct sg_strmap **headers;
- errno = 0;
- ASSERT(!sg_httpres_headers(NULL));
- ASSERT(errno == EINVAL);
- errno = 0;
- res->headers = NULL;
- ASSERT(sg_httpres_headers(res));
- ASSERT(errno == 0);
- headers = sg_httpres_headers(res);
- ASSERT(headers);
- ASSERT(sg_strmap_count(*headers) == 0);
- sg_strmap_add(&res->headers, "foo", "bar");
- sg_strmap_add(&res->headers, "abc", "123");
- ASSERT(sg_strmap_count(*headers) == 2);
- ASSERT(strcmp(sg_strmap_get(*headers, "foo"), "bar") == 0);
- ASSERT(strcmp(sg_strmap_get(*headers, "abc"), "123") == 0);
- }
- static void test_httpres_set_cookie(struct sg_httpres *res) {
- struct sg_strmap **fields;
- ASSERT(sg_httpres_set_cookie(NULL, "foo", "bar") == EINVAL);
- ASSERT(sg_httpres_set_cookie(res, NULL, "bar") == EINVAL);
- ASSERT(sg_httpres_set_cookie(res, "foo", NULL) == EINVAL);
- fields = sg_httpres_headers(res);
- sg_strmap_cleanup(fields);
- ASSERT(sg_httpres_set_cookie(res, "foo", "bar") == 0);
- ASSERT(
- strcmp(sg_strmap_get(*sg_httpres_headers(res), MHD_HTTP_HEADER_SET_COOKIE),
- "foo=bar") == 0);
- }
- static void test_httpres_send(struct sg_httpres *res) {
- char *str = "foo";
- ASSERT(sg_httpres_send(NULL, str, "text/plain", 200) == EINVAL);
- str = NULL;
- ASSERT(sg_httpres_send(res, str, "text/plain", 200) == EINVAL);
- ASSERT(sg_httpres_send(res, str, NULL, 200) == EINVAL);
- ASSERT(sg_httpres_send(res, str, "text/plain", 99) == EINVAL);
- ASSERT(sg_httpres_send(res, str, "text/plain", 600) == EINVAL);
- res->status = 0;
- ASSERT(sg_httpres_send(res, "", "text/plain", 200) == 0);
- ASSERT(res->status == 200);
- MHD_destroy_response(res->handle);
- res->handle = NULL;
- res->status = 0;
- ASSERT(sg_httpres_send(res, "", "", 204) == 0); /* No content. */
- ASSERT(res->status == 204);
- MHD_destroy_response(res->handle);
- res->handle = NULL;
- res->status = 0;
- str = "foo";
- ASSERT(sg_httpres_send(res, str, "text/plain", 201) == 0);
- ASSERT(res->status == 201);
- ASSERT(sg_httpres_send(res, str, "text/plain", 200) == EALREADY);
- ASSERT(strcmp(sg_strmap_get(*sg_httpres_headers(res),
- MHD_HTTP_HEADER_CONTENT_TYPE),
- "text/plain") == 0);
- ASSERT(res->status == 201);
- MHD_destroy_response(res->handle);
- res->handle = NULL;
- }
- static void test_httpres_sendbinary(struct sg_httpres *res) {
- char *str = "foo";
- const size_t len = strlen(str);
- ASSERT(sg_httpres_sendbinary(NULL, str, len, "text/plain", 200) == EINVAL);
- ASSERT(sg_httpres_sendbinary(res, NULL, len, "text/plain", 200) == EINVAL);
- ASSERT(sg_httpres_sendbinary(res, str, (size_t) -1, "text/plain", 200) ==
- EINVAL);
- ASSERT(sg_httpres_sendbinary(res, str, len, "text/plain", 99) == EINVAL);
- ASSERT(sg_httpres_sendbinary(res, str, len, "text/plain", 600) == EINVAL);
- res->status = 0;
- ASSERT(sg_httpres_sendbinary(res, str, len, NULL, 200) == 0);
- ASSERT(res->status == 200);
- MHD_destroy_response(res->handle);
- res->handle = NULL;
- res->status = 0;
- ASSERT(sg_httpres_sendbinary(res, "foo", 0, "text/plain", 200) == 0);
- ASSERT(res->status == 200);
- MHD_destroy_response(res->handle);
- res->handle = NULL;
- res->status = 0;
- ASSERT(sg_httpres_sendbinary(res, str, len, "", 200) == 0);
- ASSERT(res->status == 200);
- MHD_destroy_response(res->handle);
- res->handle = NULL;
- res->status = 0;
- ASSERT(sg_httpres_sendbinary(res, "", 0, "", 204) == 0); /* No content. */
- ASSERT(res->status == 204);
- MHD_destroy_response(res->handle);
- res->handle = NULL;
- res->status = 0;
- ASSERT(sg_httpres_sendbinary(res, str, len, "text/plain", 201) == 0);
- ASSERT(res->status == 201);
- ASSERT(sg_httpres_sendbinary(res, str, len, "text/plain", 200) == EALREADY);
- ASSERT(strcmp(sg_strmap_get(*sg_httpres_headers(res),
- MHD_HTTP_HEADER_CONTENT_TYPE),
- "text/plain") == 0);
- ASSERT(res->status == 201);
- MHD_destroy_response(res->handle);
- res->handle = NULL;
- }
- static void test_httpres_download(struct sg_httpres *res) {
- #define FILENAME "foo.txt"
- #define PATH TEST_HTTPRES_BASE_PATH FILENAME
- const size_t len = 3;
- char str[4];
- FILE *file;
- char *dir;
- ASSERT(sg_httpres_download(NULL, PATH, 200) == EINVAL);
- ASSERT(sg_httpres_download(res, NULL, 200) == EINVAL);
- ASSERT(sg_httpres_download(res, "", 200) == ENOENT);
- dir = sg_tmpdir();
- ASSERT(sg_httpres_download(res, dir, 200) == EISDIR);
- sg_free(dir);
- strcpy(str, "foo");
- unlink(PATH);
- file = fopen(PATH, "w");
- ASSERT(file);
- ASSERT(fwrite(str, 1, len, file) == len);
- ASSERT(fclose(file) == 0);
- ASSERT(sg_httpres_download(res, PATH, 200) == 0);
- ASSERT(strcmp(sg_strmap_get(*sg_httpres_headers(res),
- MHD_HTTP_HEADER_CONTENT_DISPOSITION),
- "attachment; filename=\"" FILENAME "\"") == 0);
- ASSERT(sg_httpres_download(res, PATH, 200) == EALREADY);
- sg_free(res->handle);
- res->handle = NULL;
- #undef PATH
- #undef FILENAME
- sg_free(res->handle);
- res->handle = NULL;
- }
- static void test_httpres_render(struct sg_httpres *res) {
- #define FILENAME "foo.txt"
- #define PATH TEST_HTTPRES_BASE_PATH FILENAME
- const size_t len = 3;
- char str[4];
- FILE *file;
- char *dir;
- ASSERT(sg_httpres_render(NULL, PATH, 200) == EINVAL);
- ASSERT(sg_httpres_render(res, NULL, 200) == EINVAL);
- ASSERT(sg_httpres_render(res, "", 200) == ENOENT);
- dir = sg_tmpdir();
- ASSERT(sg_httpres_render(res, dir, 200) == EISDIR);
- sg_free(dir);
- strcpy(str, "foo");
- unlink(PATH);
- file = fopen(PATH, "w");
- ASSERT(file);
- ASSERT(fwrite(str, 1, len, file) == len);
- ASSERT(fclose(file) == 0);
- ASSERT(sg_httpres_render(res, PATH, 200) == 0);
- ASSERT(strcmp(sg_strmap_get(*sg_httpres_headers(res),
- MHD_HTTP_HEADER_CONTENT_DISPOSITION),
- "inline; filename=\"" FILENAME "\"") == 0);
- ASSERT(sg_httpres_render(res, PATH, 200) == EALREADY);
- sg_free(res->handle);
- res->handle = NULL;
- #undef PATH
- #undef FILENAME
- sg_free(res->handle);
- res->handle = NULL;
- }
- static void test_httpres_sendfile2(struct sg_httpres *res) {
- #define FILENAME "foo.txt"
- #define PATH TEST_HTTPRES_BASE_PATH FILENAME
- const size_t len = 3;
- char str[4];
- FILE *file;
- char *dir;
- size_t size = sizeof(int);
- uint64_t max_size = 10, offset = 0;
- ASSERT(sg_httpres_sendfile2(NULL, size, max_size, offset, PATH, NULL, 200) ==
- EINVAL);
- ASSERT(sg_httpres_sendfile2(res, (uint64_t) -1, max_size, offset, PATH, NULL,
- 200) == EINVAL);
- ASSERT(sg_httpres_sendfile2(res, size, (uint64_t) -1, offset, PATH, NULL,
- 200) == EINVAL);
- ASSERT(sg_httpres_sendfile2(res, size, max_size, (uint64_t) -1, PATH, NULL,
- 200) == EINVAL);
- ASSERT(sg_httpres_sendfile2(res, size, max_size, offset, NULL, NULL, 200) ==
- EINVAL);
- ASSERT(sg_httpres_sendfile2(res, size, max_size, offset, PATH, NULL, 99) ==
- EINVAL);
- ASSERT(sg_httpres_sendfile2(res, size, max_size, offset, PATH, NULL, 600) ==
- EINVAL);
- ASSERT(sg_httpres_sendfile2(res, size, max_size, offset, "", NULL, 200) ==
- ENOENT);
- dir = sg_tmpdir();
- ASSERT(sg_httpres_sendfile2(res, size, max_size, offset, dir, NULL, 200) ==
- EISDIR);
- sg_free(dir);
- strcpy(str, "foo");
- unlink(PATH);
- file = fopen(PATH, "w");
- ASSERT(file);
- ASSERT(fwrite(str, 1, len, file) == len);
- ASSERT(fclose(file) == 0);
- ASSERT(sg_httpres_sendfile2(res, size, 1, offset, PATH, NULL, 200) == EFBIG);
- ASSERT(
- sg_httpres_sendfile2(res, size, len, offset, PATH, "attachment", 200) == 0);
- ASSERT(strcmp(sg_strmap_get(*sg_httpres_headers(res),
- MHD_HTTP_HEADER_CONTENT_DISPOSITION),
- "attachment; filename=\"" FILENAME "\"") == 0);
- ASSERT(sg_httpres_sendfile2(res, size, len, offset, PATH, "attachment",
- 200) == EALREADY);
- sg_free(res->handle);
- res->handle = NULL;
- ASSERT(sg_httpres_sendfile2(res, size, len, offset, PATH, "inline", 201) ==
- 0);
- ASSERT(strcmp(sg_strmap_get(*sg_httpres_headers(res),
- MHD_HTTP_HEADER_CONTENT_DISPOSITION),
- "inline; filename=\"" FILENAME "\"") == 0);
- ASSERT(res->status == 201);
- sg_free(res->handle);
- res->handle = NULL;
- sg_strmap_cleanup(sg_httpres_headers(res));
- ASSERT(sg_httpres_sendfile2(res, size, len, offset, PATH, NULL, 200) == 0);
- ASSERT(!sg_strmap_get(*sg_httpres_headers(res),
- MHD_HTTP_HEADER_CONTENT_DISPOSITION));
- ASSERT(res->status == 200);
- sg_free(res->handle);
- res->handle = NULL;
- ASSERT(sg_httpres_sendfile2(res, size, len, offset, PATH, "abc123", 201) ==
- 0);
- ASSERT(strcmp(sg_strmap_get(*sg_httpres_headers(res),
- MHD_HTTP_HEADER_CONTENT_DISPOSITION),
- "abc123; filename=\"" FILENAME "\"") == 0);
- ASSERT(res->status == 201);
- #undef PATH
- #undef FILENAME
- sg_free(res->handle);
- res->handle = NULL;
- }
- static void test_httpres_sendfile(struct sg_httpres *res) {
- #define FILENAME "foo.txt"
- #define PATH TEST_HTTPRES_BASE_PATH FILENAME
- const size_t len = 3;
- char str[4];
- FILE *file;
- char *dir;
- size_t size = sizeof(int);
- uint64_t max_size = 10, offset = 0;
- ASSERT(sg_httpres_sendfile(NULL, size, max_size, offset, PATH, false, 200) ==
- EINVAL);
- ASSERT(sg_httpres_sendfile(res, (uint64_t) -1, max_size, offset, PATH, false,
- 200) == EINVAL);
- ASSERT(sg_httpres_sendfile(res, size, (uint64_t) -1, offset, PATH, false,
- 200) == EINVAL);
- ASSERT(sg_httpres_sendfile(res, size, max_size, (uint64_t) -1, PATH, false,
- 200) == EINVAL);
- ASSERT(sg_httpres_sendfile(res, size, max_size, offset, NULL, false, 200) ==
- EINVAL);
- ASSERT(sg_httpres_sendfile(res, size, max_size, offset, PATH, false, 99) ==
- EINVAL);
- ASSERT(sg_httpres_sendfile(res, size, max_size, offset, PATH, false, 600) ==
- EINVAL);
- ASSERT(sg_httpres_sendfile(res, size, max_size, offset, "", false, 200) ==
- ENOENT);
- dir = sg_tmpdir();
- ASSERT(sg_httpres_sendfile(res, size, max_size, offset, dir, false, 200) ==
- EISDIR);
- sg_free(dir);
- strcpy(str, "foo");
- unlink(PATH);
- file = fopen(PATH, "w");
- ASSERT(file);
- ASSERT(fwrite(str, 1, len, file) == len);
- ASSERT(fclose(file) == 0);
- ASSERT(sg_httpres_sendfile(res, size, 1, offset, PATH, false, 200) == EFBIG);
- ASSERT(sg_httpres_sendfile(res, size, len, offset, PATH, true, 200) == 0);
- ASSERT(strcmp(sg_strmap_get(*sg_httpres_headers(res),
- MHD_HTTP_HEADER_CONTENT_DISPOSITION),
- "attachment; filename=\"" FILENAME "\"") == 0);
- ASSERT(sg_httpres_sendfile(res, size, len, offset, PATH, true, 200) ==
- EALREADY);
- sg_free(res->handle);
- res->handle = NULL;
- sg_strmap_cleanup(sg_httpres_headers(res));
- ASSERT(sg_httpres_sendfile(res, size, len, offset, PATH, false, 201) == 0);
- ASSERT(!sg_strmap_get(*sg_httpres_headers(res),
- MHD_HTTP_HEADER_CONTENT_DISPOSITION));
- ASSERT(res->status == 201);
- #undef PATH
- #undef FILENAME
- sg_free(res->handle);
- res->handle = NULL;
- }
- static void test_httpres_sendstream(struct sg_httpres *res) {
- char *str;
- size_t size = sizeof(int);
- int buf = 1;
- ASSERT(sg_httpres_sendstream(NULL, size, dummy_read_cb, &buf, dummy_free_cb,
- 200) == EINVAL);
- ASSERT(buf == 0);
- buf = 1;
- ASSERT(sg_httpres_sendstream(res, (uint64_t) -1, NULL, &buf, dummy_free_cb,
- 200) == EINVAL);
- ASSERT(buf == 0);
- buf = 1;
- ASSERT(sg_httpres_sendstream(res, size, NULL, &buf, dummy_free_cb, 200) ==
- EINVAL);
- ASSERT(buf == 0);
- buf = 1;
- ASSERT(sg_httpres_sendstream(res, size, dummy_read_cb, &buf, dummy_free_cb,
- 99) == EINVAL);
- ASSERT(buf == 0);
- buf = 1;
- ASSERT(sg_httpres_sendstream(res, size, dummy_read_cb, &buf, dummy_free_cb,
- 600) == EINVAL);
- ASSERT(buf == 0);
- size = sizeof(str);
- str = sg_alloc(size);
- ASSERT(
- sg_httpres_sendstream(res, 0, dummy_read_cb, str, dummy_free_cb, 200) == 0);
- sg_free(res->handle);
- res->handle = NULL;
- ASSERT(sg_httpres_sendstream(res, size, dummy_read_cb, str, dummy_free_cb,
- 201) == 0);
- ASSERT(res->status == 201);
- ASSERT(sg_httpres_sendstream(res, size, dummy_read_cb, str, dummy_free_cb,
- 200) == EALREADY);
- sg_free(res->handle);
- res->handle = NULL;
- sg_free(str);
- }
- #ifdef SG_HTTP_COMPRESSION
- static void test_httpres_zsend(struct sg_httpres *res) {
- char *str = "foo";
- ASSERT(sg_httpres_zsend(NULL, str, "text/plain", 200) == EINVAL);
- str = NULL;
- ASSERT(sg_httpres_zsend(res, str, "text/plain", 200) == EINVAL);
- ASSERT(sg_httpres_zsend(res, str, NULL, 200) == EINVAL);
- ASSERT(sg_httpres_zsend(res, str, "text/plain", 99) == EINVAL);
- ASSERT(sg_httpres_zsend(res, str, "text/plain", 600) == EINVAL);
- str = "foooo";
- res->status = 0;
- sg_strmap_cleanup(&res->headers);
- ASSERT(sg_httpres_zsend(res, str, "text/plain", 200) == 0);
- ASSERT(!sg_strmap_get(res->headers, "Content-Encoding"));
- ASSERT(strcmp(sg_strmap_get(res->headers, "Content-Type"), "text/plain") ==
- 0);
- ASSERT(res->status == 200);
- MHD_destroy_response(res->handle);
- res->handle = NULL;
- str = "fooooooooooobaaaaaaaaaarrrrrrrrrrr";
- res->status = 0;
- ASSERT(sg_httpres_zsend(res, str, "text/plain", 200) == 0);
- ASSERT(strcmp(sg_strmap_get(res->headers, "Content-Encoding"), "deflate") ==
- 0);
- ASSERT(strcmp(sg_strmap_get(res->headers, "Content-Type"), "text/plain") ==
- 0);
- ASSERT(res->status == 200);
- MHD_destroy_response(res->handle);
- res->handle = NULL;
- res->status = 0;
- str = "foo";
- ASSERT(sg_httpres_zsend(res, str, "", 200) == 0);
- ASSERT(res->status == 200);
- MHD_destroy_response(res->handle);
- res->handle = NULL;
- res->status = 0;
- ASSERT(sg_httpres_zsend(res, "", "", 204) == 0); /* No content. */
- ASSERT(res->status == 204);
- MHD_destroy_response(res->handle);
- res->handle = NULL;
- res->status = 0;
- ASSERT(sg_httpres_zsend(res, str, "text/plain", 201) == 0);
- ASSERT(res->status == 201);
- ASSERT(sg_httpres_zsend(res, str, "text/plain", 200) == EALREADY);
- ASSERT(strcmp(sg_strmap_get(*sg_httpres_headers(res),
- MHD_HTTP_HEADER_CONTENT_TYPE),
- "text/plain") == 0);
- ASSERT(res->status == 201);
- MHD_destroy_response(res->handle);
- res->handle = NULL;
- }
- static void test_httpres_zsendbinary2(struct sg_httpres *res) {
- char *str = "foo";
- size_t len = strlen(str);
- ASSERT(sg_httpres_zsendbinary2(NULL, -1, str, len, "text/plain", 200) ==
- EINVAL);
- ASSERT(sg_httpres_zsendbinary2(res, -2, str, len, "text/plain", 200) ==
- EINVAL);
- ASSERT(sg_httpres_zsendbinary2(res, 10, str, len, "text/plain", 200) ==
- EINVAL);
- ASSERT(sg_httpres_zsendbinary2(res, -1, NULL, len, "text/plain", 200) ==
- EINVAL);
- ASSERT(sg_httpres_zsendbinary2(res, -1, str, (size_t) -1, "text/plain",
- 200) == EINVAL);
- ASSERT(sg_httpres_zsendbinary2(res, -1, str, len, "text/plain", 99) ==
- EINVAL);
- ASSERT(sg_httpres_zsendbinary2(res, -1, str, len, "text/plain", 600) ==
- EINVAL);
- str = "foooo";
- len = strlen(str);
- res->status = 0;
- sg_strmap_cleanup(&res->headers);
- ASSERT(sg_httpres_zsendbinary2(res, -1, str, len, "text/plain", 200) == 0);
- ASSERT(!sg_strmap_get(res->headers, "Content-Encoding"));
- ASSERT(strcmp(sg_strmap_get(res->headers, "Content-Type"), "text/plain") ==
- 0);
- ASSERT(res->status == 200);
- MHD_destroy_response(res->handle);
- res->handle = NULL;
- str = "fooooooooooobaaaaaaaaaarrrrrrrrrrr";
- len = strlen(str);
- res->status = 0;
- ASSERT(sg_httpres_zsendbinary2(res, -1, str, len, "text/plain", 200) == 0);
- ASSERT(strcmp(sg_strmap_get(res->headers, "Content-Encoding"), "deflate") ==
- 0);
- ASSERT(strcmp(sg_strmap_get(res->headers, "Content-Type"), "text/plain") ==
- 0);
- ASSERT(res->status == 200);
- MHD_destroy_response(res->handle);
- res->handle = NULL;
- str = "foo";
- len = strlen(str);
- res->status = 0;
- ASSERT(sg_httpres_zsendbinary2(res, -1, "foo", 0, "text/plain", 200) == 0);
- ASSERT(res->status == 200);
- MHD_destroy_response(res->handle);
- res->handle = NULL;
- res->status = 0;
- ASSERT(sg_httpres_zsendbinary2(res, -1, str, len, NULL, 200) == 0);
- ASSERT(res->status == 200);
- MHD_destroy_response(res->handle);
- res->handle = NULL;
- res->status = 0;
- ASSERT(sg_httpres_zsendbinary2(res, -1, str, len, "", 200) == 0);
- ASSERT(res->status == 200);
- MHD_destroy_response(res->handle);
- res->handle = NULL;
- res->status = 0;
- ASSERT(sg_httpres_zsendbinary2(res, -1, "", 0, "", 204) ==
- 0); /* No content. */
- ASSERT(res->status == 204);
- MHD_destroy_response(res->handle);
- res->handle = NULL;
- res->status = 0;
- ASSERT(sg_httpres_zsendbinary2(res, -1, str, len, "text/plain", 201) == 0);
- ASSERT(res->status == 201);
- ASSERT(sg_httpres_zsendbinary2(res, -1, str, len, "text/plain", 200) ==
- EALREADY);
- ASSERT(strcmp(sg_strmap_get(*sg_httpres_headers(res),
- MHD_HTTP_HEADER_CONTENT_TYPE),
- "text/plain") == 0);
- ASSERT(res->status == 201);
- MHD_destroy_response(res->handle);
- res->handle = NULL;
- }
- static void test_httpres_zsendbinary(struct sg_httpres *res) {
- char *str = "foo";
- size_t len = strlen(str);
- ASSERT(sg_httpres_zsendbinary(NULL, str, len, "text/plain", 200) == EINVAL);
- ASSERT(sg_httpres_zsendbinary(res, NULL, len, "text/plain", 200) == EINVAL);
- ASSERT(sg_httpres_zsendbinary(res, str, (size_t) -1, "text/plain", 200) ==
- EINVAL);
- ASSERT(sg_httpres_zsendbinary(res, str, len, "text/plain", 99) == EINVAL);
- ASSERT(sg_httpres_zsendbinary(res, str, len, "text/plain", 600) == EINVAL);
- str = "foooo";
- len = strlen(str);
- res->status = 0;
- sg_strmap_cleanup(&res->headers);
- ASSERT(sg_httpres_zsendbinary(res, str, len, "text/plain", 200) == 0);
- ASSERT(!sg_strmap_get(res->headers, "Content-Encoding"));
- ASSERT(strcmp(sg_strmap_get(res->headers, "Content-Type"), "text/plain") ==
- 0);
- ASSERT(res->status == 200);
- MHD_destroy_response(res->handle);
- res->handle = NULL;
- str = "fooooooooooobaaaaaaaaaarrrrrrrrrrr";
- len = strlen(str);
- res->status = 0;
- ASSERT(sg_httpres_zsendbinary(res, str, len, "text/plain", 200) == 0);
- ASSERT(strcmp(sg_strmap_get(res->headers, "Content-Encoding"), "deflate") ==
- 0);
- ASSERT(strcmp(sg_strmap_get(res->headers, "Content-Type"), "text/plain") ==
- 0);
- ASSERT(res->status == 200);
- MHD_destroy_response(res->handle);
- res->handle = NULL;
- str = "foo";
- len = strlen(str);
- res->status = 0;
- ASSERT(sg_httpres_zsendbinary(res, "foo", 0, "text/plain", 200) == 0);
- ASSERT(res->status == 200);
- MHD_destroy_response(res->handle);
- res->handle = NULL;
- res->status = 0;
- ASSERT(sg_httpres_zsendbinary(res, str, len, NULL, 200) == 0);
- ASSERT(res->status == 200);
- MHD_destroy_response(res->handle);
- res->handle = NULL;
- res->status = 0;
- ASSERT(sg_httpres_zsendbinary(res, str, len, "", 200) == 0);
- ASSERT(res->status == 200);
- MHD_destroy_response(res->handle);
- res->handle = NULL;
- res->status = 0;
- ASSERT(sg_httpres_zsendbinary(res, "", 0, "", 204) == 0); /* No content. */
- ASSERT(res->status == 204);
- MHD_destroy_response(res->handle);
- res->handle = NULL;
- res->status = 0;
- ASSERT(sg_httpres_zsendbinary(res, str, len, "text/plain", 201) == 0);
- ASSERT(res->status == 201);
- ASSERT(sg_httpres_zsendbinary(res, str, len, "text/plain", 200) == EALREADY);
- ASSERT(strcmp(sg_strmap_get(*sg_httpres_headers(res),
- MHD_HTTP_HEADER_CONTENT_TYPE),
- "text/plain") == 0);
- ASSERT(res->status == 201);
- MHD_destroy_response(res->handle);
- res->handle = NULL;
- }
- static void test_httpres_zsendstream2(struct sg_httpres *res) {
- char *str;
- size_t size = sizeof(int);
- int buf = 1;
- ASSERT(sg_httpres_zsendstream2(NULL, -1, size, dummy_read_cb, &buf,
- dummy_free_cb, 200) == EINVAL);
- ASSERT(buf == 0);
- buf = 1;
- ASSERT(sg_httpres_zsendstream2(res, -2, size, dummy_read_cb, &buf,
- dummy_free_cb, 200) == EINVAL);
- ASSERT(buf == 0);
- buf = 1;
- ASSERT(sg_httpres_zsendstream2(res, 10, size, dummy_read_cb, &buf,
- dummy_free_cb, 200) == EINVAL);
- ASSERT(buf == 0);
- buf = 1;
- ASSERT(sg_httpres_zsendstream2(res, -1, size, NULL, &buf, dummy_free_cb,
- 200) == EINVAL);
- ASSERT(buf == 0);
- buf = 1;
- ASSERT(sg_httpres_zsendstream2(res, -1, size, dummy_read_cb, &buf,
- dummy_free_cb, 99) == EINVAL);
- ASSERT(buf == 0);
- buf = 1;
- ASSERT(sg_httpres_zsendstream2(res, -1, size, dummy_read_cb, &buf,
- dummy_free_cb, 600) == EINVAL);
- ASSERT(buf == 0);
- str = sg_alloc(sizeof(str));
- ASSERT(sg_httpres_zsendstream2(res, -1, size, dummy_read_cb, str,
- dummy_free_cb, 200) == 0);
- sg_free(res->handle);
- res->handle = NULL;
- ASSERT(sg_httpres_zsendstream2(res, -1, size, dummy_read_cb, str,
- dummy_free_cb, 201) == 0);
- ASSERT(res->status == 201);
- ASSERT(sg_httpres_zsendstream2(res, -1, size, dummy_read_cb, str,
- dummy_free_cb, 200) == EALREADY);
- sg_free(res->handle);
- res->handle = NULL;
- sg_free(str);
- }
- static void test_httpres_zsendstream(struct sg_httpres *res) {
- char *str;
- int buf = 1;
- ASSERT(sg_httpres_zsendstream(NULL, dummy_read_cb, &buf, dummy_free_cb,
- 200) == EINVAL);
- ASSERT(buf == 0);
- buf = 1;
- ASSERT(sg_httpres_zsendstream(res, NULL, &buf, dummy_free_cb, 200) == EINVAL);
- ASSERT(buf == 0);
- buf = 1;
- ASSERT(sg_httpres_zsendstream(res, dummy_read_cb, &buf, dummy_free_cb, 99) ==
- EINVAL);
- ASSERT(buf == 0);
- buf = 1;
- ASSERT(sg_httpres_zsendstream(res, dummy_read_cb, &buf, dummy_free_cb, 600) ==
- EINVAL);
- ASSERT(buf == 0);
- str = sg_alloc(sizeof(str));
- ASSERT(sg_httpres_zsendstream(res, dummy_read_cb, str, dummy_free_cb, 200) ==
- 0);
- sg_free(res->handle);
- res->handle = NULL;
- ASSERT(sg_httpres_zsendstream(res, dummy_read_cb, str, dummy_free_cb, 201) ==
- 0);
- ASSERT(res->status == 201);
- ASSERT(sg_httpres_zsendstream(res, dummy_read_cb, str, dummy_free_cb, 200) ==
- EALREADY);
- sg_free(res->handle);
- res->handle = NULL;
- sg_free(str);
- }
- static void test_httpres_zdownload(struct sg_httpres *res) {
- #define FILENAME "foo.txt"
- #define PATH TEST_HTTPRES_BASE_PATH FILENAME
- const size_t len = 3;
- char str[4];
- FILE *file;
- char *dir;
- ASSERT(sg_httpres_zdownload(NULL, PATH, 200) == EINVAL);
- ASSERT(sg_httpres_zdownload(res, NULL, 200) == EINVAL);
- ASSERT(sg_httpres_zdownload(res, "", 200) == ENOENT);
- dir = sg_tmpdir();
- ASSERT(sg_httpres_zdownload(res, dir, 200) == EISDIR);
- sg_free(dir);
- strcpy(str, "foo");
- unlink(PATH);
- file = fopen(PATH, "w");
- ASSERT(file);
- ASSERT(fwrite(str, 1, len, file) == len);
- ASSERT(fclose(file) == 0);
- ASSERT(sg_httpres_zdownload(res, PATH, 200) == 0);
- ASSERT(strcmp(sg_strmap_get(*sg_httpres_headers(res),
- MHD_HTTP_HEADER_CONTENT_DISPOSITION),
- "attachment; filename=\"" FILENAME "\"") == 0);
- ASSERT(sg_httpres_zdownload(res, PATH, 200) == EALREADY);
- sg_free(res->handle);
- res->handle = NULL;
- #undef PATH
- #undef FILENAME
- sg_free(res->handle);
- res->handle = NULL;
- }
- static void test_httpres_zrender(struct sg_httpres *res) {
- #define FILENAME "foo.txt"
- #define PATH TEST_HTTPRES_BASE_PATH FILENAME
- const size_t len = 3;
- char str[4];
- FILE *file;
- char *dir;
- ASSERT(sg_httpres_zrender(NULL, PATH, 200) == EINVAL);
- ASSERT(sg_httpres_zrender(res, NULL, 200) == EINVAL);
- ASSERT(sg_httpres_zrender(res, "", 200) == ENOENT);
- dir = sg_tmpdir();
- ASSERT(sg_httpres_zrender(res, dir, 200) == EISDIR);
- sg_free(dir);
- strcpy(str, "foo");
- unlink(PATH);
- file = fopen(PATH, "w");
- ASSERT(file);
- ASSERT(fwrite(str, 1, len, file) == len);
- ASSERT(fclose(file) == 0);
- ASSERT(sg_httpres_zrender(res, PATH, 200) == 0);
- ASSERT(strcmp(sg_strmap_get(*sg_httpres_headers(res),
- MHD_HTTP_HEADER_CONTENT_DISPOSITION),
- "inline; filename=\"" FILENAME "\"") == 0);
- ASSERT(sg_httpres_zrender(res, PATH, 200) == EALREADY);
- sg_free(res->handle);
- res->handle = NULL;
- #undef PATH
- #undef FILENAME
- sg_free(res->handle);
- res->handle = NULL;
- }
- static void test_httpres_zsendfile2(struct sg_httpres *res) {
- #define FILENAME "foo.txt"
- #define PATH TEST_HTTPRES_BASE_PATH FILENAME
- const size_t len = 3;
- char str[4];
- FILE *file;
- char *dir;
- size_t size = sizeof(int);
- uint64_t max_size = 10, offset = 0;
- ASSERT(sg_httpres_zsendfile2(NULL, -1, size, max_size, offset, PATH, NULL,
- 200) == EINVAL);
- ASSERT(sg_httpres_zsendfile2(res, -2, size, max_size, offset, PATH, NULL,
- 200) == EINVAL);
- ASSERT(sg_httpres_zsendfile2(res, 10, size, max_size, offset, PATH, NULL,
- 200) == EINVAL);
- ASSERT(sg_httpres_zsendfile2(res, -1, (uint64_t) -1, max_size, offset, PATH,
- NULL, 200) == EINVAL);
- ASSERT(sg_httpres_zsendfile2(res, -1, size, (uint64_t) -1, offset, PATH, NULL,
- 200) == EINVAL);
- ASSERT(sg_httpres_zsendfile2(res, -1, size, max_size, (uint64_t) -1, PATH,
- NULL, 200) == EINVAL);
- ASSERT(sg_httpres_zsendfile2(res, -1, size, max_size, offset, NULL, NULL,
- 200) == EINVAL);
- ASSERT(sg_httpres_zsendfile2(res, -1, size, max_size, offset, PATH, NULL,
- 99) == EINVAL);
- ASSERT(sg_httpres_zsendfile2(res, -1, size, max_size, offset, PATH, NULL,
- 600) == EINVAL);
- ASSERT(sg_httpres_zsendfile2(res, -1, size, max_size, offset, "", NULL,
- 200) == ENOENT);
- dir = sg_tmpdir();
- ASSERT(sg_httpres_zsendfile2(res, -1, size, max_size, offset, dir, NULL,
- 200) == EISDIR);
- sg_free(dir);
- strcpy(str, "foo");
- unlink(PATH);
- file = fopen(PATH, "w");
- ASSERT(file);
- ASSERT(fwrite(str, 1, len, file) == len);
- ASSERT(fclose(file) == 0);
- ASSERT(sg_httpres_zsendfile2(res, -1, size, 1, offset, PATH, NULL, 200) ==
- EFBIG);
- ASSERT(sg_httpres_zsendfile2(res, -1, size, len, offset, PATH, "attachment",
- 200) == 0);
- ASSERT(strcmp(sg_strmap_get(*sg_httpres_headers(res),
- MHD_HTTP_HEADER_CONTENT_DISPOSITION),
- "attachment; filename=\"" FILENAME "\"") == 0);
- ASSERT(sg_httpres_zsendfile2(res, -1, size, len, offset, PATH, "attachment",
- 200) == EALREADY);
- sg_free(res->handle);
- res->handle = NULL;
- ASSERT(sg_httpres_zsendfile2(res, -1, size, len, offset, PATH, "inline",
- 201) == 0);
- ASSERT(strcmp(sg_strmap_get(*sg_httpres_headers(res),
- MHD_HTTP_HEADER_CONTENT_DISPOSITION),
- "inline; filename=\"" FILENAME "\"") == 0);
- ASSERT(res->status == 201);
- sg_free(res->handle);
- res->handle = NULL;
- sg_strmap_cleanup(sg_httpres_headers(res));
- ASSERT(sg_httpres_zsendfile2(res, -1, size, len, offset, PATH, NULL, 200) ==
- 0);
- ASSERT(!sg_strmap_get(*sg_httpres_headers(res),
- MHD_HTTP_HEADER_CONTENT_DISPOSITION));
- ASSERT(res->status == 200);
- sg_free(res->handle);
- res->handle = NULL;
- ASSERT(sg_httpres_zsendfile2(res, -1, size, len, offset, PATH, "abc123",
- 201) == 0);
- ASSERT(strcmp(sg_strmap_get(*sg_httpres_headers(res),
- MHD_HTTP_HEADER_CONTENT_DISPOSITION),
- "abc123; filename=\"" FILENAME "\"") == 0);
- ASSERT(res->status == 201);
- #undef PATH
- #undef FILENAME
- sg_free(res->handle);
- res->handle = NULL;
- }
- static void test_httpres_zsendfile(struct sg_httpres *res) {
- #define FILENAME "foo.txt"
- #define PATH TEST_HTTPRES_BASE_PATH FILENAME
- const size_t len = 3;
- char str[4];
- FILE *file;
- char *dir;
- size_t size = sizeof(int);
- uint64_t max_size = 10, offset = 0;
- ASSERT(sg_httpres_zsendfile(NULL, size, max_size, offset, PATH, false, 200) ==
- EINVAL);
- ASSERT(sg_httpres_zsendfile(res, (uint64_t) -1, max_size, offset, PATH, false,
- 200) == EINVAL);
- ASSERT(sg_httpres_zsendfile(res, size, (uint64_t) -1, offset, PATH, false,
- 200) == EINVAL);
- ASSERT(sg_httpres_zsendfile(res, size, max_size, (uint64_t) -1, PATH, false,
- 200) == EINVAL);
- ASSERT(sg_httpres_zsendfile(res, size, max_size, offset, NULL, false, 200) ==
- EINVAL);
- ASSERT(sg_httpres_zsendfile(res, size, max_size, offset, PATH, false, 99) ==
- EINVAL);
- ASSERT(sg_httpres_zsendfile(res, size, max_size, offset, PATH, false, 600) ==
- EINVAL);
- ASSERT(sg_httpres_zsendfile(res, size, max_size, offset, "", false, 200) ==
- ENOENT);
- dir = sg_tmpdir();
- ASSERT(sg_httpres_zsendfile(res, size, max_size, offset, dir, false, 200) ==
- EISDIR);
- sg_free(dir);
- strcpy(str, "foo");
- unlink(PATH);
- file = fopen(PATH, "w");
- ASSERT(file);
- ASSERT(fwrite(str, 1, len, file) == len);
- ASSERT(fclose(file) == 0);
- ASSERT(sg_httpres_zsendfile(res, size, 1, offset, PATH, false, 200) == EFBIG);
- ASSERT(sg_httpres_zsendfile(res, size, len, offset, PATH, true, 200) == 0);
- ASSERT(strcmp(sg_strmap_get(*sg_httpres_headers(res),
- MHD_HTTP_HEADER_CONTENT_DISPOSITION),
- "attachment; filename=\"" FILENAME "\"") == 0);
- ASSERT(sg_httpres_zsendfile(res, size, len, offset, PATH, true, 200) ==
- EALREADY);
- sg_free(res->handle);
- res->handle = NULL;
- sg_strmap_cleanup(sg_httpres_headers(res));
- ASSERT(sg_httpres_zsendfile(res, size, len, offset, PATH, false, 201) == 0);
- ASSERT(!sg_strmap_get(*sg_httpres_headers(res),
- MHD_HTTP_HEADER_CONTENT_DISPOSITION));
- ASSERT(res->status == 201);
- #undef PATH
- #undef FILENAME
- sg_free(res->handle);
- res->handle = NULL;
- }
- #endif /* SG_HTTP_COMPRESSION */
- static void test_httpres_reset(struct sg_httpres *res) {
- struct sg_strmap **headers;
- ASSERT(sg_httpres_reset(NULL) == EINVAL);
- headers = sg_httpres_headers(res);
- ASSERT(sg_strmap_add(headers, "foo", "bar") == 0);
- ASSERT(sg_strmap_add(headers, "lorem", "ipsum") == 0);
- ASSERT(sg_httpres_set_cookie(res, "my", "cookie") == 0);
- ASSERT(sg_httpres_send(res, "", "", 200) == 0);
- ASSERT(res->handle);
- ASSERT(strcmp(sg_strmap_get(*headers, "foo"), "bar") == 0);
- ASSERT(strcmp(sg_strmap_get(*headers, "lorem"), "ipsum") == 0);
- ASSERT(strcmp(sg_strmap_get(*headers, "Set-Cookie"), "my=cookie") == 0);
- ASSERT(res->status == 200);
- ASSERT(sg_httpres_reset(res) == 0);
- ASSERT(sg_httpres_reset(res) == 0);
- ASSERT(!res->handle);
- ASSERT(sg_strmap_get(*headers, "foo"));
- ASSERT(sg_strmap_get(*headers, "lorem"));
- ASSERT(sg_strmap_get(*headers, "Set-Cookie"));
- ASSERT(res->status == 500);
- }
- static void test_httpres_clear(struct sg_httpres *res) {
- struct sg_strmap **headers;
- ASSERT(sg_httpres_clear(NULL) == EINVAL);
- headers = sg_httpres_headers(res);
- ASSERT(sg_strmap_add(headers, "foo", "bar") == 0);
- ASSERT(sg_strmap_add(headers, "lorem", "ipsum") == 0);
- ASSERT(sg_httpres_set_cookie(res, "my", "cookie") == 0);
- ASSERT(sg_httpres_send(res, "", "", 200) == 0);
- ASSERT(res->handle);
- ASSERT(strcmp(sg_strmap_get(*headers, "foo"), "bar") == 0);
- ASSERT(strcmp(sg_strmap_get(*headers, "lorem"), "ipsum") == 0);
- ASSERT(strcmp(sg_strmap_get(*headers, "Set-Cookie"), "my=cookie") == 0);
- ASSERT(res->status == 200);
- ASSERT(sg_httpres_clear(res) == 0);
- ASSERT(sg_httpres_clear(res) == 0);
- ASSERT(!res->handle);
- ASSERT(!sg_strmap_get(*headers, "foo"));
- ASSERT(!sg_strmap_get(*headers, "lorem"));
- ASSERT(!sg_strmap_get(*headers, "Set-Cookie"));
- ASSERT(res->status == 500);
- }
- static void test_httpres_is_empty(struct sg_httpres *res) {
- errno = 0;
- ASSERT(!sg_httpres_is_empty(NULL));
- ASSERT(errno == EINVAL);
- errno = 0;
- ASSERT(sg_httpres_send(res, "", "text/plain", 200) == 0);
- ASSERT(!sg_httpres_is_empty(res));
- ASSERT(errno == 0);
- MHD_destroy_response(res->handle);
- res->handle = NULL;
- ASSERT(sg_httpres_is_empty(res));
- ASSERT(errno == 0);
- }
- int main(void) {
- struct sg_httpres *res = sg__httpres_new(NULL);
- ASSERT(res);
- test__httpres_new();
- test__httpres_free();
- test__httpres_dispatch(res);
- test_httpres_headers(res);
- test_httpres_set_cookie(res);
- test_httpres_send(res);
- test_httpres_sendbinary(res);
- test_httpres_download(res);
- test_httpres_render(res);
- test_httpres_sendfile2(res);
- test_httpres_sendfile(res);
- test_httpres_sendstream(res);
- #ifdef SG_HTTP_COMPRESSION
- test_httpres_zsend(res);
- test_httpres_zsendbinary2(res);
- test_httpres_zsendbinary(res);
- test_httpres_zsendstream2(res);
- test_httpres_zsendstream(res);
- test_httpres_zdownload(res);
- test_httpres_zrender(res);
- test_httpres_zsendfile2(res);
- test_httpres_zsendfile(res);
- #endif /* SG_HTTP_COMPRESSION */
- test_httpres_reset(res);
- test_httpres_clear(res);
- test_httpres_is_empty(res);
- sg__httpres_free(res);
- return EXIT_SUCCESS;
- }
|