├── librtmp ├── librtmp.pc.in ├── http.h ├── log.h ├── bytes.h ├── Makefile ├── rtmp_sys.h ├── log.c ├── amf.h ├── parseurl.c ├── librtmp.3 ├── dh.h ├── librtmp.3.html ├── dhgroups.h ├── rtmp.h ├── hashswf.c └── COPYING ├── thread.h ├── thread.c ├── Makefile ├── rtmpgw.8 ├── rtmpdump.1 ├── README ├── ChangeLog ├── rtmpgw.8.html ├── rtmpdump.1.html └── COPYING /librtmp/librtmp.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=${prefix} 3 | libdir=@libdir@ 4 | incdir=${prefix}/include 5 | 6 | Name: librtmp 7 | Description: RTMP implementation 8 | Version: @VERSION@ 9 | Requires: @CRYPTO_REQ@ 10 | URL: http://rtmpdump.mplayerhq.hu 11 | Libs: -L${libdir} -lrtmp -lz 12 | Libs.private: @PRIVATE_LIBS@ 13 | Cflags: -I${incdir} 14 | -------------------------------------------------------------------------------- /thread.h: -------------------------------------------------------------------------------- 1 | /* Thread compatibility glue 2 | * Copyright (C) 2009 Howard Chu 3 | * 4 | * This Program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2, or (at your option) 7 | * any later version. 8 | * 9 | * This Program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with RTMPDump; see the file COPYING. If not, write to 16 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301, USA. 18 | * http://www.gnu.org/copyleft/gpl.html 19 | * 20 | */ 21 | 22 | #ifndef __THREAD_H__ 23 | #define __THREAD_H__ 1 24 | 25 | #ifdef WIN32 26 | #include 27 | #include 28 | #define TFTYPE void 29 | #define TFRET() 30 | #define THANDLE HANDLE 31 | #else 32 | #include 33 | #define TFTYPE void * 34 | #define TFRET() return 0 35 | #define THANDLE pthread_t 36 | #endif 37 | typedef TFTYPE (thrfunc)(void *arg); 38 | 39 | THANDLE ThreadCreate(thrfunc *routine, void *args); 40 | #endif /* __THREAD_H__ */ 41 | -------------------------------------------------------------------------------- /thread.c: -------------------------------------------------------------------------------- 1 | /* Thread compatibility glue 2 | * Copyright (C) 2009 Howard Chu 3 | * 4 | * This Program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2, or (at your option) 7 | * any later version. 8 | * 9 | * This Program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with RTMPDump; see the file COPYING. If not, write to 16 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301, USA. 18 | * http://www.gnu.org/copyleft/gpl.html 19 | * 20 | */ 21 | 22 | #include "thread.h" 23 | #include "librtmp/log.h" 24 | 25 | #ifdef WIN32 26 | 27 | #include 28 | 29 | HANDLE 30 | ThreadCreate(thrfunc *routine, void *args) 31 | { 32 | HANDLE thd; 33 | 34 | thd = (HANDLE) _beginthread(routine, 0, args); 35 | if (thd == -1L) 36 | RTMP_LogPrintf("%s, _beginthread failed with %d\n", __FUNCTION__, errno); 37 | 38 | return thd; 39 | } 40 | #else 41 | pthread_t 42 | ThreadCreate(thrfunc *routine, void *args) 43 | { 44 | pthread_t id = 0; 45 | pthread_attr_t attributes; 46 | int ret; 47 | 48 | pthread_attr_init(&attributes); 49 | pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED); 50 | 51 | ret = 52 | pthread_create(&id, &attributes, routine, args); 53 | if (ret != 0) 54 | RTMP_LogPrintf("%s, pthread_create failed with %d\n", __FUNCTION__, ret); 55 | 56 | return id; 57 | } 58 | #endif 59 | -------------------------------------------------------------------------------- /librtmp/http.h: -------------------------------------------------------------------------------- 1 | #ifndef __RTMP_HTTP_H__ 2 | #define __RTMP_HTTP_H__ 3 | /* 4 | * Copyright (C) 2010 Howard Chu 5 | * Copyright (C) 2010 Antti Ajanki 6 | * 7 | * This file is part of librtmp. 8 | * 9 | * librtmp is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU Lesser General Public License as 11 | * published by the Free Software Foundation; either version 2.1, 12 | * or (at your option) any later version. 13 | * 14 | * librtmp is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public License 20 | * along with librtmp see the file COPYING. If not, write to 21 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 22 | * Boston, MA 02110-1301, USA. 23 | * http://www.gnu.org/copyleft/lgpl.html 24 | */ 25 | 26 | typedef enum { 27 | HTTPRES_OK, /* result OK */ 28 | HTTPRES_OK_NOT_MODIFIED, /* not modified since last request */ 29 | HTTPRES_NOT_FOUND, /* not found */ 30 | HTTPRES_BAD_REQUEST, /* client error */ 31 | HTTPRES_SERVER_ERROR, /* server reported an error */ 32 | HTTPRES_REDIRECTED, /* resource has been moved */ 33 | HTTPRES_LOST_CONNECTION /* connection lost while waiting for data */ 34 | } HTTPResult; 35 | 36 | struct HTTP_ctx { 37 | char *date; 38 | int size; 39 | int status; 40 | void *data; 41 | }; 42 | 43 | typedef size_t (HTTP_read_callback)(void *ptr, size_t size, size_t nmemb, void *stream); 44 | 45 | HTTPResult HTTP_get(struct HTTP_ctx *http, const char *url, HTTP_read_callback *cb); 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | VERSION=v2.4 2 | 3 | prefix=/usr/local 4 | 5 | CC=$(CROSS_COMPILE)gcc 6 | LD=$(CROSS_COMPILE)ld 7 | 8 | SYS=posix 9 | #SYS=mingw 10 | 11 | CRYPTO=OPENSSL 12 | #CRYPTO=POLARSSL 13 | #CRYPTO=GNUTLS 14 | LIBZ=-lz 15 | LIB_GNUTLS=-lgnutls -lgcrypt $(LIBZ) 16 | LIB_OPENSSL=-lssl -lcrypto $(LIBZ) 17 | LIB_POLARSSL=-lpolarssl $(LIBZ) 18 | CRYPTO_LIB=$(LIB_$(CRYPTO)) 19 | DEF_=-DNO_CRYPTO 20 | CRYPTO_DEF=$(DEF_$(CRYPTO)) 21 | 22 | DEF=-DRTMPDUMP_VERSION=\"$(VERSION)\" $(CRYPTO_DEF) $(XDEF) 23 | OPT=-O2 24 | CFLAGS=-Wall $(XCFLAGS) $(INC) $(DEF) $(OPT) 25 | LDFLAGS=-Wall $(XLDFLAGS) 26 | 27 | bindir=$(prefix)/bin 28 | sbindir=$(prefix)/sbin 29 | mandir=$(prefix)/man 30 | 31 | BINDIR=$(DESTDIR)$(bindir) 32 | SBINDIR=$(DESTDIR)$(sbindir) 33 | MANDIR=$(DESTDIR)$(mandir) 34 | 35 | LIBS_posix=-lm 36 | LIBS_darwin= 37 | LIBS_mingw=-lws2_32 -lwinmm -lgdi32 38 | LIB_RTMP=-Llibrtmp -lrtmp 39 | LIBS=$(LIB_RTMP) $(CRYPTO_LIB) $(LIBS_$(SYS)) $(XLIBS) 40 | 41 | THREADLIB_posix=-lpthread 42 | THREADLIB_darwin=-lpthread 43 | THREADLIB_mingw= 44 | THREADLIB=$(THREADLIB_$(SYS)) 45 | SLIBS=$(THREADLIB) $(LIBS) 46 | 47 | LIBRTMP=librtmp/librtmp.a 48 | INCRTMP=librtmp/rtmp_sys.h librtmp/rtmp.h librtmp/log.h librtmp/amf.h 49 | 50 | EXT_posix= 51 | EXT_darwin= 52 | EXT_mingw=.exe 53 | EXT=$(EXT_$(SYS)) 54 | 55 | PROGS=rtmpdump rtmpgw rtmpsrv rtmpsuck 56 | 57 | all: $(LIBRTMP) $(PROGS) 58 | 59 | $(PROGS): $(LIBRTMP) 60 | 61 | install: $(PROGS) 62 | -mkdir -p $(BINDIR) $(SBINDIR) $(MANDIR)/man1 $(MANDIR)/man8 63 | cp rtmpdump$(EXT) $(BINDIR) 64 | cp rtmpgw$(EXT) rtmpsrv$(EXT) rtmpsuck$(EXT) $(SBINDIR) 65 | cp rtmpdump.1 $(MANDIR)/man1 66 | cp rtmpgw.8 $(MANDIR)/man8 67 | @cd librtmp; $(MAKE) install 68 | 69 | clean: 70 | rm -f *.o rtmpdump$(EXT) rtmpgw$(EXT) rtmpsrv$(EXT) rtmpsuck$(EXT) 71 | @cd librtmp; $(MAKE) clean 72 | 73 | FORCE: 74 | 75 | $(LIBRTMP): FORCE 76 | @cd librtmp; $(MAKE) all 77 | 78 | rtmpdump: rtmpdump.o 79 | $(CC) $(LDFLAGS) -o $@$(EXT) $@.o $(LIBS) 80 | 81 | rtmpsrv: rtmpsrv.o thread.o 82 | $(CC) $(LDFLAGS) -o $@$(EXT) $@.o thread.o $(SLIBS) 83 | 84 | rtmpsuck: rtmpsuck.o thread.o 85 | $(CC) $(LDFLAGS) -o $@$(EXT) $@.o thread.o $(SLIBS) 86 | 87 | rtmpgw: rtmpgw.o thread.o 88 | $(CC) $(LDFLAGS) -o $@$(EXT) $@.o thread.o $(SLIBS) 89 | 90 | rtmpgw.o: rtmpgw.c $(INCRTMP) Makefile 91 | rtmpdump.o: rtmpdump.c $(INCRTMP) Makefile 92 | rtmpsrv.o: rtmpsrv.c $(INCRTMP) Makefile 93 | rtmpsuck.o: rtmpsuck.c $(INCRTMP) Makefile 94 | thread.o: thread.c thread.h 95 | -------------------------------------------------------------------------------- /librtmp/log.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008-2009 Andrej Stepanchuk 3 | * Copyright (C) 2009-2010 Howard Chu 4 | * 5 | * This file is part of librtmp. 6 | * 7 | * librtmp is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as 9 | * published by the Free Software Foundation; either version 2.1, 10 | * or (at your option) any later version. 11 | * 12 | * librtmp is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with librtmp see the file COPYING. If not, write to 19 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 20 | * Boston, MA 02110-1301, USA. 21 | * http://www.gnu.org/copyleft/lgpl.html 22 | */ 23 | 24 | #ifndef __RTMP_LOG_H__ 25 | #define __RTMP_LOG_H__ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | /* Enable this to get full debugging output */ 35 | /* #define _DEBUG */ 36 | 37 | #ifdef _DEBUG 38 | #undef NODEBUG 39 | #endif 40 | 41 | typedef enum 42 | { RTMP_LOGCRIT=0, RTMP_LOGERROR, RTMP_LOGWARNING, RTMP_LOGINFO, 43 | RTMP_LOGDEBUG, RTMP_LOGDEBUG2, RTMP_LOGALL 44 | } RTMP_LogLevel; 45 | 46 | extern RTMP_LogLevel RTMP_debuglevel; 47 | 48 | typedef void (RTMP_LogCallback)(int level, const char *fmt, va_list); 49 | void RTMP_LogSetCallback(RTMP_LogCallback *cb); 50 | void RTMP_LogSetOutput(FILE *file); 51 | #ifdef __GNUC__ 52 | void RTMP_LogPrintf(const char *format, ...) __attribute__ ((__format__ (__printf__, 1, 2))); 53 | void RTMP_LogStatus(const char *format, ...) __attribute__ ((__format__ (__printf__, 1, 2))); 54 | void RTMP_Log(int level, const char *format, ...) __attribute__ ((__format__ (__printf__, 2, 3))); 55 | #else 56 | void RTMP_LogPrintf(const char *format, ...); 57 | void RTMP_LogStatus(const char *format, ...); 58 | void RTMP_Log(int level, const char *format, ...); 59 | #endif 60 | void RTMP_LogHex(int level, const uint8_t *data, unsigned long len); 61 | void RTMP_LogHexString(int level, const uint8_t *data, unsigned long len); 62 | void RTMP_LogSetLevel(RTMP_LogLevel lvl); 63 | RTMP_LogLevel RTMP_LogGetLevel(void); 64 | 65 | #ifdef __cplusplus 66 | } 67 | #endif 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /librtmp/bytes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2008 Team XBMC 3 | * http://www.xbmc.org 4 | * Copyright (C) 2008-2009 Andrej Stepanchuk 5 | * Copyright (C) 2009-2010 Howard Chu 6 | * 7 | * This file is part of librtmp. 8 | * 9 | * librtmp is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU Lesser General Public License as 11 | * published by the Free Software Foundation; either version 2.1, 12 | * or (at your option) any later version. 13 | * 14 | * librtmp is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public License 20 | * along with librtmp see the file COPYING. If not, write to 21 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 22 | * Boston, MA 02110-1301, USA. 23 | * http://www.gnu.org/copyleft/lgpl.html 24 | */ 25 | 26 | #ifndef __BYTES_H__ 27 | #define __BYTES_H__ 28 | 29 | #include 30 | 31 | #ifdef _WIN32 32 | /* Windows is little endian only */ 33 | #define __LITTLE_ENDIAN 1234 34 | #define __BIG_ENDIAN 4321 35 | #define __BYTE_ORDER __LITTLE_ENDIAN 36 | #define __FLOAT_WORD_ORDER __BYTE_ORDER 37 | 38 | typedef unsigned char uint8_t; 39 | 40 | #else /* !_WIN32 */ 41 | 42 | #include 43 | 44 | #if defined(BYTE_ORDER) && !defined(__BYTE_ORDER) 45 | #define __BYTE_ORDER BYTE_ORDER 46 | #endif 47 | 48 | #if defined(BIG_ENDIAN) && !defined(__BIG_ENDIAN) 49 | #define __BIG_ENDIAN BIG_ENDIAN 50 | #endif 51 | 52 | #if defined(LITTLE_ENDIAN) && !defined(__LITTLE_ENDIAN) 53 | #define __LITTLE_ENDIAN LITTLE_ENDIAN 54 | #endif 55 | 56 | #endif /* !_WIN32 */ 57 | 58 | /* define default endianness */ 59 | #ifndef __LITTLE_ENDIAN 60 | #define __LITTLE_ENDIAN 1234 61 | #endif 62 | 63 | #ifndef __BIG_ENDIAN 64 | #define __BIG_ENDIAN 4321 65 | #endif 66 | 67 | #ifndef __BYTE_ORDER 68 | #warning "Byte order not defined on your system, assuming little endian!" 69 | #define __BYTE_ORDER __LITTLE_ENDIAN 70 | #endif 71 | 72 | /* ok, we assume to have the same float word order and byte order if float word order is not defined */ 73 | #ifndef __FLOAT_WORD_ORDER 74 | #warning "Float word order not defined, assuming the same as byte order!" 75 | #define __FLOAT_WORD_ORDER __BYTE_ORDER 76 | #endif 77 | 78 | #if !defined(__BYTE_ORDER) || !defined(__FLOAT_WORD_ORDER) 79 | #error "Undefined byte or float word order!" 80 | #endif 81 | 82 | #if __FLOAT_WORD_ORDER != __BIG_ENDIAN && __FLOAT_WORD_ORDER != __LITTLE_ENDIAN 83 | #error "Unknown/unsupported float word order!" 84 | #endif 85 | 86 | #if __BYTE_ORDER != __BIG_ENDIAN && __BYTE_ORDER != __LITTLE_ENDIAN 87 | #error "Unknown/unsupported byte order!" 88 | #endif 89 | 90 | #endif 91 | 92 | -------------------------------------------------------------------------------- /librtmp/Makefile: -------------------------------------------------------------------------------- 1 | VERSION=v2.4 2 | 3 | prefix=/usr/local 4 | 5 | incdir=$(prefix)/include/librtmp 6 | bindir=$(prefix)/bin 7 | libdir=$(prefix)/lib 8 | mandir=$(prefix)/man 9 | BINDIR=$(DESTDIR)$(bindir) 10 | INCDIR=$(DESTDIR)$(incdir) 11 | LIBDIR=$(DESTDIR)$(libdir) 12 | MANDIR=$(DESTDIR)$(mandir) 13 | 14 | CC=$(CROSS_COMPILE)gcc 15 | LD=$(CROSS_COMPILE)ld 16 | AR=$(CROSS_COMPILE)ar 17 | 18 | SYS=posix 19 | CRYPTO=OPENSSL 20 | #CRYPTO=GNUTLS 21 | DEF_POLARSSL=-DUSE_POLARSSL 22 | DEF_OPENSSL=-DUSE_OPENSSL 23 | DEF_GNUTLS=-DUSE_GNUTLS 24 | DEF_=-DNO_CRYPTO 25 | REQ_GNUTLS=gnutls 26 | REQ_OPENSSL=libssl,libcrypto 27 | LIBZ=-lz 28 | LIBS_posix= 29 | LIBS_darwin= 30 | LIBS_mingw=-lws2_32 -lwinmm -lgdi32 31 | LIB_GNUTLS=-lgnutls -lgcrypt $(LIBZ) 32 | LIB_OPENSSL=-lssl -lcrypto $(LIBZ) 33 | LIB_POLARSSL=-lpolarssl $(LIBZ) 34 | PRIVATE_LIBS=$(LIBS_$(SYS)) 35 | CRYPTO_LIB=$(LIB_$(CRYPTO)) $(PRIVATE_LIBS) 36 | CRYPTO_REQ=$(REQ_$(CRYPTO)) 37 | CRYPTO_DEF=$(DEF_$(CRYPTO)) 38 | 39 | SO_VERSION=0 40 | SOX_posix=so 41 | SOX_darwin=dylib 42 | SOX_mingw=so # useless 43 | SOX=$(SOX_$(SYS)) 44 | SO_posix=$(SOX).$(SO_VERSION) 45 | SO_darwin=$(SO_VERSION).$(SOX) 46 | SO_mingw=dll 47 | SO_EXT=$(SO_$(SYS)) 48 | 49 | SODIR_posix=$(LIBDIR) 50 | SODIR_darwin=$(LIBDIR) 51 | SODIR_mingw=$(BINDIR) 52 | SODIR=$(SODIR_$(SYS)) 53 | 54 | SO_LDFLAGS_posix=-shared -Wl,-soname,$@ 55 | SO_LDFLAGS_darwin=-dynamiclib -twolevel_namespace -undefined dynamic_lookup \ 56 | -fno-common -headerpad_max_install_names -install_name $(libdir)/$@ 57 | SO_LDFLAGS_mingw=-shared -Wl,--out-implib,librtmp.dll.a 58 | SO_LDFLAGS=$(SO_LDFLAGS_$(SYS)) 59 | 60 | INSTALL_IMPLIB_posix= 61 | INSTALL_IMPLIB_darwin= 62 | INSTALL_IMPLIB_mingw=cp librtmp.dll.a $(LIBDIR) 63 | INSTALL_IMPLIB=$(INSTALL_IMPLIB_$(SYS)) 64 | 65 | SHARED=yes 66 | SODEF_yes=-fPIC 67 | SOLIB_yes=librtmp.$(SO_EXT) 68 | SOINST_yes=install_so 69 | SO_DEF=$(SODEF_$(SHARED)) 70 | SO_LIB=$(SOLIB_$(SHARED)) 71 | SO_INST=$(SOINST_$(SHARED)) 72 | 73 | DEF=-DRTMPDUMP_VERSION=\"$(VERSION)\" $(CRYPTO_DEF) $(XDEF) 74 | OPT=-O2 75 | CFLAGS=-Wall $(XCFLAGS) $(INC) $(DEF) $(OPT) $(SO_DEF) 76 | LDFLAGS=$(XLDFLAGS) 77 | 78 | 79 | OBJS=rtmp.o log.o amf.o hashswf.o parseurl.o 80 | 81 | all: librtmp.a $(SO_LIB) 82 | 83 | clean: 84 | rm -f *.o *.a *.$(SOX) *.$(SO_EXT) librtmp.pc 85 | 86 | librtmp.a: $(OBJS) 87 | $(AR) rs $@ $? 88 | 89 | librtmp.$(SO_EXT): $(OBJS) 90 | $(CC) $(SO_LDFLAGS) $(LDFLAGS) -o $@ $^ $> $(CRYPTO_LIB) 91 | ln -sf $@ librtmp.$(SOX) 92 | 93 | log.o: log.c log.h Makefile 94 | rtmp.o: rtmp.c rtmp.h rtmp_sys.h handshake.h dh.h log.h amf.h Makefile 95 | amf.o: amf.c amf.h bytes.h log.h Makefile 96 | hashswf.o: hashswf.c http.h rtmp.h rtmp_sys.h Makefile 97 | parseurl.o: parseurl.c rtmp.h rtmp_sys.h log.h Makefile 98 | 99 | librtmp.pc: librtmp.pc.in Makefile 100 | sed -e "s;@prefix@;$(prefix);" -e "s;@libdir@;$(libdir);" \ 101 | -e "s;@VERSION@;$(VERSION);" \ 102 | -e "s;@CRYPTO_REQ@;$(CRYPTO_REQ);" \ 103 | -e "s;@PRIVATE_LIBS@;$(PRIVATE_LIBS);" librtmp.pc.in > $@ 104 | 105 | install: install_base $(SO_INST) 106 | 107 | install_base: librtmp.a librtmp.pc 108 | -mkdir -p $(INCDIR) $(LIBDIR)/pkgconfig $(MANDIR)/man3 $(SODIR) 109 | cp amf.h http.h log.h rtmp.h $(INCDIR) 110 | cp librtmp.a $(LIBDIR) 111 | cp librtmp.pc $(LIBDIR)/pkgconfig 112 | cp librtmp.3 $(MANDIR)/man3 113 | 114 | install_so: librtmp.$(SO_EXT) 115 | cp librtmp.$(SO_EXT) $(SODIR) 116 | $(INSTALL_IMPLIB) 117 | cd $(SODIR); ln -sf librtmp.$(SO_EXT) librtmp.$(SOX) 118 | 119 | -------------------------------------------------------------------------------- /librtmp/rtmp_sys.h: -------------------------------------------------------------------------------- 1 | #ifndef __RTMP_SYS_H__ 2 | #define __RTMP_SYS_H__ 3 | /* 4 | * Copyright (C) 2010 Howard Chu 5 | * 6 | * This file is part of librtmp. 7 | * 8 | * librtmp is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU Lesser General Public License as 10 | * published by the Free Software Foundation; either version 2.1, 11 | * or (at your option) any later version. 12 | * 13 | * librtmp is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public License 19 | * along with librtmp see the file COPYING. If not, write to 20 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 21 | * Boston, MA 02110-1301, USA. 22 | * http://www.gnu.org/copyleft/lgpl.html 23 | */ 24 | 25 | #ifdef _WIN32 26 | 27 | #include 28 | #include 29 | 30 | #ifdef _MSC_VER /* MSVC */ 31 | #define snprintf _snprintf 32 | #define strcasecmp stricmp 33 | #define strncasecmp strnicmp 34 | #define vsnprintf _vsnprintf 35 | #endif 36 | 37 | #define GetSockError() WSAGetLastError() 38 | #define SetSockError(e) WSASetLastError(e) 39 | #define setsockopt(a,b,c,d,e) (setsockopt)(a,b,c,(const char *)d,(int)e) 40 | #define EWOULDBLOCK WSAETIMEDOUT /* we don't use nonblocking, but we do use timeouts */ 41 | #define sleep(n) Sleep(n*1000) 42 | #define msleep(n) Sleep(n) 43 | #define SET_RCVTIMEO(tv,s) int tv = s*1000 44 | #else /* !_WIN32 */ 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #define GetSockError() errno 54 | #define SetSockError(e) errno = e 55 | #undef closesocket 56 | #define closesocket(s) close(s) 57 | #define msleep(n) usleep(n*1000) 58 | #define SET_RCVTIMEO(tv,s) struct timeval tv = {s,0} 59 | #endif 60 | 61 | #include "rtmp.h" 62 | 63 | #ifdef USE_POLARSSL 64 | #include 65 | #include 66 | #include 67 | typedef struct tls_ctx { 68 | havege_state hs; 69 | ssl_session ssn; 70 | } tls_ctx; 71 | #define TLS_CTX tls_ctx * 72 | #define TLS_client(ctx,s) s = malloc(sizeof(ssl_context)); ssl_init(s);\ 73 | ssl_set_endpoint(s, SSL_IS_CLIENT); ssl_set_authmode(s, SSL_VERIFY_NONE);\ 74 | ssl_set_rng(s, havege_random, &ctx->hs);\ 75 | ssl_set_ciphersuites(s, ssl_default_ciphersuites);\ 76 | ssl_set_session(s, 1, 600, &ctx->ssn) 77 | #define TLS_setfd(s,fd) ssl_set_bio(s, net_recv, &fd, net_send, &fd) 78 | #define TLS_connect(s) ssl_handshake(s) 79 | #define TLS_read(s,b,l) ssl_read(s,(unsigned char *)b,l) 80 | #define TLS_write(s,b,l) ssl_write(s,(unsigned char *)b,l) 81 | #define TLS_shutdown(s) ssl_close_notify(s) 82 | #define TLS_close(s) ssl_free(s); free(s) 83 | 84 | #elif defined(USE_GNUTLS) 85 | #include 86 | typedef struct tls_ctx { 87 | gnutls_certificate_credentials_t cred; 88 | gnutls_priority_t prios; 89 | } tls_ctx; 90 | #define TLS_CTX tls_ctx * 91 | #define TLS_client(ctx,s) gnutls_init((gnutls_session_t *)(&s), GNUTLS_CLIENT); gnutls_priority_set(s, ctx->prios); gnutls_credentials_set(s, GNUTLS_CRD_CERTIFICATE, ctx->cred) 92 | #define TLS_setfd(s,fd) gnutls_transport_set_ptr(s, (gnutls_transport_ptr_t)(long)fd) 93 | #define TLS_connect(s) gnutls_handshake(s) 94 | #define TLS_read(s,b,l) gnutls_record_recv(s,b,l) 95 | #define TLS_write(s,b,l) gnutls_record_send(s,b,l) 96 | #define TLS_shutdown(s) gnutls_bye(s, GNUTLS_SHUT_RDWR) 97 | #define TLS_close(s) gnutls_deinit(s) 98 | 99 | #else /* USE_OPENSSL */ 100 | #define TLS_CTX SSL_CTX * 101 | #define TLS_client(ctx,s) s = SSL_new(ctx) 102 | #define TLS_setfd(s,fd) SSL_set_fd(s,fd) 103 | #define TLS_connect(s) SSL_connect(s) 104 | #define TLS_read(s,b,l) SSL_read(s,b,l) 105 | #define TLS_write(s,b,l) SSL_write(s,b,l) 106 | #define TLS_shutdown(s) SSL_shutdown(s) 107 | #define TLS_close(s) SSL_free(s) 108 | 109 | #endif 110 | #endif 111 | -------------------------------------------------------------------------------- /librtmp/log.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008-2009 Andrej Stepanchuk 3 | * Copyright (C) 2009-2010 Howard Chu 4 | * 5 | * This file is part of librtmp. 6 | * 7 | * librtmp is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as 9 | * published by the Free Software Foundation; either version 2.1, 10 | * or (at your option) any later version. 11 | * 12 | * librtmp is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with librtmp see the file COPYING. If not, write to 19 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 20 | * Boston, MA 02110-1301, USA. 21 | * http://www.gnu.org/copyleft/lgpl.html 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include "rtmp_sys.h" 31 | #include "log.h" 32 | 33 | #define MAX_PRINT_LEN 2048 34 | 35 | RTMP_LogLevel RTMP_debuglevel = RTMP_LOGERROR; 36 | 37 | static int neednl; 38 | 39 | static FILE *fmsg; 40 | 41 | static RTMP_LogCallback rtmp_log_default, *cb = rtmp_log_default; 42 | 43 | static const char *levels[] = { 44 | "CRIT", "ERROR", "WARNING", "INFO", 45 | "DEBUG", "DEBUG2" 46 | }; 47 | 48 | static void rtmp_log_default(int level, const char *format, va_list vl) 49 | { 50 | char str[MAX_PRINT_LEN]=""; 51 | 52 | vsnprintf(str, MAX_PRINT_LEN-1, format, vl); 53 | 54 | /* Filter out 'no-name' */ 55 | if (RTMP_debuglevel < RTMP_LOGDEBUG && strstr(str, "no-name") != NULL) 56 | return; 57 | 58 | if ( !fmsg ) fmsg = stderr; 59 | 60 | if ( level <= RTMP_debuglevel ) { 61 | if (neednl) { 62 | putc('\n', fmsg); 63 | neednl = 0; 64 | } 65 | fprintf(fmsg, "%s: %s\n", levels[level], str); 66 | #ifdef _DEBUG 67 | fflush(fmsg); 68 | #endif 69 | } 70 | } 71 | 72 | void RTMP_LogSetOutput(FILE *file) 73 | { 74 | fmsg = file; 75 | } 76 | 77 | void RTMP_LogSetLevel(RTMP_LogLevel level) 78 | { 79 | RTMP_debuglevel = level; 80 | } 81 | 82 | void RTMP_LogSetCallback(RTMP_LogCallback *cbp) 83 | { 84 | cb = cbp; 85 | } 86 | 87 | RTMP_LogLevel RTMP_LogGetLevel() 88 | { 89 | return RTMP_debuglevel; 90 | } 91 | 92 | void RTMP_Log(int level, const char *format, ...) 93 | { 94 | va_list args; 95 | va_start(args, format); 96 | cb(level, format, args); 97 | va_end(args); 98 | } 99 | 100 | static const char hexdig[] = "0123456789abcdef"; 101 | 102 | void RTMP_LogHex(int level, const uint8_t *data, unsigned long len) 103 | { 104 | unsigned long i; 105 | char line[50], *ptr; 106 | 107 | if ( level > RTMP_debuglevel ) 108 | return; 109 | 110 | ptr = line; 111 | 112 | for(i=0; i> 4)]; 114 | *ptr++ = hexdig[0x0f & data[i]]; 115 | if ((i & 0x0f) == 0x0f) { 116 | *ptr = '\0'; 117 | ptr = line; 118 | RTMP_Log(level, "%s", line); 119 | } else { 120 | *ptr++ = ' '; 121 | } 122 | } 123 | if (i & 0x0f) { 124 | *ptr = '\0'; 125 | RTMP_Log(level, "%s", line); 126 | } 127 | } 128 | 129 | void RTMP_LogHexString(int level, const uint8_t *data, unsigned long len) 130 | { 131 | #define BP_OFFSET 9 132 | #define BP_GRAPH 60 133 | #define BP_LEN 80 134 | char line[BP_LEN]; 135 | unsigned long i; 136 | 137 | if ( !data || level > RTMP_debuglevel ) 138 | return; 139 | 140 | /* in case len is zero */ 141 | line[0] = '\0'; 142 | 143 | for ( i = 0 ; i < len ; i++ ) { 144 | int n = i % 16; 145 | unsigned off; 146 | 147 | if( !n ) { 148 | if( i ) RTMP_Log( level, "%s", line ); 149 | memset( line, ' ', sizeof(line)-2 ); 150 | line[sizeof(line)-2] = '\0'; 151 | 152 | off = i % 0x0ffffU; 153 | 154 | line[2] = hexdig[0x0f & (off >> 12)]; 155 | line[3] = hexdig[0x0f & (off >> 8)]; 156 | line[4] = hexdig[0x0f & (off >> 4)]; 157 | line[5] = hexdig[0x0f & off]; 158 | line[6] = ':'; 159 | } 160 | 161 | off = BP_OFFSET + n*3 + ((n >= 8)?1:0); 162 | line[off] = hexdig[0x0f & ( data[i] >> 4 )]; 163 | line[off+1] = hexdig[0x0f & data[i]]; 164 | 165 | off = BP_GRAPH + n + ((n >= 8)?1:0); 166 | 167 | if ( isprint( data[i] )) { 168 | line[BP_GRAPH + n] = data[i]; 169 | } else { 170 | line[BP_GRAPH + n] = '.'; 171 | } 172 | } 173 | 174 | RTMP_Log( level, "%s", line ); 175 | } 176 | 177 | /* These should only be used by apps, never by the library itself */ 178 | void RTMP_LogPrintf(const char *format, ...) 179 | { 180 | char str[MAX_PRINT_LEN]=""; 181 | int len; 182 | va_list args; 183 | va_start(args, format); 184 | len = vsnprintf(str, MAX_PRINT_LEN-1, format, args); 185 | va_end(args); 186 | 187 | if ( RTMP_debuglevel==RTMP_LOGCRIT ) 188 | return; 189 | 190 | if ( !fmsg ) fmsg = stderr; 191 | 192 | if (neednl) { 193 | putc('\n', fmsg); 194 | neednl = 0; 195 | } 196 | 197 | if (len > MAX_PRINT_LEN-1) 198 | len = MAX_PRINT_LEN-1; 199 | fprintf(fmsg, "%s", str); 200 | if (str[len-1] == '\n') 201 | fflush(fmsg); 202 | } 203 | 204 | void RTMP_LogStatus(const char *format, ...) 205 | { 206 | char str[MAX_PRINT_LEN]=""; 207 | va_list args; 208 | va_start(args, format); 209 | vsnprintf(str, MAX_PRINT_LEN-1, format, args); 210 | va_end(args); 211 | 212 | if ( RTMP_debuglevel==RTMP_LOGCRIT ) 213 | return; 214 | 215 | if ( !fmsg ) fmsg = stderr; 216 | 217 | fprintf(fmsg, "%s", str); 218 | fflush(fmsg); 219 | neednl = 1; 220 | } 221 | -------------------------------------------------------------------------------- /librtmp/amf.h: -------------------------------------------------------------------------------- 1 | #ifndef __AMF_H__ 2 | #define __AMF_H__ 3 | /* 4 | * Copyright (C) 2005-2008 Team XBMC 5 | * http://www.xbmc.org 6 | * Copyright (C) 2008-2009 Andrej Stepanchuk 7 | * Copyright (C) 2009-2010 Howard Chu 8 | * 9 | * This file is part of librtmp. 10 | * 11 | * librtmp is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU Lesser General Public License as 13 | * published by the Free Software Foundation; either version 2.1, 14 | * or (at your option) any later version. 15 | * 16 | * librtmp is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU Lesser General Public License 22 | * along with librtmp see the file COPYING. If not, write to 23 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 24 | * Boston, MA 02110-1301, USA. 25 | * http://www.gnu.org/copyleft/lgpl.html 26 | */ 27 | 28 | #include 29 | 30 | #ifndef TRUE 31 | #define TRUE 1 32 | #define FALSE 0 33 | #endif 34 | 35 | #ifdef __cplusplus 36 | extern "C" 37 | { 38 | #endif 39 | 40 | typedef enum 41 | { AMF_NUMBER = 0, AMF_BOOLEAN, AMF_STRING, AMF_OBJECT, 42 | AMF_MOVIECLIP, /* reserved, not used */ 43 | AMF_NULL, AMF_UNDEFINED, AMF_REFERENCE, AMF_ECMA_ARRAY, AMF_OBJECT_END, 44 | AMF_STRICT_ARRAY, AMF_DATE, AMF_LONG_STRING, AMF_UNSUPPORTED, 45 | AMF_RECORDSET, /* reserved, not used */ 46 | AMF_XML_DOC, AMF_TYPED_OBJECT, 47 | AMF_AVMPLUS, /* switch to AMF3 */ 48 | AMF_INVALID = 0xff 49 | } AMFDataType; 50 | 51 | typedef enum 52 | { AMF3_UNDEFINED = 0, AMF3_NULL, AMF3_FALSE, AMF3_TRUE, 53 | AMF3_INTEGER, AMF3_DOUBLE, AMF3_STRING, AMF3_XML_DOC, AMF3_DATE, 54 | AMF3_ARRAY, AMF3_OBJECT, AMF3_XML, AMF3_BYTE_ARRAY 55 | } AMF3DataType; 56 | 57 | typedef struct AVal 58 | { 59 | char *av_val; 60 | int av_len; 61 | } AVal; 62 | #define AVC(str) {str,sizeof(str)-1} 63 | #define AVMATCH(a1,a2) ((a1)->av_len == (a2)->av_len && !memcmp((a1)->av_val,(a2)->av_val,(a1)->av_len)) 64 | 65 | struct AMFObjectProperty; 66 | 67 | typedef struct AMFObject 68 | { 69 | int o_num; 70 | struct AMFObjectProperty *o_props; 71 | } AMFObject; 72 | 73 | typedef struct AMFObjectProperty 74 | { 75 | AVal p_name; 76 | AMFDataType p_type; 77 | union 78 | { 79 | double p_number; 80 | AVal p_aval; 81 | AMFObject p_object; 82 | } p_vu; 83 | int16_t p_UTCoffset; 84 | } AMFObjectProperty; 85 | 86 | char *AMF_EncodeString(char *output, char *outend, const AVal * str); 87 | char *AMF_EncodeNumber(char *output, char *outend, double dVal); 88 | char *AMF_EncodeInt16(char *output, char *outend, short nVal); 89 | char *AMF_EncodeInt24(char *output, char *outend, int nVal); 90 | char *AMF_EncodeInt32(char *output, char *outend, int nVal); 91 | char *AMF_EncodeBoolean(char *output, char *outend, int bVal); 92 | 93 | /* Shortcuts for AMFProp_Encode */ 94 | char *AMF_EncodeNamedString(char *output, char *outend, const AVal * name, const AVal * value); 95 | char *AMF_EncodeNamedNumber(char *output, char *outend, const AVal * name, double dVal); 96 | char *AMF_EncodeNamedBoolean(char *output, char *outend, const AVal * name, int bVal); 97 | 98 | unsigned short AMF_DecodeInt16(const char *data); 99 | unsigned int AMF_DecodeInt24(const char *data); 100 | unsigned int AMF_DecodeInt32(const char *data); 101 | void AMF_DecodeString(const char *data, AVal * str); 102 | void AMF_DecodeLongString(const char *data, AVal * str); 103 | int AMF_DecodeBoolean(const char *data); 104 | double AMF_DecodeNumber(const char *data); 105 | 106 | char *AMF_Encode(AMFObject * obj, char *pBuffer, char *pBufEnd); 107 | int AMF_Decode(AMFObject * obj, const char *pBuffer, int nSize, 108 | int bDecodeName); 109 | int AMF_DecodeArray(AMFObject * obj, const char *pBuffer, int nSize, 110 | int nArrayLen, int bDecodeName); 111 | int AMF3_Decode(AMFObject * obj, const char *pBuffer, int nSize, 112 | int bDecodeName); 113 | void AMF_Dump(AMFObject * obj); 114 | void AMF_Reset(AMFObject * obj); 115 | 116 | void AMF_AddProp(AMFObject * obj, const AMFObjectProperty * prop); 117 | int AMF_CountProp(AMFObject * obj); 118 | AMFObjectProperty *AMF_GetProp(AMFObject * obj, const AVal * name, 119 | int nIndex); 120 | 121 | AMFDataType AMFProp_GetType(AMFObjectProperty * prop); 122 | void AMFProp_SetNumber(AMFObjectProperty * prop, double dval); 123 | void AMFProp_SetBoolean(AMFObjectProperty * prop, int bflag); 124 | void AMFProp_SetString(AMFObjectProperty * prop, AVal * str); 125 | void AMFProp_SetObject(AMFObjectProperty * prop, AMFObject * obj); 126 | 127 | void AMFProp_GetName(AMFObjectProperty * prop, AVal * name); 128 | void AMFProp_SetName(AMFObjectProperty * prop, AVal * name); 129 | double AMFProp_GetNumber(AMFObjectProperty * prop); 130 | int AMFProp_GetBoolean(AMFObjectProperty * prop); 131 | void AMFProp_GetString(AMFObjectProperty * prop, AVal * str); 132 | void AMFProp_GetObject(AMFObjectProperty * prop, AMFObject * obj); 133 | 134 | int AMFProp_IsValid(AMFObjectProperty * prop); 135 | 136 | char *AMFProp_Encode(AMFObjectProperty * prop, char *pBuffer, char *pBufEnd); 137 | int AMF3Prop_Decode(AMFObjectProperty * prop, const char *pBuffer, 138 | int nSize, int bDecodeName); 139 | int AMFProp_Decode(AMFObjectProperty * prop, const char *pBuffer, 140 | int nSize, int bDecodeName); 141 | 142 | void AMFProp_Dump(AMFObjectProperty * prop); 143 | void AMFProp_Reset(AMFObjectProperty * prop); 144 | 145 | typedef struct AMF3ClassDef 146 | { 147 | AVal cd_name; 148 | char cd_externalizable; 149 | char cd_dynamic; 150 | int cd_num; 151 | AVal *cd_props; 152 | } AMF3ClassDef; 153 | 154 | void AMF3CD_AddProp(AMF3ClassDef * cd, AVal * prop); 155 | AVal *AMF3CD_GetProp(AMF3ClassDef * cd, int idx); 156 | 157 | #ifdef __cplusplus 158 | } 159 | #endif 160 | 161 | #endif /* __AMF_H__ */ 162 | -------------------------------------------------------------------------------- /librtmp/parseurl.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 Andrej Stepanchuk 3 | * Copyright (C) 2009-2010 Howard Chu 4 | * 5 | * This file is part of librtmp. 6 | * 7 | * librtmp is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as 9 | * published by the Free Software Foundation; either version 2.1, 10 | * or (at your option) any later version. 11 | * 12 | * librtmp is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with librtmp see the file COPYING. If not, write to 19 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 20 | * Boston, MA 02110-1301, USA. 21 | * http://www.gnu.org/copyleft/lgpl.html 22 | */ 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | 30 | #include "rtmp_sys.h" 31 | #include "log.h" 32 | 33 | int RTMP_ParseURL(const char *url, int *protocol, AVal *host, unsigned int *port, 34 | AVal *playpath, AVal *app) 35 | { 36 | char *p, *end, *col, *ques, *slash; 37 | 38 | RTMP_Log(RTMP_LOGDEBUG, "Parsing..."); 39 | 40 | *protocol = RTMP_PROTOCOL_RTMP; 41 | *port = 0; 42 | playpath->av_len = 0; 43 | playpath->av_val = NULL; 44 | app->av_len = 0; 45 | app->av_val = NULL; 46 | 47 | /* Old School Parsing */ 48 | 49 | /* look for usual :// pattern */ 50 | p = strstr(url, "://"); 51 | if(!p) { 52 | RTMP_Log(RTMP_LOGERROR, "RTMP URL: No :// in url!"); 53 | return FALSE; 54 | } 55 | { 56 | int len = (int)(p-url); 57 | 58 | if(len == 4 && strncasecmp(url, "rtmp", 4)==0) 59 | *protocol = RTMP_PROTOCOL_RTMP; 60 | else if(len == 5 && strncasecmp(url, "rtmpt", 5)==0) 61 | *protocol = RTMP_PROTOCOL_RTMPT; 62 | else if(len == 5 && strncasecmp(url, "rtmps", 5)==0) 63 | *protocol = RTMP_PROTOCOL_RTMPS; 64 | else if(len == 5 && strncasecmp(url, "rtmpe", 5)==0) 65 | *protocol = RTMP_PROTOCOL_RTMPE; 66 | else if(len == 5 && strncasecmp(url, "rtmfp", 5)==0) 67 | *protocol = RTMP_PROTOCOL_RTMFP; 68 | else if(len == 6 && strncasecmp(url, "rtmpte", 6)==0) 69 | *protocol = RTMP_PROTOCOL_RTMPTE; 70 | else if(len == 6 && strncasecmp(url, "rtmpts", 6)==0) 71 | *protocol = RTMP_PROTOCOL_RTMPTS; 72 | else { 73 | RTMP_Log(RTMP_LOGWARNING, "Unknown protocol!\n"); 74 | goto parsehost; 75 | } 76 | } 77 | 78 | RTMP_Log(RTMP_LOGDEBUG, "Parsed protocol: %d", *protocol); 79 | 80 | parsehost: 81 | /* let's get the hostname */ 82 | p+=3; 83 | 84 | /* check for sudden death */ 85 | if(*p==0) { 86 | RTMP_Log(RTMP_LOGWARNING, "No hostname in URL!"); 87 | return FALSE; 88 | } 89 | 90 | end = p + strlen(p); 91 | col = strchr(p, ':'); 92 | ques = strchr(p, '?'); 93 | slash = strchr(p, '/'); 94 | 95 | { 96 | int hostlen; 97 | if(slash) 98 | hostlen = slash - p; 99 | else 100 | hostlen = end - p; 101 | if(col && col -p < hostlen) 102 | hostlen = col - p; 103 | 104 | if(hostlen < 256) { 105 | host->av_val = p; 106 | host->av_len = hostlen; 107 | RTMP_Log(RTMP_LOGDEBUG, "Parsed host : %.*s", hostlen, host->av_val); 108 | } else { 109 | RTMP_Log(RTMP_LOGWARNING, "Hostname exceeds 255 characters!"); 110 | } 111 | 112 | p+=hostlen; 113 | } 114 | 115 | /* get the port number if available */ 116 | if(*p == ':') { 117 | unsigned int p2; 118 | p++; 119 | p2 = atoi(p); 120 | if(p2 > 65535) { 121 | RTMP_Log(RTMP_LOGWARNING, "Invalid port number!"); 122 | } else { 123 | *port = p2; 124 | } 125 | } 126 | 127 | if(!slash) { 128 | RTMP_Log(RTMP_LOGWARNING, "No application or playpath in URL!"); 129 | return TRUE; 130 | } 131 | p = slash+1; 132 | 133 | { 134 | /* parse application 135 | * 136 | * rtmp://host[:port]/app[/appinstance][/...] 137 | * application = app[/appinstance] 138 | */ 139 | 140 | char *slash2, *slash3 = NULL; 141 | int applen, appnamelen; 142 | 143 | slash2 = strchr(p, '/'); 144 | if(slash2) 145 | slash3 = strchr(slash2+1, '/'); 146 | 147 | applen = end-p; /* ondemand, pass all parameters as app */ 148 | appnamelen = applen; /* ondemand length */ 149 | 150 | if(ques && strstr(p, "slist=")) { /* whatever it is, the '?' and slist= means we need to use everything as app and parse plapath from slist= */ 151 | appnamelen = ques-p; 152 | } 153 | else if(strncmp(p, "ondemand/", 9)==0) { 154 | /* app = ondemand/foobar, only pass app=ondemand */ 155 | applen = 8; 156 | appnamelen = 8; 157 | } 158 | else { /* app!=ondemand, so app is app[/appinstance] */ 159 | if(slash3) 160 | appnamelen = slash3-p; 161 | else if(slash2) 162 | appnamelen = slash2-p; 163 | 164 | applen = appnamelen; 165 | } 166 | 167 | app->av_val = p; 168 | app->av_len = applen; 169 | RTMP_Log(RTMP_LOGDEBUG, "Parsed app : %.*s", applen, p); 170 | 171 | p += appnamelen; 172 | } 173 | 174 | if (*p == '/') 175 | p++; 176 | 177 | if (end-p) { 178 | AVal av = {p, end-p}; 179 | RTMP_ParsePlaypath(&av, playpath); 180 | } 181 | 182 | return TRUE; 183 | } 184 | 185 | /* 186 | * Extracts playpath from RTMP URL. playpath is the file part of the 187 | * URL, i.e. the part that comes after rtmp://host:port/app/ 188 | * 189 | * Returns the stream name in a format understood by FMS. The name is 190 | * the playpath part of the URL with formatting depending on the stream 191 | * type: 192 | * 193 | * mp4 streams: prepend "mp4:", remove extension 194 | * mp3 streams: prepend "mp3:", remove extension 195 | * flv streams: remove extension 196 | */ 197 | void RTMP_ParsePlaypath(AVal *in, AVal *out) { 198 | int addMP4 = 0; 199 | int addMP3 = 0; 200 | int subExt = 0; 201 | const char *playpath = in->av_val; 202 | const char *temp, *q, *ext = NULL; 203 | const char *ppstart = playpath; 204 | char *streamname, *destptr, *p; 205 | 206 | int pplen = in->av_len; 207 | 208 | out->av_val = NULL; 209 | out->av_len = 0; 210 | 211 | if ((*ppstart == '?') && 212 | (temp=strstr(ppstart, "slist=")) != 0) { 213 | ppstart = temp+6; 214 | pplen = strlen(ppstart); 215 | 216 | temp = strchr(ppstart, '&'); 217 | if (temp) { 218 | pplen = temp-ppstart; 219 | } 220 | } 221 | 222 | q = strchr(ppstart, '?'); 223 | if (pplen >= 4) { 224 | if (q) 225 | ext = q-4; 226 | else 227 | ext = &ppstart[pplen-4]; 228 | if ((strncmp(ext, ".f4v", 4) == 0) || 229 | (strncmp(ext, ".mp4", 4) == 0)) { 230 | addMP4 = 1; 231 | subExt = 1; 232 | /* Only remove .flv from rtmp URL, not slist params */ 233 | } else if ((ppstart == playpath) && 234 | (strncmp(ext, ".flv", 4) == 0)) { 235 | subExt = 1; 236 | } else if (strncmp(ext, ".mp3", 4) == 0) { 237 | addMP3 = 1; 238 | subExt = 1; 239 | } 240 | } 241 | 242 | streamname = (char *)malloc((pplen+4+1)*sizeof(char)); 243 | if (!streamname) 244 | return; 245 | 246 | destptr = streamname; 247 | if (addMP4) { 248 | if (strncmp(ppstart, "mp4:", 4)) { 249 | strcpy(destptr, "mp4:"); 250 | destptr += 4; 251 | } else { 252 | subExt = 0; 253 | } 254 | } else if (addMP3) { 255 | if (strncmp(ppstart, "mp3:", 4)) { 256 | strcpy(destptr, "mp3:"); 257 | destptr += 4; 258 | } else { 259 | subExt = 0; 260 | } 261 | } 262 | 263 | for (p=(char *)ppstart; pplen >0;) { 264 | /* skip extension */ 265 | if (subExt && p == ext) { 266 | p += 4; 267 | pplen -= 4; 268 | continue; 269 | } 270 | if (*p == '%') { 271 | unsigned int c; 272 | sscanf(p+1, "%02x", &c); 273 | *destptr++ = c; 274 | pplen -= 3; 275 | p += 3; 276 | } else { 277 | *destptr++ = *p++; 278 | pplen--; 279 | } 280 | } 281 | *destptr = '\0'; 282 | 283 | out->av_val = streamname; 284 | out->av_len = destptr - streamname; 285 | } 286 | -------------------------------------------------------------------------------- /librtmp/librtmp.3: -------------------------------------------------------------------------------- 1 | .TH LIBRTMP 3 "2011-07-20" "RTMPDump v2.4" 2 | .\" Copyright 2011 Howard Chu. 3 | .\" Copying permitted according to the GNU General Public License V2. 4 | .SH NAME 5 | librtmp \- RTMPDump Real-Time Messaging Protocol API 6 | .SH LIBRARY 7 | RTMPDump RTMP (librtmp, -lrtmp) 8 | .SH SYNOPSIS 9 | .B #include 10 | .SH DESCRIPTION 11 | The Real-Time Messaging Protocol (RTMP) is used for streaming 12 | multimedia content across a TCP/IP network. This API provides most client 13 | functions and a few server functions needed to support RTMP, RTMP tunneled 14 | in HTTP (RTMPT), encrypted RTMP (RTMPE), RTMP over SSL/TLS (RTMPS) and 15 | tunneled variants of these encrypted types (RTMPTE, RTMPTS). The basic 16 | RTMP specification has been published by Adobe but this API was 17 | reverse-engineered without use of the Adobe specification. As such, it may 18 | deviate from any published specifications but it usually duplicates the 19 | actual behavior of the original Adobe clients. 20 | 21 | The RTMPDump software package includes a basic client utility program 22 | in 23 | .BR rtmpdump (1), 24 | some sample servers, and a library used to provide programmatic access 25 | to the RTMP protocol. This man page gives an overview of the RTMP 26 | library routines. These routines are found in the -lrtmp library. Many 27 | other routines are also available, but they are not documented yet. 28 | 29 | The basic interaction is as follows. A session handle is created using 30 | .BR RTMP_Alloc () 31 | and initialized using 32 | .BR RTMP_Init (). 33 | All session parameters are provided using 34 | .BR RTMP_SetupURL (). 35 | The network connection is established using 36 | .BR RTMP_Connect (), 37 | and then the RTMP session is established using 38 | .BR RTMP_ConnectStream (). 39 | The stream is read using 40 | .BR RTMP_Read (). 41 | A client can publish a stream by calling 42 | .BR RTMP_EnableWrite () 43 | before the 44 | .BR RTMP_Connect () 45 | call, and then using 46 | .BR RTMP_Write () 47 | after the session is established. 48 | While a stream is playing it may be paused and unpaused using 49 | .BR RTMP_Pause (). 50 | The stream playback position can be moved using 51 | .BR RTMP_Seek (). 52 | When 53 | .BR RTMP_Read () 54 | returns 0 bytes, the stream is complete and may be closed using 55 | .BR RTMP_Close (). 56 | The session handle is freed using 57 | .BR RTMP_Free (). 58 | 59 | All data is transferred using FLV format. The basic session requires 60 | an RTMP URL. The RTMP URL format is of the form 61 | .nf 62 | rtmp[t][e|s]://hostname[:port][/app[/playpath]] 63 | .fi 64 | 65 | Plain rtmp, as well as tunneled and encrypted sessions are supported. 66 | 67 | Additional options may be specified by appending space-separated 68 | key=value pairs to the URL. Special characters in values may need 69 | to be escaped to prevent misinterpretation by the option parser. 70 | The escape encoding uses a backslash followed by two hexadecimal digits 71 | representing the ASCII value of the character. E.g., spaces must 72 | be escaped as \fB\\20\fP and backslashes must be escaped as \fB\\5c\fP. 73 | .SH OPTIONS 74 | .SS "Network Parameters" 75 | These options define how to connect to the media server. 76 | .TP 77 | .BI socks= host:port 78 | Use the specified SOCKS4 proxy. 79 | .SS "Connection Parameters" 80 | These options define the content of the RTMP Connect request packet. 81 | If correct values are not provided, the media server will reject the 82 | connection attempt. 83 | .TP 84 | .BI app= name 85 | Name of application to connect to on the RTMP server. Overrides 86 | the app in the RTMP URL. Sometimes the librtmp URL parser cannot 87 | determine the app name automatically, so it must be given explicitly 88 | using this option. 89 | .TP 90 | .BI tcUrl= url 91 | URL of the target stream. Defaults to rtmp[t][e|s]://host[:port]/app. 92 | .TP 93 | .BI pageUrl= url 94 | URL of the web page in which the media was embedded. By default no 95 | value will be sent. 96 | .TP 97 | .BI swfUrl= url 98 | URL of the SWF player for the media. By default no value will be sent. 99 | .TP 100 | .BI flashVer= version 101 | Version of the Flash plugin used to run the SWF player. The 102 | default is "LNX 10,0,32,18". 103 | .TP 104 | .BI conn= type:data 105 | Append arbitrary AMF data to the Connect message. The type 106 | must be B for Boolean, N for number, S for string, O for object, or Z 107 | for null. For Booleans the data must be either 0 or 1 for FALSE or TRUE, 108 | respectively. Likewise for Objects the data must be 0 or 1 to end or 109 | begin an object, respectively. Data items in subobjects may be named, by 110 | prefixing the type with 'N' and specifying the name before the value, e.g. 111 | NB:myFlag:1. This option may be used multiple times to construct arbitrary 112 | AMF sequences. E.g. 113 | .nf 114 | conn=B:1 conn=S:authMe conn=O:1 conn=NN:code:1.23 conn=NS:flag:ok conn=O:0 115 | .fi 116 | .SS "Session Parameters" 117 | These options take effect after the Connect request has succeeded. 118 | .TP 119 | .BI playpath= path 120 | Overrides the playpath parsed from the RTMP URL. Sometimes the 121 | rtmpdump URL parser cannot determine the correct playpath 122 | automatically, so it must be given explicitly using this option. 123 | .TP 124 | .BI playlist= 0|1 125 | If the value is 1 or TRUE, issue a set_playlist command before sending the 126 | play command. The playlist will just contain the current playpath. If the 127 | value is 0 or FALSE, the set_playlist command will not be sent. The 128 | default is FALSE. 129 | .TP 130 | .BI live= 0|1 131 | Specify that the media is a live stream. No resuming or seeking in 132 | live streams is possible. 133 | .TP 134 | .BI subscribe= path 135 | Name of live stream to subscribe to. Defaults to 136 | .IR playpath . 137 | .TP 138 | .BI start= num 139 | Start at 140 | .I num 141 | seconds into the stream. Not valid for live streams. 142 | .TP 143 | .BI stop= num 144 | Stop at 145 | .I num 146 | seconds into the stream. 147 | .TP 148 | .BI buffer= num 149 | Set buffer time to 150 | .I num 151 | milliseconds. The default is 30000. 152 | .TP 153 | .BI timeout= num 154 | Timeout the session after 155 | .I num 156 | seconds without receiving any data from the server. The default is 120. 157 | .SS "Security Parameters" 158 | These options handle additional authentication requests from the server. 159 | .TP 160 | .BI token= key 161 | Key for SecureToken response, used if the server requires SecureToken 162 | authentication. 163 | .TP 164 | .BI jtv= JSON 165 | JSON token used by legacy Justin.tv servers. Invokes NetStream.Authenticate.UsherToken 166 | .TP 167 | .BI swfVfy= 0|1 168 | If the value is 1 or TRUE, the SWF player is retrieved from the 169 | specified 170 | .I swfUrl 171 | for performing SWF Verification. The SWF hash and size (used in the 172 | verification step) are computed automatically. Also the SWF information is 173 | cached in a 174 | .I .swfinfo 175 | file in the user's home directory, so that it doesn't need to be retrieved 176 | and recalculated every time. The .swfinfo file records 177 | the SWF URL, the time it was fetched, the modification timestamp of the SWF 178 | file, its size, and its hash. By default, the cached info will be used 179 | for 30 days before re-checking. 180 | .TP 181 | .BI swfAge= days 182 | Specify how many days to use the cached SWF info before re-checking. Use 183 | 0 to always check the SWF URL. Note that if the check shows that the 184 | SWF file has the same modification timestamp as before, it will not be 185 | retrieved again. 186 | .SH EXAMPLES 187 | An example character string suitable for use with 188 | .BR RTMP_SetupURL (): 189 | .nf 190 | "rtmp://flashserver:1935/ondemand/thefile swfUrl=http://flashserver/player.swf swfVfy=1" 191 | .fi 192 | .SH ENVIRONMENT 193 | .TP 194 | .B HOME 195 | The value of 196 | .RB $ HOME 197 | is used as the location for the 198 | .I .swfinfo 199 | file. 200 | .SH FILES 201 | .TP 202 | .I $HOME/.swfinfo 203 | Cache of SWF Verification information 204 | .SH "SEE ALSO" 205 | .BR rtmpdump (1), 206 | .BR rtmpgw (8) 207 | .SH AUTHORS 208 | Andrej Stepanchuk, Howard Chu, The Flvstreamer Team 209 | .br 210 | 211 | -------------------------------------------------------------------------------- /rtmpgw.8: -------------------------------------------------------------------------------- 1 | .TH RTMPGW 8 "2011-07-20" "RTMPDump v2.4" 2 | .\" Copyright 2011 Howard Chu. 3 | .\" Copying permitted according to the GNU General Public License V2. 4 | .SH NAME 5 | rtmpgw \- RTMP streaming media gateway 6 | .SH SYNOPSIS 7 | .B rtmpgw 8 | [\c 9 | .BI \-r \ url\fR] 10 | [\c 11 | .BI \-n \ hostname\fR] 12 | [\c 13 | .BI \-c \ port\fR] 14 | [\c 15 | .BI \-l \ protocol\fR] 16 | [\c 17 | .BI \-S \ host:port\fR] 18 | [\c 19 | .BI \-a \ app\fR] 20 | [\c 21 | .BI \-t \ tcUrl\fR] 22 | [\c 23 | .BI \-p \ pageUrl\fR] 24 | [\c 25 | .BI \-s \ swfUrl\fR] 26 | [\c 27 | .BI \-f \ flashVer\fR] 28 | [\c 29 | .BI \-u \ auth\fR] 30 | [\c 31 | .BI \-C \ conndata\fR] 32 | [\c 33 | .BI \-y \ playpath\fR] 34 | [\c 35 | .BR \-v ] 36 | [\c 37 | .BI \-d \ subscription\fR] 38 | [\c 39 | .BR \-e ] 40 | [\c 41 | .BI \-k \ skip\fR] 42 | [\c 43 | .BI \-A \ start\fR] 44 | [\c 45 | .BI \-B \ stop\fR] 46 | [\c 47 | .BI \-b \ buffer\fR] 48 | [\c 49 | .BI \-m \ timeout\fR] 50 | [\c 51 | .BI \-T \ key\fR] 52 | [\c 53 | .BI \-j \ JSON\fR] 54 | [\c 55 | .BI \-w \ swfHash\fR] 56 | [\c 57 | .BI \-x \ swfSize\fR] 58 | [\c 59 | .BI \-W \ swfUrl\fR] 60 | [\c 61 | .BI \-X \ swfAge\fR] 62 | [\c 63 | .BI \-D \ address\fR] 64 | [\c 65 | .BI \-g \ port\fR] 66 | [\c 67 | .BR \-q ] 68 | [\c 69 | .BR \-V ] 70 | [\c 71 | .BR \-z ] 72 | .br 73 | .B rtmpgw \-h 74 | .SH DESCRIPTION 75 | .B rtmpgw 76 | is a server for streaming media content from RTMP out to HTTP. 77 | .LP 78 | .B rtmpgw 79 | listens for HTTP requests that specify RTMP stream parameters and 80 | then returns the RTMP data in the HTTP response. The only valid 81 | HTTP request is "GET /" but additional options can be provided 82 | in URL-encoded fashion. Options specified on the command line will 83 | be used as defaults, which can be overridden by options in the HTTP 84 | request. 85 | .SH OPTIONS 86 | .SS "Network Parameters" 87 | These options define how to connect to the media server. 88 | .TP 89 | \fB\-\-rtmp \-r\fP\ \fIurl\fP 90 | URL of the server and media content. 91 | .TP 92 | \fB\-\-host \-n\fP\ \fIhostname\fP 93 | Overrides the hostname in the RTMP URL. 94 | .TP 95 | \fB\-\-port \-c\fP\ \fIport\fP 96 | Overrides the port number in the RTMP URL. 97 | .TP 98 | \fB\-\-protocol \-l\fP\ \fInumber\fP 99 | Overrides the protocol in the RTMP URL. 100 | .nf 101 | 0 = rtmp 102 | 1 = rtmpt 103 | 2 = rtmpe 104 | 3 = rtmpte 105 | 4 = rtmps 106 | 5 = rtmpts 107 | .fi 108 | .TP 109 | \fB\-\-socks \-S\fP\ \fIhost:port\fP 110 | Use the specified SOCKS4 proxy. 111 | .SS "Connection Parameters" 112 | These options define the content of the RTMP Connect request packet. 113 | If correct values are not provided, the media server will reject the 114 | connection attempt. 115 | .TP 116 | \fB\-\-app \-a\fP\ \fIapp\fP 117 | Name of application to connect to on the RTMP server. Overrides 118 | the app in the RTMP URL. Sometimes the rtmpdump URL parser cannot 119 | determine the app name automatically, so it must be given explicitly 120 | using this option. 121 | .TP 122 | \fB\-\-tcUrl \-t\fP\ \fIurl\fP 123 | URL of the target stream. Defaults to rtmp[e]://host[:port]/app/playpath. 124 | .TP 125 | \fB\-\-pageUrl \-p\fP\ \fIurl\fP 126 | URL of the web page in which the media was embedded. By default no 127 | value will be sent. 128 | .TP 129 | \fB\-\-swfUrl \-s\fP\ \fIurl\fP 130 | URL of the SWF player for the media. By default no value will be sent. 131 | .TP 132 | \fB\-\-flashVer \-f\fP\ \fIversion\fP 133 | Version of the Flash plugin used to run the SWF player. The 134 | default is "LNX 10,0,32,18". 135 | .TP 136 | \fB\-\-auth \-u\fP\ \fIstring\fP 137 | An authentication string to be appended to the Connect message. Using 138 | this option will append a Boolean TRUE and then the specified string. 139 | This option is only used by some particular servers and is 140 | deprecated. The more general 141 | .B \-\-conn 142 | option should be used instead. 143 | .TP 144 | \fB\-\-conn \-C\fP\ \fItype:data\fP 145 | Append arbitrary AMF data to the Connect message. The type 146 | must be B for Boolean, N for number, S for string, O for object, or Z 147 | for null. For Booleans the data must be either 0 or 1 for FALSE or TRUE, 148 | respectively. Likewise for Objects the data must be 0 or 1 to end or 149 | begin an object, respectively. Data items in subobjects may be named, by 150 | prefixing the type with 'N' and specifying the name before the value, e.g. 151 | NB:myFlag:1. This option may be used multiple times to construct arbitrary 152 | AMF sequences. E.g. 153 | .nf 154 | \-C B:1 \-C S:authMe \-C O:1 \-C NN:code:1.23 \-C NS:flag:ok \-C O:0 155 | .fi 156 | .SS "Session Parameters" 157 | These options take effect after the Connect request has succeeded. 158 | .TP 159 | \fB\-\-playpath \-y\fP\ \fIpath\fP 160 | Overrides the playpath parsed from the RTMP URL. Sometimes the 161 | rtmpdump URL parser cannot determine the correct playpath 162 | automatically, so it must be given explicitly using this option. 163 | .TP 164 | .B \-\-live \-v 165 | Specify that the media is a live stream. No resuming or seeking in 166 | live streams is possible. 167 | .TP 168 | \fB\-\-subscribe \-d\fP\ \fIstream\fP 169 | Name of live stream to subscribe to. Defaults to 170 | .IR playpath . 171 | .TP 172 | \fB\-\-start \-A\fP\ \fInum\fP 173 | Start at 174 | .I num 175 | seconds into the stream. Not valid for live streams. 176 | .TP 177 | \fB\-\-stop \-B\fP\ \fInum\fP 178 | Stop at 179 | .I num 180 | seconds into the stream. 181 | .TP 182 | \fB\-\-buffer \-b\fP\ \fInum\fP 183 | Set buffer time to 184 | .I num 185 | milliseconds. The default is 20000. 186 | .TP 187 | \fB\-\-timeout \-m\fP\ \fInum\fP 188 | Timeout the session after 189 | .I num 190 | seconds without receiving any data from the server. The default is 120. 191 | .SS "Security Parameters" 192 | These options handle additional authentication requests from the server. 193 | .TP 194 | \fB\-\-token \-T\fP\ \fIkey\fP 195 | Key for SecureToken response, used if the server requires SecureToken 196 | authentication. 197 | .TP 198 | \fB\-\-jtv \-j\fP\ \fIJSON\fP 199 | JSON token used by legacy Justin.tv servers. Invokes NetStream.Authenticate.UsherToken 200 | .TP 201 | \fB\-\-swfhash \-w\fP\ \fIhexstring\fP 202 | SHA256 hash of the decompressed SWF file. This option may be needed if 203 | the server uses SWF Verification, but see the 204 | .B \-\-swfVfy 205 | option below. The hash is 32 bytes, and must be 206 | given in hexadecimal. The 207 | .B \-\-swfsize 208 | option must always be used with this option. 209 | .TP 210 | \fB\-\-swfsize \-x\fP\ \fInum\fP 211 | Size of the decompressed SWF file. This option may be needed if the 212 | server uses SWF Verification, but see the 213 | .B \-\-swfVfy 214 | option below. The 215 | .B \-\-swfhash 216 | option must always be used with this option. 217 | .TP 218 | \fB\-\-swfVfy \-W\fP\ \fIurl\fP 219 | URL of the SWF player for this media. This option replaces all three 220 | of the 221 | .BR \-\-swfUrl , 222 | .BR \-\-swfhash , 223 | and 224 | .B \-\-swfsize 225 | options. When this option is used, the SWF player is retrieved from the 226 | specified URL and the hash and size are computed automatically. Also 227 | the information is cached in a 228 | .I .swfinfo 229 | file in the user's home directory, so that it doesn't need to be retrieved 230 | and recalculated every time rtmpdump is run. The .swfinfo file records 231 | the URL, the time it was fetched, the modification timestamp of the SWF 232 | file, its size, and its hash. By default, the cached info will be used 233 | for 30 days before re-checking. 234 | .TP 235 | \fB\-\-swfAge \-X\fP\ \fIdays\fP 236 | Specify how many days to use the cached SWF info before re-checking. Use 237 | 0 to always check the SWF URL. Note that if the check shows that the 238 | SWF file has the same modification timestamp as before, it will not be 239 | retrieved again. 240 | .SS Miscellaneous 241 | .TP 242 | \fB\-\-device \-D\fP\ \fIaddress\fP 243 | Listener IP address. The default is 0.0.0.0, i.e., any IP address. 244 | .TP 245 | \fB\-\-sport \-g\fP\ \fIport\fP 246 | Listener port. The default is 80. 247 | .TP 248 | .B \-\-quiet \-q 249 | Suppress all command output. 250 | .TP 251 | .B \-\-verbose \-V 252 | Verbose command output. 253 | .TP 254 | .B \-\-debug \-z 255 | Debug level output. Extremely verbose, including hex dumps of all packet data. 256 | .TP 257 | .B \-\-help \-h 258 | Print a summary of command options. 259 | .SH EXAMPLES 260 | The HTTP request 261 | .nf 262 | GET /?r=rtmp:%2f%2fserver%2fmyapp&y=somefile HTTP/1.0 263 | .fi 264 | is equivalent to the 265 | .BR rtrmpdump (1) 266 | invocation 267 | .nf 268 | rtmpdump \-r rtmp://server/myapp \-y somefile 269 | .fi 270 | 271 | Note that only the shortform (single letter) options are supported. 272 | .SH ENVIRONMENT 273 | .TP 274 | .B HOME 275 | The value of 276 | .RB $ HOME 277 | is used as the location for the 278 | .I .swfinfo 279 | file. 280 | .SH FILES 281 | .TP 282 | .I $HOME/.swfinfo 283 | Cache of SWF Verification information 284 | .SH "SEE ALSO" 285 | .BR rtmpdump (1) 286 | .SH AUTHORS 287 | Andrej Stepanchuk, Howard Chu, The Flvstreamer Team 288 | .br 289 | 290 | -------------------------------------------------------------------------------- /rtmpdump.1: -------------------------------------------------------------------------------- 1 | .TH RTMPDUMP 1 "2011-07-20" "RTMPDump v2.4" 2 | .\" Copyright 2011 Howard Chu. 3 | .\" Copying permitted according to the GNU General Public License V2. 4 | .SH NAME 5 | rtmpdump \- RTMP streaming media client 6 | .SH SYNOPSIS 7 | .B rtmpdump 8 | .BI \-r \ url 9 | [\c 10 | .BI \-n \ hostname\fR] 11 | [\c 12 | .BI \-c \ port\fR] 13 | [\c 14 | .BI \-l \ protocol\fR] 15 | [\c 16 | .BI \-S \ host:port\fR] 17 | [\c 18 | .BI \-a \ app\fR] 19 | [\c 20 | .BI \-t \ tcUrl\fR] 21 | [\c 22 | .BI \-p \ pageUrl\fR] 23 | [\c 24 | .BI \-s \ swfUrl\fR] 25 | [\c 26 | .BI \-f \ flashVer\fR] 27 | [\c 28 | .BI \-u \ auth\fR] 29 | [\c 30 | .BI \-C \ conndata\fR] 31 | [\c 32 | .BI \-y \ playpath\fR] 33 | [\c 34 | .BR \-Y ] 35 | [\c 36 | .BR \-v ] 37 | [\c 38 | .BI \-d \ subscription\fR] 39 | [\c 40 | .BR \-e ] 41 | [\c 42 | .BI \-k \ skip\fR] 43 | [\c 44 | .BI \-A \ start\fR] 45 | [\c 46 | .BI \-B \ stop\fR] 47 | [\c 48 | .BI \-b \ buffer\fR] 49 | [\c 50 | .BI \-m \ timeout\fR] 51 | [\c 52 | .BI \-T \ key\fR] 53 | [\c 54 | .BI \-j \ JSON\fR] 55 | [\c 56 | .BI \-w \ swfHash\fR] 57 | [\c 58 | .BI \-x \ swfSize\fR] 59 | [\c 60 | .BI \-W \ swfUrl\fR] 61 | [\c 62 | .BI \-X \ swfAge\fR] 63 | [\c 64 | .BI \-o \ output\fR] 65 | [\c 66 | .BR \-# ] 67 | [\c 68 | .BR \-q ] 69 | [\c 70 | .BR \-V ] 71 | [\c 72 | .BR \-z ] 73 | .br 74 | .B rtmpdump \-h 75 | .SH DESCRIPTION 76 | .B rtmpdump 77 | is a tool for dumping media content streamed over RTMP. 78 | .LP 79 | .B rtmpdump 80 | makes a connection to the specified RTMP server and plays the media 81 | specified by the given 82 | .IR url . 83 | The url should be of the form 84 | .nf 85 | rtmp[t][e]://hostname[:port][/app[/playpath]] 86 | .fi 87 | 88 | Plain rtmp, as well as tunneled and encrypted sessions are supported. 89 | .SH OPTIONS 90 | .SS "Network Parameters" 91 | These options define how to connect to the media server. 92 | .TP 93 | \fB\-\-rtmp \-r\fP\ \fIurl\fP 94 | URL of the server and media content. 95 | .TP 96 | \fB\-\-host \-n\fP\ \fIhostname\fP 97 | Overrides the hostname in the RTMP URL. 98 | .TP 99 | \fB\-\-port \-c\fP\ \fIport\fP 100 | Overrides the port number in the RTMP URL. 101 | .TP 102 | \fB\-\-protocol \-l\fP\ \fInumber\fP 103 | Overrides the protocol in the RTMP URL. 104 | .nf 105 | 0 = rtmp 106 | 1 = rtmpt 107 | 2 = rtmpe 108 | 3 = rtmpte 109 | 4 = rtmps 110 | 5 = rtmpts 111 | .fi 112 | .TP 113 | \fB\-\-socks \-S\fP\ \fIhost:port\fP 114 | Use the specified SOCKS4 proxy. 115 | .SS "Connection Parameters" 116 | These options define the content of the RTMP Connect request packet. 117 | If correct values are not provided, the media server will reject the 118 | connection attempt. 119 | .TP 120 | \fB\-\-app \-a\fP\ \fIapp\fP 121 | Name of application to connect to on the RTMP server. Overrides 122 | the app in the RTMP URL. Sometimes the rtmpdump URL parser cannot 123 | determine the app name automatically, so it must be given explicitly 124 | using this option. 125 | .TP 126 | \fB\-\-tcUrl \-t\fP\ \fIurl\fP 127 | URL of the target stream. Defaults to rtmp[e]://host[:port]/app/playpath. 128 | .TP 129 | \fB\-\-pageUrl \-p\fP\ \fIurl\fP 130 | URL of the web page in which the media was embedded. By default no 131 | value will be sent. 132 | .TP 133 | \fB\-\-swfUrl \-s\fP\ \fIurl\fP 134 | URL of the SWF player for the media. By default no value will be sent. 135 | .TP 136 | \fB\-\-flashVer \-f\fP\ \fIversion\fP 137 | Version of the Flash plugin used to run the SWF player. The 138 | default is "LNX 10,0,32,18". 139 | .TP 140 | \fB\-\-auth \-u\fP\ \fIstring\fP 141 | An authentication string to be appended to the Connect message. Using 142 | this option will append a Boolean TRUE and then the specified string. 143 | This option is only used by some particular servers and is 144 | deprecated. The more general 145 | .B \-\-conn 146 | option should be used instead. 147 | .TP 148 | \fB\-\-conn \-C\fP\ \fItype:data\fP 149 | Append arbitrary AMF data to the Connect message. The type 150 | must be B for Boolean, N for number, S for string, O for object, or Z 151 | for null. For Booleans the data must be either 0 or 1 for FALSE or TRUE, 152 | respectively. Likewise for Objects the data must be 0 or 1 to end or 153 | begin an object, respectively. Data items in subobjects may be named, by 154 | prefixing the type with 'N' and specifying the name before the value, e.g. 155 | NB:myFlag:1. This option may be used multiple times to construct arbitrary 156 | AMF sequences. E.g. 157 | .nf 158 | \-C B:1 \-C S:authMe \-C O:1 \-C NN:code:1.23 \-C NS:flag:ok \-C O:0 159 | .fi 160 | .SS "Session Parameters" 161 | These options take effect after the Connect request has succeeded. 162 | .TP 163 | \fB\-\-playpath \-y\fP\ \fIpath\fP 164 | Overrides the playpath parsed from the RTMP URL. Sometimes the 165 | rtmpdump URL parser cannot determine the correct playpath 166 | automatically, so it must be given explicitly using this option. 167 | .TP 168 | .B \-\-playlist \-Y 169 | Issue a set_playlist command before sending the play command. The 170 | playlist will just contain the current playpath. 171 | .TP 172 | .B \-\-live \-v 173 | Specify that the media is a live stream. No resuming or seeking in 174 | live streams is possible. 175 | .TP 176 | \fB\-\-subscribe \-d\fP\ \fIstream\fP 177 | Name of live stream to subscribe to. Defaults to 178 | .IR playpath . 179 | .TP 180 | .B \-\-resume \-e 181 | Resume an incomplete RTMP download. 182 | .TP 183 | \fB\-\-skip \-k\fP\ \fInum\fP 184 | Skip 185 | .I num 186 | keyframes when looking for the last keyframe from which to resume. This 187 | may be useful if a regular attempt to resume fails. The default is 0. 188 | .TP 189 | \fB\-\-start \-A\fP\ \fInum\fP 190 | Start at 191 | .I num 192 | seconds into the stream. Not valid for live streams. 193 | .TP 194 | \fB\-\-stop \-B\fP\ \fInum\fP 195 | Stop at 196 | .I num 197 | seconds into the stream. 198 | .TP 199 | \fB\-\-buffer \-b\fP\ \fInum\fP 200 | Set buffer time to 201 | .I num 202 | milliseconds. The default is 36000000. 203 | .TP 204 | \fB\-\-timeout \-m\fP\ \fInum\fP 205 | Timeout the session after 206 | .I num 207 | seconds without receiving any data from the server. The default is 120. 208 | .SS "Security Parameters" 209 | These options handle additional authentication requests from the server. 210 | .TP 211 | \fB\-\-token \-T\fP\ \fIkey\fP 212 | Key for SecureToken response, used if the server requires SecureToken 213 | authentication. 214 | .TP 215 | \fB\-\-jtv \-j\fP\ \fIJSON\fP 216 | JSON token used by legacy Justin.tv servers. Invokes NetStream.Authenticate.UsherToken 217 | .TP 218 | \fB\-\-swfhash \-w\fP\ \fIhexstring\fP 219 | SHA256 hash of the decompressed SWF file. This option may be needed if 220 | the server uses SWF Verification, but see the 221 | .B \-\-swfVfy 222 | option below. The hash is 32 bytes, and must be 223 | given in hexadecimal. The 224 | .B \-\-swfsize 225 | option must always be used with this option. 226 | .TP 227 | \fB\-\-swfsize \-x\fP\ \fInum\fP 228 | Size of the decompressed SWF file. This option may be needed if the 229 | server uses SWF Verification, but see the 230 | .B \-\-swfVfy 231 | option below. The 232 | .B \-\-swfhash 233 | option must always be used with this option. 234 | .TP 235 | \fB\-\-swfVfy \-W\fP\ \fIurl\fP 236 | URL of the SWF player for this media. This option replaces all three 237 | of the 238 | .BR \-\-swfUrl , 239 | .BR \-\-swfhash , 240 | and 241 | .B \-\-swfsize 242 | options. When this option is used, the SWF player is retrieved from the 243 | specified URL and the hash and size are computed automatically. Also 244 | the information is cached in a 245 | .I .swfinfo 246 | file in the user's home directory, so that it doesn't need to be retrieved 247 | and recalculated every time rtmpdump is run. The .swfinfo file records 248 | the URL, the time it was fetched, the modification timestamp of the SWF 249 | file, its size, and its hash. By default, the cached info will be used 250 | for 30 days before re-checking. 251 | .TP 252 | \fB\-\-swfAge \-X\fP\ \fIdays\fP 253 | Specify how many days to use the cached SWF info before re-checking. Use 254 | 0 to always check the SWF URL. Note that if the check shows that the 255 | SWF file has the same modification timestamp as before, it will not be 256 | retrieved again. 257 | .SS Miscellaneous 258 | .TP 259 | \fB\-\-flv \-o\fP\ \fIoutput\fP 260 | Specify the output file name. If the name is \- or is omitted, the 261 | stream is written to stdout. 262 | .TP 263 | .B \-\-hashes \-# 264 | Display streaming progress with a hash mark for each 1% of progress, instead 265 | of a byte counter. 266 | .TP 267 | .B \-\-quiet \-q 268 | Suppress all command output. 269 | .TP 270 | .B \-\-verbose \-V 271 | Verbose command output. 272 | .TP 273 | .B \-\-debug \-z 274 | Debug level output. Extremely verbose, including hex dumps of all packet data. 275 | .TP 276 | .B \-\-help \-h 277 | Print a summary of command options. 278 | .SH EXIT STATUS 279 | .TP 280 | .B 0 281 | Successful program execution. 282 | .TP 283 | .B 1 284 | Unrecoverable error. 285 | .TP 286 | .B 2 287 | Incomplete transfer, resuming may get further. 288 | .SH ENVIRONMENT 289 | .TP 290 | .B HOME 291 | The value of 292 | .RB $ HOME 293 | is used as the location for the 294 | .I .swfinfo 295 | file. 296 | .SH FILES 297 | .TP 298 | .I $HOME/.swfinfo 299 | Cache of SWF Verification information 300 | .SH "SEE ALSO" 301 | .BR rtmpgw (8) 302 | .SH AUTHORS 303 | Andrej Stepanchuk, Howard Chu, The Flvstreamer Team 304 | .br 305 | 306 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | RTMP Dump v2.4 2 | (C) 2009 Andrej Stepanchuk 3 | (C) 2009-2011 Howard Chu 4 | (C) 2010 2a665470ced7adb7156fcef47f8199a6371c117b8a79e399a2771e0b36384090 5 | (C) 2011 33ae1ce77301f4b4494faaa5f609f3c48b9dcf82 6 | License: GPLv2 7 | librtmp license: LGPLv2.1 8 | http://rtmpdump.mplayerhq.hu/ 9 | 10 | To compile type "make" with SYS=, e.g. 11 | 12 | $ make SYS=posix 13 | 14 | for Linux, Unix, etc. or 15 | 16 | $ make SYS=darwin 17 | 18 | for MacOSX or 19 | 20 | $ make SYS=mingw 21 | 22 | for Windows. 23 | 24 | You can cross-compile for other platforms using the CROSS_COMPILE variable: 25 | 26 | $ make CROSS_COMPILE=arm-none-linux- INC=-I/my/cross/includes 27 | 28 | Please read the Makefile to see what other make variables are used. 29 | 30 | This code also requires you to have OpenSSL and zlib installed. You may 31 | optionally use GnuTLS or polarssl instead of OpenSSL if desired. You may 32 | also build with just rtmpe support, and no rtmps/https support, by 33 | specifying -DNO_SSL in the XDEF macro, e.g. 34 | 35 | $ make XDEF=-DNO_SSL 36 | 37 | or 38 | 39 | $ make CRYPTO=POLARSSL XDEF=-DNO_SSL 40 | 41 | You may also turn off all crypto support if desired 42 | 43 | $ make CRYPTO= 44 | 45 | A shared library is now built by default, in addition to the static 46 | library. You can also turn it off if desired 47 | 48 | $ make SHARED= 49 | 50 | The rtmpdump programs still link to the static library, regardless. 51 | 52 | Note that if using OpenSSL, you must have version 0.9.8 or newer. 53 | For Polar SSL you must have version 1.0.0 or newer. 54 | 55 | Credit goes to team boxee for the XBMC RTMP code originally used in RTMPDumper. 56 | The current code is based on the XBMC code but rewritten in C by Howard Chu. 57 | 58 | 59 | SWF Verification 60 | ---------------- 61 | 62 | Note: these instructions for manually generating the SWFVerification 63 | info are provided only for historical documentation. The software can now 64 | generate this info automatically, so it is no longer necessary to 65 | run the commands described here. Just use the -W (--swfVfy) option 66 | to perform automatic SWFVerification. 67 | 68 | Download the swf player you want to use for SWFVerification, unzip it using 69 | 70 | $ flasm -x file.swf 71 | 72 | It will show the decompressed filesize, use it for --swfsize 73 | 74 | Now generate the hash 75 | 76 | $ openssl sha -sha256 -hmac "Genuine Adobe Flash Player 001" file.swf 77 | 78 | and use the --swfhash "01234..." option to pass it. 79 | 80 | e.g. $ ./rtmpdump --swfhash "123456..." --swfsize 987... 81 | 82 | 83 | Connect Parameters 84 | ------------------ 85 | 86 | Some servers expect additional custom parameters to be attached to the 87 | RTMP connect request. The "--auth" option handles a specific case, where 88 | a boolean TRUE followed by the given string are added to the request. 89 | Other servers may require completely different parameters, so the new 90 | "--conn" option has been added. This option can be set multiple times 91 | on the command line, adding one parameter each time. 92 | 93 | The argument to the option must take the form : where 94 | type can be B for boolean, S for string, N for number, and O for object. 95 | For booleans the value must be 0 or 1. Also, for objects the value must 96 | be 1 to start a new object, or 0 to end the current object. 97 | 98 | Examples: 99 | --conn B:0 --conn S:hello --conn N:3.14159 100 | 101 | Named parameters can be specified by prefixing 'N' to the type. Then the 102 | name should come next, and finally the value: 103 | --conn NB:myflag:1 --conn NS:category:something --conn NN:pi:3.14159 104 | 105 | Objects may be added sequentially: 106 | -C O:1 -C NB:flag:1 -C NS:status:success -C O:0 -C O:1 -C NN:time:12.30 -C O:0 107 | or nested: 108 | -C O:1 -C NS:code:hello -C NO:extra:1 -C NS:data:stuff -C O:0 -C O:0 109 | 110 | 111 | Building OpenSSL 0.9.8k 112 | ----------------------- 113 | arm: 114 | ./Configure -DL_ENDIAN --prefix=`pwd`/armlibs linux-generic32 115 | 116 | Then replace gcc, cc, ar, ranlib in Makefile and crypto/Makefile by arm-linux-* variants and use make && make install_sw 117 | 118 | win32: 119 | Try ./Configure mingw --prefix=`pwd`/win32libs -DL_ENDIAN -DOPENSSL_NO_HW 120 | Replace gcc, cc, ... by mingw32-* variants in Makefile and crypto/Makefile 121 | make && make install_sw 122 | 123 | OpenSSL cross-compiling can be a difficult beast. 124 | 125 | Precompiled OpenSSL binaries for Windows are available on 126 | http://www.slproweb.com/products/Win32OpenSSL.html 127 | 128 | If you're just running a pre-built Windows rtmpdump binary, then all you 129 | need is the "Light" installer. If you want to compile rtmpdump yourself, 130 | you'll need the full installer. 131 | 132 | 133 | Example Servers 134 | --------------- 135 | Three different types of servers are also present in this distribution: 136 | rtmpsrv - a stub server 137 | rtmpsuck - a transparent proxy 138 | rtmpgw - an RTMP to HTTP gateway 139 | 140 | rtmpsrv - Note that this is very incomplete code, and I haven't yet decided 141 | whether or not to finish it. It is useful for obtaining all the parameters 142 | that a real Flash client would send to an RTMP server, so that they can be 143 | used with rtmpdump. The current version now invokes rtmpdump automatically 144 | after parsing a client request. 145 | 146 | rtmpsuck - proxy server. See below... 147 | 148 | All you need to do is redirect your Flash clients to the machine running this 149 | server and it will dump out all the connect / play parameters that the Flash 150 | client sent. The simplest way to cause the redirect is by editing /etc/hosts 151 | when you know the hostname of the RTMP server, and point it to localhost while 152 | running rtmpsrv on your machine. (This approach should work on any OS; on 153 | Windows you would edit %SystemRoot%\system32\drivers\etc\hosts.) 154 | 155 | On Linux you can also use iptables to redirect all outbound RTMP traffic. You 156 | need to be running as root in order to use the iptables command. 157 | 158 | In my original plan I would have the transparent proxy running as a special 159 | user (e.g. user "proxy"), and regular Flash clients running as any other user. 160 | In that case the proxy would make the connection to the real RTMP server. The 161 | iptables rule would look like this: 162 | 163 | iptables -t nat -A OUTPUT -p tcp --dport 1935 -m owner \! --uid-owner proxy \ 164 | -j REDIRECT 165 | 166 | A rule like the above will be needed to use rtmpsuck. Note that you should 167 | replace "proxy" in the above command with an account that actually exists 168 | on your machine. 169 | 170 | Using it in this mode takes advantage of the Linux support for IP redirects; 171 | in particular it uses a special getsockopt() call to retrieve the original 172 | destination address of the connection. That way the proxy can create the 173 | real outbound connection without any other help from the user. The equivalent 174 | functionality may exist on other OSs but needs more investigation. 175 | 176 | (Based on reading the BSD ipfw manpage, this rule ought to work on BSD: 177 | 178 | ipfw add 40 fwd 127.0.0.1,1935 tcp from any to any 1935 not uid proxy 179 | 180 | Some confirmation from any BSD users would be nice.) 181 | 182 | (We have a solution for Windows based on a TDI driver; this is known to 183 | work on Win2K and WinXP but is assumed to not work on Vista or Win7 as the 184 | TDI is no longer used on those OS versions. Also, none of the known 185 | solutions are available as freeware.) 186 | 187 | The rtmpsuck command has only one option: "-z" to turn on debug logging. 188 | It listens on port 1935 for RTMP sessions, but you can also redirect other 189 | ports to it as needed (read the iptables docs). It first performs an RTMP 190 | handshake with the client, then waits for the client to send a connect 191 | request. It parses and prints the connect parameters, then makes an 192 | outbound connection to the real RTMP server. It performs an RTMP handshake 193 | with that server, forwards the connect request, and from that point on it 194 | just relays packets back and forth between the two endpoints. 195 | 196 | It also checks for a few packets that it treats specially: a play packet 197 | from the client will get parsed so that the playpath can be displayed. It 198 | also handles SWF Verification requests from the server, without forwarding 199 | them to the client. (There would be no point, since the response is tied to 200 | each session's handshake.) 201 | 202 | Once the play command is processed, all subsequent audio/video data received 203 | from the server will be written to a file, as well as being delivered back 204 | to the client. 205 | 206 | The point of all this, instead of just using a sniffer, is that since rtmpsuck 207 | has performed real handshakes with both the client and the server, it can 208 | negotiate whatever encryption keys are needed and so record the unencrypted 209 | data. 210 | 211 | rtmpgw - HTTP gateway: this is an HTTP server that accepts requests that 212 | consist of rtmpdump parameters. It then connects to the specified RTMP 213 | server and returns the retrieved data in the HTTP response. The only valid 214 | HTTP request is "GET /" but additional options can be provided in normal 215 | URL-encoded fashion. E.g. 216 | GET /?r=rtmp:%2f%2fserver%2fmyapp&y=somefile HTTP/1.0 217 | 218 | is equivalent the rtmpdump parameters "-r rtmp://server/myapp -y somefile". 219 | 220 | Note that only the shortform (single letter) rtmpdump options are supported. 221 | -------------------------------------------------------------------------------- /librtmp/dh.h: -------------------------------------------------------------------------------- 1 | /* RTMPDump - Diffie-Hellmann Key Exchange 2 | * Copyright (C) 2009 Andrej Stepanchuk 3 | * Copyright (C) 2009-2010 Howard Chu 4 | * 5 | * This file is part of librtmp. 6 | * 7 | * librtmp is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as 9 | * published by the Free Software Foundation; either version 2.1, 10 | * or (at your option) any later version. 11 | * 12 | * librtmp is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with librtmp see the file COPYING. If not, write to 19 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 20 | * Boston, MA 02110-1301, USA. 21 | * http://www.gnu.org/copyleft/lgpl.html 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #ifdef USE_POLARSSL 31 | #include 32 | typedef mpi * MP_t; 33 | #define MP_new(m) m = malloc(sizeof(mpi)); mpi_init(m) 34 | #define MP_set_w(mpi, w) mpi_lset(mpi, w) 35 | #define MP_cmp(u, v) mpi_cmp_mpi(u, v) 36 | #define MP_set(u, v) mpi_copy(u, v) 37 | #define MP_sub_w(mpi, w) mpi_sub_int(mpi, mpi, w) 38 | #define MP_cmp_1(mpi) mpi_cmp_int(mpi, 1) 39 | #define MP_modexp(r, y, q, p) mpi_exp_mod(r, y, q, p, NULL) 40 | #define MP_free(mpi) mpi_free(mpi); free(mpi) 41 | #define MP_gethex(u, hex, res) MP_new(u); res = mpi_read_string(u, 16, hex) == 0 42 | #define MP_bytes(u) mpi_size(u) 43 | #define MP_setbin(u,buf,len) mpi_write_binary(u,buf,len) 44 | #define MP_getbin(u,buf,len) MP_new(u); mpi_read_binary(u,buf,len) 45 | 46 | typedef struct MDH { 47 | MP_t p; 48 | MP_t g; 49 | MP_t pub_key; 50 | MP_t priv_key; 51 | long length; 52 | dhm_context ctx; 53 | } MDH; 54 | 55 | #define MDH_new() calloc(1,sizeof(MDH)) 56 | #define MDH_free(vp) {MDH *_dh = vp; dhm_free(&_dh->ctx); MP_free(_dh->p); MP_free(_dh->g); MP_free(_dh->pub_key); MP_free(_dh->priv_key); free(_dh);} 57 | 58 | static int MDH_generate_key(MDH *dh) 59 | { 60 | unsigned char out[2]; 61 | MP_set(&dh->ctx.P, dh->p); 62 | MP_set(&dh->ctx.G, dh->g); 63 | dh->ctx.len = 128; 64 | dhm_make_public(&dh->ctx, 1024, out, 1, havege_random, &RTMP_TLS_ctx->hs); 65 | MP_new(dh->pub_key); 66 | MP_new(dh->priv_key); 67 | MP_set(dh->pub_key, &dh->ctx.GX); 68 | MP_set(dh->priv_key, &dh->ctx.X); 69 | return 1; 70 | } 71 | 72 | static int MDH_compute_key(uint8_t *secret, size_t len, MP_t pub, MDH *dh) 73 | { 74 | MP_set(&dh->ctx.GY, pub); 75 | dhm_calc_secret(&dh->ctx, secret, &len); 76 | return 0; 77 | } 78 | 79 | #elif defined(USE_GNUTLS) 80 | #include 81 | typedef gcry_mpi_t MP_t; 82 | #define MP_new(m) m = gcry_mpi_new(1) 83 | #define MP_set_w(mpi, w) gcry_mpi_set_ui(mpi, w) 84 | #define MP_cmp(u, v) gcry_mpi_cmp(u, v) 85 | #define MP_set(u, v) gcry_mpi_set(u, v) 86 | #define MP_sub_w(mpi, w) gcry_mpi_sub_ui(mpi, mpi, w) 87 | #define MP_cmp_1(mpi) gcry_mpi_cmp_ui(mpi, 1) 88 | #define MP_modexp(r, y, q, p) gcry_mpi_powm(r, y, q, p) 89 | #define MP_free(mpi) gcry_mpi_release(mpi) 90 | #define MP_gethex(u, hex, res) res = (gcry_mpi_scan(&u, GCRYMPI_FMT_HEX, hex, 0, 0) == 0) 91 | #define MP_bytes(u) (gcry_mpi_get_nbits(u) + 7) / 8 92 | #define MP_setbin(u,buf,len) gcry_mpi_print(GCRYMPI_FMT_USG,buf,len,NULL,u) 93 | #define MP_getbin(u,buf,len) gcry_mpi_scan(&u,GCRYMPI_FMT_USG,buf,len,NULL) 94 | 95 | typedef struct MDH { 96 | MP_t p; 97 | MP_t g; 98 | MP_t pub_key; 99 | MP_t priv_key; 100 | long length; 101 | } MDH; 102 | 103 | #define MDH_new() calloc(1,sizeof(MDH)) 104 | #define MDH_free(dh) do {MP_free(((MDH*)(dh))->p); MP_free(((MDH*)(dh))->g); MP_free(((MDH*)(dh))->pub_key); MP_free(((MDH*)(dh))->priv_key); free(dh);} while(0) 105 | 106 | extern MP_t gnutls_calc_dh_secret(MP_t *priv, MP_t g, MP_t p); 107 | extern MP_t gnutls_calc_dh_key(MP_t y, MP_t x, MP_t p); 108 | 109 | #define MDH_generate_key(dh) (dh->pub_key = gnutls_calc_dh_secret(&dh->priv_key, dh->g, dh->p)) 110 | static int MDH_compute_key(uint8_t *secret, size_t len, MP_t pub, MDH *dh) 111 | { 112 | MP_t sec = gnutls_calc_dh_key(pub, dh->priv_key, dh->p); 113 | if (sec) 114 | { 115 | MP_setbin(sec, secret, len); 116 | MP_free(sec); 117 | return 0; 118 | } 119 | else 120 | return -1; 121 | } 122 | 123 | #else /* USE_OPENSSL */ 124 | #include 125 | #include 126 | 127 | typedef BIGNUM * MP_t; 128 | #define MP_new(m) m = BN_new() 129 | #define MP_set_w(mpi, w) BN_set_word(mpi, w) 130 | #define MP_cmp(u, v) BN_cmp(u, v) 131 | #define MP_set(u, v) BN_copy(u, v) 132 | #define MP_sub_w(mpi, w) BN_sub_word(mpi, w) 133 | #define MP_cmp_1(mpi) BN_cmp(mpi, BN_value_one()) 134 | #define MP_modexp(r, y, q, p) do {BN_CTX *ctx = BN_CTX_new(); BN_mod_exp(r, y, q, p, ctx); BN_CTX_free(ctx);} while(0) 135 | #define MP_free(mpi) BN_free(mpi) 136 | #define MP_gethex(u, hex, res) res = BN_hex2bn(&u, hex) 137 | #define MP_bytes(u) BN_num_bytes(u) 138 | #define MP_setbin(u,buf,len) BN_bn2bin(u,buf) 139 | #define MP_getbin(u,buf,len) u = BN_bin2bn(buf,len,0) 140 | 141 | #define MDH DH 142 | #define MDH_new() DH_new() 143 | #define MDH_free(dh) DH_free(dh) 144 | #define MDH_generate_key(dh) DH_generate_key(dh) 145 | #define MDH_compute_key(secret, seclen, pub, dh) DH_compute_key(secret, pub, dh) 146 | 147 | #endif 148 | 149 | #include "log.h" 150 | #include "dhgroups.h" 151 | 152 | /* RFC 2631, Section 2.1.5, http://www.ietf.org/rfc/rfc2631.txt */ 153 | static int 154 | isValidPublicKey(MP_t y, MP_t p, MP_t q) 155 | { 156 | int ret = TRUE; 157 | MP_t bn; 158 | assert(y); 159 | 160 | MP_new(bn); 161 | assert(bn); 162 | 163 | /* y must lie in [2,p-1] */ 164 | MP_set_w(bn, 1); 165 | if (MP_cmp(y, bn) < 0) 166 | { 167 | RTMP_Log(RTMP_LOGERROR, "DH public key must be at least 2"); 168 | ret = FALSE; 169 | goto failed; 170 | } 171 | 172 | /* bn = p-2 */ 173 | MP_set(bn, p); 174 | MP_sub_w(bn, 1); 175 | if (MP_cmp(y, bn) > 0) 176 | { 177 | RTMP_Log(RTMP_LOGERROR, "DH public key must be at most p-2"); 178 | ret = FALSE; 179 | goto failed; 180 | } 181 | 182 | /* Verify with Sophie-Germain prime 183 | * 184 | * This is a nice test to make sure the public key position is calculated 185 | * correctly. This test will fail in about 50% of the cases if applied to 186 | * random data. 187 | */ 188 | if (q) 189 | { 190 | /* y must fulfill y^q mod p = 1 */ 191 | MP_modexp(bn, y, q, p); 192 | 193 | if (MP_cmp_1(bn) != 0) 194 | { 195 | RTMP_Log(RTMP_LOGWARNING, "DH public key does not fulfill y^q mod p = 1"); 196 | } 197 | } 198 | 199 | failed: 200 | MP_free(bn); 201 | return ret; 202 | } 203 | 204 | static MDH * 205 | DHInit(int nKeyBits) 206 | { 207 | size_t res; 208 | MDH *dh = MDH_new(); 209 | 210 | if (!dh) 211 | goto failed; 212 | 213 | MP_new(dh->g); 214 | 215 | if (!dh->g) 216 | goto failed; 217 | 218 | MP_gethex(dh->p, P1024, res); /* prime P1024, see dhgroups.h */ 219 | if (!res) 220 | { 221 | goto failed; 222 | } 223 | 224 | MP_set_w(dh->g, 2); /* base 2 */ 225 | 226 | dh->length = nKeyBits; 227 | return dh; 228 | 229 | failed: 230 | if (dh) 231 | MDH_free(dh); 232 | 233 | return 0; 234 | } 235 | 236 | static int 237 | DHGenerateKey(MDH *dh) 238 | { 239 | size_t res = 0; 240 | if (!dh) 241 | return 0; 242 | 243 | while (!res) 244 | { 245 | MP_t q1 = NULL; 246 | 247 | if (!MDH_generate_key(dh)) 248 | return 0; 249 | 250 | MP_gethex(q1, Q1024, res); 251 | assert(res); 252 | 253 | res = isValidPublicKey(dh->pub_key, dh->p, q1); 254 | if (!res) 255 | { 256 | MP_free(dh->pub_key); 257 | MP_free(dh->priv_key); 258 | dh->pub_key = dh->priv_key = 0; 259 | } 260 | 261 | MP_free(q1); 262 | } 263 | return 1; 264 | } 265 | 266 | /* fill pubkey with the public key in BIG ENDIAN order 267 | * 00 00 00 00 00 x1 x2 x3 ..... 268 | */ 269 | 270 | static int 271 | DHGetPublicKey(MDH *dh, uint8_t *pubkey, size_t nPubkeyLen) 272 | { 273 | int len; 274 | if (!dh || !dh->pub_key) 275 | return 0; 276 | 277 | len = MP_bytes(dh->pub_key); 278 | if (len <= 0 || len > (int) nPubkeyLen) 279 | return 0; 280 | 281 | memset(pubkey, 0, nPubkeyLen); 282 | MP_setbin(dh->pub_key, pubkey + (nPubkeyLen - len), len); 283 | return 1; 284 | } 285 | 286 | #if 0 /* unused */ 287 | static int 288 | DHGetPrivateKey(MDH *dh, uint8_t *privkey, size_t nPrivkeyLen) 289 | { 290 | if (!dh || !dh->priv_key) 291 | return 0; 292 | 293 | int len = MP_bytes(dh->priv_key); 294 | if (len <= 0 || len > (int) nPrivkeyLen) 295 | return 0; 296 | 297 | memset(privkey, 0, nPrivkeyLen); 298 | MP_setbin(dh->priv_key, privkey + (nPrivkeyLen - len), len); 299 | return 1; 300 | } 301 | #endif 302 | 303 | /* computes the shared secret key from the private MDH value and the 304 | * other party's public key (pubkey) 305 | */ 306 | static int 307 | DHComputeSharedSecretKey(MDH *dh, uint8_t *pubkey, size_t nPubkeyLen, 308 | uint8_t *secret) 309 | { 310 | MP_t q1 = NULL, pubkeyBn = NULL; 311 | size_t len; 312 | int res; 313 | 314 | if (!dh || !secret || nPubkeyLen >= INT_MAX) 315 | return -1; 316 | 317 | MP_getbin(pubkeyBn, pubkey, nPubkeyLen); 318 | if (!pubkeyBn) 319 | return -1; 320 | 321 | MP_gethex(q1, Q1024, len); 322 | assert(len); 323 | 324 | if (isValidPublicKey(pubkeyBn, dh->p, q1)) 325 | res = MDH_compute_key(secret, nPubkeyLen, pubkeyBn, dh); 326 | else 327 | res = -1; 328 | 329 | MP_free(q1); 330 | MP_free(pubkeyBn); 331 | 332 | return res; 333 | } 334 | -------------------------------------------------------------------------------- /librtmp/librtmp.3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | LIBRTMP(3): 4 | 5 | 6 | 8 | 9 | 11 |
LIBRTMP(3)LIBRTMP(3) 7 |
RTMPDump v2.42011-07-20LIBRTMP(3) 10 |


    12 | 14 |
