1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements.  See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License.  You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <stdio.h>
18#include <stdlib.h>
19
20#include "testutil.h"
21#include "apr_general.h"
22#include "apr_strings.h"
23#include "apr_uri.h"
24
25struct aup_test {
26    const char *uri;
27    apr_status_t rv;
28    const char *scheme;
29    const char *hostinfo;
30    const char *user;
31    const char *password;
32    const char *hostname;
33    const char *port_str;
34    const char *path;
35    const char *query;
36    const char *fragment;
37    apr_port_t  port;
38};
39
40struct aup_test aup_tests[] =
41{
42    { "http://[/::1]/index.html", APR_EGENERAL },
43    { "http://[", APR_EGENERAL },
44    { "http://[?::1]/index.html", APR_EGENERAL },
45
46    {
47        "http://127.0.0.1:9999/asdf.html",
48        0, "http", "127.0.0.1:9999", NULL, NULL, "127.0.0.1", "9999", "/asdf.html", NULL, NULL, 9999
49    },
50    {
51        "http://127.0.0.1:9999a/asdf.html",
52        APR_EGENERAL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0
53    },
54    {
55        "http://[::127.0.0.1]:9999/asdf.html",
56        0, "http", "[::127.0.0.1]:9999", NULL, NULL, "::127.0.0.1", "9999", "/asdf.html", NULL, NULL, 9999
57    },
58    {
59        "http://[::127.0.0.1]:9999a/asdf.html",
60        APR_EGENERAL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0
61    },
62    {
63        "/error/include/top.html",
64        0, NULL, NULL, NULL, NULL, NULL, NULL, "/error/include/top.html", NULL, NULL, 0
65    },
66    {
67        "/error/include/../contact.html.var",
68        0, NULL, NULL, NULL, NULL, NULL, NULL, "/error/include/../contact.html.var", NULL, NULL, 0
69    },
70    {
71        "/",
72        0, NULL, NULL, NULL, NULL, NULL, NULL, "/", NULL, NULL, 0
73    },
74    {
75        "/manual/",
76        0, NULL, NULL, NULL, NULL, NULL, NULL, "/manual/", NULL, NULL, 0
77    },
78    {
79        "/cocoon/developing/graphics/Using%20Databases-label_over.jpg",
80        0, NULL, NULL, NULL, NULL, NULL, NULL, "/cocoon/developing/graphics/Using%20Databases-label_over.jpg", NULL, NULL, 0
81    },
82    {
83        "http://sonyamt:garbage@127.0.0.1/filespace/",
84        0, "http", "sonyamt:garbage@127.0.0.1", "sonyamt", "garbage", "127.0.0.1", NULL, "/filespace/", NULL, NULL, 0
85    },
86    {
87        "http://sonyamt:garbage@[fe80::1]/filespace/",
88        0, "http", "sonyamt:garbage@[fe80::1]", "sonyamt", "garbage", "fe80::1", NULL, "/filespace/", NULL, NULL, 0
89    },
90    {
91        "http://sonyamt@[fe80::1]/filespace/?arg1=store",
92        0, "http", "sonyamt@[fe80::1]", "sonyamt", NULL, "fe80::1", NULL, "/filespace/", "arg1=store", NULL, 0
93    },
94    {
95        "http://localhost",
96        0, "http", "localhost", NULL, NULL, "localhost", NULL, NULL, NULL, NULL, 0
97    },
98    {
99        "//www.apache.org/",
100        0, NULL, "www.apache.org", NULL, NULL, "www.apache.org", NULL, "/", NULL, NULL, 0
101    },
102    {
103        "file:image.jpg",
104        0, "file", NULL, NULL, NULL, NULL, NULL, "image.jpg", NULL, NULL, 0
105    },
106    {
107        "file:/image.jpg",
108        0, "file", NULL, NULL, NULL, NULL, NULL, "/image.jpg", NULL, NULL, 0
109    },
110    {
111        "file:///image.jpg",
112        0, "file", "", NULL, NULL, "", NULL, "/image.jpg", NULL, NULL, 0
113    },
114    {
115        "file:///tmp/photos/image.jpg",
116        0, "file", "", NULL, NULL, "", NULL, "/tmp/photos/image.jpg", NULL, NULL, 0
117    },
118    {
119        "file:./image.jpg",
120        0, "file", NULL, NULL, NULL, NULL, NULL, "./image.jpg", NULL, NULL, 0
121    },
122    {
123        "file:../photos/image.jpg",
124        0, "file", NULL, NULL, NULL, NULL, NULL, "../photos/image.jpg", NULL, NULL, 0
125    },
126    {
127        "file+ssh-2:../photos/image.jpg",
128        0, "file+ssh-2", NULL, NULL, NULL, NULL, NULL, "../photos/image.jpg", NULL, NULL, 0
129    },
130    {
131        "script/foo.js",
132        0, NULL, NULL, NULL, NULL, NULL, NULL, "script/foo.js", NULL, NULL, 0
133    },
134    {
135        "../foo2.js",
136        0, NULL, NULL, NULL, NULL, NULL, NULL, "../foo2.js", NULL, NULL, 0
137    },
138    {
139        "foo3.js",
140        0, NULL, NULL, NULL, NULL, NULL, NULL, "foo3.js", NULL, NULL, 0
141    },
142    {
143        "_foo/bar",
144        0, NULL, NULL, NULL, NULL, NULL, NULL, "_foo/bar", NULL, NULL, 0
145    },
146    {
147        "_foo:/bar",
148        APR_EGENERAL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0
149    },
150    {
151        "2foo:/bar",
152        APR_EGENERAL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0
153    },
154    {
155        ".foo:/bar",
156        APR_EGENERAL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0
157    },
158    {
159        "-foo:/bar",
160        APR_EGENERAL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0
161    },
162    {
163        "+foo:/bar",
164        APR_EGENERAL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0
165    },
166    {
167        "::/bar",
168        APR_EGENERAL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0
169    },
170    {
171        ":/bar",
172        APR_EGENERAL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0
173    },
174    {
175        ":foo",
176        APR_EGENERAL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0
177    },
178    {
179        ":",
180        APR_EGENERAL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0
181    },
182    {
183        "@localhost::8080",
184        APR_EGENERAL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0
185    },
186};
187
188struct uph_test {
189    const char *hostinfo;
190    apr_status_t rv;
191    const char *hostname;
192    const char *port_str;
193    apr_port_t port;
194};
195
196struct uph_test uph_tests[] =
197{
198    {
199        "www.ibm.com:443",
200        0, "www.ibm.com", "443", 443
201    },
202    {
203        "[fe80::1]:443",
204        0, "fe80::1", "443", 443
205    },
206    {
207        "127.0.0.1:443",
208        0, "127.0.0.1", "443", 443
209    },
210    {
211        "127.0.0.1",
212        APR_EGENERAL, NULL, NULL, 0
213    },
214    {
215        "[fe80:80",
216        APR_EGENERAL, NULL, NULL, 0
217    },
218    {
219        "fe80::80]:443",
220        APR_EGENERAL, NULL, NULL, 0
221    }
222};
223
224#if 0
225static void show_info(apr_status_t rv, apr_status_t expected, const apr_uri_t *info)
226{
227    if (rv != expected) {
228        fprintf(stderr, "  actual rv: %d    expected rv:  %d\n", rv, expected);
229    }
230    else {
231        fprintf(stderr,
232                "  scheme:           %s\n"
233                "  hostinfo:         %s\n"
234                "  user:             %s\n"
235                "  password:         %s\n"
236                "  hostname:         %s\n"
237                "  port_str:         %s\n"
238                "  path:             %s\n"
239                "  query:            %s\n"
240                "  fragment:         %s\n"
241                "  hostent:          %p\n"
242                "  port:             %u\n"
243                "  is_initialized:   %u\n"
244                "  dns_looked_up:    %u\n"
245                "  dns_resolved:     %u\n",
246                info->scheme, info->hostinfo, info->user, info->password,
247                info->hostname, info->port_str, info->path, info->query,
248                info->fragment, info->hostent, info->port, info->is_initialized,
249                info->dns_looked_up, info->dns_resolved);
250    }
251}
252#endif
253
254static void test_aup(abts_case *tc, void *data)
255{
256    int i;
257    apr_status_t rv;
258    apr_uri_t info;
259    struct aup_test *t;
260    const char *s = NULL;
261
262    for (i = 0; i < sizeof(aup_tests) / sizeof(aup_tests[0]); i++) {
263        char msg[256];
264
265        memset(&info, 0, sizeof(info));
266        t = &aup_tests[i];
267        rv = apr_uri_parse(p, t->uri, &info);
268        apr_snprintf(msg, sizeof msg, "uri '%s': rv=%d not %d", t->uri,
269                     rv, t->rv);
270        ABTS_ASSERT(tc, msg, rv == t->rv);
271        if (t->rv == APR_SUCCESS) {
272            ABTS_STR_EQUAL(tc, t->scheme, info.scheme);
273            ABTS_STR_EQUAL(tc, t->hostinfo, info.hostinfo);
274            ABTS_STR_EQUAL(tc, t->user, info.user);
275            ABTS_STR_EQUAL(tc, t->password, info.password);
276            ABTS_STR_EQUAL(tc, t->hostname, info.hostname);
277            ABTS_STR_EQUAL(tc, t->port_str, info.port_str);
278            ABTS_STR_EQUAL(tc, t->path, info.path);
279            ABTS_STR_EQUAL(tc, t->query, info.query);
280            ABTS_STR_EQUAL(tc, t->user, info.user);
281            ABTS_INT_EQUAL(tc, t->port, info.port);
282
283            s = apr_uri_unparse(p, &info, APR_URI_UNP_REVEALPASSWORD);
284            ABTS_STR_EQUAL(tc, t->uri, s);
285
286            s = apr_uri_unparse(p, &info, APR_URI_UNP_OMITSITEPART);
287            rv = apr_uri_parse(p, s, &info);
288            ABTS_STR_EQUAL(tc, info.scheme, NULL);
289            ABTS_STR_EQUAL(tc, info.hostinfo, NULL);
290            ABTS_STR_EQUAL(tc, info.user, NULL);
291            ABTS_STR_EQUAL(tc, info.password, NULL);
292            ABTS_STR_EQUAL(tc, info.hostname, NULL);
293            ABTS_STR_EQUAL(tc, info.port_str, NULL);
294            ABTS_STR_EQUAL(tc, info.path, t->path);
295            ABTS_STR_EQUAL(tc, info.query, t->query);
296            ABTS_STR_EQUAL(tc, info.user, NULL);
297            ABTS_INT_EQUAL(tc, info.port, 0);
298        }
299    }
300}
301
302static void test_uph(abts_case *tc, void *data)
303{
304    int i;
305    apr_status_t rv;
306    apr_uri_t info;
307    struct uph_test *t;
308
309    for (i = 0; i < sizeof(uph_tests) / sizeof(uph_tests[0]); i++) {
310        memset(&info, 0, sizeof(info));
311        t = &uph_tests[i];
312        rv = apr_uri_parse_hostinfo(p, t->hostinfo, &info);
313        ABTS_INT_EQUAL(tc, t->rv, rv);
314        if (t->rv == APR_SUCCESS) {
315            ABTS_STR_EQUAL(tc, t->hostname, info.hostname);
316            ABTS_STR_EQUAL(tc, t->port_str, info.port_str);
317            ABTS_INT_EQUAL(tc, t->port, info.port);
318        }
319    }
320}
321
322abts_suite *testuri(abts_suite *suite)
323{
324    suite = ADD_SUITE(suite);
325
326    abts_run_test(suite, test_aup, NULL);
327    abts_run_test(suite, test_uph, NULL);
328
329    return suite;
330}
331
332