@@ -20,6 +20,7 @@ OBJS = allformats.o \ | |||
riff.o \ | |||
sdp.o \ | |||
seek.o \ | |||
url.o \ | |||
utils.o \ | |||
OBJS-$(CONFIG_NETWORK) += network.o | |||
@@ -90,31 +90,6 @@ void ff_read_frame_flush(AVFormatContext *s); | |||
/** Get the current time since NTP epoch in microseconds. */ | |||
uint64_t ff_ntp_time(void); | |||
/** | |||
* Assemble a URL string from components. This is the reverse operation | |||
* of av_url_split. | |||
* | |||
* Note, this requires networking to be initialized, so the caller must | |||
* ensure ff_network_init has been called. | |||
* | |||
* @see av_url_split | |||
* | |||
* @param str the buffer to fill with the url | |||
* @param size the size of the str buffer | |||
* @param proto the protocol identifier, if null, the separator | |||
* after the identifier is left out, too | |||
* @param authorization an optional authorization string, may be null. | |||
* An empty string is treated the same as a null string. | |||
* @param hostname the host name string | |||
* @param port the port number, left out from the string if negative | |||
* @param fmt a generic format string for everything to add after the | |||
* host/port, may be null | |||
* @return the number of characters written to the destination buffer | |||
*/ | |||
int ff_url_join(char *str, int size, const char *proto, | |||
const char *authorization, const char *hostname, | |||
int port, const char *fmt, ...) av_printf_format(7, 8); | |||
/** | |||
* Append the media-specific SDP fragment for the media stream c | |||
* to the buffer buff. | |||
@@ -241,17 +216,6 @@ AVChapter *avpriv_new_chapter(AVFormatContext *s, int id, AVRational time_base, | |||
*/ | |||
void ff_reduce_index(AVFormatContext *s, int stream_index); | |||
/* | |||
* Convert a relative url into an absolute url, given a base url. | |||
* | |||
* @param buf the buffer where output absolute url is written | |||
* @param size the size of buf | |||
* @param base the base url, may be equal to buf. | |||
* @param rel the new url, which is interpreted relative to base | |||
*/ | |||
void ff_make_absolute_url(char *buf, int size, const char *base, | |||
const char *rel); | |||
enum AVCodecID ff_guess_image2_codec(const char *filename); | |||
/** | |||
@@ -18,7 +18,7 @@ | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
*/ | |||
#include "internal.h" | |||
#include "url.h" | |||
static void test(const char *base, const char *rel) | |||
{ | |||
@@ -0,0 +1,147 @@ | |||
/* | |||
* URL utility functions | |||
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard | |||
* | |||
* This file is part of Libav. | |||
* | |||
* Libav is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 2.1 of the License, or (at your option) any later version. | |||
* | |||
* Libav is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public | |||
* License along with Libav; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
*/ | |||
#include "avformat.h" | |||
#include "config.h" | |||
#include "url.h" | |||
#if CONFIG_NETWORK | |||
#include "network.h" | |||
#endif | |||
#include "libavutil/avstring.h" | |||
/** | |||
* @file | |||
* URL utility functions. | |||
*/ | |||
int ff_url_join(char *str, int size, const char *proto, | |||
const char *authorization, const char *hostname, | |||
int port, const char *fmt, ...) | |||
{ | |||
#if CONFIG_NETWORK | |||
struct addrinfo hints = { 0 }, *ai; | |||
#endif | |||
str[0] = '\0'; | |||
if (proto) | |||
av_strlcatf(str, size, "%s://", proto); | |||
if (authorization && authorization[0]) | |||
av_strlcatf(str, size, "%s@", authorization); | |||
#if CONFIG_NETWORK && defined(AF_INET6) | |||
/* Determine if hostname is a numerical IPv6 address, | |||
* properly escape it within [] in that case. */ | |||
hints.ai_flags = AI_NUMERICHOST; | |||
if (!getaddrinfo(hostname, NULL, &hints, &ai)) { | |||
if (ai->ai_family == AF_INET6) { | |||
av_strlcat(str, "[", size); | |||
av_strlcat(str, hostname, size); | |||
av_strlcat(str, "]", size); | |||
} else { | |||
av_strlcat(str, hostname, size); | |||
} | |||
freeaddrinfo(ai); | |||
} else | |||
#endif | |||
/* Not an IPv6 address, just output the plain string. */ | |||
av_strlcat(str, hostname, size); | |||
if (port >= 0) | |||
av_strlcatf(str, size, ":%d", port); | |||
if (fmt) { | |||
va_list vl; | |||
int len = strlen(str); | |||
va_start(vl, fmt); | |||
vsnprintf(str + len, size > len ? size - len : 0, fmt, vl); | |||
va_end(vl); | |||
} | |||
return strlen(str); | |||
} | |||
void ff_make_absolute_url(char *buf, int size, const char *base, | |||
const char *rel) | |||
{ | |||
char *sep, *path_query; | |||
/* Absolute path, relative to the current server */ | |||
if (base && strstr(base, "://") && rel[0] == '/') { | |||
if (base != buf) | |||
av_strlcpy(buf, base, size); | |||
sep = strstr(buf, "://"); | |||
if (sep) { | |||
/* Take scheme from base url */ | |||
if (rel[1] == '/') { | |||
sep[1] = '\0'; | |||
} else { | |||
/* Take scheme and host from base url */ | |||
sep += 3; | |||
sep = strchr(sep, '/'); | |||
if (sep) | |||
*sep = '\0'; | |||
} | |||
} | |||
av_strlcat(buf, rel, size); | |||
return; | |||
} | |||
/* If rel actually is an absolute url, just copy it */ | |||
if (!base || strstr(rel, "://") || rel[0] == '/') { | |||
av_strlcpy(buf, rel, size); | |||
return; | |||
} | |||
if (base != buf) | |||
av_strlcpy(buf, base, size); | |||
/* Strip off any query string from base */ | |||
path_query = strchr(buf, '?'); | |||
if (path_query != NULL) | |||
*path_query = '\0'; | |||
/* Is relative path just a new query part? */ | |||
if (rel[0] == '?') { | |||
av_strlcat(buf, rel, size); | |||
return; | |||
} | |||
/* Remove the file name from the base url */ | |||
sep = strrchr(buf, '/'); | |||
if (sep) | |||
sep[1] = '\0'; | |||
else | |||
buf[0] = '\0'; | |||
while (av_strstart(rel, "../", NULL) && sep) { | |||
/* Remove the path delimiter at the end */ | |||
sep[0] = '\0'; | |||
sep = strrchr(buf, '/'); | |||
/* If the next directory name to pop off is "..", break here */ | |||
if (!strcmp(sep ? &sep[1] : buf, "..")) { | |||
/* Readd the slash we just removed */ | |||
av_strlcat(buf, "/", size); | |||
break; | |||
} | |||
/* Cut off the directory name */ | |||
if (sep) | |||
sep[1] = '\0'; | |||
else | |||
buf[0] = '\0'; | |||
rel += 3; | |||
} | |||
av_strlcat(buf, rel, size); | |||
} |
@@ -246,4 +246,41 @@ URLProtocol *ffurl_protocol_next(URLProtocol *prev); | |||
int ff_udp_set_remote_url(URLContext *h, const char *uri); | |||
int ff_udp_get_local_port(URLContext *h); | |||
/** | |||
* Assemble a URL string from components. This is the reverse operation | |||
* of av_url_split. | |||
* | |||
* Note, this requires networking to be initialized, so the caller must | |||
* ensure ff_network_init has been called. | |||
* | |||
* @see av_url_split | |||
* | |||
* @param str the buffer to fill with the url | |||
* @param size the size of the str buffer | |||
* @param proto the protocol identifier, if null, the separator | |||
* after the identifier is left out, too | |||
* @param authorization an optional authorization string, may be null. | |||
* An empty string is treated the same as a null string. | |||
* @param hostname the host name string | |||
* @param port the port number, left out from the string if negative | |||
* @param fmt a generic format string for everything to add after the | |||
* host/port, may be null | |||
* @return the number of characters written to the destination buffer | |||
*/ | |||
int ff_url_join(char *str, int size, const char *proto, | |||
const char *authorization, const char *hostname, | |||
int port, const char *fmt, ...) av_printf_format(7, 8); | |||
/* | |||
* Convert a relative url into an absolute url, given a base url. | |||
* | |||
* @param buf the buffer where output absolute url is written | |||
* @param size the size of buf | |||
* @param base the base url, may be equal to buf. | |||
* @param rel the new url, which is interpreted relative to base | |||
*/ | |||
void ff_make_absolute_url(char *buf, int size, const char *base, | |||
const char *rel); | |||
#endif /* AVFORMAT_URL_H */ |
@@ -3109,50 +3109,6 @@ void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, | |||
s->pts_wrap_bits = pts_wrap_bits; | |||
} | |||
int ff_url_join(char *str, int size, const char *proto, | |||
const char *authorization, const char *hostname, | |||
int port, const char *fmt, ...) | |||
{ | |||
#if CONFIG_NETWORK | |||
struct addrinfo hints = { 0 }, *ai; | |||
#endif | |||
str[0] = '\0'; | |||
if (proto) | |||
av_strlcatf(str, size, "%s://", proto); | |||
if (authorization && authorization[0]) | |||
av_strlcatf(str, size, "%s@", authorization); | |||
#if CONFIG_NETWORK && defined(AF_INET6) | |||
/* Determine if hostname is a numerical IPv6 address, | |||
* properly escape it within [] in that case. */ | |||
hints.ai_flags = AI_NUMERICHOST; | |||
if (!getaddrinfo(hostname, NULL, &hints, &ai)) { | |||
if (ai->ai_family == AF_INET6) { | |||
av_strlcat(str, "[", size); | |||
av_strlcat(str, hostname, size); | |||
av_strlcat(str, "]", size); | |||
} else { | |||
av_strlcat(str, hostname, size); | |||
} | |||
freeaddrinfo(ai); | |||
} else | |||
#endif | |||
/* Not an IPv6 address, just output the plain string. */ | |||
av_strlcat(str, hostname, size); | |||
if (port >= 0) | |||
av_strlcatf(str, size, ":%d", port); | |||
if (fmt) { | |||
va_list vl; | |||
int len = strlen(str); | |||
va_start(vl, fmt); | |||
vsnprintf(str + len, size > len ? size - len : 0, fmt, vl); | |||
va_end(vl); | |||
} | |||
return strlen(str); | |||
} | |||
void ff_parse_key_value(const char *str, ff_parse_key_val_cb callback_get_buf, | |||
void *context) | |||
{ | |||
@@ -3217,75 +3173,6 @@ int ff_find_stream_index(AVFormatContext *s, int id) | |||
return -1; | |||
} | |||
void ff_make_absolute_url(char *buf, int size, const char *base, | |||
const char *rel) | |||
{ | |||
char *sep, *path_query; | |||
/* Absolute path, relative to the current server */ | |||
if (base && strstr(base, "://") && rel[0] == '/') { | |||
if (base != buf) | |||
av_strlcpy(buf, base, size); | |||
sep = strstr(buf, "://"); | |||
if (sep) { | |||
/* Take scheme from base url */ | |||
if (rel[1] == '/') { | |||
sep[1] = '\0'; | |||
} else { | |||
/* Take scheme and host from base url */ | |||
sep += 3; | |||
sep = strchr(sep, '/'); | |||
if (sep) | |||
*sep = '\0'; | |||
} | |||
} | |||
av_strlcat(buf, rel, size); | |||
return; | |||
} | |||
/* If rel actually is an absolute url, just copy it */ | |||
if (!base || strstr(rel, "://") || rel[0] == '/') { | |||
av_strlcpy(buf, rel, size); | |||
return; | |||
} | |||
if (base != buf) | |||
av_strlcpy(buf, base, size); | |||
/* Strip off any query string from base */ | |||
path_query = strchr(buf, '?'); | |||
if (path_query != NULL) | |||
*path_query = '\0'; | |||
/* Is relative path just a new query part? */ | |||
if (rel[0] == '?') { | |||
av_strlcat(buf, rel, size); | |||
return; | |||
} | |||
/* Remove the file name from the base url */ | |||
sep = strrchr(buf, '/'); | |||
if (sep) | |||
sep[1] = '\0'; | |||
else | |||
buf[0] = '\0'; | |||
while (av_strstart(rel, "../", NULL) && sep) { | |||
/* Remove the path delimiter at the end */ | |||
sep[0] = '\0'; | |||
sep = strrchr(buf, '/'); | |||
/* If the next directory name to pop off is "..", break here */ | |||
if (!strcmp(sep ? &sep[1] : buf, "..")) { | |||
/* Readd the slash we just removed */ | |||
av_strlcat(buf, "/", size); | |||
break; | |||
} | |||
/* Cut off the directory name */ | |||
if (sep) | |||
sep[1] = '\0'; | |||
else | |||
buf[0] = '\0'; | |||
rel += 3; | |||
} | |||
av_strlcat(buf, rel, size); | |||
} | |||
int64_t ff_iso8601_to_unix_time(const char *datestr) | |||
{ | |||
#if HAVE_STRPTIME | |||