15 | 16 |

NAME

    17 | librtmp − RTMPDump Real-Time Messaging Protocol API 18 |
19 | 20 |

LIBRARY

    21 | RTMPDump RTMP (librtmp, -lrtmp) 22 |
23 | 24 |

SYNOPSIS

    25 | #include <librtmp/rtmp.h> 26 |
27 | 28 |

DESCRIPTION

    29 | The Real-Time Messaging Protocol (RTMP) is used for streaming 30 | multimedia content across a TCP/IP network. This API provides most client 31 | functions and a few server functions needed to support RTMP, RTMP tunneled 32 | in HTTP (RTMPT), encrypted RTMP (RTMPE), RTMP over SSL/TLS (RTMPS) and 33 | tunneled variants of these encrypted types (RTMPTE, RTMPTS). The basic 34 | RTMP specification has been published by Adobe but this API was 35 | reverse-engineered without use of the Adobe specification. As such, it may 36 | deviate from any published specifications but it usually duplicates the 37 | actual behavior of the original Adobe clients. 38 |

    39 | The RTMPDump software package includes a basic client utility program 40 | in 41 | rtmpdump(1), 42 | some sample servers, and a library used to provide programmatic access 43 | to the RTMP protocol. This man page gives an overview of the RTMP 44 | library routines. These routines are found in the -lrtmp library. Many 45 | other routines are also available, but they are not documented yet. 46 |

    47 | The basic interaction is as follows. A session handle is created using 48 | RTMP_Alloc() 49 | and initialized using 50 | RTMP_Init(). 51 | All session parameters are provided using 52 | RTMP_SetupURL(). 53 | The network connection is established using 54 | RTMP_Connect(), 55 | and then the RTMP session is established using 56 | RTMP_ConnectStream(). 57 | The stream is read using 58 | RTMP_Read(). 59 | A client can publish a stream by calling 60 | RTMP_EnableWrite() 61 | before the 62 | RTMP_Connect() 63 | call, and then using 64 | RTMP_Write() 65 | after the session is established. 66 | While a stream is playing it may be paused and unpaused using 67 | RTMP_Pause(). 68 | The stream playback position can be moved using 69 | RTMP_Seek(). 70 | When 71 | RTMP_Read() 72 | returns 0 bytes, the stream is complete and may be closed using 73 | RTMP_Close(). 74 | The session handle is freed using 75 | RTMP_Free(). 76 |

    77 | All data is transferred using FLV format. The basic session requires 78 | an RTMP URL. The RTMP URL format is of the form 79 |

     80 |   rtmp[t][e|s]://hostname[:port][/app[/playpath]]
     81 | 
    82 |

    83 | Plain rtmp, as well as tunneled and encrypted sessions are supported. 84 |

    85 | Additional options may be specified by appending space-separated 86 | key=value pairs to the URL. Special characters in values may need 87 | to be escaped to prevent misinterpretation by the option parser. 88 | The escape encoding uses a backslash followed by two hexadecimal digits 89 | representing the ASCII value of the character. E.g., spaces must 90 | be escaped as \20 and backslashes must be escaped as \5c. 91 |

