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, '?');
114 if (path_query != NULL)
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);