@@ -20,6 +20,7 @@ OBJS = allformats.o \ | |||||
riff.o \ | riff.o \ | ||||
sdp.o \ | sdp.o \ | ||||
seek.o \ | seek.o \ | ||||
url.o \ | |||||
utils.o \ | utils.o \ | ||||
OBJS-$(CONFIG_NETWORK) += network.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. */ | /** Get the current time since NTP epoch in microseconds. */ | ||||
uint64_t ff_ntp_time(void); | 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 | * Append the media-specific SDP fragment for the media stream c | ||||
* to the buffer buff. | * 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); | 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); | 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 | * 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) | 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_set_remote_url(URLContext *h, const char *uri); | ||||
int ff_udp_get_local_port(URLContext *h); | 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 */ | #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; | 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 ff_parse_key_value(const char *str, ff_parse_key_val_cb callback_get_buf, | ||||
void *context) | void *context) | ||||
{ | { | ||||
@@ -3217,75 +3173,6 @@ int ff_find_stream_index(AVFormatContext *s, int id) | |||||
return -1; | 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) | int64_t ff_iso8601_to_unix_time(const char *datestr) | ||||
{ | { | ||||
#if HAVE_STRPTIME | #if HAVE_STRPTIME | ||||