92 | 93 |

OPTIONS

    94 |
95 | 96 |

Network Parameters

    97 | These options define how to connect to the media server. 98 |

    99 |

    100 | socks=host:port 101 |
    102 | Use the specified SOCKS4 proxy. 103 |
    104 |
105 | 106 |

Connection Parameters

    107 | These options define the content of the RTMP Connect request packet. 108 | If correct values are not provided, the media server will reject the 109 | connection attempt. 110 |

    111 |

    112 | app=name 113 |
    114 | Name of application to connect to on the RTMP server. Overrides 115 | the app in the RTMP URL. Sometimes the librtmp URL parser cannot 116 | determine the app name automatically, so it must be given explicitly 117 | using this option. 118 |
    119 |

    120 |

    121 | tcUrl=url 122 |
    123 | URL of the target stream. Defaults to rtmp[t][e|s]://host[:port]/app. 124 |
    125 |

    126 |

    127 | pageUrl=url 128 |
    129 | URL of the web page in which the media was embedded. By default no 130 | value will be sent. 131 |
    132 |

    133 |

    134 | swfUrl=url 135 |
    136 | URL of the SWF player for the media. By default no value will be sent. 137 |
    138 |

    139 |

    140 | flashVer=version 141 |
    142 | Version of the Flash plugin used to run the SWF player. The 143 | default is "LNX 10,0,32,18". 144 |
    145 |

    146 |

    147 | conn=type:data 148 |
    149 | Append arbitrary AMF data to the Connect message. The type 150 | must be B for Boolean, N for number, S for string, O for object, or Z 151 | for null. For Booleans the data must be either 0 or 1 for FALSE or TRUE, 152 | respectively. Likewise for Objects the data must be 0 or 1 to end or 153 | begin an object, respectively. Data items in subobjects may be named, by 154 | prefixing the type with 'N' and specifying the name before the value, e.g. 155 | NB:myFlag:1. This option may be used multiple times to construct arbitrary 156 | AMF sequences. E.g. 157 |
    158 |   conn=B:1 conn=S:authMe conn=O:1 conn=NN:code:1.23 conn=NS:flag:ok conn=O:0
    159 | 
    160 |
    161 |
