Merge of trunk into branch-1.4.x.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.4.x@127 119443c7-1b9e-41f8-b6fc-b9c35fce742c
This commit is contained in:
parent
9e775e662e
commit
8cfa0e488c
105
ChangeLog
105
ChangeLog
@ -2,30 +2,100 @@
|
||||
Version 1.4.2
|
||||
*************************************************************************
|
||||
|
||||
2007-02-02 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
|
||||
|
||||
* Bumped the program version to 1.4.2 in config.ac.
|
||||
|
||||
* Now requires autoconf 2.60.
|
||||
|
||||
* Fixed docdir use.
|
||||
|
||||
* Does not install the documentation by default.
|
||||
|
||||
* Use dist-bzip2 to create a .bz2 distribution file.
|
||||
|
||||
2007-01-23 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
|
||||
|
||||
* SF Tracker [ 1634922 ] Support for large files (>= 2 GiB), part 2
|
||||
Submitted By: Jonathan - no_dice
|
||||
Summary: This patch hopefully fixes the remaining types and related
|
||||
code to enable files >= 2 GiB to be streamed. Jonathan claims to have
|
||||
tested this with a patched version of ushare-0.9.8 and a D-Link DSM-520.
|
||||
|
||||
2007-01-09 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
|
||||
|
||||
* SF Tracker [ 1628629 ] Multicast interface patch
|
||||
Submitted By: Fredrik Svensson - svefredrik
|
||||
This patch fixes two problems:
|
||||
1) Specify the IP address for the interface when we do
|
||||
setsockopt IP_ADD_MEMBERSHIP. This makes it possible to run
|
||||
when no default router has been configured.
|
||||
2) Explicitly set the multicast interface through setsockopt
|
||||
IP_MULTICAST_IF. Avoids socket error -207 in some cases.
|
||||
|
||||
* SF Tracker [ 1628590 ] XML parsing segfault patch
|
||||
Submitted By: Fredrik Svensson - svefredrik
|
||||
This patch fixes a segmentation fault problem that occurrs
|
||||
when parsing XML code than some routers produce.
|
||||
|
||||
2007-01-06 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
|
||||
|
||||
* SF Tracker [ 1628552 ] XML white space patch
|
||||
Submitted By: Fredrik Svensson - svefredrik
|
||||
|
||||
* SF Tracker [ 1628562 ] Maximum total jobs patch
|
||||
Submitted By: Fredrik Svensson - svefredrik
|
||||
Also, I incremented the libray versions and included some
|
||||
comments in the file configure.ac so that we do not bump
|
||||
the library version excessively, only the necessary numbers
|
||||
on the next release.
|
||||
|
||||
* SF Tracker [ 1628575 ] Linksys WRT54G patch
|
||||
Submitted By: Fredrik Svensson - svefredrik
|
||||
|
||||
* SF Tracker [ 1628636 ] SSDP packet copy patch
|
||||
Submitted By: Fredrik Svensson - svefredrik
|
||||
Changed NUM_COPY to 1 since, according to section 9.2 of the
|
||||
HTTPU/MU spec, we should never send more than one copy of a
|
||||
reply to an SSDP request. Ref. section 9.2 of
|
||||
http://www.upnp.org/download/draft-goland-http-udp-04.txt
|
||||
|
||||
2006-12-23 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
|
||||
|
||||
* Thorough revision of every call of http_MakeMessage() due to a
|
||||
bug introduced in rev.79 "largefile patch added".
|
||||
http_MakeMessage() has a worst than brain damaged "printf" like
|
||||
interface. In rev.79, the "N" format parameter must be an off_t.
|
||||
Every call of this function with an "N" format parameter and an
|
||||
int passed on the stack would fail terribly.
|
||||
|
||||
* SF Bug tracker [ 1590469 ]
|
||||
Typo in ixmlparser.c
|
||||
Submitted By: Erik Johansson - erijo
|
||||
|
||||
* SF Bug Tracker [ 1590466 ] Invalid xml output
|
||||
Submitted By: Erik Johansson - erijo
|
||||
|
||||
* SF Patch tracker [ 1581161 ] VStudio2005 patch
|
||||
Submitted By: David Maass - darkservant
|
||||
|
||||
* SF Patch tracker [ 1587272 ] const-ified ixml
|
||||
Submitted By: Erik Johansson
|
||||
|
||||
* Finished const-ifications as suggested by Erik Johansson in
|
||||
SF Patch tracker [ 1587272 ].
|
||||
|
||||
2006-12-23 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
|
||||
2006-07-05 Nektarios K. Papadopoulos <npapadop(at)inaccessnetworks.com>
|
||||
* [bug-id] 1580440
|
||||
[submitted-by] Erik Johansson - erijo
|
||||
[patched-by] Erik Johansson - erijo
|
||||
The SOAP HTTP message that's generated on upnp errors
|
||||
is missing a \r\n\ between header and body.
|
||||
|
||||
* Erik Johansson's patch for const-ified ixml
|
||||
SF Patch tracker [ 1587272 ].
|
||||
2006-07-07 Oxy <virtual_worlds(at)gmx.de>
|
||||
|
||||
2006-12-23 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
|
||||
* support for large files (>2 GBytes) added
|
||||
|
||||
* David Maass's patch for VStudio2005 compilation failure.
|
||||
SF Patch tracker [ 1581161 ].
|
||||
|
||||
2006-12-23 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
|
||||
|
||||
* Erik Johansson's patch for invalid xml output.
|
||||
SF Bug Tracker [ 1590466 ].
|
||||
|
||||
2006-12-23 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
|
||||
|
||||
* Erik Johansson's patch for typo in ixmlparser.c.
|
||||
SF Bug tracker [ 1590469 ].
|
||||
|
||||
*************************************************************************
|
||||
Version 1.4.1
|
||||
@ -79,10 +149,13 @@ Version 1.4.0
|
||||
2006-05-18 Oxy <virtual_worlds(at)gmx.de>
|
||||
|
||||
* DSM-320 patch added (fetched from project MediaTomb)
|
||||
|
||||
* httpGet additons atch added, Added proxy support by introducing
|
||||
UpnpOpenHttpGetProxy. UpnpOpenHttpGet now just calls
|
||||
UpnpOpenHttpGetProxy with the proxy url set to NULL.
|
||||
|
||||
* Bugfix for typo ("\0" / "0") in ixmlparser.c
|
||||
|
||||
* Bugfix for M-Search packet
|
||||
|
||||
*************************************************************************
|
||||
|
39
Makefile.am
39
Makefile.am
@ -5,40 +5,39 @@
|
||||
# Copyright (C) 2005 Rémi Turboult <r3mi@users.sourceforge.net>
|
||||
#
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
DISTCHECK_CONFIGURE_FLAGS = --enable-debug --enable-samples
|
||||
|
||||
SUBDIRS = ixml threadutil upnp docs/dist
|
||||
SUBDIRS = ixml threadutil upnp docs/dist
|
||||
|
||||
|
||||
EXTRA_DIST = libupnp.pc.in LICENSE THANKS libupnp.spec \
|
||||
build/libupnp.bpf \
|
||||
build/libupnp.bpr \
|
||||
build/libupnp.dsp \
|
||||
build/libupnp.dsw \
|
||||
build/inc/autoconfig.h \
|
||||
build/inc/config.h \
|
||||
build/inc/upnpconfig.h
|
||||
EXTRA_DIST = \
|
||||
libupnp.pc.in \
|
||||
LICENSE \
|
||||
THANKS \
|
||||
libupnp.spec \
|
||||
build/libupnp.bpf \
|
||||
build/libupnp.bpr \
|
||||
build/libupnp.dsp \
|
||||
build/libupnp.dsw \
|
||||
build/inc/autoconfig.h \
|
||||
build/inc/config.h \
|
||||
build/inc/upnpconfig.h
|
||||
|
||||
|
||||
# This variable must have 'exec' in its name, in order to be installed
|
||||
# by 'install-exec' target (instead of default 'install-data')
|
||||
pkgconfigexecdir = $(libdir)/pkgconfig
|
||||
pkgconfigexec_DATA = libupnp.pc
|
||||
pkgconfigexecdir = $(libdir)/pkgconfig
|
||||
pkgconfigexec_DATA = libupnp.pc
|
||||
|
||||
$(pkgconfigexec_DATA): config.status
|
||||
|
||||
|
||||
if WITH_DOCDIR
|
||||
docdir = @DOCDIR@
|
||||
doc_DATA = LICENSE README NEWS TODO THANKS
|
||||
if WITH_DOCUMENTATION
|
||||
doc_DATA = LICENSE README NEWS TODO THANKS
|
||||
endif
|
||||
|
||||
|
||||
CLEANFILES = IUpnpErrFile.txt IUpnpInfoFile.txt
|
||||
|
||||
|
||||
|
||||
|
||||
CLEANFILES = IUpnpErrFile.txt IUpnpInfoFile.txt
|
||||
|
||||
|
4
THANKS
4
THANKS
@ -12,15 +12,17 @@ exempt of errors.
|
||||
- Erik Johansson
|
||||
- Eric Tanguy
|
||||
- Erwan Velu
|
||||
- Fredrik Svensson
|
||||
- Jiri Zouhar
|
||||
- John Dennis
|
||||
- Jonathan (no_dice)
|
||||
- Leuk_He
|
||||
- Loigu
|
||||
- Marcelo Roberto Jimenez
|
||||
- Markus Strobl
|
||||
- Nektarios K. Papadopoulos
|
||||
- Oskar Liljeblad
|
||||
- Oxy
|
||||
- Michael (Oxy)
|
||||
- Paul Vixie
|
||||
- Siva Chandran
|
||||
|
||||
|
@ -43,7 +43,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBUPNP_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\pthreads\include" /I "..\ixml\src\inc" /I "..\ixml\inc" /I "..\threadutil\inc" /I "..\upnp\inc" /I "..\upnp\src\inc" /I ".\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBUPNP_EXPORTS" /FR /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\pthreads\include" /I "..\ixml\src\inc" /I "..\ixml\inc" /I "..\threadutil\inc" /I "..\upnp\inc" /I "..\upnp\src\inc" /I ".\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBUPNP_EXPORTS" /D "PTW32_STATIC_LIB" /D "UPNP_STATIC_LIB" /FR /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x407 /d "NDEBUG"
|
||||
@ -53,7 +53,8 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ..\pthreads\lib\pthreadvc2.lib ws2_32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib pthreads\lib\pthreadvc2.lib ws2_32.lib /nologo /dll /machine:I386
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "libupnp - Win32 Debug"
|
||||
|
||||
@ -274,6 +275,146 @@ SOURCE=..\upnp\src\win_dll.c
|
||||
# Begin Group "Header-Dateien"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\client_table.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\config.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\gena.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\gena_ctrlpt.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\gena_device.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\global.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\gmtdate.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\http_client.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\httpparser.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\httpreadwrite.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\inet_pton.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\md5.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\membuffer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\miniserver.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\netall.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\parsetools.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\server.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\service_table.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\soaplib.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\sock.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\ssdplib.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\statcodes.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\statuscodes.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\strintmap.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\sysdep.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\unixutil.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\upnp_timeout.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\upnpapi.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\upnpclosesocket.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\uri.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\urlconfig.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\util.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\utilall.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\uuid.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\upnp\src\inc\webserver.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Ressourcendateien"
|
||||
|
||||
|
73
configure.ac
73
configure.ac
@ -8,9 +8,9 @@
|
||||
# (C) Copyright 2005-2006 Rémi Turboult <r3mi@users.sourceforge.net>
|
||||
#
|
||||
|
||||
AC_PREREQ(2.59)
|
||||
AC_PREREQ(2.60)
|
||||
|
||||
AC_INIT([libupnp], [1.4.1], [virtual_worlds@gmx.de])
|
||||
AC_INIT([libupnp], [1.4.2], [mroberto@users.sourceforge.net])
|
||||
# *Independently* of the above libupnp package version, the libtool version
|
||||
# of the 3 libraries need to be updated whenever there is a change released :
|
||||
# "current:revision:age" (this is NOT the same as the package version), where:
|
||||
@ -19,16 +19,34 @@ AC_INIT([libupnp], [1.4.1], [virtual_worlds@gmx.de])
|
||||
# - interfaces added: age++
|
||||
# - interfaces removed: age=0
|
||||
# *please update only once, before a formal release, not for each change*
|
||||
AC_SUBST([LT_VERSION_IXML], [2:2:0])
|
||||
AC_SUBST([LT_VERSION_THREADUTIL], [2:2:0])
|
||||
AC_SUBST([LT_VERSION_UPNP], [2:2:0])
|
||||
#
|
||||
# For release 1.4.1, we had:
|
||||
#AC_SUBST([LT_VERSION_IXML], [2:2:0])
|
||||
#AC_SUBST([LT_VERSION_THREADUTIL], [2:2:0])
|
||||
#AC_SUBST([LT_VERSION_UPNP], [2:2:0])
|
||||
#
|
||||
# "current:revision:age"
|
||||
#
|
||||
# - Code has changed in ixml
|
||||
# revision: 2 -> 3
|
||||
# - Code has changed in threadutil
|
||||
# revision: 2 -> 3
|
||||
# - Interface added in threadutil
|
||||
# current: 2 -> 3
|
||||
# revisiion: 3 -> 0
|
||||
# age: 0 -> 1
|
||||
# - Code has changed in upnp (revision 2 -> 3)
|
||||
# revision: 2 -> 3
|
||||
AC_SUBST([LT_VERSION_IXML], [2:3:0])
|
||||
AC_SUBST([LT_VERSION_THREADUTIL], [3:0:1])
|
||||
AC_SUBST([LT_VERSION_UPNP], [2:3:0])
|
||||
|
||||
|
||||
AC_CONFIG_AUX_DIR(config.aux)
|
||||
AC_CONFIG_MACRO_DIR(m4)
|
||||
AC_CONFIG_SRCDIR(upnp/inc/upnp.h)
|
||||
|
||||
AM_INIT_AUTOMAKE([1.8 -Wall foreign subdir-objects])
|
||||
AM_INIT_AUTOMAKE([1.8 -Wall foreign subdir-objects dist-bzip2])
|
||||
|
||||
#
|
||||
# There are 3 configuration files :
|
||||
@ -42,6 +60,7 @@ AM_INIT_AUTOMAKE([1.8 -Wall foreign subdir-objects])
|
||||
# installed libraries.
|
||||
#
|
||||
AC_CONFIG_HEADERS([autoconfig.h upnp/inc/upnpconfig.h])
|
||||
#AC_SYS_LARGEFILE_SENSITIVE
|
||||
|
||||
AC_REVISION([$Revision: 1.11 $])
|
||||
|
||||
@ -106,19 +125,28 @@ RT_BOOL_ARG_ENABLE([samples], [yes], [compilation of upnp/sample/ code])
|
||||
|
||||
|
||||
# doc installation
|
||||
AC_MSG_CHECKING([documentation installation])
|
||||
AC_ARG_WITH([docdir],
|
||||
AC_HELP_STRING([--with-docdir=DIR],
|
||||
[where documentation is installed
|
||||
@<:@[DATADIR/doc/]AC_PACKAGE_NAME[-]AC_PACKAGE_VERSION@:>@])
|
||||
AC_HELP_STRING([--without-docdir],
|
||||
[do not install the documentation]),
|
||||
[DOCDIR="$with_docdir"],
|
||||
[DOCDIR="${datadir}/doc/${PACKAGE_NAME}-${PACKAGE_VERSION}"])
|
||||
# autoconf >= 2.60 already defines ${docdir}, but we will not use its
|
||||
# default value, which is ${datarootdir}/doc/${PACKAGE_TARNAME}.
|
||||
# That would give us ${datarootdir}/doc/libupnp, and we want the package
|
||||
# version on that.
|
||||
docdir="${datadir}/doc/${PACKAGE_NAME}-${PACKAGE_VERSION}"
|
||||
AC_MSG_CHECKING([for documentation directory])
|
||||
AC_ARG_WITH([documentation],
|
||||
AS_HELP_STRING([--with-documentation=directory_name],
|
||||
[where documentation is installed
|
||||
@<:@[DATADIR/doc/]AC_PACKAGE_NAME[-]AC_PACKAGE_VERSION@:>@])
|
||||
AS_HELP_STRING([--without-documentation],
|
||||
[do not install the documentation]),
|
||||
[],
|
||||
[with_documentation=no])
|
||||
|
||||
AM_CONDITIONAL(WITH_DOCDIR, test x"$with_docdir" != xno)
|
||||
AC_SUBST(DOCDIR)
|
||||
AC_MSG_RESULT($DOCDIR)
|
||||
# If something has been entered after an equal sign, assume it is the directory
|
||||
if test x"$with_documentation" != xyes -a x"$with_documentation" != xno; then
|
||||
docdir="$with_documentation"
|
||||
fi
|
||||
AM_CONDITIONAL(WITH_DOCUMENTATION, test x"$with_documentation" != xno)
|
||||
AC_SUBST(docdir)
|
||||
AC_MSG_RESULT($docdir)
|
||||
|
||||
|
||||
#
|
||||
@ -144,9 +172,12 @@ else
|
||||
fi
|
||||
AX_CFLAGS_WARN_ALL
|
||||
|
||||
# Arrange for large-file support (can be disabled with --disable-largefile).
|
||||
# Define _FILE_OFFSET_BITS and _LARGE_FILES if necessary
|
||||
AC_SYS_LARGEFILE
|
||||
#
|
||||
# Lot's of stuff to ensure large file support
|
||||
#
|
||||
AC_TYPE_OFF_T
|
||||
AC_DEFINE(_LARGE_FILE_SOURCE, [], [Large files support])
|
||||
AC_DEFINE(_FILE_OFFSET_BITS, [64], [File Offset size])
|
||||
|
||||
|
||||
#
|
||||
|
13
docs/dist/Makefile.am
vendored
13
docs/dist/Makefile.am
vendored
@ -1,4 +1,7 @@
|
||||
EXTRA_DIST = ./UPnP_Programming_Guide.pdf \
|
||||
|
||||
|
||||
EXTRA_DIST = \
|
||||
./UPnP_Programming_Guide.pdf \
|
||||
./IXML_Programming_Guide.pdf \
|
||||
./html/upnp/icon1.gif \
|
||||
./html/upnp/icon2.gif \
|
||||
@ -251,9 +254,10 @@ EXTRA_DIST = ./UPnP_Programming_Guide.pdf \
|
||||
./html/ixml/ixmlCloneDOMString.html \
|
||||
./html/ixml/ixmlFreeDOMString.html
|
||||
|
||||
if WITH_DOCDIR
|
||||
docsdir = @DOCDIR@
|
||||
nobase_docs_DATA = ./UPnP_Programming_Guide.pdf \
|
||||
if WITH_DOCUMENTATION
|
||||
docsdir = @docdir@
|
||||
nobase_docs_DATA = \
|
||||
./UPnP_Programming_Guide.pdf \
|
||||
./IXML_Programming_Guide.pdf \
|
||||
./html/upnp/icon1.gif \
|
||||
./html/upnp/icon2.gif \
|
||||
@ -506,3 +510,4 @@ if WITH_DOCDIR
|
||||
./html/ixml/ixmlCloneDOMString.html \
|
||||
./html/ixml/ixmlFreeDOMString.html
|
||||
endif
|
||||
|
||||
|
@ -146,7 +146,7 @@ ixmlPrintDomTreeRecursive( IN IXML_Node * nodeptr,
|
||||
if( ( child != NULL )
|
||||
&& ( ixmlNode_getNodeType( child ) ==
|
||||
eELEMENT_NODE ) ) {
|
||||
ixml_membuf_append_str( buf, ">\n" );
|
||||
ixml_membuf_append_str( buf, ">\r\n" );
|
||||
} else {
|
||||
ixml_membuf_append_str( buf, ">" );
|
||||
}
|
||||
@ -164,7 +164,7 @@ ixmlPrintDomTreeRecursive( IN IXML_Node * nodeptr,
|
||||
&& ixmlNode_getNodeType( sibling ) == eTEXT_NODE ) {
|
||||
ixml_membuf_append_str( buf, ">" );
|
||||
} else {
|
||||
ixml_membuf_append_str( buf, ">\n" );
|
||||
ixml_membuf_append_str( buf, ">\r\n" );
|
||||
}
|
||||
ixmlPrintDomTreeRecursive( ixmlNode_getNextSibling
|
||||
( nodeptr ), buf );
|
||||
@ -227,7 +227,7 @@ ixmlPrintDomTree( IN IXML_Node * nodeptr,
|
||||
child = ixmlNode_getFirstChild( nodeptr );
|
||||
if( ( child != NULL )
|
||||
&& ( ixmlNode_getNodeType( child ) == eELEMENT_NODE ) ) {
|
||||
ixml_membuf_append_str( buf, ">\n" );
|
||||
ixml_membuf_append_str( buf, ">\r\n" );
|
||||
} else {
|
||||
ixml_membuf_append_str( buf, ">" );
|
||||
}
|
||||
@ -239,7 +239,7 @@ ixmlPrintDomTree( IN IXML_Node * nodeptr,
|
||||
// Done with children. Output the end tag.
|
||||
ixml_membuf_append_str( buf, "</" );
|
||||
ixml_membuf_append_str( buf, nodeName );
|
||||
ixml_membuf_append_str( buf, ">\n" );
|
||||
ixml_membuf_append_str( buf, ">\r\n" );
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -372,7 +372,7 @@ ixmlPrintDocument(IXML_Document *doc)
|
||||
}
|
||||
|
||||
ixml_membuf_init( buf );
|
||||
ixml_membuf_append_str( buf, "<?xml version=\"1.0\"?>\n" );
|
||||
ixml_membuf_append_str( buf, "<?xml version=\"1.0\"?>\r\n" );
|
||||
ixmlPrintDomTree( rootNode, buf );
|
||||
return buf->buf;
|
||||
|
||||
@ -421,7 +421,7 @@ ixmlDocumenttoString(IXML_Document *doc)
|
||||
}
|
||||
|
||||
ixml_membuf_init( buf );
|
||||
ixml_membuf_append_str( buf, "<?xml version=\"1.0\"?>\n" );
|
||||
ixml_membuf_append_str( buf, "<?xml version=\"1.0\"?>\r\n" );
|
||||
ixmlDomTreetoString( rootNode, buf );
|
||||
return buf->buf;
|
||||
|
||||
|
@ -241,6 +241,21 @@ static BOOL Parser_hasDefaultNamespace( Parser * xmlParser,
|
||||
static int Parser_getChar( IN const char *src,
|
||||
INOUT int *cLen );
|
||||
|
||||
/*==============================================================================*
|
||||
* safe_strdup
|
||||
* strdup that handles NULL input.
|
||||
*
|
||||
*===============================================================================*/
|
||||
static char *
|
||||
safe_strdup(const char *s)
|
||||
{
|
||||
assert(s != NULL);
|
||||
if (s == NULL) {
|
||||
return strdup("");
|
||||
}
|
||||
return strdup(s);
|
||||
}
|
||||
|
||||
/*==============================================================================*
|
||||
* Parser_isCharInTable
|
||||
* will determine whether character c is in the table of tbl
|
||||
@ -525,14 +540,14 @@ Parser_pushElement( IN Parser * xmlParser,
|
||||
memset( pNewStackElement, 0, sizeof( IXML_ElementStack ) );
|
||||
// the element member includes both prefix and name
|
||||
|
||||
pNewStackElement->element = strdup( newElement->nodeName );
|
||||
pNewStackElement->element = safe_strdup( newElement->nodeName );
|
||||
if( pNewStackElement->element == NULL ) {
|
||||
free( pNewStackElement );
|
||||
return IXML_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
|
||||
if( newElement->prefix != 0 ) {
|
||||
pNewStackElement->prefix = strdup( newElement->prefix );
|
||||
pNewStackElement->prefix = safe_strdup( newElement->prefix );
|
||||
if( pNewStackElement->prefix == NULL ) {
|
||||
Parser_freeElementStackItem( pNewStackElement );
|
||||
free( pNewStackElement );
|
||||
@ -542,7 +557,7 @@ Parser_pushElement( IN Parser * xmlParser,
|
||||
|
||||
if( newElement->namespaceURI != 0 ) {
|
||||
pNewStackElement->namespaceUri =
|
||||
strdup( newElement->namespaceURI );
|
||||
safe_strdup( newElement->namespaceURI );
|
||||
if( pNewStackElement->namespaceUri == NULL ) {
|
||||
Parser_freeElementStackItem( pNewStackElement );
|
||||
free( pNewStackElement );
|
||||
@ -634,7 +649,7 @@ Parser_readFileOrBuffer( IN Parser * xmlParser,
|
||||
fclose( xmlFilePtr );
|
||||
}
|
||||
} else {
|
||||
xmlParser->dataBuffer = strdup( xmlFileName );
|
||||
xmlParser->dataBuffer = safe_strdup( xmlFileName );
|
||||
if( xmlParser->dataBuffer == NULL ) {
|
||||
return IXML_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
@ -1610,7 +1625,7 @@ Parser_addNamespace( IN Parser * xmlParser )
|
||||
// it would be wrong that pNode->namespace != NULL.
|
||||
assert( pNode->namespaceURI == NULL );
|
||||
|
||||
pNode->namespaceURI = strdup( pCur->namespaceUri );
|
||||
pNode->namespaceURI = safe_strdup( pCur->namespaceUri );
|
||||
if( pNode->namespaceURI == NULL ) {
|
||||
return IXML_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
@ -1626,7 +1641,7 @@ Parser_addNamespace( IN Parser * xmlParser )
|
||||
|
||||
namespaceUri = Parser_getNameSpace( xmlParser, pCur->prefix );
|
||||
if( namespaceUri != NULL ) {
|
||||
pNode->namespaceURI = strdup( namespaceUri );
|
||||
pNode->namespaceURI = safe_strdup( namespaceUri );
|
||||
if( pNode->namespaceURI == NULL ) {
|
||||
return IXML_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
@ -1661,7 +1676,7 @@ Parser_setNodePrefixAndLocalName( IN IXML_Node * node )
|
||||
pStrPrefix = strchr( node->nodeName, ':' );
|
||||
if( pStrPrefix == NULL ) {
|
||||
node->prefix = NULL;
|
||||
node->localName = strdup( node->nodeName );
|
||||
node->localName = safe_strdup( node->nodeName );
|
||||
if( node->localName == NULL ) {
|
||||
return IXML_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
@ -1678,7 +1693,7 @@ Parser_setNodePrefixAndLocalName( IN IXML_Node * node )
|
||||
memset( node->prefix, 0, nPrefix + 1 );
|
||||
strncpy( node->prefix, node->nodeName, nPrefix );
|
||||
|
||||
node->localName = strdup( pLocalName );
|
||||
node->localName = safe_strdup( pLocalName );
|
||||
if( node->localName == NULL ) {
|
||||
free( node->prefix );
|
||||
node->prefix = NULL; //no need to free really, main loop will frees it
|
||||
@ -1718,7 +1733,7 @@ Parser_xmlNamespace( IN Parser * xmlParser,
|
||||
}
|
||||
///here it goes to segfault on "" when not copying
|
||||
if(newNode->nodeValue){
|
||||
pCur->namespaceUri = strdup( newNode->nodeValue );
|
||||
pCur->namespaceUri = safe_strdup( newNode->nodeValue );
|
||||
if( pCur->namespaceUri == NULL ) {
|
||||
return IXML_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
@ -1738,7 +1753,7 @@ Parser_xmlNamespace( IN Parser * xmlParser,
|
||||
|
||||
if( ( pCur->prefix != NULL )
|
||||
&& ( strcmp( pCur->prefix, newNode->localName ) == 0 ) ) {
|
||||
pCur->namespaceUri = strdup( newNode->nodeValue );
|
||||
pCur->namespaceUri = safe_strdup( newNode->nodeValue );
|
||||
if( pCur->namespaceUri == NULL ) {
|
||||
return IXML_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
@ -1765,13 +1780,13 @@ Parser_xmlNamespace( IN Parser * xmlParser,
|
||||
}
|
||||
memset( pNewNs, 0, sizeof( IXML_NamespaceURI ) );
|
||||
|
||||
pNewNs->prefix = strdup( newNode->localName );
|
||||
pNewNs->prefix = safe_strdup( newNode->localName );
|
||||
if( pNewNs->prefix == NULL ) {
|
||||
free( pNewNs );
|
||||
return IXML_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
|
||||
pNewNs->nsURI = strdup( newNode->nodeValue );
|
||||
pNewNs->nsURI = safe_strdup( newNode->nodeValue );
|
||||
if( pNewNs->nsURI == NULL ) {
|
||||
Parser_freeNsURI( pNewNs );
|
||||
free( pNewNs );
|
||||
@ -1789,7 +1804,7 @@ Parser_xmlNamespace( IN Parser * xmlParser,
|
||||
free( pNs->nsURI );
|
||||
}
|
||||
|
||||
pNs->nsURI = strdup( newNode->nodeValue );
|
||||
pNs->nsURI = safe_strdup( newNode->nodeValue );
|
||||
if( pNs->nsURI == NULL ) {
|
||||
return IXML_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
@ -1826,7 +1841,7 @@ Parser_processSTag( IN Parser * xmlParser,
|
||||
|
||||
pCurToken = ( xmlParser->tokenBuf ).buf;
|
||||
if( pCurToken != NULL ) {
|
||||
node->nodeName = strdup( pCurToken );
|
||||
node->nodeName = safe_strdup( pCurToken );
|
||||
if( node->nodeName == NULL ) {
|
||||
return IXML_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
@ -1977,7 +1992,7 @@ Parser_processCDSect( IN char **pSrc,
|
||||
strncpy( node->nodeValue, pCDataStart, tokenLength );
|
||||
node->nodeValue[tokenLength] = '\0';
|
||||
|
||||
node->nodeName = strdup( CDATANODENAME );
|
||||
node->nodeName = safe_strdup( CDATANODENAME );
|
||||
if( node->nodeName == NULL ) {
|
||||
// no need to free node->nodeValue at all, bacause node contents
|
||||
// will be freed by the main loop.
|
||||
@ -2008,7 +2023,7 @@ Parser_setElementNamespace( IN IXML_Element * newElement,
|
||||
if( newElement->n.namespaceURI != NULL ) {
|
||||
return IXML_SYNTAX_ERR;
|
||||
} else {
|
||||
( newElement->n ).namespaceURI = strdup( nsURI );
|
||||
( newElement->n ).namespaceURI = safe_strdup( nsURI );
|
||||
if( ( newElement->n ).namespaceURI == NULL ) {
|
||||
return IXML_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
@ -2107,7 +2122,7 @@ Parser_processContent( IN Parser * xmlParser,
|
||||
|
||||
pCurToken = ( xmlParser->tokenBuf ).buf;
|
||||
if( pCurToken != NULL ) {
|
||||
node->nodeValue = strdup( pCurToken );
|
||||
node->nodeValue = safe_strdup( pCurToken );
|
||||
if( node->nodeValue == NULL ) {
|
||||
return IXML_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
@ -2115,7 +2130,7 @@ Parser_processContent( IN Parser * xmlParser,
|
||||
return IXML_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
node->nodeName = strdup( TEXTNODENAME );
|
||||
node->nodeName = safe_strdup( TEXTNODENAME );
|
||||
if( node->nodeName == NULL ) {
|
||||
return IXML_SYNTAX_ERR;
|
||||
}
|
||||
@ -2152,7 +2167,7 @@ Parser_processETag( IN Parser * xmlParser,
|
||||
if( pCurToken == NULL ) {
|
||||
return IXML_SYNTAX_ERR;
|
||||
}
|
||||
node->nodeName = strdup( pCurToken );
|
||||
node->nodeName = safe_strdup( pCurToken );
|
||||
if( node->nodeName == NULL ) {
|
||||
return IXML_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
@ -2320,7 +2335,7 @@ Parser_processAttribute( IN Parser * xmlParser,
|
||||
return IXML_SYNTAX_ERR;
|
||||
}
|
||||
// copy in the attribute name
|
||||
node->nodeName = strdup( pCurToken );
|
||||
node->nodeName = safe_strdup( pCurToken );
|
||||
if( node->nodeName == NULL ) {
|
||||
return IXML_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
@ -2373,7 +2388,7 @@ Parser_processAttribute( IN Parser * xmlParser,
|
||||
|
||||
pCurToken = ( xmlParser->tokenBuf ).buf;
|
||||
if( pCurToken != NULL ) { // attribute has value, like a="c"
|
||||
node->nodeValue = strdup( pCurToken );
|
||||
node->nodeValue = safe_strdup( pCurToken );
|
||||
if( node->nodeValue == NULL ) {
|
||||
return IXML_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
@ -2456,7 +2471,7 @@ Parser_getNextNode( IN Parser * xmlParser,
|
||||
goto ErrorHandler;
|
||||
}
|
||||
|
||||
node->nodeName = strdup( lastElement );
|
||||
node->nodeName = safe_strdup( lastElement );
|
||||
if( node->nodeName == NULL ) {
|
||||
return IXML_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
|
13
libupnp.spec
13
libupnp.spec
@ -1,15 +1,14 @@
|
||||
Version: 1.4.1
|
||||
Version: 1.4.2
|
||||
Summary: Universal Plug and Play (UPnP) SDK
|
||||
Name: libupnp
|
||||
Release: 1%{?dist}
|
||||
License: BSD
|
||||
Group: System Environment/Libraries
|
||||
URL: http://www.libupnp.org/
|
||||
Source: http://puzzle.dl.sourceforge.net/sourceforge/pupnp/%{name}-%{version}.tar.gz
|
||||
Source: http://puzzle.dl.sourceforge.net/sourceforge/pupnp/%{name}-%{version}.tar.bz2
|
||||
Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
|
||||
%define docdir %{_docdir}/%{name}-%{version}-%{release}
|
||||
%define docdeveldir %{_docdir}/%{name}-devel-%{version}-%{release}
|
||||
%define docdeveldir %{_docdir}/%{name}-devel-%{version}
|
||||
|
||||
%description
|
||||
The Universal Plug and Play (UPnP) SDK for Linux provides
|
||||
@ -29,7 +28,7 @@ the UPnP SDK libraries.
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
%configure --with-docdir=%{docdir}/
|
||||
%configure --with-documentation
|
||||
make %{?_smp_mflags}
|
||||
|
||||
%install
|
||||
@ -78,6 +77,9 @@ make install DESTDIR=$RPM_BUILD_ROOT
|
||||
rm -rf %{buildroot}
|
||||
|
||||
%changelog
|
||||
* Fri Feb 02 2007 Eric Tanguy <eric.tanguy@univ-nantes.fr> - 1.4.2-1
|
||||
- Update to version 1.4.2
|
||||
|
||||
* Wed Jul 05 2006 Eric Tanguy <eric.tanguy@univ-nantes.fr> - 1.4.1-1
|
||||
- Update to version 1.4.1
|
||||
|
||||
@ -117,3 +119,4 @@ rm -rf %{buildroot}
|
||||
* Thu Dec 22 2005 Eric Tanguy 1.2.1a-1
|
||||
- Modify spec file from
|
||||
http://rpm.pbone.net/index.php3/stat/4/idpl/2378737/com/libupnp-1.2.1a_DSM320-3.i386.rpm.html
|
||||
|
||||
|
@ -61,32 +61,33 @@ typedef enum priority {LOW_PRIORITY,
|
||||
#define DEFAULT_JOBS_PER_THREAD 10 //default jobs per thread used by TPAttrInit
|
||||
#define DEFAULT_STARVATION_TIME 500 //default starvation time used by TPAttrInit
|
||||
#define DEFAULT_IDLE_TIME 10 * 1000 //default idle time used by TPAttrInit
|
||||
#define DEFAULT_FREE_ROUTINE NULL //default free routine used TPJobInit
|
||||
#define DEFAULT_FREE_ROUTINE NULL //default free routine used TPJobInit
|
||||
#define DEFAULT_MAX_JOBS_TOTAL 100 //default max jobs used TPAttrInit
|
||||
|
||||
#define STATS 1 //always include stats because code change is minimal
|
||||
|
||||
|
||||
//Statistics
|
||||
//Statistics
|
||||
#ifdef WIN32 // todo: check why STATSONLY fails during compilation
|
||||
#undef STATS
|
||||
#endif
|
||||
|
||||
#ifdef STATS
|
||||
#define STATSONLY(x) x
|
||||
#define STATSONLY(x) x
|
||||
#else
|
||||
#define STATSONLY(x)
|
||||
#define STATSONLY(x)
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define DEBUG 1
|
||||
#define DEBUG 1
|
||||
#endif
|
||||
|
||||
//DEBUGGING
|
||||
#ifndef WIN32
|
||||
#ifdef DEBUG
|
||||
#define DBGONLY(x) x
|
||||
#define DBGONLY(x) x
|
||||
#else
|
||||
#define DBGONLY(x)
|
||||
#define DBGONLY(x)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -97,7 +98,7 @@ typedef enum priority {LOW_PRIORITY,
|
||||
#include "ithread.h"
|
||||
#include <errno.h>
|
||||
#include <sys/timeb.h>
|
||||
#define EXPORT
|
||||
#define EXPORT
|
||||
typedef int PolicyType;
|
||||
#define DEFAULT_POLICY SCHED_OTHER
|
||||
#define DEFAULT_SCHED_PARAM 0 //default priority
|
||||
@ -114,28 +115,30 @@ typedef void (*free_routine)(void *arg);
|
||||
* Name: ThreadPoolAttr
|
||||
*
|
||||
* Description:
|
||||
* Attributes for thread pool. Used to set and change parameters of
|
||||
* Attributes for thread pool. Used to set and change parameters of
|
||||
* thread pool
|
||||
*****************************************************************************/
|
||||
typedef struct THREADPOOLATTR
|
||||
{
|
||||
int minThreads; //minThreads, ThreadPool will always maintain at least
|
||||
//this many threads
|
||||
|
||||
int maxThreads; //maxThreads, ThreadPool will never have more than this
|
||||
//number of threads
|
||||
|
||||
int maxIdleTime; //maxIdleTime (in milliseconds)
|
||||
// this is the maximum time a thread will remain idle
|
||||
// before dying
|
||||
int minThreads; // minThreads, ThreadPool will always maintain at least
|
||||
// this many threads
|
||||
|
||||
int jobsPerThread; //jobs per thread to maintain
|
||||
|
||||
int starvationTime; //the time a low priority or med priority
|
||||
//job waits before getting bumped
|
||||
//up a priority (in milliseconds)
|
||||
|
||||
PolicyType schedPolicy; //scheduling policy to use
|
||||
int maxThreads; // maxThreads, ThreadPool will never have more than this
|
||||
// number of threads
|
||||
|
||||
int maxIdleTime; // maxIdleTime (in milliseconds)
|
||||
// this is the maximum time a thread will remain idle
|
||||
// before dying
|
||||
|
||||
int jobsPerThread; // jobs per thread to maintain
|
||||
|
||||
int maxJobsTotal; // maximum number of jobs that can be queued totally.
|
||||
|
||||
int starvationTime; // the time a low priority or med priority
|
||||
// job waits before getting bumped
|
||||
// up a priority (in milliseconds)
|
||||
|
||||
PolicyType schedPolicy; // scheduling policy to use
|
||||
|
||||
} ThreadPoolAttr;
|
||||
|
||||
@ -152,7 +155,7 @@ typedef struct THREADPOOLJOB
|
||||
free_routine free_func; //free function
|
||||
struct timeb requestTime; //time of request
|
||||
int priority; //priority of request
|
||||
int jobId; //id
|
||||
int jobId; //id
|
||||
} ThreadPoolJob;
|
||||
|
||||
/****************************************************************************
|
||||
@ -168,20 +171,20 @@ typedef struct TPOOLSTATS
|
||||
{
|
||||
double totalTimeHQ; //total time spent by all jobs in high priority Q
|
||||
int totalJobsHQ; //total jobs in HQ run so far
|
||||
double avgWaitHQ; //average wait in HQ
|
||||
double avgWaitHQ; //average wait in HQ
|
||||
double totalTimeMQ; //total time spent by all jobs in med priority Q
|
||||
int totalJobsMQ; //total jobs in MQ run so far
|
||||
double avgWaitMQ; //average wait in MQ
|
||||
double totalTimeLQ; //total time spent by all jobs in low priority Q
|
||||
int totalJobsLQ; //total jobs in LQ run so far
|
||||
double avgWaitLQ; //average wait in LQ
|
||||
double avgWaitLQ; //average wait in LQ
|
||||
double totalWorkTime; //total time spent working for all threads
|
||||
double totalIdleTime; //total time spent idle for all threads
|
||||
int workerThreads; //number of current workerThreads
|
||||
int idleThreads; //number of current idle threads
|
||||
int persistentThreads; //number of persistent threads
|
||||
int totalThreads; //total number of current threads
|
||||
int maxThreads; //max threads so far
|
||||
int maxThreads; //max threads so far
|
||||
int currentJobsHQ; // current jobs in Q
|
||||
int currentJobsLQ; //current jobs in Q
|
||||
int currentJobsMQ; //current jobs in Q
|
||||
@ -521,6 +524,19 @@ int TPAttrSetStarvationTime(ThreadPoolAttr *attr, int starvationTime);
|
||||
int TPAttrSetSchedPolicy(ThreadPoolAttr *attr, PolicyType schedPolicy);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Function: TPAttrSetMaxJobsTotal
|
||||
*
|
||||
* Description:
|
||||
* Sets the maximum number jobs that can be qeued totally.
|
||||
* Parameters:
|
||||
* attr - must be valid thread pool attributes.
|
||||
* maxJobsTotal - maximum number of jobs
|
||||
* Returns:
|
||||
* Always returns 0.
|
||||
*****************************************************************************/
|
||||
int TPAttrSetMaxJobsTotal(ThreadPoolAttr *attr, int maxJobsTotal);
|
||||
|
||||
/****************************************************************************
|
||||
* Function: ThreadPoolGetStats
|
||||
*
|
||||
|
@ -906,6 +906,7 @@ tp->stats.totalJobsLQ++; tp->stats.totalTimeLQ += diff; break; default:
|
||||
int rc = EOUTOFMEM;
|
||||
|
||||
int tempId = -1;
|
||||
int totalJobs;
|
||||
|
||||
ThreadPoolJob *temp = NULL;
|
||||
|
||||
@ -922,6 +923,13 @@ tp->stats.totalJobsLQ++; tp->stats.totalTimeLQ += diff; break; default:
|
||||
|| ( job->priority == MED_PRIORITY )
|
||||
|| ( job->priority == HIGH_PRIORITY ) );
|
||||
|
||||
totalJobs = tp->highJobQ.size + tp->lowJobQ.size + tp->medJobQ.size;
|
||||
if (totalJobs >= tp->attr.maxJobsTotal) {
|
||||
fprintf(stderr, "total jobs = %d, too many jobs", totalJobs);
|
||||
ithread_mutex_unlock( &tp->mutex );
|
||||
return rc;
|
||||
}
|
||||
|
||||
if( jobId == NULL )
|
||||
jobId = &tempId;
|
||||
|
||||
@ -1267,6 +1275,7 @@ tp->stats.totalJobsLQ++; tp->stats.totalTimeLQ += diff; break; default:
|
||||
attr->minThreads = DEFAULT_MIN_THREADS;
|
||||
attr->schedPolicy = DEFAULT_POLICY;
|
||||
attr->starvationTime = DEFAULT_STARVATION_TIME;
|
||||
attr->maxJobsTotal = DEFAULT_MAX_JOBS_TOTAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1518,6 +1527,29 @@ tp->stats.totalJobsLQ++; tp->stats.totalTimeLQ += diff; break; default:
|
||||
stats->totalIdleTime );}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: TPAttrSetMaxJobsTotal
|
||||
*
|
||||
* Description:
|
||||
* Sets the maximum number jobs that can be qeued totally.
|
||||
* Parameters:
|
||||
* attr - must be valid thread pool attributes.
|
||||
* maxJobsTotal - maximum number of jobs
|
||||
* Returns:
|
||||
* Always returns 0.
|
||||
*****************************************************************************/
|
||||
int TPAttrSetMaxJobsTotal( ThreadPoolAttr * attr,
|
||||
int maxJobsTotal ) {
|
||||
assert( attr != NULL );
|
||||
|
||||
if( attr == NULL ) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
attr->maxJobsTotal = maxJobsTotal;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: ThreadPoolGetStats
|
||||
*
|
||||
|
@ -132,8 +132,7 @@ upnp_tv_ctrlpt_SOURCES = \
|
||||
sample/tvctrlpt/upnp_tv_ctrlpt.h \
|
||||
sample/tvctrlpt/linux/upnp_tv_ctrlpt_main.c
|
||||
|
||||
if WITH_DOCDIR
|
||||
docdir = @DOCDIR@
|
||||
if WITH_DOCUMENTATION
|
||||
examplesdir = $(docdir)/examples
|
||||
examples_DATA = $(upnp_tv_ctrlpt_SOURCES) $(upnp_tv_device_SOURCES)
|
||||
endif
|
||||
|
@ -36,6 +36,14 @@
|
||||
|
||||
//@{
|
||||
|
||||
#if defined MYLIB_LARGEFILE_SENSITIVE && _FILE_OFFSET_BITS+0 != 64
|
||||
#if defined __GNUC__
|
||||
#warning libupnp requires largefile mode - use AC_SYS_LARGEFILE
|
||||
#else
|
||||
#error libupnp requires largefile mode - use AC_SYS_LARGEFILE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef __FreeBSD__
|
||||
#include <time.h>
|
||||
@ -65,6 +73,7 @@
|
||||
#define UpnpCloseSocket close
|
||||
#else
|
||||
#define UpnpCloseSocket closesocket
|
||||
#define fseeko fseek
|
||||
#endif
|
||||
#define UPNP_SOCKETERROR -1
|
||||
#define UPNP_INVALID_SOCKET -1
|
||||
@ -79,6 +88,8 @@
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#define NUM_HANDLE 200
|
||||
#define LINE_SIZE 180
|
||||
#define NAME_SIZE 256
|
||||
@ -875,7 +886,7 @@ struct File_Info
|
||||
/** The length of the file. A length less than 0 indicates the size
|
||||
* is unknown, and data will be sent until 0 bytes are returned from
|
||||
* a read call. */
|
||||
int file_length;
|
||||
off_t file_length;
|
||||
|
||||
/** The time at which the contents of the file was modified;
|
||||
* The time system is always local (not GMT). */
|
||||
@ -969,7 +980,7 @@ struct UpnpVirtualDirCallbacks
|
||||
int (*seek) (
|
||||
IN UpnpWebFileHandle fileHnd, /** The handle of the file to move the
|
||||
file pointer. */
|
||||
IN long offset, /** The number of bytes to move in the
|
||||
IN off_t offset, /** The number of bytes to move in the
|
||||
file. Positive values move foward and
|
||||
negative values move backward. Note
|
||||
that this must be positive if the
|
||||
@ -2707,4 +2718,3 @@ EXPORT_SPEC void UpnpFree(
|
||||
//@} The API
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1974,9 +1974,7 @@ TvDeviceStart( char *ip_address,
|
||||
ip_address = UpnpGetServerIpAddress( );
|
||||
}
|
||||
|
||||
if( port == 0 ) {
|
||||
port = UpnpGetServerPort( );
|
||||
}
|
||||
|
||||
SampleUtil_Print( "UPnP Initialized\n \t ipaddress= %s port = %d\n",
|
||||
ip_address, port );
|
||||
|
@ -244,6 +244,7 @@ int UpnpInit( IN const char *HostIP,
|
||||
TPAttrSetMinThreads( &attr, MIN_THREADS );
|
||||
TPAttrSetJobsPerThread( &attr, JOBS_PER_THREAD );
|
||||
TPAttrSetIdleTime( &attr, THREAD_IDLE_TIME );
|
||||
TPAttrSetMaxJobsTotal( &attr, MAX_JOBS_TOTAL );
|
||||
|
||||
if( ThreadPoolInit( &gSendThreadPool, &attr ) != UPNP_E_SUCCESS ) {
|
||||
UpnpSdkInit = 0;
|
||||
@ -955,7 +956,7 @@ GetDescDocumentAndURL( IN Upnp_DescType descriptionType,
|
||||
char aliasStr[LINE_SIZE];
|
||||
char *temp_str = NULL;
|
||||
FILE *fp = NULL;
|
||||
unsigned fileLen;
|
||||
off_t fileLen;
|
||||
unsigned num_read;
|
||||
time_t last_modified;
|
||||
struct stat file_info;
|
||||
@ -3339,19 +3340,20 @@ UpnpDownloadXmlDoc( const char *url,
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
/* TODO: MoNKi: Do not check this?? Some routers (Linksys WRT54GS) sends
|
||||
"CONTENT-TYPE: application/octet-stream". If the data sended is not
|
||||
an xml file, ixmlParseBufferEx will fail and the function will return
|
||||
UPNP_E_INVALID_DESC too.*/
|
||||
|
||||
if( strncasecmp( content_type, "text/xml", strlen( "text/xml" ) ) ) {
|
||||
DBGONLY(
|
||||
UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, "Not text/xml\n" );
|
||||
)
|
||||
// Linksys WRT54G router returns
|
||||
// "CONTENT-TYPE: application/octet-stream".
|
||||
// Let's be nice to Linksys and try to parse document anyway.
|
||||
// If the data sended is not a xml file, ixmlParseBufferEx
|
||||
// will fail and the function will return UPNP_E_INVALID_DESC too.
|
||||
#if 0
|
||||
free( xml_buf );
|
||||
DBGONLY( UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__,
|
||||
"Not text/xml\n" );
|
||||
)
|
||||
return UPNP_E_INVALID_DESC;
|
||||
return UPNP_E_INVALID_DESC;
|
||||
#endif
|
||||
}
|
||||
// end of TODO Do not check this
|
||||
|
||||
ret_code = ixmlParseBufferEx( xml_buf, xmlDoc );
|
||||
free( xml_buf );
|
||||
|
@ -196,11 +196,12 @@ addToAction( IN int response,
|
||||
|
||||
if( response ) {
|
||||
sprintf( ActBuff,
|
||||
"<u:%sResponse xmlns:u=\"%s\"></u:%sResponse>",
|
||||
ActionName, ServType, ActionName );
|
||||
"<u:%sResponse xmlns:u=\"%s\">\r\n</u:%sResponse>",
|
||||
ActionName, ServType, ActionName );
|
||||
} else {
|
||||
sprintf( ActBuff, "<u:%s xmlns:u=\"%s\"></u:%s>",
|
||||
ActionName, ServType, ActionName );
|
||||
sprintf( ActBuff,
|
||||
"<u:%s xmlns:u=\"%s\">\r\n</u:%s>",
|
||||
ActionName, ServType, ActionName );
|
||||
}
|
||||
|
||||
rc = ixmlParseBufferEx( ActBuff, ActionDoc );
|
||||
@ -274,11 +275,13 @@ makeAction( IN int response,
|
||||
}
|
||||
|
||||
if( response ) {
|
||||
sprintf( ActBuff, "<u:%sResponse xmlns:u=\"%s\"></u:%sResponse>",
|
||||
ActionName, ServType, ActionName );
|
||||
sprintf( ActBuff,
|
||||
"<u:%sResponse xmlns:u=\"%s\">\r\n</u:%sResponse>",
|
||||
ActionName, ServType, ActionName );
|
||||
} else {
|
||||
sprintf( ActBuff, "<u:%s xmlns:u=\"%s\"></u:%s>",
|
||||
ActionName, ServType, ActionName );
|
||||
sprintf( ActBuff,
|
||||
"<u:%s xmlns:u=\"%s\">\r\n</u:%s>",
|
||||
ActionName, ServType, ActionName );
|
||||
}
|
||||
|
||||
if( ixmlParseBufferEx( ActBuff, &ActionDoc ) != IXML_SUCCESS ) {
|
||||
|
@ -219,10 +219,11 @@ gena_unsubscribe( IN char *url,
|
||||
// make request msg
|
||||
membuffer_init( &request );
|
||||
request.size_inc = 30;
|
||||
return_code = http_MakeMessage( &request, 1, 1,
|
||||
"q" "ssc" "U" "c",
|
||||
HTTPMETHOD_UNSUBSCRIBE, &dest_url,
|
||||
"SID: ", sid );
|
||||
return_code = http_MakeMessage(
|
||||
&request, 1, 1,
|
||||
"q" "ssc" "Uc",
|
||||
HTTPMETHOD_UNSUBSCRIBE, &dest_url,
|
||||
"SID: ", sid );
|
||||
|
||||
//Not able to make the message so destroy the existing buffer
|
||||
if( return_code != 0 ) {
|
||||
@ -305,20 +306,21 @@ gena_subscribe( IN char *url,
|
||||
request.size_inc = 30;
|
||||
if( renewal_sid ) {
|
||||
// renew subscription
|
||||
return_code = http_MakeMessage( &request, 1, 1,
|
||||
"q" "ssc" "ssc" "c",
|
||||
HTTPMETHOD_SUBSCRIBE, &dest_url,
|
||||
"SID: ", renewal_sid,
|
||||
"TIMEOUT: Second-", timeout_str );
|
||||
return_code = http_MakeMessage(
|
||||
&request, 1, 1,
|
||||
"q" "ssc" "sscc",
|
||||
HTTPMETHOD_SUBSCRIBE, &dest_url,
|
||||
"SID: ", renewal_sid,
|
||||
"TIMEOUT: Second-", timeout_str );
|
||||
} else {
|
||||
// subscribe
|
||||
return_code = http_MakeMessage( &request, 1, 1,
|
||||
"q" "sssdsscc",
|
||||
HTTPMETHOD_SUBSCRIBE, &dest_url,
|
||||
"CALLBACK: <http://", LOCAL_HOST,
|
||||
":", LOCAL_PORT,
|
||||
"/>\r\n" "NT: upnp:event\r\n"
|
||||
"TIMEOUT: Second-", timeout_str );
|
||||
return_code = http_MakeMessage(
|
||||
&request, 1, 1,
|
||||
"q" "sssdsc" "sc" "sscc",
|
||||
HTTPMETHOD_SUBSCRIBE, &dest_url,
|
||||
"CALLBACK: <http://", LOCAL_HOST, ":", LOCAL_PORT, "/>",
|
||||
"NT: upnp:event",
|
||||
"TIMEOUT: Second-", timeout_str );
|
||||
}
|
||||
if( return_code != 0 ) {
|
||||
return return_code;
|
||||
|
@ -219,9 +219,11 @@ notify_send_and_recv( IN uri_type * destination_url,
|
||||
}
|
||||
// make start line and HOST header
|
||||
membuffer_init( &start_msg );
|
||||
if( http_MakeMessage( &start_msg, 1, 1,
|
||||
"q" "s",
|
||||
HTTPMETHOD_NOTIFY, &url, mid_msg->buf ) != 0 ) {
|
||||
if (http_MakeMessage(
|
||||
&start_msg, 1, 1,
|
||||
"q" "s",
|
||||
HTTPMETHOD_NOTIFY, &url,
|
||||
mid_msg->buf ) != 0 ) {
|
||||
membuffer_destroy( &start_msg );
|
||||
sock_destroy( &info, SD_BOTH );
|
||||
return UPNP_E_OUTOF_MEMORY;
|
||||
@ -296,11 +298,12 @@ genaNotify( IN char *headers,
|
||||
|
||||
// make 'end' msg (the part that won't vary with the destination)
|
||||
endmsg.size_inc = 30;
|
||||
if( http_MakeMessage( &mid_msg, 1, 1,
|
||||
"s" "ssc" "sdcc",
|
||||
headers,
|
||||
"SID: ", sub->sid,
|
||||
"SEQ: ", sub->ToSendEventKey ) != 0 ) {
|
||||
if( http_MakeMessage(
|
||||
&mid_msg, 1, 1,
|
||||
"s" "ssc" "sdcc",
|
||||
headers,
|
||||
"SID: ", sub->sid,
|
||||
"SEQ: ", sub->ToSendEventKey ) != 0 ) {
|
||||
membuffer_destroy( &mid_msg );
|
||||
return UPNP_E_OUTOF_MEMORY;
|
||||
}
|
||||
@ -1165,10 +1168,14 @@ respond_ok( IN SOCKINFO * info,
|
||||
|
||||
membuffer_init( &response );
|
||||
response.size_inc = 30;
|
||||
if( http_MakeMessage( &response, major, minor,
|
||||
"R" "D" "S" "N" "Xc" "ssc" "sc" "c",
|
||||
HTTP_OK, 0, X_USER_AGENT,
|
||||
"SID: ", sub->sid, timeout_str ) != 0 ) {
|
||||
if( http_MakeMessage(
|
||||
&response, major, minor,
|
||||
"R" "D" "S" "N" "Xc" "ssc" "scc",
|
||||
HTTP_OK,
|
||||
(off_t)0,
|
||||
X_USER_AGENT,
|
||||
"SID: ", sub->sid,
|
||||
timeout_str ) != 0 ) {
|
||||
membuffer_destroy( &response );
|
||||
error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
|
||||
return UPNP_E_OUTOF_MEMORY;
|
||||
|
@ -651,6 +651,11 @@ get_miniserver_sockets( MiniServerSockArray * out,
|
||||
sizeof( struct sockaddr_in )
|
||||
);
|
||||
if( sockError == UPNP_SOCKETERROR ) {
|
||||
#ifdef WIN32
|
||||
errCode = WSAGetLastError();
|
||||
#else
|
||||
errCode = errno;
|
||||
#endif
|
||||
if( errno == EADDRINUSE )
|
||||
errCode = 1;
|
||||
} else
|
||||
|
@ -306,8 +306,8 @@ http_SendMessage( IN SOCKINFO * info,
|
||||
char *filename = NULL;
|
||||
FILE *Fp;
|
||||
int num_read,
|
||||
num_written,
|
||||
amount_to_be_read = 0;
|
||||
num_written;
|
||||
off_t amount_to_be_read = 0;
|
||||
va_list argp;
|
||||
char *file_buf = NULL,
|
||||
*ChunkBuf = NULL;
|
||||
@ -367,7 +367,7 @@ http_SendMessage( IN SOCKINFO * info,
|
||||
return UPNP_E_FILE_READ_ERROR;
|
||||
}
|
||||
} else if( Instr && Instr->IsRangeActive ) {
|
||||
if( fseek( Fp, Instr->RangeOffset, SEEK_CUR ) != 0 ) {
|
||||
if( fseeko( Fp, Instr->RangeOffset, SEEK_CUR ) != 0 ) {
|
||||
free( ChunkBuf );
|
||||
return UPNP_E_FILE_READ_ERROR;
|
||||
}
|
||||
@ -640,10 +640,11 @@ http_Download( IN const char *url_str,
|
||||
"HOSTNAME : %s Length : %d\n", hoststr, hostlen );
|
||||
)
|
||||
|
||||
ret_code = http_MakeMessage( &request, 1, 1, "QsbcDCUc",
|
||||
HTTPMETHOD_GET, url.pathquery.buff,
|
||||
url.pathquery.size, "HOST: ", hoststr,
|
||||
hostlen );
|
||||
ret_code = http_MakeMessage(
|
||||
&request, 1, 1,
|
||||
"QsbcDCUc",
|
||||
HTTPMETHOD_GET, url.pathquery.buff, url.pathquery.size,
|
||||
"HOST: ", hoststr, hostlen );
|
||||
if( ret_code != 0 ) {
|
||||
DBGONLY( UpnpPrintf
|
||||
( UPNP_INFO, HTTP, __FILE__, __LINE__,
|
||||
@ -796,21 +797,27 @@ MakePostMessage( const char *url_str,
|
||||
)
|
||||
|
||||
if( contentLength >= 0 ) {
|
||||
ret_code = http_MakeMessage( request, 1, 1, "QsbcDCUTNc",
|
||||
HTTPMETHOD_POST, url->pathquery.buff,
|
||||
url->pathquery.size, "HOST: ",
|
||||
hoststr, hostlen, contentType,
|
||||
contentLength );
|
||||
ret_code = http_MakeMessage(
|
||||
request, 1, 1,
|
||||
"QsbcDCUTNc",
|
||||
HTTPMETHOD_POST, url->pathquery.buff, url->pathquery.size,
|
||||
"HOST: ", hoststr, hostlen,
|
||||
contentType,
|
||||
(off_t)contentLength );
|
||||
} else if( contentLength == UPNP_USING_CHUNKED ) {
|
||||
ret_code = http_MakeMessage( request, 1, 1, "QsbcDCUTKc",
|
||||
HTTPMETHOD_POST, url->pathquery.buff,
|
||||
url->pathquery.size, "HOST: ",
|
||||
hoststr, hostlen, contentType );
|
||||
ret_code = http_MakeMessage(
|
||||
request, 1, 1,
|
||||
"QsbcDCUTKc",
|
||||
HTTPMETHOD_POST, url->pathquery.buff, url->pathquery.size,
|
||||
"HOST: ", hoststr, hostlen,
|
||||
contentType );
|
||||
} else if( contentLength == UPNP_UNTIL_CLOSE ) {
|
||||
ret_code = http_MakeMessage( request, 1, 1, "QsbcDCUTc",
|
||||
HTTPMETHOD_POST, url->pathquery.buff,
|
||||
url->pathquery.size, "HOST: ",
|
||||
hoststr, hostlen, contentType );
|
||||
ret_code = http_MakeMessage(
|
||||
request, 1, 1,
|
||||
"QsbcDCUTc",
|
||||
HTTPMETHOD_POST, url->pathquery.buff, url->pathquery.size,
|
||||
"HOST: ", hoststr, hostlen,
|
||||
contentType );
|
||||
} else {
|
||||
ret_code = UPNP_E_INVALID_PARAM;
|
||||
}
|
||||
@ -1131,9 +1138,11 @@ MakeGetMessage( const char *url_str,
|
||||
querylen = url->pathquery.size;
|
||||
}
|
||||
|
||||
ret_code = http_MakeMessage( request, 1, 1, "QsbcDCUc",
|
||||
HTTPMETHOD_GET, querystr, querylen,
|
||||
"HOST: ", hoststr, hostlen );
|
||||
ret_code = http_MakeMessage(
|
||||
request, 1, 1,
|
||||
"QsbcDCUc",
|
||||
HTTPMETHOD_GET, querystr, querylen,
|
||||
"HOST: ", hoststr, hostlen );
|
||||
|
||||
if( ret_code != 0 ) {
|
||||
DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
|
||||
@ -1729,8 +1738,11 @@ http_SendStatusResponse( IN SOCKINFO * info,
|
||||
membuffer_init( &membuf );
|
||||
membuf.size_inc = 70;
|
||||
|
||||
ret = http_MakeMessage( &membuf, response_major, response_minor, "RSCB", http_status_code, // response start line
|
||||
http_status_code ); // body
|
||||
ret = http_MakeMessage(
|
||||
&membuf, response_major, response_minor,
|
||||
"RSCB",
|
||||
http_status_code, // response start line
|
||||
http_status_code ); // body
|
||||
if( ret == 0 ) {
|
||||
timeout = HTTP_DEFAULT_TIMEOUT;
|
||||
ret = http_SendMessage( info, &timeout, "b",
|
||||
@ -1757,28 +1769,30 @@ http_SendStatusResponse( IN SOCKINFO * info,
|
||||
* specified in the input parameters.
|
||||
*
|
||||
* fmt types:
|
||||
* 's': arg = const char* C_string
|
||||
* 'B': arg = int status_code
|
||||
* appends content-length, content-type and HTML body for given code
|
||||
* 'b': arg1 = const char* buf; arg2 = size_t buf_length
|
||||
* memory ptr
|
||||
* 'c': (no args) appends CRLF "\r\n"
|
||||
* 'd': arg = int number // appends decimal number
|
||||
* 't': arg = time_t * gmt_time // appends time in RFC 1123 fmt
|
||||
* 'D': (no args) appends HTTP DATE: header
|
||||
* 'S': (no args) appends HTTP SERVER: header
|
||||
* 'U': (no args) appends HTTP USER-AGENT: header
|
||||
* 'C': (no args) appends a HTTP CONNECTION: close header
|
||||
* depending on major,minor version
|
||||
* 'c': (no args) appends CRLF "\r\n"
|
||||
* 'D': (no args) appends HTTP DATE: header
|
||||
* 'd': arg = int number // appends decimal number
|
||||
* 'G': arg = range information // add range header
|
||||
* 'h': arg = off_t number // appends off_t number
|
||||
* 'K': (no args) // add chunky header
|
||||
* 'N': arg1 = int content_length // content-length header
|
||||
* 'q': arg1 = http_method_t, arg2 = (uri_type *) // request start line and HOST header
|
||||
* 'Q': arg1 = http_method_t; arg2 = char* url;
|
||||
* arg3 = int url_length // start line of request
|
||||
* 'R': arg = int status_code // adds a response start line
|
||||
* 'B': arg = int status_code
|
||||
* appends content-length, content-type and HTML body for given code
|
||||
* 'S': (no args) appends HTTP SERVER: header
|
||||
* 's': arg = const char* C_string
|
||||
* 'T': arg = char * content_type; format e.g: "text/html";
|
||||
* content-type header
|
||||
* --- PATCH START - Sergey 'Jin' Bostandzhyan <jin_eld@users.sourceforge.net>
|
||||
* 'X': arg = const char useragent; "redsonic" HTTP X-User-Agent: useragent
|
||||
* --- PATCH END ---
|
||||
* 't': arg = time_t * gmt_time // appends time in RFC 1123 fmt
|
||||
* 'U': (no args) appends HTTP USER-AGENT: header
|
||||
* 'X': arg = const char useragent; "redsonic" HTTP X-User-Agent: useragent
|
||||
*
|
||||
* Return : int;
|
||||
* 0 - On Success
|
||||
@ -1797,6 +1811,7 @@ http_MakeMessage( INOUT membuffer * buf,
|
||||
char c;
|
||||
char *s = NULL;
|
||||
int num;
|
||||
off_t bignum;
|
||||
size_t length;
|
||||
time_t *loc_time;
|
||||
time_t curr_time;
|
||||
@ -1884,6 +1899,16 @@ http_MakeMessage( INOUT membuffer * buf,
|
||||
}
|
||||
}
|
||||
|
||||
else if( c == 'h' ) // off_t
|
||||
{
|
||||
bignum = ( off_t )va_arg( argp, off_t );
|
||||
|
||||
sprintf( tempbuf, "%lld", bignum );
|
||||
if( membuffer_append( buf, tempbuf, strlen( tempbuf ) ) != 0 ) {
|
||||
goto error_handler;
|
||||
}
|
||||
}
|
||||
|
||||
else if( c == 't' || c == 'D' ) // date
|
||||
{
|
||||
if( c == 'D' ) {
|
||||
@ -1925,12 +1950,13 @@ http_MakeMessage( INOUT membuffer * buf,
|
||||
|
||||
else if( c == 'N' ) {
|
||||
// content-length header
|
||||
num = ( int )va_arg( argp, int );
|
||||
bignum = ( off_t )va_arg( argp, off_t );
|
||||
|
||||
assert( num >= 0 );
|
||||
if( http_MakeMessage
|
||||
( buf, http_major_version, http_minor_version, "sdc",
|
||||
"CONTENT-LENGTH: ", num ) != 0 ) {
|
||||
assert( bignum >= 0 );
|
||||
if (http_MakeMessage(
|
||||
buf, http_major_version, http_minor_version,
|
||||
"shc",
|
||||
"CONTENT-LENGTH: ", bignum ) != 0 ) {
|
||||
goto error_handler;
|
||||
}
|
||||
}
|
||||
@ -1940,14 +1966,14 @@ http_MakeMessage( INOUT membuffer * buf,
|
||||
|
||||
temp_str = ( c == 'S' ) ? "SERVER: " : "USER-AGENT: ";
|
||||
get_sdk_info( tempbuf );
|
||||
if( http_MakeMessage
|
||||
( buf, http_major_version, http_minor_version, "ss",
|
||||
temp_str, tempbuf ) != 0 ) {
|
||||
if (http_MakeMessage(
|
||||
buf, http_major_version, http_minor_version,
|
||||
"ss",
|
||||
temp_str, tempbuf ) != 0 ) {
|
||||
goto error_handler;
|
||||
}
|
||||
}
|
||||
|
||||
/* --- PATCH START - Sergey 'Jin' Bostandzhyan <jin_eld@users.sourceforge.net> */
|
||||
else if( c == 'X' ) // C string
|
||||
{
|
||||
s = ( char * )va_arg( argp, char * );
|
||||
@ -1962,9 +1988,6 @@ http_MakeMessage( INOUT membuffer * buf,
|
||||
}
|
||||
}
|
||||
|
||||
/* --- PATCH END --- */
|
||||
|
||||
|
||||
else if( c == 'R' ) {
|
||||
// response start line
|
||||
// e.g.: 'HTTP/1.1 200 OK'
|
||||
@ -1979,9 +2002,11 @@ http_MakeMessage( INOUT membuffer * buf,
|
||||
|
||||
// str
|
||||
status_msg = http_get_code_text( status_code );
|
||||
if( http_MakeMessage
|
||||
( buf, http_major_version, http_minor_version, "ssc",
|
||||
tempbuf, status_msg ) != 0 ) {
|
||||
if (http_MakeMessage(
|
||||
buf, http_major_version, http_minor_version,
|
||||
"ssc",
|
||||
tempbuf,
|
||||
status_msg ) != 0 ) {
|
||||
goto error_handler;
|
||||
}
|
||||
}
|
||||
@ -1996,11 +2021,14 @@ http_MakeMessage( INOUT membuffer * buf,
|
||||
"<html><body><h1>",
|
||||
status_code, http_get_code_text( status_code ),
|
||||
"</h1></body></html>" );
|
||||
num = strlen( tempbuf );
|
||||
bignum = strlen( tempbuf );
|
||||
|
||||
if( http_MakeMessage( buf, http_major_version, http_minor_version, "NTcs", num, // content-length
|
||||
"text/html", // content-type
|
||||
tempbuf ) != 0 ) // body
|
||||
if (http_MakeMessage(
|
||||
buf, http_major_version, http_minor_version,
|
||||
"NTcs",
|
||||
bignum, // content-length
|
||||
"text/html", // content-type
|
||||
tempbuf ) != 0 ) // body
|
||||
{
|
||||
goto error_handler;
|
||||
}
|
||||
@ -2009,17 +2037,18 @@ http_MakeMessage( INOUT membuffer * buf,
|
||||
else if( c == 'Q' ) {
|
||||
// request start line
|
||||
// GET /foo/bar.html HTTP/1.1\r\n
|
||||
//
|
||||
|
||||
method = ( http_method_t ) va_arg( argp, http_method_t );
|
||||
method_str = method_to_str( method );
|
||||
url_str = ( const char * )va_arg( argp, const char * );
|
||||
num = ( int )va_arg( argp, int ); // length of url_str
|
||||
|
||||
if( http_MakeMessage( buf, http_major_version, http_minor_version, "ssbsdsdc", method_str, // method
|
||||
" ", url_str, num, // url
|
||||
" HTTP/", http_major_version, ".",
|
||||
http_minor_version ) != 0 ) {
|
||||
if (http_MakeMessage(
|
||||
buf, http_major_version, http_minor_version,
|
||||
"ssbsdsdc",
|
||||
method_str, // method
|
||||
" ", url_str, num, // url
|
||||
" HTTP/", http_major_version, ".", http_minor_version ) != 0 ) {
|
||||
goto error_handler;
|
||||
}
|
||||
}
|
||||
@ -2036,10 +2065,11 @@ http_MakeMessage( INOUT membuffer * buf,
|
||||
goto error_handler;
|
||||
}
|
||||
|
||||
if( http_MakeMessage
|
||||
( buf, http_major_version, http_minor_version, "Q" "sbc",
|
||||
method, url.pathquery.buff, url.pathquery.size, "HOST: ",
|
||||
url.hostport.text.buff, url.hostport.text.size ) != 0 ) {
|
||||
if (http_MakeMessage(
|
||||
buf, http_major_version, http_minor_version,
|
||||
"Q" "sbc",
|
||||
method, url.pathquery.buff, url.pathquery.size,
|
||||
"HOST: ", url.hostport.text.buff, url.hostport.text.size ) != 0 ) {
|
||||
goto error_handler;
|
||||
}
|
||||
}
|
||||
@ -2048,9 +2078,10 @@ http_MakeMessage( INOUT membuffer * buf,
|
||||
// content type header
|
||||
temp_str = ( const char * )va_arg( argp, const char * ); // type/subtype format
|
||||
|
||||
if( http_MakeMessage
|
||||
( buf, http_major_version, http_minor_version, "ssc",
|
||||
"CONTENT-TYPE: ", temp_str ) != 0 ) {
|
||||
if (http_MakeMessage(
|
||||
buf, http_major_version, http_minor_version,
|
||||
"ssc",
|
||||
"CONTENT-TYPE: ", temp_str ) != 0 ) {
|
||||
goto error_handler;
|
||||
}
|
||||
}
|
||||
@ -2174,16 +2205,13 @@ MakeGetMessageEx( const char *url_str,
|
||||
hostlen );
|
||||
)
|
||||
|
||||
errCode = http_MakeMessage( request,
|
||||
1,
|
||||
1,
|
||||
"QsbcGDCUc",
|
||||
HTTPMETHOD_GET,
|
||||
url->pathquery.buff,
|
||||
url->pathquery.size,
|
||||
"HOST: ",
|
||||
hoststr,
|
||||
hostlen, pRangeSpecifier );
|
||||
errCode = http_MakeMessage(
|
||||
request, 1, 1,
|
||||
"QsbcGDCUc",
|
||||
HTTPMETHOD_GET,
|
||||
url->pathquery.buff, url->pathquery.size,
|
||||
"HOST: ", hoststr, hostlen,
|
||||
pRangeSpecifier );
|
||||
|
||||
if( errCode != 0 ) {
|
||||
DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
|
||||
|
@ -632,7 +632,7 @@ get_file_info( IN const char *filename,
|
||||
rc = get_content_type( filename, &info->content_type );
|
||||
|
||||
DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
|
||||
"file info: %s, length: %d, last_mod=%s readable=%d\n",
|
||||
"file info: %s, length: %lld, last_mod=%s readable=%d\n",
|
||||
filename, info->file_length,
|
||||
asctime( gmtime( &info->last_modified ) ),
|
||||
info->is_readable ); )
|
||||
@ -871,8 +871,8 @@ StrTok( char **Src,
|
||||
************************************************************************/
|
||||
int
|
||||
GetNextRange( char **SrcRangeStr,
|
||||
int *FirstByte,
|
||||
int *LastByte )
|
||||
off_t *FirstByte,
|
||||
off_t *LastByte )
|
||||
{
|
||||
char *Ptr,
|
||||
*Tok;
|
||||
@ -936,11 +936,11 @@ GetNextRange( char **SrcRangeStr,
|
||||
************************************************************************/
|
||||
int
|
||||
CreateHTTPRangeResponseHeader( char *ByteRangeSpecifier,
|
||||
long FileLength,
|
||||
off_t FileLength,
|
||||
OUT struct SendInstruction *Instr )
|
||||
{
|
||||
|
||||
int FirstByte,
|
||||
off_t FirstByte,
|
||||
LastByte;
|
||||
char *RangeInput,
|
||||
*Ptr;
|
||||
@ -984,26 +984,26 @@ CreateHTTPRangeResponseHeader( char *ByteRangeSpecifier,
|
||||
|
||||
Instr->RangeOffset = FirstByte;
|
||||
Instr->ReadSendSize = LastByte - FirstByte + 1;
|
||||
sprintf( Instr->RangeHeader, "CONTENT-RANGE: bytes %d-%d/%ld\r\n", FirstByte, LastByte, FileLength ); //Data between two range.
|
||||
sprintf( Instr->RangeHeader, "CONTENT-RANGE: bytes %lld-%lld/%lld\r\n", FirstByte, LastByte, FileLength ); //Data between two range.
|
||||
} else if( FirstByte >= 0 && LastByte == -1
|
||||
&& FirstByte < FileLength ) {
|
||||
Instr->RangeOffset = FirstByte;
|
||||
Instr->ReadSendSize = FileLength - FirstByte;
|
||||
sprintf( Instr->RangeHeader,
|
||||
"CONTENT-RANGE: bytes %d-%ld/%ld\r\n", FirstByte,
|
||||
"CONTENT-RANGE: bytes %lld-%lld/%lld\r\n", FirstByte,
|
||||
FileLength - 1, FileLength );
|
||||
} else if( FirstByte == -1 && LastByte > 0 ) {
|
||||
if( LastByte >= FileLength ) {
|
||||
Instr->RangeOffset = 0;
|
||||
Instr->ReadSendSize = FileLength;
|
||||
sprintf( Instr->RangeHeader,
|
||||
"CONTENT-RANGE: bytes 0-%ld/%ld\r\n",
|
||||
"CONTENT-RANGE: bytes 0-%lld/%lld\r\n",
|
||||
FileLength - 1, FileLength );
|
||||
} else {
|
||||
Instr->RangeOffset = FileLength - LastByte;
|
||||
Instr->ReadSendSize = LastByte;
|
||||
sprintf( Instr->RangeHeader,
|
||||
"CONTENT-RANGE: bytes %ld-%ld/%ld\r\n",
|
||||
"CONTENT-RANGE: bytes %lld-%lld/%lld\r\n",
|
||||
FileLength - LastByte + 1, FileLength,
|
||||
FileLength );
|
||||
}
|
||||
@ -1042,7 +1042,7 @@ CreateHTTPRangeResponseHeader( char *ByteRangeSpecifier,
|
||||
int
|
||||
CheckOtherHTTPHeaders( IN http_message_t * Req,
|
||||
OUT struct SendInstruction *RespInstr,
|
||||
int FileSize )
|
||||
off_t FileSize )
|
||||
{
|
||||
http_header_t *header;
|
||||
ListNode *node;
|
||||
@ -1184,7 +1184,6 @@ process_request( IN http_message_t * req,
|
||||
int code;
|
||||
int err_code;
|
||||
|
||||
//membuffer content_type;
|
||||
char *request_doc;
|
||||
struct File_Info finfo;
|
||||
xboolean using_alias;
|
||||
@ -1208,7 +1207,6 @@ process_request( IN http_message_t * req,
|
||||
// init
|
||||
request_doc = NULL;
|
||||
finfo.content_type = NULL;
|
||||
//membuffer_init( &content_type );
|
||||
alias_grabbed = FALSE;
|
||||
err_code = HTTP_INTERNAL_SERVER_ERROR; // default error
|
||||
using_virtual_dir = FALSE;
|
||||
@ -1362,7 +1360,7 @@ process_request( IN http_message_t * req,
|
||||
|
||||
RespInstr->ReadSendSize = finfo.file_length;
|
||||
|
||||
//Check other header field.
|
||||
// Check other header field.
|
||||
if( ( err_code =
|
||||
CheckOtherHTTPHeaders( req, RespInstr,
|
||||
finfo.file_length ) ) != HTTP_OK ) {
|
||||
@ -1376,85 +1374,80 @@ process_request( IN http_message_t * req,
|
||||
}
|
||||
|
||||
if( RespInstr->IsRangeActive && RespInstr->IsChunkActive ) {
|
||||
|
||||
/* - PATCH START - Sergey 'Jin' Bostandzhyan <jin_eld at users.sourceforge.net>
|
||||
* added X-User-Agent header
|
||||
*/
|
||||
|
||||
//Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT
|
||||
//Transfer-Encoding: chunked
|
||||
// K means add chunky header ang G means range header.
|
||||
if( http_MakeMessage( headers, resp_major, resp_minor, "RTGKDstcSXcCc", HTTP_PARTIAL_CONTENT, // status code
|
||||
// RespInstr->ReadSendSize,// content length
|
||||
finfo.content_type,
|
||||
// content_type.buf, // content type
|
||||
RespInstr, // Range
|
||||
"LAST-MODIFIED: ",
|
||||
&finfo.last_modified,
|
||||
X_USER_AGENT) != 0 ) {
|
||||
// Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT
|
||||
// Transfer-Encoding: chunked
|
||||
if (http_MakeMessage(
|
||||
headers, resp_major, resp_minor,
|
||||
"R" "T" "GKD" "s" "tcS" "XcCc",
|
||||
HTTP_PARTIAL_CONTENT, // status code
|
||||
finfo.content_type, // content type
|
||||
RespInstr, // range info
|
||||
"LAST-MODIFIED: ",
|
||||
&finfo.last_modified,
|
||||
X_USER_AGENT) != 0 ) {
|
||||
goto error_handler;
|
||||
}
|
||||
} else if( RespInstr->IsRangeActive && !RespInstr->IsChunkActive ) {
|
||||
|
||||
//Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT
|
||||
//Transfer-Encoding: chunked
|
||||
// K means add chunky header ang G means range header.
|
||||
if( http_MakeMessage( headers, resp_major, resp_minor, "RNTGDstcSXcCc", HTTP_PARTIAL_CONTENT, // status code
|
||||
RespInstr->ReadSendSize, // content length
|
||||
finfo.content_type,
|
||||
//content_type.buf, // content type
|
||||
RespInstr, //Range Info
|
||||
"LAST-MODIFIED: ",
|
||||
&finfo.last_modified,
|
||||
X_USER_AGENT) != 0 ) {
|
||||
// Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT
|
||||
// Transfer-Encoding: chunked
|
||||
if (http_MakeMessage(
|
||||
headers, resp_major, resp_minor,
|
||||
"R" "N" "T" "GD" "s" "tcS" "XcCc",
|
||||
HTTP_PARTIAL_CONTENT, // status code
|
||||
RespInstr->ReadSendSize, // content length
|
||||
finfo.content_type, // content type
|
||||
RespInstr, // range info
|
||||
"LAST-MODIFIED: ",
|
||||
&finfo.last_modified,
|
||||
X_USER_AGENT) != 0 ) {
|
||||
goto error_handler;
|
||||
}
|
||||
|
||||
} else if( !RespInstr->IsRangeActive && RespInstr->IsChunkActive ) {
|
||||
|
||||
//Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT
|
||||
//Transfer-Encoding: chunked
|
||||
// K means add chunky header ang G means range header.
|
||||
if( http_MakeMessage( headers, resp_major, resp_minor, "RKTDstcSXcCc", HTTP_OK, // status code
|
||||
//RespInstr->ReadSendSize,// content length
|
||||
finfo.content_type,
|
||||
// content_type.buf, // content type
|
||||
"LAST-MODIFIED: ",
|
||||
&finfo.last_modified,
|
||||
X_USER_AGENT) != 0 ) {
|
||||
// Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT
|
||||
// Transfer-Encoding: chunked
|
||||
if (http_MakeMessage(
|
||||
headers, resp_major, resp_minor,
|
||||
"RK" "TD" "s" "tcS" "XcCc",
|
||||
HTTP_OK, // status code
|
||||
finfo.content_type, // content type
|
||||
"LAST-MODIFIED: ",
|
||||
&finfo.last_modified,
|
||||
X_USER_AGENT) != 0 ) {
|
||||
goto error_handler;
|
||||
}
|
||||
|
||||
} else {
|
||||
if( RespInstr->ReadSendSize >= 0 ) {
|
||||
//Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT
|
||||
//Transfer-Encoding: chunked
|
||||
// K means add chunky header ang G means range header.
|
||||
if( http_MakeMessage( headers, resp_major, resp_minor, "RNTDstcSXcCc", HTTP_OK, // status code
|
||||
RespInstr->ReadSendSize, // content length
|
||||
finfo.content_type,
|
||||
//content_type.buf, // content type
|
||||
"LAST-MODIFIED: ",
|
||||
&finfo.last_modified,
|
||||
X_USER_AGENT) != 0 ) {
|
||||
} else { // !RespInstr->IsRangeActive && !RespInstr->IsChunkActive
|
||||
if (RespInstr->ReadSendSize >= 0) {
|
||||
// Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT
|
||||
// Transfer-Encoding: chunked
|
||||
if (http_MakeMessage(
|
||||
headers, resp_major, resp_minor,
|
||||
"R" "N" "TD" "s" "tcS" "XcCc",
|
||||
HTTP_OK, // status code
|
||||
RespInstr->ReadSendSize, // content length
|
||||
finfo.content_type, // content type
|
||||
"LAST-MODIFIED: ",
|
||||
&finfo.last_modified,
|
||||
X_USER_AGENT) != 0 ) {
|
||||
goto error_handler;
|
||||
}
|
||||
} else {
|
||||
//Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT
|
||||
//Transfer-Encoding: chunked
|
||||
// K means add chunky header ang G means range header.
|
||||
if( http_MakeMessage( headers, resp_major, resp_minor, "RTDstcSXcCc", HTTP_OK, // status code
|
||||
//RespInstr->ReadSendSize,// content length
|
||||
finfo.content_type,
|
||||
//content_type.buf, // content type
|
||||
"LAST-MODIFIED: ",
|
||||
&finfo.last_modified,
|
||||
X_USER_AGENT) != 0 ) {
|
||||
// Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT
|
||||
// Transfer-Encoding: chunked
|
||||
if (http_MakeMessage(
|
||||
headers, resp_major, resp_minor,
|
||||
"R" "TD" "s" "tcS" "XcCc",
|
||||
HTTP_OK, // status code
|
||||
finfo.content_type, // content type
|
||||
"LAST-MODIFIED: ",
|
||||
&finfo.last_modified,
|
||||
X_USER_AGENT) != 0 ) {
|
||||
goto error_handler;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* -- PATCH END -- */
|
||||
|
||||
if( req->method == HTTPMETHOD_HEAD ) {
|
||||
*rtype = RESP_HEADERS;
|
||||
@ -1468,8 +1461,8 @@ process_request( IN http_message_t * req,
|
||||
*rtype = RESP_FILEDOC;
|
||||
}
|
||||
|
||||
//simple get http 0.9 as specified in http 1.0
|
||||
//don't send headers
|
||||
// simple get http 0.9 as specified in http 1.0
|
||||
// don't send headers
|
||||
if( req->method == HTTPMETHOD_SIMPLEGET ) {
|
||||
membuffer_destroy( headers );
|
||||
}
|
||||
@ -1479,7 +1472,6 @@ process_request( IN http_message_t * req,
|
||||
error_handler:
|
||||
free( request_doc );
|
||||
ixmlFreeDOMString( finfo.content_type );
|
||||
// membuffer_destroy( &content_type );
|
||||
if( err_code != UPNP_E_SUCCESS && alias_grabbed ) {
|
||||
alias_release( alias );
|
||||
}
|
||||
@ -1738,12 +1730,12 @@ web_server_callback( IN http_parser_t * parser,
|
||||
&RespInstr );
|
||||
//Send response.
|
||||
|
||||
/* - PATCH START - Sergey 'Jin' Bostandzhyan <jin_eld at users.sourceforge.net>
|
||||
* added X-User-Agent header
|
||||
*/
|
||||
http_MakeMessage( &headers, 1, 1, "RTDSXcCc", ret,
|
||||
"text/html", X_USER_AGENT );
|
||||
/* - PATCH END --- */
|
||||
http_MakeMessage(
|
||||
&headers, 1, 1,
|
||||
"RTDSXcCc",
|
||||
ret,
|
||||
"text/html",
|
||||
X_USER_AGENT );
|
||||
|
||||
http_SendMessage( info, &timeout, "b", headers.buf,
|
||||
headers.length );
|
||||
|
@ -95,6 +95,17 @@
|
||||
#define MAX_THREADS 12
|
||||
//@}
|
||||
|
||||
/** @name MAX_JOBS_TOTAL
|
||||
* The {\tt MAX_JOBS_TOTAL} constant determines the maximum number of jobs
|
||||
* that can be queued. If this limit is reached further jobs will be thrown
|
||||
* to avoid memory exhaustion. The default value 100.
|
||||
* (Added by Axis.)
|
||||
*/
|
||||
|
||||
//@{
|
||||
#define MAX_JOBS_TOTAL 100
|
||||
//@}
|
||||
|
||||
/** @name DEFAULT_SOAP_CONTENT_LENGTH
|
||||
* SOAP messages will read at most {\tt DEFAULT_SOAP_CONTENT_LENGTH} bytes.
|
||||
* This prevents devices that have a misbehaving web server to send
|
||||
|
@ -475,6 +475,7 @@ int http_SendStatusResponse( IN SOCKINFO *info, IN int http_status_code,
|
||||
* memory ptr
|
||||
* 'c': (no args) appends CRLF "\r\n"
|
||||
* 'd': arg = int number // appends decimal number
|
||||
* 'h': arg = off_t number // appends off_t number
|
||||
* 't': arg = time_t * gmt_time // appends time in RFC 1123 fmt
|
||||
* 'D': (no args) appends HTTP DATE: header
|
||||
* 'S': (no args) appends HTTP SERVER: header
|
||||
|
@ -80,7 +80,7 @@ typedef enum SsdpCmdType{SSDP_ERROR=-1,
|
||||
#define SSDP_IP "239.255.255.250"
|
||||
#define SSDP_PORT 1900
|
||||
#define NUM_TRY 3
|
||||
#define NUM_COPY 2
|
||||
#define NUM_COPY 1
|
||||
#define THREAD_LIMIT 50
|
||||
#define COMMAND_LEN 300
|
||||
|
||||
|
@ -48,8 +48,8 @@ struct SendInstruction
|
||||
int IsRangeActive;
|
||||
int IsTrailers;
|
||||
char RangeHeader[200];
|
||||
long RangeOffset;
|
||||
long ReadSendSize; // Read from local source and send on the network.
|
||||
off_t RangeOffset;
|
||||
off_t ReadSendSize; // Read from local source and send on the network.
|
||||
long RecvWriteSize; // Recv from the network and write into local file.
|
||||
|
||||
//Later few more member could be added depending on the requirement.
|
||||
|
@ -602,12 +602,15 @@ SoapSendAction( IN char *action_url,
|
||||
char *upnp_error_str;
|
||||
xboolean got_response = FALSE;
|
||||
|
||||
off_t content_length;
|
||||
char *xml_start =
|
||||
// "<?xml version=\"1.0\"?>\n" required??
|
||||
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "
|
||||
"s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n"
|
||||
"<s:Envelope "
|
||||
"xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "
|
||||
"s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n"
|
||||
"<s:Body>";
|
||||
char *xml_end = "</s:Body>\n" "</s:Envelope>\n";
|
||||
char *xml_end =
|
||||
"</s:Body>\r\n"
|
||||
"</s:Envelope>\r\n\r\n";
|
||||
int xml_start_len;
|
||||
int xml_end_len;
|
||||
int action_str_len;
|
||||
@ -645,18 +648,23 @@ SoapSendAction( IN char *action_url,
|
||||
url.hostport.text.size,
|
||||
url.hostport.text.buff ); )
|
||||
|
||||
xml_start_len = strlen( xml_start );
|
||||
xml_start_len = strlen( xml_start );
|
||||
xml_end_len = strlen( xml_end );
|
||||
action_str_len = strlen( action_str );
|
||||
|
||||
// make request msg
|
||||
request.size_inc = 50;
|
||||
if( http_MakeMessage( &request, 1, 1, "q" "N" "s" "sssbs" "U" "c" "bbb", SOAPMETHOD_POST, &url, xml_start_len + action_str_len + xml_end_len, // content-length
|
||||
ContentTypeHeader,
|
||||
"SOAPACTION: \"", service_type, "#", name.buf,
|
||||
name.length, "\"\r\n", xml_start, xml_start_len,
|
||||
action_str, action_str_len, xml_end,
|
||||
xml_end_len ) != 0 ) {
|
||||
content_length = xml_start_len + action_str_len + xml_end_len;
|
||||
if (http_MakeMessage(
|
||||
&request, 1, 1,
|
||||
"q" "N" "s" "sssbsc" "Uc" "b" "b" "b",
|
||||
SOAPMETHOD_POST, &url,
|
||||
content_length,
|
||||
ContentTypeHeader,
|
||||
"SOAPACTION: \"", service_type, "#", name.buf, name.length, "\"",
|
||||
xml_start, xml_start_len,
|
||||
action_str, action_str_len,
|
||||
xml_end, xml_end_len ) != 0 ) {
|
||||
goto error_handler;
|
||||
}
|
||||
|
||||
@ -737,20 +745,26 @@ SoapSendActionEx( IN char *action_url,
|
||||
xboolean got_response = FALSE;
|
||||
|
||||
char *xml_start =
|
||||
// "<?xml version=\"1.0\"?>\n" required??
|
||||
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "
|
||||
"s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n";
|
||||
char *xml_body_start = "<s:Body>";
|
||||
char *xml_end = "</s:Body>\n" "</s:Envelope>\n";
|
||||
"<s:Envelope "
|
||||
"xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "
|
||||
"s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n";
|
||||
char *xml_header_start =
|
||||
"<s:Header>\r\n";
|
||||
char *xml_header_end =
|
||||
"</s:Header>\r\n";
|
||||
char *xml_body_start =
|
||||
"<s:Body>";
|
||||
char *xml_end =
|
||||
"</s:Body>\r\n"
|
||||
"</s:Envelope>\r\n";
|
||||
int xml_start_len;
|
||||
int xml_end_len;
|
||||
char *xml_header_start = "<s:Header>\n";
|
||||
char *xml_header_end = "</s:Header>\n";
|
||||
int xml_header_start_len;
|
||||
int xml_header_end_len;
|
||||
int xml_header_str_len;
|
||||
int action_str_len;
|
||||
int xml_header_end_len;
|
||||
int xml_body_start_len;
|
||||
int action_str_len;
|
||||
int xml_end_len;
|
||||
off_t content_length;
|
||||
|
||||
*response_node = NULL; // init
|
||||
|
||||
@ -790,7 +804,7 @@ SoapSendActionEx( IN char *action_url,
|
||||
url.hostport.text.size,
|
||||
url.hostport.text.buff ); )
|
||||
|
||||
xml_start_len = strlen( xml_start );
|
||||
xml_start_len = strlen( xml_start );
|
||||
xml_body_start_len = strlen( xml_body_start );
|
||||
xml_end_len = strlen( xml_end );
|
||||
action_str_len = strlen( action_str );
|
||||
@ -801,17 +815,24 @@ SoapSendActionEx( IN char *action_url,
|
||||
|
||||
// make request msg
|
||||
request.size_inc = 50;
|
||||
if( http_MakeMessage( &request, 1, 1, "q" "N" "s" "sssbs" "U" "c" "bbbbbbb", SOAPMETHOD_POST, &url, xml_start_len + xml_header_start_len + xml_header_str_len + xml_header_end_len + xml_body_start_len + action_str_len + xml_end_len, // content-length
|
||||
ContentTypeHeader,
|
||||
"SOAPACTION: \"", service_type, "#", name.buf,
|
||||
name.length, "\"\r\n",
|
||||
xml_start, xml_start_len,
|
||||
xml_header_start, xml_header_start_len,
|
||||
xml_header_str, xml_header_str_len,
|
||||
xml_header_end, xml_header_end_len,
|
||||
xml_body_start, xml_body_start_len,
|
||||
action_str, action_str_len,
|
||||
xml_end, xml_end_len ) != 0 ) {
|
||||
content_length =
|
||||
xml_start_len +
|
||||
xml_header_start_len + xml_header_str_len + xml_header_end_len +
|
||||
xml_body_start_len + action_str_len + xml_end_len;
|
||||
if (http_MakeMessage(
|
||||
&request, 1, 1,
|
||||
"q" "N" "s" "sssbsc" "Uc" "bbbbbbb",
|
||||
SOAPMETHOD_POST, &url,
|
||||
content_length,
|
||||
ContentTypeHeader,
|
||||
"SOAPACTION: \"", service_type, "#", name.buf, name.length, "\"",
|
||||
xml_start, xml_start_len,
|
||||
xml_header_start, xml_header_start_len,
|
||||
xml_header_str, xml_header_str_len,
|
||||
xml_header_end, xml_header_end_len,
|
||||
xml_body_start, xml_body_start_len,
|
||||
action_str, action_str_len,
|
||||
xml_end, xml_end_len ) != 0 ) {
|
||||
goto error_handler;
|
||||
}
|
||||
|
||||
@ -882,16 +903,20 @@ SoapGetServiceVarStatus( IN char *action_url,
|
||||
http_parser_t response;
|
||||
int upnp_error_code;
|
||||
|
||||
off_t content_length;
|
||||
char *xml_start =
|
||||
// "<?xml version=\"1.0\"?>\n" required??
|
||||
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "
|
||||
"s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n"
|
||||
"<s:Body>\n"
|
||||
"<u:QueryStateVariable xmlns:u=\"urn:schemas-upnp-org:control-1-0\">\n"
|
||||
"<s:Envelope "
|
||||
"xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "
|
||||
"s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n"
|
||||
"<s:Body>\r\n"
|
||||
"<u:QueryStateVariable xmlns:u=\"urn:schemas-upnp-org:control-1-0\">\r\n"
|
||||
"<u:varName>";
|
||||
|
||||
char *xml_end = "</u:varName>\n"
|
||||
"</u:QueryStateVariable>\n" "</s:Body>\n" "</s:Envelope>\n";
|
||||
char *xml_end =
|
||||
"</u:varName>\r\n"
|
||||
"</u:QueryStateVariable>\r\n"
|
||||
"</s:Body>\r\n"
|
||||
"</s:Envelope>\r\n";
|
||||
|
||||
*var_value = NULL; // return NULL in case of an error
|
||||
|
||||
@ -903,11 +928,16 @@ SoapGetServiceVarStatus( IN char *action_url,
|
||||
}
|
||||
// make headers
|
||||
request.size_inc = 50;
|
||||
if( http_MakeMessage( &request, 1, 1, "Q" "sbc" "N" "s" "s" "U" "c" "sss", SOAPMETHOD_POST, path.buf, path.length, "HOST: ", host.buf, host.length, strlen( xml_start ) + strlen( var_name ) + strlen( xml_end ), // content-length
|
||||
ContentTypeHeader,
|
||||
"SOAPACTION: \"urn:schemas"
|
||||
"-upnp-org:control-1-0#QueryStateVariable\"\r\n",
|
||||
xml_start, var_name, xml_end ) != 0 ) {
|
||||
content_length = strlen( xml_start ) + strlen( var_name ) + strlen( xml_end );
|
||||
if (http_MakeMessage(
|
||||
&request, 1, 1,
|
||||
"Q" "sbc" "N" "s" "s" "Ucc" "sss",
|
||||
SOAPMETHOD_POST, path.buf, path.length,
|
||||
"HOST: ", host.buf, host.length,
|
||||
content_length,
|
||||
ContentTypeHeader,
|
||||
"SOAPACTION: \"urn:schemas-upnp-org:control-1-0#QueryStateVariable\"",
|
||||
xml_start, var_name, xml_end ) != 0 ) {
|
||||
return UPNP_E_OUTOF_MEMORY;
|
||||
}
|
||||
// send msg and get reply
|
||||
|
@ -189,7 +189,7 @@ send_error_response( IN SOCKINFO * info,
|
||||
IN const char *err_msg,
|
||||
IN http_message_t * hmsg )
|
||||
{
|
||||
int content_length;
|
||||
off_t content_length;
|
||||
int timeout_secs = SOAP_TIMEOUT;
|
||||
int major,
|
||||
minor;
|
||||
@ -228,20 +228,19 @@ send_error_response( IN SOCKINFO * info,
|
||||
|
||||
// make headers
|
||||
membuffer_init( &headers );
|
||||
/* -- PATCH START - Sergey 'Jin' Bostandzhyan <jin_eld at users.sourceforge.net> */
|
||||
if( http_MakeMessage( &headers, major, minor,
|
||||
"RNsDsSXc" "sssss",
|
||||
500,
|
||||
content_length,
|
||||
ContentTypeHeader,
|
||||
"EXT:\r\n",
|
||||
X_USER_AGENT,
|
||||
start_body, err_code_str, mid_body, err_msg,
|
||||
end_body ) != 0 ) {
|
||||
if (http_MakeMessage(
|
||||
&headers, major, minor,
|
||||
"RNsDsSXcc" "sssss",
|
||||
500,
|
||||
content_length,
|
||||
ContentTypeHeader,
|
||||
"EXT:\r\n",
|
||||
X_USER_AGENT,
|
||||
start_body, err_code_str, mid_body, err_msg,
|
||||
end_body ) != 0 ) {
|
||||
membuffer_destroy( &headers );
|
||||
return; // out of mem
|
||||
}
|
||||
/*-- PATCH END - */
|
||||
// send err msg
|
||||
http_SendMessage( info, &timeout_secs, "b",
|
||||
headers.buf, headers.length );
|
||||
@ -268,12 +267,11 @@ send_var_query_response( IN SOCKINFO * info,
|
||||
IN const char *var_value,
|
||||
IN http_message_t * hmsg )
|
||||
{
|
||||
int content_length;
|
||||
off_t content_length;
|
||||
int timeout_secs = SOAP_TIMEOUT;
|
||||
int major,
|
||||
minor;
|
||||
int major;
|
||||
int minor;
|
||||
const char *start_body =
|
||||
// "<?xml version=\"1.0\"?>\n" required??
|
||||
"<s:Envelope "
|
||||
"xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "
|
||||
"s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n"
|
||||
@ -297,19 +295,18 @@ send_var_query_response( IN SOCKINFO * info,
|
||||
// make headers
|
||||
membuffer_init( &response );
|
||||
|
||||
/* -- PATCH START - Sergey 'Jin' Bostandzhyan <jin_eld at users.sourceforge.net> */
|
||||
if( http_MakeMessage( &response, major, minor,
|
||||
"RNsDsSXcc" "sss",
|
||||
HTTP_OK,
|
||||
content_length,
|
||||
ContentTypeHeader,
|
||||
"EXT:\r\n",
|
||||
X_USER_AGENT,
|
||||
start_body, var_value, end_body ) != 0 ) {
|
||||
if (http_MakeMessage(
|
||||
&response, major, minor,
|
||||
"RNsDsSXcc" "sss",
|
||||
HTTP_OK,
|
||||
content_length,
|
||||
ContentTypeHeader,
|
||||
"EXT:\r\n",
|
||||
X_USER_AGENT,
|
||||
start_body, var_value, end_body ) != 0 ) {
|
||||
membuffer_destroy( &response );
|
||||
return; // out of mem
|
||||
}
|
||||
/* -- PATCH END - */
|
||||
|
||||
// send msg
|
||||
http_SendMessage( info, &timeout_secs, "b",
|
||||
@ -695,7 +692,7 @@ send_action_response( IN SOCKINFO * info,
|
||||
int major,
|
||||
minor;
|
||||
int err_code;
|
||||
int content_length;
|
||||
off_t content_length;
|
||||
int ret_code;
|
||||
int timeout_secs = SOAP_TIMEOUT;
|
||||
static char *start_body =
|
||||
@ -717,17 +714,22 @@ send_action_response( IN SOCKINFO * info,
|
||||
goto error_handler;
|
||||
}
|
||||
|
||||
content_length = strlen( start_body ) + strlen( xml_response ) +
|
||||
content_length =
|
||||
strlen( start_body ) +
|
||||
strlen( xml_response ) +
|
||||
strlen( end_body );
|
||||
|
||||
// make headers
|
||||
/* -- PATCH START - Sergey 'Jin' Bostandzhyan <jin_eld at users.sourceforge.net> */
|
||||
if( http_MakeMessage( &headers, major, minor, "RNsDsSXcc", HTTP_OK, // status code
|
||||
content_length, ContentTypeHeader, "EXT:\r\n", X_USER_AGENT // EXT header
|
||||
) != 0 ) {
|
||||
if (http_MakeMessage(
|
||||
&headers, major, minor,
|
||||
"RNsDsSXcc",
|
||||
HTTP_OK, // status code
|
||||
content_length,
|
||||
ContentTypeHeader,
|
||||
"EXT:\r\n",
|
||||
X_USER_AGENT) != 0 ) {
|
||||
goto error_handler;
|
||||
}
|
||||
/* -- PATCH END - */
|
||||
|
||||
// send whole msg
|
||||
ret_code = http_SendMessage( info, &timeout_secs, "bbbb",
|
||||
|
@ -234,7 +234,17 @@ NewRequestHandler( IN struct sockaddr_in *DestAddr,
|
||||
|
||||
for( Index = 0; Index < NumPacket; Index++ ) {
|
||||
int rc;
|
||||
|
||||
// The reason to keep this loop is purely historical/documentation,
|
||||
// according to section 9.2 of HTTPU spec:
|
||||
//
|
||||
// "If a multicast resource would send a response(s) to any copy of the
|
||||
// request, it SHOULD send its response(s) to each copy of the request
|
||||
// it receives. It MUST NOT repeat its response(s) per copy of the
|
||||
// reuqest."
|
||||
//
|
||||
// http://www.upnp.org/download/draft-goland-http-udp-04.txt
|
||||
//
|
||||
// So, NUM_COPY has been changed from 2 to 1.
|
||||
NumCopy = 0;
|
||||
while( NumCopy < NUM_COPY ) {
|
||||
DBGONLY( UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
|
||||
@ -295,16 +305,16 @@ CreateServicePacket( IN int msg_type,
|
||||
*packet = NULL;
|
||||
|
||||
if( msg_type == MSGTYPE_REPLY ) {
|
||||
/* -- PATCH START - Sergey 'Jin' Bostandzhyan <jin_eld at users.sourceforge.net> */
|
||||
ret_code = http_MakeMessage( &buf, 1, 1,
|
||||
"R" "sdc" "D" "s" "ssc" "S" "Xc" "ssc"
|
||||
"ssc" "c", HTTP_OK,
|
||||
"CACHE-CONTROL: max-age=", duration,
|
||||
"EXT:\r\n", "LOCATION: ", location,
|
||||
X_USER_AGENT,
|
||||
"ST: ", nt, "USN: ", usn );
|
||||
/* -- PATCH END - */
|
||||
|
||||
ret_code = http_MakeMessage(
|
||||
&buf, 1, 1,
|
||||
"R" "sdc" "D" "sc" "ssc" "S" "Xc" "ssc" "sscc",
|
||||
HTTP_OK,
|
||||
"CACHE-CONTROL: max-age=", duration,
|
||||
"EXT:",
|
||||
"LOCATION: ", location,
|
||||
X_USER_AGENT,
|
||||
"ST: ", nt,
|
||||
"USN: ", usn);
|
||||
if( ret_code != 0 ) {
|
||||
return;
|
||||
}
|
||||
@ -320,15 +330,17 @@ CreateServicePacket( IN int msg_type,
|
||||
// NOTE: The CACHE-CONTROL and LOCATION headers are not present in
|
||||
// a shutdown msg, but are present here for MS WinMe interop.
|
||||
|
||||
/* -- PATCH START - Sergey 'Jin' Bostandzhyan <jin_eld at users.sourceforge.net> */
|
||||
ret_code = http_MakeMessage( &buf, 1, 1,
|
||||
"Q" "sssdc" "sdc" "ssc" "ssc" "ssc"
|
||||
"S" "Xc" "ssc" "c", HTTPMETHOD_NOTIFY, "*",
|
||||
1, "HOST: ", SSDP_IP, ":", SSDP_PORT,
|
||||
"CACHE-CONTROL: max-age=", duration,
|
||||
"LOCATION: ", location, "NT: ", nt,
|
||||
"NTS: ", nts, X_USER_AGENT, "USN: ", usn );
|
||||
/* -- PATCH END - */
|
||||
ret_code = http_MakeMessage(
|
||||
&buf, 1, 1,
|
||||
"Q" "sssdc" "sdc" "ssc" "ssc" "ssc" "S" "Xc" "sscc",
|
||||
HTTPMETHOD_NOTIFY, "*",
|
||||
1, "HOST: ", SSDP_IP, ":", SSDP_PORT,
|
||||
"CACHE-CONTROL: max-age=", duration,
|
||||
"LOCATION: ", location,
|
||||
"NT: ", nt,
|
||||
"NTS: ", nts,
|
||||
X_USER_AGENT,
|
||||
"USN: ", usn );
|
||||
if( ret_code != 0 ) {
|
||||
return;
|
||||
}
|
||||
|
@ -922,6 +922,7 @@ get_ssdp_sockets( MiniServerSockArray * out )
|
||||
struct ip_mreq ssdpMcastAddr;
|
||||
struct sockaddr_in ssdpAddr;
|
||||
int option = 1;
|
||||
struct in_addr addr;
|
||||
|
||||
CLIENTONLY( if( ( ssdpReqSock = socket( AF_INET, SOCK_DGRAM, 0 ) )
|
||||
== UPNP_INVALID_SOCKET ) {
|
||||
@ -997,7 +998,7 @@ get_ssdp_sockets( MiniServerSockArray * out )
|
||||
}
|
||||
|
||||
memset( ( void * )&ssdpMcastAddr, 0, sizeof( struct ip_mreq ) );
|
||||
ssdpMcastAddr.imr_interface.s_addr = htonl( INADDR_ANY );
|
||||
ssdpMcastAddr.imr_interface.s_addr = inet_addr( LOCAL_HOST );
|
||||
ssdpMcastAddr.imr_multiaddr.s_addr = inet_addr( SSDP_IP );
|
||||
if( setsockopt( ssdpSock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
|
||||
( char * )&ssdpMcastAddr,
|
||||
@ -1012,6 +1013,17 @@ get_ssdp_sockets( MiniServerSockArray * out )
|
||||
CLIENTONLY( UpnpCloseSocket( ssdpReqSock ) );
|
||||
return UPNP_E_SOCKET_ERROR;
|
||||
}
|
||||
|
||||
/* Set multicast interface. */
|
||||
memset( ( void * )&addr, 0, sizeof( struct in_addr ));
|
||||
addr.s_addr = inet_addr(LOCAL_HOST);
|
||||
if (setsockopt(ssdpSock, IPPROTO_IP, IP_MULTICAST_IF,
|
||||
(char *)&addr, sizeof addr) != 0) {
|
||||
DBGONLY(UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
|
||||
"Couldn't set multicast interface.\n" ));
|
||||
/* This is probably not a critical error, so let's continue. */
|
||||
}
|
||||
|
||||
// result is not checked becuase it will fail in WinMe and Win9x.
|
||||
setsockopt( ssdpSock, IPPROTO_IP,
|
||||
IP_MULTICAST_TTL, &ttl, sizeof( ttl ) );
|
||||
|
Loading…
Reference in New Issue
Block a user