aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar wm4 <wm4@nowhere>2013-07-07 19:40:14 +0200
committerGravatar wm4 <wm4@nowhere>2013-07-07 19:42:38 +0200
commit854303ad49d188d96af8151b290162916c81c993 (patch)
treed47fc0ccd34adf47df7612c8b213d09b3816eae5
parentfeaa721916303c36dcd676c11ac74ecdec2db006 (diff)
Remove internal network support
This commit removes the "old" networking code in favor of libavformat's code. The code was still used for mp_http, udp, ftp, cddb. http has been mapped to libavformat's http support since approximately 6 months ago. udp and ftp have support in ffmpeg (though ftp was added only last month). cddb support is removed with this commit - it's probably not important and rarely used if at all, so we don't care about it.
-rw-r--r--DOCS/man/en/options.rst28
-rw-r--r--Makefile12
-rwxr-xr-xconfigure190
-rw-r--r--core/m_option.c34
-rw-r--r--core/options.c11
-rw-r--r--core/options.h3
-rw-r--r--stream/asf_mmst_streaming.c686
-rw-r--r--stream/asf_mmst_streaming.h26
-rw-r--r--stream/asf_streaming.c855
-rw-r--r--stream/cookies.c86
-rw-r--r--stream/cookies.h4
-rw-r--r--stream/http.c966
-rw-r--r--stream/http.h70
-rw-r--r--stream/network.c455
-rw-r--r--stream/network.h84
-rw-r--r--stream/stream.c76
-rw-r--r--stream/stream.h29
-rw-r--r--stream/stream_cdda.c32
-rw-r--r--stream/stream_cddb.c902
-rw-r--r--stream/stream_ftp.c520
-rw-r--r--stream/stream_lavf.c3
-rw-r--r--stream/stream_udp.c105
-rw-r--r--stream/tcp.c279
-rw-r--r--stream/tcp.h35
-rw-r--r--stream/udp.c201
-rw-r--r--stream/udp.h30
-rw-r--r--stream/url.c506
-rw-r--r--stream/url.h55
28 files changed, 43 insertions, 6240 deletions
diff --git a/DOCS/man/en/options.rst b/DOCS/man/en/options.rst
index 8a5a9baa44..0d83764d80 100644
--- a/DOCS/man/en/options.rst
+++ b/DOCS/man/en/options.rst
@@ -1051,12 +1051,6 @@
work (key bindings that normally quit will be shown on OSD only, just
like any other binding).
---ipv4-only-proxy
- Skip any HTTP proxy for IPv6 addresses. It will still be used for IPv4
- connections.
-
- *WARNING*: works with the deprecated ``mp_http://`` protocol only.
-
--joystick, --no-joystick
Enable/disable joystick support. Enabled by default.
@@ -1416,12 +1410,6 @@
allows a zoom factor of up to 4. This feature is experimental. Do not
report bugs unless you are using ``--vo=opengl``.
---passwd=<password>
- Used with some network protocols. Specify password for HTTP authentication.
- See also ``--user``.
-
- *WARNING*: works with the deprecated ``mp_http://`` protocol only.
-
--playing-msg=<string>
Print out a string after starting playback. The string is expanded for
properties, e.g. ``--playing-msg=file: ${filename}`` will print the string
@@ -1466,16 +1454,6 @@
--pphelp
See also ``--vf=pp``.
---prefer-ipv4
- Use IPv4 on network connections. Falls back on IPv6 automatically.
-
- *WARNING*: works with the deprecated ``mp_http://`` protocol only.
-
---prefer-ipv6
- Use IPv6 on network connections. Falls back on IPv4 automatically.
-
- *WARNING*: works with the deprecated ``mp_http://`` protocol only.
-
--priority=<prio>
(Windows only.)
Set process priority for mpv according to the predefined priorities
@@ -2284,12 +2262,6 @@
*WARNING*: May be dangerous if playing from untrusted media.
---user=<username>
- Used with some network protocols.
- Specify username for HTTP authentication. See also ``--passwd``.
-
- *WARNING*: works with the deprecated ``mp_http://`` protocol only.
-
--user-agent=<string>
Use <string> as user agent for HTTP streaming.
diff --git a/Makefile b/Makefile
index 6b6f05dc86..373a6f3ddc 100644
--- a/Makefile
+++ b/Makefile
@@ -28,13 +28,11 @@ SOURCES_AUDIO_INPUT-$(OSS) += stream/ai_oss.c
SOURCES-$(AUDIO_INPUT) += $(SOURCES_AUDIO_INPUT-yes)
SOURCES-$(CDDA) += stream/stream_cdda.c \
stream/cdinfo.c
-SOURCES-$(CDDB) += stream/stream_cddb.c
SOURCES-$(DVBIN) += stream/dvb_tune.c \
stream/stream_dvb.c
SOURCES-$(DVDREAD) += stream/stream_dvd.c \
stream/stream_dvd_common.c
-SOURCES-$(FTP) += stream/stream_ftp.c
SOURCES-$(HAVE_SYS_MMAN_H) += audio/filter/af_export.c osdep/mmap_anon.c
SOURCES-$(LADSPA) += audio/filter/af_ladspa.c
SOURCES-$(LIBASS) += sub/ass_mp.c sub/sd_ass.c \
@@ -56,14 +54,6 @@ SOURCES-$(MPG123) += audio/decode/ad_mpg123.c
SOURCES-$(NEED_GETTIMEOFDAY) += osdep/gettimeofday.c
SOURCES-$(NEED_GLOB) += osdep/glob-win.c
-SOURCES-$(NETWORKING) += stream/asf_mmst_streaming.c \
- stream/asf_streaming.c \
- stream/cookies.c \
- stream/http.c \
- stream/network.c \
- stream/udp.c \
- stream/tcp.c \
- stream/stream_udp.c \
SOURCES-$(PRIORITY) += osdep/priority.c
SOURCES-$(PVR) += stream/stream_pvr.c
@@ -223,6 +213,7 @@ SOURCES = talloc.c \
osdep/io.c \
osdep/numcores.c \
osdep/timer.c \
+ stream/cookies.c \
stream/stream.c \
stream/stream_avdevice.c \
stream/stream_file.c \
@@ -230,7 +221,6 @@ SOURCES = talloc.c \
stream/stream_memory.c \
stream/stream_mf.c \
stream/stream_null.c \
- stream/url.c \
sub/dec_sub.c \
sub/draw_bmp.c \
sub/find_subfiles.c \
diff --git a/configure b/configure
index 78385e1276..58e615de26 100755
--- a/configure
+++ b/configure
@@ -307,8 +307,6 @@ Optional features:
--disable-tv disable TV interface (TV/DVB grabbers) [enable]
--disable-tv-v4l2 disable Video4Linux2 TV interface [autodetect]
--disable-pvr disable Video4Linux2 MPEG PVR [autodetect]
- --disable-networking disable networking [enable]
- --enable-winsock2_h enable winsock2_h [autodetect]
--enable-smb enable Samba (SMB) input [autodetect]
--disable-libquvi4 disable libquvi 0.4.x [autodetect]
--disable-libquvi9 disable libquvi 0.9.x [autodetect]
@@ -316,12 +314,10 @@ Optional features:
--disable-vcd disable VCD support [autodetect]
--disable-bluray disable Blu-ray support [autodetect]
--disable-dvdread disable libdvdread [autodetect]
- --disable-cddb disable cddb [autodetect]
--disable-enca disable ENCA charset oracle library [autodetect]
--enable-macosx-bundle enable Mac OS X bundle file locations [autodetect]
--disable-inet6 disable IPv6 support [autodetect]
--disable-gethostbyname2 gethostbyname2 part of the C library [autodetect]
- --disable-ftp disable FTP support [enabled]
--disable-vstream disable TiVo vstream client support [autodetect]
--disable-pthreads disable Posix threads support [autodetect]
--disable-libass disable subtitle rendering with libass [autodetect]
@@ -463,8 +459,6 @@ _radio_v4l2=auto
_tv=yes
_tv_v4l2=auto
_pvr=auto
-networking=yes
-_winsock2_h=auto
_smb=auto
_libquvi4=auto
_libquvi9=auto
@@ -477,7 +471,6 @@ _termios=auto
_shm=auto
_gettext=no
_cdda=auto
-_cddb=auto
_coreaudio=auto
_corevideo=auto
_cocoa=auto
@@ -485,7 +478,6 @@ _macosx_bundle=auto
_enca=auto
_inet6=auto
_gethostbyname2=auto
-_ftp=auto
_vstream=auto
_pthreads=auto
_ass=auto
@@ -662,10 +654,6 @@ for ac_option do
--disable-radio-v4l2) _radio_v4l2=no ;;
--enable-pvr) _pvr=yes ;;
--disable-pvr) _pvr=no ;;
- --enable-networking) networking=yes ;;
- --disable-networking) networking=no ;;
- --enable-winsock2_h) _winsock2_h=yes ;;
- --disable-winsock2_h) _winsock2_h=no ;;
--enable-smb) _smb=yes ;;
--disable-smb) _smb=no ;;
--enable-libquvi4) _libquvi4=yes ;;
@@ -692,10 +680,6 @@ for ac_option do
--disable-shm) _shm=no ;;
--enable-select) _select=yes ;;
--disable-select) _select=no ;;
- --enable-cddb) _cddb=yes ;;
- --disable-cddb) _cddb=no ;;
- --enable-ftp) _ftp=yes ;;
- --disable-ftp) _ftp=no ;;
--enable-vstream) _vstream=yes ;;
--disable-vstream) _vstream=no ;;
--enable-pthreads) _pthreads=yes ;;
@@ -1247,146 +1231,6 @@ fi
echores "$_nanosleep"
-echocheck "socklib"
-# for Solaris (socket stuff is in -lsocket, gethostbyname and friends in -lnsl):
-cat > $TMPC << EOF
-#include <netdb.h>
-#include <sys/socket.h>
-int main(void) { gethostbyname(0); socket(AF_INET, SOCK_STREAM, 0); return 0; }
-EOF
-_socklib=no
-for _ld_tmp in "" "-lsocket -lbind" "-lsocket -ldnet" "-lsocket -lnsl" "-lnsl" "-lsocket" ; do
- cc_check $_ld_tmp && _ld_sock="$_ld_tmp" && _socklib=yes && break
-done
-test $_socklib = yes && test $_winsock2_h = auto && _winsock2_h=no
-if test $_winsock2_h = auto ; then
- _winsock2_h=no
- statement_check winsock2.h 'gethostbyname(0)' -lws2_32 && _ld_sock="-lws2_32" && _winsock2_h=yes
-fi
-test "$_ld_sock" && res_comment="using $_ld_sock"
-echores "$_socklib"
-
-
-if test $_winsock2_h = yes ; then
- _ld_sock="-lws2_32"
- def_winsock2_h='#define HAVE_WINSOCK2_H 1'
-else
- def_winsock2_h='#define HAVE_WINSOCK2_H 0'
-fi
-
-
-echocheck "inet_pton()"
-def_inet_pton='#define HAVE_INET_PTON 0'
-inet_pton=no
-for _ld_tmp in "$_ld_sock" "$_ld_sock -lresolv" ; do
- statement_check arpa/inet.h 'inet_pton(0, 0, 0)' $_ld_tmp && inet_pton=yes && break
-done
-if test $inet_pton = yes ; then
- test "$_ld_tmp" && res_comment="using $_ld_tmp"
- def_inet_pton='#define HAVE_INET_PTON 1'
-fi
-echores "$inet_pton"
-
-
-echocheck "inet_aton()"
-def_inet_aton='#define HAVE_INET_ATON 0'
-inet_aton=no
-for _ld_tmp in "$_ld_sock" "$_ld_sock -lresolv" ; do
- statement_check arpa/inet.h 'inet_aton(0, 0)' $_ld_tmp && inet_aton=yes && break
-done
-if test $inet_aton = yes ; then
- test "$_ld_tmp" && res_comment="using $_ld_tmp"
- def_inet_aton='#define HAVE_INET_ATON 1'
-fi
-echores "$inet_aton"
-
-
-echocheck "socklen_t"
-_socklen_t=no
-for header in "sys/socket.h" "ws2tcpip.h" "sys/types.h" ; do
- statement_check $header 'socklen_t v = 0' && _socklen_t=yes && break
-done
-if test "$_socklen_t" = yes ; then
- def_socklen_t='#define HAVE_SOCKLEN_T 1'
-else
- def_socklen_t='#define HAVE_SOCKLEN_T 0'
-fi
-echores "$_socklen_t"
-
-
-echocheck "closesocket()"
-_closesocket=no
-statement_check winsock2.h 'closesocket(~0)' $_ld_sock && _closesocket=yes
-if test "$_closesocket" = yes ; then
- def_closesocket='#define HAVE_CLOSESOCKET 1'
-else
- def_closesocket='#define HAVE_CLOSESOCKET 0'
-fi
-echores "$_closesocket"
-
-
-echocheck "networking"
-test $_winsock2_h = no && test $inet_pton = no &&
- test $inet_aton = no && networking=no
-if test "$networking" = yes ; then
- def_network='#define CONFIG_NETWORK 1'
- def_networking='#define CONFIG_NETWORKING 1'
- libs_mplayer="$libs_mplayer $_ld_sock"
- inputmodules="networking $inputmodules"
-else
- noinputmodules="networking $noinputmodules"
- def_network='#define CONFIG_NETWORK 0'
- def_networking='#undef CONFIG_NETWORKING'
-fi
-echores "$networking"
-
-
-echocheck "inet6"
-if test "$_inet6" = auto ; then
- cat > $TMPC << EOF
-#include <sys/types.h>
-#if !defined(_WIN32)
-#include <sys/socket.h>
-#include <netinet/in.h>
-#else
-#include <ws2tcpip.h>
-#endif
-int main(void) { struct sockaddr_in6 six; socket(AF_INET6, SOCK_STREAM, AF_INET6); return 0; }
-EOF
- _inet6=no
- if cc_check $_ld_sock ; then
- _inet6=yes
- fi
-fi
-if test "$_inet6" = yes ; then
- def_inet6='#define HAVE_AF_INET6 1'
-else
- def_inet6='#undef HAVE_AF_INET6'
-fi
-echores "$_inet6"
-
-
-echocheck "gethostbyname2"
-if test "$_gethostbyname2" = auto ; then
-cat > $TMPC << EOF
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-int main(void) { gethostbyname2("", AF_INET); return 0; }
-EOF
- _gethostbyname2=no
- if cc_check ; then
- _gethostbyname2=yes
- fi
-fi
-if test "$_gethostbyname2" = yes ; then
- def_gethostbyname2='#define HAVE_GETHOSTBYNAME2 1'
-else
- def_gethostbyname2='#undef HAVE_GETHOSTBYNAME2'
-fi
-echores "$_gethostbyname2"
-
-
echocheck "mman.h"
_mman=no
statement_check sys/mman.h 'mmap(0, 0, 0, 0, 0, 0)' && _mman=yes
@@ -2585,7 +2429,6 @@ fi
if test "$_libcdio" = yes ; then
_cdda='yes'
def_cdda='#define CONFIG_CDDA 1'
- test $_cddb = auto && test $networking = yes && _cddb=yes
inputmodules="cdda $inputmodules"
else
_libcdio=no
@@ -2595,15 +2438,6 @@ else
fi
echores "$_libcdio"
-if test "$_cddb" = yes ; then
- def_cddb='#define CONFIG_CDDB 1'
- inputmodules="cddb $inputmodules"
-else
- _cddb=no
- def_cddb='#undef CONFIG_CDDB'
- noinputmodules="cddb $noinputmodules"
-fi
-
echocheck "SSA/ASS support"
if test "$_ass" = auto ; then
@@ -2999,19 +2833,6 @@ fi
echores "$_pvr"
-echocheck "ftp"
-if test "$_ftp" = "auto" ; then
-test "$networking" = "yes" && _ftp=yes
-fi
-if test "$_ftp" = yes ; then
- def_ftp='#define CONFIG_FTP 1'
- inputmodules="ftp $inputmodules"
-else
- noinputmodules="ftp $noinputmodules"
- def_ftp='#undef CONFIG_FTP'
-fi
-echores "$_ftp"
-
echocheck "vstream client"
if test "$_vstream" = auto ; then
_vstream=no
@@ -3175,7 +2996,6 @@ ALSA = $_alsa
AUDIO_INPUT = $_audio_input
CACA = $_caca
CDDA = $_cdda
-CDDB = $_cddb
COCOA = $_cocoa
COREAUDIO = $_coreaudio
COREVIDEO = $_corevideo
@@ -3187,7 +3007,6 @@ WASAPI0 = $_wasapi0
DVBIN = $_dvbin
DVDREAD = $_dvdread
DXR3 = $_dxr3
-FTP = $_ftp
GL = $_gl
GL_COCOA = $_gl_cocoa
GL_WIN32 = $_gl_win32
@@ -3220,7 +3039,6 @@ LIRC = $_lirc
MACOSX_BUNDLE = $_macosx_bundle
MNG = $_mng
MPG123 = $_mpg123
-NETWORKING = $networking
OPENAL = $_openal
OSS = $_ossaudio
PE_EXECUTABLE = $_pe_executable
@@ -3344,7 +3162,6 @@ $(ff_config_enable "$subarch_all" "$subarch" "ARCH")
$def_bluray
$def_bsdi_dvd
$def_cdda
-$def_cddb
$def_cdio
$def_cdrom
$def_dvd
@@ -3405,17 +3222,10 @@ $def_ass
$def_enca
/* networking */
-$def_closesocket
-$def_ftp
-$def_inet6
-$def_inet_aton
-$def_inet_pton
-$def_networking
$def_smb
$def_libquvi4
$def_libquvi9
$def_libguess
-$def_socklen_t
$def_vstream
$def_lcms2
diff --git a/core/m_option.c b/core/m_option.c
index 9ef968194f..9b8256abe4 100644
--- a/core/m_option.c
+++ b/core/m_option.c
@@ -29,6 +29,7 @@
#include <limits.h>
#include <inttypes.h>
#include <unistd.h>
+#include <ctype.h>
#include <assert.h>
#include <libavutil/common.h>
@@ -38,7 +39,6 @@
#include "core/mp_common.h"
#include "core/m_option.h"
#include "core/mp_msg.h"
-#include "stream/url.h"
char *m_option_strerror(int code)
{
@@ -2367,6 +2367,38 @@ const m_option_type_t m_option_type_obj_settings_list = {
};
+/* Replace escape sequences in an URL (or a part of an URL) */
+/* works like strcpy(), but without return argument,
+ except that outbuf == inbuf is allowed */
+static void url_unescape_string(char *outbuf, const char *inbuf)
+{
+ unsigned char c,c1,c2;
+ int i,len=strlen(inbuf);
+ for (i=0;i<len;i++) {
+ c = inbuf[i];
+ if (c == '%' && i<len-2) { //must have 2 more chars
+ c1 = toupper(inbuf[i+1]); // we need uppercase characters
+ c2 = toupper(inbuf[i+2]);
+ if (((c1>='0' && c1<='9') || (c1>='A' && c1<='F')) &&
+ ((c2>='0' && c2<='9') || (c2>='A' && c2<='F')) )
+ {
+ if (c1>='0' && c1<='9')
+ c1-='0';
+ else
+ c1-='A'-10;
+ if (c2>='0' && c2<='9')
+ c2-='0';
+ else
+ c2-='A'-10;
+ c = (c1<<4) + c2;
+ i=i+2; //only skip next 2 chars if valid esc
+ }
+ }
+ *outbuf++ = c;
+ }
+ *outbuf++='\0'; //add nullterm to string
+}
+
static int parse_custom_url(const m_option_t *opt, struct bstr name,
struct bstr url, void *dst)
{
diff --git a/core/options.c b/core/options.c
index 3a60e3c810..b00f79c003 100644
--- a/core/options.c
+++ b/core/options.c
@@ -40,8 +40,6 @@
#include "mp_core.h"
#include "osdep/priority.h"
-char *network_username=NULL;
-char *network_password=NULL;
int network_bandwidth=0;
int network_cookies_enabled = 0;
char *network_useragent="MPlayer 1.1-4.7";
@@ -351,20 +349,11 @@ const m_option_t mp_opts[] = {
{"bluray-angle", &bluray_angle, CONF_TYPE_INT, CONF_RANGE, 0, 999, NULL},
#endif /* CONFIG_LIBBLURAY */
- {"user", &network_username, CONF_TYPE_STRING, 0, 0, 0, NULL},
- {"passwd", &network_password, CONF_TYPE_STRING, 0, 0, 0, NULL},
- {"bandwidth", &network_bandwidth, CONF_TYPE_INT, CONF_MIN, 0, 0, NULL},
{"http-header-fields", &network_http_header_fields, CONF_TYPE_STRING_LIST, 0, 0, 0, NULL},
{"user-agent", &network_useragent, CONF_TYPE_STRING, 0, 0, 0, NULL},
{"referrer", &network_referrer, CONF_TYPE_STRING, 0, 0, 0, NULL},
{"cookies", &network_cookies_enabled, CONF_TYPE_FLAG, 0, 0, 1, NULL},
{"cookies-file", &cookies_file, CONF_TYPE_STRING, 0, 0, 0, NULL},
- {"prefer-ipv4", &network_prefer_ipv4, CONF_TYPE_FLAG, 0, 0, 1, NULL},
- {"ipv4-only-proxy", &network_ipv4_only_proxy, CONF_TYPE_FLAG, 0, 0, 1, NULL},
- {"reuse-socket", &reuse_socket, CONF_TYPE_FLAG, 0, 0, 1, NULL},
-#ifdef HAVE_AF_INET6
- {"prefer-ipv6", &network_prefer_ipv4, CONF_TYPE_FLAG, 0, 1, 0, NULL},
-#endif /* HAVE_AF_INET6 */
// ------------------------- demuxer options --------------------
diff --git a/core/options.h b/core/options.h
index 54048d9966..1eb111e33e 100644
--- a/core/options.h
+++ b/core/options.h
@@ -268,9 +268,6 @@ typedef struct MPOpts {
// Should be moved into MPOpts
extern char **network_http_header_fields;
-extern char *network_username;
-extern char *network_password;
-extern int network_bandwidth;
extern char *network_useragent;
extern char *network_referrer;
extern int network_cookies_enabled;
diff --git a/stream/asf_mmst_streaming.c b/stream/asf_mmst_streaming.c
deleted file mode 100644
index 98c386d11d..0000000000
--- a/stream/asf_mmst_streaming.c
+++ /dev/null
@@ -1,686 +0,0 @@
-/*
- * MMST implementation taken from the xine-mms plugin made by
- * Major MMS (http://geocities.com/majormms/).
- * Ported to MPlayer by Abhijeet Phatak <abhijeetphatak@yahoo.com>.
- *
- * Information about the MMS protocol can be found at http://get.to/sdp
- *
- * copyright (C) 2002 Abhijeet Phatak <abhijeetphatak@yahoo.com>
- * copyright (C) 2002 the xine project
- * copyright (C) 2000-2001 major mms
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <inttypes.h>
-
-#include "config.h"
-#include "core/options.h"
-#include "core/mp_msg.h"
-
-#if HAVE_WINSOCK2_H
-#include <winsock2.h>
-#endif
-
-#ifdef CONFIG_ICONV
-#include <iconv.h>
-#endif
-
-#include "url.h"
-#include "demux/asf.h"
-
-#include "stream.h"
-#include "asf_mmst_streaming.h"
-#include "network.h"
-#include "tcp.h"
-
-extern int audio_id;
-extern int video_id;
-
-#define BUF_SIZE 102400
-#define HDR_BUF_SIZE 8192
-#define MAX_STREAMS 20
-
-typedef struct
-{
- uint8_t buf[BUF_SIZE];
- int num_bytes;
-
-} command_t;
-
-static int seq_num;
-static int num_stream_ids;
-static int stream_ids[MAX_STREAMS];
-
-static int get_data (int s, char *buf, size_t count);
-
-static void put_32 (command_t *cmd, uint32_t value)
-{
- cmd->buf[cmd->num_bytes ] = value % 256;
- value = value >> 8;
- cmd->buf[cmd->num_bytes+1] = value % 256 ;
- value = value >> 8;
- cmd->buf[cmd->num_bytes+2] = value % 256 ;
- value = value >> 8;
- cmd->buf[cmd->num_bytes+3] = value % 256 ;
-
- cmd->num_bytes += 4;
-}
-
-static uint32_t get_32 (unsigned char *cmd, int offset)
-{
- uint32_t ret;
-
- ret = cmd[offset] ;
- ret |= cmd[offset+1]<<8 ;
- ret |= cmd[offset+2]<<16 ;
- ret |= cmd[offset+3]<<24 ;
-
- return ret;
-}
-
-static void send_command (int s, int command, uint32_t switches,
- uint32_t extra, int length,
- char *data)
-{
- command_t cmd;
- int len8;
-
- len8 = (length + 7) / 8;
-
- cmd.num_bytes = 0;
-
- put_32 (&cmd, 0x00000001); /* start sequence */
- put_32 (&cmd, 0xB00BFACE); /* #-)) */
- put_32 (&cmd, len8*8 + 32);
- put_32 (&cmd, 0x20534d4d); /* protocol type "MMS " */
- put_32 (&cmd, len8 + 4);
- put_32 (&cmd, seq_num);
- seq_num++;
- put_32 (&cmd, 0x0); /* unknown */
- put_32 (&cmd, 0x0);
- put_32 (&cmd, len8+2);
- put_32 (&cmd, 0x00030000 | command); /* dir | command */
- put_32 (&cmd, switches);
- put_32 (&cmd, extra);
-
- memcpy (&cmd.buf[48], data, length);
- if (length & 7)
- memset(&cmd.buf[48 + length], 0, 8 - (length & 7));
-
- if (send (s, cmd.buf, len8*8+48, 0) != (len8*8+48)) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"write error\n");
- }
-}
-
-#ifdef CONFIG_ICONV
-static iconv_t url_conv;
-#endif
-
-static void string_utf16(char *dest, char *src, int len) {
- int i;
-#ifdef CONFIG_ICONV
- size_t len1, len2;
- char *ip, *op;
-
- if (url_conv != (iconv_t)(-1))
- {
- memset(dest, 0, 1000);
- len1 = len; len2 = 1000;
- ip = src; op = dest;
-
- iconv(url_conv, &ip, &len1, &op, &len2);
- }
- else
- {
-#endif
- if (len > 499) len = 499;
- for (i=0; i<len; i++) {
- dest[i*2] = src[i];
- dest[i*2+1] = 0;
- }
- /* trailing zeroes */
- dest[i*2] = 0;
- dest[i*2+1] = 0;
-#ifdef CONFIG_ICONV
- }
-#endif
-}
-
-static void get_answer (int s)
-{
- char data[BUF_SIZE];
- int command = 0x1b;
-
- while (command == 0x1b) {
- int len;
-
- len = recv (s, data, BUF_SIZE, 0) ;
- if (!len) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"\nAlert! EOF\n");
- return;
- }
-
- command = get_32 (data, 36) & 0xFFFF;
-
- if (command == 0x1b)
- send_command (s, 0x1b, 0, 0, 0, data);
- }
-}
-
-static int get_data (int s, char *buf, size_t count)
-{
- ssize_t len;
- size_t total = 0;
-
- while (total < count) {
-
- len = recv (s, &buf[total], count-total, 0);
-
- if (len<=0) {
- perror ("read error:");
- return 0;
- }
-
- total += len;
-
- if (len != 0) {
-// mp_msg(MSGT_NETWORK,MSGL_INFO,"[%d/%d]", total, count);
- fflush (stdout);
- }
-
- }
-
- return 1;
-
-}
-
-static int get_header (int s, uint8_t *header, streaming_ctrl_t *streaming_ctrl)
-{
- unsigned char pre_header[8];
- int header_len;
-
- header_len = 0;
-
- while (1) {
- if (!get_data (s, pre_header, 8)) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"pre-header read failed\n");
- return 0;
- }
- if (pre_header[4] == 0x02) {
-
- int packet_len;
-
- packet_len = (pre_header[7] << 8 | pre_header[6]) - 8;
-
-// mp_msg(MSGT_NETWORK,MSGL_INFO,"asf header packet detected, len=%d\n", packet_len);
-
- if (packet_len < 0 || packet_len > HDR_BUF_SIZE - header_len) {
- mp_tmsg(MSGT_NETWORK, MSGL_FATAL, "Invalid header size, giving up.\n");
- return 0;
- }
-
- if (!get_data (s, &header[header_len], packet_len)) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"Header data read failed.\n");
- return 0;
- }
-
- header_len += packet_len;
-
- if ( (header[header_len-1] == 1) && (header[header_len-2]==1)) {
-
-
- if( streaming_bufferize( streaming_ctrl, header, header_len )<0 ) {
- return -1;
- }
-
- // mp_msg(MSGT_NETWORK,MSGL_INFO,"get header packet finished\n");
-
- return header_len;
-
- }
-
- } else {
-
- int32_t packet_len;
- int command;
- char data[BUF_SIZE];
-
- if (!get_data (s, (char*)&packet_len, 4)) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"packet_len read failed.\n");
- return 0;
- }
-
- packet_len = get_32 ((unsigned char*)&packet_len, 0) + 4;
-
-// mp_msg(MSGT_NETWORK,MSGL_INFO,"command packet detected, len=%d\n", packet_len);
-
- if (packet_len < 0 || packet_len > BUF_SIZE) {
- mp_tmsg(MSGT_NETWORK, MSGL_FATAL,
- "Invalid RTSP packet size, giving up.\n");
- return 0;
- }
-
- if (!get_data (s, data, packet_len)) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"Command data read failed.\n");
- return 0;
- }
-
- command = get_32 (data, 24) & 0xFFFF;
-
-// mp_msg(MSGT_NETWORK,MSGL_INFO,"command: %02x\n", command);
-
- if (command == 0x1b)
- send_command (s, 0x1b, 0, 0, 0, data);
-
- }
-
-// mp_msg(MSGT_NETWORK,MSGL_INFO,"get header packet succ\n");
- }
-}
-
-static int interp_header (uint8_t *header, int header_len)
-{
- int i;
- int packet_length=-1;
-
- /*
- * parse header
- */
-
- i = 30;
- while (i<header_len) {
-
- uint64_t guid_1, guid_2, length;
-
- guid_2 = (uint64_t)header[i] | ((uint64_t)header[i+1]<<8)
- | ((uint64_t)header[i+2]<<16) | ((uint64_t)header[i+3]<<24)
- | ((uint64_t)header[i+4]<<32) | ((uint64_t)header[i+5]<<40)
- | ((uint64_t)header[i+6]<<48) | ((uint64_t)header[i+7]<<56);
- i += 8;
-
- guid_1 = (uint64_t)header[i] | ((uint64_t)header[i+1]<<8)
- | ((uint64_t)header[i+2]<<16) | ((uint64_t)header[i+3]<<24)
- | ((uint64_t)header[i+4]<<32) | ((uint64_t)header[i+5]<<40)
- | ((uint64_t)header[i+6]<<48) | ((uint64_t)header[i+7]<<56);
- i += 8;
-
-// mp_msg(MSGT_NETWORK,MSGL_INFO,"guid found: %016llx%016llx\n", guid_1, guid_2);
-
- length = (uint64_t)header[i] | ((uint64_t)header[i+1]<<8)
- | ((uint64_t)header[i+2]<<16) | ((uint64_t)header[i+3]<<24)
- | ((uint64_t)header[i+4]<<32) | ((uint64_t)header[i+5]<<40)
- | ((uint64_t)header[i+6]<<48) | ((uint64_t)header[i+7]<<56);
-
- i += 8;
-
- if ( (guid_1 == 0x6cce6200aa00d9a6ULL) && (guid_2 == 0x11cf668e75b22630ULL) ) {
- mp_tmsg(MSGT_NETWORK,MSGL_INFO,"header object\n");
- } else if ((guid_1 == 0x6cce6200aa00d9a6ULL) && (guid_2 == 0x11cf668e75b22636ULL)) {
- mp_tmsg(MSGT_NETWORK,MSGL_INFO,"data object\n");
- } else if ((guid_1 == 0x6553200cc000e48eULL) && (guid_2 == 0x11cfa9478cabdca1ULL)) {
-
- packet_length = get_32(header, i+92-24);
-
- mp_tmsg(MSGT_NETWORK,MSGL_INFO,"file object, packet length = %d (%d)\n",
- packet_length, get_32(header, i+96-24));
-
-
- } else if ((guid_1 == 0x6553200cc000e68eULL) && (guid_2 == 0x11cfa9b7b7dc0791ULL)) {
-
- int stream_id = header[i+48] | header[i+49] << 8;
-
- mp_tmsg(MSGT_NETWORK,MSGL_INFO,"stream object, stream ID: %d\n", stream_id);
-
- if (num_stream_ids < MAX_STREAMS) {
- stream_ids[num_stream_ids] = stream_id;
- num_stream_ids++;
- } else {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"Too many IDs, stream skipped.");
- }
-
- } else {
-#if 0
- int b = i;
- printf ("unknown object (guid: %016llx, %016llx, len: %lld)\n", guid_1, guid_2, length);
- for (; b < length; b++)
- {
- if (isascii(header[b]) || isalpha(header[b]))
- printf("%c ", header[b]);
- else
- printf("%x ", header[b]);
- }
- printf("\n");
-#else
- mp_tmsg(MSGT_NETWORK,MSGL_WARN,"unknown object\n");
-#endif
- }
-
-// mp_msg(MSGT_NETWORK,MSGL_INFO,"length : %lld\n", length);
-
- i += length-24;
-
- }
-
- return packet_length;
-
-}
-
-
-static int get_media_packet (int s, int padding, streaming_ctrl_t *stream_ctrl) {
- unsigned char pre_header[8];
- char data[BUF_SIZE];
-
- if (!get_data (s, pre_header, 8)) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"pre-header read failed\n");
- return 0;
- }
-
-// for (i=0; i<8; i++)
-// mp_msg(MSGT_NETWORK,MSGL_INFO,"pre_header[%d] = %02x (%d)\n",
-// i, pre_header[i], pre_header[i]);
-
- if (pre_header[4] == 0x04) {
-
- int packet_len;
-
- packet_len = (pre_header[7] << 8 | pre_header[6]) - 8;
-
-// mp_msg(MSGT_NETWORK,MSGL_INFO,"asf media packet detected, len=%d\n", packet_len);
-
- if (packet_len < 0 || packet_len > BUF_SIZE) {
- mp_tmsg(MSGT_NETWORK, MSGL_FATAL, "Invalid RTSP packet size, giving up.\n");
- return 0;
- }
-
- if (!get_data (s, data, packet_len)) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"Media data read failed.\n");
- return 0;
- }
-
- streaming_bufferize(stream_ctrl, data, padding);
-
- } else {
-
- int32_t packet_len;
- int command;
-
- if (!get_data (s, (char*)&packet_len, 4)) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"packet_len read failed.\n");
- return 0;
- }
-
- packet_len = get_32 ((unsigned char*)&packet_len, 0) + 4;
-
- if (packet_len < 0 || packet_len > BUF_SIZE) {
- mp_tmsg(MSGT_NETWORK,MSGL_FATAL,"Invalid RTSP packet size, giving up.\n");
- return 0;
- }
-
- if (!get_data (s, data, packet_len)) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"Command data read failed.\n");
- return 0;
- }
-
- if ( (pre_header[7] != 0xb0) || (pre_header[6] != 0x0b)
- || (pre_header[5] != 0xfa) || (pre_header[4] != 0xce) ) {
-
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"missing signature\n");
- return -1;
- }
-
- command = get_32 (data, 24) & 0xFFFF;
-
-// mp_msg(MSGT_NETWORK,MSGL_INFO,"\ncommand packet detected, len=%d cmd=0x%X\n", packet_len, command);
-
- if (command == 0x1b)
- send_command (s, 0x1b, 0, 0, 0, data);
- else if (command == 0x1e) {
- mp_tmsg(MSGT_NETWORK,MSGL_INFO,"Everything done. Thank you for downloading a media file containing proprietary and patented technology.\n");
- return 0;
- }
- else if (command == 0x21 ) {
- // Looks like it's new in WMS9
- // Unknown command, but ignoring it seems to work.
- return 0;
- }
- else if (command != 0x05) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"unknown command %02x\n",command);
- return -1;
- }
- }
-
-// mp_msg(MSGT_NETWORK,MSGL_INFO,"get media packet succ\n");
-
- return 1;
-}
-
-
-static int packet_length1;
-
-static int asf_mmst_streaming_read( int fd, char *buffer, int size, streaming_ctrl_t *stream_ctrl )
-{
- int len;
-
- while( stream_ctrl->buffer_size==0 ) {
- // buffer is empty - fill it!
- int ret = get_media_packet( fd, packet_length1, stream_ctrl);
- if( ret<0 ) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"get_media_packet error : %s\n",strerror(errno));
- return -1;
- } else if (ret==0) //EOF?
- return ret;
- }
-
- len = stream_ctrl->buffer_size-stream_ctrl->buffer_pos;
- if(len>size) len=size;
- memcpy( buffer, (stream_ctrl->buffer)+(stream_ctrl->buffer_pos), len );
- stream_ctrl->buffer_pos += len;
- if( stream_ctrl->buffer_pos>=stream_ctrl->buffer_size ) {
- free( stream_ctrl->buffer );
- stream_ctrl->buffer = NULL;
- stream_ctrl->buffer_size = 0;
- stream_ctrl->buffer_pos = 0;
- }
- return len;
-
-}
-
-static int asf_mmst_streaming_seek( int fd, int64_t pos, streaming_ctrl_t *streaming_ctrl )
-{
- return -1;
- // Shut up gcc warning
- fd++;
- pos++;
- streaming_ctrl=NULL;
-}
-
-int asf_mmst_streaming_start(stream_t *stream)
-{
- char str[1024];
- char data[BUF_SIZE];
- uint8_t asf_header[HDR_BUF_SIZE];
- int asf_header_len;
- int i, packet_length;
- char *path, *unescpath;
- URL_t *url1 = stream->streaming_ctrl->url;
- int s = stream->fd;
-
- if( s>0 ) {
- closesocket( stream->fd );
- stream->fd = -1;
- }
-
- /* parse url */
- path = strchr(url1->file,'/') + 1;
-
- /* mmst filename are not url_escaped by MS MediaPlayer and are expected as
- * "plain text" by the server, so need to decode it here
- */
- unescpath=malloc(strlen(path)+1);
- if (!unescpath) {
- mp_tmsg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed.\n");
- return -1;
- }
- url_unescape_string(unescpath,path);
- path=unescpath;
-
-
- if( url1->port==0 ) {
- url1->port=1755;
- }
- s = connect2Server( url1->hostname, url1->port, 1);
- if( s<0 ) {
- free(path);
- return s;
- }
- mp_tmsg(MSGT_NETWORK,MSGL_INFO,"Connected\n");
-
- seq_num=0;
-
- /*
- * Send the initial connect info including player version no. Client GUID (random) and the host address being connected to.
- * This command is sent at the very start of protocol initiation. It sends local information to the serve
- * cmd 1 0x01
- * */
-
- /* prepare for the url encoding conversion */
-#ifdef CONFIG_ICONV
- url_conv = iconv_open("UTF-16LE", "UTF-8");
-#endif
-
- snprintf (str, 1023, "\034\003NSPlayer/7.0.0.1956; {33715801-BAB3-9D85-24E9-03B90328270A}; Host: %s", url1->hostname);
- string_utf16 (data, str, strlen(str));
-// send_command(s, commandno ....)
- send_command (s, 1, 0, 0x0004000b, strlen(str)*2+2, data);
-
- recv (s, data, BUF_SIZE, 0) ;
-
- /*This sends details of the local machine IP address to a Funnel system at the server.
- * Also, the TCP or UDP transport selection is sent.
- *
- * here 192.168.0.1 is local ip address TCP/UDP states the tronsport we r using
- * and 1037 is the local TCP or UDP socket number
- * cmd 2 0x02
- * */
-
- string_utf16 (&data[8], "\002\000\\\\192.168.0.1\\TCP\\1037", 24);
- memset (data, 0, 8);
- send_command (s, 2, 0, 0, 24*2+10, data);
-
- recv (s, data, BUF_SIZE, 0) ;
-
- /* This command sends file path (at server) and file name request to the server.
- * 0x5 */
-
- string_utf16 (&data[8], path, strlen(path));
- memset (data, 0, 8);
- send_command (s, 5, 0, 0, strlen(path)*2+10, data);
- free(path);
-
- get_answer (s);
-
- /* The ASF header chunk request. Includes ?session' variable for pre header value.
- * After this command is sent,
- * the server replies with 0x11 command and then the header chunk with header data follows.
- * 0x15 */
-
- memset (data, 0, 40);
- data[32] = 2;
-
- send_command (s, 0x15, 1, 0, 40, data);
-
- num_stream_ids = 0;
- /* get_headers(s, asf_header); */
-
- asf_header_len = get_header (s, asf_header, stream->streaming_ctrl);
-// mp_msg(MSGT_NETWORK,MSGL_INFO,"---------------------------------- asf_header %d\n",asf_header);
- if (asf_header_len==0) { //error reading header
- closesocket(s);
- return -1;
- }
- packet_length = interp_header (asf_header, asf_header_len);
-
-
- /*
- * This command is the media stream MBR selector. Switches are always 6 bytes in length.
- * After all switch elements, data ends with bytes [00 00] 00 20 ac 40 [02].
- * Where:
- * [00 00] shows 0x61 0x00 (on the first 33 sent) or 0xff 0xff for ASF files, and with no ending data for WMV files.
- * It is not yet understood what all this means.
- * And the last [02] byte is probably the header ?session' value.
- *
- * 0x33 */
-
- memset (data, 0, 40);
-
- int audio_id = stream->opts->audio_id;
- if (audio_id > 0) {
- data[2] = 0xFF;
- data[3] = 0xFF;
- data[4] = audio_id;
- send_command(s, 0x33, num_stream_ids, 0xFFFF | audio_id << 16, 8, data);
- } else {
- for (i=1; i<num_stream_ids; i++) {
- data [ (i-1) * 6 + 2 ] = 0xFF;
- data [ (i-1) * 6 + 3 ] = 0xFF;
- data [ (i-1) * 6 + 4 ] = stream_ids[i];
- data [ (i-1) * 6 + 5 ] = 0x00;
- }
-
- send_command (s, 0x33, num_stream_ids, 0xFFFF | stream_ids[0] << 16, (num_stream_ids-1)*6+2 , data);
- }
-
- get_answer (s);
-
- /* Start sending file from packet xx.
- * This command is also used for resume downloads or requesting a lost packet.
- * Also used for seeking by sending a play point value which seeks to the media time point.
- * Includes ?session' value in pre header and the maximum media stream time.
- * 0x07 */
-
- memset (data, 0, 40);
-
- for (i=8; i<16; i++)
- data[i] = 0xFF;
-
- data[20] = 0x04;
-
- send_command (s, 0x07, 1, 0xFFFF | stream_ids[0] << 16, 24, data);
-
- stream->fd = s;
- stream->streaming_ctrl->streaming_read = asf_mmst_streaming_read;
- stream->streaming_ctrl->streaming_seek = asf_mmst_streaming_seek;
- stream->streaming_ctrl->status = streaming_playing_e;
- stream->streaming = true;
-
- packet_length1 = packet_length;
- mp_msg(MSGT_NETWORK,MSGL_INFO,"mmst packet_length = %d\n", packet_length);
-
-#ifdef CONFIG_ICONV
- if (url_conv != (iconv_t)(-1))
- iconv_close(url_conv);
-#endif
-
- return 0;
-}
diff --git a/stream/asf_mmst_streaming.h b/stream/asf_mmst_streaming.h
deleted file mode 100644
index 204cf0a450..0000000000
--- a/stream/asf_mmst_streaming.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef MPLAYER_ASF_MMST_STREAMING_H
-#define MPLAYER_ASF_MMST_STREAMING_H
-
-#include "stream.h"
-
-int asf_mmst_streaming_start(stream_t *stream);
-
-#endif /* MPLAYER_ASF_MMST_STREAMING_H */
diff --git a/stream/asf_streaming.c b/stream/asf_streaming.c
deleted file mode 100644
index 862d7c3177..0000000000
--- a/stream/asf_streaming.c
+++ /dev/null
@@ -1,855 +0,0 @@
-/*
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <limits.h>
-
-#include <libavutil/intreadwrite.h>
-
-#include "config.h"
-#include "core/mp_msg.h"
-#include "core/options.h"
-
-#if HAVE_WINSOCK2_H
-#include <winsock2.h>
-#endif
-
-#include "url.h"
-#include "http.h"
-#include "demux/asf.h"
-
-#include "stream.h"
-#include "demux/demux.h"
-#include "asf_mmst_streaming.h"
-#include "network.h"
-#include "tcp.h"
-
-#include "demux/asfguid.h"
-
-static int asf_http_streaming_start(stream_t *stream, int *demuxer_type);
-
-static int asf_read_wrapper(int fd, void *buffer, int len, streaming_ctrl_t *stream_ctrl) {
- uint8_t *buf = buffer;
- while (len > 0) {
- int got = nop_streaming_read(fd, buf, len, stream_ctrl);
- if (got <= 0) {
- mp_tmsg(MSGT_NETWORK, MSGL_ERR, "Error while reading network stream.\n");
- return got;
- }
- buf += got;
- len -= got;
- }
- return 1;
-}
-
-// We can try several protocol for asf streaming
-// * First we can try TCP, but if there is a proxy for
-// internet connection, the TCP connection will not get
-// through
-// * Then we can try HTTP.
-//
-// Note: Using WMP sequence MMST and then HTTP.
-
-static int asf_streaming_start( stream_t *stream, int *demuxer_type) {
- char *proto = stream->streaming_ctrl->url->protocol;
- int fd = -1;
- int port = stream->streaming_ctrl->url->port;
-
- //Is protocol mms or mmst?
- if (!strcasecmp(proto, "mp_mmst") || !strcasecmp(proto, "mp_mms"))
- {
- mp_msg(MSGT_NETWORK,MSGL_V,"Trying ASF/TCP...\n");
- fd = asf_mmst_streaming_start( stream );
- stream->streaming_ctrl->url->port = port;
- if( fd>-1 ) return fd;
- mp_msg(MSGT_NETWORK,MSGL_V," ===> ASF/TCP failed\n");
- if( fd==-2 ) return -1;
- }
-
- //Is protocol http, http_proxy, or mms?
- if (!strcasecmp(proto, "mp_http_proxy") || !strcasecmp(proto, "mp_http") ||
- !strcasecmp(proto, "mp_mms") || !strcasecmp(proto, "mp_mmsh") ||
- !strcasecmp(proto, "mp_mmshttp"))
- {
- mp_msg(MSGT_NETWORK,MSGL_V,"Trying ASF/HTTP...\n");
- fd = asf_http_streaming_start( stream, demuxer_type );
- stream->streaming_ctrl->url->port = port;
- if( fd>-1 ) return fd;
- mp_msg(MSGT_NETWORK,MSGL_V," ===> ASF/HTTP failed\n");
- if( fd==-2 ) return -1;
- }
-
- //everything failed
- return -1;
-}
-
-static int asf_streaming(ASF_stream_chunck_t *stream_chunck, int *drop_packet ) {
-/*
-printf("ASF stream chunck size=%d\n", stream_chunck->size);
-printf("length: %d\n", length );
-printf("0x%02X\n", stream_chunck->type );
-*/
- if( drop_packet!=NULL ) *drop_packet = 0;
-
- if( stream_chunck->size<8 ) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"Ahhhh, stream_chunck size is too small: %d\n", stream_chunck->size);
- return -1;
- }
- if( stream_chunck->size!=stream_chunck->size_confirm ) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"size_confirm mismatch!: %d %d\n", stream_chunck->size, stream_chunck->size_confirm);
- return -1;
- }
-/*
- printf(" type: 0x%02X\n", stream_chunck->type );
- printf(" size: %d (0x%02X)\n", stream_chunck->size, stream_chunck->size );
- printf(" sequence_number: 0x%04X\n", stream_chunck->sequence_number );
- printf(" unknown: 0x%02X\n", stream_chunck->unknown );
- printf(" size_confirm: 0x%02X\n", stream_chunck->size_confirm );
-*/
- switch(stream_chunck->type) {
- case ASF_STREAMING_CLEAR: // $C Clear ASF configuration
- mp_msg(MSGT_NETWORK,MSGL_V,"=====> Clearing ASF stream configuration!\n");
- if( drop_packet!=NULL ) *drop_packet = 1;
- return stream_chunck->size;
- break;
- case ASF_STREAMING_DATA: // $D Data follows
-// printf("=====> Data follows\n");
- break;
- case ASF_STREAMING_END_TRANS: // $E Transfer complete
- mp_msg(MSGT_NETWORK,MSGL_V,"=====> Transfer complete\n");
- if( drop_packet!=NULL ) *drop_packet = 1;
- return stream_chunck->size;
- break;
- case ASF_STREAMING_HEADER: // $H ASF header chunk follows
- mp_msg(MSGT_NETWORK,MSGL_V,"=====> ASF header chunk follows\n");
- break;
- default:
- mp_msg(MSGT_NETWORK,MSGL_V,"=====> Unknown stream type 0x%x\n", stream_chunck->type );
- }
- return stream_chunck->size+4;
-}
-
-static void close_s(stream_t *stream) {
- closesocket(stream->fd);
- stream->fd=-1;
-}
-
-static int max_idx(int s_count, int *s_rates, int bound) {
- int i, best = -1, rate = -1;
- for (i = 0; i < s_count; i++) {
- if (s_rates[i] > rate && s_rates[i] <= bound) {
- rate = s_rates[i];
- best = i;
- }
- }
- return best;
-}
-
-static int asf_streaming_parse_header(stream_t *s, int fd) {
- streaming_ctrl_t* streaming_ctrl = s->streaming_ctrl;
- ASF_stream_chunck_t chunk;
- asf_http_streaming_ctrl_t* asf_ctrl = streaming_ctrl->data;
- char* buffer=NULL, *chunk_buffer=NULL;
- int i,r,size,pos = 0;
- int start;
- int buffer_size = 0;
- int chunk_size2read = 0;
- int bw = streaming_ctrl->bandwidth;
- int *v_rates = NULL, *a_rates = NULL;
- int v_rate = 0, a_rate = 0, a_idx = -1, v_idx = -1;
-
- if(asf_ctrl == NULL) return -1;
-
- // The ASF header can be in several network chunks. For example if the content description
- // is big, the ASF header will be split in 2 network chunk.
- // So we need to retrieve all the chunk before starting to parse the header.
- do {
- if (asf_read_wrapper(fd, &chunk, sizeof(ASF_stream_chunck_t), streaming_ctrl) <= 0)
- return -1;
- // Endian handling of the stream chunk
- le2me_ASF_stream_chunck_t(&chunk);
- size = asf_streaming( &chunk, &r) - sizeof(ASF_stream_chunck_t);
- if(r) mp_tmsg(MSGT_NETWORK,MSGL_WARN,"Warning: drop header ????\n");
- if(size < 0){
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"Error while parsing chunk header\n");
- return -1;
- }
- if (chunk.type != ASF_STREAMING_HEADER) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"Didn't get a header as first chunk !!!!\n");
- return -1;
- }
-
- // audit: do not overflow buffer_size
- if (size > SIZE_MAX - buffer_size) return -1;
- buffer = malloc(size+buffer_size);
- if(buffer == NULL) {
- mp_tmsg(MSGT_NETWORK,MSGL_FATAL,"Error: Can't allocate %d bytes buffer.\n",size+buffer_size);
- return -1;
- }
- if( chunk_buffer!=NULL ) {
- memcpy( buffer, chunk_buffer, buffer_size );
- free( chunk_buffer );
- }
- chunk_buffer = buffer;
- buffer += buffer_size;
- buffer_size += size;
-
- if (asf_read_wrapper(fd, buffer, size, streaming_ctrl) <= 0)
- return -1;
-
- if( chunk_size2read==0 ) {
- ASF_header_t *asfh = (ASF_header_t *)buffer;
- if(size < (int)sizeof(ASF_header_t)) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"Error: Chunk is too small.\n");
- return -1;
- } else mp_msg(MSGT_NETWORK,MSGL_DBG2,"Got chunk\n");
- chunk_size2read = AV_RL64(&asfh->objh.size);
- mp_msg(MSGT_NETWORK,MSGL_DBG2,"Size 2 read=%d\n", chunk_size2read);
- }
- } while( buffer_size<chunk_size2read);
- buffer = chunk_buffer;
- size = buffer_size;
-
- start = sizeof(ASF_header_t);
-
- pos = find_asf_guid(buffer, asf_file_header_guid, start, size);
- if (pos >= 0) {
- ASF_file_header_t *fileh = (ASF_file_header_t *) &buffer[pos];
- pos += sizeof(ASF_file_header_t);
- if (pos > size) goto len_err_out;
-/*
- if(fileh.packetsize != fileh.packetsize2) {
- printf("Error packetsize check don't match\n");
- return -1;
- }
-*/
- asf_ctrl->packet_size = AV_RL32(&fileh->max_packet_size);
- // before playing.
- // preroll: time in ms to bufferize before playing
- unsigned int preroll = (unsigned int)(((double)fileh->preroll/1000.0)*((double)fileh->max_bitrate/8.0));
- // buffer in KBytes, *5 assuming the prefill is 20% of the buffer.
- s->cache_size = preroll / 1024 * 5;
- }
-
- pos = start;
- while ((pos = find_asf_guid(buffer, asf_stream_header_guid, pos, size)) >= 0)
- {
- ASF_stream_header_t *streamh = (ASF_stream_header_t *)&buffer[pos];
- pos += sizeof(ASF_stream_header_t);
- if (pos > size) goto len_err_out;
- switch(ASF_LOAD_GUID_PREFIX(streamh->type)) {
- case 0xF8699E40 : // audio stream
- if(asf_ctrl->audio_streams == NULL){
- asf_ctrl->audio_streams = malloc(sizeof(int));
- asf_ctrl->n_audio = 1;
- } else {
- asf_ctrl->n_audio++;
- asf_ctrl->audio_streams = realloc(asf_ctrl->audio_streams,
- asf_ctrl->n_audio*sizeof(int));
- }
- asf_ctrl->audio_streams[asf_ctrl->n_audio-1] = AV_RL16(&streamh->stream_no);
- break;
- case 0xBC19EFC0 : // video stream
- if(asf_ctrl->video_streams == NULL){
- asf_ctrl->video_streams = malloc(sizeof(int));
- asf_ctrl->n_video = 1;
- } else {
- asf_ctrl->n_video++;
- asf_ctrl->video_streams = realloc(asf_ctrl->video_streams,
- asf_ctrl->n_video*sizeof(int));
- }
- asf_ctrl->video_streams[asf_ctrl->n_video-1] = AV_RL16(&streamh->stream_no);
- break;
- }
- }
-
- // always allocate to avoid lots of ifs later
- v_rates = calloc(asf_ctrl->n_video, sizeof(int));
- a_rates = calloc(asf_ctrl->n_audio, sizeof(int));
-
- pos = find_asf_guid(buffer, asf_stream_group_guid, start, size);
- if (pos >= 0) {
- // stream bitrate properties object
- int stream_count;
- char *ptr = &buffer[pos];
- char *end = &buffer[size];
-
- mp_msg(MSGT_NETWORK, MSGL_V, "Stream bitrate properties object\n");
- if (ptr + 2 > end) goto len_err_out;
- stream_count = AV_RL16(ptr);
- ptr += 2;
- mp_msg(MSGT_NETWORK, MSGL_V, " stream count=[0x%x][%u]\n",
- stream_count, stream_count );
- for( i=0 ; i<stream_count ; i++ ) {
- uint32_t rate;
- int id;
- int j;
- if (ptr + 6 > end) goto len_err_out;
- id = AV_RL16(ptr);
- ptr += 2;
- rate = AV_RL32(ptr);
- ptr += 4;
- mp_msg(MSGT_NETWORK, MSGL_V,
- " stream id=[0x%x][%u]\n", id, id);
- mp_msg(MSGT_NETWORK, MSGL_V,
- " max bitrate=[0x%x][%u]\n", rate, rate);
- for (j = 0; j < asf_ctrl->n_video; j++) {
- if (id == asf_ctrl->video_streams[j]) {
- mp_msg(MSGT_NETWORK, MSGL_V, " is video stream\n");
- v_rates[j] = rate;
- break;
- }
- }
- for (j = 0; j < asf_ctrl->n_audio; j++) {
- if (id == asf_ctrl->audio_streams[j]) {
- mp_msg(MSGT_NETWORK, MSGL_V, " is audio stream\n");
- a_rates[j] = rate;
- break;
- }
- }
- }
- }
- free(buffer);
-
- // automatic stream selection based on bandwidth
- if (bw == 0) bw = INT_MAX;
- mp_msg(MSGT_NETWORK, MSGL_V, "Max bandwidth set to %d\n", bw);
-
- if (asf_ctrl->n_audio) {
- // find lowest-bitrate audio stream
- a_rate = a_rates[0];
- a_idx = 0;
- for (i = 0; i < asf_ctrl->n_audio; i++) {
- if (a_rates[i] < a_rate) {
- a_rate = a_rates[i];
- a_idx = i;
- }
- }
- if (max_idx(asf_ctrl->n_video, v_rates, bw - a_rate) < 0) {
- // both audio and video are not possible, try video only next
- a_idx = -1;
- a_rate = 0;
- }
- }
- // find best video stream
- v_idx = max_idx(asf_ctrl->n_video, v_rates, bw - a_rate);
- if (v_idx >= 0)
- v_rate = v_rates[v_idx];
-
- // find best audio stream
- a_idx = max_idx(asf_ctrl->n_audio, a_rates, bw - v_rate);
-
- free(v_rates);
- free(a_rates);
-
- if (a_idx < 0 && v_idx < 0) {
- mp_tmsg(MSGT_NETWORK, MSGL_FATAL, "Bandwidth too small, file cannot be played!\n");
- return -1;
- }
-
- if (*streaming_ctrl->audio_id_ptr > 0)
- // a audio stream was forced
- asf_ctrl->audio_id = *streaming_ctrl->audio_id_ptr;
- else if (a_idx >= 0)
- asf_ctrl->audio_id = asf_ctrl->audio_streams[a_idx];
- else if (asf_ctrl->n_audio) {
- mp_tmsg(MSGT_NETWORK, MSGL_WARN, "Bandwidth too small, deselected audio stream.\n");
- *streaming_ctrl->audio_id_ptr = -2;
- }
-
- if (*streaming_ctrl->video_id_ptr > 0)
- // a video stream was forced
- asf_ctrl->video_id = *streaming_ctrl->video_id_ptr;
- else if (v_idx >= 0)
- asf_ctrl->video_id = asf_ctrl->video_streams[v_idx];
- else if (asf_ctrl->n_video) {
- mp_tmsg(MSGT_NETWORK, MSGL_WARN, "Bandwidth too small, deselected video stream.\n");
- *streaming_ctrl->video_id_ptr = -2;
- }
-
- return 1;
-
-len_err_out:
- mp_tmsg(MSGT_NETWORK, MSGL_FATAL, "Invalid length in ASF header!\n");
- free(buffer);
- free(v_rates);
- free(a_rates);
- return -1;
-}
-
-static int asf_http_streaming_read( int fd, char *buffer, int size, streaming_ctrl_t *streaming_ctrl ) {
- static ASF_stream_chunck_t chunk;
- int read,chunk_size = 0;
- static int rest = 0, drop_chunk = 0, waiting = 0;
- asf_http_streaming_ctrl_t *asf_http_ctrl = (asf_http_streaming_ctrl_t*)streaming_ctrl->data;
-
- while(1) {
- if (rest == 0 && waiting == 0) {
- if (asf_read_wrapper(fd, &chunk, sizeof(ASF_stream_chunck_t), streaming_ctrl) <= 0)
- return -1;
-
- // Endian handling of the stream chunk
- le2me_ASF_stream_chunck_t(&chunk);
- chunk_size = asf_streaming( &chunk, &drop_chunk );
- if(chunk_size < 0) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"Error while parsing chunk header\n");
- return -1;
- }
- chunk_size -= sizeof(ASF_stream_chunck_t);
-
- if(chunk.type != ASF_STREAMING_HEADER && (!drop_chunk)) {
- if (asf_http_ctrl->packet_size < chunk_size) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"Error: chunk_size > packet_size\n");
- return -1;
- }
- waiting = asf_http_ctrl->packet_size;
- } else {
- waiting = chunk_size;
- }
-
- } else if (rest){
- chunk_size = rest;
- rest = 0;
- }
-
- read = 0;
- if ( waiting >= chunk_size) {
- if (chunk_size > size){
- rest = chunk_size - size;
- chunk_size = size;
- }
- if (asf_read_wrapper(fd, buffer, chunk_size, streaming_ctrl) <= 0)
- return -1;
- read = chunk_size;
- waiting -= read;
- if (drop_chunk) continue;
- }
- if (rest == 0 && waiting > 0 && size-read > 0) {
- int s = FFMIN(waiting,size-read);
- memset(buffer+read,0,s);
- waiting -= s;
- read += s;
- }
- break;
- }
-
- return read;
-}
-
-static int asf_http_streaming_seek( int fd, int64_t pos, streaming_ctrl_t *streaming_ctrl ) {
- return -1;
- // to shut up gcc warning
- fd++;
- pos++;
- streaming_ctrl=NULL;
-}
-
-static int asf_header_check( HTTP_header_t *http_hdr ) {
- ASF_obj_header_t *objh;
- if( http_hdr==NULL ) return -1;
- if( http_hdr->body==NULL || http_hdr->body_size<sizeof(ASF_obj_header_t) ) return -1;
-
- objh = (ASF_obj_header_t*)http_hdr->body;
- if( ASF_LOAD_GUID_PREFIX(objh->guid)==0x75B22630 ) return 0;
- return -1;
-}
-
-static int asf_http_streaming_type(char *content_type, char *features, HTTP_header_t *http_hdr ) {
- if( content_type==NULL ) return ASF_Unknown_e;
- if( !strcasecmp(content_type, "application/octet-stream") ||
- !strcasecmp(content_type, "application/vnd.ms.wms-hdr.asfv1") || // New in Corona, first request
- !strcasecmp(content_type, "application/x-mms-framed") || // New in Corana, second request
- !strcasecmp(content_type, "video/x-ms-wmv") ||
- !strcasecmp(content_type, "video/x-ms-asf")) {
-
- if( strstr(features, "broadcast") ) {
- mp_msg(MSGT_NETWORK,MSGL_V,"=====> ASF Live stream\n");
- return ASF_Live_e;
- } else {
- mp_msg(MSGT_NETWORK,MSGL_V,"=====> ASF Prerecorded\n");
- return ASF_Prerecorded_e;
- }
- } else {
- // Ok in a perfect world, web servers should be well configured
- // so we could used mime type to know the stream type,
- // but guess what? All of them are not well configured.
- // So we have to check for an asf header :(, but it works :p
- if( http_hdr->body_size>sizeof(ASF_obj_header_t) ) {
- if( asf_header_check( http_hdr )==0 ) {
- mp_msg(MSGT_NETWORK,MSGL_V,"=====> ASF Plain text\n");
- return ASF_PlainText_e;
- } else if( (!strcasecmp(content_type, "text/html")) ) {
- mp_msg(MSGT_NETWORK,MSGL_V,"=====> HTML, MPlayer is not a browser...yet!\n");
- return ASF_Unknown_e;
- } else {
- mp_msg(MSGT_NETWORK,MSGL_V,"=====> ASF Redirector\n");
- return ASF_Redirector_e;
- }
- } else {
- if( (!strcasecmp(content_type, "audio/x-ms-wax")) ||
- (!strcasecmp(content_type, "audio/x-ms-wma")) ||
- (!strcasecmp(content_type, "video/x-ms-asf")) ||
- (!strcasecmp(content_type, "video/x-ms-afs")) ||
- (!strcasecmp(content_type, "video/x-ms-wmv")) ||
- (!strcasecmp(content_type, "video/x-ms-wma")) ) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"=====> ASF Redirector\n");
- return ASF_Redirector_e;
- } else if( !strcasecmp(content_type, "text/plain") ) {
- mp_msg(MSGT_NETWORK,MSGL_V,"=====> ASF Plain text\n");
- return ASF_PlainText_e;
- } else {
- mp_msg(MSGT_NETWORK,MSGL_V,"=====> ASF unknown content-type: %s\n", content_type );
- return ASF_Unknown_e;
- }
- }
- }
- return ASF_Unknown_e;
-}
-
-static HTTP_header_t *asf_http_request(streaming_ctrl_t *streaming_ctrl) {
- HTTP_header_t *http_hdr;
- URL_t *url = NULL;
- URL_t *server_url = NULL;
- asf_http_streaming_ctrl_t *asf_http_ctrl;
- char str[250];
- char *ptr;
- int i, enable;
-
- int offset_hi=0, offset_lo=0, length=0;
- int asf_nb_stream=0, stream_id;
-
- // Sanity check
- if( streaming_ctrl==NULL ) return NULL;
- url = streaming_ctrl->url;
- asf_http_ctrl = (asf_http_streaming_ctrl_t*)streaming_ctrl->data;
- if( url==NULL || asf_http_ctrl==NULL ) return NULL;
-
- // Common header for all requests.
- http_hdr = http_new_header();
- http_set_field( http_hdr, "Accept: */*" );
- http_set_field( http_hdr, "User-Agent: NSPlayer/4.1.0.3856" );
- http_add_basic_authentication( http_hdr, url->username, url->password );
-
- // Check if we are using a proxy
- if( !strcasecmp( url->protocol, "mp_http_proxy" ) ) {
- server_url = url_new( (url->file)+1 );
- if( server_url==NULL ) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"invalid proxy URL\n");
- http_free( http_hdr );
- return NULL;
- }
- http_set_uri( http_hdr, server_url->url );
- sprintf( str, "Host: %.220s:%d", server_url->hostname, server_url->port );
- url_free( server_url );
- } else {
- http_set_uri( http_hdr, url->file );
- sprintf( str, "Host: %.220s:%d", url->hostname, url->port );
- }
-
- http_set_field( http_hdr, str );
- http_set_field( http_hdr, "Pragma: xClientGUID={c77e7400-738a-11d2-9add-0020af0a3278}" );
- sprintf(str,
- "Pragma: no-cache,rate=1.000000,stream-time=0,stream-offset=%u:%u,request-context=%d,max-duration=%u",
- offset_hi, offset_lo, asf_http_ctrl->request, length );
- http_set_field( http_hdr, str );
-
- switch( asf_http_ctrl->streaming_type ) {
- case ASF_Live_e:
- case ASF_Prerecorded_e:
- http_set_field( http_hdr, "Pragma: xPlayStrm=1" );
- ptr = str;
- ptr += sprintf( ptr, "Pragma: stream-switch-entry=");
- if(asf_http_ctrl->n_audio > 0) {
- for( i=0; i<asf_http_ctrl->n_audio ; i++ ) {
- stream_id = asf_http_ctrl->audio_streams[i];
- if(stream_id == asf_http_ctrl->audio_id) {
- enable = 0;
- } else {
- enable = 2;
- continue;
- }
- asf_nb_stream++;
- ptr += sprintf(ptr, "ffff:%x:%d ", stream_id, enable);
- }
- }
- if(asf_http_ctrl->n_video > 0) {
- for( i=0; i<asf_http_ctrl->n_video ; i++ ) {
- stream_id = asf_http_ctrl->video_streams[i];
- if(stream_id == asf_http_ctrl->video_id) {
- enable = 0;
- } else {
- enable = 2;
- continue;
- }
- asf_nb_stream++;
- ptr += sprintf(ptr, "ffff:%x:%d ", stream_id, enable);
- }
- }
- http_set_field( http_hdr, str );
- sprintf( str, "Pragma: stream-switch-count=%d", asf_nb_stream );
- http_set_field( http_hdr, str );
- break;
- case ASF_Redirector_e:
- break;
- case ASF_Unknown_e:
- // First request goes here.
- break;
- default:
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"unknown ASF stream type\n");
- }
-
- http_set_field( http_hdr, "Connection: Close" );
- http_build_request( http_hdr );
-
- return http_hdr;
-}
-
-static int asf_http_parse_response(asf_http_streaming_ctrl_t *asf_http_ctrl, HTTP_header_t *http_hdr ) {
- char *content_type, *pragma;
- char features[64] = "\0";
- size_t len;
- if( http_response_parse(http_hdr)<0 ) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"Failed to parse HTTP response.\n");
- return -1;
- }
- switch( http_hdr->status_code ) {
- case 200:
- break;
- case 401: // Authentication required
- return ASF_Authenticate_e;
- default:
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"Server returned %d:%s\n", http_hdr->status_code, http_hdr->reason_phrase);
- return -1;
- }
-
- content_type = http_get_field( http_hdr, "Content-Type");
-//printf("Content-Type: [%s]\n", content_type);
-
- pragma = http_get_field( http_hdr, "Pragma");
- while( pragma!=NULL ) {
- char *comma_ptr=NULL;
- char *end;
-//printf("Pragma: [%s]\n", pragma );
- // The pragma line can get severals attributes
- // separeted with a comma ','.
- do {
- if( !strncasecmp( pragma, "features=", 9) ) {
- pragma += 9;
- end = strstr( pragma, "," );
- if( end==NULL ) {
- len = strlen(pragma);
- } else {
- len = (unsigned int)(end-pragma);
- }
- if(len > sizeof(features) - 1) {
- mp_tmsg(MSGT_NETWORK,MSGL_WARN,"ASF HTTP PARSE WARNING : Pragma %s cut from %zd bytes to %zd\n",pragma,len,sizeof(features) - 1);
- len = sizeof(features) - 1;
- }
- strncpy( features, pragma, len );
- features[len]='\0';
- break;
- }
- comma_ptr = strstr( pragma, "," );
- if( comma_ptr!=NULL ) {
- pragma = comma_ptr+1;
- if( pragma[0]==' ' ) pragma++;
- }
- } while( comma_ptr!=NULL );
- pragma = http_get_next_field( http_hdr );
- }
- asf_http_ctrl->streaming_type = asf_http_streaming_type( content_type, features, http_hdr );
- return 0;
-}
-
-static int asf_http_streaming_start( stream_t *stream, int *demuxer_type ) {
- HTTP_header_t *http_hdr=NULL;
- URL_t *url = stream->streaming_ctrl->url;
- asf_http_streaming_ctrl_t *asf_http_ctrl;
- char buffer[BUFFER_SIZE];
- int i, ret;
- int fd = stream->fd;
- int done;
- int auth_retry = 0;
-
- asf_http_ctrl = malloc(sizeof(asf_http_streaming_ctrl_t));
- if( asf_http_ctrl==NULL ) {
- mp_tmsg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed.\n");
- return -1;
- }
- asf_http_ctrl->streaming_type = ASF_Unknown_e;
- asf_http_ctrl->request = 1;
- asf_http_ctrl->audio_streams = asf_http_ctrl->video_streams = NULL;
- asf_http_ctrl->n_audio = asf_http_ctrl->n_video = 0;
- stream->streaming_ctrl->data = (void*)asf_http_ctrl;
-
- do {
- done = 1;
- if( fd>0 ) closesocket( fd );
-
- if( !strcasecmp( url->protocol, "mp_http_proxy" ) ) {
- if( url->port==0 ) url->port = 8080;
- } else {
- if( url->port==0 ) url->port = 80;
- }
- fd = connect2Server( url->hostname, url->port, 1);
- if( fd<0 ) return fd;
-
- http_hdr = asf_http_request( stream->streaming_ctrl );
- mp_msg(MSGT_NETWORK,MSGL_DBG2,"Request [%s]\n", http_hdr->buffer );
- for(i=0; i < (int)http_hdr->buffer_size ; ) {
- int r = send( fd, http_hdr->buffer+i, http_hdr->buffer_size-i, DEFAULT_SEND_FLAGS );
- if(r <0) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"socket write error: %s\n",strerror(errno));
- goto err_out;
- }
- i += r;
- }
- http_free( http_hdr );
- http_hdr = http_new_header();
- do {
- i = recv( fd, buffer, BUFFER_SIZE, 0 );
-//printf("read: %d\n", i );
- if( i<=0 ) {
- perror("read");
- goto err_out;
- }
- http_response_append( http_hdr, buffer, i );
- } while( !http_is_header_entire( http_hdr ) );
- if( mp_msg_test(MSGT_NETWORK,MSGL_V) ) {
- http_hdr->buffer[http_hdr->buffer_size]='\0';
- mp_msg(MSGT_NETWORK,MSGL_DBG2,"Response [%s]\n", http_hdr->buffer );
- }
- ret = asf_http_parse_response(asf_http_ctrl, http_hdr);
- if( ret<0 ) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"Failed to parse header.\n");
- goto err_out;
- }
- switch( asf_http_ctrl->streaming_type ) {
- case ASF_Live_e:
- case ASF_Prerecorded_e:
- case ASF_PlainText_e:
- if( http_hdr->body_size>0 ) {
- if( streaming_bufferize( stream->streaming_ctrl, http_hdr->body, http_hdr->body_size )<0 ) {
- goto err_out;
- }
- }
- if( asf_http_ctrl->request==1 ) {
- if( asf_http_ctrl->streaming_type!=ASF_PlainText_e ) {
- // First request, we only got the ASF header.
- ret = asf_streaming_parse_header(stream,fd);
- if(ret < 0) goto err_out;
- if(asf_http_ctrl->n_audio == 0 && asf_http_ctrl->n_video == 0) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"No stream found.\n");
- goto err_out;
- }
- asf_http_ctrl->request++;
- done = 0;
- } else {
- done = 1;
- }
- }
- break;
- case ASF_Redirector_e:
- if( http_hdr->body_size>0 ) {
- if( streaming_bufferize( stream->streaming_ctrl, http_hdr->body, http_hdr->body_size )<0 ) {
- goto err_out;
- }
- }
- *demuxer_type = DEMUXER_TYPE_PLAYLIST;
- done = 1;
- break;
- case ASF_Authenticate_e:
- if( http_authenticate( http_hdr, url, &auth_retry)<0 ) return -1;
- asf_http_ctrl->streaming_type = ASF_Unknown_e;
- done = 0;
- break;
- case ASF_Unknown_e:
- default:
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"unknown ASF streaming type\n");
- goto err_out;
- }
- // Check if we got a redirect.
- } while(!done);
-
- stream->fd = fd;
- if( asf_http_ctrl->streaming_type==ASF_PlainText_e || asf_http_ctrl->streaming_type==ASF_Redirector_e ) {
- stream->streaming_ctrl->streaming_read = nop_streaming_read;
- stream->streaming_ctrl->streaming_seek = nop_streaming_seek;
- } else {
- stream->streaming_ctrl->streaming_read = asf_http_streaming_read;
- stream->streaming_ctrl->streaming_seek = asf_http_streaming_seek;
- stream->streaming = true;
- }
- stream->streaming_ctrl->status = streaming_playing_e;
- stream->close = close_s;
-
- http_free( http_hdr );
- return 0;
-
-err_out:
- if (fd > 0)
- closesocket(fd);
- stream->fd = -1;
- http_free(http_hdr);
- return -1;
-}
-
-static int open_s(stream_t *stream,int mode, void* opts, int* file_format) {
- stream->streaming_ctrl = streaming_ctrl_new();
- if( stream->streaming_ctrl==NULL ) {
- return STREAM_ERROR;
- }
- stream->streaming_ctrl->audio_id_ptr = &stream->opts->audio_id;
- stream->streaming_ctrl->video_id_ptr = &stream->opts->video_id;
- stream->streaming_ctrl->bandwidth = network_bandwidth;
- stream->streaming_ctrl->url = url_new_with_proxy(stream->url);
-
- mp_tmsg(MSGT_OPEN, MSGL_INFO, "STREAM_ASF, URL: %s\n", stream->url);
- if((!strncmp(stream->url, "mp_http", 4)) && (*file_format!=DEMUXER_TYPE_ASF && *file_format!=DEMUXER_TYPE_UNKNOWN)) {
- streaming_ctrl_free(stream->streaming_ctrl);
- stream->streaming_ctrl = NULL;
- return STREAM_UNSUPPORTED;
- }
-
- if(asf_streaming_start(stream, file_format) < 0) {
- mp_tmsg(MSGT_OPEN, MSGL_ERR, "Failed, exiting.\n");
- streaming_ctrl_free(stream->streaming_ctrl);
- stream->streaming_ctrl = NULL;
- return STREAM_UNSUPPORTED;
- }
-
- if (*file_format != DEMUXER_TYPE_PLAYLIST)
- *file_format = DEMUXER_TYPE_ASF;
- stream->type = STREAMTYPE_STREAM;
- return STREAM_OK;
-}
-
-const stream_info_t stream_info_asf = {
- "mms and mms over http streaming",
- "null",
- "Bertrand, Reimar Doeffinger, Albeu",
- "originally based on work by Majormms (is that code still there?)",
- open_s,
- {"mp_mms", "mp_mmst", "mp_http", "mp_http_proxy", "mp_mmsh", "mp_mmshttp", NULL},
- NULL,
- 0 // Urls are an option string
-};
diff --git a/stream/cookies.c b/stream/cookies.c
index a7f01ef420..4181458405 100644
--- a/stream/cookies.c
+++ b/stream/cookies.c
@@ -33,8 +33,8 @@
#include "osdep/io.h"
+#include "core/options.h"
#include "cookies.h"
-#include "http.h"
#include "core/mp_msg.h"
#define MAX_COOKIES 20
@@ -72,24 +72,6 @@ static char *col_dup(const char *src)
return dst;
}
-static int right_hand_strcmp(const char *cookie_domain, const char *url_domain)
-{
- int c_l;
- int u_l;
-
- c_l = strlen(cookie_domain);
- u_l = strlen(url_domain);
-
- if (c_l > u_l)
- return -1;
- return strcmp(cookie_domain, url_domain + u_l - c_l);
-}
-
-static int left_hand_strcmp(const char *cookie_path, const char *url_path)
-{
- return strncmp(cookie_path, url_path, strlen(cookie_path));
-}
-
/* Finds the start of all the columns */
static int parse_line(char **ptr, char *cols[6])
{
@@ -196,72 +178,6 @@ static struct cookie_list_type *load_cookies(void)
return NULL;
}
-/* Take an HTTP_header_t, and insert the correct headers. The cookie files are read if necessary. */
-void
-cookies_set(HTTP_header_t * http_hdr, const char *domain, const char *url)
-{
- int found_cookies = 0;
- struct cookie_list_type *cookies[MAX_COOKIES];
- struct cookie_list_type *list, *start;
- int i;
- char *path;
- char *buf;
-
- path = strchr(url, '/');
- if (!path)
- path = "";
-
- if (!cookie_list)
- cookie_list = load_cookies();
-
-
- list = start = cookie_list;
-
- /* Find which cookies we want, removing duplicates. Cookies with the longest domain, then longest path take priority */
- while (list) {
- /* Check the cookie domain and path. Also, we never send "secure" cookies. These should only be sent over HTTPS. */
- if ((right_hand_strcmp(list->domain, domain) == 0)
- && (left_hand_strcmp(list->path, path) == 0) && !list->secure) {
- int replacing = 0;
- for (i = 0; i < found_cookies; i++) {
- if (strcmp(list->name, cookies[i]->name) == 0) {
- replacing = 0;
- if (strlen(list->domain) <= strlen(cookies[i]->domain)) {
- cookies[i] = list;
- } else if (strlen(list->path) <= strlen(cookies[i]->path)) {
- cookies[i] = list;
- }
- }
- }
- if (found_cookies > MAX_COOKIES) {
- /* Cookie jar overflow! */
- break;
- }
- if (!replacing)
- cookies[found_cookies++] = list;
- }
- list = list->next;
- }
-
-
- buf = strdup("Cookie:");
-
- for (i = 0; i < found_cookies; i++) {
- char *nbuf;
-
- nbuf = malloc(strlen(buf) + strlen(" ") + strlen(cookies[i]->name) +
- strlen("=") + strlen(cookies[i]->value) + strlen(";") + 1);
- sprintf(nbuf, "%s %s=%s;", buf, cookies[i]->name,
- cookies[i]->value);
- free(buf);
- buf = nbuf;
- }
-
- if (found_cookies)
- http_set_field(http_hdr, buf);
- free(buf);
-}
-
// Return a cookies string as expected by lavf (libavformat/http.c). The format
// is like a Set-Cookie header (http://curl.haxx.se/rfc/cookie_spec.html),
// separated by newlines.
diff --git a/stream/cookies.h b/stream/cookies.h
index a24560631b..e8b548c112 100644
--- a/stream/cookies.h
+++ b/stream/cookies.h
@@ -24,10 +24,6 @@
#ifndef MPLAYER_COOKIES_H
#define MPLAYER_COOKIES_H
-#include "http.h"
-
-void cookies_set(HTTP_header_t * http_hdr, const char *hostname,
- const char *url);
char *cookies_lavf(void);
#endif /* MPLAYER_COOKIES_H */
diff --git a/stream/http.c b/stream/http.c
deleted file mode 100644
index d17261910f..0000000000
--- a/stream/http.c
+++ /dev/null
@@ -1,966 +0,0 @@
-/*
- * HTTP Helper
- *
- * Copyright (C) 2001 Bertrand Baudet <bertrand_baudet@yahoo.com>
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#if !HAVE_WINSOCK2_H
-#else
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#endif
-
-#include "http.h"
-#include "url.h"
-#include "core/options.h"
-#include "core/mp_msg.h"
-
-#include "stream.h"
-#include "demux/demux.h"
-#include "network.h"
-
-#include "libavutil/base64.h"
-
-#include <libavutil/avutil.h>
-
-typedef struct {
- unsigned metaint;
- unsigned metapos;
- int is_ultravox;
-} scast_data_t;
-
-/**
- * \brief first read any data from sc->buffer then from fd
- * \param fd file descriptor to read data from
- * \param buffer buffer to read into
- * \param len how many bytes to read
- * \param sc streaming control containing buffer to read from first
- * \return len unless there is a read error or eof
- */
-static unsigned my_read(int fd, char *buffer, int len, streaming_ctrl_t *sc) {
- unsigned pos = 0;
- unsigned cp_len = sc->buffer_size - sc->buffer_pos;
- if (cp_len > len)
- cp_len = len;
- memcpy(buffer, &sc->buffer[sc->buffer_pos], cp_len);
- sc->buffer_pos += cp_len;
- pos += cp_len;
- while (pos < len) {
- int ret = recv(fd, &buffer[pos], len - pos, 0);
- if (ret <= 0)
- break;
- pos += ret;
- }
- return pos;
-}
-
-/**
- * \brief read and process (i.e. discard *g*) a block of ultravox metadata
- * \param fd file descriptor to read from
- * \param sc streaming_ctrl_t whose buffer is consumed before reading from fd
- * \return number of real data before next metadata block starts or 0 on error
- *
- * You can use unsv://samples.mplayerhq.hu/V-codecs/VP5/vp5_artefacts.nsv to
- * test.
- */
-static unsigned uvox_meta_read(int fd, streaming_ctrl_t *sc) {
- unsigned metaint;
- unsigned char info[6] = {0, 0, 0, 0, 0, 0};
- int info_read;
- do {
- info_read = my_read(fd, info, 1, sc);
- if (info[0] == 0x00)
- info_read = my_read(fd, info, 6, sc);
- else
- info_read += my_read(fd, &info[1], 5, sc);
- if (info_read != 6) // read error or eof
- return 0;
- // sync byte and reserved flags
- if (info[0] != 0x5a || (info[1] & 0xfc) != 0x00) {
- mp_msg(MSGT_DEMUXER, MSGL_ERR, "Invalid or unknown uvox metadata\n");
- return 0;
- }
- if (info[1] & 0x01)
- mp_msg(MSGT_DEMUXER, MSGL_WARN, "Encrypted ultravox data\n");
- metaint = info[4] << 8 | info[5];
- if ((info[3] & 0xf) < 0x07) { // discard any metadata nonsense
- char *metabuf = malloc(metaint);
- my_read(fd, metabuf, metaint, sc);
- free(metabuf);
- }
- } while ((info[3] & 0xf) < 0x07);
- return metaint;
-}
-
-/**
- * \brief read one scast meta data entry and print it
- * \param fd file descriptor to read from
- * \param sc streaming_ctrl_t whose buffer is consumed before reading from fd
- */
-static void scast_meta_read(int fd, streaming_ctrl_t *sc) {
- unsigned char tmp = 0;
- unsigned metalen;
- my_read(fd, &tmp, 1, sc);
- metalen = tmp * 16;
- if (metalen > 0) {
- int i;
- uint8_t *info = malloc(metalen + 1);
- unsigned nlen = my_read(fd, info, metalen, sc);
- // avoid breaking the user's terminal too much
- if (nlen > 256) nlen = 256;
- for (i = 0; i < nlen; i++)
- if (info[i] && info[i] < 32) info[i] = '?';
- info[nlen] = 0;
- mp_msg(MSGT_DEMUXER, MSGL_INFO, "\nICY Info: %s\n", info);
- free(info);
- }
-}
-
-/**
- * \brief read data from scast/ultravox stream without any metadata
- * \param fd file descriptor to read from
- * \param buffer buffer to read data into
- * \param size number of bytes to read
- * \param sc streaming_ctrl_t whose buffer is consumed before reading from fd
- */
-static int scast_streaming_read(int fd, char *buffer, int size,
- streaming_ctrl_t *sc) {
- scast_data_t *sd = (scast_data_t *)sc->data;
- unsigned block, ret;
- unsigned done = 0;
-
- // first read remaining data up to next metadata
- block = sd->metaint - sd->metapos;
- if (block > size)
- block = size;
- ret = my_read(fd, buffer, block, sc);
- sd->metapos += ret;
- done += ret;
- if (ret != block) // read problems or eof
- size = done;
-
- while (done < size) { // now comes the metadata
- if (sd->is_ultravox)
- {
- sd->metaint = uvox_meta_read(fd, sc);
- if (!sd->metaint)
- size = done;
- }
- else
- scast_meta_read(fd, sc); // read and display metadata
- sd->metapos = 0;
- block = size - done;
- if (block > sd->metaint)
- block = sd->metaint;
- ret = my_read(fd, &buffer[done], block, sc);
- sd->metapos += ret;
- done += ret;
- if (ret != block) // read problems or eof
- size = done;
- }
- return done;
-}
-
-static int scast_streaming_start(stream_t *stream) {
- int metaint;
- scast_data_t *scast_data;
- HTTP_header_t *http_hdr = stream->streaming_ctrl->data;
- if (!stream || stream->fd < 0 || !http_hdr)
- return -1;
- int is_ultravox = strcasecmp(stream->streaming_ctrl->url->protocol, "unsv") == 0;
- if (is_ultravox)
- metaint = 0;
- else {
- metaint = -1;
- char *h = http_get_field(http_hdr, "Icy-MetaInt");
- if (h)
- metaint = atoi(h);
- if (metaint <= 0)
- return -1;
- }
- stream->streaming_ctrl->buffer = malloc(http_hdr->body_size);
- stream->streaming_ctrl->buffer_size = http_hdr->body_size;
- stream->streaming_ctrl->buffer_pos = 0;
- memcpy(stream->streaming_ctrl->buffer, http_hdr->body, http_hdr->body_size);
- scast_data = malloc(sizeof(scast_data_t));
- scast_data->metaint = metaint;
- scast_data->metapos = 0;
- scast_data->is_ultravox = is_ultravox;
- http_free(http_hdr);
- stream->streaming_ctrl->data = scast_data;
- stream->streaming_ctrl->streaming_read = scast_streaming_read;
- stream->streaming_ctrl->streaming_seek = NULL;
- stream->streaming_ctrl->status = streaming_playing_e;
- stream->streaming = true;
- return 0;
-}
-
-static int nop_streaming_start( stream_t *stream ) {
- HTTP_header_t *http_hdr = NULL;
- char *next_url=NULL;
- int fd,ret;
- if( stream==NULL ) return -1;
-
- fd = stream->fd;
- if( fd<0 ) {
- fd = http_send_request( stream->streaming_ctrl->url, 0 );
- if( fd<0 ) return -1;
- http_hdr = http_read_response( fd );
- if( http_hdr==NULL ) return -1;
-
- switch( http_hdr->status_code ) {
- case 200: // OK
- mp_msg(MSGT_NETWORK,MSGL_V,"Content-Type: [%s]\n", http_get_field(http_hdr, "Content-Type") );
- mp_msg(MSGT_NETWORK,MSGL_V,"Content-Length: [%s]\n", http_get_field(http_hdr, "Content-Length") );
- if( http_hdr->body_size>0 ) {
- if( streaming_bufferize( stream->streaming_ctrl, http_hdr->body, http_hdr->body_size )<0 ) {
- http_free( http_hdr );
- return -1;
- }
- }
- break;
- // Redirect
- case 301: // Permanently
- case 302: // Temporarily
- case 303: // See Other
- case 307: // Temporarily (since HTTP/1.1)
- ret=-1;
- next_url = http_get_field( http_hdr, "Location" );
-
- if (next_url != NULL) {
- mp_msg(MSGT_NETWORK,MSGL_STATUS,"Redirected: Using this url instead %s\n",next_url);
- stream->streaming_ctrl->url=url_new_with_proxy(next_url);
- ret=nop_streaming_start(stream); //recursively get streaming started
- } else {
- mp_msg(MSGT_NETWORK,MSGL_ERR,"Redirection failed\n");
- closesocket( fd );
- fd = -1;
- }
- return ret;
- break;
- case 401: //Authorization required
- case 403: //Forbidden
- case 404: //Not found
- case 500: //Server Error
- default:
- mp_msg(MSGT_NETWORK,MSGL_ERR,"Server returned code %d: %s\n", http_hdr->status_code, http_hdr->reason_phrase );
- closesocket( fd );
- fd = -1;
- return -1;
- break;
- }
- stream->fd = fd;
- } else {
- http_hdr = (HTTP_header_t*)stream->streaming_ctrl->data;
- if( http_hdr->body_size>0 ) {
- if( streaming_bufferize( stream->streaming_ctrl, http_hdr->body, http_hdr->body_size )<0 ) {
- http_free( http_hdr );
- stream->streaming_ctrl->data = NULL;
- return -1;
- }
- }
- }
-
- if( http_hdr ) {
- http_free( http_hdr );
- stream->streaming_ctrl->data = NULL;
- }
-
- stream->streaming_ctrl->streaming_read = nop_streaming_read;
- stream->streaming_ctrl->streaming_seek = nop_streaming_seek;
- stream->streaming_ctrl->status = streaming_playing_e;
- stream->streaming = true;
- return 0;
-}
-
-HTTP_header_t *
-http_new_header(void) {
- HTTP_header_t *http_hdr;
-
- http_hdr = calloc(1, sizeof(*http_hdr));
- if( http_hdr==NULL ) return NULL;
-
- return http_hdr;
-}
-
-void
-http_free( HTTP_header_t *http_hdr ) {
- HTTP_field_t *field, *field2free;
- if( http_hdr==NULL ) return;
- free(http_hdr->protocol);
- free(http_hdr->uri);
- free(http_hdr->reason_phrase);
- free(http_hdr->field_search);
- free(http_hdr->method);
- free(http_hdr->buffer);
- field = http_hdr->first_field;
- while( field!=NULL ) {
- field2free = field;
- free(field->field_name);
- field = field->next;
- free( field2free );
- }
- free( http_hdr );
- http_hdr = NULL;
-}
-
-int
-http_response_append( HTTP_header_t *http_hdr, char *response, int length ) {
- if( http_hdr==NULL || response==NULL || length<0 ) return -1;
-
- if( (unsigned)length > SIZE_MAX - http_hdr->buffer_size - 1) {
- mp_msg(MSGT_NETWORK,MSGL_FATAL,"Bad size in memory (re)allocation\n");
- return -1;
- }
- http_hdr->buffer = realloc( http_hdr->buffer, http_hdr->buffer_size+length+1 );
- if( http_hdr->buffer==NULL ) {
- mp_msg(MSGT_NETWORK,MSGL_FATAL,"Memory (re)allocation failed\n");
- return -1;
- }
- memcpy( http_hdr->buffer+http_hdr->buffer_size, response, length );
- http_hdr->buffer_size += length;
- http_hdr->buffer[http_hdr->buffer_size]=0; // close the string!
- return http_hdr->buffer_size;
-}
-
-int
-http_is_header_entire( HTTP_header_t *http_hdr ) {
- if( http_hdr==NULL ) return -1;
- if( http_hdr->buffer==NULL ) return 0; // empty
-
- if(http_hdr->buffer_size > 128*1024) return 1;
- if( strstr(http_hdr->buffer, "\r\n\r\n")==NULL &&
- strstr(http_hdr->buffer, "\n\n")==NULL ) return 0;
- return 1;
-}
-
-int
-http_response_parse( HTTP_header_t *http_hdr ) {
- char *hdr_ptr, *ptr;
- char *field=NULL;
- int pos_hdr_sep, hdr_sep_len;
- size_t len;
- if( http_hdr==NULL ) return -1;
- if( http_hdr->is_parsed ) return 0;
-
- // Get the protocol
- hdr_ptr = strstr( http_hdr->buffer, " " );
- if( hdr_ptr==NULL ) {
- mp_msg(MSGT_NETWORK,MSGL_ERR,"Malformed answer. No space separator found.\n");
- return -1;
- }
- len = hdr_ptr-http_hdr->buffer;
- http_hdr->protocol = malloc(len+1);
- if( http_hdr->protocol==NULL ) {
- mp_msg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed\n");
- return -1;
- }
- strncpy( http_hdr->protocol, http_hdr->buffer, len );
- http_hdr->protocol[len]='\0';
- if( !strncasecmp( http_hdr->protocol, "HTTP", 4) ) {
- if( sscanf( http_hdr->protocol+5,"1.%d", &(http_hdr->http_minor_version) )!=1 ) {
- mp_msg(MSGT_NETWORK,MSGL_ERR,"Malformed answer. Unable to get HTTP minor version.\n");
- return -1;
- }
- }
-
- // Get the status code
- if( sscanf( ++hdr_ptr, "%d", &(http_hdr->status_code) )!=1 ) {
- mp_msg(MSGT_NETWORK,MSGL_ERR,"Malformed answer. Unable to get status code.\n");
- return -1;
- }
- hdr_ptr += 4;
-
- // Get the reason phrase
- ptr = strstr( hdr_ptr, "\n" );
- if( ptr==NULL ) {
- mp_msg(MSGT_NETWORK,MSGL_ERR,"Malformed answer. Unable to get the reason phrase.\n");
- return -1;
- }
- len = ptr-hdr_ptr;
- http_hdr->reason_phrase = malloc(len+1);
- if( http_hdr->reason_phrase==NULL ) {
- mp_msg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed\n");
- return -1;
- }
- strncpy( http_hdr->reason_phrase, hdr_ptr, len );
- if( http_hdr->reason_phrase[len-1]=='\r' ) {
- len--;
- }
- http_hdr->reason_phrase[len]='\0';
-
- // Set the position of the header separator: \r\n\r\n
- hdr_sep_len = 4;
- ptr = strstr( http_hdr->buffer, "\r\n\r\n" );
- if( ptr==NULL ) {
- hdr_sep_len = 2;
- ptr = strstr( http_hdr->buffer, "\n\n" );
- if( ptr==NULL ) {
- mp_msg(MSGT_NETWORK,MSGL_ERR,"Header may be incomplete. No CRLF CRLF found.\n");
- hdr_sep_len = 0;
- }
- }
- pos_hdr_sep = ptr-http_hdr->buffer;
-
- // Point to the first line after the method line.
- hdr_ptr = strstr( http_hdr->buffer, "\n" )+1;
- do {
- ptr = hdr_ptr;
- while( *ptr!='\r' && *ptr!='\n' ) ptr++;
- len = ptr-hdr_ptr;
- if (len == 0 || !memchr(hdr_ptr, ':', len)) {
- mp_msg(MSGT_NETWORK, MSGL_ERR, "Broken response header, missing ':'\n");
- pos_hdr_sep = ptr - http_hdr->buffer;
- hdr_sep_len = 0;
- break;
- }
- if (len > 16 && !strncasecmp(hdr_ptr + 4, "icy-metaint:", 12))
- {
- mp_msg(MSGT_NETWORK, MSGL_WARN, "Server sent a severely broken icy-metaint HTTP header!\n");
- hdr_ptr += 4;
- len -= 4;
- }
- field = realloc(field, len+1);
- if( field==NULL ) {
- mp_msg(MSGT_NETWORK,MSGL_ERR,"Memory allocation failed\n");
- return -1;
- }
- strncpy( field, hdr_ptr, len );
- field[len]='\0';
- http_set_field( http_hdr, field );
- hdr_ptr = ptr+((*ptr=='\r')?2:1);
- } while( hdr_ptr<(http_hdr->buffer+pos_hdr_sep) );
-
- free(field);
-
- if( pos_hdr_sep+hdr_sep_len<http_hdr->buffer_size ) {
- // Response has data!
- http_hdr->body = http_hdr->buffer+pos_hdr_sep+hdr_sep_len;
- http_hdr->body_size = http_hdr->buffer_size-(pos_hdr_sep+hdr_sep_len);
- }
-
- http_hdr->is_parsed = 1;
- return 0;
-}
-
-char *
-http_build_request( HTTP_header_t *http_hdr ) {
- char *ptr;
- int len;
- HTTP_field_t *field;
- if( http_hdr==NULL ) return NULL;
- if( http_hdr->uri==NULL ) return NULL;
-
- if( http_hdr->method==NULL ) http_set_method( http_hdr, "GET");
- if( http_hdr->uri==NULL ) http_set_uri( http_hdr, "/");
- if( !http_hdr->uri || !http_hdr->method)
- return NULL;
-
- //**** Compute the request length
- // Add the Method line
- len = strlen(http_hdr->method)+strlen(http_hdr->uri)+12;
- // Add the fields
- field = http_hdr->first_field;
- while( field!=NULL ) {
- len += strlen(field->field_name)+2;
- field = field->next;
- }
- // Add the CRLF
- len += 2;
- // Add the body
- if( http_hdr->body!=NULL ) {
- len += http_hdr->body_size;
- }
- // Free the buffer if it was previously used
- if( http_hdr->buffer!=NULL ) {
- free( http_hdr->buffer );
- http_hdr->buffer = NULL;
- }
- http_hdr->buffer = malloc(len+1);
- if( http_hdr->buffer==NULL ) {
- mp_msg(MSGT_NETWORK,MSGL_ERR,"Memory allocation failed\n");
- return NULL;
- }
- http_hdr->buffer_size = len;
-
- //*** Building the request
- ptr = http_hdr->buffer;
- // Add the method line
- ptr += sprintf( ptr, "%s %s HTTP/1.%d\r\n", http_hdr->method, http_hdr->uri, http_hdr->http_minor_version );
- field = http_hdr->first_field;
- // Add the field
- while( field!=NULL ) {
- ptr += sprintf( ptr, "%s\r\n", field->field_name );
- field = field->next;
- }
- ptr += sprintf( ptr, "\r\n" );
- // Add the body
- if( http_hdr->body!=NULL ) {
- memcpy( ptr, http_hdr->body, http_hdr->body_size );
- }
-
- return http_hdr->buffer;
-}
-
-char *
-http_get_field( HTTP_header_t *http_hdr, const char *field_name ) {
- if( http_hdr==NULL || field_name==NULL ) return NULL;
- http_hdr->field_search_pos = http_hdr->first_field;
- http_hdr->field_search = realloc( http_hdr->field_search, strlen(field_name)+1 );
- if( http_hdr->field_search==NULL ) {
- mp_msg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed\n");
- return NULL;
- }
- strcpy( http_hdr->field_search, field_name );
- return http_get_next_field( http_hdr );
-}
-
-char *
-http_get_next_field( HTTP_header_t *http_hdr ) {
- char *ptr;
- HTTP_field_t *field;
- if( http_hdr==NULL ) return NULL;
-
- field = http_hdr->field_search_pos;
- while( field!=NULL ) {
- ptr = strstr( field->field_name, ":" );
- if( ptr==NULL ) return NULL;
- if( !strncasecmp( field->field_name, http_hdr->field_search, ptr-(field->field_name) ) ) {
- ptr++; // Skip the column
- while( ptr[0]==' ' ) ptr++; // Skip the spaces if there is some
- http_hdr->field_search_pos = field->next;
- return ptr; // return the value without the field name
- }
- field = field->next;
- }
- return NULL;
-}
-
-void
-http_set_field( HTTP_header_t *http_hdr, const char *field_name ) {
- HTTP_field_t *new_field;
- if( http_hdr==NULL || field_name==NULL ) return;
-
- new_field = malloc(sizeof(HTTP_field_t));
- if( new_field==NULL ) {
- mp_msg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed\n");
- return;
- }
- new_field->next = NULL;
- new_field->field_name = malloc(strlen(field_name)+1);
- if( new_field->field_name==NULL ) {
- mp_msg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed\n");
- free(new_field);
- return;
- }
- strcpy( new_field->field_name, field_name );
-
- if( http_hdr->last_field==NULL ) {
- http_hdr->first_field = new_field;
- } else {
- http_hdr->last_field->next = new_field;
- }
- http_hdr->last_field = new_field;
- http_hdr->field_nb++;
-}
-
-void
-http_set_method( HTTP_header_t *http_hdr, const char *method ) {
- if( http_hdr==NULL || method==NULL ) return;
-
- http_hdr->method = malloc(strlen(method)+1);
- if( http_hdr->method==NULL ) {
- mp_msg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed\n");
- return;
- }
- strcpy( http_hdr->method, method );
-}
-
-void
-http_set_uri( HTTP_header_t *http_hdr, const char *uri ) {
- if( http_hdr==NULL || uri==NULL ) return;
-
- http_hdr->uri = malloc(strlen(uri)+1);
- if( http_hdr->uri==NULL ) {
- mp_msg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed\n");
- return;
- }
- strcpy( http_hdr->uri, uri );
-}
-
-static int
-http_add_authentication( HTTP_header_t *http_hdr, const char *username, const char *password, const char *auth_str ) {
- char *auth = NULL, *usr_pass = NULL, *b64_usr_pass = NULL;
- int encoded_len, pass_len=0;
- size_t auth_len, usr_pass_len;
- int res = -1;
- if( http_hdr==NULL || username==NULL ) return -1;
-
- if( password!=NULL ) {
- pass_len = strlen(password);
- }
-
- usr_pass_len = strlen(username) + 1 + pass_len;
- usr_pass = malloc(usr_pass_len + 1);
- if( usr_pass==NULL ) {
- mp_msg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed\n");
- goto out;
- }
-
- sprintf( usr_pass, "%s:%s", username, (password==NULL)?"":password );
-
- encoded_len = AV_BASE64_SIZE(usr_pass_len);
- b64_usr_pass = malloc(encoded_len);
- if( b64_usr_pass==NULL ) {
- mp_msg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed\n");
- goto out;
- }
- av_base64_encode(b64_usr_pass, encoded_len, usr_pass, usr_pass_len);
-
- auth_len = encoded_len + 100;
- auth = malloc(auth_len);
- if( auth==NULL ) {
- mp_msg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed\n");
- goto out;
- }
-
- snprintf(auth, auth_len, "%s: Basic %s", auth_str, b64_usr_pass);
- http_set_field( http_hdr, auth );
- res = 0;
-
-out:
- free( usr_pass );
- free( b64_usr_pass );
- free( auth );
-
- return res;
-}
-
-int
-http_add_basic_authentication( HTTP_header_t *http_hdr, const char *username, const char *password ) {
- return http_add_authentication(http_hdr, username, password, "Authorization");
-}
-
-int
-http_add_basic_proxy_authentication( HTTP_header_t *http_hdr, const char *username, const char *password ) {
- return http_add_authentication(http_hdr, username, password, "Proxy-Authorization");
-}
-
-void
-http_debug_hdr( HTTP_header_t *http_hdr ) {
- HTTP_field_t *field;
- int i = 0;
- if( http_hdr==NULL ) return;
-
- mp_msg(MSGT_NETWORK,MSGL_V,"--- HTTP DEBUG HEADER --- START ---\n");
- mp_msg(MSGT_NETWORK,MSGL_V,"protocol: [%s]\n", http_hdr->protocol );
- mp_msg(MSGT_NETWORK,MSGL_V,"http minor version: [%d]\n", http_hdr->http_minor_version );
- mp_msg(MSGT_NETWORK,MSGL_V,"uri: [%s]\n", http_hdr->uri );
- mp_msg(MSGT_NETWORK,MSGL_V,"method: [%s]\n", http_hdr->method );
- mp_msg(MSGT_NETWORK,MSGL_V,"status code: [%d]\n", http_hdr->status_code );
- mp_msg(MSGT_NETWORK,MSGL_V,"reason phrase: [%s]\n", http_hdr->reason_phrase );
- mp_msg(MSGT_NETWORK,MSGL_V,"body size: [%zd]\n", http_hdr->body_size );
-
- mp_msg(MSGT_NETWORK,MSGL_V,"Fields:\n");
- field = http_hdr->first_field;
- while( field!=NULL ) {
- mp_msg(MSGT_NETWORK,MSGL_V," %d - %s\n", i++, field->field_name );
- field = field->next;
- }
- mp_msg(MSGT_NETWORK,MSGL_V,"--- HTTP DEBUG HEADER --- END ---\n");
-}
-
-static void print_icy_metadata(HTTP_header_t *http_hdr) {
- const char *field_data;
- // note: I skip icy-notice1 and 2, as they contain html <BR>
- // and are IMHO useless info ::atmos
- if( (field_data = http_get_field(http_hdr, "icy-name")) != NULL )
- mp_msg(MSGT_NETWORK,MSGL_INFO,"Name : %s\n", field_data);
- if( (field_data = http_get_field(http_hdr, "icy-genre")) != NULL )
- mp_msg(MSGT_NETWORK,MSGL_INFO,"Genre : %s\n", field_data);
- if( (field_data = http_get_field(http_hdr, "icy-url")) != NULL )
- mp_msg(MSGT_NETWORK,MSGL_INFO,"Website: %s\n", field_data);
- // XXX: does this really mean public server? ::atmos
- if( (field_data = http_get_field(http_hdr, "icy-pub")) != NULL )
- mp_msg(MSGT_NETWORK,MSGL_INFO,"Public : %s\n", atoi(field_data)?"yes":"no");
- if( (field_data = http_get_field(http_hdr, "icy-br")) != NULL )
- mp_msg(MSGT_NETWORK,MSGL_INFO,"Bitrate: %skbit/s\n", field_data);
-}
-
-//! If this function succeeds you must closesocket stream->fd
-static int http_streaming_start(stream_t *stream, int* file_format) {
- HTTP_header_t *http_hdr = NULL;
- int fd = stream->fd;
- int res = STREAM_UNSUPPORTED;
- int redirect = 0;
- int auth_retry=0;
- int seekable=0;
- char *content_type;
- const char *content_length;
- char *next_url;
- URL_t *url = stream->streaming_ctrl->url;
-
- do
- {
- redirect = 0;
- if (fd >= 0) closesocket(fd);
- fd = http_send_request( url, 0 );
- if( fd<0 ) {
- goto err_out;
- }
-
- http_free(http_hdr);
- http_hdr = http_read_response( fd );
- if( http_hdr==NULL ) {
- goto err_out;
- }
-
- if( mp_msg_test(MSGT_NETWORK,MSGL_V) ) {
- http_debug_hdr( http_hdr );
- }
-
- // Check if we can make partial content requests and thus seek in http-streams
- if( http_hdr!=NULL && http_hdr->status_code==200 ) {
- const char *accept_ranges = http_get_field(http_hdr,"Accept-Ranges");
- const char *server = http_get_field(http_hdr, "Server");
- if (accept_ranges)
- seekable = strncmp(accept_ranges,"bytes",5)==0;
- else if (server && (strcmp(server, "gvs 1.0") == 0 ||
- strncmp(server, "MakeMKV", 7) == 0)) {
- // HACK for youtube and MakeMKV incorrectly claiming not to support seeking
- mp_msg(MSGT_NETWORK, MSGL_WARN, "Broken webserver, incorrectly claims to not support Accept-Ranges\n");
- seekable = 1;
- }
- }
-
- print_icy_metadata(http_hdr);
-
- // Check if the response is an ICY status_code reason_phrase
- if( !strcasecmp(http_hdr->protocol, "ICY") ||
- http_get_field(http_hdr, "Icy-MetaInt") ) {
- switch( http_hdr->status_code ) {
- case 200: { // OK
- char *field_data;
- // If content-type == video/nsv we most likely have a winamp video stream
- // otherwise it should be mp3. if there are more types consider adding mime type
- // handling like later
- if ( (field_data = http_get_field(http_hdr, "content-type")) != NULL && (!strcmp(field_data, "video/nsv") || !strcmp(field_data, "misc/ultravox")))
- *file_format = DEMUXER_TYPE_NSV;
- else if ( (field_data = http_get_field(http_hdr, "content-type")) != NULL && (!strcmp(field_data, "audio/aacp") || !strcmp(field_data, "audio/aac")))
- *file_format = DEMUXER_TYPE_AAC;
- else
- *file_format = DEMUXER_TYPE_LAVF;
- res = STREAM_ERROR;
- goto out;
- }
- case 400: // Server Full
- mp_msg(MSGT_NETWORK,MSGL_ERR,"Error: ICY-Server is full, skipping!\n");
- goto err_out;
- case 401: // Service Unavailable
- mp_msg(MSGT_NETWORK,MSGL_ERR,"Error: ICY-Server return service unavailable, skipping!\n");
- goto err_out;
- case 403: // Service Forbidden
- mp_msg(MSGT_NETWORK,MSGL_ERR,"Error: ICY-Server return 'Service Forbidden'\n");
- goto err_out;
- case 404: // Resource Not Found
- mp_msg(MSGT_NETWORK,MSGL_ERR,"Error: ICY-Server couldn't find requested stream, skipping!\n");
- goto err_out;
- default:
- mp_msg(MSGT_NETWORK,MSGL_ERR,"Error: unhandled ICY-Errorcode, contact MPlayer developers!\n");
- goto err_out;
- }
- }
-
- // Assume standard http if not ICY
- switch( http_hdr->status_code ) {
- case 200: // OK
- content_length = http_get_field(http_hdr, "Content-Length");
- if (content_length) {
- mp_msg(MSGT_NETWORK,MSGL_V,"Content-Length: [%s]\n", content_length);
- stream->end_pos = atoll(content_length);
- }
- // Look if we can use the Content-Type
- content_type = http_get_field( http_hdr, "Content-Type" );
- if( content_type!=NULL ) {
- unsigned int i;
-
- mp_msg(MSGT_NETWORK,MSGL_V,"Content-Type: [%s]\n", content_type );
- // Check in the mime type table for a demuxer type
- for (i = 0; mime_type_table[i].mime_type != NULL; i++) {
- if( !strcasecmp( content_type, mime_type_table[i].mime_type ) ) {
- *file_format = mime_type_table[i].demuxer_type;
- res = seekable;
- goto out;
- }
- }
- }
- // Not found in the mime type table, don't fail,
- // we should try raw HTTP
- res = seekable;
- goto out;
- // Redirect
- case 301: // Permanently
- case 302: // Temporarily
- case 303: // See Other
- case 307: // Temporarily (since HTTP/1.1)
- // TODO: RFC 2616, recommand to detect infinite redirection loops
- next_url = http_get_field( http_hdr, "Location" );
- if( next_url!=NULL ) {
- int is_ultravox = strcasecmp(stream->streaming_ctrl->url->protocol, "unsv") == 0;
- stream->streaming_ctrl->url = url_redirect( &url, next_url );
- if (url_is_protocol(url, "mms")) {
- res = STREAM_REDIRECTED;
- goto err_out;
- }
- if (!url_is_protocol(url, "http")) {
- mp_msg(MSGT_NETWORK,MSGL_ERR,"Unsupported http %d redirect to %s protocol\n", http_hdr->status_code, url->protocol);
- goto err_out;
- }
- if (is_ultravox)
- url_set_protocol(url, "unsv");
- redirect = 1;
- }
- break;
- case 401: // Authentication required
- if( http_authenticate(http_hdr, url, &auth_retry)<0 )
- goto err_out;
- redirect = 1;
- break;
- default:
- mp_msg(MSGT_NETWORK,MSGL_ERR,"Server returned %d: %s\n", http_hdr->status_code, http_hdr->reason_phrase );
- goto err_out;
- }
- } while( redirect );
-
-err_out:
- if (fd >= 0) closesocket( fd );
- fd = -1;
- http_free( http_hdr );
- http_hdr = NULL;
-out:
- stream->streaming_ctrl->data = http_hdr;
- stream->fd = fd;
- return res;
-}
-
-static int fixup_open(stream_t *stream,int seekable) {
- HTTP_header_t *http_hdr = stream->streaming_ctrl->data;
- int is_icy = http_hdr && http_get_field(http_hdr, "Icy-MetaInt");
- int is_ultravox = strcasecmp(stream->streaming_ctrl->url->protocol, "unsv") == 0;
-
- stream->type = STREAMTYPE_STREAM;
- if(!is_icy && !is_ultravox && seekable)
- {
- stream->flags |= MP_STREAM_SEEK;
- stream->seek = http_seek;
- }
- stream->streaming_ctrl->bandwidth = network_bandwidth;
- if ((!is_icy && !is_ultravox) || scast_streaming_start(stream))
- if(nop_streaming_start( stream )) {
- mp_msg(MSGT_NETWORK,MSGL_ERR,"nop_streaming_start failed\n");
- if (stream->fd >= 0)
- closesocket(stream->fd);
- stream->fd = -1;
- streaming_ctrl_free(stream->streaming_ctrl);
- stream->streaming_ctrl = NULL;
- return STREAM_UNSUPPORTED;
- }
-
- return STREAM_OK;
-}
-
-static int open_s1(stream_t *stream,int mode, void* opts, int* file_format) {
- int seekable=0;
-
- stream->streaming_ctrl = streaming_ctrl_new();
- if( stream->streaming_ctrl==NULL ) {
- return STREAM_ERROR;
- }
- stream->streaming_ctrl->bandwidth = network_bandwidth;
- stream->streaming_ctrl->url = url_new_with_proxy(stream->url);
-
- mp_msg(MSGT_OPEN, MSGL_V, "STREAM_HTTP(1), URL: %s\n", stream->url);
- seekable = http_streaming_start(stream, file_format);
- if((seekable < 0) || (*file_format == DEMUXER_TYPE_ASF)) {
- if (stream->fd >= 0)
- closesocket(stream->fd);
- stream->fd = -1;
- if (seekable == STREAM_REDIRECTED)
- return seekable;
- streaming_ctrl_free(stream->streaming_ctrl);
- stream->streaming_ctrl = NULL;
- return STREAM_UNSUPPORTED;
- }
-
- return fixup_open(stream, seekable);
-}
-
-static int open_s2(stream_t *stream,int mode, void* opts, int* file_format) {
- int seekable=0;
-
- stream->streaming_ctrl = streaming_ctrl_new();
- if( stream->streaming_ctrl==NULL ) {
- return STREAM_ERROR;
- }
- stream->streaming_ctrl->bandwidth = network_bandwidth;
- stream->streaming_ctrl->url = url_new_with_proxy(stream->url);
-
- mp_msg(MSGT_OPEN, MSGL_V, "STREAM_HTTP(2), URL: %s\n", stream->url);
- seekable = http_streaming_start(stream, file_format);
- if(seekable < 0) {
- if (stream->fd >= 0)
- closesocket(stream->fd);
- stream->fd = -1;
- streaming_ctrl_free(stream->streaming_ctrl);
- stream->streaming_ctrl = NULL;
- return STREAM_UNSUPPORTED;
- }
-
- return fixup_open(stream, seekable);
-}
-
-
-const stream_info_t stream_info_http1 = {
- "http streaming",
- "null",
- "Bertrand, Albeau, Reimar Doeffinger, Arpi?",
- "plain http",
- open_s1,
- {"mp_http", "mp_http_proxy", "unsv", "icyx", "noicyx", NULL},
- NULL,
- 0 // Urls are an option string
-};
-
-const stream_info_t stream_info_http2 = {
- "http streaming",
- "null",
- "Bertrand, Albeu, Arpi? who?",
- "plain http, also used as fallback for many other protocols",
- open_s2,
- {"mp_http", "mp_http_proxy", "pnm", "mms", "mmsu", "mmst", "rtsp", NULL}, //all the others as fallback
- NULL,
- 0 // Urls are an option string
-};
diff --git a/stream/http.h b/stream/http.h
deleted file mode 100644
index 2dd5125881..0000000000
--- a/stream/http.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * HTTP Helper
- *
- * Copyright (C) 2001 Bertrand Baudet <bertrand_baudet@yahoo.com>
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef MPLAYER_HTTP_H
-#define MPLAYER_HTTP_H
-
-#include <sys/types.h>
-
-typedef struct HTTP_field_type {
- char *field_name;
- struct HTTP_field_type *next;
-} HTTP_field_t;
-
-typedef struct {
- char *protocol;
- char *method;
- char *uri;
- unsigned int status_code;
- char *reason_phrase;
- unsigned int http_minor_version;
- // Field variables
- HTTP_field_t *first_field;
- HTTP_field_t *last_field;
- unsigned int field_nb;
- char *field_search;
- HTTP_field_t *field_search_pos;
- // Body variables
- char *body;
- size_t body_size;
- char *buffer;
- size_t buffer_size;
- unsigned int is_parsed;
-} HTTP_header_t;
-
-HTTP_header_t* http_new_header(void);
-void http_free( HTTP_header_t *http_hdr );
-int http_response_append( HTTP_header_t *http_hdr, char *data, int length );
-int http_response_parse( HTTP_header_t *http_hdr );
-int http_is_header_entire( HTTP_header_t *http_hdr );
-char* http_build_request( HTTP_header_t *http_hdr );
-char* http_get_field( HTTP_header_t *http_hdr, const char *field_name );
-char* http_get_next_field( HTTP_header_t *http_hdr );
-void http_set_field( HTTP_header_t *http_hdr, const char *field_name );
-void http_set_method( HTTP_header_t *http_hdr, const char *method );
-void http_set_uri( HTTP_header_t *http_hdr, const char *uri );
-int http_add_basic_authentication( HTTP_header_t *http_hdr, const char *username, const char *password );
-int http_add_basic_proxy_authentication( HTTP_header_t *http_hdr, const char *username, const char *password );
-
-void http_debug_hdr( HTTP_header_t *http_hdr );
-
-#endif /* MPLAYER_HTTP_H */
diff --git a/stream/network.c b/stream/network.c
deleted file mode 100644
index 101e4507ab..0000000000
--- a/stream/network.c
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- * Network layer for MPlayer
- *
- * Copyright (C) 2001 Bertrand Baudet <bertrand_baudet@yahoo.com>
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <errno.h>
-#include <ctype.h>
-
-#include "config.h"
-#include "core/options.h"
-
-#include "core/mp_msg.h"
-
-#if HAVE_WINSOCK2_H
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#endif
-
-#include "stream.h"
-#include "demux/demux.h"
-#include "core/mp_common.h"
-#include "network.h"
-#include "tcp.h"
-#include "http.h"
-#include "cookies.h"
-#include "url.h"
-
-/* IPv6 options */
-int network_ipv4_only_proxy = 0;
-
-
-const mime_struct_t mime_type_table[] = {
- // MP3 streaming, some MP3 streaming server answer with audio/mpeg
- { "audio/mpeg", DEMUXER_TYPE_LAVF },
- // ASF
- { "audio/x-ms-wax", DEMUXER_TYPE_ASF },
- { "audio/x-ms-wma", DEMUXER_TYPE_ASF },
- { "video/x-ms-asf", DEMUXER_TYPE_ASF },
- { "video/x-ms-afs", DEMUXER_TYPE_ASF },
- { "video/x-ms-wmv", DEMUXER_TYPE_ASF },
- { "video/x-ms-wma", DEMUXER_TYPE_ASF },
- { "application/x-mms-framed", DEMUXER_TYPE_ASF },
- { "application/vnd.ms.wms-hdr.asfv1", DEMUXER_TYPE_ASF },
- // Playlists
- { "video/x-ms-wmx", DEMUXER_TYPE_PLAYLIST },
- { "video/x-ms-wvx", DEMUXER_TYPE_PLAYLIST },
- { "audio/x-scpls", DEMUXER_TYPE_PLAYLIST },
- { "audio/x-mpegurl", DEMUXER_TYPE_PLAYLIST },
- { "audio/x-pls", DEMUXER_TYPE_PLAYLIST },
- // Real Media
-// { "audio/x-pn-realaudio", DEMUXER_TYPE_REAL },
- { NULL, DEMUXER_TYPE_UNKNOWN},
-};
-
-
-streaming_ctrl_t *
-streaming_ctrl_new(void) {
- streaming_ctrl_t *streaming_ctrl = calloc(1, sizeof(*streaming_ctrl));
- if( streaming_ctrl==NULL ) {
- mp_tmsg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed.\n");
- return NULL;
- }
- return streaming_ctrl;
-}
-
-void
-streaming_ctrl_free( streaming_ctrl_t *streaming_ctrl ) {
- if( streaming_ctrl==NULL ) return;
- if( streaming_ctrl->url ) url_free( streaming_ctrl->url );
- free(streaming_ctrl->buffer);
- free(streaming_ctrl->data);
- free(streaming_ctrl);
-}
-
-URL_t*
-check4proxies( const URL_t *url ) {
- URL_t *url_out = NULL;
- if( url==NULL ) return NULL;
- url_out = url_new( url->url );
- if( !strcasecmp(url->protocol, "mp_http_proxy") ) {
- mp_msg(MSGT_NETWORK,MSGL_V,"Using HTTP proxy: http://%s:%d\n", url->hostname, url->port );
- return url_out;
- }
- // Check if the http_proxy environment variable is set.
- if( !strcasecmp(url->protocol, "mp_http") ) {
- char *proxy;
- proxy = getenv("http_proxy");
- if( proxy!=NULL ) {
- // We got a proxy, build the URL to use it
- char *new_url;
- URL_t *tmp_url;
- URL_t *proxy_url = url_new( proxy );
-
- if( proxy_url==NULL ) {
- mp_tmsg(MSGT_NETWORK,MSGL_WARN,
- "Invalid proxy setting... Trying without proxy.\n");
- return url_out;
- }
-
-#ifdef HAVE_AF_INET6
- if (network_ipv4_only_proxy && (gethostbyname(url->hostname)==NULL)) {
- mp_tmsg(MSGT_NETWORK,MSGL_WARN,
- "Could not resolve remote hostname for AF_INET. Trying without proxy.\n");
- url_free(proxy_url);
- return url_out;
- }
-#endif
-
- mp_msg(MSGT_NETWORK,MSGL_V,"Using HTTP proxy: %s\n", proxy_url->url );
- new_url = get_http_proxy_url(proxy_url, url->url);
- if( new_url==NULL ) {
- mp_tmsg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed.\n");
- url_free(proxy_url);
- return url_out;
- }
- tmp_url = url_new( new_url );
- if( tmp_url==NULL ) {
- free( new_url );
- url_free( proxy_url );
- return url_out;
- }
- url_free( url_out );
- url_out = tmp_url;
- free( new_url );
- url_free( proxy_url );
- }
- }
- return url_out;
-}
-
-URL_t *url_new_with_proxy(const char *urlstr)
-{
- URL_t *url = url_new(urlstr);
- URL_t *url_with_proxy = check4proxies(url);
- url_free(url);
- return url_with_proxy;
-}
-
-int
-http_send_request( URL_t *url, int64_t pos ) {
- HTTP_header_t *http_hdr;
- URL_t *server_url;
- char str[256];
- int fd = -1;
- int ret;
- int proxy = 0; // Boolean
-
- http_hdr = http_new_header();
-
- if( !strcasecmp(url->protocol, "mp_http_proxy") ) {
- proxy = 1;
- if (!strncasecmp(url->file, "/mp_", 3))
- server_url = url_new( (url->file)+4 );
- else
- server_url = url_new( (url->file)+1 );
- if (!server_url) {
- mp_msg(MSGT_NETWORK, MSGL_ERR, "Invalid URL '%s' to proxify\n", url->file+1);
- goto err_out;
- }
- http_set_uri( http_hdr, server_url->noauth_url );
- } else {
- server_url = url;
- http_set_uri( http_hdr, server_url->file );
- }
- if (server_url->port && server_url->port != 80)
- snprintf(str, sizeof(str), "Host: %s:%d", server_url->hostname, server_url->port );
- else
- snprintf(str, sizeof(str), "Host: %s", server_url->hostname );
- http_set_field( http_hdr, str);
- if (network_useragent)
- snprintf(str, sizeof(str), "User-Agent: %s", network_useragent);
- else
- snprintf(str, sizeof(str), "User-Agent: %s", mplayer_version);
- http_set_field(http_hdr, str);
-
- if (network_referrer) {
- char *referrer = NULL;
- size_t len = strlen(network_referrer) + 10;
-
- // Check len to ensure we don't do something really bad in case of an overflow
- if (len > 10)
- referrer = malloc(len);
-
- if (referrer == NULL) {
- mp_tmsg(MSGT_NETWORK, MSGL_FATAL, "Memory allocation failed.\n");
- } else {
- snprintf(referrer, len, "Referer: %s", network_referrer);
- http_set_field(http_hdr, referrer);
- free(referrer);
- }
- }
-
- if( strcasecmp(url->protocol, "noicyx") )
- http_set_field(http_hdr, "Icy-MetaData: 1");
-
- if(pos>0) {
- // Extend http_send_request with possibility to do partial content retrieval
- snprintf(str, sizeof(str), "Range: bytes=%"PRId64"-", (int64_t)pos);
- http_set_field(http_hdr, str);
- }
-
- if (network_cookies_enabled) cookies_set( http_hdr, server_url->hostname, server_url->url );
-
- if (network_http_header_fields) {
- int i=0;
- while (network_http_header_fields[i])
- http_set_field(http_hdr, network_http_header_fields[i++]);
- }
-
- http_set_field( http_hdr, "Connection: close");
- if (proxy)
- http_add_basic_proxy_authentication(http_hdr, url->username, url->password);
- http_add_basic_authentication(http_hdr, server_url->username, server_url->password);
- if( http_build_request( http_hdr )==NULL ) {
- goto err_out;
- }
-
- if( proxy ) {
- if( url->port==0 ) url->port = 8080; // Default port for the proxy server
- fd = connect2Server( url->hostname, url->port,1 );
- url_free( server_url );
- server_url = NULL;
- } else {
- if( server_url->port==0 ) server_url->port = 80; // Default port for the web server
- fd = connect2Server( server_url->hostname, server_url->port,1 );
- }
- if( fd<0 ) {
- goto err_out;
- }
- mp_msg(MSGT_NETWORK,MSGL_DBG2,"Request: [%s]\n", http_hdr->buffer );
-
- ret = send( fd, http_hdr->buffer, http_hdr->buffer_size, DEFAULT_SEND_FLAGS );
- if( ret!=(int)http_hdr->buffer_size ) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"Error while sending HTTP request: Didn't send all the request.\n");
- goto err_out;
- }
-
- http_free( http_hdr );
-
- return fd;
-err_out:
- if (fd > 0) closesocket(fd);
- http_free(http_hdr);
- if (proxy && server_url)
- url_free(server_url);
- return -1;
-}
-
-HTTP_header_t *
-http_read_response( int fd ) {
- HTTP_header_t *http_hdr;
- char response[BUFFER_SIZE];
- int i;
-
- http_hdr = http_new_header();
- if( http_hdr==NULL ) {
- return NULL;
- }
-
- do {
- i = recv( fd, response, BUFFER_SIZE, 0 );
- if( i<0 ) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"Read failed.\n");
- http_free( http_hdr );
- return NULL;
- }
- if( i==0 ) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"http_read_response read 0 (i.e. EOF).\n");
- http_free( http_hdr );
- return NULL;
- }
- http_response_append( http_hdr, response, i );
- } while( !http_is_header_entire( http_hdr ) );
- if (http_response_parse( http_hdr ) < 0) {
- http_free( http_hdr );
- return NULL;
- }
- return http_hdr;
-}
-
-int
-http_authenticate(HTTP_header_t *http_hdr, URL_t *url, int *auth_retry) {
- char *aut;
-
-#define MPDEMUX_NW_AuthFailed _(\
-"Authentication failed. Please use the -user and -passwd options to provide your\n"\
-"username/password for a list of URLs, or form an URL like:\n"\
-"http://username:password@hostname/file\n")
-
-
- if( *auth_retry==1 ) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,MPDEMUX_NW_AuthFailed);
- return -1;
- }
- if( *auth_retry>0 ) {
- free(url->username);
- url->username = NULL;
- free(url->password);
- url->password = NULL;
- }
-
- aut = http_get_field(http_hdr, "WWW-Authenticate");
- if( aut!=NULL ) {
- char *aut_space;
- aut_space = strstr(aut, "realm=");
- if( aut_space!=NULL ) aut_space += 6;
- mp_tmsg(MSGT_NETWORK,MSGL_INFO,"Authentication required for %s\n", aut_space);
- } else {
- mp_tmsg(MSGT_NETWORK,MSGL_INFO,"Authentication required.\n");
- }
- if( network_username ) {
- url->username = strdup(network_username);
- if( url->username==NULL ) {
- mp_tmsg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed.\n");
- return -1;
- }
- } else {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,MPDEMUX_NW_AuthFailed);
- return -1;
- }
- if( network_password ) {
- url->password = strdup(network_password);
- if( url->password==NULL ) {
- mp_tmsg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed.\n");
- return -1;
- }
- } else {
- mp_tmsg(MSGT_NETWORK,MSGL_INFO,"No password provided, trying blank password.\n");
- }
- (*auth_retry)++;
- return 0;
-}
-
-int
-http_seek( stream_t *stream, int64_t pos ) {
- HTTP_header_t *http_hdr = NULL;
- int fd;
- if( stream==NULL ) return 0;
-
- if( stream->fd>0 ) closesocket(stream->fd); // need to reconnect to seek in http-stream
- fd = http_send_request( stream->streaming_ctrl->url, pos );
- if( fd<0 ) return 0;
-
- http_hdr = http_read_response( fd );
-
- if( http_hdr==NULL ) return 0;
-
- if( mp_msg_test(MSGT_NETWORK,MSGL_V) )
- http_debug_hdr( http_hdr );
-
- switch( http_hdr->status_code ) {
- case 200:
- case 206: // OK
- mp_msg(MSGT_NETWORK,MSGL_V,"Content-Type: [%s]\n", http_get_field(http_hdr, "Content-Type") );
- mp_msg(MSGT_NETWORK,MSGL_V,"Content-Length: [%s]\n", http_get_field(http_hdr, "Content-Length") );
- if( http_hdr->body_size>0 ) {
- if( streaming_bufferize( stream->streaming_ctrl, http_hdr->body, http_hdr->body_size )<0 ) {
- http_free( http_hdr );
- return -1;
- }
- }
- break;
- default:
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"Server returns %d: %s\n", http_hdr->status_code, http_hdr->reason_phrase );
- closesocket( fd );
- fd = -1;
- }
- stream->fd = fd;
-
- if( http_hdr ) {
- http_free( http_hdr );
- stream->streaming_ctrl->data = NULL;
- }
-
- stream->pos=pos;
-
- return 1;
-}
-
-
-int
-streaming_bufferize( streaming_ctrl_t *streaming_ctrl, char *buffer, int size) {
-//printf("streaming_bufferize\n");
- streaming_ctrl->buffer = malloc(size);
- if( streaming_ctrl->buffer==NULL ) {
- mp_tmsg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed.\n");
- return -1;
- }
- memcpy( streaming_ctrl->buffer, buffer, size );
- streaming_ctrl->buffer_size = size;
- return size;
-}
-
-int
-nop_streaming_read( int fd, char *buffer, int size, streaming_ctrl_t *stream_ctrl ) {
- int len=0;
-//printf("nop_streaming_read\n");
- if( stream_ctrl->buffer_size!=0 ) {
- int buffer_len = stream_ctrl->buffer_size-stream_ctrl->buffer_pos;
-//printf("%d bytes in buffer\n", stream_ctrl->buffer_size);
- len = (size<buffer_len)?size:buffer_len;
- memcpy( buffer, (stream_ctrl->buffer)+(stream_ctrl->buffer_pos), len );
- stream_ctrl->buffer_pos += len;
-//printf("buffer_pos = %d\n", stream_ctrl->buffer_pos );
- if( stream_ctrl->buffer_pos>=stream_ctrl->buffer_size ) {
- free( stream_ctrl->buffer );
- stream_ctrl->buffer = NULL;
- stream_ctrl->buffer_size = 0;
- stream_ctrl->buffer_pos = 0;
-//printf("buffer cleaned\n");
- }
-//printf("read %d bytes from buffer\n", len );
- }
-
- if( len<size ) {
- int ret;
- ret = recv( fd, buffer+len, size-len, 0 );
- if( ret<0 ) {
- mp_msg(MSGT_NETWORK,MSGL_ERR,"nop_streaming_read error : %s\n",strerror(errno));
- ret = 0;
- } else if (ret == 0)
- stream_ctrl->status = streaming_stopped_e;
- len += ret;
-//printf("read %d bytes from network\n", len );
- }
-
- return len;
-}
-
-int
-nop_streaming_seek( int fd, int64_t pos, streaming_ctrl_t *stream_ctrl ) {
- return -1;
-}
diff --git a/stream/network.h b/stream/network.h
deleted file mode 100644
index 65ec3d41d9..0000000000
--- a/stream/network.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Network layer for MPlayer
- *
- * Copyright (C) 2001 Bertrand Baudet <bertrand_baudet@yahoo.com>
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef MPLAYER_NETWORK_H
-#define MPLAYER_NETWORK_H
-
-#include <fcntl.h>
-#include <sys/time.h>
-#include <sys/types.h>
-
-#include "config.h"
-#if !HAVE_WINSOCK2_H
-#include <netdb.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#endif
-
-#include "stream.h"
-#include "url.h"
-#include "http.h"
-
-#ifdef MSG_NOSIGNAL
-#define DEFAULT_SEND_FLAGS MSG_NOSIGNAL
-#else
-#define DEFAULT_SEND_FLAGS 0
-#endif
-
-#if !HAVE_CLOSESOCKET
-#define closesocket close
-#endif
-#if !HAVE_SOCKLEN_T
-typedef int socklen_t;
-#endif
-
-#define BUFFER_SIZE 2048
-
-typedef struct {
- const char *mime_type;
- int demuxer_type;
-} mime_struct_t;
-
-extern const mime_struct_t mime_type_table[];
-
-extern int network_prefer_ipv4;
-extern int network_ipv4_only_proxy;
-extern int reuse_socket;
-
-streaming_ctrl_t *streaming_ctrl_new(void);
-int streaming_bufferize( streaming_ctrl_t *streaming_ctrl, char *buffer, int size);
-
-int nop_streaming_read( int fd, char *buffer, int size, streaming_ctrl_t *stream_ctrl );
-int nop_streaming_seek( int fd, int64_t pos, streaming_ctrl_t *stream_ctrl );
-void streaming_ctrl_free( streaming_ctrl_t *streaming_ctrl );
-
-int http_send_request(URL_t *url, int64_t pos);
-HTTP_header_t *http_read_response(int fd);
-
-int http_authenticate(HTTP_header_t *http_hdr, URL_t *url, int *auth_retry);
-URL_t* check4proxies(const URL_t *url);
-URL_t *url_new_with_proxy(const char *urlstr);
-
-int http_seek(stream_t *stream, int64_t pos);
-
-#endif /* MPLAYER_NETWORK_H */
diff --git a/stream/stream.c b/stream/stream.c
index 5d2ef46f96..a1eec388d3 100644
--- a/stream/stream.c
+++ b/stream/stream.c
@@ -37,14 +37,9 @@
#include "config.h"
-#if HAVE_WINSOCK2_H
-#include <winsock2.h>
-#endif
-
#include "core/bstr.h"
#include "core/mp_msg.h"
#include "osdep/timer.h"
-#include "network.h"
#include "stream.h"
#include "demux/demux.h"
@@ -96,12 +91,6 @@ static const stream_info_t *const auto_open_streams[] = {
#endif
&stream_info_ffmpeg, // use for rstp:// before http fallback
&stream_info_avdevice,
-#ifdef CONFIG_NETWORKING
- &stream_info_http1,
- &stream_info_asf,
- &stream_info_udp,
- &stream_info_http2,
-#endif
#ifdef CONFIG_DVBIN
&stream_info_dvb,
#endif
@@ -174,16 +163,6 @@ static stream_t *open_stream_plugin(const stream_info_t *sinfo,
s->flags |= mode;
*ret = sinfo->open(s, mode, arg, file_format);
if ((*ret) != STREAM_OK) {
-#ifdef CONFIG_NETWORKING
- if (*ret == STREAM_REDIRECTED && redirected_url) {
- if (s->streaming_ctrl && s->streaming_ctrl->url
- && s->streaming_ctrl->url->url)
- *redirected_url = strdup(s->streaming_ctrl->url->url);
- else
- *redirected_url = NULL;
- }
- streaming_ctrl_free(s->streaming_ctrl);
-#endif
free(s->url);
talloc_free(s);
return NULL;
@@ -363,18 +342,10 @@ static int stream_read_unbuffered(stream_t *s, void *buf, int len)
// we will retry even if we already reached EOF previously.
switch (s->type) {
case STREAMTYPE_STREAM:
- if (s->streaming_ctrl != NULL && s->streaming_ctrl->streaming_read) {
- len = s->streaming_ctrl->streaming_read(s->fd, buf, len,
- s->streaming_ctrl);
- if (s->streaming_ctrl->status == streaming_stopped_e &&
- (!s->end_pos || s->pos == s->end_pos))
- s->eof = 1;
- } else {
- if (s->fill_buffer)
- len = s->fill_buffer(s, buf, len);
- else
- len = read(s->fd, buf, len);
- }
+ if (s->fill_buffer)
+ len = s->fill_buffer(s, buf, len);
+ else
+ len = read(s->fd, buf, len);
break;
default:
@@ -508,25 +479,6 @@ static int stream_seek_unbuffered(stream_t *s, int64_t newpos)
// Some streaming protocol allow to seek backward and forward
// A function call that return -1 can tell that the protocol
// doesn't support seeking.
-#ifdef CONFIG_NETWORKING
- if (s->seek) {
- if (!s->seek(s, newpos)) {
- mp_tmsg(MSGT_STREAM, MSGL_ERR, "Seek failed\n");
- return 0;
- }
- break;
- }
-
- if (s->streaming_ctrl != NULL &&
- s->streaming_ctrl->streaming_seek) {
- if (s->streaming_ctrl->streaming_seek(s->fd, newpos,
- s->streaming_ctrl) < 0) {
- mp_tmsg(MSGT_STREAM, MSGL_INFO, "Stream not seekable!\n");
- return 1;
- }
- break;
- }
-#endif
if (newpos < s->pos) {
mp_tmsg(MSGT_STREAM, MSGL_INFO,
"Cannot seek backward in linear streams!\n");
@@ -675,14 +627,6 @@ static stream_t *new_stream(size_t min_size)
stream_t *s = talloc_size(NULL, sizeof(stream_t) + min_size);
memset(s, 0, sizeof(stream_t));
-#if HAVE_WINSOCK2_H
- {
- WSADATA wsdata;
- int temp = WSAStartup(0x0202, &wsdata); // there might be a better place for this (-> later)
- mp_msg(MSGT_STREAM, MSGL_V, "WINSOCK2 init: %i\n", temp);
- }
-#endif
-
s->fd = -2;
s->type = -2;
return s;
@@ -695,18 +639,8 @@ void free_stream(stream_t *s)
if (s->close)
s->close(s);
if (s->fd > 0) {
- /* on unix we define closesocket to close
- on windows however we have to distinguish between
- network socket and file */
- if (s->url && strstr(s->url, "://"))
- closesocket(s->fd);
- else
- close(s->fd);
+ close(s->fd);
}
-#if HAVE_WINSOCK2_H
- mp_msg(MSGT_STREAM, MSGL_V, "WINSOCK2 uninit\n");
- WSACleanup(); // there might be a better place for this (-> later)
-#endif
free(s->url);
if (s->uncached_stream)
free_stream(s->uncached_stream);
diff --git a/stream/stream.h b/stream/stream.h
index d5400470d3..98de2f4814 100644
--- a/stream/stream.h
+++ b/stream/stream.h
@@ -21,7 +21,6 @@
#include "config.h"
#include "core/mp_msg.h"
-#include "url.h"
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
@@ -116,29 +115,6 @@ struct stream_dvd_info_req {
int num_subs;
};
-typedef enum {
- streaming_stopped_e,
- streaming_playing_e
-} streaming_status;
-
-// All this is for legacy http streams (and other things using tcp/udp)
-typedef struct streaming_control {
- URL_t *url;
- streaming_status status;
- char *buffer;
- unsigned int buffer_size;
- unsigned int buffer_pos;
- unsigned int bandwidth; // The downstream available
- int (*streaming_read)(int fd, char *buffer, int buffer_size,
- struct streaming_control *stream_ctrl);
- int (*streaming_seek)(int fd, int64_t pos,
- struct streaming_control *stream_ctrl);
- void *data;
- // hacks for asf
- int *audio_id_ptr;
- int *video_id_ptr;
-} streaming_ctrl_t;
-
struct stream;
typedef struct stream_info_st {
const char *info;
@@ -185,7 +161,6 @@ typedef struct stream {
char *mime_type; // when HTTP streaming is used
char *lavf_type; // name of expected demuxer type for lavf
struct MPOpts *opts;
- streaming_ctrl_t *streaming_ctrl;
FILE *capture_file;
char *capture_filename;
@@ -196,10 +171,6 @@ typedef struct stream {
unsigned char buffer[];
} stream_t;
-#ifdef CONFIG_NETWORKING
-#include "network.h"
-#endif
-
int stream_fill_buffer(stream_t *s);
void stream_set_capture_file(stream_t *s, const char *filename);
diff --git a/stream/stream_cdda.c b/stream/stream_cdda.c
index c19c71d64f..4e45e51a07 100644
--- a/stream/stream_cdda.c
+++ b/stream/stream_cdda.c
@@ -340,11 +340,10 @@ static int open_cdda(stream_t *st, int m, void *opts, int *file_format)
int offset = p->toc_offset;
cdrom_drive_t *cdd = NULL;
cdda_priv *priv;
- cd_info_t *cd_info, *cddb_info = NULL;
+ cd_info_t *cd_info;
unsigned int audiolen = 0;
int last_track;
int i;
- char *xmcd_file = NULL;
if (m != STREAM_READ) {
m_struct_free(&stream_opts, opts);
@@ -358,18 +357,6 @@ static int open_cdda(stream_t *st, int m, void *opts, int *file_format)
p->device = talloc_strdup(NULL, DEFAULT_CDROM_DEVICE);
}
-#ifdef CONFIG_CDDB
- // cdd_identify returns -1 if it cannot read the TOC,
- // in which case there is no point in calling cddb_resolve
- if (cdd_identify(p->device) >= 0 && strncmp(st->url, "cddb", 4) == 0) {
- i = cddb_resolve(p->device, &xmcd_file);
- if (i == 0) {
- cddb_info = cddb_parse_xmcd(xmcd_file);
- free(xmcd_file);
- }
- }
-#endif
-
#if defined(__NetBSD__)
cdd = cdda_identify_scsi(p->device, p->device, 0, NULL);
#else
@@ -379,7 +366,6 @@ static int open_cdda(stream_t *st, int m, void *opts, int *file_format)
if (!cdd) {
mp_tmsg(MSGT_OPEN, MSGL_ERR, "Can't open CDDA device.\n");
m_struct_free(&stream_opts, opts);
- free(cddb_info);
return STREAM_ERROR;
}
@@ -392,7 +378,6 @@ static int open_cdda(stream_t *st, int m, void *opts, int *file_format)
mp_tmsg(MSGT_OPEN, MSGL_ERR, "Can't open disc.\n");
cdda_close(cdd);
m_struct_free(&stream_opts, opts);
- free(cddb_info);
return STREAM_ERROR;
}
@@ -455,7 +440,6 @@ static int open_cdda(stream_t *st, int m, void *opts, int *file_format)
free(priv);
cd_info_free(cd_info);
m_struct_free(&stream_opts, opts);
- free(cddb_info);
return STREAM_ERROR;
}
@@ -484,14 +468,6 @@ static int open_cdda(stream_t *st, int m, void *opts, int *file_format)
paranoia_seek(priv->cdp, priv->start_sector, SEEK_SET);
priv->sector = priv->start_sector;
-#ifdef CONFIG_CDDB
- if (cddb_info) {
- cd_info_free(cd_info);
- priv->cd_info = cddb_info;
- cd_info_debug(cddb_info);
- }
-#endif
-
st->priv = priv;
st->start_pos = priv->start_sector * CDIO_CD_FRAMESIZE_RAW;
st->end_pos = (priv->end_sector + 1) * CDIO_CD_FRAMESIZE_RAW;
@@ -518,11 +494,7 @@ const stream_info_t stream_info_cdda = {
"Albeu",
"",
open_cdda,
- {"cdda",
-#ifdef CONFIG_CDDB
- "cddb",
-#endif
- NULL },
+ {"cdda", NULL },
&stream_opts,
.opts_url = 1,
};
diff --git a/stream/stream_cddb.c b/stream/stream_cddb.c
deleted file mode 100644
index 5a6ba4e280..0000000000
--- a/stream/stream_cddb.c
+++ /dev/null
@@ -1,902 +0,0 @@
-/*
- * CDDB HTTP protocol
- *
- * Copyright (C) 2002 Bertrand Baudet <bertrand_baudet@yahoo.com>
- *
- * Implementation follow the freedb.howto1.06.txt specification
- * from http://freedb.freedb.org
- *
- * discid computation by Jeremy D. Zawodny
- * Copyright (c) 1998-2000 Jeremy D. Zawodny <Jeremy@Zawodny.com>
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <unistd.h>
-#include <string.h>
-#include <limits.h>
-#include "osdep/io.h"
-#if defined(__MINGW32__) || defined(__CYGWIN__)
-#include <windows.h>
-#if HAVE_WINSOCK2_H
-#include <winsock2.h>
-#endif
-#else
-#include <netdb.h>
-#include <sys/ioctl.h>
-#endif
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "core/mp_msg.h"
-#include "core/path.h"
-
-#if defined(__linux__)
-#include <linux/cdrom.h>
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
-#include <sys/cdio.h>
-#elif defined(__MINGW32__) || defined(__CYGWIN__)
-#include <ntddcdrm.h>
-#elif defined(__bsdi__)
-#include <dvd.h>
-#elif defined(__APPLE__) || defined(__DARWIN__)
-#include <IOKit/storage/IOCDTypes.h>
-#include <IOKit/storage/IOCDMediaBSDClient.h>
-#include "compat/mpbswap.h"
-#endif
-
-#include "cdd.h"
-#include "core/mp_common.h"
-#include "stream.h"
-#include "network.h"
-#include "libavutil/common.h"
-
-#define DEFAULT_FREEDB_SERVER "freedb.freedb.org"
-#define DEFAULT_CACHE_DIR "/.cddb/"
-
-typedef struct {
- char cddb_hello[1024];
- unsigned long disc_id;
- unsigned int tracks;
- char *cache_dir;
- char *freedb_server;
- int freedb_proto_level;
- int anonymous;
- char category[100];
- char *xmcd_file;
- size_t xmcd_file_size;
- void *user_data;
-} cddb_data_t;
-
-typedef struct {
- unsigned int min, sec, frame;
-} cd_toc_t;
-
-static cd_toc_t cdtoc[100];
-static int cdtoc_last_track;
-
-static int read_toc(const char *dev)
-{
- int first = 0, last = -1;
- int i;
-#if defined(__MINGW32__) || defined(__CYGWIN__)
- HANDLE drive;
- DWORD r;
- CDROM_TOC toc;
- char device[10];
-
- snprintf(device, sizeof(device), "\\\\.\\%s", dev);
- drive = CreateFile(device, GENERIC_READ, FILE_SHARE_READ, NULL,
- OPEN_EXISTING, 0, 0);
-
- if (!DeviceIoControl(drive, IOCTL_CDROM_READ_TOC, NULL, 0, &toc,
- sizeof(CDROM_TOC), &r, 0)) {
- mp_tmsg(MSGT_OPEN, MSGL_ERR, "Failed to read TOC.\n");
- return 0;
- }
-
- first = toc.FirstTrack - 1; last = toc.LastTrack;
- for (i = first; i <= last; i++) {
- cdtoc[i].min = toc.TrackData[i].Address[1];
- cdtoc[i].sec = toc.TrackData[i].Address[2];
- cdtoc[i].frame = toc.TrackData[i].Address[3];
- }
- CloseHandle(drive);
-
-#else
- int drive;
- drive = open(dev, O_RDONLY | O_NONBLOCK);
- if (drive < 0) {
- return drive;
- }
-
-#if defined(__linux__) || defined(__bsdi__)
- {
- struct cdrom_tochdr tochdr;
- ioctl(drive, CDROMREADTOCHDR, &tochdr);
- first = tochdr.cdth_trk0 - 1; last = tochdr.cdth_trk1;
- }
- for (i = first; i <= last; i++) {
- struct cdrom_tocentry tocentry;
- tocentry.cdte_track = (i == last) ? 0xAA : i + 1;
- tocentry.cdte_format = CDROM_MSF;
- ioctl(drive, CDROMREADTOCENTRY, &tocentry);
- cdtoc[i].min = tocentry.cdte_addr.msf.minute;
- cdtoc[i].sec = tocentry.cdte_addr.msf.second;
- cdtoc[i].frame = tocentry.cdte_addr.msf.frame;
- }
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
- {
- struct ioc_toc_header tochdr;
- ioctl(drive, CDIOREADTOCHEADER, &tochdr);
- first = tochdr.starting_track - 1; last = tochdr.ending_track;
- }
- for (i = first; i <= last; i++) {
- struct ioc_read_toc_single_entry tocentry;
- tocentry.track = (i == last) ? 0xAA : i + 1;
- tocentry.address_format = CD_MSF_FORMAT;
- ioctl(drive, CDIOREADTOCENTRY, &tocentry);
- cdtoc[i].min = tocentry.entry.addr.msf.minute;
- cdtoc[i].sec = tocentry.entry.addr.msf.second;
- cdtoc[i].frame = tocentry.entry.addr.msf.frame;
- }
-#elif defined(__NetBSD__) || defined(__OpenBSD__)
- {
- struct ioc_toc_header tochdr;
- ioctl(drive, CDIOREADTOCHEADER, &tochdr);
- first = tochdr.starting_track - 1; last = tochdr.ending_track;
- }
- for (i = first; i <= last; i++) {
- struct ioc_read_toc_entry tocentry;
- struct cd_toc_entry toc_buffer;
- tocentry.starting_track = (i == last) ? 0xAA : i + 1;
- tocentry.address_format = CD_MSF_FORMAT;
- tocentry.data = &toc_buffer;
- tocentry.data_len = sizeof(toc_buffer);
- ioctl(drive, CDIOREADTOCENTRYS, &tocentry);
- cdtoc[i].min = toc_buffer.addr.msf.minute;
- cdtoc[i].sec = toc_buffer.addr.msf.second;
- cdtoc[i].frame = toc_buffer.addr.msf.frame;
- }
-#elif defined(__APPLE__) || defined(__DARWIN__)
- {
- dk_cd_read_toc_t tochdr;
- uint8_t buf[4];
- uint8_t buf2[100 * sizeof(CDTOCDescriptor) + sizeof(CDTOC)];
- memset(&tochdr, 0, sizeof(tochdr));
- tochdr.bufferLength = sizeof(buf);
- tochdr.buffer = &buf;
- if (!ioctl(drive, DKIOCCDREADTOC, &tochdr)
- && tochdr.bufferLength == sizeof(buf)) {
- first = buf[2] - 1;
- last = buf[3];
- }
- if (last >= 0) {
- memset(&tochdr, 0, sizeof(tochdr));
- tochdr.bufferLength = sizeof(buf2);
- tochdr.buffer = &buf2;
- tochdr.format = kCDTOCFormatTOC;
- if (ioctl(drive, DKIOCCDREADTOC, &tochdr)
- || tochdr.bufferLength < sizeof(CDTOC))
- last = -1;
- }
- if (last >= 0) {
- CDTOC *cdToc = (CDTOC *)buf2;
- CDTrackInfo lastTrack;
- dk_cd_read_track_info_t trackInfoParams;
- for (i = first; i < last; ++i) {
- CDMSF msf = CDConvertTrackNumberToMSF(i + 1, cdToc);
- cdtoc[i].min = msf.minute;
- cdtoc[i].sec = msf.second;
- cdtoc[i].frame = msf.frame;
- }
- memset(&trackInfoParams, 0, sizeof(trackInfoParams));
- trackInfoParams.addressType = kCDTrackInfoAddressTypeTrackNumber;
- trackInfoParams.bufferLength = sizeof(lastTrack);
- trackInfoParams.address = last;
- trackInfoParams.buffer = &lastTrack;
- if (!ioctl(drive, DKIOCCDREADTRACKINFO, &trackInfoParams)) {
- CDMSF msf = CDConvertLBAToMSF(be2me_32(lastTrack.trackStartAddress)
- + be2me_32(lastTrack.trackSize));
- cdtoc[last].min = msf.minute;
- cdtoc[last].sec = msf.second;
- cdtoc[last].frame = msf.frame;
- }
- }
- }
-#endif
- close(drive);
-#endif
- for (i = first; i <= last; i++)
- cdtoc[i].frame += (cdtoc[i].min * 60 + cdtoc[i].sec) * 75;
- return last;
-}
-
-/**
-\brief Reads TOC from CD in the given device and prints the number of tracks
- and the length of each track in minute:second:frame format.
-\param *dev the device to analyse
-\return if the command line -identify is given, returns the last track of
- the TOC or -1 if the TOC can't be read,
- otherwise just returns 0 and let cddb_resolve the TOC
-*/
-int cdd_identify(const char *dev)
-{
- cdtoc_last_track = 0;
- if (mp_msg_test(MSGT_IDENTIFY, MSGL_INFO)) {
- int i, min, sec, frame;
- cdtoc_last_track = read_toc(dev);
- if (cdtoc_last_track < 0) {
- mp_tmsg(MSGT_OPEN, MSGL_ERR, "Failed to open %s device.\n", dev);
- return -1;
- }
- mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_CDDA_TRACKS=%d\n", cdtoc_last_track);
- for (i = 1; i <= cdtoc_last_track; i++) {
- frame = cdtoc[i].frame - cdtoc[i-1].frame;
- sec = frame / 75;
- frame -= sec * 75;
- min = sec / 60;
- sec -= min * 60;
- mp_msg(MSGT_IDENTIFY, MSGL_INFO,
- "ID_CDDA_TRACK_%d_MSF=%02d:%02d:%02d\n", i, min, sec, frame);
- }
- }
- return cdtoc_last_track;
-}
-
-static unsigned int cddb_sum(int n)
-{
- unsigned int ret;
-
- ret = 0;
- while (n > 0) {
- ret += (n % 10);
- n /= 10;
- }
- return ret;
-}
-
-static unsigned long cddb_discid(int tot_trks)
-{
- unsigned int i, t = 0, n = 0;
-
- i = 0;
- while (i < (unsigned int)tot_trks) {
- n = n + cddb_sum((cdtoc[i].min * 60) + cdtoc[i].sec);
- i++;
- }
- t = ((cdtoc[tot_trks].min * 60) + cdtoc[tot_trks].sec) -
- ((cdtoc[0].min * 60) + cdtoc[0].sec);
- return (n % 0xff) << 24 | t << 8 | tot_trks;
-}
-
-
-
-static int cddb_http_request(char *command,
- int (*reply_parser)(HTTP_header_t*, cddb_data_t*),
- cddb_data_t *cddb_data)
-{
- char request[4096];
- int fd, ret = 0;
- URL_t *url;
- HTTP_header_t *http_hdr;
-
- if (reply_parser == NULL || command == NULL || cddb_data == NULL)
- return -1;
-
- snprintf(request, sizeof(request), "http://%s/~cddb/cddb.cgi?cmd=%s%s&proto=%d",
- cddb_data->freedb_server, command, cddb_data->cddb_hello,
- cddb_data->freedb_proto_level);
- mp_msg(MSGT_OPEN, MSGL_INFO,"Request[%s]\n", request);
-
- url = url_new(request);
- if (url == NULL) {
- mp_tmsg(MSGT_DEMUX, MSGL_ERR, "not a valid URL\n");
- return -1;
- }
-
- fd = http_send_request(url,0);
- if (fd < 0) {
- mp_tmsg(MSGT_DEMUX, MSGL_ERR, "Failed to send the HTTP request.\n");
- return -1;
- }
-
- http_hdr = http_read_response(fd);
- if (http_hdr == NULL) {
- mp_tmsg(MSGT_DEMUX, MSGL_ERR, "Failed to read the HTTP response.\n");
- return -1;
- }
-
- http_debug_hdr(http_hdr);
- mp_msg(MSGT_OPEN, MSGL_INFO,"body=[%s]\n", http_hdr->body);
-
- switch (http_hdr->status_code) {
- case 200:
- ret = reply_parser(http_hdr, cddb_data);
- break;
- case 400:
- mp_tmsg(MSGT_DEMUX, MSGL_ERR, "Not Found.\n");
- break;
- default:
- mp_tmsg(MSGT_DEMUX, MSGL_ERR, "unknown error code\n");
- }
-
- http_free(http_hdr);
- url_free(url);
-
- return ret;
-}
-
-static int cddb_read_cache(cddb_data_t *cddb_data)
-{
- char file_name[100];
- struct stat stats;
- int file_fd, ret;
- size_t file_size;
-
- if (cddb_data == NULL || cddb_data->cache_dir == NULL)
- return -1;
-
- snprintf(file_name, sizeof(file_name), "%s%08lx", cddb_data->cache_dir, cddb_data->disc_id);
-
- file_fd = open(file_name, O_RDONLY | O_BINARY);
- if (file_fd < 0) {
- mp_tmsg(MSGT_DEMUX, MSGL_ERR, "No cache found.\n");
- return -1;
- }
-
- ret = fstat(file_fd, &stats);
- if (ret < 0) {
- perror("fstat");
- file_size = 4096;
- } else {
- file_size = stats.st_size < UINT_MAX ? stats.st_size : UINT_MAX - 1;
- }
-
- cddb_data->xmcd_file = malloc(file_size + 1);
- if (cddb_data->xmcd_file == NULL) {
- mp_tmsg(MSGT_DEMUX, MSGL_ERR, "Memory allocation failed.\n");
- close(file_fd);
- return -1;
- }
- cddb_data->xmcd_file_size = read(file_fd, cddb_data->xmcd_file, file_size);
- if (cddb_data->xmcd_file_size != file_size) {
- mp_tmsg(MSGT_DEMUX, MSGL_WARN, "Not all the xmcd file has been read.\n");
- close(file_fd);
- return -1;
- }
- cddb_data->xmcd_file[cddb_data->xmcd_file_size] = 0;
-
- close(file_fd);
-
- return 0;
-}
-
-static int cddb_write_cache(cddb_data_t *cddb_data)
-{
- // We have the file, save it for cache.
- char file_name[100];
- int file_fd, ret;
- int wrote = 0;
-
- if (cddb_data == NULL || cddb_data->cache_dir == NULL)
- return -1;
-
- // Check if the CDDB cache dir exist
- if (!mp_path_exists(cddb_data->cache_dir)) {
- // Directory not present, create it.
- ret = mkdir(cddb_data->cache_dir, 0755);
-#ifdef __MINGW32__
- if (ret < 0 && errno != EEXIST) {
-#else
- if (ret < 0) {
-#endif
- perror("mkdir");
- mp_tmsg(MSGT_DEMUX, MSGL_ERR, "Failed to create directory %s.\n",
- cddb_data->cache_dir);
- return -1;
- }
- }
-
- snprintf(file_name, sizeof(file_name), "%s%08lx", cddb_data->cache_dir, cddb_data->disc_id);
-
- file_fd = creat(file_name, S_IRUSR | S_IWUSR);
- if (file_fd < 0) {
- perror("create");
- return -1;
- }
-
- wrote = write(file_fd, cddb_data->xmcd_file, cddb_data->xmcd_file_size);
- if (wrote < 0) {
- perror("write");
- close(file_fd);
- return -1;
- }
- if ((unsigned int) wrote != cddb_data->xmcd_file_size) {
- mp_tmsg(MSGT_DEMUX, MSGL_WARN, "Not all of the xmcd file has been written.\n");
- close(file_fd);
- return -1;
- }
-
- close(file_fd);
-
- return 0;
-}
-
-static int cddb_read_parse(HTTP_header_t *http_hdr, cddb_data_t *cddb_data)
-{
- unsigned long disc_id;
- char category[100];
- char *ptr = NULL, *ptr2 = NULL;
- int ret, status;
-
- if (http_hdr == NULL || cddb_data == NULL)
- return -1;
-
- ret = sscanf(http_hdr->body, "%d ", &status);
- if (ret != 1) {
- mp_tmsg(MSGT_DEMUX, MSGL_ERR, "parse error");
- return -1;
- }
-
- switch (status) {
- case 210:
- ret = sscanf(http_hdr->body, "%d %99s %08lx", &status,
- category, &disc_id);
- if (ret != 3) {
- mp_tmsg(MSGT_DEMUX, MSGL_ERR, "parse error");
- return -1;
- }
- // Check if it's a xmcd database file
- ptr = strstr(http_hdr->body, "# xmcd");
- if (ptr == NULL) {
- mp_tmsg(MSGT_DEMUX, MSGL_ERR,
- "Invalid xmcd database file returned.\n");
- return -1;
- }
- ptr = strdup(ptr);
- // Ok found the beginning of the file
- // look for the end
- ptr2 = strstr(ptr, "\n.\r\n");
- if (!ptr2)
- ptr2 = strstr(ptr, "\n.\n");
- if (ptr2) {
- ptr2++;
- } else {
- mp_msg(MSGT_DEMUX, MSGL_FIXME, "Unable to find '.'\n");
- ptr2 = ptr + strlen(ptr); //return -1;
- }
- // Ok found the end
- // do a sanity check
- if (http_hdr->body_size < (unsigned int)(ptr2 - ptr)) {
- mp_tmsg(MSGT_DEMUX, MSGL_ERR, "unexpected FIXME\n");
- return -1;
- }
- cddb_data->xmcd_file = ptr;
- cddb_data->xmcd_file_size = ptr2 - ptr;
- cddb_data->xmcd_file[cddb_data->xmcd_file_size] = '\0';
- return cddb_write_cache(cddb_data);
- default:
- mp_tmsg(MSGT_DEMUX, MSGL_FIXME, "unhandled code\n");
- }
- return 0;
-}
-
-static int cddb_request_titles(cddb_data_t *cddb_data)
-{
- char command[1024];
- snprintf(command, sizeof(command), "cddb+read+%s+%08lx",
- cddb_data->category, cddb_data->disc_id);
- return cddb_http_request(command, cddb_read_parse, cddb_data);
-}
-
-static int cddb_parse_matches_list(HTTP_header_t *http_hdr, cddb_data_t *cddb_data)
-{
- char album_title[100];
- char *ptr = NULL;
- int ret;
-
- ptr = strstr(http_hdr->body, "\n");
- if (ptr == NULL) {
- mp_tmsg(MSGT_DEMUX, MSGL_ERR, "Unable to find end of line.\n");
- return -1;
- }
- ptr++;
- // We have a list of exact/inexact matches, so which one do we use?
- // So let's take the first one.
- ret = sscanf(ptr, "%99s %08lx %99s", cddb_data->category,
- &(cddb_data->disc_id), album_title);
- if (ret != 3) {
- mp_tmsg(MSGT_DEMUX, MSGL_ERR, "parse error");
- return -1;
- }
- ptr = strstr(http_hdr->body, album_title);
- if (ptr != NULL) {
- char *ptr2;
- int len;
- ptr2 = strstr(ptr, "\n");
- if (ptr2 == NULL) {
- len = (http_hdr->body_size)-(ptr-(http_hdr->body));
- } else {
- len = ptr2-ptr+1;
- }
- len = FFMIN(sizeof(album_title) - 1, len);
- strncpy(album_title, ptr, len);
- album_title[len]='\0';
- }
- mp_tmsg(MSGT_DEMUX, MSGL_STATUS, "Parse OK, found: %s\n", album_title);
- return 0;
-}
-
-static int cddb_query_parse(HTTP_header_t *http_hdr, cddb_data_t *cddb_data)
-{
- char album_title[100];
- char *ptr = NULL;
- int ret, status;
-
- ret = sscanf(http_hdr->body, "%d ", &status);
- if (ret != 1) {
- mp_tmsg(MSGT_DEMUX, MSGL_ERR, "parse error");
- return -1;
- }
-
- switch (status) {
- case 200:
- // Found exact match
- ret = sscanf(http_hdr->body, "%d %99s %08lx %99s", &status,
- cddb_data->category, &(cddb_data->disc_id), album_title);
- if (ret != 4) {
- mp_tmsg(MSGT_DEMUX, MSGL_ERR, "parse error");
- return -1;
- }
- ptr = strstr(http_hdr->body, album_title);
- if (ptr != NULL) {
- char *ptr2;
- int len;
- ptr2 = strstr(ptr, "\n");
- if (ptr2 == NULL) {
- len = (http_hdr->body_size)-(ptr-(http_hdr->body));
- } else {
- len = ptr2-ptr+1;
- }
- len = FFMIN(sizeof(album_title) - 1, len);
- strncpy(album_title, ptr, len);
- album_title[len]='\0';
- }
- mp_tmsg(MSGT_DEMUX, MSGL_STATUS, "Parse OK, found: %s\n", album_title);
- return cddb_request_titles(cddb_data);
- case 202:
- // No match found
- mp_tmsg(MSGT_DEMUX, MSGL_WARN, "Album not found.\n");
- break;
- case 210:
- // Found exact matches, list follows
- cddb_parse_matches_list(http_hdr, cddb_data);
- return cddb_request_titles(cddb_data);
-/*
-body=[210 Found exact matches, list follows (until terminating `.')
-misc c711930d Santana / Supernatural
-rock c711930d Santana / Supernatural
-blues c711930d Santana / Supernatural
-.]
-*/
- case 211:
- // Found inexact matches, list follows
- cddb_parse_matches_list(http_hdr, cddb_data);
- return cddb_request_titles(cddb_data);
- case 500:
- mp_tmsg(MSGT_DEMUX, MSGL_FIXME,
- "Server returns: Command syntax error\n");
- break;
- default:
- mp_tmsg(MSGT_DEMUX, MSGL_FIXME, "unhandled code\n");
- }
- return -1;
-}
-
-static int cddb_proto_level_parse(HTTP_header_t *http_hdr, cddb_data_t *cddb_data)
-{
- int max;
- int ret, status;
- char *ptr;
-
- ret = sscanf(http_hdr->body, "%d ", &status);
- if (ret != 1) {
- mp_tmsg(MSGT_DEMUX, MSGL_ERR, "parse error");
- return -1;
- }
-
- switch (status) {
- case 210:
- ptr = strstr(http_hdr->body, "max proto:");
- if (ptr == NULL) {
- mp_tmsg(MSGT_DEMUX, MSGL_ERR, "parse error");
- return -1;
- }
- ret = sscanf(ptr, "max proto: %d", &max);
- if (ret != 1) {
- mp_tmsg(MSGT_DEMUX, MSGL_ERR, "parse error");
- return -1;
- }
- cddb_data->freedb_proto_level = max;
- return 0;
- default:
- mp_tmsg(MSGT_DEMUX, MSGL_FIXME, "unhandled code\n");
- }
- return -1;
-}
-
-static int cddb_get_proto_level(cddb_data_t *cddb_data)
-{
- return cddb_http_request("stat", cddb_proto_level_parse, cddb_data);
-}
-
-static void cddb_create_hello(cddb_data_t *cddb_data)
-{
- char host_name[51];
- char *user_name;
-
- if (cddb_data->anonymous) { // Default is anonymous
- /* Note from Eduardo Pérez Ureta <eperez@it.uc3m.es> :
- * We don't send current user/host name in hello to prevent spam.
- * Software that sends this is considered spyware
- * that most people don't like.
- */
- user_name = "anonymous";
- strcpy(host_name, "localhost");
- } else {
- if (gethostname(host_name, 50) < 0) {
- strcpy(host_name, "localhost");
- }
- user_name = getenv("LOGNAME");
- }
- snprintf(cddb_data->cddb_hello, sizeof(cddb_data->cddb_hello),
- "&hello=%s+%s+%s",
- user_name, host_name, mplayer_version);
-}
-
-static int cddb_retrieve(cddb_data_t *cddb_data)
-{
- char offsets[1024], command[1024];
- char *ptr;
- unsigned int i, time_len;
- int ret;
-
- ptr = offsets;
- for (i = 0; i < cddb_data->tracks ; i++) {
- unsigned space = sizeof(offsets) - (ptr - offsets);
- if (space < 40) break;
- ptr += snprintf(ptr, space, "%d+", cdtoc[i].frame);
- }
- ptr[0] = 0;
- time_len = (cdtoc[cddb_data->tracks].frame)/75;
-
- cddb_data->freedb_server = DEFAULT_FREEDB_SERVER;
- cddb_data->freedb_proto_level = 1;
- cddb_data->xmcd_file = NULL;
-
- cddb_create_hello(cddb_data);
- if (cddb_get_proto_level(cddb_data) < 0) {
- mp_tmsg(MSGT_DEMUX, MSGL_ERR, "Failed to get the protocol level.\n");
- return -1;
- }
-
- snprintf(command, sizeof(command), "cddb+query+%08lx+%d+%s%d", cddb_data->disc_id,
- cddb_data->tracks, offsets, time_len);
- ret = cddb_http_request(command, cddb_query_parse, cddb_data);
- if (ret < 0)
- return -1;
-
- free(cddb_data->cache_dir);
- return 0;
-}
-
-int cddb_resolve(const char *dev, char **xmcd_file)
-{
- char cddb_cache_dir[] = DEFAULT_CACHE_DIR;
- char *home_dir = NULL;
- cddb_data_t cddb_data;
- void *talloc_ctx = talloc_new(NULL);
-
- if (cdtoc_last_track <= 0) {
- cdtoc_last_track = read_toc(dev);
- if (cdtoc_last_track < 0) {
- mp_tmsg(MSGT_OPEN, MSGL_ERR, "Failed to open %s device.\n", dev);
- return -1;
- }
- }
- cddb_data.tracks = cdtoc_last_track;
- cddb_data.disc_id = cddb_discid(cddb_data.tracks);
- cddb_data.anonymous = 1; // Don't send user info by default
-
- mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CDDB_DISCID=%08lx\n",
- cddb_data.disc_id);
-
- // Check if there is a CD in the drive
- // FIXME: That's not really a good way to check
- if (cddb_data.disc_id == 0) {
- mp_tmsg(MSGT_DEMUX, MSGL_ERR, "No CD in the drive.\n");
- return -1;
- }
-
- home_dir = getenv("HOME");
-#ifdef __MINGW32__
- if (home_dir == NULL)
- home_dir = getenv("USERPROFILE");
- if (home_dir == NULL)
- home_dir = getenv("HOMEPATH");
- // Last resort, store the cddb cache in the mplayer directory
- if (home_dir == NULL)
- home_dir = (char *)talloc_steal(talloc_ctx,
- mp_find_user_config_file(""));
-#endif
- if (home_dir == NULL) {
- cddb_data.cache_dir = NULL;
- } else {
- unsigned len = strlen(home_dir) + strlen(cddb_cache_dir) + 1;
- cddb_data.cache_dir = malloc(len);
- if (cddb_data.cache_dir == NULL) {
- mp_tmsg(MSGT_DEMUX, MSGL_ERR, "Memory allocation failed.\n");
- talloc_free(talloc_ctx);
- return -1;
- }
- snprintf(cddb_data.cache_dir, len, "%s%s", home_dir, cddb_cache_dir);
- }
- talloc_free(talloc_ctx);
-
- // Check for a cached file
- if (cddb_read_cache(&cddb_data) < 0) {
- // No Cache found
- if (cddb_retrieve(&cddb_data) < 0) {
- return -1;
- }
- }
-
- if (cddb_data.xmcd_file != NULL) {
-// printf("%s\n", cddb_data.xmcd_file);
- *xmcd_file = cddb_data.xmcd_file;
- return 0;
- }
-
- return -1;
-}
-
-/***************
- * xmcd parser *
- ***************/
-static char *xmcd_parse_dtitle(cd_info_t *cd_info, char *line)
-{
- char *ptr, *album;
- ptr = strstr(line, "DTITLE=");
- if (ptr != NULL) {
- ptr += 7;
- album = strstr(ptr, "/");
- if (album == NULL)
- return NULL;
- cd_info->album = malloc(strlen(album + 2) + 1);
- if (cd_info->album == NULL) {
- return NULL;
- }
- strcpy(cd_info->album, album + 2);
- album--;
- album[0] = '\0';
- cd_info->artist = malloc(strlen(ptr) + 1);
- if (cd_info->artist == NULL) {
- return NULL;
- }
- strcpy(cd_info->artist, ptr);
- }
- return ptr;
-}
-
-static char *xmcd_parse_dgenre(cd_info_t *cd_info, char *line)
-{
- char *ptr;
- ptr = strstr(line, "DGENRE=");
- if (ptr != NULL) {
- ptr += 7;
- cd_info->genre = malloc(strlen(ptr)+1);
- if (cd_info->genre == NULL) {
- return NULL;
- }
- strcpy(cd_info->genre, ptr);
- }
- return ptr;
-}
-
-static char *xmcd_parse_ttitle(cd_info_t *cd_info, char *line)
-{
- unsigned int track_nb;
- unsigned long sec, off;
- char *ptr;
- ptr = strstr(line, "TTITLE");
- if (ptr != NULL) {
- ptr += 6;
- // Here we point to the track number
- track_nb = atoi(ptr);
- ptr = strstr(ptr, "=");
- if (ptr == NULL)
- return NULL;
- ptr++;
-
- sec = cdtoc[track_nb].frame;
- off = cdtoc[track_nb + 1].frame - sec + 1;
-
- cd_info_add_track(cd_info, ptr, track_nb + 1,
- (unsigned int) (off / (60 * 75)),
- (unsigned int) ((off / 75) % 60),
- (unsigned int) (off % 75),
- sec, off);
- }
- return ptr;
-}
-
-cd_info_t *cddb_parse_xmcd(char *xmcd_file)
-{
- cd_info_t *cd_info = NULL;
- int length, pos = 0;
- char *ptr, *ptr2;
- if (xmcd_file == NULL)
- return NULL;
-
- cd_info = cd_info_new();
- if (cd_info == NULL) {
- return NULL;
- }
-
- length = strlen(xmcd_file);
- ptr = xmcd_file;
- while (ptr != NULL && pos < length) {
- // Read a line
- ptr2 = ptr;
- while(ptr2[0] != '\0' && ptr2[0] != '\r' && ptr2[0] != '\n')
- ptr2++;
- if (ptr2[0] == '\0') {
- break;
- }
- ptr2[0] = '\0';
- // Ignore comments
- if (ptr[0] != '#') {
- // Search for the album title
- if (!xmcd_parse_dtitle(cd_info, ptr)) {
- // Search for the genre
- if (!xmcd_parse_dgenre(cd_info, ptr)) {
- // Search for a track title
- xmcd_parse_ttitle(cd_info, ptr);
- }
- }
- }
- if (ptr2[1] == '\n')
- ptr2++;
- pos = (ptr2 + 1) - ptr;
- ptr = ptr2 + 1;
- }
-
- unsigned int audiolen = cdtoc[cd_info->nb_tracks].frame-cdtoc[0].frame;
- cd_info->min = (unsigned int) (audiolen / (60 * 75));
- cd_info->sec = (unsigned int) ((audiolen / 75) % 60);
- cd_info->msec = (unsigned int) (audiolen % 75);
-
- return cd_info;
-}
diff --git a/stream/stream_ftp.c b/stream/stream_ftp.c
deleted file mode 100644
index 77537e08fd..0000000000
--- a/stream/stream_ftp.c
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-#if !HAVE_WINSOCK2_H
-#include <sys/socket.h>
-#else
-#include <winsock2.h>
-#endif
-
-#include <libavutil/common.h>
-
-#include "core/mp_msg.h"
-#include "network.h"
-#include "stream.h"
-#include "core/m_option.h"
-#include "core/m_struct.h"
-#include "tcp.h"
-
-static struct stream_priv_s {
- char* user;
- char* pass;
- char* host;
- int port;
- char* filename;
-
- char *cput,*cget;
- int handle;
- int cavail,cleft;
- char *buf;
- char *cmd_buf;
-} stream_priv_dflts = {
- .user = "anonymous",
- .pass = "no@spam",
- .port = 21,
- .handle = -1,
-};
-
-#define CMD_BUFSIZE 8192
-
-#define BUFSIZE 2048
-
-#define ST_OFF(f) M_ST_OFF(struct stream_priv_s,f)
-/// URL definition
-static const m_option_t stream_opts_fields[] = {
- {"username", ST_OFF(user), CONF_TYPE_STRING, 0, 0 ,0, NULL},
- {"password", ST_OFF(pass), CONF_TYPE_STRING, 0, 0 ,0, NULL},
- {"hostname", ST_OFF(host), CONF_TYPE_STRING, 0, 0 ,0, NULL},
- {"port", ST_OFF(port), CONF_TYPE_INT, 0, 0 ,65635, NULL},
- {"filename", ST_OFF(filename), CONF_TYPE_STRING, 0, 0 ,0, NULL},
- { NULL, NULL, 0, 0, 0, 0, NULL }
-};
-static const struct m_struct_st stream_opts = {
- "ftp",
- sizeof(struct stream_priv_s),
- &stream_priv_dflts,
- stream_opts_fields
-};
-
-#define TELNET_IAC 255 /* interpret as command: */
-#define TELNET_IP 244 /* interrupt process--permanently */
-#define TELNET_SYNCH 242 /* for telfunc calls */
-
-// Check if there is something to read on a fd. This avoid hanging
-// forever if the network stop responding.
-static int fd_can_read(int fd,int timeout) {
- fd_set fds;
- struct timeval tv;
-
- FD_ZERO(&fds);
- FD_SET(fd,&fds);
- tv.tv_sec = timeout;
- tv.tv_usec = 0;
-
- return select(fd+1, &fds, NULL, NULL, &tv) > 0;
-}
-
-/*
- * read a line of text
- *
- * If the line is too long to fit in the buffer, provided via parameters
- * buf and max, the remaining characters are skipped. So the next call to
- * this function is synchronized to the start of the following response
- * line.
- *
- * The parameter buf will always be initialized as long as max is bigger
- * then 1. If nothing is read it will contain an empty string.
- *
- * return -1 on error or bytecount
- */
-static int readline(char *buf,int max,struct stream_priv_s *ctl)
-{
- int x,retval = 0;
- char *end,*bp=buf;
- int eof = 0;
-
- if (max <= 0) {
- return -1;
- }
- *bp = '\0';
-
- do {
- if (ctl->cavail > 0) {
- x = FFMIN(ctl->cavail, max-1);
- end = memccpy(bp,ctl->cget,'\n',x);
- if (end != NULL)
- x = end - bp;
- retval += x;
- bp += x;
- *bp = '\0';
- max -= x;
- ctl->cget += x;
- ctl->cavail -= x;
- if (end != NULL) {
- bp -= 2;
- if (strcmp(bp,"\r\n") == 0) {
- *bp++ = '\n';
- *bp++ = '\0';
- --retval;
- }
- break;
- }
- }
- if (max == 1) {
- char *q = memchr(ctl->cget, '\n', ctl->cavail);
-
- if (q) { // found EOL: update state and return
- ++q;
- ctl->cavail -= q - ctl->cget;
- ctl->cget = q;
-
- break;
- }
-
- // receive more data to find end of current line
- ctl->cget = ctl->cput;
- }
- if (ctl->cput == ctl->cget) {
- ctl->cput = ctl->cget = ctl->buf;
- ctl->cavail = 0;
- ctl->cleft = BUFSIZE;
- }
- if(eof) {
- if (retval == 0)
- retval = -1;
- break;
- }
-
- if(!fd_can_read(ctl->handle, 15)) {
- mp_msg(MSGT_OPEN,MSGL_ERR, "[ftp] read timed out\n");
- retval = -1;
- break;
- }
-
- if ((x = recv(ctl->handle,ctl->cput,ctl->cleft,0)) == -1) {
- mp_msg(MSGT_STREAM,MSGL_ERR, "[ftp] read error: %s\n",strerror(errno));
- retval = -1;
- break;
- }
- if (x == 0)
- eof = 1;
- ctl->cleft -= x;
- ctl->cavail += x;
- ctl->cput += x;
- } while (1);
-
- return retval;
-}
-
-/*
- * read a response from the server
- *
- * return 0 if first char doesn't match
- * return 1 if first char matches
- */
-static int readresp(struct stream_priv_s* ctl,char* rsp)
-{
- static char response[256];
- char match[5];
- int r, len;
-
- len = readline(response,256,ctl);
- if (rsp) strcpy(rsp,response);
- if (len == -1)
- return 0;
-
- r = atoi(response)/100;
-
- mp_msg(MSGT_STREAM,MSGL_V, "[ftp] < %s",response);
-
- if (response[3] == '-') {
- strncpy(match,response,3);
- match[3] = ' ';
- match[4] = '\0';
- do {
- if (readline(response,256,ctl) == -1) {
- mp_msg(MSGT_OPEN,MSGL_ERR, "[ftp] Control socket read failed\n");
- return 0;
- }
- mp_msg(MSGT_OPEN,MSGL_V, "[ftp] < %s",response);
- } while (strncmp(response,match,4));
- }
- return r;
-}
-
-
-static int FtpSendCmd(const char *cmd, struct stream_priv_s *nControl,char* rsp)
-{
- int l = strlen(cmd);
- int hascrlf = cmd[l - 2] == '\r' && cmd[l - 1] == '\n';
-
- if(hascrlf && l == 2) mp_msg(MSGT_STREAM,MSGL_V, "\n");
- else mp_msg(MSGT_STREAM,MSGL_V, "[ftp] > %s",cmd);
- while(l > 0) {
- int s = send(nControl->handle,cmd,l,DEFAULT_SEND_FLAGS);
-
- if(s <= 0) {
- mp_msg(MSGT_OPEN,MSGL_ERR, "[ftp] write error: %s\n",strerror(errno));
- return 0;
- }
-
- cmd += s;
- l -= s;
- }
-
- if (hascrlf)
- return readresp(nControl,rsp);
- else
- return FtpSendCmd("\r\n", nControl, rsp);
-}
-
-static int FtpOpenPort(struct stream_priv_s* p) {
- int resp,fd;
- char rsp_txt[256];
- char* par,str[128];
- int num[6];
-
- resp = FtpSendCmd("PASV",p,rsp_txt);
- if(resp != 2) {
- mp_msg(MSGT_OPEN,MSGL_WARN, "[ftp] command 'PASV' failed: %s\n",rsp_txt);
- return 0;
- }
-
- par = strchr(rsp_txt,'(');
-
- if(!par || !par[0] || !par[1]) {
- mp_msg(MSGT_OPEN,MSGL_ERR, "[ftp] invalid server response: %s ??\n",rsp_txt);
- return 0;
- }
-
- sscanf(par+1,"%u,%u,%u,%u,%u,%u",&num[0],&num[1],&num[2],
- &num[3],&num[4],&num[5]);
- snprintf(str,sizeof(str),"%d.%d.%d.%d",num[0],num[1],num[2],num[3]);
- fd = connect2Server(str,(num[4]<<8)+num[5],0);
-
- if(fd < 0)
- mp_msg(MSGT_OPEN,MSGL_ERR, "[ftp] failed to create data connection\n");
-
- return fd;
-}
-
-static int FtpOpenData(stream_t* s,int64_t newpos) {
- struct stream_priv_s* p = s->priv;
- int resp;
- char rsp_txt[256];
-
- // Open a new connection
- s->fd = FtpOpenPort(p);
-
- if(s->fd < 0) return 0;
-
- if(newpos > 0) {
- snprintf(p->cmd_buf,CMD_BUFSIZE,"REST %"PRId64, (int64_t)newpos);
-
- resp = FtpSendCmd(p->cmd_buf,p,rsp_txt);
- if(resp != 3) {
- mp_msg(MSGT_OPEN,MSGL_WARN, "[ftp] command '%s' failed: %s\n",p->cmd_buf,rsp_txt);
- newpos = 0;
- }
- }
-
- // Get the file
- snprintf(p->cmd_buf,CMD_BUFSIZE,"RETR %s",p->filename);
- resp = FtpSendCmd(p->cmd_buf,p,rsp_txt);
-
- if(resp != 1) {
- mp_msg(MSGT_OPEN,MSGL_ERR, "[ftp] command '%s' failed: %s\n",p->cmd_buf,rsp_txt);
- return 0;
- }
-
- s->pos = newpos;
- return 1;
-}
-
-static int fill_buffer(stream_t *s, char* buffer, int max_len){
- int r;
-
- if(s->fd < 0 && !FtpOpenData(s,s->pos))
- return -1;
-
- if(!fd_can_read(s->fd, 15)) {
- mp_msg(MSGT_OPEN,MSGL_ERR, "[ftp] read timed out\n");
- return -1;
- }
-
- r = recv(s->fd,buffer,max_len,0);
- return (r <= 0) ? -1 : r;
-}
-
-static int seek(stream_t *s,int64_t newpos) {
- struct stream_priv_s* p = s->priv;
- int resp;
- char rsp_txt[256];
-
- if(s->pos > s->end_pos) {
- return 0;
- }
-
- // Check to see if the server did not already terminate the transfer
- if(fd_can_read(p->handle, 0)) {
- if(readresp(p,rsp_txt) != 2)
- mp_msg(MSGT_OPEN,MSGL_WARN, "[ftp] Warning the server didn't finished the transfer correctly: %s\n",rsp_txt);
- closesocket(s->fd);
- s->fd = -1;
- }
-
- // Close current download
- if(s->fd >= 0) {
- static const char pre_cmd[]={TELNET_IAC,TELNET_IP,TELNET_IAC,TELNET_SYNCH};
- //int fl;
-
- // First close the fd
- closesocket(s->fd);
- s->fd = -1;
-
- // Send send the telnet sequence needed to make the server react
-
- // Dunno if this is really needed, lftp have it. I let
- // it here in case it turn out to be needed on some other OS
- //fl=fcntl(p->handle,F_GETFL);
- //fcntl(p->handle,F_SETFL,fl&~O_NONBLOCK);
-
- // send only first byte as OOB due to OOB braindamage in many unices
- send(p->handle,pre_cmd,1,MSG_OOB|DEFAULT_SEND_FLAGS);
- send(p->handle,pre_cmd+1,sizeof(pre_cmd)-1,DEFAULT_SEND_FLAGS);
-
- //fcntl(p->handle,F_SETFL,fl);
-
- // Get the 426 Transfer aborted
- // Or the 226 Transfer complete
- resp = readresp(p,rsp_txt);
- if(resp != 4 && resp != 2) {
- mp_msg(MSGT_OPEN,MSGL_ERR, "[ftp] Server didn't abort correctly: %s\n",rsp_txt);
- return 0;
- }
- // Send the ABOR command
- // Ignore the return code as sometimes it fail with "nothing to abort"
- FtpSendCmd("ABOR",p,rsp_txt);
- }
- return FtpOpenData(s,newpos);
-}
-
-
-static void close_f(stream_t *s) {
- struct stream_priv_s* p = s->priv;
-
- if(!p) return;
-
- if(s->fd >= 0) {
- closesocket(s->fd);
- s->fd = -1;
- }
-
- if (p->handle >= 0) {
- FtpSendCmd("QUIT", p, NULL);
- closesocket(p->handle);
- }
-
- free(p->buf);
- free(p->cmd_buf);
-
- m_struct_free(&stream_opts,p);
-}
-
-
-
-static int open_f(stream_t *stream,int mode, void* opts, av_unused int* file_format) {
- int resp;
- int64_t len = 0;
- struct stream_priv_s* p = opts;
- char rsp_txt[256];
-
- if(mode != STREAM_READ) {
- mp_msg(MSGT_OPEN,MSGL_ERR, "[ftp] Unknown open mode %d\n",mode);
- m_struct_free(&stream_opts,opts);
- return STREAM_UNSUPPORTED;
- }
-
- if(!p->filename || !p->host) {
- mp_msg(MSGT_OPEN,MSGL_ERR, "[ftp] Bad url\n");
- m_struct_free(&stream_opts,opts);
- return STREAM_ERROR;
- }
-
- // Allocate buffers
- p->buf = malloc(BUFSIZE);
- p->cmd_buf = malloc(CMD_BUFSIZE);
-
- if (!p->buf || !p->cmd_buf) {
- close_f(stream);
- m_struct_free(&stream_opts,opts);
- return STREAM_ERROR;
- }
-
- // Open the control connection
- p->handle = connect2Server(p->host,p->port,1);
-
- if(p->handle < 0) {
- m_struct_free(&stream_opts,opts);
- return STREAM_ERROR;
- }
-
- // We got a connection, let's start serious things
- stream->fd = -1;
- stream->priv = p;
-
- if (readresp(p, NULL) == 0) {
- close_f(stream);
- return STREAM_ERROR;
- }
-
- // Login
- snprintf(p->cmd_buf,CMD_BUFSIZE,"USER %s",p->user);
- resp = FtpSendCmd(p->cmd_buf,p,rsp_txt);
-
- // password needed
- if(resp == 3) {
- snprintf(p->cmd_buf,CMD_BUFSIZE,"PASS %s",p->pass);
- resp = FtpSendCmd(p->cmd_buf,p,rsp_txt);
- if(resp != 2) {
- mp_msg(MSGT_OPEN,MSGL_ERR, "[ftp] command '%s' failed: %s\n",p->cmd_buf,rsp_txt);
- close_f(stream);
- return STREAM_ERROR;
- }
- } else if(resp != 2) {
- mp_msg(MSGT_OPEN,MSGL_ERR, "[ftp] command '%s' failed: %s\n",p->cmd_buf,rsp_txt);
- close_f(stream);
- return STREAM_ERROR;
- }
-
- // Set the transfer type
- resp = FtpSendCmd("TYPE I",p,rsp_txt);
- if(resp != 2) {
- mp_msg(MSGT_OPEN,MSGL_WARN, "[ftp] command 'TYPE I' failed: %s\n",rsp_txt);
- close_f(stream);
- return STREAM_ERROR;
- }
-
- // Get the filesize
- snprintf(p->cmd_buf,CMD_BUFSIZE,"SIZE %s",p->filename);
- resp = FtpSendCmd(p->cmd_buf,p,rsp_txt);
- if(resp != 2) {
- mp_msg(MSGT_OPEN,MSGL_WARN, "[ftp] command '%s' failed: %s\n",p->cmd_buf,rsp_txt);
- } else {
- int dummy;
- sscanf(rsp_txt,"%d %"SCNd64,&dummy,&len);
- }
-
- if(len > 0) {
- stream->seek = seek;
- stream->end_pos = len;
- }
-
- // The data connection is really opened only at the first
- // read/seek. This must be done when the cache is used
- // because the connection would stay open in the main process,
- // preventing correct abort with many servers.
- stream->fd = -1;
- stream->priv = p;
- stream->fill_buffer = fill_buffer;
- stream->close = close_f;
- stream->type = STREAMTYPE_STREAM;
-
- return STREAM_OK;
-}
-
-const stream_info_t stream_info_ftp = {
- "File Transfer Protocol",
- "ftp",
- "Albeu",
- "reuse a bit of code from ftplib written by Thomas Pfau",
- open_f,
- { "ftp", NULL },
- &stream_opts,
- 1 // Urls are an option string
-};
diff --git a/stream/stream_lavf.c b/stream/stream_lavf.c
index 640c719109..3223bc3eaa 100644
--- a/stream/stream_lavf.c
+++ b/stream/stream_lavf.c
@@ -28,7 +28,6 @@
#include "core/m_struct.h"
#include "demux/demux.h"
-#include "network.h"
#include "cookies.h"
#include "core/bstr.h"
@@ -317,7 +316,7 @@ const stream_info_t stream_info_ffmpeg = {
"",
open_f,
{ "lavf", "ffmpeg", "rtmp", "rtsp", "http", "https", "mms", "mmst", "mmsh",
- "mmshttp", NULL },
+ "mmshttp", "udp", "ftp", NULL },
NULL,
1 // Urls are an option string
};
diff --git a/stream/stream_udp.c b/stream/stream_udp.c
deleted file mode 100644
index f3a3918e63..0000000000
--- a/stream/stream_udp.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * stream layer for MPEG over UDP, based on previous work from Dave Chapman
- *
- * Copyright (C) 2006 Benjamin Zores
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "core/options.h"
-#include "stream.h"
-#include "url.h"
-#include "udp.h"
-
-static int
-udp_streaming_start (stream_t *stream)
-{
- streaming_ctrl_t *streaming_ctrl;
- int fd;
-
- if (!stream)
- return -1;
-
- streaming_ctrl = stream->streaming_ctrl;
- fd = stream->fd;
-
- if (fd < 0)
- {
- fd = udp_open_socket (streaming_ctrl->url);
- if (fd < 0)
- return -1;
- stream->fd = fd;
- }
-
- streaming_ctrl->streaming_read = nop_streaming_read;
- streaming_ctrl->streaming_seek = nop_streaming_seek;
- streaming_ctrl->status = streaming_playing_e;
- stream->streaming = false;
-
- return 0;
-}
-
-static int
-udp_stream_open (stream_t *stream, int mode, void *opts, int *file_format)
-{
- mp_msg (MSGT_OPEN, MSGL_INFO, "STREAM_UDP, URL: %s\n", stream->url);
- stream->streaming_ctrl = streaming_ctrl_new ();
- if (!stream->streaming_ctrl)
- return STREAM_ERROR;
-
- stream->streaming_ctrl->bandwidth = network_bandwidth;
- stream->streaming_ctrl->url = url_new(stream->url);
-
- if (stream->streaming_ctrl->url->port == 0)
- {
- mp_msg (MSGT_NETWORK, MSGL_ERR,
- "You must enter a port number for UDP streams!\n");
- streaming_ctrl_free (stream->streaming_ctrl);
- stream->streaming_ctrl = NULL;
-
- return STREAM_UNSUPPORTED;
- }
-
- if (udp_streaming_start (stream) < 0)
- {
- mp_msg (MSGT_NETWORK, MSGL_ERR, "udp_streaming_start failed\n");
- streaming_ctrl_free (stream->streaming_ctrl);
- stream->streaming_ctrl = NULL;
-
- return STREAM_UNSUPPORTED;
- }
-
- stream->type = STREAMTYPE_STREAM;
-
- return STREAM_OK;
-}
-
-const stream_info_t stream_info_udp = {
- "MPEG over UDP streaming",
- "udp",
- "Dave Chapman, Benjamin Zores",
- "native udp support",
- udp_stream_open,
- { "udp", NULL},
- NULL,
- 0 // Urls are an option string
-};
diff --git a/stream/tcp.c b/stream/tcp.c
deleted file mode 100644
index be27c490dc..0000000000
--- a/stream/tcp.c
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Network layer for MPlayer
- *
- * Copyright (C) 2001 Bertrand BAUDET <bertrand_baudet@yahoo.com>
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <errno.h>
-#include <ctype.h>
-
-#include <fcntl.h>
-#include <sys/time.h>
-#include <sys/types.h>
-
-#include "config.h"
-
-#include "core/mp_msg.h"
-
-#if !HAVE_WINSOCK2_H
-#include <netdb.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#else
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#endif
-
-#include "network.h"
-#include "stream.h"
-#include "tcp.h"
-#include "libavutil/avstring.h"
-
-/* IPv6 options */
-int network_prefer_ipv4 = 0;
-
-// Converts an address family constant to a string
-
-static const char *af2String(int af) {
- switch (af) {
- case AF_INET: return "AF_INET";
-
-#ifdef HAVE_AF_INET6
- case AF_INET6: return "AF_INET6";
-#endif
- default: return "Unknown address family!";
- }
-}
-
-
-
-// Connect to a server using a TCP connection, with specified address family
-// return -2 for fatal error, like unable to resolve name, connection timeout...
-// return -1 is unable to connect to a particular port
-
-static int
-connect2Server_with_af(char *host, int port, int af,int verb) {
- int socket_server_fd;
- int err;
- socklen_t err_len;
- int ret,count = 0;
- fd_set set;
- struct timeval tv;
- union {
- struct sockaddr_in four;
-#ifdef HAVE_AF_INET6
- struct sockaddr_in6 six;
-#endif
- } server_address;
- size_t server_address_size;
- void *our_s_addr; // Pointer to sin_addr or sin6_addr
- struct hostent *hp=NULL;
- char buf[255];
-
-#if HAVE_WINSOCK2_H
- unsigned long val;
- int to;
-#else
- struct timeval to;
-#endif
-
-#if HAVE_WINSOCK2_H && defined(HAVE_AF_INET6)
- // our winsock name resolution code can not handle IPv6
- if (af == AF_INET6) {
- mp_msg(MSGT_NETWORK, MSGL_WARN, "IPv6 not supported for winsock2\n");
- return TCP_ERROR_FATAL;
- }
-#endif
-
- socket_server_fd = socket(af, SOCK_STREAM, 0);
-
-
- if( socket_server_fd==-1 ) {
-// mp_msg(MSGT_NETWORK,MSGL_ERR,"Failed to create %s socket:\n", af2String(af));
- return TCP_ERROR_FATAL;
- }
-
-#if defined(SO_RCVTIMEO) && defined(SO_SNDTIMEO)
-#if HAVE_WINSOCK2_H
- /* timeout in milliseconds */
- to = 10 * 1000;
-#else
- to.tv_sec = 10;
- to.tv_usec = 0;
-#endif
- setsockopt(socket_server_fd, SOL_SOCKET, SO_RCVTIMEO, &to, sizeof(to));
- setsockopt(socket_server_fd, SOL_SOCKET, SO_SNDTIMEO, &to, sizeof(to));
-#endif
-
- switch (af) {
- case AF_INET: our_s_addr = &server_address.four.sin_addr; break;
-#ifdef HAVE_AF_INET6
- case AF_INET6: our_s_addr = &server_address.six.sin6_addr; break;
-#endif
- default:
- mp_tmsg(MSGT_NETWORK,MSGL_ERR, "Unknown address family %d\n", af);
- return TCP_ERROR_FATAL;
- }
-
-
- memset(&server_address, 0, sizeof(server_address));
-
-#if HAVE_INET_PTON
- if (inet_pton(af, host, our_s_addr)!=1)
-#elif HAVE_INET_ATON
- if (inet_aton(host, our_s_addr)!=1)
-#elif HAVE_WINSOCK2_H
- if ( inet_addr(host)==INADDR_NONE )
-#endif
- {
- if(verb) mp_tmsg(MSGT_NETWORK,MSGL_STATUS,"Resolving %s for %s...\n", host, af2String(af));
-
-#ifdef HAVE_GETHOSTBYNAME2
- hp=gethostbyname2( host, af );
-#else
- hp=gethostbyname( host );
-#endif
- if( hp==NULL ) {
- if(verb) mp_tmsg(MSGT_NETWORK,MSGL_ERR,"Couldn't resolve name for %s: %s\n", af2String(af), host);
- return TCP_ERROR_FATAL;
- }
-
- memcpy( our_s_addr, hp->h_addr_list[0], hp->h_length );
- }
-#if HAVE_WINSOCK2_H
- else {
- unsigned long addr = inet_addr(host);
- memcpy( our_s_addr, &addr, sizeof(addr) );
- }
-#endif
-
- switch (af) {
- case AF_INET:
- server_address.four.sin_family=af;
- server_address.four.sin_port=htons(port);
- server_address_size = sizeof(server_address.four);
- break;
-#ifdef HAVE_AF_INET6
- case AF_INET6:
- server_address.six.sin6_family=af;
- server_address.six.sin6_port=htons(port);
- server_address_size = sizeof(server_address.six);
- break;
-#endif
- default:
- mp_tmsg(MSGT_NETWORK,MSGL_ERR, "Unknown address family %d\n", af);
- return TCP_ERROR_FATAL;
- }
-
-#if HAVE_INET_PTON
- inet_ntop(af, our_s_addr, buf, 255);
-#elif HAVE_INET_ATON || defined(HAVE_WINSOCK2_H)
- av_strlcpy( buf, inet_ntoa( *((struct in_addr*)our_s_addr) ), 255);
-#endif
- if(verb) mp_tmsg(MSGT_NETWORK,MSGL_STATUS,"Connecting to server %s[%s]: %d...\n", host, buf , port );
-
- // Turn the socket as non blocking so we can timeout on the connection
-#if !HAVE_WINSOCK2_H
- fcntl( socket_server_fd, F_SETFL, fcntl(socket_server_fd, F_GETFL) | O_NONBLOCK );
-#else
- val = 1;
- ioctlsocket( socket_server_fd, FIONBIO, &val );
-#endif
- if( connect( socket_server_fd, (struct sockaddr*)&server_address, server_address_size )==-1 ) {
-#if !HAVE_WINSOCK2_H
- if( errno!=EINPROGRESS ) {
-#else
- if( (WSAGetLastError() != WSAEINPROGRESS) && (WSAGetLastError() != WSAEWOULDBLOCK) ) {
-#endif
- if(verb) mp_tmsg(MSGT_NETWORK,MSGL_ERR,"Failed to connect to server with %s\n", af2String(af));
- closesocket(socket_server_fd);
- return TCP_ERROR_PORT;
- }
- }
- tv.tv_sec = 0;
- tv.tv_usec = 500000;
- FD_ZERO( &set );
- FD_SET( socket_server_fd, &set );
- // When the connection will be made, we will have a writeable fd
- while((ret = select(socket_server_fd+1, NULL, &set, NULL, &tv)) == 0) {
- if(count > 30 || stream_check_interrupt(500)) {
- if(count > 30)
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"connection timeout\n");
- else
- mp_msg(MSGT_NETWORK,MSGL_V,"Connection interrupted by user\n");
- return TCP_ERROR_TIMEOUT;
- }
- count++;
- FD_ZERO( &set );
- FD_SET( socket_server_fd, &set );
- tv.tv_sec = 0;
- tv.tv_usec = 500000;
- }
- if (ret < 0) mp_tmsg(MSGT_NETWORK,MSGL_ERR,"Select failed.\n");
-
- // Turn back the socket as blocking
-#if !HAVE_WINSOCK2_H
- fcntl( socket_server_fd, F_SETFL, fcntl(socket_server_fd, F_GETFL) & ~O_NONBLOCK );
-#else
- val = 0;
- ioctlsocket( socket_server_fd, FIONBIO, &val );
-#endif
- // Check if there were any errors
- err_len = sizeof(int);
- ret = getsockopt(socket_server_fd,SOL_SOCKET,SO_ERROR,&err,&err_len);
- if(ret < 0) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"getsockopt failed: %s\n",strerror(errno));
- return TCP_ERROR_FATAL;
- }
- if(err > 0) {
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"connect error: %s\n",strerror(err));
- return TCP_ERROR_PORT;
- }
-
- return socket_server_fd;
-}
-
-// Connect to a server using a TCP connection
-// return -2 for fatal error, like unable to resolve name, connection timeout...
-// return -1 is unable to connect to a particular port
-
-
-int
-connect2Server(char *host, int port, int verb) {
-#ifdef HAVE_AF_INET6
- int r;
- int s = TCP_ERROR_FATAL;
-
- r = connect2Server_with_af(host, port, network_prefer_ipv4 ? AF_INET:AF_INET6,verb);
- if (r >= 0) return r;
-
- s = connect2Server_with_af(host, port, network_prefer_ipv4 ? AF_INET6:AF_INET,verb);
- if (s == TCP_ERROR_FATAL) return r;
- return s;
-#else
- return connect2Server_with_af(host, port, AF_INET,verb);
-#endif
-
-
-}
diff --git a/stream/tcp.h b/stream/tcp.h
deleted file mode 100644
index 5ff193c66d..0000000000
--- a/stream/tcp.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * network helpers for TCP connections
- * (originally borrowed from network.c,
- * by Bertrand BAUDET <bertrand_baudet@yahoo.com>)
- *
- * Copyright (C) 2001 Bertrand BAUDET, 2006 Benjamin Zores
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef MPLAYER_TCP_H
-#define MPLAYER_TCP_H
-
-/* Connect to a server using a TCP connection */
-int connect2Server (char *host, int port, int verb);
-
-#define TCP_ERROR_TIMEOUT -3 /* connection timeout */
-#define TCP_ERROR_FATAL -2 /* unable to resolve name */
-#define TCP_ERROR_PORT -1 /* unable to connect to a particular port */
-
-#endif /* MPLAYER_TCP_H */
diff --git a/stream/udp.c b/stream/udp.c
deleted file mode 100644
index c09a7f7e07..0000000000
--- a/stream/udp.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * network helpers for UDP connections (originally borrowed from rtp.c)
- *
- * Copyright (C) 2006 Benjamin Zores
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <ctype.h>
-
-#if !HAVE_WINSOCK2_H
-#include <netdb.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#else
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#endif
-
-#include "core/mp_msg.h"
-#include "network.h"
-#include "url.h"
-#include "udp.h"
-
-int reuse_socket=0;
-
-/* Start listening on a UDP port. If multicast, join the group. */
-int
-udp_open_socket (URL_t *url)
-{
- int socket_server_fd, rxsockbufsz;
- int err;
- socklen_t err_len;
- fd_set set;
- struct sockaddr_in server_address;
- struct ip_mreq mcast;
- struct timeval tv;
- struct hostent *hp;
- int reuse=reuse_socket;
-
- mp_msg (MSGT_NETWORK, MSGL_V,
- "Listening for traffic on %s:%d ...\n", url->hostname, url->port);
-
- socket_server_fd = socket (AF_INET, SOCK_DGRAM, 0);
- if (socket_server_fd == -1)
- {
- mp_msg (MSGT_NETWORK, MSGL_ERR, "Failed to create socket\n");
- return -1;
- }
-
- memset(&server_address, 0, sizeof(server_address));
- if (isalpha (url->hostname[0]))
- {
-#if !HAVE_WINSOCK2_H
- hp = gethostbyname (url->hostname);
- if (!hp)
- {
- mp_msg (MSGT_NETWORK, MSGL_ERR,
- "Counldn't resolve name: %s\n", url->hostname);
- closesocket (socket_server_fd);
- return -1;
- }
- memcpy (&server_address.sin_addr.s_addr,
- hp->h_addr_list[0], hp->h_length);
-#else
- server_address.sin_addr.s_addr = htonl (INADDR_ANY);
-#endif /* HAVE_WINSOCK2_H */
- }
- else
- {
-#if HAVE_INET_PTON
- inet_pton (AF_INET, url->hostname, &server_address.sin_addr);
-#elif HAVE_INET_ATON
- inet_aton (url->hostname, &server_address.sin_addr);
-#elif !HAVE_WINSOCK2_H
- server_address.sin_addr.s_addr = htonl(INADDR_ANY);
-#endif
- }
- server_address.sin_family = AF_INET;
- server_address.sin_port = htons (url->port);
-
- if(reuse_socket && setsockopt(socket_server_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)))
- mp_msg(MSGT_NETWORK, MSGL_ERR, "SO_REUSEADDR failed! ignore.\n");
-
- if (bind (socket_server_fd, (struct sockaddr *) &server_address,
- sizeof (server_address)) == -1)
- {
-#if !HAVE_WINSOCK2_H
- if (errno != EINPROGRESS)
-#else
- if (WSAGetLastError () != WSAEINPROGRESS)
-#endif /* HAVE_WINSOCK2_H */
- {
- mp_msg (MSGT_NETWORK, MSGL_ERR, "Failed to connect to server\n");
- closesocket (socket_server_fd);
- return -1;
- }
- }
-
-#if HAVE_WINSOCK2_H
- if (isalpha (url->hostname[0]))
- {
- hp = gethostbyname (url->hostname);
- if (!hp)
- {
- mp_msg (MSGT_NETWORK, MSGL_ERR,
- "Could not resolve name: %s\n", url->hostname);
- closesocket (socket_server_fd);
- return -1;
- }
- memcpy (&server_address.sin_addr.s_addr,
- hp->h_addr, hp->h_length);
- }
- else
- {
- unsigned int addr = inet_addr (url->hostname);
- memcpy (&server_address.sin_addr, &addr, sizeof (addr));
- }
-#endif /* HAVE_WINSOCK2_H */
-
- /* Increase the socket rx buffer size to maximum -- this is UDP */
- rxsockbufsz = 240 * 1024;
- if (setsockopt (socket_server_fd, SOL_SOCKET, SO_RCVBUF,
- &rxsockbufsz, sizeof (rxsockbufsz)))
- {
- mp_msg (MSGT_NETWORK, MSGL_ERR,
- "Couldn't set receive socket buffer size\n");
- }
-
- if ((ntohl (server_address.sin_addr.s_addr) >> 28) == 0xe)
- {
- mcast.imr_multiaddr.s_addr = server_address.sin_addr.s_addr;
- mcast.imr_interface.s_addr = 0;
-
- if (setsockopt (socket_server_fd, IPPROTO_IP,
- IP_ADD_MEMBERSHIP, &mcast, sizeof (mcast)))
- {
- mp_msg (MSGT_NETWORK, MSGL_ERR, "IP_ADD_MEMBERSHIP failed (do you have multicasting enabled in your kernel?)\n");
- closesocket (socket_server_fd);
- return -1;
- }
- }
-
- tv.tv_sec = 1; /* 1 second timeout */
- tv.tv_usec = 0;
-
- FD_ZERO (&set);
- FD_SET (socket_server_fd, &set);
-
- err = select (socket_server_fd + 1, &set, NULL, NULL, &tv);
- if (err < 0)
- {
- mp_msg (MSGT_NETWORK, MSGL_FATAL,
- "Select failed: %s\n", strerror (errno));
- closesocket (socket_server_fd);
- return -1;
- }
-
- if (err == 0)
- {
- mp_msg (MSGT_NETWORK, MSGL_ERR,
- "Timeout! No data from host %s\n", url->hostname);
- closesocket (socket_server_fd);
- return -1;
- }
-
- err_len = sizeof (err);
- getsockopt (socket_server_fd, SOL_SOCKET, SO_ERROR, &err, &err_len);
- if (err)
- {
- mp_msg (MSGT_NETWORK, MSGL_DBG2, "Socket error: %d\n", err);
- closesocket (socket_server_fd);
- return -1;
- }
-
- return socket_server_fd;
-}
diff --git a/stream/udp.h b/stream/udp.h
deleted file mode 100644
index 73031f06c2..0000000000
--- a/stream/udp.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * network helpers for UDP connections (originally borrowed from rtp.c)
- *
- * Copyright (C) 2006 Benjamin Zores
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef MPLAYER_UDP_H
-#define MPLAYER_UDP_H
-
-#include "url.h"
-
-int udp_open_socket (URL_t *url);
-
-#endif /* MPLAYER_UDP_H */
diff --git a/stream/url.c b/stream/url.c
deleted file mode 100644
index 70d2db4ea5..0000000000
--- a/stream/url.c
+++ /dev/null
@@ -1,506 +0,0 @@
-/*
- * URL Helper
- *
- * Copyright (C) 2001 Bertrand Baudet <bertrand_baudet@yahoo.com>
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <inttypes.h>
-
-#include "url.h"
-#include "core/mp_msg.h"
-
-#ifndef SIZE_MAX
-#define SIZE_MAX ((size_t)-1)
-#endif
-
-static char *mp_asprintf(const char *fmt, ...)
-{
- char *p = NULL;
- va_list va, va_bak;
- int len;
-
- va_start(va, fmt);
- va_copy(va_bak, va);
-
- len = vsnprintf(NULL, 0, fmt, va);
- if (len < 0)
- goto end;
-
- p = malloc(len + 1);
- if (!p)
- goto end;
-
- len = vsnprintf(p, len + 1, fmt, va_bak);
- if (len < 0)
- free(p), p = NULL;
-
-end:
- va_end(va);
- return p;
-}
-
-static int is_proxy(const URL_t *url) {
- return !strcasecmp(url->protocol, "mp_http_proxy") && url->file && strstr(url->file, "://");
-}
-
-int url_is_protocol(const URL_t *url, const char *proto) {
- int proxy = is_proxy(url);
- if (proxy) {
- URL_t *tmp = url_new(url->file + 1);
- int res = !strcasecmp(tmp->protocol, proto);
- url_free(tmp);
- return res;
- }
- return !strcasecmp(url->protocol, proto);
-}
-
-void url_set_protocol(URL_t *url, const char *proto) {
- int proxy = is_proxy(url);
- if (proxy) {
- char *dst = url->file + 1;
- int oldlen = strstr(dst, "://") - dst;
- int newlen = strlen(proto);
- if (newlen != oldlen) {
- mp_msg(MSGT_NETWORK, MSGL_ERR, "Setting protocol not implemented!\n");
- return;
- }
- memcpy(dst, proto, newlen);
- return;
- }
- free(url->protocol);
- url->protocol = strdup(proto);
-}
-
-URL_t *url_redirect(URL_t **url, const char *redir) {
- URL_t *u = *url;
- int proxy = is_proxy(u);
- const char *oldurl = proxy ? u->file + 1 : u->url;
- const char *newurl = redir;
- char *buffer = NULL;
- URL_t *res;
- if (!strchr(redir, '/') || *redir == '/') {
- char *tmp;
- newurl = buffer = malloc(strlen(oldurl) + strlen(redir) + 1);
- strcpy(buffer, oldurl);
- if (*redir == '/') {
- redir++;
- tmp = strstr(buffer, "://");
- if (tmp) tmp = strchr(tmp + 3, '/');
- } else
- tmp = strrchr(buffer, '/');
- if (tmp) tmp[1] = 0;
- strcat(buffer, redir);
- }
- if (proxy) {
- char *tmp = get_http_proxy_url(u, newurl);
- free(buffer);
- newurl = buffer = tmp;
- }
- res = url_new(newurl);
- free(buffer);
- url_free(u);
- *url = res;
- return res;
-}
-
-static char *get_noauth_url(const URL_t *url)
-{
- if (url->port)
- return mp_asprintf("%s://%s:%d%s",
- url->protocol, url->hostname, url->port, url->file);
- else
- return mp_asprintf("%s://%s%s",
- url->protocol, url->hostname, url->file);
-}
-
-char *get_http_proxy_url(const URL_t *proxy, const char *host_url)
-{
- if (proxy->username)
- return mp_asprintf("mp_http_proxy://%s:%s@%s:%d/%s",
- proxy->username,
- proxy->password ? proxy->password : "",
- proxy->hostname, proxy->port, host_url);
- else
- return mp_asprintf("mp_http_proxy://%s:%d/%s",
- proxy->hostname, proxy->port, host_url);
-}
-
-URL_t*
-url_new(const char* url) {
- int pos1, pos2,v6addr = 0;
- URL_t* Curl = NULL;
- char *escfilename=NULL;
- char *ptr1=NULL, *ptr2=NULL, *ptr3=NULL, *ptr4=NULL;
- int jumpSize = 3;
-
- if( url==NULL ) return NULL;
-
- if (strlen(url) > (SIZE_MAX / 3 - 1)) {
- mp_tmsg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed.\n");
- goto err_out;
- }
- escfilename=malloc(strlen(url)*3+1);
- if (!escfilename ) {
- mp_tmsg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed.\n");
- goto err_out;
- }
-
- // Create the URL container
- Curl = calloc(1, sizeof(*Curl));
- if( Curl==NULL ) {
- mp_tmsg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed.\n");
- goto err_out;
- }
-
- url_escape_string(escfilename,url);
-
- // Copy the url in the URL container
- Curl->url = strdup(escfilename);
- if( Curl->url==NULL ) {
- mp_tmsg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed.\n");
- goto err_out;
- }
- mp_msg(MSGT_OPEN,MSGL_V,"Filename for url is now %s\n",escfilename);
-
- // extract the protocol
- ptr1 = strstr(escfilename, "://");
- if( ptr1==NULL ) {
- // Check for a special case: "sip:" (without "//"):
- if (strstr(escfilename, "sip:") == escfilename) {
- ptr1 = (char *)&url[3]; // points to ':'
- jumpSize = 1;
- } else {
- mp_msg(MSGT_NETWORK,MSGL_V,"Not an URL!\n");
- goto err_out;
- }
- }
- pos1 = ptr1-escfilename;
- Curl->protocol = malloc(pos1+1);
- if( Curl->protocol==NULL ) {
- mp_tmsg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed.\n");
- goto err_out;
- }
- strncpy(Curl->protocol, escfilename, pos1);
- Curl->protocol[pos1] = '\0';
-
- // jump the "://"
- ptr1 += jumpSize;
- pos1 += jumpSize;
-
- // check if a username:password is given
- ptr2 = strstr(ptr1, "@");
- ptr3 = strstr(ptr1, "/");
- if( ptr3!=NULL && ptr3<ptr2 ) {
- // it isn't really a username but rather a part of the path
- ptr2 = NULL;
- }
- if( ptr2!=NULL ) {
- // We got something, at least a username...
- int len = ptr2-ptr1;
- Curl->username = malloc(len+1);
- if( Curl->username==NULL ) {
- mp_tmsg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed.\n");
- goto err_out;
- }
- strncpy(Curl->username, ptr1, len);
- Curl->username[len] = '\0';
-
- ptr3 = strstr(ptr1, ":");
- if( ptr3!=NULL && ptr3<ptr2 ) {
- // We also have a password
- int len2 = ptr2-ptr3-1;
- Curl->username[ptr3-ptr1]='\0';
- Curl->password = malloc(len2+1);
- if( Curl->password==NULL ) {
- mp_tmsg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed.\n");
- goto err_out;
- }
- strncpy( Curl->password, ptr3+1, len2);
- Curl->password[len2]='\0';
- url_unescape_string(Curl->password, Curl->password);
- }
- url_unescape_string(Curl->username, Curl->username);
- ptr1 = ptr2+1;
- pos1 = ptr1-escfilename;
- }
-
- // before looking for a port number check if we have an IPv6 type numeric address
- // in IPv6 URL the numeric address should be inside square braces.
- ptr2 = strstr(ptr1, "[");
- ptr3 = strstr(ptr1, "]");
- ptr4 = strstr(ptr1, "/");
- if( ptr2!=NULL && ptr3!=NULL && ptr2 < ptr3 && (!ptr4 || ptr4 > ptr3)) {
- // we have an IPv6 numeric address
- ptr1++;
- pos1++;
- ptr2 = ptr3;
- v6addr = 1;
- } else {
- ptr2 = ptr1;
-
- }
-
- // look if the port is given
- ptr2 = strstr(ptr2, ":");
- // If the : is after the first / it isn't the port
- ptr3 = strstr(ptr1, "/");
- if(ptr3 && ptr3 - ptr2 < 0) ptr2 = NULL;
- if( ptr2==NULL ) {
- // No port is given
- // Look if a path is given
- if( ptr3==NULL ) {
- // No path/filename
- // So we have an URL like http://www.hostname.com
- pos2 = strlen(escfilename);
- } else {
- // We have an URL like http://www.hostname.com/file.txt
- pos2 = ptr3-escfilename;
- }
- } else {
- // We have an URL beginning like http://www.hostname.com:1212
- // Get the port number
- Curl->port = atoi(ptr2+1);
- pos2 = ptr2-escfilename;
- }
- if( v6addr ) pos2--;
- // copy the hostname in the URL container
- Curl->hostname = malloc(pos2-pos1+1);
- if( Curl->hostname==NULL ) {
- mp_tmsg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed.\n");
- goto err_out;
- }
- strncpy(Curl->hostname, ptr1, pos2-pos1);
- Curl->hostname[pos2-pos1] = '\0';
-
- // Look if a path is given
- ptr2 = strstr(ptr1, "/");
- if( ptr2!=NULL ) {
- // A path/filename is given
- // check if it's not a trailing '/'
- if( strlen(ptr2)>1 ) {
- // copy the path/filename in the URL container
- Curl->file = strdup(ptr2);
- if( Curl->file==NULL ) {
- mp_tmsg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed.\n");
- goto err_out;
- }
- }
- }
- // Check if a filename was given or set, else set it with '/'
- if( Curl->file==NULL ) {
- Curl->file = malloc(2);
- if( Curl->file==NULL ) {
- mp_tmsg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed.\n");
- goto err_out;
- }
- strcpy(Curl->file, "/");
- }
-
- Curl->noauth_url = get_noauth_url(Curl);
- if (!Curl->noauth_url) {
- mp_msg(MSGT_NETWORK, MSGL_FATAL, "Memory allocation failed.\n");
- goto err_out;
- }
-
- free(escfilename);
- return Curl;
-err_out:
- free(escfilename);
- if (Curl) url_free(Curl);
- return NULL;
-}
-
-void
-url_free(URL_t* url) {
- if(!url) return;
- free(url->url);
- free(url->protocol);
- free(url->hostname);
- free(url->file);
- free(url->username);
- free(url->password);
- free(url);
-}
-
-
-/* Replace escape sequences in an URL (or a part of an URL) */
-/* works like strcpy(), but without return argument,
- except that outbuf == inbuf is allowed */
-void
-url_unescape_string(char *outbuf, const char *inbuf)
-{
- unsigned char c,c1,c2;
- int i,len=strlen(inbuf);
- for (i=0;i<len;i++){
- c = inbuf[i];
- if (c == '%' && i<len-2) { //must have 2 more chars
- c1 = toupper(inbuf[i+1]); // we need uppercase characters
- c2 = toupper(inbuf[i+2]);
- if ( ((c1>='0' && c1<='9') || (c1>='A' && c1<='F')) &&
- ((c2>='0' && c2<='9') || (c2>='A' && c2<='F')) ) {
- if (c1>='0' && c1<='9') c1-='0';
- else c1-='A'-10;
- if (c2>='0' && c2<='9') c2-='0';
- else c2-='A'-10;
- c = (c1<<4) + c2;
- i=i+2; //only skip next 2 chars if valid esc
- }
- }
- *outbuf++ = c;
- }
- *outbuf++='\0'; //add nullterm to string
-}
-
-static void
-url_escape_string_part(char *outbuf, const char *inbuf) {
- unsigned char c,c1,c2;
- int i,len=strlen(inbuf);
-
- for (i=0;i<len;i++) {
- c = inbuf[i];
- if ((c=='%') && i<len-2 ) { //need 2 more characters
- c1=toupper(inbuf[i+1]); c2=toupper(inbuf[i+2]); // need uppercase chars
- } else {
- c1=129; c2=129; //not escape chars
- }
-
- if( (c >= 'A' && c <= 'Z') ||
- (c >= 'a' && c <= 'z') ||
- (c >= '0' && c <= '9')) {
- *outbuf++ = c;
- } else if ( c=='%' && ((c1 >= '0' && c1 <= '9') || (c1 >= 'A' && c1 <= 'F')) &&
- ((c2 >= '0' && c2 <= '9') || (c2 >= 'A' && c2 <= 'F'))) {
- // check if part of an escape sequence
- *outbuf++=c; // already
-
- // dont escape again
- mp_tmsg(MSGT_NETWORK,MSGL_ERR,"String appears to be already escaped in url_escape %c%c1%c2\n",c,c1,c2);
- // error as this should not happen against RFC 2396
- // to escape a string twice
- } else {
- /* all others will be escaped */
- c1 = ((c & 0xf0) >> 4);
- c2 = (c & 0x0f);
- if (c1 < 10) c1+='0';
- else c1+='A'-10;
- if (c2 < 10) c2+='0';
- else c2+='A'-10;
- *outbuf++ = '%';
- *outbuf++ = c1;
- *outbuf++ = c2;
- }
- }
- *outbuf++='\0';
-}
-
-/* Replace specific characters in the URL string by an escape sequence */
-/* works like strcpy(), but without return argument */
-void
-url_escape_string(char *outbuf, const char *inbuf) {
- unsigned char c;
- int i = 0,j,len = strlen(inbuf);
- char* tmp,*unesc = NULL, *in;
-
- // Look if we have an ip6 address, if so skip it there is
- // no need to escape anything in there.
- tmp = strstr(inbuf,"://[");
- if(tmp) {
- tmp = strchr(tmp+4,']');
- if(tmp && (tmp[1] == '/' || tmp[1] == ':' ||
- tmp[1] == '\0')) {
- i = tmp+1-inbuf;
- strncpy(outbuf,inbuf,i);
- outbuf += i;
- tmp = NULL;
- }
- }
-
- tmp = NULL;
- while(i < len) {
- // look for the next char that must be kept
- for (j=i;j<len;j++) {
- c = inbuf[j];
- if(c=='-' || c=='_' || c=='.' || c=='!' || c=='~' || /* mark characters */
- c=='*' || c=='\'' || c=='(' || c==')' || /* do not touch escape character */
- c==';' || c=='/' || c=='?' || c==':' || c=='@' || /* reserved characters */
- c=='&' || c=='=' || c=='+' || c=='$' || c==',') /* see RFC 2396 */
- break;
- }
- // we are on a reserved char, write it out
- if(j == i) {
- *outbuf++ = c;
- i++;
- continue;
- }
- // we found one, take that part of the string
- if(j < len) {
- if(!tmp) tmp = malloc(len+1);
- strncpy(tmp,inbuf+i,j-i);
- tmp[j-i] = '\0';
- in = tmp;
- } else // take the rest of the string
- in = (char*)inbuf+i;
-
- if(!unesc) unesc = malloc(len+1);
- // unescape first to avoid escaping escape
- url_unescape_string(unesc,in);
- // then escape, including mark and other reserved chars
- // that can come from escape sequences
- url_escape_string_part(outbuf,unesc);
- outbuf += strlen(outbuf);
- i += strlen(in);
- }
- *outbuf = '\0';
- free(tmp);
- free(unesc);
-}
-
-#ifdef URL_DEBUG
-void
-url_debug(const URL_t *url) {
- if( url==NULL ) {
- printf("URL pointer NULL\n");
- return;
- }
- if( url->url!=NULL ) {
- printf("url=%s\n", url->url );
- }
- if( url->protocol!=NULL ) {
- printf("protocol=%s\n", url->protocol );
- }
- if( url->hostname!=NULL ) {
- printf("hostname=%s\n", url->hostname );
- }
- printf("port=%d\n", url->port );
- if( url->file!=NULL ) {
- printf("file=%s\n", url->file );
- }
- if( url->username!=NULL ) {
- printf("username=%s\n", url->username );
- }
- if( url->password!=NULL ) {
- printf("password=%s\n", url->password );
- }
-}
-#endif /* URL_DEBUG */
diff --git a/stream/url.h b/stream/url.h
deleted file mode 100644
index 9115692fd1..0000000000
--- a/stream/url.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * URL Helper
- *
- * Copyright (C) 2001 Bertrand Baudet <bertrand_baudet@yahoo.com>
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef MPLAYER_URL_H
-#define MPLAYER_URL_H
-
-//#define URL_DEBUG
-
-typedef struct {
- char *url;
- char *noauth_url;
- char *protocol;
- char *hostname;
- char *file;
- unsigned int port;
- char *username;
- char *password;
-} URL_t;
-
-int url_is_protocol(const URL_t *url, const char *proto);
-void url_set_protocol(URL_t *url, const char *proto);
-URL_t *url_redirect(URL_t **url, const char *redir);
-
-char *get_http_proxy_url(const URL_t *proxy, const char *host_url);
-
-URL_t* url_new(const char* url);
-void url_free(URL_t* url);
-
-void url_unescape_string(char *outbuf, const char *inbuf);
-void url_escape_string(char *outbuf, const char *inbuf);
-
-#ifdef URL_DEBUG
-void url_debug(const URL_t* url);
-#endif /* URL_DEBUG */
-
-#endif /* MPLAYER_URL_H */