162 | 163 |

Session Parameters

    164 | These options take effect after the Connect request has succeeded. 165 |

    166 |

    167 | playpath=path 168 |
    169 | Overrides the playpath parsed from the RTMP URL. Sometimes the 170 | rtmpdump URL parser cannot determine the correct playpath 171 | automatically, so it must be given explicitly using this option. 172 |
    173 |

    174 |

    175 | playlist=0|1 176 |
    177 | If the value is 1 or TRUE, issue a set_playlist command before sending the 178 | play command. The playlist will just contain the current playpath. If the 179 | value is 0 or FALSE, the set_playlist command will not be sent. The 180 | default is FALSE. 181 |
    182 |

    183 |

    184 | live=0|1 185 |
    186 | Specify that the media is a live stream. No resuming or seeking in 187 | live streams is possible. 188 |
    189 |

    190 |

    191 | subscribe=path 192 |
    193 | Name of live stream to subscribe to. Defaults to 194 | playpath. 195 |
    196 |

    197 |

    198 | start=num 199 |
    200 | Start at 201 | num 202 | seconds into the stream. Not valid for live streams. 203 |
    204 |

    205 |

    206 | stop=num 207 |
    208 | Stop at 209 | num 210 | seconds into the stream. 211 |
    212 |

    213 |

    214 | buffer=num 215 |
    216 | Set buffer time to 217 | num 218 | milliseconds. The default is 30000. 219 |
    220 |

    221 |

    222 | timeout=num 223 |
    224 | Timeout the session after 225 | num 226 | seconds without receiving any data from the server. The default is 120. 227 |
    228 |
