4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
26 /* $Id: uri.c 146 2006-03-24 00:26:54Z njacobs $ */
34 #include <sys/types.h>
39 * This will handle the following forms:
41 * scheme://[[user[:password]@]host[:port]]/path[[#fragment]|[?query]]
44 uri_from_string(char *string
, uri_t
**uri
)
49 if ((string
== NULL
) || (uri
== NULL
)) {
54 /* find the scheme:scheme_part split */
55 if ((ptr
= strchr(string
, ':')) == NULL
) {
60 if ((*uri
= u
= calloc(1, sizeof (*u
))) == NULL
)
63 u
->scheme
= strndup(string
, ptr
- string
);
65 if ((ptr
[1] == '/') && (ptr
[2] == '/')) {
68 * scheme://[host_part]/[path_part]
70 char *end
= NULL
, *user
= NULL
, *host
= NULL
, *path
= NULL
;
72 string
= ptr
+ 3; /* skip the :// */
74 if ((path
= end
= strchr(string
, '/')) == NULL
)
75 for (end
= string
; *end
!= '\0'; end
++)
78 u
->host_part
= strndup(string
, end
- string
);
80 for (host
= string
; host
< end
; host
++)
82 /* string to host is the user part */
83 u
->user_part
= strndup(string
, host
-string
);
84 /* host+1 to end is the host part */
85 u
->host_part
= strndup(host
+ 1,
93 char *password
= NULL
;
95 for (password
= user
; (password
< host
- 1); password
++)
96 if (*password
== ':') {
97 u
->password
= strndup(password
+ 1,
101 u
->user
= strndup(user
, password
- user
);
108 for (port
= host
; (port
< path
); port
++)
109 if ((*port
== ':') || (*port
== '/'))
113 u
->port
= strndup(port
+ 1, path
- port
- 1);
116 u
->host
= strndup(host
, port
- host
);
120 char *name
= strrchr(path
, '/');
122 u
->path_part
= strdup(path
);
125 char *query
, *fragment
;
127 query
= strrchr(name
, '?');
128 if ((query
!= NULL
) && (*query
!= '\0')) {
129 u
->query
= strdup(query
+ 1);
132 for (end
= path
; *end
!= '\0'; end
++)
136 fragment
= strrchr(name
, '#');
137 if ((fragment
!= NULL
) && (*fragment
!= '\0')) {
138 u
->fragment
= strndup(fragment
+ 1,
143 u
->path
= strndup(path
, end
- path
);
146 } else { /* scheme:scheme_part */
147 u
->scheme_part
= strdup(&ptr
[1]);
150 if ((u
->host_part
== NULL
) && (u
->path_part
== NULL
) &&
151 (u
->scheme_part
== NULL
)) {
162 uri_to_string(uri_t
*uri
, char *buffer
, size_t buflen
)
166 if ((uri
== NULL
) || (buffer
== NULL
) || (buflen
== 0) ||
167 (uri
->scheme
== NULL
) ||
168 ((uri
->password
!= NULL
) && (uri
->user
== NULL
)) ||
169 ((uri
->user
!= NULL
) && (uri
->host
== NULL
)) ||
170 ((uri
->port
!= NULL
) && (uri
->host
== NULL
)) ||
171 ((uri
->fragment
!= NULL
) && (uri
->path
== NULL
)) ||
172 ((uri
->query
!= NULL
) && (uri
->path
== NULL
))) {
176 if (uri
->path
== NULL
|| uri
->path
[0] == '/')
181 (void) memset(buffer
, 0, buflen
);
183 if (uri
->scheme_part
== NULL
) {
184 (void) snprintf(buffer
, buflen
,
185 "%s://%s%s%s%s%s%s%s%s%s%s%s%s%s",
187 (uri
->user
? uri
->user
: ""),
188 (uri
->password
? ":" : ""),
189 (uri
->password
? uri
->password
: ""),
190 (uri
->user
? "@": ""),
191 (uri
->host
? uri
->host
: ""),
192 (uri
->port
? ":" : ""),
193 (uri
->port
? uri
->port
: ""),
195 (uri
->path
? uri
->path
: ""),
196 (uri
->fragment
? "#" : ""),
197 (uri
->fragment
? uri
->fragment
: ""),
198 (uri
->query
? "?" : ""),
199 (uri
->query
? uri
->query
: ""));
201 (void) snprintf(buffer
, buflen
, "%s:%s", uri
->scheme
,
212 if (uri
->scheme
!= NULL
)
214 if (uri
->scheme_part
!= NULL
)
215 free(uri
->scheme_part
);
216 if (uri
->user
!= NULL
)
218 if (uri
->password
!= NULL
)
220 if (uri
->host
!= NULL
)
222 if (uri
->port
!= NULL
)
224 if (uri
->path
!= NULL
)
226 if (uri
->fragment
!= NULL
)
228 if (uri
->query
!= NULL
)
231 if (uri
->user_part
!= NULL
)
232 free(uri
->user_part
);
233 if (uri
->host_part
!= NULL
)
234 free(uri
->host_part
);
235 if (uri
->path_part
!= NULL
)
236 free(uri
->path_part
);
243 uri_dump(FILE *fp
, uri_t
*uri
)
246 fprintf(fp
, "URI:\n");
247 if (uri
->scheme
!= NULL
)
248 fprintf(fp
, "scheme: %s\n", uri
->scheme
);
249 if (uri
->scheme_part
!= NULL
)
250 fprintf(fp
, "scheme_part: %s\n", uri
->scheme_part
);
251 if (uri
->user
!= NULL
)
252 fprintf(fp
, "user: %s\n", uri
->user
);
253 if (uri
->password
!= NULL
)
254 fprintf(fp
, "password: %s\n", uri
->password
);
255 if (uri
->host
!= NULL
)
256 fprintf(fp
, "host: %s\n", uri
->host
);
257 if (uri
->port
!= NULL
)
258 fprintf(fp
, "port: %s\n", uri
->port
);
259 if (uri
->path
!= NULL
)
260 fprintf(fp
, "path: %s\n", uri
->path
);
261 if (uri
->fragment
!= NULL
)
262 fprintf(fp
, "fragment: %s\n", uri
->fragment
);
263 if (uri
->query
!= NULL
)
264 fprintf(fp
, "query: %s\n", uri
->query
);
266 if (uri
->user_part
!= NULL
)
267 fprintf(fp
, "user_part: %s\n", uri
->user_part
);
268 if (uri
->host_part
!= NULL
)
269 fprintf(fp
, "host_part: %s\n", uri
->host_part
);
270 if (uri
->path_part
!= NULL
)
271 fprintf(fp
, "path_part: %s\n", uri
->path_part
);
277 main(int argc
, char *argv
[])
282 fprintf(stderr
, "Usage: %s uri\n", argv
[0]);
286 if (uri_from_string(argv
[1], &u
) == 0) {
290 uri_to_string(u
, buf
, sizeof (buf
));
291 fprintf(stdout
, "reconstituted: %s\n", buf
);
293 uri_to_string(u
, buf
, 12);
294 fprintf(stdout
, "reconstituted(12): %s\n", buf
);
296 printf(" failed for %s (%s)\n", argv
[1], strerror(errno
));
300 #endif /* DEADBEEF */