From 8f888fb1a3469b87e557efad93b293dd36288ba9 Mon Sep 17 00:00:00 2001 From: Sunil Nimmagadda Date: Sat, 14 Sep 2024 12:32:01 +0530 Subject: A HTTP(S), FTP client --- regress/unit-tests/Makefile | 2 + regress/unit-tests/url_parse/Makefile | 17 ++++ regress/unit-tests/url_parse/test_url_parse.c | 134 ++++++++++++++++++++++++++ 3 files changed, 153 insertions(+) create mode 100644 regress/unit-tests/Makefile create mode 100644 regress/unit-tests/url_parse/Makefile create mode 100644 regress/unit-tests/url_parse/test_url_parse.c (limited to 'regress/unit-tests') diff --git a/regress/unit-tests/Makefile b/regress/unit-tests/Makefile new file mode 100644 index 0000000..e67c6f6 --- /dev/null +++ b/regress/unit-tests/Makefile @@ -0,0 +1,2 @@ +SUBDIR+= url_parse +. include diff --git a/regress/unit-tests/url_parse/Makefile b/regress/unit-tests/url_parse/Makefile new file mode 100644 index 0000000..608eb81 --- /dev/null +++ b/regress/unit-tests/url_parse/Makefile @@ -0,0 +1,17 @@ +FTPREL= ../../../ +.PATH: ${.CURDIR}/${FTPREL} + +PROG=test_url_parse +SRCS=test_url_parse.c +SRCS+=file.c ftp.c http.c progressmeter.c url.c util.c xmalloc.c + +CFLAGS+=-I ${.CURDIR}/${FTPREL} +LDADD+= -lutil -ltls -lssl -lcrypto +DPADD+= ${LIBUTIL} ${LIBTLS} ${LIBSSL} ${LIBCRYPTO} + +REGRESS_TARGETS=run-regress-${PROG} + +run-regress-${PROG}: ${PROG} + env ${TEST_ENV} ./${PROG} + +.include diff --git a/regress/unit-tests/url_parse/test_url_parse.c b/regress/unit-tests/url_parse/test_url_parse.c new file mode 100644 index 0000000..5c15d35 --- /dev/null +++ b/regress/unit-tests/url_parse/test_url_parse.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2020 Sunil Nimmagadda + * + * 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 +#include +#include +#include + +#include "ftp.h" + +struct url *ftp_proxy, *http_proxy; +volatile sig_atomic_t interrupted; +const char *useragent; +char *oarg; +int activemode, family, io_debug, verbose, progressmeter; + +int +fd_request(char *path, int flags, off_t *offset) +{ + /* dummy */ + return 0; +} + +static struct { + const char *str; + struct url url; + int noparse; +} testcases[] = { + { "http://google.com/index.html", { + S_HTTP, 0, "google.com", "80", "/index.html" } }, + { "https://google.com:", { + S_HTTPS, 0, "google.com", "443" } }, + { "file:.", { + S_FILE, 0, NULL, NULL, "." } }, + { "http://[::1]:/index.html", { + S_HTTP, 1, "::1", "80", "/index.html" } }, + { "http://[::1]:1234/", { + S_HTTP, 1, "::1", "1234", "/" } }, + { "foo.bar", {}, 1 }, + { "http://[::1:1234", {}, 1 }, + { "http://[1::2::3]:1234", { + S_HTTP, 0, "1::2::3", "1234" } }, + { "http://foo.com:bar", { + S_HTTP, 0, "foo.com", "bar" } }, + { "http:/foo.com", {}, 1 }, + { "http://foo:bar@baz.com", { + S_HTTP, 0, "baz.com", "80" } }, + { "http://[::1]abcd/", {}, 1 }, + { " http://localhost:8080", { + S_HTTP, 0, "localhost", "8080" } }, + { "ftps://localhost:21", {}, 1 }, + { "http://marc.info/?l=openbsd-tech&m=151790635206581&q=raw", { + S_HTTP, 0, "marc.info", "80", "/?l=openbsd-tech&m=151790635206581&q=raw" } }, + { "file://disklabel.template", { + S_FILE, 0, NULL, NULL, "/disklabel.template" } }, + { "file:/disklabel.template", { + S_FILE, 0, NULL, NULL, "/disklabel.template" } }, + { "file:///disklabel.template", { + S_FILE, 0, NULL, NULL, "/disklabel.template" } }, +}; + +static int +ptr_null_cmp(void *a, void *b) +{ + if ((a && b == NULL) || (a == NULL && b)) + return 1; + + return 0; +} + +static int +url_cmp(struct url *a, struct url *b) +{ + if (ptr_null_cmp(a, b) || + ptr_null_cmp(a->host, b->host) || + ptr_null_cmp(a->port, b->port) || + ptr_null_cmp(a->path, b->path)) + return 1; + + if (a->scheme != b->scheme || + (a->host && strcmp(a->host, b->host)) || + (a->port && strcmp(a->port, b->port)) || + (a->path && strcmp(a->path, b->path))) + return 1; + + return 0; +} + +int +main(void) +{ + struct url *url, *eurl; + size_t i; + + if (freopen("/dev/null", "w", stderr) == NULL) + err(1, "freopen"); + + for (i = 0; i < nitems(testcases); i++) { + url = url_parse(testcases[i].str); + if (testcases[i].noparse) { + if (url != NULL) + goto bad; + + continue; + } + + if (url_cmp(url, &testcases[i].url) != 0) + goto bad; + } + + return 0; + + bad: + printf("%s\n", testcases[i].str); + eurl = &testcases[i].url; + printf("Expected: scheme = %s, host = %s, port = %s, path = %s\n", + url_scheme_str(eurl->scheme), eurl->host, eurl->port, eurl->path); + printf("Got: scheme = %s, host = %s, port = %s, path = %s\n", + url_scheme_str(url->scheme), url->host, url->port, url->path); + return 1; +} -- cgit v1.2.3