229 | 230 |

Security Parameters

    231 | These options handle additional authentication requests from the server. 232 |

    233 |

    234 | token=key 235 |
    236 | Key for SecureToken response, used if the server requires SecureToken 237 | authentication. 238 |
    239 |

    240 |

    241 | jtv=JSON 242 |
    243 | JSON token used by legacy Justin.tv servers. Invokes NetStream.Authenticate.UsherToken 244 |
    245 |

    246 |

    247 | swfVfy=0|1 248 |
    249 | If the value is 1 or TRUE, the SWF player is retrieved from the 250 | specified 251 | swfUrl 252 | for performing SWF Verification. The SWF hash and size (used in the 253 | verification step) are computed automatically. Also the SWF information is 254 | cached in a 255 | .swfinfo 256 | file in the user's home directory, so that it doesn't need to be retrieved 257 | and recalculated every time. The .swfinfo file records 258 | the SWF URL, the time it was fetched, the modification timestamp of the SWF 259 | file, its size, and its hash. By default, the cached info will be used 260 | for 30 days before re-checking. 261 |
    262 |

    263 |

    264 | swfAge=days 265 |
    266 | Specify how many days to use the cached SWF info before re-checking. Use 267 | 0 to always check the SWF URL. Note that if the check shows that the 268 | SWF file has the same modification timestamp as before, it will not be 269 | retrieved again. 270 |
    271 |
272 | 273 |

EXAMPLES

    274 | An example character string suitable for use with 275 | RTMP_SetupURL(): 276 |
    277 |   "rtmp://flashserver:1935/ondemand/thefile swfUrl=http://flashserver/player.swf swfVfy=1"
    278 | 
    279 |
280 | 281 |

ENVIRONMENT

    282 |

    283 |

    284 | HOME 285 |
    286 | The value of 287 | $HOME 288 | is used as the location for the 289 | .swfinfo 290 | file. 291 |
    292 |
293 | 294 |

FILES

    295 |

    296 |

    297 | $HOME/.swfinfo 298 |
    299 | Cache of SWF Verification information 300 |
    301 |
302 | 303 |

SEE ALSO

307 | 308 |

AUTHORS

313 | -------------------------------------------------------------------------------- /librtmp/dhgroups.h: -------------------------------------------------------------------------------- 1 | /* librtmp - Diffie-Hellmann Key Exchange 2 | * Copyright (C) 2009 Andrej Stepanchuk 3 | * 4 | * This file is part of librtmp. 5 | * 6 | * librtmp is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License as 8 | * published by the Free Software Foundation; either version 2.1, 9 | * or (at your option) any later version. 10 | * 11 | * librtmp is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with librtmp see the file COPYING. If not, write to 18 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 | * Boston, MA 02110-1301, USA. 20 | * http://www.gnu.org/copyleft/lgpl.html 21 | */ 22 | 23 | /* from RFC 3526, see http://www.ietf.org/rfc/rfc3526.txt */ 24 | 25 | /* 2^768 - 2 ^704 - 1 + 2^64 * { [2^638 pi] + 149686 } */ 26 | #define P768 \ 27 | "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ 28 | "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ 29 | "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ 30 | "E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF" 31 | 32 | /* 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 } */ 33 | #define P1024 \ 34 | "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ 35 | "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ 36 | "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ 37 | "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ 38 | "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" \ 39 | "FFFFFFFFFFFFFFFF" 40 | 41 | /* Group morder largest prime factor: */ 42 | #define Q1024 \ 43 | "7FFFFFFFFFFFFFFFE487ED5110B4611A62633145C06E0E68" \ 44 | "948127044533E63A0105DF531D89CD9128A5043CC71A026E" \ 45 | "F7CA8CD9E69D218D98158536F92F8A1BA7F09AB6B6A8E122" \ 46 | "F242DABB312F3F637A262174D31BF6B585FFAE5B7A035BF6" \ 47 | "F71C35FDAD44CFD2D74F9208BE258FF324943328F67329C0" \ 48 | "FFFFFFFFFFFFFFFF" 49 | 50 | /* 2^1536 - 2^1472 - 1 + 2^64 * { [2^1406 pi] + 741804 } */ 51 | #define P1536 \ 52 | "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ 53 | "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ 54 | "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ 55 | "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ 56 | "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \ 57 | "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \ 58 | "83655D23DCA3AD961C62F356208552BB9ED529077096966D" \ 59 | "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF" 60 | 61 | /* 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 } */ 62 | #define P2048 \ 63 | "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ 64 | "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ 65 | "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ 66 | "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ 67 | "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \ 68 | "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \ 69 | "83655D23DCA3AD961C62F356208552BB9ED529077096966D" \ 70 | "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \ 71 | "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \ 72 | "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \ 73 | "15728E5A8AACAA68FFFFFFFFFFFFFFFF" 74 | 75 | /* 2^3072 - 2^3008 - 1 + 2^64 * { [2^2942 pi] + 1690314 } */ 76 | #define P3072 \ 77 | "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ 78 | "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ 79 | "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ 80 | "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ 81 | "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \ 82 | "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \ 83 | "83655D23DCA3AD961C62F356208552BB9ED529077096966D" \ 84 | "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \ 85 | "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \ 86 | "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \ 87 | "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" \ 88 | "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" \ 89 | "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" \ 90 | "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" \ 91 | "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" \ 92 | "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF" 93 | 94 | /* 2^4096 - 2^4032 - 1 + 2^64 * { [2^3966 pi] + 240904 } */ 95 | #define P4096 \ 96 | "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ 97 | "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ 98 | "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ 99 | "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ 100 | "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \ 101 | "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \ 102 | "83655D23DCA3AD961C62F356208552BB9ED529077096966D" \ 103 | "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \ 104 | "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \ 105 | "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \ 106 | "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" \ 107 | "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" \ 108 | "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" \ 109 | "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" \ 110 | "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" \ 111 | "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" \ 112 | "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" \ 113 | "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" \ 114 | "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" \ 115 | "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" \ 116 | "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199" \ 117 | "FFFFFFFFFFFFFFFF" 118 | 119 | /* 2^6144 - 2^6080 - 1 + 2^64 * { [2^6014 pi] + 929484 } */ 120 | #define P6144 \ 121 | "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ 122 | "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ 123 | "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ 124 | "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ 125 | "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \ 126 | "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \ 127 | "83655D23DCA3AD961C62F356208552BB9ED529077096966D" \ 128 | "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \ 129 | "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \ 130 | "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \ 131 | "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" \ 132 | "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" \ 133 | "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" \ 134 | "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" \ 135 | "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" \ 136 | "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" \ 137 | "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" \ 138 | "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" \ 139 | "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" \ 140 | "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" \ 141 | "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" \ 142 | "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD" \ 143 | "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831" \ 144 | "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B" \ 145 | "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF" \ 146 | "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6" \ 147 | "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3" \ 148 | "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" \ 149 | "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328" \ 150 | "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C" \ 151 | "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE" \ 152 | "12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF" 153 | 154 | /* 2^8192 - 2^8128 - 1 + 2^64 * { [2^8062 pi] + 4743158 } */ 155 | #define P8192 \ 156 | "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ 157 | "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ 158 | "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ 159 | "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ 160 | "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \ 161 | "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \ 162 | "83655D23DCA3AD961C62F356208552BB9ED529077096966D" \ 163 | "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \ 164 | "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \ 165 | "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \ 166 | "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" \ 167 | "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" \ 168 | "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" \ 169 | "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" \ 170 | "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" \ 171 | "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" \ 172 | "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" \ 173 | "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" \ 174 | "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" \ 175 | "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" \ 176 | "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" \ 177 | "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD" \ 178 | "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831" \ 179 | "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B" \ 180 | "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF" \ 181 | "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6" \ 182 | "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3" \ 183 | "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" \ 184 | "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328" \ 185 | "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C" \ 186 | "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE" \ 187 | "12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4" \ 188 | "38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300" \ 189 | "741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F568" \ 190 | "3423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9" \ 191 | "22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B" \ 192 | "4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A" \ 193 | "062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A36" \ 194 | "4597E899A0255DC164F31CC50846851DF9AB48195DED7EA1" \ 195 | "B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92" \ 196 | "4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E47" \ 197 | "9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71" \ 198 | "60C980DD98EDD3DFFFFFFFFFFFFFFFFF" 199 | 200 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | RTMPDump 2 | Copyright 2008-2009 Andrej Stepanchuk; Distributed under the GPL v2 3 | Copyright 2009-2011 Howard Chu 4 | Copyright 2009 The Flvstreamer Team 5 | http://rtmpdump.mplayerhq.hu/ 6 | 7 | 20 July 2011 8 | - add NetStream.Authenticate.UsherToken for Justin.tv 9 | 10 | 11 July 2011, v2.4 11 | - add RTMPE type 9 handshake support 12 | 13 | 30 June 2010, v2.3 14 | - fix RC4 cleanup for GnuTLS/gcrypt 15 | - declare RTMP_Write buf as const 16 | - cleanup Makefile 17 | - replace all use of bool with int 18 | - add RTMP_Socket() and RTMP_Pause() APIs 19 | - add ping/pong message handling 20 | - add basic shared library support 21 | - fix RTMP_ParseURL extension skipping 22 | - fix bad switch() from -r477 in RTMP_Read 23 | - fix rtmpsrv to always use .flv extension on output 24 | - fix crash on socket failure while RTMP_Read() is reading header 25 | - fix RTMP_ReadPacket signed/unsigned chars for m_nChannel 26 | - license cleanup, use current FSF address 27 | - fix RTMP_SetupURL tcUrl generation 28 | - ignore multiple spaces between URL options 29 | - only send CheckBW request once per session 30 | 31 | 29 May 2010, v2.2e 32 | - port to Xbox 33 | - add explicit URL scheme for rtmpts 34 | - fix rtmpt clientID NUL-termination 35 | - use BufferEmpty trick in rtmpdump but not by default in librtmp 36 | - add librtmp manpage 37 | - fix RTMP_Read, return 0 on EOF, not -1 38 | - change RTMP_Read to return 1 packet at a time, fix buffer mgmt 39 | - fix request/result queue, fix server compatibility for Publishing 40 | - add RTMP_EnableWrite to enable Publishing 41 | 42 | 29 April 2010, v2.2d 43 | - add RTMP_Alloc, RTMP_Free APIs 44 | - add optional support for polarssl instead of OpenSSL 45 | - add option to build crypto support without SSL/TLS 46 | - tweak handshake offset checking 47 | - add RTMP set_playlist command 48 | - check for (and fix) broken timestamps in FLV packets 49 | - fix tcUrl and playpath parsing in rtmpsrv and rtmpsuck 50 | - change internal boolean flags to bitmasks 51 | 52 | 14 April 2010, v2.2c 53 | - internal restructuring, fix #undef CRYPTO builds 54 | - add RTMP_SetupURL, RTMP_SetOpt APIs 55 | - add logging callback 56 | 57 | 22 March 2010, v2.2b 58 | - fix v2.2a crashes in rtmpsrv/rtmpsuck 59 | - fix v2.2a .swfinfo location on Windows 60 | - fix typo for --auth parameter in manpages 61 | - add FP10 handshake support for rtmpsrv/rtmpsuck 62 | - avoid GNUMake vs BSDMake incompatibilities 63 | - add pkgconfig file for librtmp 64 | - more library cleanup 65 | 66 | 20 March 2010, v2.2a 67 | - fix C++ compatibility for librtmp 68 | - misc library restructuring 69 | - add client support for tunneling: rtmpt, rtmpte, rtmps 70 | - fix rtmpdump/rtmpgw FLV header dataType 71 | - implement RTMP_Read() and RTMP_Write() to simplify library use 72 | - fix SendPacket timestamps 73 | - add optional support for GnuTLS/Gcrypt instead of OpenSSL 74 | - use $HOMEPATH on Windows instead of $HOME for .swfinfo 75 | 76 | 4 March 2010, v2.2 77 | - move RTMP code into library librtmp 78 | - relicense RTMP code under LGPL v2.1 79 | - add rtmpdump manpage 80 | - fix AMF_LONG_STRING handling 81 | - more FlashPlayer 10 handshake support 82 | - in rtmpsrv fix Play Start/Stop messages 83 | - rename "streams" program to "rtmpgw" 84 | 85 | 20 February 2010, v2.1d 86 | - extend .swfinfo file format, add --swfAge rtmpdump parameter 87 | old file should be replaced or manually updated: copy the 88 | "date:" line and rename it to "ctim:" 89 | 90 | - fix MacOSX builds - just use "make posix" now for all Unix-derived systems 91 | - more explicit error checks in HTTP_get() 92 | - in rtmpsrv spawn rtmpdump automatically 93 | - fix bug in retry/resume of audio-only streams 94 | - other minor misc. fixes 95 | 96 | 9 January 2010, v2.1c 97 | - cleanup rtmpsrv output 98 | - fix crash in 2.1b hashswf 99 | - fix parseurl to url-decode PlayPath 100 | - fix parseurl to recognize extensions followed by URL params 101 | - fix Makefile, inadvertently dropped 'v' from version string 102 | - in rtmpdump try Reconnect if ToggleStream doesn't work on timeouts 103 | - in rtmpsuck use chunk-based I/O for better latency 104 | - in rtmpsuck support lists of streams 105 | - in rtmpsuck use raw client connect packet to workaround unsupported features 106 | - support arbitrary AMF data appended to connect requests 107 | 108 | 4 January 2010, v2.1b 109 | - fix url matching in .swfinfo lookup 110 | - fix resume parsing in rtmpdump 111 | - minor code cleanup (CRYPTO dependencies, logging) 112 | - add getStreamLength recognition to rtmpsrv 113 | - add close processing in rtmpsuck 114 | 115 | 1 January 2010, v2.1a 116 | - fix socket receive timeouts for WIN32 117 | - add streams description to README 118 | 119 | 29 December 2009, v2.1 120 | - AMF cleanup: bounds checking for all encoders, moved AMF_EncodeNamed* from rtmp.c 121 | - added SecureToken support 122 | - added automatic SWF hash calculation 123 | - added server-side handshake processing 124 | - added rtmpsrv stub server example 125 | - added rtmpsuck proxy server 126 | - tweaks for logging 127 | - renamed more functions to cleanup namespace for library use 128 | - tweaks for server operation: objectEncoding, chunksize changes 129 | 130 | 16 December 2009, v2.0 131 | - rewrote everything else in C, reorganized to make it usable again as a library 132 | - fixed more portability bugs 133 | - plugged memory leaks 134 | 135 | 2 December 2009, v1.9a 136 | - fix auth string typo 137 | - handle FCUnsubscribe message 138 | - don't try retry on live streams 139 | - SIGPIPE portability fix 140 | - remove "not supported" comment for RTMPE 141 | 142 | 13 November 2009, v1.9 143 | - Handle more signals to reduce risk of unresumable/corrupted partially streamed files 144 | - Fixed >2GB file handling 145 | - Added --hashes option for a hash progress bar instead of byte counter 146 | - Fix to allow win32 to use binary mode on stdout. 147 | - Added auto-unpause for buffer-limited streams 148 | 149 | 1 November 2009, v1.7 150 | 151 | - added --subscribe option for subscribing to a stream 152 | - added --start / --stop options for specifying endpoints of a stream 153 | - added --debug / --quiet / --verbose options for controlling output 154 | 155 | - added SOCKS4 support (by Monsieur Video) 156 | 157 | - restructured to support auto-restart of timed-out streams 158 | 159 | - rewritten byteswapping, works on all platforms 160 | 161 | - fixed errors in command / result parsing 162 | 163 | - support functions rewritten in C to avoid g++ compiler bugs on ARM 164 | 165 | - support for 65600 channels instead of just 64 166 | 167 | - fixed signature buffer overruns 168 | 169 | 17 May 2009, v1.6 170 | 171 | - big endian alignment fix, should fix sparc64 and others 172 | 173 | - moved timestamp handling into RTMP protocol innings, all packets have 174 | absolute timestamps now, when seeking the stream will start with timestamp 0 175 | even if seeked to a later position! 176 | 177 | - fixed a timestamp bug (should fix async audio/video problems) 178 | 179 | 30 Apr 2009, v1.5a 180 | 181 | - fixed host name resolution bug (caused unexpected crashes if DNS resolution 182 | was not available) 183 | 184 | - also using the hostname in tcUrl instead of the IP turns out to give much 185 | better results 186 | 187 | 27 Apr 2009, v1.5 188 | 189 | - RTMPE support (tested on Adobe 3.0.2,3.0.3,3.5.1, Wowza) 190 | 191 | - SWFVerification (tested on Adobe 3.0.2,3.0.3,3.5.1) 192 | 193 | - added AMF3 parsing support (experimental feauture, only some primitives, no references) 194 | 195 | - added -o - option which allows the stream to be dumped to stdout 196 | (debug/error messages go to stderr) 197 | 198 | - added --live option to enable download of live streams 199 | 200 | - added support for (Free)BSD and Mac (untested, so might need more fixing, 201 | especially for PPC/sparc64) 202 | 203 | - fixed a bug in url parsing 204 | 205 | - added a useful application: streams, it will start a streaming server and 206 | using a request like http://localhost/?r=rtmp://.... you can restream the 207 | content to your player over http 208 | 209 | 11 Mar 2009, v1.4 210 | 211 | - fixed resume bug: when the server switches between audio/video packets and FLV 212 | chunk packets (why should a server want to do that? some actually do!) and rtmpdump 213 | was invoked with --resume the keyframe check prevented rtmpdump from continuing 214 | 215 | - fixed endianness 216 | 217 | - added win32 and arm support (you can cross-compile it onto your Windows box 218 | or even PDA) 219 | 220 | - removed libboost dependency, written a small parser for rtmp urls, but it is 221 | more of a heuristic one since the rtmp urls can be ambigous in some 222 | circumstances. The best way is to supply all prameters using the override 223 | options like --play, --app, etc. 224 | 225 | - fixed stream ids (from XBMC tree) 226 | 227 | 19 Jan 2009, v1.3b 228 | 229 | - fixed segfault on Mac OS/BSDdue to times(0) 230 | 231 | - Makefile rewritten 232 | 233 | 16 Jan 2009, v1.3a 234 | 235 | - fixed a bug introduced in v1.3 (wrong report bytes count), downloads won't 236 | hang anymore 237 | 238 | 10 Jan 2009, v1.3 239 | 240 | - fixed audio only streams (rtmpdump now recognizes the stream and writes a 241 | correct tag, audio, video, audio+video) 242 | 243 | - improved resume function to wait till a the seek is executed by the server. 244 | The server might send playback data before seeking, so we ignore up to e.g. 50 245 | frames and keep waiting for a keyframe with a timestamp of zero. 246 | 247 | - nevertheless resuming does not always work since the server sometimes 248 | doesn't resend the keyframe, seeking in flash is unreliable 249 | 250 | 02 Jan 2009, v1.2a 251 | 252 | - fixed non-standard rtmp urls (including characters + < > ; ) 253 | 254 | - added small script get_hulu which can download hulu.com streams (US only) 255 | (many thanks to Richard Ablewhite for the help with hulu.com) 256 | 257 | 01 Jan 2009, v1.2: 258 | 259 | - fixed FLV streams (support for resuming extended) 260 | 261 | - fixed hanging download at the end 262 | 263 | - several minor bugfixes 264 | 265 | - changed parameter behaviour: not supplied parameters are omitted from the 266 | connect packet, --auth is introduced (was automatically obtained from url 267 | before, but it is possible to have an auth in the tcurl/rtmp url only without 268 | an additional encoded string in the connect packet) 269 | 270 | 28 Dec 2008, v1.1a: 271 | 272 | - fixed warnings, added -Wall to Makefile 273 | 274 | 28 Dec 2008, v1.1: 275 | 276 | - fixed stucking downloads (the buffer time is set to the duration now, 277 | so the server doesn't wait till the buffer is emptied 278 | 279 | - added a --resume option to coninue incomplete downloads 280 | 281 | - added support for AMF_DATE (experimental, no stream to test so far) 282 | 283 | - fixed AMF parsing and several small bugs (works on 64bit platforms now) 284 | 285 | 24 Dec 2008, v1.0: 286 | 287 | - First release 288 | 289 | -------------------------------------------------------------------------------- /rtmpgw.8.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | RTMPGW(8): 4 | 5 | 6 | 8 | 9 | 11 |
RTMPGW(8)RTMPGW(8) 7 |
RTMPDump v2.42011-07-20RTMPGW(8) 10 |


    12 | 14 |
15 | 16 |

NAME

    17 | rtmpgw − RTMP streaming media gateway 18 |
19 | 20 |

SYNOPSIS

    21 | rtmpgw 22 | [−r url] 23 | [−n hostname] 24 | [−c port] 25 | [−l protocol] 26 | [−S host:port] 27 | [−a app] 28 | [−t tcUrl] 29 | [−p pageUrl] 30 | [−s swfUrl] 31 | [−f flashVer] 32 | [−u auth] 33 | [−C conndata] 34 | [−y playpath] 35 | [−v] 36 | [−d subscription] 37 | [−e] 38 | [−k skip] 39 | [−A start] 40 | [−B stop] 41 | [−b buffer] 42 | [−m timeout] 43 | [−T key] 44 | [−j JSON] 45 | [−w swfHash] 46 | [−x swfSize] 47 | [−W swfUrl] 48 | [−X swfAge] 49 | [−D address] 50 | [−g port] 51 | [−q] 52 | [−V] 53 | [−z] 54 |
    55 | rtmpgw −h 56 |
