summaryrefslogtreecommitdiff
path: root/test/basic.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/basic.c')
-rw-r--r--test/basic.c228
1 files changed, 228 insertions, 0 deletions
diff --git a/test/basic.c b/test/basic.c
new file mode 100644
index 0000000..15f5c8a
--- /dev/null
+++ b/test/basic.c
@@ -0,0 +1,228 @@
+/*
+ Tests for high-level HTTP interface (ne_basic.h)
+ Copyright (C) 2002-2003, Joe Orton <joe@manyfish.co.uk>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "config.h"
+
+#include <sys/types.h>
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <fcntl.h>
+
+#include "ne_basic.h"
+
+#include "tests.h"
+#include "child.h"
+#include "utils.h"
+
+static int content_type(void)
+{
+ int n;
+ static const struct {
+ const char *value, *type, *subtype, *charset;
+ } ctypes[] = {
+ { "foo/bar", "foo", "bar", NULL },
+ { "foo/bar ", "foo", "bar", NULL },
+ { "application/xml", "application", "xml", NULL },
+ /* text/ subtypes default to charset ISO-8859-1. */
+ { "text/lemon", "text", "lemon", "ISO-8859-1" },
+#undef TXU
+#define TXU "text", "xml", "utf-8"
+ /* 2616 doesn't *say* that charset can be quoted, but bets are
+ * that some servers do it anyway. */
+ { "text/xml; charset=utf-8", TXU },
+ { "text/xml; charset=utf-8; foo=bar", TXU },
+ { "text/xml;charset=utf-8", TXU },
+ { "text/xml ;charset=utf-8", TXU },
+ { "text/xml;charset=utf-8;foo=bar", TXU },
+ { "text/xml; foo=bar; charset=utf-8", TXU },
+ { "text/xml; foo=bar; charset=utf-8; bar=foo", TXU },
+ { "text/xml; charset=\"utf-8\"", TXU },
+ { "text/xml; charset='utf-8'", TXU },
+ { "text/xml; foo=bar; charset=\"utf-8\"; bar=foo", TXU },
+#undef TXU
+ /* badly quoted charset should come out as NULL */
+ { "foo/lemon; charset=\"utf-8", "foo", "lemon", NULL },
+ { NULL }
+ };
+
+ for (n = 0; ctypes[n].value != NULL; n++) {
+ ne_content_type ct = {0};
+
+ ne_content_type_handler(&ct, ctypes[n].value);
+
+ ONV(strcmp(ct.type, ctypes[n].type),
+ ("for `%s': type was `%s'", ctypes[n].value, ct.type));
+
+ ONV(strcmp(ct.subtype, ctypes[n].subtype),
+ ("for `%s': subtype was `%s'", ctypes[n].value, ct.subtype));
+
+ ONV(ctypes[n].charset && ct.charset == NULL,
+ ("for `%s': charset unset", ctypes[n].value));
+
+ ONV(ctypes[n].charset == NULL && ct.charset != NULL,
+ ("for `%s': unexpected charset `%s'", ctypes[n].value,
+ ct.charset));
+
+ ONV(ctypes[n].charset && ct.charset &&
+ strcmp(ctypes[n].charset, ct.charset),
+ ("for `%s': charset was `%s'", ctypes[n].value, ct.charset));
+
+ NE_FREE(ct.value);
+ }
+
+ return OK;
+}
+
+/* Do ranged GET for range 'start' to 'end'; with 'resp' as response.
+ * If 'fail' is non-NULL, expect ne_get_range to fail, and fail the
+ * test with given message if it doesn't. */
+static int do_range(off_t start, off_t end, const char *fail,
+ char *resp)
+{
+ ne_session *sess;
+ ne_content_range range = {0};
+ int fd, ret;
+
+ CALL(make_session(&sess, single_serve_string, resp));
+
+ range.start = start;
+ range.end = end;
+
+ fd = open("/dev/null", O_WRONLY);
+
+ ret = ne_get_range(sess, "/foo", &range, fd);
+
+ close(fd);
+ CALL(await_server());
+
+ if (fail) {
+#if 0
+ t_warning("error was %s", ne_get_error(sess));
+#endif
+ ONN(fail, ret == NE_OK);
+ } else {
+ ONREQ(ret);
+ }
+
+ ne_session_destroy(sess);
+ return OK;
+}
+
+static int get_range(void)
+{
+ return do_range(1, 10, NULL,
+ "HTTP/1.1 206 Widgets\r\n" "Connection: close\r\n"
+ "Content-Range: bytes 1-10\r\n"
+ "Content-Length: 10\r\n\r\nabcdefghij");
+}
+
+static int fail_range_length(void)
+{
+ return do_range(1, 10, "range response length mismatch should fail",
+ "HTTP/1.1 206 Widgets\r\n" "Connection: close\r\n"
+ "Content-Range: bytes 1-2\r\n"
+ "Content-Length: 2\r\n\r\nab");
+}
+
+static int fail_range_units(void)
+{
+ return do_range(1, 2, "range response units check should fail",
+ "HTTP/1.1 206 Widgets\r\n" "Connection: close\r\n"
+ "Content-Range: fish 1-2\r\n"
+ "Content-Length: 2\r\n\r\nab");
+}
+
+static int fail_range_notrange(void)
+{
+ return do_range(1, 2, "non-ranged response should fail",
+ "HTTP/1.1 200 Widgets\r\n" "Connection: close\r\n"
+ "Content-Range: bytes 1-2\r\n"
+ "Content-Length: 2\r\n\r\nab");
+}
+
+static int fail_range_unsatify(void)
+{
+ return do_range(1, 2, "unsatisfiable range should fail",
+ "HTTP/1.1 416 No Go\r\n" "Connection: close\r\n"
+ "Content-Length: 2\r\n\r\nab");
+}
+
+static int dav_capabilities(void)
+{
+ static const struct {
+ const char *hdrs;
+ unsigned int class1, class2, exec;
+ } caps[] = {
+ { "DAV: 1,2\r\n", 1, 1, 0 },
+ { "DAV: 1 2\r\n", 0, 0, 0 },
+ /* these aren't strictly legal DAV: headers: */
+ { "DAV: 2,1\r\n", 1, 1, 0 },
+ { "DAV: 1, 2 \r\n", 1, 1, 0 },
+ { "DAV: 1\r\nDAV:2\r\n", 1, 1, 0 },
+ { NULL, 0, 0, 0 }
+ };
+ char resp[BUFSIZ];
+ int n;
+
+ for (n = 0; caps[n].hdrs != NULL; n++) {
+ ne_server_capabilities c = {0};
+ ne_session *sess;
+
+ ne_snprintf(resp, BUFSIZ, "HTTP/1.0 200 OK\r\n"
+ "Connection: close\r\n"
+ "%s" "\r\n", caps[n].hdrs);
+
+ CALL(make_session(&sess, single_serve_string, resp));
+
+ ONREQ(ne_options(sess, "/foo", &c));
+
+ ONV(c.dav_class1 != caps[n].class1,
+ ("class1 was %d not %d", c.dav_class1, caps[n].class1));
+ ONV(c.dav_class2 != caps[n].class2,
+ ("class2 was %d not %d", c.dav_class2, caps[n].class2));
+ ONV(c.dav_executable != caps[n].exec,
+ ("class2 was %d not %d", c.dav_executable, caps[n].exec));
+
+ CALL(await_server());
+
+ ne_session_destroy(sess);
+ }
+
+ return OK;
+}
+
+ne_test tests[] = {
+ T(lookup_localhost),
+ T(content_type),
+ T(get_range),
+ T(fail_range_length),
+ T(fail_range_units),
+ T(fail_range_notrange),
+ T(fail_range_unsatify),
+ T(dav_capabilities),
+ T(NULL)
+};
+