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
128struct uph_test {
129    const char *hostinfo;
130    apr_status_t rv;
131    const char *hostname;
132    const char *port_str;
133    apr_port_t port;
134};
135
136struct uph_test uph_tests[] =
137{
138    {
139        "www.ibm.com:443",
140        0, "www.ibm.com", "443", 443
141    },
142    {
143        "[fe80::1]:443",
144        0, "fe80::1", "443", 443
145    },
146    {
147        "127.0.0.1:443",
148        0, "127.0.0.1", "443", 443
149    },
150    {
151        "127.0.0.1",
152        APR_EGENERAL, NULL, NULL, 0
153    },
154    {
155        "[fe80:80",
156        APR_EGENERAL, NULL, NULL, 0
157    },
158    {
159        "fe80::80]:443",
160        APR_EGENERAL, NULL, NULL, 0
161    }
162};
163
164#if 0
165static void show_info(apr_status_t rv, apr_status_t expected, const apr_uri_t *info)
166{
167    if (rv != expected) {
168        fprintf(stderr, "  actual rv: %d    expected rv:  %d\n", rv, expected);
169    }
170    else {
171        fprintf(stderr,
172                "  scheme:           %s\n"
173                "  hostinfo:         %s\n"
174                "  user:             %s\n"
175                "  password:         %s\n"
176                "  hostname:         %s\n"
177                "  port_str:         %s\n"
178                "  path:             %s\n"
179                "  query:            %s\n"
180                "  fragment:         %s\n"
181                "  hostent:          %p\n"
182                "  port:             %u\n"
183                "  is_initialized:   %u\n"
184                "  dns_looked_up:    %u\n"
185                "  dns_resolved:     %u\n",
186                info->scheme, info->hostinfo, info->user, info->password,
187                info->hostname, info->port_str, info->path, info->query,
188                info->fragment, info->hostent, info->port, info->is_initialized,
189                info->dns_looked_up, info->dns_resolved);
190    }
191}
192#endif
193
194static void test_aup(abts_case *tc, void *data)
195{
196    int i;
197    apr_status_t rv;
198    apr_uri_t info;
199    struct aup_test *t;
200    const char *s = NULL;
201
202    for (i = 0; i < sizeof(aup_tests) / sizeof(aup_tests[0]); i++) {
203        char msg[256];
204
205        memset(&info, 0, sizeof(info));
206        t = &aup_tests[i];
207        rv = apr_uri_parse(p, t->uri, &info);
208        apr_snprintf(msg, sizeof msg, "uri '%s': rv=%d not %d", t->uri,
209                     rv, t->rv);
210        ABTS_ASSERT(tc, msg, rv == t->rv);
211        if (t->rv == APR_SUCCESS) {
212            ABTS_STR_EQUAL(tc, t->scheme, info.scheme);
213            ABTS_STR_EQUAL(tc, t->hostinfo, info.hostinfo);
214            ABTS_STR_EQUAL(tc, t->user, info.user);
215            ABTS_STR_EQUAL(tc, t->password, info.password);
216            ABTS_STR_EQUAL(tc, t->hostname, info.hostname);
217            ABTS_STR_EQUAL(tc, t->port_str, info.port_str);
218            ABTS_STR_EQUAL(tc, t->path, info.path);
219            ABTS_STR_EQUAL(tc, t->query, info.query);
220            ABTS_STR_EQUAL(tc, t->user, info.user);
221            ABTS_INT_EQUAL(tc, t->port, info.port);
222
223            s = apr_uri_unparse(p, &info, APR_URI_UNP_REVEALPASSWORD);
224            ABTS_STR_EQUAL(tc, t->uri, s);
225
226            s = apr_uri_unparse(p, &info, APR_URI_UNP_OMITSITEPART);
227            rv = apr_uri_parse(p, s, &info);
228            ABTS_STR_EQUAL(tc, info.scheme, NULL);
229            ABTS_STR_EQUAL(tc, info.hostinfo, NULL);
230            ABTS_STR_EQUAL(tc, info.user, NULL);
231            ABTS_STR_EQUAL(tc, info.password, NULL);
232            ABTS_STR_EQUAL(tc, info.hostname, NULL);
233            ABTS_STR_EQUAL(tc, info.port_str, NULL);
234            ABTS_STR_EQUAL(tc, info.path, t->path);
235            ABTS_STR_EQUAL(tc, info.query, t->query);
236            ABTS_STR_EQUAL(tc, info.user, NULL);
237            ABTS_INT_EQUAL(tc, info.port, 0);
238        }
239    }
240}
241
242static void test_uph(abts_case *tc, void *data)
243{
244    int i;
245    apr_status_t rv;
246    apr_uri_t info;
247    struct uph_test *t;
248
249    for (i = 0; i < sizeof(uph_tests) / sizeof(uph_tests[0]); i++) {
250        memset(&info, 0, sizeof(info));
251        t = &uph_tests[i];
252        rv = apr_uri_parse_hostinfo(p, t->hostinfo, &info);
253        ABTS_INT_EQUAL(tc, t->rv, rv);
254        if (t->rv == APR_SUCCESS) {
255            ABTS_STR_EQUAL(tc, t->hostname, info.hostname);
256            ABTS_STR_EQUAL(tc, t->port_str, info.port_str);
257            ABTS_INT_EQUAL(tc, t->port, info.port);
258        }
259    }
260}
261
262abts_suite *testuri(abts_suite *suite)
263{
264    suite = ADD_SUITE(suite);
265
266    abts_run_test(suite, test_aup, NULL);
267    abts_run_test(suite, test_uph, NULL);
268
269    return suite;
270}
271
272