57 | 58 |

DESCRIPTION

    59 | rtmpgw 60 | is a server for streaming media content from RTMP out to HTTP. 61 |

    62 | rtmpgw 63 | listens for HTTP requests that specify RTMP stream parameters and 64 | then returns the RTMP data in the HTTP response. The only valid 65 | HTTP request is "GET /" but additional options can be provided 66 | in URL-encoded fashion. Options specified on the command line will 67 | be used as defaults, which can be overridden by options in the HTTP 68 | request. 69 |

70 | 71 |

OPTIONS

    72 |
73 | 74 |

Network Parameters

    75 | These options define how to connect to the media server. 76 |

    77 |

    78 | −−rtmp −r url 79 |
    80 | URL of the server and media content. 81 |
    82 |

    83 |

    84 | −−host −n hostname 85 |
    86 | Overrides the hostname in the RTMP URL. 87 |
    88 |

    89 |

    90 | −−port −c port 91 |
    92 | Overrides the port number in the RTMP URL. 93 |
    94 |

    95 |

    96 | −−protocol −l number 97 |
    98 | Overrides the protocol in the RTMP URL. 99 |
    100 |   0 = rtmp
    101 |   1 = rtmpt
    102 |   2 = rtmpe
    103 |   3 = rtmpte
    104 |   4 = rtmps
    105 |   5 = rtmpts
    106 | 
    107 |
    108 |

    109 |

    110 | −−socks −S host:port 111 |
    112 | Use the specified SOCKS4 proxy. 113 |
    114 |
115 | 116 |

Connection Parameters

    117 | These options define the content of the RTMP Connect request packet. 118 | If correct values are not provided, the media server will reject the 119 | connection attempt. 120 |

    121 |

    122 | −−app −a app 123 |
    124 | Name of application to connect to on the RTMP server. Overrides 125 | the app in the RTMP URL. Sometimes the rtmpdump URL parser cannot 126 | determine the app name automatically, so it must be given explicitly 127 | using this option. 128 |
    129 |

    130 |

    131 | −−tcUrl −t url 132 |
    133 | URL of the target stream. Defaults to rtmp[e]://host[:port]/app/playpath. 134 |
    135 |

    136 |

    137 | −−pageUrl −p url 138 |
    139 | URL of the web page in which the media was embedded. By default no 140 | value will be sent. 141 |
    142 |

    143 |

    144 | −−swfUrl −s url 145 |
    146 | URL of the SWF player for the media. By default no value will be sent. 147 |
    148 |

    149 |

    150 | −−flashVer −f version 151 |
    152 | Version of the Flash plugin used to run the SWF player. The 153 | default is "LNX 10,0,32,18". 154 |
    155 |

    156 |

    157 | −−auth −u string 158 |
    159 | An authentication string to be appended to the Connect message. Using 160 | this option will append a Boolean TRUE and then the specified string. 161 | This option is only used by some particular servers and is 162 | deprecated. The more general 163 | −−conn 164 | option should be used instead. 165 |
    166 |

    167 |

    168 | −−conn −C type:data 169 |
    170 | Append arbitrary AMF data to the Connect message. The type 171 | must be B for Boolean, N for number, S for string, O for object, or Z 172 | for null. For Booleans the data must be either 0 or 1 for FALSE or TRUE, 173 | respectively. Likewise for Objects the data must be 0 or 1 to end or 174 | begin an object, respectively. Data items in subobjects may be named, by 175 | prefixing the type with 'N' and specifying the name before the value, e.g. 176 | NB:myFlag:1. This option may be used multiple times to construct arbitrary 177 | AMF sequences. E.g. 178 |
    179 |   −C B:1 −C S:authMe −C O:1 −C NN:code:1.23 −C NS:flag:ok −C O:0
    180 | 
    181 |
    182 |
183 | 184 |

Session Parameters

    185 | These options take effect after the Connect request has succeeded. 186 |

    187 |

    188 | −−playpath −y path 189 |
    190 | Overrides the playpath parsed from the RTMP URL. Sometimes the 191 | rtmpdump URL parser cannot determine the correct playpath 192 | automatically, so it must be given explicitly using this option. 193 |
    194 |

    195 |

    196 | −−live −v 197 |
    198 | Specify that the media is a live stream. No resuming or seeking in 199 | live streams is possible. 200 |
    201 |

    202 |

    203 | −−subscribe −d stream 204 |
    205 | Name of live stream to subscribe to. Defaults to 206 | playpath. 207 |
    208 |

    209 |

    210 | −−start −A num 211 |
    212 | Start at 213 | num 214 | seconds into the stream. Not valid for live streams. 215 |
    216 |

    217 |

    218 | −−stop −B num 219 |
    220 | Stop at 221 | num 222 | seconds into the stream. 223 |
    224 |

    225 |

    226 | −−buffer −b num 227 |
    228 | Set buffer time to 229 | num 230 | milliseconds. The default is 20000. 231 |
    232 |

    233 |

    234 | −−timeout −m num 235 |
    236 | Timeout the session after 237 | num 238 | seconds without receiving any data from the server. The default is 120. 239 |
    240 |
241 | 242 |

Security Parameters

    243 | These options handle additional authentication requests from the server. 244 |

    245 |

    246 | −−token −T key 247 |
    248 | Key for SecureToken response, used if the server requires SecureToken 249 | authentication. 250 |
    251 |

    252 |

    253 | −−jtv −j JSON 254 |
    255 | JSON token used by legacy Justin.tv servers. Invokes NetStream.Authenticate.UsherToken 256 |
    257 |

    258 |

    259 | −−swfhash −w hexstring 260 |
    261 | SHA256 hash of the decompressed SWF file. This option may be needed if 262 | the server uses SWF Verification, but see the 263 | −−swfVfy 264 | option below. The hash is 32 bytes, and must be 265 | given in hexadecimal. The 266 | −−swfsize 267 | option must always be used with this option. 268 |
    269 |

    270 |

    271 | −−swfsize −x num 272 |
    273 | Size of the decompressed SWF file. This option may be needed if the 274 | server uses SWF Verification, but see the 275 | −−swfVfy 276 | option below. The 277 | −−swfhash 278 | option must always be used with this option. 279 |
    280 |

    281 |

    282 | −−swfVfy −W url 283 |
    284 | URL of the SWF player for this media. This option replaces all three 285 | of the 286 | −−swfUrl, 287 | −−swfhash, 288 | and 289 | −−swfsize 290 | options. When this option is used, the SWF player is retrieved from the 291 | specified URL and the hash and size are computed automatically. Also 292 | the information is cached in a 293 | .swfinfo 294 | file in the user's home directory, so that it doesn't need to be retrieved 295 | and recalculated every time rtmpdump is run. The .swfinfo file records 296 | the URL, the time it was fetched, the modification timestamp of the SWF 297 | file, its size, and its hash. By default, the cached info will be used 298 | for 30 days before re-checking. 299 |
    300 |

    301 |

    302 | −−swfAge −X days 303 |
    304 | Specify how many days to use the cached SWF info before re-checking. Use 305 | 0 to always check the SWF URL. Note that if the check shows that the 306 | SWF file has the same modification timestamp as before, it will not be 307 | retrieved again. 308 |
    309 |
310 | 311 |

Miscellaneous

    312 |

    313 |

    314 | −−device −D address 315 |
    316 | Listener IP address. The default is 0.0.0.0, i.e., any IP address. 317 |
    318 |

    319 |

    320 | −−sport −g port 321 |
    322 | Listener port. The default is 80. 323 |
    324 |

    325 |

    326 | −−quiet −q 327 |
    328 | Suppress all command output. 329 |
    330 |

    331 |

    332 | −−verbose −V 333 |
    334 | Verbose command output. 335 |
    336 |

    337 |

    338 | −−debug −z 339 |
    340 | Debug level output. Extremely verbose, including hex dumps of all packet data. 341 |
    342 |

    343 |

    344 | −−help −h 345 |
    346 | Print a summary of command options. 347 |
    348 |
349 | 350 |

EXAMPLES

    351 | The HTTP request 352 |
    353 | 	GET /?r=rtmp:%2f%2fserver%2fmyapp&y=somefile HTTP/1.0
    354 | 
    355 | is equivalent to the 356 | rtrmpdump(1) 357 | invocation 358 |
    359 | 	rtmpdump −r rtmp://server/myapp −y somefile
    360 | 
    361 |

    362 | Note that only the shortform (single letter) options are supported. 363 |

364 | 365 |

ENVIRONMENT

    366 |

    367 |

    368 | HOME 369 |
    370 | The value of 371 | $HOME 372 | is used as the location for the 373 | .swfinfo 374 | file. 375 |
    376 |
377 | 378 |

FILES

    379 |

    380 |

    381 | $HOME/.swfinfo 382 |
    383 | Cache of SWF Verification information 384 |
    385 |
386 | 387 |

SEE ALSO

390 | 391 |

AUTHORS

396 | -------------------------------------------------------------------------------- /librtmp/rtmp.h: -------------------------------------------------------------------------------- 1 | #ifndef __RTMP_H__ 2 | #define __RTMP_H__ 3 | /* 4 | * Copyright (C) 2005-2008 Team XBMC 5 | * http://www.xbmc.org 6 | * Copyright (C) 2008-2009 Andrej Stepanchuk 7 | * Copyright (C) 2009-2010 Howard Chu 8 | * 9 | * This file is part of librtmp. 10 | * 11 | * librtmp is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU Lesser General Public License as 13 | * published by the Free Software Foundation; either version 2.1, 14 | * or (at your option) any later version. 15 | * 16 | * librtmp is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU Lesser General Public License 22 | * along with librtmp see the file COPYING. If not, write to 23 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 24 | * Boston, MA 02110-1301, USA. 25 | * http://www.gnu.org/copyleft/lgpl.html 26 | */ 27 | 28 | #if !defined(NO_CRYPTO) && !defined(CRYPTO) 29 | #define CRYPTO 30 | #endif 31 | 32 | #include 33 | #include 34 | #include 35 | 36 | #include "amf.h" 37 | 38 | #ifdef __cplusplus 39 | extern "C" 40 | { 41 | #endif 42 | 43 | #define RTMP_LIB_VERSION 0x020300 /* 2.3 */ 44 | 45 | #define RTMP_FEATURE_HTTP 0x01 46 | #define RTMP_FEATURE_ENC 0x02 47 | #define RTMP_FEATURE_SSL 0x04 48 | #define RTMP_FEATURE_MFP 0x08 /* not yet supported */ 49 | #define RTMP_FEATURE_WRITE 0x10 /* publish, not play */ 50 | #define RTMP_FEATURE_HTTP2 0x20 /* server-side rtmpt */ 51 | 52 | #define RTMP_PROTOCOL_UNDEFINED -1 53 | #define RTMP_PROTOCOL_RTMP 0 54 | #define RTMP_PROTOCOL_RTMPE RTMP_FEATURE_ENC 55 | #define RTMP_PROTOCOL_RTMPT RTMP_FEATURE_HTTP 56 | #define RTMP_PROTOCOL_RTMPS RTMP_FEATURE_SSL 57 | #define RTMP_PROTOCOL_RTMPTE (RTMP_FEATURE_HTTP|RTMP_FEATURE_ENC) 58 | #define RTMP_PROTOCOL_RTMPTS (RTMP_FEATURE_HTTP|RTMP_FEATURE_SSL) 59 | #define RTMP_PROTOCOL_RTMFP RTMP_FEATURE_MFP 60 | 61 | #define RTMP_DEFAULT_CHUNKSIZE 128 62 | 63 | /* needs to fit largest number of bytes recv() may return */ 64 | #define RTMP_BUFFER_CACHE_SIZE (16*1024) 65 | 66 | #define RTMP_CHANNELS 65600 67 | 68 | extern const char RTMPProtocolStringsLower[][7]; 69 | extern const AVal RTMP_DefaultFlashVer; 70 | extern int RTMP_ctrlC; 71 | 72 | uint32_t RTMP_GetTime(void); 73 | 74 | /* RTMP_PACKET_TYPE_... 0x00 */ 75 | #define RTMP_PACKET_TYPE_CHUNK_SIZE 0x01 76 | /* RTMP_PACKET_TYPE_... 0x02 */ 77 | #define RTMP_PACKET_TYPE_BYTES_READ_REPORT 0x03 78 | #define RTMP_PACKET_TYPE_CONTROL 0x04 79 | #define RTMP_PACKET_TYPE_SERVER_BW 0x05 80 | #define RTMP_PACKET_TYPE_CLIENT_BW 0x06 81 | /* RTMP_PACKET_TYPE_... 0x07 */ 82 | #define RTMP_PACKET_TYPE_AUDIO 0x08 83 | #define RTMP_PACKET_TYPE_VIDEO 0x09 84 | /* RTMP_PACKET_TYPE_... 0x0A */ 85 | /* RTMP_PACKET_TYPE_... 0x0B */ 86 | /* RTMP_PACKET_TYPE_... 0x0C */ 87 | /* RTMP_PACKET_TYPE_... 0x0D */ 88 | /* RTMP_PACKET_TYPE_... 0x0E */ 89 | #define RTMP_PACKET_TYPE_FLEX_STREAM_SEND 0x0F 90 | #define RTMP_PACKET_TYPE_FLEX_SHARED_OBJECT 0x10 91 | #define RTMP_PACKET_TYPE_FLEX_MESSAGE 0x11 92 | #define RTMP_PACKET_TYPE_INFO 0x12 93 | #define RTMP_PACKET_TYPE_SHARED_OBJECT 0x13 94 | #define RTMP_PACKET_TYPE_INVOKE 0x14 95 | /* RTMP_PACKET_TYPE_... 0x15 */ 96 | #define RTMP_PACKET_TYPE_FLASH_VIDEO 0x16 97 | 98 | #define RTMP_MAX_HEADER_SIZE 18 99 | 100 | #define RTMP_PACKET_SIZE_LARGE 0 101 | #define RTMP_PACKET_SIZE_MEDIUM 1 102 | #define RTMP_PACKET_SIZE_SMALL 2 103 | #define RTMP_PACKET_SIZE_MINIMUM 3 104 | 105 | typedef struct RTMPChunk 106 | { 107 | int c_headerSize; 108 | int c_chunkSize; 109 | char *c_chunk; 110 | char c_header[RTMP_MAX_HEADER_SIZE]; 111 | } RTMPChunk; 112 | 113 | typedef struct RTMPPacket 114 | { 115 | uint8_t m_headerType; 116 | uint8_t m_packetType; 117 | uint8_t m_hasAbsTimestamp; /* timestamp absolute or relative? */ 118 | int m_nChannel; 119 | uint32_t m_nTimeStamp; /* timestamp */ 120 | int32_t m_nInfoField2; /* last 4 bytes in a long header */ 121 | uint32_t m_nBodySize; 122 | uint32_t m_nBytesRead; 123 | RTMPChunk *m_chunk; 124 | char *m_body; 125 | } RTMPPacket; 126 | 127 | typedef struct RTMPSockBuf 128 | { 129 | int sb_socket; 130 | int sb_size; /* number of unprocessed bytes in buffer */ 131 | char *sb_start; /* pointer into sb_pBuffer of next byte to process */ 132 | char sb_buf[RTMP_BUFFER_CACHE_SIZE]; /* data read from socket */ 133 | int sb_timedout; 134 | void *sb_ssl; 135 | } RTMPSockBuf; 136 | 137 | void RTMPPacket_Reset(RTMPPacket *p); 138 | void RTMPPacket_Dump(RTMPPacket *p); 139 | int RTMPPacket_Alloc(RTMPPacket *p, int nSize); 140 | void RTMPPacket_Free(RTMPPacket *p); 141 | 142 | #define RTMPPacket_IsReady(a) ((a)->m_nBytesRead == (a)->m_nBodySize) 143 | 144 | typedef struct RTMP_LNK 145 | { 146 | AVal hostname; 147 | AVal sockshost; 148 | 149 | AVal playpath0; /* parsed from URL */ 150 | AVal playpath; /* passed in explicitly */ 151 | AVal tcUrl; 152 | AVal swfUrl; 153 | AVal swfHash; 154 | AVal pageUrl; 155 | AVal app; 156 | AVal auth; 157 | AVal flashVer; 158 | AVal subscribepath; 159 | AVal usherToken; 160 | AVal WeebToken; 161 | AVal token; 162 | AMFObject extras; 163 | int edepth; 164 | 165 | int seekTime; 166 | int stopTime; 167 | 168 | #define RTMP_LF_AUTH 0x0001 /* using auth param */ 169 | #define RTMP_LF_LIVE 0x0002 /* stream is live */ 170 | #define RTMP_LF_SWFV 0x0004 /* do SWF verification */ 171 | #define RTMP_LF_PLST 0x0008 /* send playlist before play */ 172 | #define RTMP_LF_BUFX 0x0010 /* toggle stream on BufferEmpty msg */ 173 | #define RTMP_LF_FTCU 0x0020 /* free tcUrl on close */ 174 | int lFlags; 175 | 176 | int swfAge; 177 | int swfSize; 178 | 179 | int protocol; 180 | int ConnectPacket; 181 | int CombineConnectPacket; 182 | int timeout; /* connection timeout in seconds */ 183 | AVal Extras; 184 | AVal HandshakeResponse; 185 | 186 | unsigned short socksport; 187 | unsigned short port; 188 | 189 | #ifdef CRYPTO 190 | #define RTMP_SWF_HASHLEN 32 191 | void *dh; /* for encryption */ 192 | void *rc4keyIn; 193 | void *rc4keyOut; 194 | 195 | uint32_t SWFSize; 196 | uint8_t SWFHash[RTMP_SWF_HASHLEN]; 197 | char SWFVerificationResponse[RTMP_SWF_HASHLEN+10]; 198 | #endif 199 | } RTMP_LNK; 200 | 201 | /* state for read() wrapper */ 202 | typedef struct RTMP_READ 203 | { 204 | char *buf; 205 | char *bufpos; 206 | unsigned int buflen; 207 | uint32_t timestamp; 208 | uint8_t dataType; 209 | uint8_t flags; 210 | #define RTMP_READ_HEADER 0x01 211 | #define RTMP_READ_RESUME 0x02 212 | #define RTMP_READ_NO_IGNORE 0x04 213 | #define RTMP_READ_GOTKF 0x08 214 | #define RTMP_READ_GOTFLVK 0x10 215 | #define RTMP_READ_SEEKING 0x20 216 | int8_t status; 217 | #define RTMP_READ_COMPLETE -3 218 | #define RTMP_READ_ERROR -2 219 | #define RTMP_READ_EOF -1 220 | #define RTMP_READ_IGNORE 0 221 | 222 | /* if bResume == TRUE */ 223 | uint8_t initialFrameType; 224 | uint32_t nResumeTS; 225 | char *metaHeader; 226 | char *initialFrame; 227 | uint32_t nMetaHeaderSize; 228 | uint32_t nInitialFrameSize; 229 | uint32_t nIgnoredFrameCounter; 230 | uint32_t nIgnoredFlvFrameCounter; 231 | } RTMP_READ; 232 | 233 | typedef struct RTMP_METHOD 234 | { 235 | AVal name; 236 | int num; 237 | } RTMP_METHOD; 238 | 239 | typedef struct RTMP 240 | { 241 | int m_inChunkSize; 242 | int m_outChunkSize; 243 | int m_nBWCheckCounter; 244 | int m_nBytesIn; 245 | int m_nBytesInSent; 246 | int m_nBufferMS; 247 | int m_stream_id; /* returned in _result from createStream */ 248 | int m_mediaChannel; 249 | uint32_t m_mediaStamp; 250 | uint32_t m_pauseStamp; 251 | int m_pausing; 252 | int m_nServerBW; 253 | int m_nClientBW; 254 | uint8_t m_nClientBW2; 255 | uint8_t m_bPlaying; 256 | uint8_t m_bSendEncoding; 257 | uint8_t m_bSendCounter; 258 | 259 | int m_numInvokes; 260 | int m_numCalls; 261 | RTMP_METHOD *m_methodCalls; /* remote method calls queue */ 262 | 263 | RTMPPacket *m_vecChannelsIn[RTMP_CHANNELS]; 264 | RTMPPacket *m_vecChannelsOut[RTMP_CHANNELS]; 265 | int m_channelTimestamp[RTMP_CHANNELS]; /* abs timestamp of last packet */ 266 | 267 | double m_fAudioCodecs; /* audioCodecs for the connect packet */ 268 | double m_fVideoCodecs; /* videoCodecs for the connect packet */ 269 | double m_fEncoding; /* AMF0 or AMF3 */ 270 | 271 | double m_fDuration; /* duration of stream in seconds */ 272 | 273 | int m_msgCounter; /* RTMPT stuff */ 274 | int m_polling; 275 | int m_resplen; 276 | int m_unackd; 277 | AVal m_clientID; 278 | 279 | RTMP_READ m_read; 280 | RTMPPacket m_write; 281 | RTMPSockBuf m_sb; 282 | RTMP_LNK Link; 283 | } RTMP; 284 | 285 | int RTMP_ParseURL(const char *url, int *protocol, AVal *host, 286 | unsigned int *port, AVal *playpath, AVal *app); 287 | 288 | void RTMP_ParsePlaypath(AVal *in, AVal *out); 289 | void RTMP_SetBufferMS(RTMP *r, int size); 290 | void RTMP_UpdateBufferMS(RTMP *r); 291 | 292 | int RTMP_SetOpt(RTMP *r, const AVal *opt, AVal *arg); 293 | int RTMP_SetupURL(RTMP *r, char *url); 294 | void RTMP_SetupStream(RTMP *r, int protocol, 295 | AVal *hostname, 296 | unsigned int port, 297 | AVal *sockshost, 298 | AVal *playpath, 299 | AVal *tcUrl, 300 | AVal *swfUrl, 301 | AVal *pageUrl, 302 | AVal *app, 303 | AVal *auth, 304 | AVal *swfSHA256Hash, 305 | uint32_t swfSize, 306 | AVal *flashVer, 307 | AVal *subscribepath, 308 | AVal *usherToken, 309 | AVal *WeebToken, 310 | int dStart, 311 | int dStop, int bLiveStream, long int timeout); 312 | 313 | int RTMP_Connect(RTMP *r, RTMPPacket *cp); 314 | struct sockaddr; 315 | int RTMP_Connect0(RTMP *r, struct sockaddr *svc); 316 | int RTMP_Connect1(RTMP *r, RTMPPacket *cp); 317 | int RTMP_Serve(RTMP *r); 318 | 319 | int RTMP_ReadPacket(RTMP *r, RTMPPacket *packet); 320 | int RTMP_SendPacket(RTMP *r, RTMPPacket *packet, int queue); 321 | int RTMP_SendChunk(RTMP *r, RTMPChunk *chunk); 322 | int RTMP_IsConnected(RTMP *r); 323 | int RTMP_Socket(RTMP *r); 324 | int RTMP_IsTimedout(RTMP *r); 325 | double RTMP_GetDuration(RTMP *r); 326 | int RTMP_ToggleStream(RTMP *r); 327 | 328 | int RTMP_ConnectStream(RTMP *r, int seekTime); 329 | int RTMP_ReconnectStream(RTMP *r, int seekTime); 330 | void RTMP_DeleteStream(RTMP *r); 331 | int RTMP_GetNextMediaPacket(RTMP *r, RTMPPacket *packet); 332 | int RTMP_ClientPacket(RTMP *r, RTMPPacket *packet); 333 | 334 | void RTMP_Init(RTMP *r); 335 | void RTMP_Close(RTMP *r); 336 | RTMP *RTMP_Alloc(void); 337 | void RTMP_Free(RTMP *r); 338 | void RTMP_EnableWrite(RTMP *r); 339 | 340 | int RTMP_LibVersion(void); 341 | void RTMP_UserInterrupt(void); /* user typed Ctrl-C */ 342 | 343 | int RTMP_SendCtrl(RTMP *r, short nType, unsigned int nObject, 344 | unsigned int nTime); 345 | 346 | /* caller probably doesn't know current timestamp, should 347 | * just use RTMP_Pause instead 348 | */ 349 | int RTMP_SendPause(RTMP *r, int DoPause, int dTime); 350 | int RTMP_Pause(RTMP *r, int DoPause); 351 | 352 | int RTMP_FindFirstMatchingProperty(AMFObject *obj, const AVal *name, 353 | AMFObjectProperty * p); 354 | 355 | int RTMPSockBuf_Fill(RTMPSockBuf *sb); 356 | int RTMPSockBuf_Send(RTMPSockBuf *sb, const char *buf, int len); 357 | int RTMPSockBuf_Close(RTMPSockBuf *sb); 358 | 359 | int RTMP_SendCreateStream(RTMP *r); 360 | int RTMP_SendSeek(RTMP *r, int dTime); 361 | int RTMP_SendServerBW(RTMP *r); 362 | int RTMP_SendClientBW(RTMP *r); 363 | void RTMP_DropRequest(RTMP *r, int i, int freeit); 364 | int RTMP_Read(RTMP *r, char *buf, int size); 365 | int RTMP_Write(RTMP *r, const char *buf, int size); 366 | 367 | /* hashswf.c */ 368 | int RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash, 369 | int age); 370 | 371 | #ifdef __cplusplus 372 | }; 373 | #endif 374 | 375 | #endif 376 | -------------------------------------------------------------------------------- /rtmpdump.1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | RTMPDUMP(1): 4 | 5 | 6 | 8 | 9 | 11 |
RTMPDUMP(1)RTMPDUMP(1) 7 |
RTMPDump v2.42011-07-20RTMPDUMP(1) 10 |


    12 | 14 |
15 | 16 |

NAME

    17 | rtmpdump − RTMP streaming media client 18 |
19 | 20 |

