Imported Debian version 2.4.3~trusty1
[deb_ffmpeg.git] / ffmpeg / libavformat / url.c
CommitLineData
2ba45a60
DM
1/*
2 * URL utility functions
3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
4 *
5 * This file is part of FFmpeg.
6 *
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.
11 *
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.
16 *
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
20 */
21
22
23#include "avformat.h"
24#include "config.h"
25#include "url.h"
26#if CONFIG_NETWORK
27#include "network.h"
28#endif
29#include "libavutil/avstring.h"
30
31/**
32 * @file
33 * URL utility functions.
34 */
35
36int ff_url_join(char *str, int size, const char *proto,
37 const char *authorization, const char *hostname,
38 int port, const char *fmt, ...)
39{
40#if CONFIG_NETWORK
41 struct addrinfo hints = { 0 }, *ai;
42#endif
43
44 str[0] = '\0';
45 if (proto)
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);
58 } else {
59 av_strlcat(str, hostname, size);
60 }
61 freeaddrinfo(ai);
62 } else
63#endif
64 /* Not an IPv6 address, just output the plain string. */
65 av_strlcat(str, hostname, size);
66
67 if (port >= 0)
68 av_strlcatf(str, size, ":%d", port);
69 if (fmt) {
70 va_list vl;
71 int len = strlen(str);
72
73 va_start(vl, fmt);
74 vsnprintf(str + len, size > len ? size - len : 0, fmt, vl);
75 va_end(vl);
76 }
77 return strlen(str);
78}
79
80void ff_make_absolute_url(char *buf, int size, const char *base,
81 const char *rel)
82{
83 char *sep, *path_query;
84 /* Absolute path, relative to the current server */
85 if (base && strstr(base, "://") && rel[0] == '/') {
86 if (base != buf)
87 av_strlcpy(buf, base, size);
88 sep = strstr(buf, "://");
89 if (sep) {
90 /* Take scheme from base url */
91 if (rel[1] == '/') {
92 sep[1] = '\0';
93 } else {
94 /* Take scheme and host from base url */
95 sep += 3;
96 sep = strchr(sep, '/');
97 if (sep)
98 *sep = '\0';
99 }
100 }
101 av_strlcat(buf, rel, size);
102 return;
103 }
104 /* If rel actually is an absolute url, just copy it */
105 if (!base || strstr(rel, "://") || rel[0] == '/') {
106 av_strlcpy(buf, rel, size);
107 return;
108 }
109 if (base != buf)
110 av_strlcpy(buf, base, size);
111
112 /* Strip off any query string from base */
113 path_query = strchr(buf, '?');
114 if (path_query)
115 *path_query = '\0';
116
117 /* Is relative path just a new query part? */
118 if (rel[0] == '?') {
119 av_strlcat(buf, rel, size);
120 return;
121 }
122
123 /* Remove the file name from the base url */
124 sep = strrchr(buf, '/');
125 if (sep)
126 sep[1] = '\0';
127 else
128 buf[0] = '\0';
129 while (av_strstart(rel, "../", NULL) && sep) {
130 /* Remove the path delimiter at the end */
131 sep[0] = '\0';
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);
137 break;
138 }
139 /* Cut off the directory name */
140 if (sep)
141 sep[1] = '\0';
142 else
143 buf[0] = '\0';
144 rel += 3;
145 }
146 av_strlcat(buf, rel, size);
147}