2 * URL utility functions
3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29 #include "libavutil/avstring.h"
33 * URL utility functions.
36 int ff_url_join(char *str
, int size
, const char *proto
,
37 const char *authorization
, const char *hostname
,
38 int port
, const char *fmt
, ...)
41 struct addrinfo hints
= { 0 }, *ai
;
46 av_strlcatf(str
, size
, "%s://", proto
);
47 if (authorization
&& authorization
[0])
48 av_strlcatf(str
, size
, "%s@", authorization
);
49 #if CONFIG_NETWORK && defined(AF_INET6)
50 /* Determine if hostname is a numerical IPv6 address,
51 * properly escape it within [] in that case. */
52 hints
.ai_flags
= AI_NUMERICHOST
;
53 if (!getaddrinfo(hostname
, NULL
, &hints
, &ai
)) {
54 if (ai
->ai_family
== AF_INET6
) {
55 av_strlcat(str
, "[", size
);
56 av_strlcat(str
, hostname
, size
);
57 av_strlcat(str
, "]", size
);
59 av_strlcat(str
, hostname
, size
);
64 /* Not an IPv6 address, just output the plain string. */
65 av_strlcat(str
, hostname
, size
);
68 av_strlcatf(str
, size
, ":%d", port
);
71 int len
= strlen(str
);
74 vsnprintf(str
+ len
, size
> len
? size
- len
: 0, fmt
, vl
);
80 void ff_make_absolute_url(char *buf
, int size
, const char *base
,
83 char *sep
, *path_query
;
84 /* Absolute path, relative to the current server */
85 if (base
&& strstr(base
, "://") && rel
[0] == '/') {
87 av_strlcpy(buf
, base
, size
);
88 sep
= strstr(buf
, "://");
90 /* Take scheme from base url */
94 /* Take scheme and host from base url */
96 sep
= strchr(sep
, '/');
101 av_strlcat(buf
, rel
, size
);
104 /* If rel actually is an absolute url, just copy it */
105 if (!base
|| strstr(rel
, "://") || rel
[0] == '/') {
106 av_strlcpy(buf
, rel
, size
);
110 av_strlcpy(buf
, base
, size
);
112 /* Strip off any query string from base */
113 path_query
= strchr(buf
, '?');
117 /* Is relative path just a new query part? */
119 av_strlcat(buf
, rel
, size
);
123 /* Remove the file name from the base url */
124 sep
= strrchr(buf
, '/');
129 while (av_strstart(rel
, "../", NULL
) && sep
) {
130 /* Remove the path delimiter at the end */
132 sep
= strrchr(buf
, '/');
133 /* If the next directory name to pop off is "..", break here */
134 if (!strcmp(sep
? &sep
[1] : buf
, "..")) {
135 /* Readd the slash we just removed */
136 av_strlcat(buf
, "/", size
);
139 /* Cut off the directory name */
146 av_strlcat(buf
, rel
, size
);