SYNOPSIS

    21 | rtmpdump 22 | −r url 23 | [−n hostname] 24 | [−c port] 25 | [−l protocol] 26 | [−S host:port] 27 | [−a app] 28 | [−t tcUrl] 29 | [−p pageUrl] 30 | [−s swfUrl] 31 | [−f flashVer] 32 | [−u auth] 33 | [−C conndata] 34 | [−y playpath] 35 | [−Y] 36 | [−v] 37 | [−d subscription] 38 | [−e] 39 | [−k skip] 40 | [−A start] 41 | [−B stop] 42 | [−b buffer] 43 | [−m timeout] 44 | [−T key] 45 | [−j JSON] 46 | [−w swfHash] 47 | [−x swfSize] 48 | [−W swfUrl] 49 | [−X swfAge] 50 | [−o output] 51 | [−#] 52 | [−q] 53 | [−V] 54 | [−z] 55 |
    56 | rtmpdump −h 57 |
58 | 59 |

DESCRIPTION

    60 | rtmpdump 61 | is a tool for dumping media content streamed over RTMP. 62 |

    63 | rtmpdump 64 | makes a connection to the specified RTMP server and plays the media 65 | specified by the given 66 | url. 67 | The url should be of the form 68 |

     69 |   rtmp[t][e]://hostname[:port][/app[/playpath]]
     70 | 
    71 |

    72 | Plain rtmp, as well as tunneled and encrypted sessions are supported. 73 |

74 | 75 |

OPTIONS

    76 |
77 | 78 |

Network Parameters

    79 | These options define how to connect to the media server. 80 |

    81 |

    82 | −−rtmp −r url 83 |
    84 | URL of the server and media content. 85 |
    86 |

    87 |

    88 | −−host −n hostname 89 |
    90 | Overrides the hostname in the RTMP URL. 91 |
    92 |

    93 |

    94 | −−port −c port 95 |
    96 | Overrides the port number in the RTMP URL. 97 |
    98 |

    99 |

    100 | −−protocol −l number 101 |
    102 | Overrides the protocol in the RTMP URL. 103 |
    104 |   0 = rtmp
    105 |   1 = rtmpt
    106 |   2 = rtmpe
    107 |   3 = rtmpte
    108 |   4 = rtmps
    109 |   5 = rtmpts
    110 | 
    111 |
    112 |

    113 |

    114 | −−socks −S host:port 115 |
    116 | Use the specified SOCKS4 proxy. 117 |
    118 |
119 | 120 |

Connection Parameters

    121 | These options define the content of the RTMP Connect request packet. 122 | If correct values are not provided, the media server will reject the 123 | connection attempt. 124 |

    125 |

    126 | −−app −a app 127 |
    128 | Name of application to connect to on the RTMP server. Overrides 129 | the app in the RTMP URL. Sometimes the rtmpdump URL parser cannot 130 | determine the app name automatically, so it must be given explicitly 131 | using this option. 132 |
    133 |

    134 |

    135 | −−tcUrl −t url 136 |
    137 | URL of the target stream. Defaults to rtmp[e]://host[:port]/app/playpath. 138 |
    139 |

    140 |

    141 | −−pageUrl −p url 142 |
    143 | URL of the web page in which the media was embedded. By default no 144 | value will be sent. 145 |
    146 |

    147 |

    148 | −−swfUrl −s url 149 |
    150 | URL of the SWF player for the media. By default no value will be sent. 151 |
    152 |

    153 |

    154 | −−flashVer −f version 155 |
    156 | Version of the Flash plugin used to run the SWF player. The 157 | default is "LNX 10,0,32,18". 158 |
    159 |

    160 |

    161 | −−auth −u string 162 |
    163 | An authentication string to be appended to the Connect message. Using 164 | this option will append a Boolean TRUE and then the specified string. 165 | This option is only used by some particular servers and is 166 | deprecated. The more general 167 | −−conn 168 | option should be used instead. 169 |
    170 |

    171 |

    172 | −−conn −C type:data 173 |
    174 | Append arbitrary AMF data to the Connect message. The type 175 | must be B for Boolean, N for number, S for string, O for object, or Z 176 | for null. For Booleans the data must be either 0 or 1 for FALSE or TRUE, 177 | respectively. Likewise for Objects the data must be 0 or 1 to end or 178 | begin an object, respectively. Data items in subobjects may be named, by 179 | prefixing the type with 'N' and specifying the name before the value, e.g. 180 | NB:myFlag:1. This option may be used multiple times to construct arbitrary 181 | AMF sequences. E.g. 182 |
    183 |   −C B:1 −C S:authMe −C O:1 −C NN:code:1.23 −C NS:flag:ok −C O:0
    184 | 
    185 |
    186 |
187 | 188 |

Session Parameters

    189 | These options take effect after the Connect request has succeeded. 190 |

    191 |

    192 | −−playpath −y path 193 |
    194 | Overrides the playpath parsed from the RTMP URL. Sometimes the 195 | rtmpdump URL parser cannot determine the correct playpath 196 | automatically, so it must be given explicitly using this option. 197 |
    198 |

    199 |

    200 | −−playlist −Y 201 |
    202 | Issue a set_playlist command before sending the play command. The 203 | playlist will just contain the current playpath. 204 |
    205 |

    206 |

    207 | −−live −v 208 |
    209 | Specify that the media is a live stream. No resuming or seeking in 210 | live streams is possible. 211 |
    212 |

    213 |

    214 | −−subscribe −d stream 215 |
    216 | Name of live stream to subscribe to. Defaults to 217 | playpath. 218 |
    219 |

    220 |

    221 | −−resume −e 222 |
    223 | Resume an incomplete RTMP download. 224 |
    225 |

    226 |

    227 | −−skip −k num 228 |
    229 | Skip 230 | num 231 | keyframes when looking for the last keyframe from which to resume. This 232 | may be useful if a regular attempt to resume fails. The default is 0. 233 |
    234 |

    235 |

    236 | −−start −A num 237 |
    238 | Start at 239 | num 240 | seconds into the stream. Not valid for live streams. 241 |
    242 |

    243 |

    244 | −−stop −B num 245 |
    246 | Stop at 247 | num 248 | seconds into the stream. 249 |
    250 |

    251 |

    252 | −−buffer −b num 253 |
    254 | Set buffer time to 255 | num 256 | milliseconds. The default is 36000000. 257 |
    258 |

    259 |

    260 | −−timeout −m num 261 |
    262 | Timeout the session after 263 | num 264 | seconds without receiving any data from the server. The default is 120. 265 |
    266 |
267 | 268 |

Security Parameters

    269 | These options handle additional authentication requests from the server. 270 |

    271 |

    272 | −−token −T key 273 |
    274 | Key for SecureToken response, used if the server requires SecureToken 275 | authentication. 276 |
    277 |

    278 |

    279 | −−jtv −j JSON 280 |
    281 | JSON token used by legacy Justin.tv servers. Invokes NetStream.Authenticate.UsherToken 282 |
    283 |

    284 |

    285 | −−swfhash −w hexstring 286 |
    287 | SHA256 hash of the decompressed SWF file. This option may be needed if 288 | the server uses SWF Verification, but see the 289 | −−swfVfy 290 | option below. The hash is 32 bytes, and must be 291 | given in hexadecimal. The 292 | −−swfsize 293 | option must always be used with this option. 294 |
    295 |

    296 |

    297 | −−swfsize −x num 298 |
    299 | Size of the decompressed SWF file. This option may be needed if the 300 | server uses SWF Verification, but see the 301 | −−swfVfy 302 | option below. The 303 | −−swfhash 304 | option must always be used with this option. 305 |
    306 |

    307 |

    308 | −−swfVfy −W url 309 |
    310 | URL of the SWF player for this media. This option replaces all three 311 | of the 312 | −−swfUrl, 313 | −−swfhash, 314 | and 315 | −−swfsize 316 | options. When this option is used, the SWF player is retrieved from the 317 | specified URL and the hash and size are computed automatically. Also 318 | the information is cached in a 319 | .swfinfo 320 | file in the user's home directory, so that it doesn't need to be retrieved 321 | and recalculated every time rtmpdump is run. The .swfinfo file records 322 | the URL, the time it was fetched, the modification timestamp of the SWF 323 | file, its size, and its hash. By default, the cached info will be used 324 | for 30 days before re-checking. 325 |
    326 |

    327 |

    328 | −−swfAge −X days 329 |
    330 | Specify how many days to use the cached SWF info before re-checking. Use 331 | 0 to always check the SWF URL. Note that if the check shows that the 332 | SWF file has the same modification timestamp as before, it will not be 333 | retrieved again. 334 |
    335 |
336 | 337 |

Miscellaneous

    338 |

    339 |

    340 | −−flv −o output 341 |
    342 | Specify the output file name. If the name is − or is omitted, the 343 | stream is written to stdout. 344 |
    345 |

    346 |

    347 | −−hashes −# 348 |
    349 | Display streaming progress with a hash mark for each 1% of progress, instead 350 | of a byte counter. 351 |
    352 |

    353 |

    354 | −−quiet −q 355 |
    356 | Suppress all command output. 357 |
    358 |

    359 |

    360 | −−verbose −V 361 |
    362 | Verbose command output. 363 |
    364 |

    365 |

    366 | −−debug −z 367 |
    368 | Debug level output. Extremely verbose, including hex dumps of all packet data. 369 |
    370 |

    371 |

    372 | −−help −h 373 |
    374 | Print a summary of command options. 375 |
    376 |
377 | 378 |

EXIT STATUS

    379 |

    380 |

    381 | 0 382 |
    383 | Successful program execution. 384 |
    385 |

    386 |

    387 | 1 388 |
    389 | Unrecoverable error. 390 |
    391 |

    392 |

    393 | 2 394 |
    395 | Incomplete transfer, resuming may get further. 396 |
    397 |
398 | 399 |

ENVIRONMENT

    400 |

    401 |

    402 | HOME 403 |
    404 | The value of 405 | $HOME 406 | is used as the location for the 407 | .swfinfo 408 | file. 409 |
    410 |
411 | 412 |

FILES

    413 |

    414 |

    415 | $HOME/.swfinfo 416 |
    417 | Cache of SWF Verification information 418 |
    419 |
420 | 421 |

SEE ALSO

424 | 425 |

AUTHORS

430 | -------------------------------------------------------------------------------- /librtmp/hashswf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009-2010 Howard Chu 3 | * 4 | * This file is part of librtmp. 5 | * 6 | * librtmp is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License as 8 | * published by the Free Software Foundation; either version 2.1, 9 | * or (at your option) any later version. 10 | * 11 | * librtmp is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with librtmp see the file COPYING. If not, write to 18 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 | * Boston, MA 02110-1301, USA. 20 | * http://www.gnu.org/copyleft/lgpl.html 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include "rtmp_sys.h" 30 | #include "log.h" 31 | #include "http.h" 32 | 33 | #ifdef CRYPTO 34 | #ifdef USE_POLARSSL 35 | #include 36 | #ifndef SHA256_DIGEST_LENGTH 37 | #define SHA256_DIGEST_LENGTH 32 38 | #endif 39 | #define HMAC_CTX sha2_context 40 | #define HMAC_setup(ctx, key, len) sha2_hmac_starts(&ctx, (unsigned char *)key, len, 0) 41 | #define HMAC_crunch(ctx, buf, len) sha2_hmac_update(&ctx, buf, len) 42 | #define HMAC_finish(ctx, dig, dlen) dlen = SHA256_DIGEST_LENGTH; sha2_hmac_finish(&ctx, dig) 43 | #define HMAC_close(ctx) 44 | #elif defined(USE_GNUTLS) 45 | #include 46 | #include 47 | #ifndef SHA256_DIGEST_LENGTH 48 | #define SHA256_DIGEST_LENGTH 32 49 | #endif 50 | #define HMAC_CTX gcry_md_hd_t 51 | #define HMAC_setup(ctx, key, len) gcry_md_open(&ctx, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC); gcry_md_setkey(ctx, key, len) 52 | #define HMAC_crunch(ctx, buf, len) gcry_md_write(ctx, buf, len) 53 | #define HMAC_finish(ctx, dig, dlen) dlen = SHA256_DIGEST_LENGTH; memcpy(dig, gcry_md_read(ctx, 0), dlen) 54 | #define HMAC_close(ctx) gcry_md_close(ctx) 55 | #else /* USE_OPENSSL */ 56 | #include 57 | #include 58 | #include 59 | #include 60 | #define HMAC_setup(ctx, key, len) HMAC_CTX_init(&ctx); HMAC_Init_ex(&ctx, (unsigned char *)key, len, EVP_sha256(), 0) 61 | #define HMAC_crunch(ctx, buf, len) HMAC_Update(&ctx, (unsigned char *)buf, len) 62 | #define HMAC_finish(ctx, dig, dlen) HMAC_Final(&ctx, (unsigned char *)dig, &dlen); 63 | #define HMAC_close(ctx) HMAC_CTX_cleanup(&ctx) 64 | #endif 65 | 66 | extern void RTMP_TLS_Init(); 67 | extern TLS_CTX RTMP_TLS_ctx; 68 | 69 | #include 70 | 71 | #endif /* CRYPTO */ 72 | 73 | #define AGENT "Mozilla/5.0 (Windows NT 5.1; rv:8.0) Gecko/20100101 Firefox/8.0" 74 | 75 | HTTPResult 76 | HTTP_get(struct HTTP_ctx *http, const char *url, HTTP_read_callback *cb) 77 | { 78 | char *host, *path; 79 | char *p1, *p2; 80 | char hbuf[256]; 81 | int port = 80; 82 | #ifdef CRYPTO 83 | int ssl = 0; 84 | #endif 85 | int hlen, flen = 0; 86 | int rc, i; 87 | int len_known; 88 | HTTPResult ret = HTTPRES_OK; 89 | struct sockaddr_in sa; 90 | RTMPSockBuf sb = {0}; 91 | 92 | http->status = -1; 93 | 94 | memset(&sa, 0, sizeof(struct sockaddr_in)); 95 | sa.sin_family = AF_INET; 96 | 97 | /* we only handle http here */ 98 | if (strncasecmp(url, "http", 4)) 99 | return HTTPRES_BAD_REQUEST; 100 | 101 | if (url[4] == 's') 102 | { 103 | #ifdef CRYPTO 104 | ssl = 1; 105 | port = 443; 106 | if (!RTMP_TLS_ctx) 107 | RTMP_TLS_Init(); 108 | #else 109 | return HTTPRES_BAD_REQUEST; 110 | #endif 111 | } 112 | 113 | p1 = strchr(url + 4, ':'); 114 | if (!p1 || strncmp(p1, "://", 3)) 115 | return HTTPRES_BAD_REQUEST; 116 | 117 | host = p1 + 3; 118 | path = strchr(host, '/'); 119 | hlen = path - host; 120 | strncpy(hbuf, host, hlen); 121 | hbuf[hlen] = '\0'; 122 | host = hbuf; 123 | p1 = strrchr(host, ':'); 124 | if (p1) 125 | { 126 | *p1++ = '\0'; 127 | port = atoi(p1); 128 | } 129 | 130 | sa.sin_addr.s_addr = inet_addr(host); 131 | if (sa.sin_addr.s_addr == INADDR_NONE) 132 | { 133 | struct hostent *hp = gethostbyname(host); 134 | if (!hp || !hp->h_addr) 135 | return HTTPRES_LOST_CONNECTION; 136 | sa.sin_addr = *(struct in_addr *)hp->h_addr; 137 | } 138 | sa.sin_port = htons(port); 139 | sb.sb_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 140 | if (sb.sb_socket == -1) 141 | return HTTPRES_LOST_CONNECTION; 142 | i = 143 | sprintf(sb.sb_buf, 144 | "GET %s HTTP/1.0\r\nUser-Agent: %s\r\nHost: %s\r\nReferer: %.*s\r\n", 145 | path, AGENT, host, (int)(path - url + 1), url); 146 | if (http->date[0]) 147 | i += sprintf(sb.sb_buf + i, "If-Modified-Since: %s\r\n", http->date); 148 | i += sprintf(sb.sb_buf + i, "\r\n"); 149 | 150 | if (connect 151 | (sb.sb_socket, (struct sockaddr *)&sa, sizeof(struct sockaddr)) < 0) 152 | { 153 | ret = HTTPRES_LOST_CONNECTION; 154 | goto leave; 155 | } 156 | #ifdef CRYPTO 157 | if (ssl) 158 | { 159 | #ifdef NO_SSL 160 | RTMP_Log(RTMP_LOGERROR, "%s, No SSL/TLS support", __FUNCTION__); 161 | ret = HTTPRES_BAD_REQUEST; 162 | goto leave; 163 | #else 164 | TLS_client(RTMP_TLS_ctx, sb.sb_ssl); 165 | TLS_setfd(sb.sb_ssl, sb.sb_socket); 166 | if (TLS_connect(sb.sb_ssl) < 0) 167 | { 168 | RTMP_Log(RTMP_LOGERROR, "%s, TLS_Connect failed", __FUNCTION__); 169 | ret = HTTPRES_LOST_CONNECTION; 170 | goto leave; 171 | } 172 | #endif 173 | } 174 | #endif 175 | RTMPSockBuf_Send(&sb, sb.sb_buf, i); 176 | 177 | /* set timeout */ 178 | #define HTTP_TIMEOUT 5 179 | { 180 | SET_RCVTIMEO(tv, HTTP_TIMEOUT); 181 | if (setsockopt 182 | (sb.sb_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv))) 183 | { 184 | RTMP_Log(RTMP_LOGERROR, "%s, Setting socket timeout to %ds failed!", 185 | __FUNCTION__, HTTP_TIMEOUT); 186 | } 187 | } 188 | 189 | sb.sb_size = 0; 190 | sb.sb_timedout = FALSE; 191 | if (RTMPSockBuf_Fill(&sb) < 1) 192 | { 193 | ret = HTTPRES_LOST_CONNECTION; 194 | goto leave; 195 | } 196 | if (strncmp(sb.sb_buf, "HTTP/1", 6)) 197 | { 198 | ret = HTTPRES_BAD_REQUEST; 199 | goto leave; 200 | } 201 | 202 | p1 = strchr(sb.sb_buf, ' '); 203 | rc = atoi(p1 + 1); 204 | http->status = rc; 205 | 206 | if (rc >= 300) 207 | { 208 | if (rc == 304) 209 | { 210 | ret = HTTPRES_OK_NOT_MODIFIED; 211 | goto leave; 212 | } 213 | else if (rc == 404) 214 | ret = HTTPRES_NOT_FOUND; 215 | else if (rc >= 500) 216 | ret = HTTPRES_SERVER_ERROR; 217 | else if (rc >= 400) 218 | ret = HTTPRES_BAD_REQUEST; 219 | else 220 | ret = HTTPRES_REDIRECTED; 221 | } 222 | 223 | p1 = memchr(sb.sb_buf, '\n', sb.sb_size); 224 | if (!p1) 225 | { 226 | ret = HTTPRES_BAD_REQUEST; 227 | goto leave; 228 | } 229 | sb.sb_start = p1 + 1; 230 | sb.sb_size -= sb.sb_start - sb.sb_buf; 231 | 232 | while ((p2 = memchr(sb.sb_start, '\r', sb.sb_size))) 233 | { 234 | if (*sb.sb_start == '\r') 235 | { 236 | sb.sb_start += 2; 237 | sb.sb_size -= 2; 238 | break; 239 | } 240 | else 241 | if (!strncasecmp 242 | (sb.sb_start, "Content-Length: ", sizeof("Content-Length: ") - 1)) 243 | { 244 | flen = atoi(sb.sb_start + sizeof("Content-Length: ") - 1); 245 | } 246 | else 247 | if (!strncasecmp 248 | (sb.sb_start, "Last-Modified: ", sizeof("Last-Modified: ") - 1)) 249 | { 250 | *p2 = '\0'; 251 | strcpy(http->date, sb.sb_start + sizeof("Last-Modified: ") - 1); 252 | } 253 | p2 += 2; 254 | sb.sb_size -= p2 - sb.sb_start; 255 | sb.sb_start = p2; 256 | if (sb.sb_size < 1) 257 | { 258 | if (RTMPSockBuf_Fill(&sb) < 1) 259 | { 260 | ret = HTTPRES_LOST_CONNECTION; 261 | goto leave; 262 | } 263 | } 264 | } 265 | 266 | len_known = flen > 0; 267 | while ((!len_known || flen > 0) && 268 | (sb.sb_size > 0 || RTMPSockBuf_Fill(&sb) > 0)) 269 | { 270 | cb(sb.sb_start, 1, sb.sb_size, http->data); 271 | if (len_known) 272 | flen -= sb.sb_size; 273 | http->size += sb.sb_size; 274 | sb.sb_size = 0; 275 | } 276 | 277 | if (flen > 0) 278 | ret = HTTPRES_LOST_CONNECTION; 279 | 280 | leave: 281 | RTMPSockBuf_Close(&sb); 282 | return ret; 283 | } 284 | 285 | #ifdef CRYPTO 286 | 287 | #define CHUNK 16384 288 | 289 | struct info 290 | { 291 | z_stream *zs; 292 | HMAC_CTX ctx; 293 | int first; 294 | int zlib; 295 | int size; 296 | }; 297 | 298 | static size_t 299 | swfcrunch(void *ptr, size_t size, size_t nmemb, void *stream) 300 | { 301 | struct info *i = stream; 302 | char *p = ptr; 303 | size_t len = size * nmemb; 304 | 305 | if (i->first) 306 | { 307 | i->first = 0; 308 | /* compressed? */ 309 | if (!strncmp(p, "CWS", 3)) 310 | { 311 | *p = 'F'; 312 | i->zlib = 1; 313 | } 314 | HMAC_crunch(i->ctx, (unsigned char *)p, 8); 315 | p += 8; 316 | len -= 8; 317 | i->size = 8; 318 | } 319 | 320 | if (i->zlib) 321 | { 322 | unsigned char out[CHUNK]; 323 | i->zs->next_in = (unsigned char *)p; 324 | i->zs->avail_in = len; 325 | do 326 | { 327 | i->zs->avail_out = CHUNK; 328 | i->zs->next_out = out; 329 | inflate(i->zs, Z_NO_FLUSH); 330 | len = CHUNK - i->zs->avail_out; 331 | i->size += len; 332 | HMAC_crunch(i->ctx, out, len); 333 | } 334 | while (i->zs->avail_out == 0); 335 | } 336 | else 337 | { 338 | i->size += len; 339 | HMAC_crunch(i->ctx, (unsigned char *)p, len); 340 | } 341 | return size * nmemb; 342 | } 343 | 344 | static int tzoff; 345 | static int tzchecked; 346 | 347 | #define JAN02_1980 318340800 348 | 349 | static const char *monthtab[12] = { "Jan", "Feb", "Mar", 350 | "Apr", "May", "Jun", 351 | "Jul", "Aug", "Sep", 352 | "Oct", "Nov", "Dec" 353 | }; 354 | static const char *days[] = 355 | { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; 356 | 357 | /* Parse an HTTP datestamp into Unix time */ 358 | static time_t 359 | make_unix_time(char *s) 360 | { 361 | struct tm time; 362 | int i, ysub = 1900, fmt = 0; 363 | char *month; 364 | char *n; 365 | time_t res; 366 | 367 | if (s[3] != ' ') 368 | { 369 | fmt = 1; 370 | if (s[3] != ',') 371 | ysub = 0; 372 | } 373 | for (n = s; *n; ++n) 374 | if (*n == '-' || *n == ':') 375 | *n = ' '; 376 | 377 | time.tm_mon = 0; 378 | n = strchr(s, ' '); 379 | if (fmt) 380 | { 381 | /* Day, DD-MMM-YYYY HH:MM:SS GMT */ 382 | time.tm_mday = strtol(n + 1, &n, 0); 383 | month = n + 1; 384 | n = strchr(month, ' '); 385 | time.tm_year = strtol(n + 1, &n, 0); 386 | time.tm_hour = strtol(n + 1, &n, 0); 387 | time.tm_min = strtol(n + 1, &n, 0); 388 | time.tm_sec = strtol(n + 1, NULL, 0); 389 | } 390 | else 391 | { 392 | /* Unix ctime() format. Does not conform to HTTP spec. */ 393 | /* Day MMM DD HH:MM:SS YYYY */ 394 | month = n + 1; 395 | n = strchr(month, ' '); 396 | while (isspace(*n)) 397 | n++; 398 | time.tm_mday = strtol(n, &n, 0); 399 | time.tm_hour = strtol(n + 1, &n, 0); 400 | time.tm_min = strtol(n + 1, &n, 0); 401 | time.tm_sec = strtol(n + 1, &n, 0); 402 | time.tm_year = strtol(n + 1, NULL, 0); 403 | } 404 | if (time.tm_year > 100) 405 | time.tm_year -= ysub; 406 | 407 | for (i = 0; i < 12; i++) 408 | if (!strncasecmp(month, monthtab[i], 3)) 409 | { 410 | time.tm_mon = i; 411 | break; 412 | } 413 | time.tm_isdst = 0; /* daylight saving is never in effect in GMT */ 414 | 415 | /* this is normally the value of extern int timezone, but some 416 | * braindead C libraries don't provide it. 417 | */ 418 | if (!tzchecked) 419 | { 420 | struct tm *tc; 421 | time_t then = JAN02_1980; 422 | tc = localtime(&then); 423 | tzoff = (12 - tc->tm_hour) * 3600 + tc->tm_min * 60 + tc->tm_sec; 424 | tzchecked = 1; 425 | } 426 | res = mktime(&time); 427 | /* Unfortunately, mktime() assumes the input is in local time, 428 | * not GMT, so we have to correct it here. 429 | */ 430 | if (res != -1) 431 | res += tzoff; 432 | return res; 433 | } 434 | 435 | /* Convert a Unix time to a network time string 436 | * Weekday, DD-MMM-YYYY HH:MM:SS GMT 437 | */ 438 | static void 439 | strtime(time_t * t, char *s) 440 | { 441 | struct tm *tm; 442 | 443 | tm = gmtime((time_t *) t); 444 | sprintf(s, "%s, %02d %s %d %02d:%02d:%02d GMT", 445 | days[tm->tm_wday], tm->tm_mday, monthtab[tm->tm_mon], 446 | tm->tm_year + 1900, tm->tm_hour, tm->tm_min, tm->tm_sec); 447 | } 448 | 449 | #define HEX2BIN(a) (((a)&0x40)?((a)&0xf)+9:((a)&0xf)) 450 | 451 | int 452 | RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash, 453 | int age) 454 | { 455 | FILE *f = NULL; 456 | char *path, date[64], cctim[64]; 457 | long pos = 0; 458 | time_t ctim = -1, cnow; 459 | int i, got = 0, ret = 0; 460 | unsigned int hlen; 461 | struct info in = { 0 }; 462 | struct HTTP_ctx http = { 0 }; 463 | HTTPResult httpres; 464 | z_stream zs = { 0 }; 465 | AVal home, hpre; 466 | 467 | date[0] = '\0'; 468 | #ifdef _WIN32 469 | #ifdef XBMC4XBOX 470 | hpre.av_val = "Q:"; 471 | hpre.av_len = 2; 472 | home.av_val = "\\UserData"; 473 | #else 474 | hpre.av_val = getenv("HOMEDRIVE"); 475 | hpre.av_len = strlen(hpre.av_val); 476 | home.av_val = getenv("HOMEPATH"); 477 | #endif 478 | #define DIRSEP "\\" 479 | 480 | #else /* !_WIN32 */ 481 | hpre.av_val = ""; 482 | hpre.av_len = 0; 483 | home.av_val = getenv("HOME"); 484 | #define DIRSEP "/" 485 | #endif 486 | if (!home.av_val) 487 | home.av_val = "."; 488 | home.av_len = strlen(home.av_val); 489 | 490 | /* SWF hash info is cached in a fixed-format file. 491 | * url: 492 | * ctim: HTTP datestamp of when we last checked it. 493 | * date: HTTP datestamp of the SWF's last modification. 494 | * size: SWF size in hex 495 | * hash: SWF hash in hex 496 | * 497 | * These fields must be present in this order. All fields 498 | * besides URL are fixed size. 499 | */ 500 | path = malloc(hpre.av_len + home.av_len + sizeof(DIRSEP ".swfinfo")); 501 | sprintf(path, "%s%s" DIRSEP ".swfinfo", hpre.av_val, home.av_val); 502 | 503 | f = fopen(path, "r+"); 504 | while (f) 505 | { 506 | char buf[4096], *file, *p; 507 | 508 | file = strchr(url, '/'); 509 | if (!file) 510 | break; 511 | file += 2; 512 | file = strchr(file, '/'); 513 | if (!file) 514 | break; 515 | file++; 516 | hlen = file - url; 517 | p = strrchr(file, '/'); 518 | if (p) 519 | file = p; 520 | else 521 | file--; 522 | 523 | while (fgets(buf, sizeof(buf), f)) 524 | { 525 | char *r1; 526 | 527 | got = 0; 528 | 529 | if (strncmp(buf, "url: ", 5)) 530 | continue; 531 | if (strncmp(buf + 5, url, strlen(buf + 5) - 1)) 532 | continue; 533 | r1 = strrchr(buf, '/'); 534 | i = strlen(r1); 535 | r1[--i] = '\0'; 536 | if (strncmp(r1, file, i)) 537 | continue; 538 | pos = ftell(f); 539 | while (got < 4 && fgets(buf, sizeof(buf), f)) 540 | { 541 | if (!strncmp(buf, "size: ", 6)) 542 | { 543 | *size = strtol(buf + 6, NULL, 16); 544 | got++; 545 | } 546 | else if (!strncmp(buf, "hash: ", 6)) 547 | { 548 | unsigned char *ptr = hash, *in = (unsigned char *)buf + 6; 549 | int l = strlen((char *)in) - 1; 550 | for (i = 0; i < l; i += 2) 551 | *ptr++ = (HEX2BIN(in[i]) << 4) | HEX2BIN(in[i + 1]); 552 | got++; 553 | } 554 | else if (!strncmp(buf, "date: ", 6)) 555 | { 556 | buf[strlen(buf) - 1] = '\0'; 557 | strncpy(date, buf + 6, sizeof(date)); 558 | got++; 559 | } 560 | else if (!strncmp(buf, "ctim: ", 6)) 561 | { 562 | buf[strlen(buf) - 1] = '\0'; 563 | ctim = make_unix_time(buf + 6); 564 | got++; 565 | } 566 | else if (!strncmp(buf, "url: ", 5)) 567 | break; 568 | } 569 | break; 570 | } 571 | break; 572 | } 573 | 574 | cnow = time(NULL); 575 | /* If we got a cache time, see if it's young enough to use directly */ 576 | if (age && ctim > 0) 577 | { 578 | ctim = cnow - ctim; 579 | ctim /= 3600 * 24; /* seconds to days */ 580 | if (ctim < age) /* ok, it's new enough */ 581 | goto out; 582 | } 583 | 584 | in.first = 1; 585 | HMAC_setup(in.ctx, "Genuine Adobe Flash Player 001", 30); 586 | inflateInit(&zs); 587 | in.zs = &zs; 588 | 589 | http.date = date; 590 | http.data = ∈ 591 | 592 | httpres = HTTP_get(&http, url, swfcrunch); 593 | 594 | inflateEnd(&zs); 595 | 596 | if (httpres != HTTPRES_OK && httpres != HTTPRES_OK_NOT_MODIFIED) 597 | { 598 | ret = -1; 599 | if (httpres == HTTPRES_LOST_CONNECTION) 600 | RTMP_Log(RTMP_LOGERROR, "%s: connection lost while downloading swfurl %s", 601 | __FUNCTION__, url); 602 | else if (httpres == HTTPRES_NOT_FOUND) 603 | RTMP_Log(RTMP_LOGERROR, "%s: swfurl %s not found", __FUNCTION__, url); 604 | else 605 | RTMP_Log(RTMP_LOGERROR, "%s: couldn't contact swfurl %s (HTTP error %d)", 606 | __FUNCTION__, url, http.status); 607 | } 608 | else 609 | { 610 | if (got && pos) 611 | fseek(f, pos, SEEK_SET); 612 | else 613 | { 614 | char *q; 615 | if (!f) 616 | f = fopen(path, "w"); 617 | if (!f) 618 | { 619 | int err = errno; 620 | RTMP_Log(RTMP_LOGERROR, 621 | "%s: couldn't open %s for writing, errno %d (%s)", 622 | __FUNCTION__, path, err, strerror(err)); 623 | ret = -1; 624 | goto out; 625 | } 626 | fseek(f, 0, SEEK_END); 627 | q = strchr(url, '?'); 628 | if (q) 629 | i = q - url; 630 | else 631 | i = strlen(url); 632 | 633 | fprintf(f, "url: %.*s\n", i, url); 634 | } 635 | strtime(&cnow, cctim); 636 | fprintf(f, "ctim: %s\n", cctim); 637 | 638 | if (!in.first) 639 | { 640 | HMAC_finish(in.ctx, hash, hlen); 641 | *size = in.size; 642 | 643 | fprintf(f, "date: %s\n", date); 644 | fprintf(f, "size: %08x\n", in.size); 645 | fprintf(f, "hash: "); 646 | for (i = 0; i < SHA256_DIGEST_LENGTH; i++) 647 | fprintf(f, "%02x", hash[i]); 648 | fprintf(f, "\n"); 649 | } 650 | } 651 | HMAC_close(in.ctx); 652 | out: 653 | free(path); 654 | if (f) 655 | fclose(f); 656 | return ret; 657 | } 658 | #else 659 | int 660 | RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash, 661 | int age) 662 | { 663 | return -1; 664 | } 665 | #endif 666 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /librtmp/COPYING: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 2.1, February 1999 3 | 4 | Copyright (C) 1991, 1999 Free Software Foundation, Inc. 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | [This is the first released version of the Lesser GPL. It also counts 10 | as the successor of the GNU Library Public License, version 2, hence 11 | the version number 2.1.] 12 | 13 | Preamble 14 | 15 | The licenses for most software are designed to take away your 16 | freedom to share and change it. By contrast, the GNU General Public 17 | Licenses are intended to guarantee your freedom to share and change 18 | free software--to make sure the software is free for all its users. 19 | 20 | This license, the Lesser General Public License, applies to some 21 | specially designated software packages--typically libraries--of the 22 | Free Software Foundation and other authors who decide to use it. You 23 | can use it too, but we suggest you first think carefully about whether 24 | this license or the ordinary General Public License is the better 25 | strategy to use in any particular case, based on the explanations below. 26 | 27 | When we speak of free software, we are referring to freedom of use, 28 | not price. Our General Public Licenses are designed to make sure that 29 | you have the freedom to distribute copies of free software (and charge 30 | for this service if you wish); that you receive source code or can get 31 | it if you want it; that you can change the software and use pieces of 32 | it in new free programs; and that you are informed that you can do 33 | these things. 34 | 35 | To protect your rights, we need to make restrictions that forbid 36 | distributors to deny you these rights or to ask you to surrender these 37 | rights. These restrictions translate to certain responsibilities for 38 | you if you distribute copies of the library or if you modify it. 39 | 40 | For example, if you distribute copies of the library, whether gratis 41 | or for a fee, you must give the recipients all the rights that we gave 42 | you. You must make sure that they, too, receive or can get the source 43 | code. If you link other code with the library, you must provide 44 | complete object files to the recipients, so that they can relink them 45 | with the library after making changes to the library and recompiling 46 | it. And you must show them these terms so they know their rights. 47 | 48 | We protect your rights with a two-step method: (1) we copyright the 49 | library, and (2) we offer you this license, which gives you legal 50 | permission to copy, distribute and/or modify the library. 51 | 52 | To protect each distributor, we want to make it very clear that 53 | there is no warranty for the free library. Also, if the library is 54 | modified by someone else and passed on, the recipients should know 55 | that what they have is not the original version, so that the original 56 | author's reputation will not be affected by problems that might be 57 | introduced by others. 58 | 59 | Finally, software patents pose a constant threat to the existence of 60 | any free program. We wish to make sure that a company cannot 61 | effectively restrict the users of a free program by obtaining a 62 | restrictive license from a patent holder. Therefore, we insist that 63 | any patent license obtained for a version of the library must be 64 | consistent with the full freedom of use specified in this license. 65 | 66 | Most GNU software, including some libraries, is covered by the 67 | ordinary GNU General Public License. This license, the GNU Lesser 68 | General Public License, applies to certain designated libraries, and 69 | is quite different from the ordinary General Public License. We use 70 | this license for certain libraries in order to permit linking those 71 | libraries into non-free programs. 72 | 73 | When a program is linked with a library, whether statically or using 74 | a shared library, the combination of the two is legally speaking a 75 | combined work, a derivative of the original library. The ordinary 76 | General Public License therefore permits such linking only if the 77 | entire combination fits its criteria of freedom. The Lesser General 78 | Public License permits more lax criteria for linking other code with 79 | the library. 80 | 81 | We call this license the "Lesser" General Public License because it 82 | does Less to protect the user's freedom than the ordinary General 83 | Public License. It also provides other free software developers Less 84 | of an advantage over competing non-free programs. These disadvantages 85 | are the reason we use the ordinary General Public License for many 86 | libraries. However, the Lesser license provides advantages in certain 87 | special circumstances. 88 | 89 | For example, on rare occasions, there may be a special need to 90 | encourage the widest possible use of a certain library, so that it becomes 91 | a de-facto standard. To achieve this, non-free programs must be 92 | allowed to use the library. A more frequent case is that a free 93 | library does the same job as widely used non-free libraries. In this 94 | case, there is little to gain by limiting the free library to free 95 | software only, so we use the Lesser General Public License. 96 | 97 | In other cases, permission to use a particular library in non-free 98 | programs enables a greater number of people to use a large body of 99 | free software. For example, permission to use the GNU C Library in 100 | non-free programs enables many more people to use the whole GNU 101 | operating system, as well as its variant, the GNU/Linux operating 102 | system. 103 | 104 | Although the Lesser General Public License is Less protective of the 105 | users' freedom, it does ensure that the user of a program that is 106 | linked with the Library has the freedom and the wherewithal to run 107 | that program using a modified version of the Library. 108 | 109 | The precise terms and conditions for copying, distribution and 110 | modification follow. Pay close attention to the difference between a 111 | "work based on the library" and a "work that uses the library". The 112 | former contains code derived from the library, whereas the latter must 113 | be combined with the library in order to run. 114 | 115 | GNU LESSER GENERAL PUBLIC LICENSE 116 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 117 | 118 | 0. This License Agreement applies to any software library or other 119 | program which contains a notice placed by the copyright holder or 120 | other authorized party saying it may be distributed under the terms of 121 | this Lesser General Public License (also called "this License"). 122 | Each licensee is addressed as "you". 123 | 124 | A "library" means a collection of software functions and/or data 125 | prepared so as to be conveniently linked with application programs 126 | (which use some of those functions and data) to form executables. 127 | 128 | The "Library", below, refers to any such software library or work 129 | which has been distributed under these terms. A "work based on the 130 | Library" means either the Library or any derivative work under 131 | copyright law: that is to say, a work containing the Library or a 132 | portion of it, either verbatim or with modifications and/or translated 133 | straightforwardly into another language. (Hereinafter, translation is 134 | included without limitation in the term "modification".) 135 | 136 | "Source code" for a work means the preferred form of the work for 137 | making modifications to it. For a library, complete source code means 138 | all the source code for all modules it contains, plus any associated 139 | interface definition files, plus the scripts used to control compilation 140 | and installation of the library. 141 | 142 | Activities other than copying, distribution and modification are not 143 | covered by this License; they are outside its scope. The act of 144 | running a program using the Library is not restricted, and output from 145 | such a program is covered only if its contents constitute a work based 146 | on the Library (independent of the use of the Library in a tool for 147 | writing it). Whether that is true depends on what the Library does 148 | and what the program that uses the Library does. 149 | 150 | 1. You may copy and distribute verbatim copies of the Library's 151 | complete source code as you receive it, in any medium, provided that 152 | you conspicuously and appropriately publish on each copy an 153 | appropriate copyright notice and disclaimer of warranty; keep intact 154 | all the notices that refer to this License and to the absence of any 155 | warranty; and distribute a copy of this License along with the 156 | Library. 157 | 158 | You may charge a fee for the physical act of transferring a copy, 159 | and you may at your option offer warranty protection in exchange for a 160 | fee. 161 | 162 | 2. You may modify your copy or copies of the Library or any portion 163 | of it, thus forming a work based on the Library, and copy and 164 | distribute such modifications or work under the terms of Section 1 165 | above, provided that you also meet all of these conditions: 166 | 167 | a) The modified work must itself be a software library. 168 | 169 | b) You must cause the files modified to carry prominent notices 170 | stating that you changed the files and the date of any change. 171 | 172 | c) You must cause the whole of the work to be licensed at no 173 | charge to all third parties under the terms of this License. 174 | 175 | d) If a facility in the modified Library refers to a function or a 176 | table of data to be supplied by an application program that uses 177 | the facility, other than as an argument passed when the facility 178 | is invoked, then you must make a good faith effort to ensure that, 179 | in the event an application does not supply such function or 180 | table, the facility still operates, and performs whatever part of 181 | its purpose remains meaningful. 182 | 183 | (For example, a function in a library to compute square roots has 184 | a purpose that is entirely well-defined independent of the 185 | application. Therefore, Subsection 2d requires that any 186 | application-supplied function or table used by this function must 187 | be optional: if the application does not supply it, the square 188 | root function must still compute square roots.) 189 | 190 | These requirements apply to the modified work as a whole. If 191 | identifiable sections of that work are not derived from the Library, 192 | and can be reasonably considered independent and separate works in 193 | themselves, then this License, and its terms, do not apply to those 194 | sections when you distribute them as separate works. But when you 195 | distribute the same sections as part of a whole which is a work based 196 | on the Library, the distribution of the whole must be on the terms of 197 | this License, whose permissions for other licensees extend to the 198 | entire whole, and thus to each and every part regardless of who wrote 199 | it. 200 | 201 | Thus, it is not the intent of this section to claim rights or contest 202 | your rights to work written entirely by you; rather, the intent is to 203 | exercise the right to control the distribution of derivative or 204 | collective works based on the Library. 205 | 206 | In addition, mere aggregation of another work not based on the Library 207 | with the Library (or with a work based on the Library) on a volume of 208 | a storage or distribution medium does not bring the other work under 209 | the scope of this License. 210 | 211 | 3. You may opt to apply the terms of the ordinary GNU General Public 212 | License instead of this License to a given copy of the Library. To do 213 | this, you must alter all the notices that refer to this License, so 214 | that they refer to the ordinary GNU General Public License, version 2, 215 | instead of to this License. (If a newer version than version 2 of the 216 | ordinary GNU General Public License has appeared, then you can specify 217 | that version instead if you wish.) Do not make any other change in 218 | these notices. 219 | 220 | Once this change is made in a given copy, it is irreversible for 221 | that copy, so the ordinary GNU General Public License applies to all 222 | subsequent copies and derivative works made from that copy. 223 | 224 | This option is useful when you wish to copy part of the code of 225 | the Library into a program that is not a library. 226 | 227 | 4. You may copy and distribute the Library (or a portion or 228 | derivative of it, under Section 2) in object code or executable form 229 | under the terms of Sections 1 and 2 above provided that you accompany 230 | it with the complete corresponding machine-readable source code, which 231 | must be distributed under the terms of Sections 1 and 2 above on a 232 | medium customarily used for software interchange. 233 | 234 | If distribution of object code is made by offering access to copy 235 | from a designated place, then offering equivalent access to copy the 236 | source code from the same place satisfies the requirement to 237 | distribute the source code, even though third parties are not 238 | compelled to copy the source along with the object code. 239 | 240 | 5. A program that contains no derivative of any portion of the 241 | Library, but is designed to work with the Library by being compiled or 242 | linked with it, is called a "work that uses the Library". Such a 243 | work, in isolation, is not a derivative work of the Library, and 244 | therefore falls outside the scope of this License. 245 | 246 | However, linking a "work that uses the Library" with the Library 247 | creates an executable that is a derivative of the Library (because it 248 | contains portions of the Library), rather than a "work that uses the 249 | library". The executable is therefore covered by this License. 250 | Section 6 states terms for distribution of such executables. 251 | 252 | When a "work that uses the Library" uses material from a header file 253 | that is part of the Library, the object code for the work may be a 254 | derivative work of the Library even though the source code is not. 255 | Whether this is true is especially significant if the work can be 256 | linked without the Library, or if the work is itself a library. The 257 | threshold for this to be true is not precisely defined by law. 258 | 259 | If such an object file uses only numerical parameters, data 260 | structure layouts and accessors, and small macros and small inline 261 | functions (ten lines or less in length), then the use of the object 262 | file is unrestricted, regardless of whether it is legally a derivative 263 | work. (Executables containing this object code plus portions of the 264 | Library will still fall under Section 6.) 265 | 266 | Otherwise, if the work is a derivative of the Library, you may 267 | distribute the object code for the work under the terms of Section 6. 268 | Any executables containing that work also fall under Section 6, 269 | whether or not they are linked directly with the Library itself. 270 | 271 | 6. As an exception to the Sections above, you may also combine or 272 | link a "work that uses the Library" with the Library to produce a 273 | work containing portions of the Library, and distribute that work 274 | under terms of your choice, provided that the terms permit 275 | modification of the work for the customer's own use and reverse 276 | engineering for debugging such modifications. 277 | 278 | You must give prominent notice with each copy of the work that the 279 | Library is used in it and that the Library and its use are covered by 280 | this License. You must supply a copy of this License. If the work 281 | during execution displays copyright notices, you must include the 282 | copyright notice for the Library among them, as well as a reference 283 | directing the user to the copy of this License. Also, you must do one 284 | of these things: 285 | 286 | a) Accompany the work with the complete corresponding 287 | machine-readable source code for the Library including whatever 288 | changes were used in the work (which must be distributed under 289 | Sections 1 and 2 above); and, if the work is an executable linked 290 | with the Library, with the complete machine-readable "work that 291 | uses the Library", as object code and/or source code, so that the 292 | user can modify the Library and then relink to produce a modified 293 | executable containing the modified Library. (It is understood 294 | that the user who changes the contents of definitions files in the 295 | Library will not necessarily be able to recompile the application 296 | to use the modified definitions.) 297 | 298 | b) Use a suitable shared library mechanism for linking with the 299 | Library. A suitable mechanism is one that (1) uses at run time a 300 | copy of the library already present on the user's computer system, 301 | rather than copying library functions into the executable, and (2) 302 | will operate properly with a modified version of the library, if 303 | the user installs one, as long as the modified version is 304 | interface-compatible with the version that the work was made with. 305 | 306 | c) Accompany the work with a written offer, valid for at 307 | least three years, to give the same user the materials 308 | specified in Subsection 6a, above, for a charge no more 309 | than the cost of performing this distribution. 310 | 311 | d) If distribution of the work is made by offering access to copy 312 | from a designated place, offer equivalent access to copy the above 313 | specified materials from the same place. 314 | 315 | e) Verify that the user has already received a copy of these 316 | materials or that you have already sent this user a copy. 317 | 318 | For an executable, the required form of the "work that uses the 319 | Library" must include any data and utility programs needed for 320 | reproducing the executable from it. However, as a special exception, 321 | the materials to be distributed need not include anything that is 322 | normally distributed (in either source or binary form) with the major 323 | components (compiler, kernel, and so on) of the operating system on 324 | which the executable runs, unless that component itself accompanies 325 | the executable. 326 | 327 | It may happen that this requirement contradicts the license 328 | restrictions of other proprietary libraries that do not normally 329 | accompany the operating system. Such a contradiction means you cannot 330 | use both them and the Library together in an executable that you 331 | distribute. 332 | 333 | 7. You may place library facilities that are a work based on the 334 | Library side-by-side in a single library together with other library 335 | facilities not covered by this License, and distribute such a combined 336 | library, provided that the separate distribution of the work based on 337 | the Library and of the other library facilities is otherwise 338 | permitted, and provided that you do these two things: 339 | 340 | a) Accompany the combined library with a copy of the same work 341 | based on the Library, uncombined with any other library 342 | facilities. This must be distributed under the terms of the 343 | Sections above. 344 | 345 | b) Give prominent notice with the combined library of the fact 346 | that part of it is a work based on the Library, and explaining 347 | where to find the accompanying uncombined form of the same work. 348 | 349 | 8. You may not copy, modify, sublicense, link with, or distribute 350 | the Library except as expressly provided under this License. Any 351 | attempt otherwise to copy, modify, sublicense, link with, or 352 | distribute the Library is void, and will automatically terminate your 353 | rights under this License. However, parties who have received copies, 354 | or rights, from you under this License will not have their licenses 355 | terminated so long as such parties remain in full compliance. 356 | 357 | 9. You are not required to accept this License, since you have not 358 | signed it. However, nothing else grants you permission to modify or 359 | distribute the Library or its derivative works. These actions are 360 | prohibited by law if you do not accept this License. Therefore, by 361 | modifying or distributing the Library (or any work based on the 362 | Library), you indicate your acceptance of this License to do so, and 363 | all its terms and conditions for copying, distributing or modifying 364 | the Library or works based on it. 365 | 366 | 10. Each time you redistribute the Library (or any work based on the 367 | Library), the recipient automatically receives a license from the 368 | original licensor to copy, distribute, link with or modify the Library 369 | subject to these terms and conditions. You may not impose any further 370 | restrictions on the recipients' exercise of the rights granted herein. 371 | You are not responsible for enforcing compliance by third parties with 372 | this License. 373 | 374 | 11. If, as a consequence of a court judgment or allegation of patent 375 | infringement or for any other reason (not limited to patent issues), 376 | conditions are imposed on you (whether by court order, agreement or 377 | otherwise) that contradict the conditions of this License, they do not 378 | excuse you from the conditions of this License. If you cannot 379 | distribute so as to satisfy simultaneously your obligations under this 380 | License and any other pertinent obligations, then as a consequence you 381 | may not distribute the Library at all. For example, if a patent 382 | license would not permit royalty-free redistribution of the Library by 383 | all those who receive copies directly or indirectly through you, then 384 | the only way you could satisfy both it and this License would be to 385 | refrain entirely from distribution of the Library. 386 | 387 | If any portion of this section is held invalid or unenforceable under any 388 | particular circumstance, the balance of the section is intended to apply, 389 | and the section as a whole is intended to apply in other circumstances. 390 | 391 | It is not the purpose of this section to induce you to infringe any 392 | patents or other property right claims or to contest validity of any 393 | such claims; this section has the sole purpose of protecting the 394 | integrity of the free software distribution system which is 395 | implemented by public license practices. Many people have made 396 | generous contributions to the wide range of software distributed 397 | through that system in reliance on consistent application of that 398 | system; it is up to the author/donor to decide if he or she is willing 399 | to distribute software through any other system and a licensee cannot 400 | impose that choice. 401 | 402 | This section is intended to make thoroughly clear what is believed to 403 | be a consequence of the rest of this License. 404 | 405 | 12. If the distribution and/or use of the Library is restricted in 406 | certain countries either by patents or by copyrighted interfaces, the 407 | original copyright holder who places the Library under this License may add 408 | an explicit geographical distribution limitation excluding those countries, 409 | so that distribution is permitted only in or among countries not thus 410 | excluded. In such case, this License incorporates the limitation as if 411 | written in the body of this License. 412 | 413 | 13. The Free Software Foundation may publish revised and/or new 414 | versions of the Lesser General Public License from time to time. 415 | Such new versions will be similar in spirit to the present version, 416 | but may differ in detail to address new problems or concerns. 417 | 418 | Each version is given a distinguishing version number. If the Library 419 | specifies a version number of this License which applies to it and 420 | "any later version", you have the option of following the terms and 421 | conditions either of that version or of any later version published by 422 | the Free Software Foundation. If the Library does not specify a 423 | license version number, you may choose any version ever published by 424 | the Free Software Foundation. 425 | 426 | 14. If you wish to incorporate parts of the Library into other free 427 | programs whose distribution conditions are incompatible with these, 428 | write to the author to ask for permission. For software which is 429 | copyrighted by the Free Software Foundation, write to the Free 430 | Software Foundation; we sometimes make exceptions for this. Our 431 | decision will be guided by the two goals of preserving the free status 432 | of all derivatives of our free software and of promoting the sharing 433 | and reuse of software generally. 434 | 435 | NO WARRANTY 436 | 437 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 438 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 439 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 440 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY 441 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 442 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 443 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE 444 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME 445 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 446 | 447 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 448 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 449 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU 450 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR 451 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 452 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 453 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 454 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF 455 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 456 | DAMAGES. 457 | 458 | END OF TERMS AND CONDITIONS 459 | 460 | How to Apply These Terms to Your New Libraries 461 | 462 | If you develop a new library, and you want it to be of the greatest 463 | possible use to the public, we recommend making it free software that 464 | everyone can redistribute and change. You can do so by permitting 465 | redistribution under these terms (or, alternatively, under the terms of the 466 | ordinary General Public License). 467 | 468 | To apply these terms, attach the following notices to the library. It is 469 | safest to attach them to the start of each source file to most effectively 470 | convey the exclusion of warranty; and each file should have at least the 471 | "copyright" line and a pointer to where the full notice is found. 472 | 473 | 474 | Copyright (C) 475 | 476 | This library is free software; you can redistribute it and/or 477 | modify it under the terms of the GNU Lesser General Public 478 | License as published by the Free Software Foundation; either 479 | version 2.1 of the License, or (at your option) any later version. 480 | 481 | This library is distributed in the hope that it will be useful, 482 | but WITHOUT ANY WARRANTY; without even the implied warranty of 483 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 484 | Lesser General Public License for more details. 485 | 486 | You should have received a copy of the GNU Lesser General Public 487 | License along with this library; if not, write to the Free Software 488 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 489 | 490 | Also add information on how to contact you by electronic and paper mail. 491 | 492 | You should also get your employer (if you work as a programmer) or your 493 | school, if any, to sign a "copyright disclaimer" for the library, if 494 | necessary. Here is a sample; alter the names: 495 | 496 | Yoyodyne, Inc., hereby disclaims all copyright interest in the 497 | library `Frob' (a library for tweaking knobs) written by James Random Hacker. 498 | 499 | , 1 April 1990 500 | Ty Coon, President of Vice 501 | 502 | That's all there is to it! 503 | 504 | 505 | --------------------------------------------------------------------------------