/* _ * ___ __ _ __ _ _ _(_) * / __|/ _` |/ _` | | | | | * \__ \ (_| | (_| | |_| | | * |___/\__,_|\__, |\__,_|_| * |___/ * * Cross-platform library which helps to develop web servers or frameworks. * * Copyright (C) 2016-2020 Silvio Clecio * * 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 #include #include #include "sg_utils.h" #include "sg_httpuplds.c" #ifndef TEST_HTTPUPLDS_BASE_PATH #ifdef __ANDROID__ #define TEST_HTTPUPLDS_BASE_PATH SG_ANDROID_TESTS_DEST_DIR "/" #else /* __ANDROID__ */ #ifdef _WIN32 #define TEST_HTTPUPLDS_BASE_PATH BINARY_DIR "/" #else /* _WIN32 */ #define TEST_HTTPUPLDS_BASE_PATH "/tmp/" #endif /* _WIN32 */ #endif /* __ANDROID__ */ #endif /* TEST_HTTPUPLDS_BASE_PATH */ #ifndef TEST_HTTPUPLDS_OPEN_MODE #define TEST_HTTPUPLDS_OPEN_MODE \ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH #endif /* TEST_HTTPUPLDS_OPEN_MODE */ #ifndef TEST_HTTPUPLDS_OPEN_WFLAGS #define TEST_HTTPUPLDS_OPEN_WFLAGS O_RDWR | O_CREAT | O_TRUNC #endif /* TEST_HTTPUPLDS_OPEN_WFLAGS */ static int dummy_httpuplds_save_cb(void *handle, bool overwritten) { (void) handle; (void) overwritten; return 123; } static int dummy_httpuplds_save_as_cb(void *handle, const char *path, bool overwritten) { (void) handle; (void) path; (void) overwritten; return 123; } static int dummy_httpuplds_iter_cb(void *cls, struct sg_httpupld *upld) { const char *str = cls; if (strcmp(upld->name, "foo") == 0 || strcmp(upld->name, "bar") == 0) { sprintf(cls, "%s%s", str, upld->name); return 0; } return 123; } static void dummy_httpreq_cb(void *cls, struct sg_httpreq *req, struct sg_httpres *res) { (void) cls; (void) req; (void) res; } static void dummy_err_cb(void *cls, const char *err) { strcpy(cls, err); } static int empty_httpupld_cb(void *cls, void **handle, const char *dir, const char *field, const char *name, const char *mime, const char *encoding) { (void) cls; (void) handle; (void) dir; (void) field; (void) name; (void) mime; (void) encoding; return -1; } static ssize_t empty_httpupld_write_cb(void *handle, uint64_t offset, const char *buf, size_t size) { (void) handle; (void) offset; (void) buf; (void) size; return -1; } static void test__httpuplds_add(void) { char err[256]; struct sg_httpsrv *srv = sg_httpsrv_new2(NULL, dummy_httpreq_cb, dummy_err_cb, err); struct sg_httpreq *req = sg__httpreq_new(srv, NULL, "", "", ""); ASSERT(sg_httpuplds_count(sg_httpreq_uploads(req)) == 0); sg__httpuplds_add(srv, req, "abc", "def", "ghi", "jkl"); ASSERT(strcmp(sg_httpupld_field(req->curr_upld), "abc") == 0); ASSERT(strcmp(sg_httpupld_name(req->curr_upld), "def") == 0); ASSERT(strcmp(sg_httpupld_mime(req->curr_upld), "ghi") == 0); ASSERT(strcmp(sg_httpupld_encoding(req->curr_upld), "jkl") == 0); ASSERT(sg_httpuplds_count(sg_httpreq_uploads(req)) == 1); sg__httpuplds_free(srv, req); sg__httpreq_free(req); sg_httpsrv_free(srv); } static void test__httpuplds_free(void) { sg__httpuplds_free(NULL, NULL); } static void test__httpuplds_iter(void) { const char *filename = "foo.txt"; const size_t len = 3; char err[256], str[256]; struct sg_httpsrv *srv = sg_httpsrv_new2(NULL, dummy_httpreq_cb, dummy_err_cb, err); struct sg_httpreq *req = sg__httpreq_new(srv, NULL, "", "", ""); struct sg__httpupld_holder holder = {srv, req}; struct sg_strmap **fields; sg_httpupld_cb saved_upld_cb; sg_write_cb saved_upld_write_cb; char *dir, *dest_path; ASSERT(sg__httpuplds_iter(NULL, MHD_POSTDATA_KIND, NULL, NULL, NULL, NULL, NULL, 0, 0) == MHD_YES); saved_upld_cb = srv->upld_cb; srv->upld_cb = empty_httpupld_cb; ASSERT(sg__httpuplds_iter(&holder, MHD_POSTDATA_KIND, NULL, filename, NULL, NULL, "foo", 0, len) == MHD_NO); srv->upld_cb = saved_upld_cb; saved_upld_write_cb = srv->upld_write_cb; srv->upld_write_cb = empty_httpupld_write_cb; ASSERT(sg__httpuplds_iter(&holder, MHD_POSTDATA_KIND, NULL, filename, NULL, NULL, "foo", 0, len) == MHD_NO); srv->upld_write_cb = saved_upld_write_cb; dir = sg_tmpdir(); ASSERT(dir); dest_path = sg__strjoin(PATH_SEP, dir, filename); sg_free(dir); ASSERT(dest_path); unlink(dest_path); ASSERT(access(dest_path, F_OK) == -1); ASSERT(sg__httpuplds_iter(&holder, MHD_POSTDATA_KIND, NULL, filename, NULL, NULL, "foo", 0, len) == MHD_YES); ASSERT(sg_httpupld_save(holder.req->curr_upld, true) == 0); ASSERT(access(dest_path, F_OK) == 0); sg_free(dest_path); ASSERT(sg_httpsrv_set_uplds_limit(srv, 1) == 0); memset(err, 0, sizeof(err)); ASSERT(sg__httpuplds_iter(&holder, MHD_POSTDATA_KIND, NULL, filename, NULL, NULL, "foo", 0, len) == MHD_NO); memset(str, 0, sizeof(str)); snprintf(str, sizeof(str), _("Upload too large.\n")); ASSERT(strcmp(err, str) == 0); fields = sg_httpreq_fields(req); ASSERT(!sg_strmap_get(*fields, "foo")); ASSERT(sg__httpuplds_iter(&holder, MHD_POSTDATA_KIND, "foo", NULL, NULL, NULL, "bar", 0, len) == MHD_YES); ASSERT(strcmp(sg_strmap_get(*fields, "foo"), "bar") == 0); ASSERT(sg_httpsrv_set_payld_limit(srv, 1) == 0); memset(err, 0, sizeof(err)); ASSERT(sg__httpuplds_iter(&holder, MHD_POSTDATA_KIND, "foo", NULL, NULL, NULL, "bar", 0, len) == MHD_NO); memset(str, 0, sizeof(str)); snprintf(str, sizeof(str), _("Payload too large.\n")); ASSERT(strcmp(err, str) == 0); sg__httpuplds_cleanup(srv, req); sg__httpreq_free(req); sg_httpsrv_free(srv); } static void test__httpuplds_process(void) { const size_t len = 3; char err[256], str[256]; struct MHD_Connection *con = sg_alloc(64); struct sg_httpsrv *srv = sg_httpsrv_new2(NULL, dummy_httpreq_cb, dummy_err_cb, err); struct sg_httpreq *req = sg__httpreq_new(srv, NULL, "", "", ""); int ret = 0; size_t size = 0; ASSERT(!sg__httpuplds_process(NULL, NULL, NULL, NULL, &size, &ret)); ASSERT(sg_httpsrv_set_payld_limit(srv, 1) == 0); size = len; ret = MHD_YES; memset(err, 0, sizeof(err)); ASSERT(sg__httpuplds_process(srv, req, con, "foo", &size, &ret)); ASSERT(ret == MHD_NO); memset(str, 0, sizeof(str)); snprintf(str, sizeof(str), _("Payload too large.\n")); ASSERT(strcmp(err, str) == 0); ASSERT(sg_httpsrv_set_payld_limit(srv, len) == 0); ret = MHD_NO; ASSERT(sg__httpuplds_process(srv, req, con, "foo", &size, &ret)); ASSERT(ret == MHD_YES); ASSERT(strcmp(sg_str_content(req->payload), "foo") == 0); sg__httpreq_free(req); sg_httpsrv_free(srv); sg_free(con); } static void test__httpuplds_cleanup(void) { struct sg_httpsrv *srv = sg_httpsrv_new(dummy_httpreq_cb, NULL); struct sg_httpreq *req = sg__httpreq_new(srv, NULL, "", "", ""); struct sg_httpupld *tmp; size_t count = 0; ASSERT(srv); ASSERT(req); sg__httpuplds_cleanup(srv, req); LL_COUNT(req->uplds, tmp, count); ASSERT(count == 0); req->curr_upld = sg_alloc(sizeof(struct sg_httpupld)); LL_APPEND(req->uplds, req->curr_upld); req->curr_upld = NULL; /* fix PVS-Studio analysis */ req->curr_upld = sg_alloc(sizeof(struct sg_httpupld)); LL_APPEND(req->uplds, req->curr_upld); LL_COUNT(req->uplds, tmp, count); ASSERT(count == 2); sg__httpuplds_cleanup(srv, req); LL_COUNT(req->uplds, tmp, count); ASSERT(count == 0); sg__httpreq_free(req); sg_httpsrv_free(srv); } static void test__httpupld_cb(void) { const char *dummy_path = TEST_HTTPUPLDS_BASE_PATH "foo.txt", *filename = "foo.txt"; const ssize_t len = 3; char err[256], str[256]; void *handle = NULL; struct sg__httpupld *h; struct sg_httpsrv *srv; char *dir, *dest_path; int fd; memset(err, 0, sizeof(err)); srv = sg_httpsrv_new2(NULL, dummy_httpreq_cb, dummy_err_cb, err); ASSERT(sg__httpupld_cb(srv, &handle, "", "", "", "", "") == ENOENT); ASSERT(!handle); snprintf(str, sizeof(str), _("Cannot find uploads directory \"%s\": %s.\n"), "", strerror(ENOENT)); ASSERT(strcmp(err, str) == 0); unlink(dummy_path); fd = open(dummy_path, TEST_HTTPUPLDS_OPEN_WFLAGS, TEST_HTTPUPLDS_OPEN_MODE); ASSERT(fd > -1); ASSERT(close(fd) == 0); ASSERT(access(dummy_path, F_OK) == 0); memset(err, 0, sizeof(err)); ASSERT(sg__httpupld_cb(srv, &handle, dummy_path, "", "", "", "") == ENOTDIR); unlink(dummy_path); ASSERT(!handle); memset(str, 0, sizeof(str)); snprintf(str, sizeof(str), _("Cannot access uploads directory \"%s\": %s.\n"), dummy_path, strerror(ENOTDIR)); ASSERT(strcmp(err, str) == 0); #if defined(__linux__) && !defined(__ANDROID__) memset(err, 0, sizeof(err)); ASSERT(sg__httpupld_cb(srv, &handle, "/", "", "", "", "") == EACCES); ASSERT(!handle); memset(str, 0, sizeof(str)); snprintf(str, sizeof(str), _("Cannot create temporary upload file in \"%s\": %s.\n"), "/", strerror(EACCES)); ASSERT(strcmp(err, str) == 0); #endif /* __linux__ && !__ANDROID__ */ dir = sg_tmpdir(); dest_path = sg__strjoin(PATH_SEP, dir, filename); ASSERT(dest_path); unlink(dest_path); ASSERT(access(dest_path, F_OK) == -1); ASSERT(sg__httpupld_cb(srv, &handle, dir, "foo", "foo.txt", "", "") == 0); sg_free(dir); h = handle; ASSERT(access(h->path, F_OK) == 0); ASSERT(sg__httpupld_write_cb(handle, 0, "foo", len) == len); ASSERT(sg__httpupld_save_cb(handle, true) == 0); sg__httpupld_free_cb(handle); ASSERT(access(dest_path, F_OK) == 0); fd = open(dest_path, O_RDONLY); sg_free(dest_path); ASSERT(fd > -1); memset(str, 0, sizeof(str)); ASSERT(read(fd, str, len) == len); ASSERT(close(fd) == 0); ASSERT(strcmp(str, "foo") == 0); sg_httpsrv_free(srv); } static void test__httpupld_write_cb(void) { const ssize_t len = 3; char str[4]; struct sg__httpupld *handle = sg_alloc(sizeof(struct sg__httpupld)); handle->path = TEST_HTTPUPLDS_BASE_PATH "foo.txt"; unlink(handle->path); ASSERT(access(handle->path, F_OK) == -1); handle->fd = open(handle->path, TEST_HTTPUPLDS_OPEN_WFLAGS, TEST_HTTPUPLDS_OPEN_MODE); ASSERT(handle->fd > -1); ASSERT(sg__httpupld_write_cb(handle, 0, "foo", len - 1) == (len - 1)); ASSERT(close(handle->fd) == 0); ASSERT(access(handle->path, F_OK) == 0); handle->fd = open(handle->path, O_RDONLY); ASSERT(handle->fd); memset(str, 0, sizeof(str)); ASSERT(read(handle->fd, str, len) == (len - 1)); ASSERT(close(handle->fd) == 0); ASSERT(strcmp(str, "fo") == 0); sg_free(handle); } static void test__httpupld_free_cb(void) { const char *path = TEST_HTTPUPLDS_BASE_PATH "foo.txt"; char err[256]; struct sg_httpsrv *saved_srv; struct sg__httpupld *handle = sg_alloc(sizeof(struct sg__httpupld)); memset(err, 0, sizeof(err)); handle->srv = sg_httpsrv_new2(NULL, dummy_httpreq_cb, dummy_err_cb, err); handle->path = sg__strdup(path); handle->dest = NULL; unlink(handle->path); handle->fd = open(handle->path, TEST_HTTPUPLDS_OPEN_WFLAGS, TEST_HTTPUPLDS_OPEN_MODE); ASSERT(handle->fd > -1); #ifdef _WIN32 ASSERT(close(handle->fd) == 0); #endif /* _WIN32 */ ASSERT(unlink(handle->path) == 0); ASSERT(strcmp(err, "") == 0); saved_srv = handle->srv; sg__httpupld_free_cb(handle); sg_httpsrv_free(saved_srv); } static void test__httpupld_save_cb(void) { const ssize_t len = 3; char str[4]; struct sg__httpupld *handle = sg_alloc(sizeof(struct sg__httpupld)); handle->path = TEST_HTTPUPLDS_BASE_PATH "foo.txt"; handle->dest = TEST_HTTPUPLDS_BASE_PATH "bar.txt"; unlink(handle->dest); unlink(handle->path); ASSERT(sg__httpupld_save_cb(NULL, false) == EINVAL); handle->fd = open(handle->path, TEST_HTTPUPLDS_OPEN_WFLAGS, TEST_HTTPUPLDS_OPEN_MODE); ASSERT(handle->fd > -1); ASSERT(write(handle->fd, "foo", len) == len); ASSERT(access(handle->dest, F_OK) == -1); ASSERT(sg__httpupld_save_cb(handle, true) == 0); ASSERT(access(handle->dest, F_OK) == 0); handle->fd = open(handle->dest, O_RDONLY); ASSERT(handle->fd > -1); memset(str, 0, sizeof(str)); ASSERT(read(handle->fd, str, len) == len); ASSERT(close(handle->fd) == 0); ASSERT(strcmp(str, "foo") == 0); sg_free(handle); } static void test__httpupld_save_as_cb(void) { const ssize_t len = 3; const char *bar_path = TEST_HTTPUPLDS_BASE_PATH "bar.txt"; char str[4]; char *dir; struct sg__httpupld *handle = sg_alloc(sizeof(struct sg__httpupld)); handle->path = TEST_HTTPUPLDS_BASE_PATH "foo.txt"; handle->fd = -1; unlink(bar_path); unlink(handle->path); ASSERT(sg__httpupld_save_as_cb(NULL, "foo", false) == EINVAL); ASSERT(sg__httpupld_save_as_cb(handle, "foo", false) == EINVAL); handle->fd = open(handle->path, TEST_HTTPUPLDS_OPEN_WFLAGS, TEST_HTTPUPLDS_OPEN_MODE); ASSERT(handle->fd > -1); ASSERT(sg__httpupld_save_as_cb(handle, NULL, false) == EINVAL); close(handle->fd); handle->fd = open(bar_path, TEST_HTTPUPLDS_OPEN_WFLAGS, TEST_HTTPUPLDS_OPEN_MODE); ASSERT(handle->fd > -1); ASSERT(write(handle->fd, "bar", len) == len); ASSERT(close(handle->fd) == 0); ASSERT(access(bar_path, F_OK) == 0); handle->fd = open(bar_path, O_RDONLY); ASSERT(handle->fd > -1); memset(str, 0, sizeof(str)); ASSERT(read(handle->fd, str, len) == len); ASSERT(close(handle->fd) == 0); ASSERT(strcmp(str, "bar") == 0); handle->fd = open(handle->path, TEST_HTTPUPLDS_OPEN_WFLAGS, TEST_HTTPUPLDS_OPEN_MODE); ASSERT(handle->fd > -1); ASSERT(write(handle->fd, "foo", len) == len); ASSERT(sg__httpupld_save_as_cb(handle, bar_path, false) == EEXIST); ASSERT(access(bar_path, F_OK) == 0); handle->fd = open(bar_path, O_RDONLY); ASSERT(handle->fd > -1); memset(str, 0, sizeof(str)); ASSERT(read(handle->fd, str, len) == len); ASSERT(close(handle->fd) == 0); ASSERT(strcmp(str, "bar") == 0); dir = sg_tmpdir(); ASSERT(dir); ASSERT(access(dir, F_OK) == 0); handle->fd = open(handle->path, TEST_HTTPUPLDS_OPEN_WFLAGS, TEST_HTTPUPLDS_OPEN_MODE); ASSERT(handle->fd > -1); ASSERT(write(handle->fd, "foo", len) == len); ASSERT(sg__httpupld_save_as_cb(handle, dir, false) == EISDIR); sg_free(dir); handle->fd = open(handle->path, TEST_HTTPUPLDS_OPEN_WFLAGS, TEST_HTTPUPLDS_OPEN_MODE); ASSERT(handle->fd > -1); ASSERT(write(handle->fd, "foo", len) == len); ASSERT(sg__httpupld_save_as_cb(handle, "", false) == ENOENT); handle->fd = open(handle->path, TEST_HTTPUPLDS_OPEN_WFLAGS, TEST_HTTPUPLDS_OPEN_MODE); ASSERT(handle->fd > -1); ASSERT(write(handle->fd, "foo", len) == len); ASSERT(sg__httpupld_save_as_cb(handle, bar_path, true) == 0); ASSERT(access(bar_path, F_OK) == 0); handle->fd = open(bar_path, O_RDONLY); ASSERT(handle->fd > -1); memset(str, 0, sizeof(str)); ASSERT(read(handle->fd, str, len) == len); ASSERT(close(handle->fd) == 0); ASSERT(strcmp(str, "foo") == 0); unlink(bar_path); ASSERT(access(bar_path, F_OK) == -1); handle->fd = open(handle->path, TEST_HTTPUPLDS_OPEN_WFLAGS, TEST_HTTPUPLDS_OPEN_MODE); ASSERT(handle->fd > -1); ASSERT(write(handle->fd, "foo", len) == len); ASSERT(sg__httpupld_save_as_cb(handle, bar_path, false) == 0); ASSERT(access(bar_path, F_OK) == 0); handle->fd = open(bar_path, O_RDONLY); ASSERT(handle->fd > -1); memset(str, 0, sizeof(str)); ASSERT(read(handle->fd, str, len) == len); ASSERT(close(handle->fd) == 0); ASSERT(strcmp(str, "foo") == 0); sg_free(handle); unlink(bar_path); } static void test_httpuplds_iter(void) { struct sg_httpupld *tmp, *upld, *uplds = NULL; char str[100]; ASSERT(sg_httpuplds_iter(uplds, NULL, str) == EINVAL); ASSERT(sg_httpuplds_iter(NULL, dummy_httpuplds_iter_cb, str) == 0); upld = sg_alloc(sizeof(struct sg_httpupld)); upld->name = "foo"; LL_APPEND(uplds, upld); upld = sg_alloc(sizeof(struct sg_httpupld)); upld->name = "bar"; LL_APPEND(uplds, upld); memset(str, 0, sizeof(str)); ASSERT(sg_httpuplds_iter(uplds, dummy_httpuplds_iter_cb, str) == 0); ASSERT(strcmp(str, "foobar") == 0); upld = sg_alloc(sizeof(struct sg_httpupld)); upld->name = "xxx"; LL_APPEND(uplds, upld); ASSERT(sg_httpuplds_iter(uplds, dummy_httpuplds_iter_cb, str) == 123); LL_FOREACH_SAFE(uplds, upld, tmp) { LL_DELETE(uplds, upld); sg_free(upld); } } static void test_httpuplds_next(void) { struct sg_httpupld *tmp, *upld, *uplds = NULL; ASSERT(sg_httpuplds_next(NULL) == EINVAL); upld = sg_alloc(sizeof(struct sg_httpupld)); upld->name = "abc123"; LL_APPEND(uplds, upld); upld = sg_alloc(sizeof(struct sg_httpupld)); upld->name = "def456"; LL_APPEND(uplds, upld); upld = sg_alloc(sizeof(struct sg_httpupld)); upld->name = "ghi789"; LL_APPEND(uplds, upld); upld = uplds; ASSERT(strcmp(sg_httpupld_name(upld), "abc123") == 0); ASSERT(sg_httpuplds_next(&upld) == 0); ASSERT(strcmp(sg_httpupld_name(upld), "def456") == 0); ASSERT(sg_httpuplds_next(&upld) == 0); ASSERT(strcmp(sg_httpupld_name(upld), "ghi789") == 0); LL_FOREACH_SAFE(uplds, upld, tmp) { LL_DELETE(uplds, upld); sg_free(upld); } } static void test_httpuplds_count(void) { struct sg_httpupld *tmp, *upld, *uplds = NULL; errno = 0; ASSERT(sg_httpuplds_count(NULL) == 0); ASSERT(errno == 0); upld = sg_alloc(sizeof(struct sg_httpupld)); LL_APPEND(uplds, upld); ASSERT(sg_httpuplds_count(uplds) == 1); upld = sg_alloc(sizeof(struct sg_httpupld)); LL_APPEND(uplds, upld); ASSERT(sg_httpuplds_count(uplds) == 2); LL_FOREACH_SAFE(uplds, upld, tmp) { LL_DELETE(uplds, upld); sg_free(upld); } } static void test_httpupld_handle(struct sg_httpupld *upld) { errno = 0; ASSERT(sg_httpupld_handle(NULL) == 0); ASSERT(errno == EINVAL); upld->handle = NULL; errno = 0; ASSERT(!sg_httpupld_handle(upld)); ASSERT(errno == 0); upld->handle = upld; ASSERT(sg_httpupld_handle(upld) == upld); } static void test_httpupld_dir(struct sg_httpupld *upld) { errno = 0; ASSERT(sg_httpupld_dir(NULL) == 0); ASSERT(errno == EINVAL); upld->dir = NULL; errno = 0; ASSERT(!sg_httpupld_dir(upld)); ASSERT(errno == 0); upld->dir = "K7eFIFhFJmwSI601"; ASSERT(strcmp(sg_httpupld_dir(upld), "K7eFIFhFJmwSI601") == 0); } static void test_httpupld_field(struct sg_httpupld *upld) { errno = 0; ASSERT(sg_httpupld_field(NULL) == 0); ASSERT(errno == EINVAL); upld->field = NULL; errno = 0; ASSERT(!sg_httpupld_field(upld)); ASSERT(errno == 0); upld->field = "ZgJwfUrXVAHSV4pb"; ASSERT(strcmp(sg_httpupld_field(upld), "ZgJwfUrXVAHSV4pb") == 0); } static void test_httpupld_name(struct sg_httpupld *upld) { errno = 0; ASSERT(sg_httpupld_name(NULL) == 0); ASSERT(errno == EINVAL); upld->name = NULL; errno = 0; ASSERT(!sg_httpupld_name(upld)); ASSERT(errno == 0); upld->name = "04wSe5er0FCCI1JG"; ASSERT(strcmp(sg_httpupld_name(upld), "04wSe5er0FCCI1JG") == 0); } static void test_httpupld_mime(struct sg_httpupld *upld) { errno = 0; ASSERT(sg_httpupld_mime(NULL) == 0); ASSERT(errno == EINVAL); upld->mime = NULL; errno = 0; ASSERT(!sg_httpupld_mime(upld)); ASSERT(errno == 0); upld->mime = "diOx11XHmluaYegV"; ASSERT(strcmp(sg_httpupld_mime(upld), "diOx11XHmluaYegV") == 0); } static void test_httpupld_encoding(struct sg_httpupld *upld) { errno = 0; ASSERT(sg_httpupld_encoding(NULL) == 0); ASSERT(errno == EINVAL); upld->encoding = NULL; errno = 0; ASSERT(!sg_httpupld_encoding(upld)); ASSERT(errno == 0); upld->encoding = "uwJtxi8hSMIDMdO7"; ASSERT(strcmp(sg_httpupld_encoding(upld), "uwJtxi8hSMIDMdO7") == 0); } static void test_httpupld_size(struct sg_httpupld *upld) { errno = 0; ASSERT(sg_httpupld_size(NULL) == 0); ASSERT(errno == EINVAL); upld->size = 0; errno = 0; ASSERT(sg_httpupld_size(upld) == 0); ASSERT(errno == 0); upld->size = 123; ASSERT(sg_httpupld_size(upld) == 123); } static void test_httpupld_save(struct sg_httpupld *upld) { ASSERT(sg_httpupld_save(NULL, false) == EINVAL); upld->save_cb = dummy_httpuplds_save_cb; ASSERT(sg_httpupld_save(upld, true) == 123); } static void test_httpupld_save_as(struct sg_httpupld *upld) { ASSERT(sg_httpupld_save_as(NULL, "", false) == EINVAL); ASSERT(sg_httpupld_save_as(upld, NULL, false) == EINVAL); upld->save_as_cb = dummy_httpuplds_save_as_cb; ASSERT(sg_httpupld_save_as(upld, "abc", true) == 123); } int main(void) { struct sg_httpupld *upld = sg_alloc(sizeof(struct sg_httpupld)); test__httpuplds_add(); test__httpuplds_free(); test__httpuplds_iter(); test__httpuplds_process(); test__httpuplds_cleanup(); test__httpupld_cb(); test__httpupld_write_cb(); test__httpupld_free_cb(); test__httpupld_save_cb(); test__httpupld_save_as_cb(); test_httpuplds_iter(); test_httpuplds_next(); test_httpuplds_count(); test_httpupld_handle(upld); test_httpupld_dir(upld); test_httpupld_field(upld); test_httpupld_name(upld); test_httpupld_mime(upld); test_httpupld_encoding(upld); test_httpupld_size(upld); test_httpupld_save(upld); test_httpupld_save_as(upld); sg_free(upld); return EXIT_SUCCESS; }