Blame


1 92e07b23 2022-12-25 op /*
2 92e07b23 2022-12-25 op * Copyright (c) 2022 Omar Polo <op@omarpolo.com>
3 92e07b23 2022-12-25 op *
4 92e07b23 2022-12-25 op * Permission to use, copy, modify, and distribute this software for any
5 92e07b23 2022-12-25 op * purpose with or without fee is hereby granted, provided that the above
6 92e07b23 2022-12-25 op * copyright notice and this permission notice appear in all copies.
7 92e07b23 2022-12-25 op *
8 92e07b23 2022-12-25 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 92e07b23 2022-12-25 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 92e07b23 2022-12-25 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 92e07b23 2022-12-25 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 92e07b23 2022-12-25 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 92e07b23 2022-12-25 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 92e07b23 2022-12-25 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 92e07b23 2022-12-25 op */
16 92e07b23 2022-12-25 op
17 92e07b23 2022-12-25 op #include <err.h>
18 92e07b23 2022-12-25 op #include <errno.h>
19 92e07b23 2022-12-25 op #include <stdio.h>
20 92e07b23 2022-12-25 op #include <string.h>
21 92e07b23 2022-12-25 op
22 92e07b23 2022-12-25 op #include "iri.h"
23 92e07b23 2022-12-25 op
24 92e07b23 2022-12-25 op static int
25 5cc70f14 2022-12-26 op resolve(const char *base, const char *ref, const char *expected)
26 92e07b23 2022-12-25 op {
27 92e07b23 2022-12-25 op static struct iri i;
28 92e07b23 2022-12-25 op char buf[512];
29 92e07b23 2022-12-25 op
30 92e07b23 2022-12-25 op if (iri_parse(base, ref, &i) == -1) {
31 3f2ab305 2022-12-26 op fprintf(stderr, "FAIL resolve(\"%s\", \"%s\") %s\n", base, ref,
32 92e07b23 2022-12-25 op strerror(errno));
33 92e07b23 2022-12-25 op return (1);
34 92e07b23 2022-12-25 op }
35 92e07b23 2022-12-25 op
36 92e07b23 2022-12-25 op if (iri_unparse(&i, buf, sizeof(buf)) == -1) {
37 3f2ab305 2022-12-26 op fprintf(stderr, "FAIL resolve(\"%s\", \"%s\") %s\n", base, ref,
38 92e07b23 2022-12-25 op strerror(errno));
39 92e07b23 2022-12-25 op return (1);
40 92e07b23 2022-12-25 op }
41 92e07b23 2022-12-25 op
42 92e07b23 2022-12-25 op if (strcmp(buf, expected) != 0) {
43 3f2ab305 2022-12-26 op fprintf(stderr, "FAIL resolve(\"%s\", \"%s\")\n", base, ref);
44 92e07b23 2022-12-25 op fprintf(stderr, "got:\t%s\n", buf);
45 92e07b23 2022-12-25 op fprintf(stderr, "want:\t%s\n", expected);
46 92e07b23 2022-12-25 op return (1);
47 92e07b23 2022-12-25 op }
48 92e07b23 2022-12-25 op
49 3f2ab305 2022-12-26 op fprintf(stderr, "OK resolve(\"%s\", \"%s\") -> %s\n", base, ref,
50 3f2ab305 2022-12-26 op expected);
51 92e07b23 2022-12-25 op return (0);
52 92e07b23 2022-12-25 op }
53 92e07b23 2022-12-25 op
54 92e07b23 2022-12-25 op int
55 92e07b23 2022-12-25 op main(void)
56 92e07b23 2022-12-25 op {
57 92e07b23 2022-12-25 op const char *base = "http://a/b/c/d;p?q";
58 92e07b23 2022-12-25 op int ret = 0;
59 92e07b23 2022-12-25 op
60 5cc70f14 2022-12-26 op ret |= resolve(base, "g:h", "g:h");
61 5cc70f14 2022-12-26 op ret |= resolve(base, "g", "http://a/b/c/g");
62 5cc70f14 2022-12-26 op ret |= resolve(base, "./g", "http://a/b/c/g");
63 5cc70f14 2022-12-26 op ret |= resolve(base, "g/", "http://a/b/c/g/");
64 5cc70f14 2022-12-26 op ret |= resolve(base, "/g", "http://a/g");
65 92e07b23 2022-12-25 op
66 92e07b23 2022-12-25 op /*
67 92e07b23 2022-12-25 op * the RFC says "http://g" but we always normalize an
68 92e07b23 2022-12-25 op * empty path to "/" if there is an authority.
69 92e07b23 2022-12-25 op */
70 5cc70f14 2022-12-26 op ret |= resolve(base, "//g", "http://g/");
71 92e07b23 2022-12-25 op
72 5cc70f14 2022-12-26 op ret |= resolve(base, "?y", "http://a/b/c/d;p?y");
73 5cc70f14 2022-12-26 op ret |= resolve(base, "g?y", "http://a/b/c/g?y");
74 5cc70f14 2022-12-26 op ret |= resolve(base, "#s", "http://a/b/c/d;p?q#s");
75 5cc70f14 2022-12-26 op ret |= resolve(base, "g#s", "http://a/b/c/g#s");
76 5cc70f14 2022-12-26 op ret |= resolve(base, "g?y#s", "http://a/b/c/g?y#s");
77 5cc70f14 2022-12-26 op ret |= resolve(base, ";x", "http://a/b/c/;x");
78 5cc70f14 2022-12-26 op ret |= resolve(base, "g;x", "http://a/b/c/g;x");
79 5cc70f14 2022-12-26 op ret |= resolve(base, "g;x?y#s", "http://a/b/c/g;x?y#s");
80 5cc70f14 2022-12-26 op ret |= resolve(base, "", "http://a/b/c/d;p?q");
81 5cc70f14 2022-12-26 op ret |= resolve(base, ".", "http://a/b/c/");
82 5cc70f14 2022-12-26 op ret |= resolve(base, "./", "http://a/b/c/");
83 5cc70f14 2022-12-26 op ret |= resolve(base, "..", "http://a/b/");
84 5cc70f14 2022-12-26 op ret |= resolve(base, "../", "http://a/b/");
85 5cc70f14 2022-12-26 op ret |= resolve(base, "../g", "http://a/b/g");
86 5cc70f14 2022-12-26 op ret |= resolve(base, "../..", "http://a/");
87 5cc70f14 2022-12-26 op ret |= resolve(base, "../../", "http://a/");
88 5cc70f14 2022-12-26 op ret |= resolve(base, "../../g", "http://a/g");
89 92e07b23 2022-12-25 op
90 5cc70f14 2022-12-26 op ret |= resolve(base, "../../../g", "http://a/g");
91 5cc70f14 2022-12-26 op ret |= resolve(base, "../../../../g", "http://a/g");
92 5cc70f14 2022-12-26 op ret |= resolve(base, "/./g", "http://a/g");
93 5cc70f14 2022-12-26 op ret |= resolve(base, "/../g", "http://a/g");
94 5cc70f14 2022-12-26 op ret |= resolve(base, "g.", "http://a/b/c/g.");
95 5cc70f14 2022-12-26 op ret |= resolve(base, ".g", "http://a/b/c/.g");
96 5cc70f14 2022-12-26 op ret |= resolve(base, "g..", "http://a/b/c/g..");
97 5cc70f14 2022-12-26 op ret |= resolve(base, "..g", "http://a/b/c/..g");
98 92e07b23 2022-12-25 op
99 5cc70f14 2022-12-26 op ret |= resolve(base, "./../g", "http://a/b/g");
100 5cc70f14 2022-12-26 op ret |= resolve(base, "./g/.", "http://a/b/c/g/");
101 5cc70f14 2022-12-26 op ret |= resolve(base, "g/./h", "http://a/b/c/g/h");
102 5cc70f14 2022-12-26 op ret |= resolve(base, "g/../h", "http://a/b/c/h");
103 5cc70f14 2022-12-26 op ret |= resolve(base, "g;x=1/./y", "http://a/b/c/g;x=1/y");
104 5cc70f14 2022-12-26 op ret |= resolve(base, "g;x=1/../y", "http://a/b/c/y");
105 92e07b23 2022-12-25 op
106 5cc70f14 2022-12-26 op ret |= resolve(base, "g?y/./x", "http://a/b/c/g?y/./x");
107 5cc70f14 2022-12-26 op ret |= resolve(base, "g?y/../x", "http://a/b/c/g?y/../x");
108 5cc70f14 2022-12-26 op ret |= resolve(base, "g#s/./x", "http://a/b/c/g#s/./x");
109 5cc70f14 2022-12-26 op ret |= resolve(base, "g#s/../x", "http://a/b/c/g#s/../x");
110 92e07b23 2022-12-25 op
111 5cc70f14 2022-12-26 op ret |= resolve(base, "http:g", "http:g");
112 92e07b23 2022-12-25 op
113 92e07b23 2022-12-25 op return (ret);
114 92e07b23 2022-12-25 op }