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:
Marcelo Roberto Jimenez 2007-02-03 19:30:31 +00:00
parent 9e775e662e
commit 8cfa0e488c
29 changed files with 874 additions and 443 deletions

105
ChangeLog
View File

@ -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
*************************************************************************

View File

@ -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
View File

@ -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

View File

@ -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"

View File

@ -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
View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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
*

View File

@ -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
*

View File

@ -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

View File

@ -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

View File

@ -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 );

View File

@ -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 );

View File

@ -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 ) {

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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__,

View File

@ -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 );

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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",

View File

@ -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;
}

View File

@ -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 ) );