diff options
author | Joe Orton <notroj@users.noreply.github.com> | 2004-10-02 21:17:02 +0000 |
---|---|---|
committer | Joe Orton <notroj@users.noreply.github.com> | 2004-10-02 21:17:02 +0000 |
commit | 2908421cc7b1be3304c996b313cb49e12ba96370 (patch) | |
tree | f116f6fe8805a011083e7d2ce303dec489fa7e8b | |
parent | 6b481ae6548ea00a8285deab9e674925853b107d (diff) | |
download | neon-git-0.24.6.tar.gz |
Tag 0.24.6.0.24.6
69 files changed, 1015 insertions, 2662 deletions
@@ -2,8 +2,6 @@ Known problems/bugs in neon -*- text -*- --------------------------- -* look at escaping logic again w.r.t. ?, # characters? - * 2818 requires that a on rejection of the SSL server cert, a "bad certificate" message should be sent - this is not being done currently (and can probably only be done with OpenSSL by actually doing cert verification in the verify @@ -14,15 +12,13 @@ Known problems/bugs in neon -*- text -*- * SSL session caching issues; only cache for clean shutdowns, and only cache on shutdown, since the SSL_SESSION may change during - an ne_session? + an ne_session. * what is passed as 'path' to req create hook: auth needs Request-URI; how does that interact with proxies? also they will be passed NULL for a CONNECT request, or "*" possibly as well. -* expect100 support is broken: enable it per-request, don't bother -caching support over the session, rely on the app only enabling it if -it works. +* expect100 support is broken. * It would be nice to fail with a friendly error message if a client cert is requested by the srever but one is not provided. Currently, @@ -30,16 +26,3 @@ returning -1 from the provide_client_cert function would allow that (as it forces the SSL handshake to fail), but that would prevent opportunistic use of client certificates, of the "SSLVerifyClient optional" variety. - -* D.J. Heap has a proxy which returns a 401 in response to a CONNECT; -relax the ne_auth rules to allow this since it's unambiguous. - -* Error handling from ne__pull_request_body/send_request_body is -buggy: socket errors are not distinguished from body provider errors; -the connection must be closed in ne_request after a body provider -error. - -* Check whether the following always return UTF-8-encoded strings: - - ne_ssl_clicert_name - - ne_ssl_cert_identity - @@ -1,59 +1,15 @@ Mon May 17 21:25:44 2004 Joe Orton <joe@manyfish.co.uk> - * neon.mak: Fix for handling of paths with spaces, and - simplify (Jon Foster <jon@jon-foster.co.uk>). + * neon.mak: Fix handling of paths with spaces, and simplify (Jon + Foster <jon@jon-foster.co.uk>). Thu May 13 11:42:07 2004 Joe Orton <joe@manyfish.co.uk> * configure.in: Don't rely on echo -n in ne_version. -Sun Feb 22 20:29:04 2004 Joe Orton <joe@manyfish.co.uk> +Fri Mar 26 12:07:04 2004 Joe Orton <joe@manyfish.co.uk> - * configure.in: Move memleak.h include to end of config.h. - -Sun Feb 22 18:44:55 2004 Joe Orton <joe@manyfish.co.uk> - - * configure.in: Fix to run DAV tests when an XML parser is - configured. - -Sat Jan 24 17:50:52 2004 Joe Orton <joe@manyfish.co.uk> - - * configure.in: AC_DEFINE _GNU_SOURCE again so that it's used - during compiler checks. - -Sat Jan 24 17:33:54 2004 Joe Orton <joe@manyfish.co.uk> - - * configure.in: Cleanup; move all AC_SUBSTs together; use a single - AH_TOP for config.h.in header; require autoconf 2.58. - -Thu Jan 1 17:40:34 2004 Joe Orton <joe@manyfish.co.uk> - - * neon-config.in: Handle 'lfs' feature. - -Sat Nov 15 09:42:40 2003 Joe Orton <joe@manyfish.co.uk> - - * neon-config.in: Print help output on stderr for unknown arguments. - (usage): Update help output for new NE_FLAG_ substitutions. - -Sat Nov 15 09:24:49 2003 Joe Orton <joe@manyfish.co.uk> - - * configure.in: Update for use latest autoconf best-practice: - s/AC_HELP_STRING/AS_HELP_STRING. - -Fri Nov 14 11:28:24 2003 Joe Orton <joe@manyfish.co.uk> - - * configure.in, neon-config.in: Use new NE_FLAG substitutions - for feature detection. - -Fri Nov 14 09:08:10 2003 Joe Orton <joe@manyfish.co.uk> - - * configure.in: Add -export-symbols-regex to NEON_LINK_FLAGS to - prevent export of ne__ symbols where possible. - -Sun Oct 26 12:42:15 2003 Joe Orton <joe@manyfish.co.uk> - - * neon-config.in: Fix to exit with failure for an unrecognized - option. + * Makefile.in (distclean): Clean more. Sat Oct 25 10:37:59 2003 Joe Orton <joe@manyfish.co.uk> diff --git a/Makefile.in b/Makefile.in index 25b63eb..ae8a535 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2002 Joe Orton <joe@manyfish.co.uk> +# Copyright (C) 2001-2004 Joe Orton <joe@manyfish.co.uk> # Copyright (C) 1994, 1995-8, 1999, 2000 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -99,7 +99,7 @@ clean: cd test && $(MAKE) clean distclean: clean - rm -rf Makefile config.h config.status src/Makefile libtool config.log config.cache neon-config autom4te.cache test/Makefile + rm -rf Makefile config.h config.status libtool config.log config.cache neon-config autom4te.cache neon.pc test/Makefile test/common/Makefile src/Makefile again: clean @@ -1,30 +1,3 @@ -Changes in release 0.25.0: -* New feature detection interface, ne_has_feature(): - - replaces ne_supports_ssl(); NEON_SSL is no longer defined by neon-config. -* ne_set_request_body_fd takes offset and length arguments and returns void. -* ne_set_request_body_provider takes an off_t length argument. -* Support for non-ASCII hostnames following the IDNA spec, using GNU libidn: - - if enabled, ne_session_create can be passed a UTF-8 encoded hostname. -* ne_xml_failed() replaces ne_xml_valid(), with different return value logic. -* Support for >2Gb request/response bodies on 32-bit Unixes with LFS support: - - new ne_set_request_body_fd64() call for using an fd opened using O_LARGEFILE - - new ne_set_request_body_provider64() which takes an off64_t length argument -* ne_xml interface now rejects more invalid XML element names (e.g. "foo::bar"). -* Add ne_set_addrlist() interface to bypass normal DNS resolution. -* Use a per-request flag to enable "Expect: 100-continue" support: - - ne_set_request_expect100() replaces ne_set_expect100() -* Fix handling of multiple Authentication challenges per request. -* Fix timezone handling on Win32 (Jiang Lei). - -Changes in release 0.24.7: -* Compression interface fixes: - - fix issues handling content decoding and request retries from - authentication challenges (Justin Erenkrantz) - - fix places where reader callback would receive spurious size=0 calls - - fix to pass user-supplied userdata to user-supplied acceptance callback -* Fix for RFC2617-style digest authentication (Hideaki Takahashi). -* Fix to pick up gethostbyname() on QNX 6.2. - Changes in release 0.24.6: * SECURITY (CVE CAN-2004-0398): Fix sscanf overflow in ne_rfc1036_parse, thanks to Stefan Esser. @@ -32,7 +32,7 @@ For one-point-oh 62. Select which auth mechanisms are allowed, e.g. JUST SAY NO to basic might very well be useful to some apps. -64. Add options to only enable SSLv2 support, etc. +63. Unconditionally turn off Nagle algorithm. Longer term ----------- @@ -116,5 +116,3 @@ Longer term 57. Add function to map of status-code values to i18n-ized reason phrase. -65. Add ne_uri_copy function and use it in ne_lock_copy. (patch - sent to neon@webdav.org) @@ -11,12 +11,12 @@ if test ! -f .version; then echo -n 0.0.0-dev > doc/version.xml fi set -e -echo -n "libtoolize... " -${LIBTOOLIZE:-libtoolize} --copy --force >/dev/null echo -n "aclocal... " -${ACLOCAL:-aclocal} -I macros 2>&1 | grep -v "warning: underquoted definition" +${ACLOCAL:-aclocal} -I macros echo -n "autoheader... " ${AUTOHEADER:-autoheader} +echo -n "libtoolize... " +${LIBTOOLIZE:-libtoolize} --copy --force >/dev/null echo -n "autoconf... " ${AUTOCONF:-autoconf} -Wall echo okay. diff --git a/configure.in b/configure.in index 87781c5..0ba04ce 100644 --- a/configure.in +++ b/configure.in @@ -1,4 +1,6 @@ -AC_PREREQ(2.58) dnl 2.58 required for AS_HELP_STRING +dnl Require autoconf 2.53 for an AC_C_BIGENDIAN which supports +dnl cross-compiling. +AC_PREREQ(2.53) dnl Extract the version (sans LF) from .version, created at release-time. m4_define(ne_version, [m4_translit(m4_include(.version), [ @@ -6,7 +8,7 @@ m4_define(ne_version, [m4_translit(m4_include(.version), [ AC_INIT(neon, ne_version, [neon@webdav.org]) -AC_COPYRIGHT([Copyright 2000-2004 Joe Orton +AC_COPYRIGHT([Copyright (c) 2000, 2001, 2002 Joe Orton This configure script may be copied, distributed and modified under the terms of the GNU Library General Public license; see COPYING for more details]) @@ -19,22 +21,16 @@ NEON_WITH_LIBS # libraries which are detected (e.g. OpenSSL) can still be found when # building using the --libs output of neon-config. user_LDFLAGS=$LDFLAGS +AC_SUBST(user_LDFLAGS) # By default, allow 'make install' to work. ALLOW_INSTALL=yes +AC_SUBST(ALLOW_INSTALL) -AC_DEFINE([_GNU_SOURCE], 1, [Always defined to enable GNU extensions]) - -dnl Place straight into config.h.in: -AH_TOP([ -/* Only defined when neon source directory built as a standalone library */ -#define NEON_IS_LIBRARY 1]) - -AH_BOTTOM([ -/* Enable leak-tracking versions of ne_*alloc when NEON_MEMLEAK is enabled */ -#ifdef NEON_MEMLEAK -# include "memleak.h" -#endif]) +# Always defined +AC_DEFINE([_GNU_SOURCE], 1, [Unconditionally define _GNU_SOURCE]) +# Defined when neon is built as library +AC_DEFINE(NEON_IS_LIBRARY, 1, [Define when building neon as a library]) AC_PROG_INSTALL @@ -48,9 +44,10 @@ AC_PROG_LIBTOOL AC_EXEEXT top_builddir=`pwd` +AC_SUBST(top_builddir) -AC_ARG_ENABLE(webdav, - AS_HELP_STRING([--disable-webdav],[disable WebDAV support])) +AC_ARG_ENABLE(webdav, +AC_HELP_STRING([--disable-webdav], [disable WebDAV support])) if test "$enable_webdav" = "no"; then NEON_WITHOUT_WEBDAV @@ -63,6 +60,7 @@ fi # The bundled macros also set this, which makes sure we recurse # into the 'src' directory. NEON_BUILD_BUNDLED=yes +AC_SUBST(NEON_BUILD_BUNDLED) # Define NEON_VERSION* and make the appropriate substitutions. NEON_VERSIONS @@ -70,10 +68,6 @@ NEON_VERSIONS # Pass the interface version on to libtool when linking libneon.la NEON_LINK_FLAGS="-version-info ${NEON_INTERFACE_VERSION}" -# Library-internal symbols are in the ne__ namespace: tell libtool -# to not export these from the built library if possible. -NEON_LINK_FLAGS="$NEON_LINK_FLAGS -export-symbols-regex '^ne_[[^_]]'" - # Checks to compile test suite NEON_TEST @@ -88,11 +82,20 @@ NEON_DEBUG # Leave till last to prevent CFLAGS affecting checks. NEON_WARNINGS -CPPFLAGS="$CPPFLAGS -I\${top_builddir}" +CFLAGS="$CFLAGS -I\${top_builddir}" + +dnl Substitute NEON_VERSION for neon-config too. +AC_SUBST(NEON_VERSION) AC_ARG_ENABLE(memleak, - AS_HELP_STRING([--enable-memleak], - [for test builds only: enable memory leak checking])) +AC_HELP_STRING([--enable-memleak], [for test builds only: enable memory leak checking])) + +dnl Have autoheader include the following template in config.h.in: +AH_VERBATIM([NEON_MEMLEAK], +[/* Enable memory leak detection. */ +#ifdef NEON_MEMLEAK +# include "memleak.h" +#endif]) if test "$enable_memleak" = "yes"; then CPPFLAGS="$CPPFLAGS -DNEON_MEMLEAK -I\$(top_srcdir)/src" @@ -103,7 +106,7 @@ fi # Enable tests for optional features TESTS="\$(BASIC_TESTS)" HELPERS="" -if test $NE_FLAG_SSL = yes; then +if test "$NEON_SUPPORTS_SSL" = "yes"; then # Only enable SSL tests if an openssl binary is found (needed to make # certs etc). AC_PATH_PROG(OPENSSL, openssl, notfound) @@ -114,25 +117,19 @@ if test $NE_FLAG_SSL = yes; then AC_MSG_WARN([no openssl binary in \$PATH: SSL tests disabled]) fi fi -if test $NE_FLAG_ZLIB = yes; then +if test "$NEON_SUPPORTS_DAV" = "yes"; then + TESTS="$TESTS \$(DAV_TESTS)" +fi +if test "$NEON_SUPPORTS_ZLIB" = "yes"; then TESTS="$TESTS \$(ZLIB_TESTS)" HELPERS="$HELPERS \$(ZLIB_HELPERS)" fi -if test x$enable_webdav != xno; then - TESTS="$TESTS \$(DAV_TESTS)" -fi +AC_SUBST(HELPERS) +AC_SUBST(TESTS) AC_CONFIG_FILES([neon-config], [chmod +x neon-config]) AC_CONFIG_FILES([Makefile src/Makefile test/Makefile neon.pc]) -AC_SUBST(NEON_VERSION) -AC_SUBST(NEON_BUILD_BUNDLED) -AC_SUBST(top_builddir) -AC_SUBST(user_LDFLAGS) -AC_SUBST(HELPERS) -AC_SUBST(TESTS) -AC_SUBST(ALLOW_INSTALL) - AC_OUTPUT # for VPATH builds: @@ -143,8 +140,8 @@ AC_MSG_NOTICE([Configured to build AC_PACKAGE_STRING: Install prefix: ${prefix} Compiler: ${CC} XML Parser: ${neon_xml_parser_message} - SSL library: ${ne_SSL_message} - zlib support: ${ne_ZLIB_message} + SSL library: ${neon_ssl_message} + zlib support: ${neon_zlib_message} Build libraries: Shared=${enable_shared}, Static=${enable_static} Now run 'make' to compile the neon library. diff --git a/doc/biblio.xml b/doc/biblio.xml index 43574b8..cda37a7 100644 --- a/doc/biblio.xml +++ b/doc/biblio.xml @@ -10,11 +10,12 @@ <pubdate>March 2001</pubdate> </biblioentry> -<biblioentry id="bib.xmlnames"> +<biblioentry id="bib.xsltrec"> <abbrev>REC-XML-names</abbrev> - <corpauthor>World Wide Web Consortium</corpauthor> - <title><ulink url="http://www.w3.org/TR/REC-xml-names">Namespaces in XML</ulink></title> - <pubdate>January 1999</pubdate> + <editor><firstname>James</firstname><surname>Clark</surname></editor> + <title><ulink url="http://www.w3.org/TR/xslt">XSL Transformations + (XSLT) Version 1.0</ulink></title> <publishername>W3C + Recommendation</publishername> <pubdate>16 November 1999</pubdate> </biblioentry> <biblioentry id="bib.rfc2616"> diff --git a/doc/ref/clicert.xml b/doc/ref/clicert.xml index 67833aa..49f95cf 100644 --- a/doc/ref/clicert.xml +++ b/doc/ref/clicert.xml @@ -62,9 +62,9 @@ <para>The <function>ne_ssl_clicert_read</function> function reads a <firstterm>client certificate</firstterm> from a PKCS#12-formatted file, and returns an - <type>ne_ssl_client_cert</type> object. If the client + <type>ne_ssl_client_certificate</type> object. If the client certificate is encrypted, it must be decrypted before it is used. - An <type>ne_ssl_client_cert</type> object holds a client + An <type>ne_ssl_client_certificate</type> object holds a client certificate and the associated private key, not just a certificate; the term "<glossterm>client certificate</glossterm>" will used to refer to this pair.</para> @@ -124,7 +124,7 @@ <para>The following code reads a client certificate and decrypts it if necessary, then loads it into an HTTP session.</para> - <programlisting>ne_ssl_client_cert *ccert; + <programlisting>ne_ssl_client_certificate *ccert; ccert = ne_ssl_clicert_read("/path/to/client.p12"); diff --git a/doc/using.xml b/doc/using.xml index e88c9ef..efb53d1 100644 --- a/doc/using.xml +++ b/doc/using.xml @@ -73,11 +73,11 @@ </sect1> <sect1 id="compliance"> - <title>Standards compliance</title> + <title>Protocol compliance</title> - <para>&neon; is intended to be compliant with the IETF and W3C - standards which it implements, with a few exceptions due to - practical necessity or interoperability issues. These + <para>&neon; is intended to be compliant with the IETF + protocol standards it implements, with a few exceptions where + real-world use has necessitated minor deviations. These exceptions are documented in this section.</para> <sect2><title>RFC 2518, HTTP Extensions for Distributed Authoring—WebDAV</title> @@ -116,25 +116,4 @@ quotes—this is not known to cause any problems with other server implementations.</para></sect2> - <sect2> - <title>Namespaces in XML</title> - - <para>The &neon; XML parser interface will accept and parse - without error some XML documents which are well-formed - according to the XML specification but do not conform to the - "Namespaces in XML" specification <xref - linkend="bib.xmlnames"/>. Specifically: the restrictions on - the first character of the <literal>NCName</literal> rule are - not all implemented; &neon; will allow any - <literal>CombiningChar</literal>, <literal>Extender</literal> - and some characters from the <literal>Digit</literal> class in - this position.</para> </sect2> - - <!-- a few RFC2818/3280 issues: rules about when to cache - sessions in the face of unclean shutdown are strict, neon is - probably not compliant: document or fix. Likewise SSL - shutdown issues in general. Cert hostname checks allow - wildcard "*." syntax which is less than 2818 but more than - 3280 requires. --> - </sect1> diff --git a/macros/ChangeLog b/macros/ChangeLog index ad26543..2d0b7b1 100644 --- a/macros/ChangeLog +++ b/macros/ChangeLog @@ -1,24 +1,3 @@ -Sun Sep 12 18:38:13 2004 Joe Orton <joe@manyfish.co.uk> - - * neon.m4 (NEON_USE_EXTERNAL): Check for IDNA, LFS, SOCKS - support. - (NEON_SOCKS): Use common feature code for SOCKSv5 support. - -Fri Sep 10 20:52:54 2004 Joe Orton <joe@manyfish.co.uk> - - * neon.m4 (LIBNEON_SOURCE_CHECKS): Safer autoheader template for - declaring stpcpy as necessary for bundled neon builds. - (NEON_WARNINGS): Drop -Winline. - -Wed Aug 25 19:44:26 2004 Joe Orton <joe@manyfish.co.uk> - - * neon.m4 (LIBNEON_SOURCE_CHECKS): Check for poll. - -Sat Jul 3 11:39:01 2004 Joe Orton <joe@manyfish.co.uk> - - * neon.m4 (LIBNEON_SOURCE_CHECKS): Pick up gethostbyname in - -lsocket for QNX. - Fri Apr 16 11:43:10 2004 Joe Orton <joe@manyfish.co.uk> * neon-xml-parser.m4 (NEON_XML_PARSER): If built using libtool, @@ -32,87 +11,6 @@ Tue Apr 13 20:51:59 2004 Joe Orton <joe@manyfish.co.uk> * neon.m4 (NEON_GSSAPI): Check for presence of gssapi/gssapi_generic.h. -Wed Apr 7 13:16:33 2004 Joe Orton <joe@manyfish.co.uk> - - * neon.m4 (NE_LARGEFILE): Check for strtoq. - -Mon Mar 15 19:59:36 2004 Joe Orton <joe@manyfish.co.uk> - - * neon.m4 (LIBNEON_SOURCE_CHECKS): Be safer around getaddrinfo - blacklist for HP-UX and reference why it's needed. - -Sun Mar 7 11:15:44 2004 Joe Orton <joe@manyfish.co.uk> - - * neon.m4 (LIBNEON_SOURCE_CHECKS): Use NE_LARGEFILE in-place - rather than AC_REQUIRE'ing it. - (NE_LARGEFILE): Add NE_LFS to CPPFLAGS for use in bundled builds. - -Mon Feb 23 23:02:54 2004 Joe Orton <joe@manyfish.co.uk> - - * neon.m4 (NE_SNPRINTF): Define HAVE_TRIO if trio is used. - -Mon Feb 23 00:22:39 2004 Joe Orton <joe@manyfish.co.uk> - - * neon.m4 (LIBNEON_SOURCE_CHECKS): Give INCLUDES argument to - AC_CHECK_HEADERS; prevent warning from cpp test for netinet/in.h - on some platforms. - -Sun Feb 22 17:52:42 2004 Joe Orton <joe@manyfish.co.uk> - - * neon.m4 (NE_SEARCH_LIBS): Fix to run actions-if-found if - function is found without needing additional libraries. - (LIBNEON_SOURCE_CHECKS): Only check for gethostbyname if - getaddrinfo is not found. Disable getaddrinfo on HP-UX 11.[01]* - here rather than ne_socket.c. - -Sat Jan 24 17:49:50 2004 Joe Orton <joe@manyfish.co.uk> - - * neon.m4 (LIBNEON_SOURCE_CHECKS): Also check for __tm_gmtoff in - struct tm. - -Sat Jan 24 17:16:48 2004 Joe Orton <joe@manyfish.co.uk> - - * neon.m4: Remove -ansi-pedantic and -Wimplicit-prototypes for gcc - 3.4 compatibility (thanks to Olaf Hering). - -Sat Jan 3 14:11:14 2004 Joe Orton <joe@manyfish.co.uk> - - * neon-test.m4: Check for stdint.h. - -Sat Jan 3 13:17:21 2004 Joe Orton <joe@manyfish.co.uk> - - * neon.m4 (NE_LARGEFILE): Add NE_LFS to neon-config --cflags - output. - -Thu Jan 1 18:42:56 2004 Joe Orton <joe@manyfish.co.uk> - - * neon.m4 (NEON_FORMAT): Use C99 'll' rather than non-standard 'q' - length modifier. - -Thu Jan 1 17:36:39 2004 Joe Orton <joe@manyfish.co.uk> - - * neon.m4 (NE_LARGEFILE): New macro. - (LIBNEON_SOURCE_CHECKS): Call it. - -Sat Nov 15 09:25:43 2003 Joe Orton <joe@manyfish.co.uk> - - * neon.m4, neon-xml-parser.m4: Update for latest autoconf - best-practice: s/AC_HELP_STRING/AS_HELP_STRING, replace AC_TRY_RUN - with AC_RUN_IFELSE, AC_TRY_LINK_FUNC with AC_LINK_IFELSE, - AC_TRY_COMPILE with AC_COMPILE_IFELSE, remove AC_LANG_C and - AC_PROG_CC_STDC, - -Fri Nov 14 13:12:10 2003 Joe Orton <joe@manyfish.co.uk> - - * neon.m4 (NEON_LIBIDN): New macro. - (LIBNEON_SOURCE_CHECKS): Use NEON_LIBIDN. - -Fri Nov 14 11:28:58 2003 Joe Orton <joe@manyfish.co.uk> - - * neon.m4 (NE_ENABLE_SUPPORT, NE_DISABLE_SUPPORT): New macros. - Use throughout to flag support or lack of support for optional - features. - Thu Nov 13 20:25:28 2003 Joe Orton <joe@manyfish.co.uk> * neon.m4 (LIBNEON_SOURCE_CHECKS): Check for gethostbyname in @@ -385,11 +283,6 @@ Sun May 19 20:23:55 2002 Joe Orton <joe@manyfish.co.uk> * neon.m4 (NEON_WARNINGS): Remove with_warnings variable; simplify. -Wed May 19 08:36:44 2004 Joe Orton <joe@manyfish.co.uk> - - * neon.m4 (LIBNEON_SOURCE_CHECKS): Declare stpcpy on modern - "Linux-like" AIXes. - Sun May 19 09:35:08 2002 Joe Orton <joe@manyfish.co.uk> * neon.m4 (NE_FIND_AR): Fix $PATH handling on some Linux diff --git a/macros/neon-test.m4 b/macros/neon-test.m4 index aec38dd..7a9fa23 100644 --- a/macros/neon-test.m4 +++ b/macros/neon-test.m4 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2004 Joe Orton <joe@manyfish.co.uk> -*- autoconf -*- +# Copyright (C) 2001-2002 Joe Orton <joe@manyfish.co.uk> -*- autoconf -*- # # This file is free software; you may copy and/or distribute it with # or without modifications, as long as this notice is preserved. @@ -29,7 +29,7 @@ dnl CPPFLAGS which make "gcc -Werror" fail in NEON_FORMAT; suggest dnl this macro is used first. AC_BEFORE([$0], [NEON_XML_PARSER]) -AC_CHECK_HEADERS(sys/time.h stdint.h) +AC_CHECK_HEADERS(sys/time.h) AC_CHECK_FUNCS(pipe isatty usleep shutdown) diff --git a/macros/neon-xml-parser.m4 b/macros/neon-xml-parser.m4 index 7fb033b..38a804e 100644 --- a/macros/neon-xml-parser.m4 +++ b/macros/neon-xml-parser.m4 @@ -86,14 +86,14 @@ AC_DEFUN([NEON_XML_PARSER], [ dnl Switches to force choice of library AC_ARG_WITH([libxml2], -AS_HELP_STRING([--with-libxml2], [force use of libxml 2.x])) +AC_HELP_STRING([--with-libxml2], [force use of libxml 2.x])) AC_ARG_WITH([expat], -AS_HELP_STRING([--with-expat], [force use of expat])) +AC_HELP_STRING([--with-expat], [force use of expat])) dnl Flag to force choice of included expat, if available. ifelse($#, 1, [ AC_ARG_WITH([included-expat], -AS_HELP_STRING([--with-included-expat], [use bundled expat sources]),, +AC_HELP_STRING([--with-included-expat], [use bundled expat sources]),, with_included_expat=no)], with_included_expat=no) diff --git a/macros/neon.m4 b/macros/neon.m4 index 72114b4..4094aaf 100644 --- a/macros/neon.m4 +++ b/macros/neon.m4 @@ -88,7 +88,7 @@ AC_DEFUN([NEON_COMMON_BUNDLED],[ AC_PREREQ(2.50) AC_ARG_WITH(included-neon, -AS_HELP_STRING([--with-included-neon], [force use of included neon library]), +AC_HELP_STRING([--with-included-neon], [force use of included neon library]), [neon_force_included="$withval"], [neon_force_included="no"]) NEON_COMMON @@ -121,9 +121,9 @@ AC_DEFUN([NEON_VERSIONS], [ # Define the current versions. NEON_VERSION_MAJOR=0 -NEON_VERSION_MINOR=25 -NEON_VERSION_RELEASE=0 -NEON_VERSION_TAG=-dev +NEON_VERSION_MINOR=24 +NEON_VERSION_RELEASE=6 +NEON_VERSION_TAG= NEON_VERSION="${NEON_VERSION_MAJOR}.${NEON_VERSION_MINOR}.${NEON_VERSION_RELEASE}${NEON_VERSION_TAG}" @@ -173,16 +173,15 @@ else ne_libver=`$NEON_CONFIG --version | sed -e "s/neon //g"` # Check whether it's possible to link against neon AC_CACHE_CHECK([linking against neon], [ne_cv_lib_neon], - [AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[#include <ne_utils.h>]], [[ne_version_match(0, 0);]])], - [ne_cv_lib_neon=yes], [ne_cv_lib_neon=no])]) + AC_TRY_LINK_FUNC([ne_version_match], + [ne_cv_lib_neon=yes], [ne_cv_lib_neon=no])) if test "$ne_cv_lib_neon" = "yes"; then # Now check whether the neon library version is satisfactory AC_CACHE_CHECK([neon library version], [ne_cv_lib_neonver], - [AC_RUN_IFELSE( - [AC_LANG_PROGRAM([[#include <ne_utils.h>]], - [[return ne_version_match($neon_require_major, $neon_require_minor);]])], - [ne_cv_lib_neonver=yes], [ne_cv_lib_neonver=no], [ne_cv_lib_neonver=no])]) + AC_TRY_RUN([#include <ne_utils.h> +int main(int argc, char **argv) { +return ne_version_match($neon_require_major, $neon_require_minor); +}], ne_cv_lib_neonver=yes, ne_cv_lib_neonver=no)) fi ne_goodver=$ne_cv_lib_neonver LIBS=$ne_save_LIBS @@ -196,38 +195,17 @@ else $2 fi]) -dnl NEON_CHECK_SUPPORT(feature, var, name) +dnl NEON_CHECK_SUPPORT(feature, var) AC_DEFUN([NEON_CHECK_SUPPORT], [ if $NEON_CONFIG --support $1 >/dev/null; then - NE_ENABLE_SUPPORT($2, [$3 is supported by neon]) + neon_$1_message="supported by neon" + $2=yes else - NE_DISABLE_SUPPORT($2, [$3 is not supported by neon]) + neon_$1_message="not supported by neon" + $2=no fi ]) -dnl enable support for feature $1 with define $2, message $2 -AC_DEFUN([NE_ENABLE_SUPPORT], [ -NE_FLAG_$1=yes -AC_SUBST(NE_FLAG_$1) -AC_DEFINE([NE_HAVE_]$1, 1, [Defined if $1 is supported]) -m4_if([$2], [], - [ne_$1_message="support enabled" - AC_MSG_NOTICE([$1 support is enabled])], - [ne_$1_message="$2" - AC_MSG_NOTICE([$2])]) -]) - -dnl Disable support for feature $1 with define $1, message $3 -AC_DEFUN([NE_DISABLE_SUPPORT], [ -NE_FLAG_$1=no -AC_SUBST(NE_FLAG_$1) -m4_if([$2], [], - [ne_$1_message="not supported" - AC_MSG_NOTICE([$1 support is not enabled])], - [ne_$1_message="$2" - AC_MSG_NOTICE([$2])]) -]) - AC_DEFUN([NEON_USE_EXTERNAL], [ # Configure to use an external neon, given a neon-config script # found at $NEON_CONFIG. @@ -237,12 +215,8 @@ NEON_CHECK_VERSION([ NEON_LIBS="$NEON_LIBS `$NEON_CONFIG --libs`" neon_library_message="library in ${neon_prefix} (`$NEON_CONFIG --version`)" neon_xml_parser_message="using whatever neon uses" - NEON_CHECK_SUPPORT([ssl], [SSL], [SSL]) - NEON_CHECK_SUPPORT([zlib], [ZLIB], [zlib]) - NEON_CHECK_SUPPORT([idna], [IDNA], [IDNA]) - NEON_CHECK_SUPPORT([ipv6], [IPV6], [IPv6]) - NEON_CHECK_SUPPORT([lfs], [LFS], [LFS]) - NEON_CHECK_SUPPORT([socks], [SOCKS], [SOCKSv5]) + NEON_CHECK_SUPPORT([ssl], [NEON_SUPPORTS_SSL]) + NEON_CHECK_SUPPORT([zlib], [NEON_SUPPORTS_ZLIB]) neon_got_library=yes ], [neon_got_library=no]) ]) @@ -337,27 +311,21 @@ dnl give an error and fail configure. AC_DEFUN([NE_SEARCH_LIBS], [ AC_CACHE_CHECK([for library containing $1], [ne_cv_libsfor_$1], [ -AC_LINK_IFELSE( - [AC_LANG_PROGRAM([], [[$1();]])], - [ne_cv_libsfor_$1="none needed"], [ +AC_TRY_LINK_FUNC($1, [ne_cv_libsfor_$1="none needed"], [ ne_sl_save_LIBS=$LIBS ne_cv_libsfor_$1="not found" for lib in $2; do LIBS="$ne_sl_save_LIBS -l$lib $NEON_LIBS" - AC_LINK_IFELSE([AC_LANG_PROGRAM([], [[$1();]])], - [ne_cv_libsfor_$1="-l$lib"; break]) + AC_TRY_LINK_FUNC($1, [ne_cv_libsfor_$1="-l$lib"; break]) m4_if($3, [], [], dnl If $3 is specified, then... [LIBS="$ne_sl_save_LIBS -l$lib $3 $NEON_LIBS" - AC_LINK_IFELSE([AC_LANG_PROGRAM([], [[$1();]])], - [ne_cv_libsfor_$1="-l$lib $3"; break])]) + AC_TRY_LINK_FUNC($1, [ne_cv_libsfor_$1="-l$lib $3"; break])]) done LIBS=$ne_sl_save_LIBS])]) if test "$ne_cv_libsfor_$1" = "not found"; then - m4_if([$4], [], [AC_MSG_ERROR([could not find library containing $1])], [$4]) -elif test "$ne_cv_libsfor_$1" = "none needed"; then - m4_if([$5], [], [:], [$5]) -else + m4_if($4, [], [AC_MSG_ERROR([could not find library containing $1])], [$4]) +elif test "$ne_cv_libsfor_$1" != "none needed"; then NEON_LIBS="$ne_cv_libsfor_$1 $NEON_LIBS" $5 fi]) @@ -365,18 +333,23 @@ fi]) dnl Check for presence and suitability of zlib library AC_DEFUN([NEON_ZLIB], [ -AC_ARG_WITH(zlib, AS_HELP_STRING([--without-zlib], [disable zlib support]), +AC_ARG_WITH(zlib, AC_HELP_STRING([--without-zlib], [disable zlib support]), ne_use_zlib=$withval, ne_use_zlib=yes) +NEON_SUPPORTS_ZLIB=no +AC_SUBST(NEON_SUPPORTS_ZLIB) + if test "$ne_use_zlib" = "yes"; then AC_CHECK_HEADER(zlib.h, [ AC_CHECK_LIB(z, inflate, [ NEON_LIBS="$NEON_LIBS -lz" - NE_ENABLE_SUPPORT(ZLIB, [zlib support enabled, using -lz]) - ], [NE_DISABLE_SUPPORT(ZLIB, [zlib library not found])]) - ], [NE_DISABLE_SUPPORT(ZLIB, [zlib header not found])]) + NEON_CFLAGS="$NEON_CFLAGS -DNEON_ZLIB" + NEON_SUPPORTS_ZLIB=yes + neon_zlib_message="found in -lz" + ], [neon_zlib_message="zlib not found"]) + ], [neon_zlib_message="zlib not found"]) else - NE_DISABLE_SUPPORT(ZLIB, [zlib not enabled]) + neon_zlib_message="zlib disabled" fi ]) @@ -399,6 +372,8 @@ AC_DEFUN([NEON_COMMON_CHECKS], [ # is used. AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([AC_PROG_CC_STDC]) +AC_REQUIRE([AC_LANG_C]) AC_REQUIRE([AC_ISC_POSIX]) AC_REQUIRE([AC_C_INLINE]) AC_REQUIRE([AC_C_CONST]) @@ -428,8 +403,8 @@ if test "$GCC" = "yes"; then # See whether a simple test program will compile without errors. ne_save_CPPFLAGS=$CPPFLAGS CPPFLAGS="$CPPFLAGS -Wformat -Werror" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h> -#include <stdio.h>]], [[int i = 42; printf("%d", i);]])], + AC_TRY_COMPILE([#include <sys/types.h> + #include <stdio.h>], [int i = 42; printf("%d", i);], [ne_cv_cc_werror=yes], [ne_cv_cc_werror=no]) CPPFLAGS=$ne_save_CPPFLAGS]) ne_fmt_trycompile=$ne_cv_cc_werror @@ -438,39 +413,6 @@ else fi ]) -dnl Check for LFS support -AC_DEFUN([NE_LARGEFILE], [ -dnl Need the size of off_t -AC_REQUIRE([NEON_COMMON_CHECKS]) - -if test -z "$ac_cv_sizeof_off_t"; then - NE_DISABLE_SUPPORT(LFS, [LFS support omitted: off_t size unknown!]) -elif test $ac_cv_sizeof_off_t != 4; then - NE_DISABLE_SUPPORT(LFS, [LFS support unnecessary, off_t is not 32-bit]) - AC_CHECK_FUNCS([strtoll strtoq], [break]) -elif test -z "$ac_cv_sizeof_long_long"; then - NE_DISABLE_SUPPORT(LFS, [LFS support omitted: long long size unknown]) -elif test $ac_cv_sizeof_long_long != 8; then - NE_DISABLE_SUPPORT(LFS, [LFS support omitted: long long not 64-bit]) -else - ne_save_CPPFLAGS=$CPPFLAGS - CPPFLAGS="$CPPFLAGS -D_LARGEFILE64_SOURCE" - AC_CHECK_TYPE(off64_t, [ - NEON_FORMAT(off64_t) - ne_lfsok=no - AC_CHECK_FUNCS([strtoll strtoq], [ne_lfsok=yes; break]) - AC_CHECK_FUNCS([lseek64 fstat64], [], [ne_lfsok=no; break]) - if test x$ne_lfsok = xyes; then - NE_ENABLE_SUPPORT(LFS, [LFS (large file) support enabled]) - NEON_CFLAGS="$NEON_CFLAGS -D_LARGEFILE64_SOURCE -DNE_LFS" - ne_save_CPPFLAGS="$CPPFLAGS -DNE_LFS" - else - NE_DISABLE_SUPPORT(LFS, - [LFS support omitted: 64-bit support functions not found]) - fi], [NE_DISABLE_SUPPORT(LFS, [LFS support omitted: off64_t type not found])]) - CPPFLAGS=$ne_save_CPPFLAGS -fi]) - dnl NEON_FORMAT(TYPE[, HEADERS[, [SPECIFIER]]) dnl dnl This macro finds out which modifier is needed to create a @@ -494,11 +436,11 @@ if test $ne_fmt_trycompile = yes; then oflags="$CPPFLAGS" # Consider format string mismatches as errors CPPFLAGS="$CPPFLAGS -Wformat -Werror" - dnl obscured for m4 quoting: "for str in d ld lld; do" - for str in ne_spec l]ne_spec[ ll]ne_spec[; do - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h> + dnl obscured for m4 quoting: "for str in d ld qd; do" + for str in ne_spec l]ne_spec[ q]ne_spec[; do + AC_TRY_COMPILE([#include <sys/types.h> $2 -#include <stdio.h>]], [[$1 i = 1; printf("%$str", i);]])], +#include <stdio.h>], [$1 i = 1; printf("%$str", i);], [ne_cv_fmt_$1=$str; break]) done CPPFLAGS=$oflags @@ -539,73 +481,37 @@ AC_REQUIRE([AC_C_BIGENDIAN]) dnl Is strerror_r present; if so, which variant AC_REQUIRE([AC_FUNC_STRERROR_R]) -AC_CHECK_HEADERS([sys/time.h limits.h sys/select.h arpa/inet.h \ - signal.h sys/socket.h netinet/in.h netinet/tcp.h netdb.h sys/poll.h],,, -[AC_INCLUDES_DEFAULT -/* netinet/tcp.h requires netinet/in.h on some platforms. */ -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif]) +AC_CHECK_HEADERS([strings.h sys/time.h limits.h sys/select.h arpa/inet.h \ + signal.h sys/socket.h netinet/in.h netinet/tcp.h netdb.h]) AC_REQUIRE([NE_SNPRINTF]) -dnl Check for large file support -NE_LARGEFILE - AC_REPLACE_FUNCS(strcasecmp) -AC_CHECK_FUNCS(signal setvbuf setsockopt stpcpy poll) - -if test "x${ac_cv_func_poll}${ac_cv_header_sys_poll_h}y" = "xyesyesy"; then - AC_DEFINE([NE_USE_POLL], 1, [Define if poll() should be used]) -fi - -if test "$ac_cv_func_stpcpy" = "yes"; then - AC_CHECK_DECLS(stpcpy) -fi - -# Modern AIXes with the "Linux-like" libc have an undeclared stpcpy -AH_BOTTOM([#if defined(HAVE_STPCPY) && defined(HAVE_DECL_STPCPY) && !HAVE_DECL_STPCPY && !defined(stpcpy) -char *stpcpy(char *, const char *); -#endif]) - -# Enable getaddrinfo support if it, gai_strerror and inet_ntop are -# all available. Solaris etc hide things in -lsocket, use that too. +AC_CHECK_FUNCS(signal setvbuf setsockopt stpcpy) # Unixware 7 can only link gethostbyname with -lnsl -lsocket # Pick up -lsocket first, then the gethostbyname check will work. -# QNX has gethostbyname in -lsocket. BeOS only has it in -lbind. NE_SEARCH_LIBS(socket, socket inet) -NE_SEARCH_LIBS(gethostbyname, socket nsl bind) - -NE_SEARCH_LIBS(getaddrinfo, nsl,, - [ne_enable_gai=no], - [# HP-UX boxes commonly get into a state where getaddrinfo is present - # but borked: http://marc.theaimsgroup.com/?l=apr-dev&m=107730955207120&w=2 - case x`uname -sr 2>/dev/null`y in - xHP-UX*11.[[01]]*y) - AC_MSG_NOTICE([getaddrinfo support disabled on HP-UX 11.0x/11.1x]) ;; - *) - ne_enable_gai=yes - NE_CHECK_FUNCS(gai_strerror inet_ntop,,[ne_enable_gai=no; break]) ;; - esac -]) +NE_SEARCH_LIBS(gethostbyname, nsl bind) +# Enable getaddrinfo() support only if all the necessary functions +# are found. +ne_enable_gai=yes +NE_CHECK_FUNCS(getaddrinfo gai_strerror inet_ntop,,[ne_enable_gai=no; break]) if test $ne_enable_gai = yes; then - NE_ENABLE_SUPPORT(IPV6, [IPv6 support is enabled]) AC_DEFINE(USE_GETADDRINFO, 1, [Define if getaddrinfo() should be used]) AC_CACHE_CHECK([for working AI_ADDRCONFIG], [ne_cv_gai_addrconfig], [ AC_RUN_IFELSE([AC_LANG_PROGRAM([#include <netdb.h>], [struct addrinfo hints = {0}, *result; hints.ai_flags = AI_ADDRCONFIG; if (getaddrinfo("localhost", NULL, &hints, &result) != 0) return 1;])], - ne_cv_gai_addrconfig=yes, ne_cv_gai_addrconfig=no, ne_cv_gai_addrconfig=no)]) + ne_cv_gai_addrconfig=yes, ne_cv_gai_addrconfig=no)]) if test $ne_cv_gai_addrconfig = yes; then AC_DEFINE(USE_GAI_ADDRCONFIG, 1, [Define if getaddrinfo supports AI_ADDRCONFIG]) fi else # Checks for non-getaddrinfo() based resolver interfaces. - NE_SEARCH_LIBS(gethostbyname, nsl bind) NE_SEARCH_LIBS(hstrerror, resolv,,[:]) NE_CHECK_FUNCS(hstrerror) # Older Unixes don't declare h_errno. @@ -613,16 +519,16 @@ else #include <netdb.h>]) fi -AC_CHECK_MEMBERS([struct tm.tm_gmtoff, struct tm.__tm_gmtoff],,, - [#include <time.h>]) - -if test $ac_cv_member_struct_tm_tm_gmtoff$ac_cv_member_struct_tm___tm_gmtoff = nono; then - AC_MSG_WARN([no timezone handling in date parsing on this platform]) -fi +AC_CHECK_MEMBERS(struct tm.tm_gmtoff,, +AC_MSG_WARN([no timezone handling in date parsing on this platform]), +[#include <time.h>]) -ifdef([neon_no_zlib], - [NE_DISABLE_SUPPORT(ZLIB, [zlib not supported])], - [NEON_ZLIB()]) +ifdef([neon_no_zlib], [ + neon_zlib_message="zlib disabled" + NEON_SUPPORTS_ZLIB=no +], [ + NEON_ZLIB() +]) # Conditionally enable ACL support AC_MSG_CHECKING([whether to enable ACL support in neon]) @@ -635,7 +541,6 @@ fi NEON_SSL() NEON_SOCKS() -NEON_LIBIDN() NEON_GSSAPI() AC_SUBST(NEON_CFLAGS) @@ -686,17 +591,27 @@ ne="$NEON_EXTRAOBJS" NEON_EXTRAOBJS= for o in $ne; do NEON_EXTRAOBJS="$NEON_EXTRAOBJS $o.$NEON_OBJEXT" -done +done + +AC_MSG_CHECKING(whether to enable WebDAV support in neon) -# Was DAV support explicitly turned off? +dnl Did they want DAV support? if test "x$neon_no_webdav" = "xyes"; then # No WebDAV support + AC_MSG_RESULT(no) NEONOBJS="$NEONOBJS \$(NEON_BASEOBJS)" - NE_DISABLE_SUPPORT(DAV, [WebDAV support is not enabled]) + NEON_CFLAGS="$NEON_CFLAGS -DNEON_NODAV" + NEON_SUPPORTS_DAV=no + AC_DEFINE(NEON_NODAV, 1, [Enable if built without WebDAV support]) else # WebDAV support + NEON_SUPPORTS_DAV=yes NEONOBJS="$NEONOBJS \$(NEON_DAVOBJS)" - NE_ENABLE_SUPPORT(DAV, [WebDAV support is enabled]) + # Turn on DAV locking please then. + AC_DEFINE(USE_DAV_LOCKS, 1, [Support WebDAV locking through the library]) + + AC_MSG_RESULT(yes) + fi AC_SUBST(NEON_TARGET) @@ -704,6 +619,7 @@ AC_SUBST(NEON_OBJEXT) AC_SUBST(NEONOBJS) AC_SUBST(NEON_EXTRAOBJS) AC_SUBST(NEON_LINK_FLAGS) +AC_SUBST(NEON_SUPPORTS_DAV) ]) @@ -751,7 +667,7 @@ AC_CHECK_FUNCS(snprintf vsnprintf,,[ AC_MSG_ERROR([trio installation problem? libtrio found but not trio.h])) AC_MSG_NOTICE(using trio printf replacement library) NEON_LIBS="$NEON_LIBS -ltrio -lm" - AC_DEFINE(HAVE_TRIO, 1, [Use trio printf replacement library])], + NEON_CFLAGS="$NEON_CFLAGS -DNEON_TRIO"], [AC_MSG_NOTICE([no vsnprintf/snprintf detected in C library]) AC_MSG_ERROR([Install the trio library from http://daniel.haxx.se/trio/])]) LIBS=$ne_save_LIBS @@ -796,7 +712,7 @@ fi]) dnl Check for OpenSSL AC_DEFUN([NEON_SSL], [ -AC_ARG_WITH(ssl, AS_HELP_STRING([--with-ssl], [enable OpenSSL support])) +AC_ARG_WITH(ssl, [AC_HELP_STRING([--with-ssl], [enable OpenSSL support])]) AC_ARG_WITH(egd, [[ --with-egd[=PATH] enable EGD support [using EGD socket at PATH]]]) @@ -819,14 +735,14 @@ yes) NE_CHECK_SSLVER(ne_cv_lib_ssl097, 0.9.7, 0x00907000L) if test "$ne_cv_lib_ssl097" = "yes"; then AC_MSG_NOTICE([OpenSSL >= 0.9.7; EGD support not needed in neon]) - NE_ENABLE_SUPPORT(SSL, [SSL support enabled, using OpenSSL (0.9.7 or later)]) + neon_ssl_message="OpenSSL (0.9.7 or later)" else # Fail if OpenSSL is older than 0.9.6 NE_CHECK_SSLVER(ne_cv_lib_ssl096, 0.9.6, 0x00906000L) if test "$ne_cv_lib_ssl096" != "yes"; then AC_MSG_ERROR([OpenSSL 0.9.6 or later is required]) fi - NE_ENABLE_SUPPORT(SSL, [SSL support enabled, using OpenSSL (0.9.6 or later)]) + neon_ssl_message="OpenSSL (0.9.6 or later)" case "$with_egd" in yes|no) ne_cv_lib_sslegd=$with_egd ;; @@ -848,31 +764,19 @@ yes) fi fi + NEON_SUPPORTS_SSL=yes + NEON_CFLAGS="$NEON_CFLAGS -DNEON_SSL" NEON_EXTRAOBJS="$NEON_EXTRAOBJS ne_openssl" ;; *) # Default to off; only create crypto-enabled binaries if requested. - NE_DISABLE_SUPPORT(SSL, [SSL support is not enabled]) + neon_ssl_message="No SSL support" + NEON_SUPPORTS_SSL=no NEON_EXTRAOBJS="$NEON_EXTRAOBJS ne_stubssl" ;; esac AC_SUBST(NEON_SUPPORTS_SSL) ]) -dnl Check for GNU libidn -AC_DEFUN([NEON_LIBIDN], [ -AC_ARG_WITH(libidn, AS_HELP_STRING(--without-libidn, disable IDNA support)) -if test "$with_libidn" != "no"; then - ne_use_idna=no - AC_CHECK_HEADER(idna.h, - [NE_SEARCH_LIBS(idna_to_ascii_8z,idn,,,[ne_use_idna=yes])]) - if test $ne_use_idna = yes; then - NE_ENABLE_SUPPORT(IDNA, [IDNA support enabled using GNU libidn]) - else - NE_DISABLE_SUPPORT(IDNA, - [IDNA support not enabled; GNU libidn >=0.2.0 required]) - fi -fi]) - dnl Check for Kerberos installation AC_DEFUN([NEON_GSSAPI], [ AC_PATH_PROG([KRB5_CONFIG], krb5-config, none, $PATH:/usr/kerberos/bin) @@ -889,7 +793,7 @@ if test "x$KRB5_CONFIG" != "xnone"; then AC_MSG_NOTICE([GSSAPI authentication support enabled]) AC_DEFINE(HAVE_GSSAPI, 1, [Define if GSSAPI support is enabled]) AC_CHECK_HEADERS(gssapi/gssapi_generic.h) - # Older versions of MIT Kerberos lack GSS_C_NT_HOSTBASED_SERVICE + # MIT Kerberos lacks GSS_C_NT_HOSTBASED_SERVICE AC_CHECK_DECL([GSS_C_NT_HOSTBASED_SERVICE],, [AC_DEFINE([GSS_C_NT_HOSTBASED_SERVICE], gss_nt_service_name, [Define if GSS_C_NT_HOSTBASED_SERVICE is not defined otherwise])], @@ -911,12 +815,12 @@ AC_DEFUN([NEON_WARNINGS],[ AC_REQUIRE([AC_PROG_CC]) dnl so that $GCC is set AC_ARG_ENABLE(warnings, -AS_HELP_STRING(--enable-warnings, [enable compiler warnings])) +AC_HELP_STRING(--enable-warnings, [enable compiler warnings])) if test "$enable_warnings" = "yes"; then case $GCC:`uname` in yes:*) - CFLAGS="$CFLAGS -Wall -Wmissing-declarations -Wshadow -Wreturn-type -Wsign-compare -Wundef -Wpointer-arith -Wcast-align -Wbad-function-cast -Wformat-security" + CFLAGS="$CFLAGS -Wall -ansi-pedantic -Wmissing-declarations -Winline -Wshadow -Wreturn-type -Wsign-compare -Wundef -Wpointer-arith -Wcast-align -Wbad-function-cast -Wimplicit-prototypes -Wformat-security" if test -z "$with_ssl" -o "$with_ssl" = "no"; then # OpenSSL headers fail strict prototypes checks CFLAGS="$CFLAGS -Wstrict-prototypes" @@ -938,7 +842,7 @@ dnl AC_DEFUN([NEON_DEBUG], [ AC_ARG_ENABLE(debug, -AS_HELP_STRING(--disable-debug,[disable runtime debugging messages])) +AC_HELP_STRING(--disable-debug,[disable runtime debugging messages])) # default is to enable debugging case $enable_debug in @@ -953,21 +857,21 @@ esac]) dnl Macro to optionally enable socks support AC_DEFUN([NEON_SOCKS], [ -AC_ARG_WITH([socks], AS_HELP_STRING([--with-socks],[use SOCKSv5 library])) +AC_ARG_WITH([socks], AC_HELP_STRING([--with-socks],[use SOCKSv5 library])) if test "$with_socks" = "yes"; then ne_save_LIBS=$LIBS AC_CHECK_HEADERS(socks.h, - [AC_CHECK_LIB(socks5, connect, [:], + [AC_CHECK_LIB(socks5, connect, + [AC_MSG_NOTICE([SOCKSv5 support enabled])], [AC_MSG_ERROR([could not find libsocks5 for SOCKS support])])], [AC_MSG_ERROR([could not find socks.h for SOCKS support])]) - NE_ENABLE_SUPPORT(SOCKS, [SOCKSv5 support is enabled]) + CFLAGS="$CFLAGS -DNEON_SOCKS" NEON_LIBS="$NEON_LIBS -lsocks5" LIBS=$ne_save_LIBS -else - NE_DISABLE_SUPPORT(SOCKS, [SOCKSv5 support is not enabled]) + fi]) AC_DEFUN([NEON_WITH_LIBS], [ diff --git a/neon-config.in b/neon-config.in index 8db113c..27b74d1 100644 --- a/neon-config.in +++ b/neon-config.in @@ -1,6 +1,6 @@ #! /bin/sh # Originally from libxml, Copyright (C) Daniel Veillard -# Modifications for neon Copyright (C) 2000-2004 Joe Orton. +# Modifications for neon Copyright (C) 2000-2002 Joe Orton. prefix=@prefix@ exec_prefix=@exec_prefix@ @@ -21,7 +21,7 @@ Known values for OPTION are: --help display this help and exit --version output version information --support FEATURE exit with success if feature is supported - Known features: dav [@NE_FLAG_DAV@], ssl [@NE_FLAG_SSL@], zlib [@NE_FLAG_ZLIB@], idna [@NE_FLAG_IDNA@], ipv6 [@NE_FLAG_IPV6@], lfs [@NE_FLAG_LFS@] + Known features: dav [@NEON_SUPPORTS_DAV@], ssl [@NEON_SUPPORTS_SSL@], zlib [@NEON_SUPPORTS_ZLIB@] EOF @@ -87,18 +87,16 @@ while test $# -gt 0; do shift case "$1" in - ssl|SSL) support @NE_FLAG_SSL@ ;; - zlib|ZLIB) support @NE_FLAG_ZLIB@ ;; - ipv6|IPV6) support @NE_FLAG_IPV6@ ;; - dav|DAV) support @NE_FLAG_DAV@ ;; - idna|IDNA) support @NE_FLAG_IDNA@ ;; - lfs|LFS) support @NE_FLAG_LFS@ ;; + ssl|SSL) support @NEON_SUPPORTS_SSL@ ;; + zlib|ZLIB) support @NEON_SUPPORTS_ZLIB@ ;; + dav|DAV) support @NEON_SUPPORTS_DAV@ ;; *) support no ;; esac ;; *) - usage 1 1>&2 + usage + exit 1 ;; esac shift diff --git a/src/.cvsignore b/src/.cvsignore index 61aba4e..6eb5bf3 100644 --- a/src/.cvsignore +++ b/src/.cvsignore @@ -14,4 +14,3 @@ checkincl.c *.da *.bbg *.[is] -*.gcno diff --git a/src/ChangeLog b/src/ChangeLog index 7859493..68760c1 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,118 +1,3 @@ -Sun Sep 12 19:21:30 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_locks.c (ne_lock_refresh): Fix to pass correct userdata to - callbacks, and do call lk_cdata. - -Sun Sep 12 18:53:15 2004 Joe Orton <joe@manyfish.co.uk> - - * Makefile.in (libneon.a): Remove the archive first, avoiding - strange problems when build $(OBJECTS) change. - -Sun Sep 12 18:40:50 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_utils.h: Add NE_FEATURE_SOCKS. - - * ne_utils.c (ne_has_support): Add NE_FEATURE_SOCKS. - (version_string): Use NE_HAVE_SOCKS, add NE_HAVE_IDNA. - - * ne_socket.c (ne_sock_init): Use NE_HAVE_SOCKS. - -Sun Sep 12 17:29:54 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_utils.c (version_string): Declare as array rather than - pointer; include "IPv6" component as necessary - -Sun Sep 12 15:51:38 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_socket.c (ne_iaddr_typeof): New function. - -Sun Sep 12 12:00:10 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_defs.h (ne_attribute_malloc): New macro. - - * ne_alloc.h: Use it to avoid warnings with older GCCs. - -Wed Aug 25 21:03:40 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_string.h (split_string, split_string_c, pair_string, - split_string_free, pair_string_free): Remove obsolete interfaces. - -Wed Aug 25 21:01:03 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_cookies.c, ne_cookies.h: Drop cookies support: used old spec - revision and wasn't very complete anyway. - -Wed Aug 25 20:40:26 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_socket.c: Remove ne_read, ne_write macros and just use recv - and send; remove unused SOCK_ERR macro. - -Wed Aug 25 20:27:43 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_xml.c (declare_nspaces): Drop rejection of names including a - colon to prevent breaking SVN deployments. - -Wed Aug 25 19:45:20 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_socket.c (readable_raw): Use poll where available. - (ne_sock_connect): Fail if not using poll and fd returned by - socket() is greater than FD_SETSIZE. - -Wed Aug 25 18:40:28 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_xml.h (ne_xml_parse): Clarify that a len=0 call is required - to signify end-of-document. - -Wed Aug 25 18:37:13 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_request.c (resolve_first, resolve_next): New functions. - (lookup_host): Use them to allow user-forced addresses. - - * ne_session.c (ne_set_addrlist): New function. - - * ne_private.h (struct ne_session_s): Add addrlist, numaddrs, - curaddr fields. - -Wed Aug 25 18:25:31 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_xml.c (struct ne_xml_parser_s): Add bom_pos field. - (ne_xml_parse): Skip over the UTF-8 Byte Order Mark since - the XML parsers do not support it yet. - -Wed Jul 7 16:07:44 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_request.c (do_connect): Fix ne_conn_connected status call - (Shameek Basu). - -Mon Jul 5 18:40:35 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_basic.c (ne_content_type_handler): Use us-ascii as default - charset for text/xml, as per RFC3280. - -Mon Jul 5 10:56:19 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_compress.c (struct ne_decompress_s): Add acceptor field. - (gz_acceptor): New function. - (ne_decompress_reader): Fix to pass the user-supplied userdata - pointer to the user-supplied acceptor callback, via gz_acceptor. - -Mon Jul 5 10:52:40 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_compress.c (do_inflate): Don't invoke the reader callback if - no bytes where produced by inflate(). - (process_footer): Call the reader callback with size=0 to indicate - end-of-response for a good checksum match. - -Sat Jul 3 14:33:56 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_auth.c (auth_challenge): Fix to set got_qop in challenge - correctly (Hideaki Takahashi). - -Mon May 17 15:03:54 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_socket.h (ne_addr_resolve): Clarify that 'flags' must - be passed as zero for forwards-compat. - Sun May 2 21:14:14 2004 Joe Orton <joe@manyfish.co.uk> Fix buffer overflow in RFC1036 date parser, CVE CAN-2004-0389. @@ -122,18 +7,16 @@ Sun May 2 21:14:14 2004 Joe Orton <joe@manyfish.co.uk> (ne_rfc1123_parse, ne_rfc1036_parse, ne_asctime_parse): Make thread-safe; remove static buffers. -Sun May 2 16:59:39 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_dates.c [RFC1123_TEST] (main): Remove embedded test cases. - -Sun May 2 13:18:29 2004 Joe Orton <joe@manyfish.co.uk> +Thu Mar 11 23:38:01 2004 Joe Orton <joe@manyfish.co.uk> - * Makefile.in (LINK): Add -no-undefined. + * ne_openssl.c (provide_client_cert): Avoid malloc(0) when server + sends no CA names in CertificateRequest. + (ne_ssl_cert_write): Be paranoid and clear the OpenSSL error stack + on write failures. -Fri Apr 16 22:53:59 2004 Joe Orton <joe@manyfish.co.uk> +Sun May 2 16:59:39 2004 Joe Orton <joe@manyfish.co.uk> - * ne_xml.c (declare_nspaces, expand_qname): Don't try to include - document context in error strings. + * ne_dates.c [RFC1123_TEST] (main): Remove embedded test cases. Fri Apr 16 11:44:34 2004 Joe Orton <joe@manyfish.co.uk> @@ -166,83 +49,11 @@ Thu Apr 8 13:40:03 2004 Joe Orton <joe@manyfish.co.uk> * ne_props.h: Don't use an anonymous enum for the proppatch operation type, as some C++ compilers don't like it. -Wed Apr 7 13:50:10 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_request.c (add_fixed_headers): Don't both sending Keep-Alive - header if persistent connections are disabled. - -Wed Apr 7 13:47:46 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_auth.c (auth_challenge): Allow Negotiate challenges from - a proxy. - -Wed Apr 7 13:36:55 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_auth.c (clean_session): Remove redundant assignment of - GSS_C_NO_CONTEXT; gss_delete_sec_context already does this. - -Wed Apr 7 13:33:10 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_auth.c (get_gss_name): Handle failure case internally. - (auth_register): Updated accordingly. - -Wed Apr 7 13:15:57 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_request.c: Use strtoq to print off_t's where necessary. - -Wed Apr 7 11:14:24 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_auth.c (get_gss_name): Take a hostname string. - (auth_register): Pass proxy or server hostname to get_gss_name as - appropriate. - -Wed Apr 7 11:09:50 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_auth.c (continue_negotiate): If given no input token, and the - gssctx is not in the initial state, reset it. - -Mon Mar 29 17:06:49 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_auth.c: Adjust to cope with GSSAPI continuation: - (struct auth_session_s): Store GSSAPI context, name and mechanism. - (get_gss_name): Take an ne_session. - (continue_negotiate): Renamed from gssapi_challenge; take input - token, handle GSS_S_CONTINUE_NEEDED return value. - (verify_digest_response): Renamed from verify_response. - (verify_negotiate_response): New function. - (auth_challenge): Cope with Negotiate responses which gratuitously - break the auth-param grammar. - (ah_post_send): Handle Negotiate responses. - (free_auth, clean_session): Free persisted GSSAPI objects. - (auth_register): Initialize GSSAPI objects. - -Sun Mar 28 03:03:17 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_auth.c (get_gss_name): Don't leak token.value. - Sun Mar 28 02:59:58 2004 Joe Orton <joe@manyfish.co.uk> * ne_auth.c (get_cnonce): Only use RAND_pseudo_bytes() if the PRNG is seeded. -Sun Mar 28 02:47:20 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_auth.c (gssapi_challenge, get_gss_name): Simplify. - -Sun Mar 28 02:35:48 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_auth.c (request_gssapi, get_gss_name, auth_challenge): - Implement the Negotiate protocol rather than the obsoleted - GSS-Negotiate. - (make_gss_error): New function. - (gssapi_challenge): Use it for better error handling (set session - error string); fix memory leaks. Don't delegate credentials. - -Sat Mar 27 20:49:24 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_auth.c (ah_post_send): Clear auth header collector buffers - after each request. - Fri Mar 26 12:16:15 2004 Joe Orton <joe@manyfish.co.uk> * ne_socket.c (init_ssl): Just initialize the SSL library; delay @@ -256,72 +67,12 @@ Fri Mar 26 12:01:38 2004 Joe Orton <joe@manyfish.co.uk> * ne_utils.c: Include zlib.h before ne_*.h to fix issues on platforms where zconf.h does "#define const". -Thu Mar 11 23:38:01 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_openssl.c (provide_client_cert): Avoid malloc(0) when server - sends no CA names in CertificateRequest. - (ne_ssl_cert_write): Be paranoid and clear the OpenSSL error stack - on write failures. - -Sun Mar 7 11:17:04 2004 Joe Orton <joe@manyfish.co.uk> - - * Makefile.in (CFLAGS): Don't use NEON_CFLAGS. - -Mon Feb 23 23:03:08 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_string.c (ne_vsnprintf, ne_snprintf): New functions. - -Sun Feb 22 23:34:47 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_private.h (struct ne_session_s): Remove expect100_works field. - - * ne_request.c (ne_set_request_expect100): New function. - (ne_begin_request): Remove req->use_expect100 manipulation. - (send_request): Handle enabling 100continue without a request - body. - - * ne_session.c (ne_set_expect100): Removed function. - -Sun Feb 22 20:17:04 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_socket.c (error_ossl): Check for ERR_reason_error_string - returning NULL. - -Sun Feb 22 17:54:43 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_socket.c: Don't disable getaddrinfo support here. - -Sun Feb 22 17:40:07 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_utils.h (min): Remove definition to... - - * ne_uri.c (min): ...here. - -Sun Feb 22 17:31:35 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_props.h: Give the 'type' enum a tag name. - -Sun Feb 22 17:27:28 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_207.c (end_element): Strip whitespace from cdata. - -Sun Feb 22 16:27:58 2004 Joe Orton <joe@manyfish.co.uk> +Fri Mar 26 11:55:06 2004 Joe Orton <joe@manyfish.co.uk> - * ne_auth.c (struct auth_request): Make auth_hdr, auth_info_hdr - fields into ne_buffer *'s. - (ah_collect_header): New function. - (ah_create): Create ne_buffers for auth_{,info_}hdr; use - ah_collect_header rather than ne_duplicate_header to fix handling - of multiple auth challenge headers. - (ah_post_send): Adjust for char * -> ne_buffer *. - (tokenize): Recognize a challenge scheme which is terminated with - a comma (i.e. with no challange parameters). - (auth_challenge): Fix handling of unrecognized challenges. - (ah_destroy): Destroy ne_buffers. - -Sun Feb 22 15:04:46 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_request.c (ne_set_request_body_provider64): New function. + * ne_auth.c (get_gss_name, request_gssapi, gssapi_challenge, + auth_challenge): Implement the Negotiate auth scheme rather than + the obsolete GSS-Negotiate, and fix memory leaks. Only accept + Negotiate challenges over SSL. Sun Feb 15 13:37:03 2004 Joe Orton <joe@manyfish.co.uk> @@ -331,112 +82,11 @@ Sun Feb 15 13:37:03 2004 Joe Orton <joe@manyfish.co.uk> * ne_openssl.c (ne_ssl_readable_dname): Convert dname strings to UTF-8, or use "???". -Sat Feb 14 21:57:25 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_xml.c (invalid_ncname_ch1): New macro. - (declare_nspaces): Use it, to reject some more invalid namespace - prefixes; also check for a colon anywhere in the NCName. - (expand_qname): Likewise for the element name. - -Mon Feb 9 21:38:03 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_dates.c [WIN32] (GMTOFF): Use gmt_to_local_win32; - (gmt_to_local_win32): New function, from Jiang Lei. - -Mon Jan 26 14:38:05 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_socket.c (ne_sock_connect_ssl): Check that OpenSSL version - matches between library at run-time and headers at compile-time. - -Sat Jan 24 17:49:27 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_dates.c (HAVE_STRUCT_TM___TM_GMTOFF): Alternative GMTOFF() - macro. - Sat Jan 24 16:49:30 2004 Joe Orton <joe@manyfish.co.uk> * ne_auth.c (basic_challenge): Cast first parameter to ne_base64 to unsigned char * to fix warnings with some compilers. -Sat Jan 3 13:17:36 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_request.h (ne_set_request_body_fd64): Define conditional on - NE_LFS. - - * ne_request.c (ne_set_request_body_fd64): Likewise. - -Thu Jan 1 18:01:45 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_request.c: Use NE_HAVE_LFS not _LARGEFILE64_SOURCE in - conditional support for off64_t. - -Thu Jan 1 17:38:55 2004 Joe Orton <joe@manyfish.co.uk> - - * ne_request.h [_LARGEFILE64_SOURCE] (ne_set_request_body_fd64): - New function. - - * ne_request.c: Define ne_lseek, ne_off_t, ne_strtoff, - NE_OFFT_MAX, FMT_NE_OFF_T appropriately for _LARGEFILE64_SOURCE or - otherwise. - (struct ne_request_s): Use ne_off_t in place of off_t throughout. - (body_fd_send): Use ne_lseek; reset 'remain' after seeking. - (clength_hdr_handler): Use ne_off_t, ne_strtoff and NE_OFFT_MAX. - (set_body_length): Take an ne_off_t length parameter; use - FMT_NE_OFF_T to print it. - (ne_set_request_body_fd64): New function. - - * ne_utils.h (NE_FEATURE_LFS): New feature. - - * ne_utils.c (ne_has_support): Support NE_FEATURE_LFS. - -Mon Nov 24 20:13:14 2003 Joe Orton <joe@manyfish.co.uk> - - * ne_request.c (struct ne_response): Split handling for chunked vs - clength-delimited responses into a union. Use off_t for storing - whole-length-of-response values. - (read_response_block, ne_read_response_block): Update accordingly. - (ne_begin_request): Remove unnecessary variable assignments. - -Sun Nov 23 16:03:22 2003 Joe Orton <joe@manyfish.co.uk> - - * ne_request.h (ne_set_request_body_fd): Take offset and length - arguments, return void. - (ne_set_request_body_provider): Take off_t length argument. - - * ne_request.c (struct ne_request_s): Store current position - within buffer/file used as request body source. Store request - body lengths using off_t type. - (body_string_send): Adjust for renamed fields. - (body_fd_send): Seek to requested offset; don't read past - requested body length. - (set_body_length): Renamed from set_body_size. - - * ne_basic.c (ne_put): Determine file size here; adjust for new - ne_set_request_body_fd API. - -Sun Nov 23 15:05:12 2003 Joe Orton <joe@manyfish.co.uk> - - * ne_basic.c, ne_basic.h: Remove two-functions-in-one, - ne_put_if_unmodified. - -Fri Nov 14 14:05:32 2003 Joe Orton <joe@manyfish.co.uk> - - * ne_utils.c (ne_has_support): Add NE_FEATURE_IDNA. - -Fri Nov 14 13:11:49 2003 Joe Orton <joe@manyfish.co.uk> - - * ne_session.c (set_hostinfo): [NE_HAVE_LIBIDN]: Use string from - IDNA ToAscii operation on provided hostname if successful. - -Fri Nov 14 11:23:16 2003 Joe Orton <joe@manyfish.co.uk> - - All files: replace use of NEON_NODAV with NE_HAVE_DAV, NEON_SSL - with NE_HAVE_SSL, NEON_ZLIB with NE_HAVE_ZLIB. Use NE_HAVE_DAV - not USE_DAV_LOCKS. - - * ne_utils.c (ne_has_support): New feature detection interface, - replaces ne_supports_ssl. - Thu Nov 13 20:38:28 2003 Joe Orton <joe@manyfish.co.uk> * ne_request.c (ne_begin_request): Presume a 205 response has no @@ -448,42 +98,6 @@ Thu Nov 13 20:31:07 2003 Joe Orton <joe@manyfish.co.uk> request as a valid proxy auth challenge, to work around buggy proxies. -Tue Nov 11 21:13:18 2003 Joe Orton <joe@manyfish.co.uk> - - Place library-internal symbols in the "ne__" namespace. - - * ne_request.c (ne__pull_request_body): Renamed from - ne_pull_request_body; all callers updated. - - * ne_session.c (ne__negotiate_ssl): Renamed from - ne_negotiate_ssl; all callers updated. - -Tue Nov 11 21:08:54 2003 Joe Orton <joe@manyfish.co.uk> - - * ne_alloc.h: Mark all allocation functions as having 'malloc' - attribute for GCC. - -Tue Nov 11 20:36:12 2003 Joe Orton <joe@manyfish.co.uk> - - * ne_xml.h (ne_xml_failure): Replaces ne_xml_valid, - inverted and more useful return value. - - * ne_xml.c (struct ne_xml_parser_s): Replace 'valid' field with - 'failure', with inverted logic. - (start_element, end_element, char_data): Check failure flag - appropriately. Set failure flag to return value of callback. - Set failure flag to positive integer on a parse error. - (ne_xml_create): Don't initialize failure flag. - (ne_xml_parse): Check/set failure flag appropriately. - (sax_error): Only set an error string (and the error flag) - if failure is zero. - - * ne_207.c (ne_simple_request): Adjust to use ne_xml_failure. - - * ne_locks.c (ne_lock, ne_lock_refresh): Likewise. - - * ne_props.c (propfind): Likewise. - Wed Oct 22 22:19:19 2003 Joe Orton <joe@manyfish.co.uk> * ne_request.c (read_response_block): Treat an EOF without clean diff --git a/src/Makefile.in b/src/Makefile.in index 81c9522..a0fb73a 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -25,7 +25,7 @@ LIBTOOL = @LIBTOOL@ # Flags CPPFLAGS = @DEFS@ @CPPFLAGS@ -CFLAGS = @CFLAGS@ +CFLAGS = @CFLAGS@ @NEON_CFLAGS@ LDFLAGS = @LDFLAGS@ NEON_LINK_FLAGS = @NEON_LINK_FLAGS@ # Note: don't substitute @LIBS@ in here; during a bundled @@ -33,14 +33,15 @@ NEON_LINK_FLAGS = @NEON_LINK_FLAGS@ LIBS = @NEON_LIBS@ @NEON_LTLIBS@ COMPILE = $(CC) $(CPPFLAGS) $(CFLAGS) -LINK = $(LIBTOOL) --quiet --mode=link $(CC) -no-undefined $(LDFLAGS) +LINK = $(LIBTOOL) --quiet --mode=link $(CC) $(LDFLAGS) NEON_BASEOBJS = ne_request.@NEON_OBJEXT@ ne_session.@NEON_OBJEXT@ \ ne_basic.@NEON_OBJEXT@ ne_string.@NEON_OBJEXT@ \ ne_uri.@NEON_OBJEXT@ ne_dates.@NEON_OBJEXT@ ne_alloc.@NEON_OBJEXT@ \ ne_md5.@NEON_OBJEXT@ ne_utils.@NEON_OBJEXT@ \ ne_socket.@NEON_OBJEXT@ ne_auth.@NEON_OBJEXT@ \ - ne_redirect.@NEON_OBJEXT@ ne_compress.@NEON_OBJEXT@ + ne_cookies.@NEON_OBJEXT@ ne_redirect.@NEON_OBJEXT@ \ + ne_compress.@NEON_OBJEXT@ NEON_DAVOBJS = $(NEON_BASEOBJS) \ ne_207.@NEON_OBJEXT@ ne_xml.@NEON_OBJEXT@ \ @@ -69,7 +70,6 @@ libneon.la: $(OBJECTS) $(LINK) -rpath $(libdir) $(NEON_LINK_FLAGS) -o $@ $(OBJECTS) $(LIBS) libneon.a: $(OBJECTS) - @rm -f $@ $(AR) cru $@ $(OBJECTS) $(RANLIB) $@ @@ -139,8 +139,9 @@ ne_locks.@NEON_OBJEXT@: ne_locks.c $(neonreq) ne_locks.h ne_207.h ne_xml.h ne_redirect.@NEON_OBJEXT@: ne_redirect.c $(neonreq) ne_redirect.h \ ne_uri.h ne_private.h +ne_cookies.@NEON_OBJEXT@: ne_cookies.c $(neonreq) ne_cookies.h ne_uri.h \ + ne_private.h + ne_compress.@NEON_OBJEXT@: ne_compress.c $(neonreq) ne_compress.h ne_acl.@NEON_OBJEXT@: ne_acl.c ne_acl.h $(neonreq) - -ne_stubssl.@NEON_OBJEXT@: ne_stubssl.c $(neonreq) diff --git a/src/ne_207.c b/src/ne_207.c index dec4ddf..039bc6b 100644 --- a/src/ne_207.c +++ b/src/ne_207.c @@ -158,7 +158,7 @@ static int end_element(void *userdata, int state, const char *nspace, const char *name) { ne_207_parser *p = userdata; - const char *cdata = ne_shave(p->cdata->data, "\r\n\t "); + const char *cdata = p->cdata->data; switch (state) { case ELM_responsedescription: @@ -318,7 +318,7 @@ int ne_simple_request(ne_session *sess, ne_request *req) if (ret == NE_OK) { if (ne_get_status(req)->code == 207) { - if (ne_xml_failed(p)) { + if (!ne_xml_valid(p)) { /* The parse was invalid */ ne_set_error(sess, "%s", ne_xml_get_error(p)); ret = NE_ERROR; diff --git a/src/ne_acl.c b/src/ne_acl.c index a6047e0..c540a0e 100644 --- a/src/ne_acl.c +++ b/src/ne_acl.c @@ -111,7 +111,7 @@ int ne_acl_set(ne_session *sess, const char *uri, ne_request *req = ne_request_create(sess, "ACL", uri); ne_buffer *body = acl_body(entries, numentries); -#ifdef NE_HAVE_DAV +#ifdef USE_DAV_LOCKS ne_lock_using_resource(req, uri, 0); #endif diff --git a/src/ne_alloc.h b/src/ne_alloc.h index 3a3e2ec..1da4a38 100644 --- a/src/ne_alloc.h +++ b/src/ne_alloc.h @@ -1,6 +1,6 @@ /* Replacement memory allocation handling etc. - Copyright (C) 1999-2004, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 1999-2002, Joe Orton <joe@manyfish.co.uk> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -41,11 +41,11 @@ void ne_oom_callback(void (*callback)(void)); * neon will abort(); calling an OOM callback beforehand if one is * registered. The C library will only ever return NULL if the * operating system does not use optimistic memory allocation. */ -void *ne_malloc(size_t size) ne_attribute_malloc; -void *ne_calloc(size_t size) ne_attribute_malloc; -void *ne_realloc(void *ptr, size_t s) ne_attribute_malloc; -char *ne_strdup(const char *s) ne_attribute_malloc; -char *ne_strndup(const char *s, size_t n) ne_attribute_malloc; +void *ne_malloc(size_t size); +void *ne_calloc(size_t size); +void *ne_realloc(void *ptr, size_t s); +char *ne_strdup(const char *s); +char *ne_strndup(const char *s, size_t n); #define ne_free free #endif diff --git a/src/ne_auth.c b/src/ne_auth.c index 52a137c..e3504a0 100644 --- a/src/ne_auth.c +++ b/src/ne_auth.c @@ -50,7 +50,7 @@ #include <windows.h> /* for GetCurrentThreadId() etc */ #endif -#ifdef NE_HAVE_SSL +#ifdef NEON_SSL #include <openssl/rand.h> #endif @@ -161,11 +161,8 @@ typedef struct { /* This used for Basic auth */ char *basic; #ifdef HAVE_GSSAPI - /* for the GSSAPI/Negotiate scheme: */ + /* This used for GSSAPI auth */ char *gssapi_token; - gss_ctx_id_t gssctx; - gss_name_t gssname; - gss_OID gssmech; #endif /* These all used for Digest auth */ char *realm; @@ -205,7 +202,7 @@ struct auth_request { struct ne_md5_ctx response_body; /* Results of response-header callbacks */ - ne_buffer *auth_hdr, *auth_info_hdr; + char *auth_hdr, *auth_info_hdr; }; static void clean_session(auth_session *sess) @@ -217,17 +214,6 @@ static void clean_session(auth_session *sess) NE_FREE(sess->opaque); NE_FREE(sess->realm); #ifdef HAVE_GSSAPI - { - int major; - - if (sess->gssctx != GSS_C_NO_CONTEXT) - gss_delete_sec_context(&major, sess->gssctx, GSS_C_NO_BUFFER); - - if (sess->gssmech != GSS_C_NO_OID) { - gss_release_oid(&major, &sess->gssmech); - sess->gssmech = GSS_C_NO_OID; - } - } NE_FREE(sess->gssapi_token); #endif } @@ -241,7 +227,7 @@ static char *get_cnonce(void) ne_md5_init_ctx(&hash); -#ifdef NE_HAVE_SSL +#ifdef NEON_SSL if (RAND_status() == 1 && RAND_pseudo_bytes(data, sizeof data) >= 0) ne_md5_process_bytes(data, sizeof data, &hash); else { @@ -274,7 +260,7 @@ static char *get_cnonce(void) ne_md5_process_bytes(&pid, sizeof pid, &hash); } -#ifdef NE_HAVE_SSL +#ifdef NEON_SSL } #endif @@ -335,162 +321,69 @@ static char *request_basic(auth_session *sess) /* Add GSSAPI authentication credentials to a request */ static char *request_gssapi(auth_session *sess) { - if (sess->gssapi_token) - return ne_concat("Negotiate ", sess->gssapi_token, "\r\n", NULL); - else - return NULL; + return ne_concat("Negotiate ", sess->gssapi_token, "\r\n", NULL); } -/* Create an GSSAPI name for server HOSTNAME; returns non-zero on - * error. */ -static void get_gss_name(gss_name_t *server, const char *hostname) +static int get_gss_name(gss_name_t *server, auth_session *sess) { - unsigned int major, minor; + unsigned int major_status, minor_status; gss_buffer_desc token = GSS_C_EMPTY_BUFFER; - token.value = ne_concat("HTTP@", hostname, NULL); + token.value = ne_concat("HTTP@", sess->sess->server.hostname, NULL); token.length = strlen(token.value); - major = gss_import_name(&minor, &token, GSS_C_NT_HOSTBASED_SERVICE, - server); - ne_free(token.value); - - if (GSS_ERROR(major)) { - NE_DEBUG(NE_DBG_HTTPAUTH, "gssapi: gss_import_name failed.\n"); - *server = GSS_C_NO_NAME; - } + major_status = gss_import_name(&minor_status, &token, + GSS_C_NT_HOSTBASED_SERVICE, + server); + return GSS_ERROR(major_status) ? -1 : 0; } -/* Append GSSAPI error(s) for STATUS of type TYPE to BUF; prepending - * ": " to each error if *FLAG is non-zero, setting *FLAG after an - * error has been appended. */ -static void make_gss_error(ne_buffer *buf, int *flag, - unsigned int status, int type) +/* Examine a GSSAPI auth challenge; returns 0 if a valid challenge, + * else non-zero. */ +static int +gssapi_challenge(auth_session *sess, struct auth_challenge *parms) { - int major, minor; - int context = 0; - - do { - gss_buffer_desc msg; - major = gss_display_status(&minor, status, type, - GSS_C_NO_OID, &context, &msg); - if (major == GSS_S_COMPLETE && msg.length) { - if ((*flag)++) ne_buffer_append(buf, ": ", 2); - ne_buffer_append(buf, msg.value, msg.length); - } - if (msg.length) gss_release_buffer(&minor, &msg); - } while (context); -} + gss_ctx_id_t context; + gss_name_t server_name; + unsigned int major_status, minor_status; + gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; + gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; -/* Continue a GSS-API Negotiate exchange, using input TOKEN if - * non-NULL. Returns non-zero on error. */ -static int continue_negotiate(auth_session *sess, const char *token) -{ - unsigned int major, minor; - gss_buffer_desc input = GSS_C_EMPTY_BUFFER; - gss_buffer_desc output = GSS_C_EMPTY_BUFFER; - unsigned char *bintoken = NULL; - int ret; - gss_OID mech = sess->gssmech; - - if (token) { - input.length = ne_unbase64(token, &bintoken); - if (input.length == 0) { - NE_DEBUG(NE_DBG_HTTPAUTH, "gssapi: Invalid input [%s].\n", - token); - return -1; - } - input.value = bintoken; - NE_DEBUG(NE_DBG_HTTPAUTH, "gssapi: Continuation token [%s]\n", token); - } - else if (sess->gssctx != GSS_C_NO_CONTEXT) { - NE_DEBUG(NE_DBG_HTTPAUTH, "gssapi: Reset incomplete context.\n"); - gss_delete_sec_context(&minor, &sess->gssctx, GSS_C_NO_BUFFER); - } + clean_session(sess); - major = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL, &sess->gssctx, - sess->gssname, mech, - GSS_C_MUTUAL_FLAG, GSS_C_INDEFINITE, - GSS_C_NO_CHANNEL_BINDINGS, - &input, &sess->gssmech, &output, NULL, NULL); - - /* done with the input token. */ - if (bintoken) ne_free(bintoken); - - if (GSS_ERROR(major)) { - ne_buffer *err = ne_buffer_create(); - int flag = 0; - - make_gss_error(err, &flag, major, GSS_C_GSS_CODE); - make_gss_error(err, &flag, minor, GSS_C_MECH_CODE); - NE_DEBUG(NE_DBG_HTTPAUTH, "gssapi: Error: %s\n", err->data); - ne_set_error(sess->sess, _("GSSAPI authentication error (%s)"), - err->data); - ne_buffer_destroy(err); + if (get_gss_name(&server_name, sess)) return -1; - } - if (major == GSS_S_CONTINUE_NEEDED || major == GSS_S_COMPLETE) { - NE_DEBUG(NE_DBG_HTTPAUTH, "gssapi: init_sec_context OK. (major=%d)\n", - major); - ret = 0; - } - else { - NE_DEBUG(NE_DBG_HTTPAUTH, "gssapi: Init failure %d.\n", major); - ret = -1; - } - - if (major != GSS_S_CONTINUE_NEEDED) { - /* context no longer needed: destroy it */ - gss_delete_sec_context(&minor, &sess->gssctx, GSS_C_NO_BUFFER); - } - - if (output.length) { - sess->gssapi_token = ne_base64(output.value, output.length); - NE_DEBUG(NE_DBG_HTTPAUTH, "gssapi: Output token: [%s]\n", - sess->gssapi_token); - gss_release_buffer(&minor, &output); - } else { - NE_DEBUG(NE_DBG_HTTPAUTH, "gssapi: No output token.\n"); - } - - return ret; -} - -/* Process a Negotiate challange CHALL in session SESS; returns zero - * if challenge is accepted. */ -static int gssapi_challenge(auth_session *sess, struct auth_challenge *chall) -{ - int ret = continue_negotiate(sess, chall->opaque); - if (ret == 0) - sess->scheme = auth_scheme_gssapi; - return ret; -} - -/* Verify the header HDR in a Negotiate response. */ -static int verify_negotiate_response(auth_session *sess, char *hdr) -{ - char *sep, *ptr = strchr(hdr, ' '); - - if (strncmp(hdr, "Negotiate", ptr - hdr) != 0) { - NE_DEBUG(NE_DBG_HTTPAUTH, "gssapi: Not a Negotiate response!\n"); + major_status = gss_init_sec_context(&minor_status, + GSS_C_NO_CREDENTIAL, + &context, + server_name, + GSS_C_NO_OID, + 0, + GSS_C_INDEFINITE, + GSS_C_NO_CHANNEL_BINDINGS, + &input_token, + NULL, + &output_token, + NULL, + NULL); + gss_release_name(&minor_status, &server_name); + + if (GSS_ERROR(major_status)) { + NE_DEBUG(NE_DBG_HTTPAUTH, "gss_init_sec_context failed.\n"); return -1; } - ptr++; - - if (strlen(ptr) == 0) { - NE_DEBUG(NE_DBG_HTTPAUTH, "gssapi: No token in Negotiate response!\n"); - return 0; - } + if (output_token.length == 0) + return -1; - if ((sep = strchr(ptr, ',')) != NULL) - *sep = '\0'; - if ((sep = strchr(ptr, ' ')) != NULL) - *sep = '\0'; + sess->gssapi_token = ne_base64(output_token.value, output_token.length); + gss_release_buffer(&major_status, &output_token); - NE_DEBUG(NE_DBG_HTTPAUTH, "gssapi: Negotiate response token [%s]\n", ptr); - return continue_negotiate(sess, ptr); + NE_DEBUG(NE_DBG_HTTPAUTH, + "Base64 encoded GSSAPI challenge: %s.\n", sess->gssapi_token); + sess->scheme = auth_scheme_gssapi; + return 0; } #endif @@ -639,7 +532,7 @@ static char *request_digest(auth_session *sess, struct auth_request *req) * where-ever it is coming from, and calculate the digest. */ NE_DEBUG(NE_DBG_HTTPAUTH, "Digesting request body...\n"); - ne__pull_request_body(req->request, digest_body, &body); + ne_pull_request_body(req->request, digest_body, &body); NE_DEBUG(NE_DBG_HTTPAUTH, "Digesting request body done.\n"); ne_md5_finish_ctx(&body, tmp_md5); @@ -744,8 +637,7 @@ static int tokenize(char **hdr, char **key, char **value, int ischall) *pnt = '\0'; *value = pnt + 1; state = AFTER_EQ; - } else if ((*pnt == ' ' || *pnt == ',') - && ischall && *key != NULL) { + } else if (*pnt == ' ' && ischall && *key != NULL) { *value = NULL; *pnt = '\0'; *hdr = pnt + 1; @@ -787,8 +679,8 @@ static int tokenize(char **hdr, char **key, char **value, int ischall) * 0 if it gives a valid authentication for the server * non-zero otherwise (don't believe the response in this case!). */ -static int verify_digest_response(struct auth_request *req, auth_session *sess, - const char *value) +static int verify_response(struct auth_request *req, auth_session *sess, + const char *value) { char *hdr, *pnt, *key, *val; auth_qop qop = auth_qop_none; @@ -950,43 +842,40 @@ static int auth_challenge(auth_session *sess, const char *value) while (!tokenize(&pnt, &key, &val, 1)) { if (val == NULL) { - auth_scheme scheme; - + /* We have a new challenge */ + NE_DEBUG(NE_DBG_HTTPAUTH, "New challenge for scheme [%s]\n", key); + chall = ne_calloc(sizeof *chall); + + chall->next = challenges; + challenges = chall; + /* Initialize the challenge parameters */ + /* Which auth-scheme is it (case-insensitive matching) */ if (strcasecmp(key, "basic") == 0) { - scheme = auth_scheme_basic; + NE_DEBUG(NE_DBG_HTTPAUTH, "Basic scheme.\n"); + chall->scheme = auth_scheme_basic; } else if (strcasecmp(key, "digest") == 0) { - scheme = auth_scheme_digest; - } -#ifdef HAVE_GSSAPI - /* cope with a Negotiate parameter which doesn't match the - * auth-param due to the broken spec. */ - else if (chall && chall->scheme == auth_scheme_gssapi - && chall->opaque == NULL) { - chall->opaque = key; - continue; + NE_DEBUG(NE_DBG_HTTPAUTH, "Digest scheme.\n"); + chall->scheme = auth_scheme_digest; +#ifdef HAVE_GSSAPI } else if (strcasecmp(key, "negotiate") == 0) { - scheme = auth_scheme_gssapi; - } + NE_DEBUG(NE_DBG_HTTPAUTH, "GSSAPI scheme.\n"); + chall->scheme = auth_scheme_gssapi; #endif - else { - NE_DEBUG(NE_DBG_HTTPAUTH, "Ignoring challenge '%s'.\n", key); - chall = NULL; - continue; + } else { + NE_DEBUG(NE_DBG_HTTPAUTH, "Unknown scheme.\n"); + ne_free(chall); + challenges = NULL; + break; } - - NE_DEBUG(NE_DBG_HTTPAUTH, "New '%s' challenge.\n", key); - chall = ne_calloc(sizeof *chall); - chall->scheme = scheme; - chall->next = challenges; - challenges = chall; continue; } else if (chall == NULL) { - /* Ignore pairs for an unknown challenge. */ - NE_DEBUG(NE_DBG_HTTPAUTH, "Ignored pair: %s = %s\n", key, val); + /* If we haven't got an auth-scheme, and we're + * haven't yet found a challenge, skip this pair. + */ continue; } - /* Strip quotes off value. */ + /* Strip quotes of value. */ val = ne_shave(val, "\"'"); NE_DEBUG(NE_DBG_HTTPAUTH, "Got pair: [%s] = [%s]\n", key, val); @@ -1019,8 +908,6 @@ static int auth_challenge(auth_session *sess, const char *value) chall->qop_auth_int = 1; } } while (val); - - chall->got_qop = chall->qop_auth || chall->qop_auth_int; } } @@ -1035,17 +922,15 @@ static int auth_challenge(auth_session *sess, const char *value) success = 0; #ifdef HAVE_GSSAPI - /* Ignore Negotiate challenges from origin servers which don't - * come over SSL. */ - if (sess->spec == &ah_proxy_class || sess->context != AUTH_ANY) { + if (strcmp(ne_get_scheme(sess->sess), "https") == 0) { NE_DEBUG(NE_DBG_HTTPAUTH, "Looking for GSSAPI.\n"); /* Try a GSSAPI challenge */ for (chall = challenges; chall != NULL; chall = chall->next) { if (chall->scheme == auth_scheme_gssapi) { - if (!gssapi_challenge(sess, chall)) { - success = 1; - break; - } + if (!gssapi_challenge(sess, chall)) { + success = 1; + break; + } } } } @@ -1106,14 +991,6 @@ static void auth_body_reader(void *cookie, const char *block, size_t length) ne_md5_process_bytes(block, length, ctx); } -/* Collect auth challenges into an ne_buffer */ -static void ah_collect_header(void *userdata, const char *value) -{ - ne_buffer *ar = userdata; - if (ne_buffer_size(ar)) ne_buffer_append(ar, ", ", 2); - ne_buffer_zappend(ar, value); -} - static void ah_create(ne_request *req, void *session, const char *method, const char *uri) { @@ -1130,14 +1007,14 @@ static void ah_create(ne_request *req, void *session, const char *method, areq->method = method; areq->uri = uri; areq->request = req; - areq->auth_hdr = ne_buffer_create(); - areq->auth_info_hdr = ne_buffer_create(); ne_add_response_header_handler(req, sess->spec->resp_hdr, - ah_collect_header, areq->auth_hdr); + ne_duplicate_header, &areq->auth_hdr); + ne_add_response_header_handler(req, sess->spec->resp_info_hdr, - ah_collect_header, areq->auth_info_hdr); + ne_duplicate_header, + &areq->auth_info_hdr); sess->attempt = 0; @@ -1156,7 +1033,7 @@ static void ah_pre_send(ne_request *r, void *cookie, ne_buffer *request) } else { char *value; - NE_DEBUG(NE_DBG_HTTPAUTH, "Handling auth session.\n"); + NE_DEBUG(NE_DBG_HTTPAUTH, "Handling."); req->will_handle = 1; if (sess->qop == auth_qop_auth_int) { @@ -1203,44 +1080,22 @@ static int ah_post_send(ne_request *req, void *cookie, const ne_status *status) if (!areq) return NE_OK; -#ifdef HAVE_GSSAPI - /* whatever happens: forget the GSSAPI token cached thus far */ - if (sess->gssapi_token) { - ne_free(sess->gssapi_token); - sess->gssapi_token = NULL; - } -#endif - NE_DEBUG(NE_DBG_HTTPAUTH, "ah_post_send (#%d), code is %d (want %d), %s is %s\n", sess->attempt, status->code, sess->spec->status_code, - sess->spec->resp_hdr, areq->auth_hdr->data); - if (ne_buffer_size(areq->auth_info_hdr) - && sess->scheme == auth_scheme_digest) { - if (verify_digest_response(areq, sess, areq->auth_info_hdr->data)) { - NE_DEBUG(NE_DBG_HTTPAUTH, "Response authentication invalid.\n"); - ne_set_error(sess->sess, "%s", _(sess->spec->fail_msg)); - ret = NE_ERROR; - } - } -#ifdef HAVE_GSSAPI - /* one must wonder... has Mr Brezak actually read RFC2617? */ - else if (sess->scheme == auth_scheme_gssapi - && (status->klass == 2 || status->klass == 3) - && ne_buffer_size(areq->auth_hdr)) { - if (verify_negotiate_response(sess, areq->auth_hdr->data)) { - NE_DEBUG(NE_DBG_HTTPAUTH, "gssapi: Mutual auth failed.\n"); - ret = NE_ERROR; - } - } -#endif /* HAVE_GSSAPI */ - else if ((status->code == sess->spec->status_code || - (status->code == 401 && sess->context == AUTH_CONNECT)) && - ne_buffer_size(areq->auth_hdr)) { + sess->spec->resp_hdr, SAFELY(areq->auth_hdr)); + if (areq->auth_info_hdr != NULL && + verify_response(areq, sess, areq->auth_info_hdr)) { + NE_DEBUG(NE_DBG_HTTPAUTH, "Response authentication invalid.\n"); + ne_set_error(sess->sess, "%s", _(sess->spec->fail_msg)); + ret = NE_ERROR; + } else if ((status->code == sess->spec->status_code || + (status->code == 401 && sess->context == AUTH_CONNECT)) && + areq->auth_hdr != NULL) { /* note above: allow a 401 in response to a CONNECT request * from a proxy since some buggy proxies send that. */ - NE_DEBUG(NE_DBG_HTTPAUTH, "Got challenge (code %d).\n", status->code); - if (!auth_challenge(sess, areq->auth_hdr->data)) { + NE_DEBUG(NE_DBG_HTTPAUTH, "Got challenge with code %d.\n", status->code); + if (!auth_challenge(sess, areq->auth_hdr)) { ret = NE_RETRY; } else { clean_session(sess); @@ -1248,9 +1103,9 @@ static int ah_post_send(ne_request *req, void *cookie, const ne_status *status) } } - ne_buffer_clear(areq->auth_hdr); - ne_buffer_clear(areq->auth_info_hdr); - + NE_FREE(areq->auth_info_hdr); + NE_FREE(areq->auth_hdr); + return ret; } @@ -1258,25 +1113,13 @@ static void ah_destroy(ne_request *req, void *session) { auth_session *sess = session; struct auth_request *areq = ne_get_request_private(req, sess->spec->id); - - if (areq) { - ne_buffer_destroy(areq->auth_info_hdr); - ne_buffer_destroy(areq->auth_hdr); - ne_free(areq); - } + if (areq) ne_free(areq); } static void free_auth(void *cookie) { auth_session *sess = cookie; -#ifdef HAVE_GSSAPI - if (sess->gssname != GSS_C_NO_NAME) { - int major; - gss_release_name(&major, sess->gssname); - } -#endif - clean_session(sess); ne_free(sess); } @@ -1292,19 +1135,10 @@ static void auth_register(ne_session *sess, int isproxy, ahs->sess = sess; ahs->spec = ahc; - if (strcmp(ne_get_scheme(sess), "https") == 0) { + if (strcmp(ne_get_scheme(sess), "https") == 0) ahs->context = isproxy ? AUTH_CONNECT : AUTH_NOTCONNECT; -#ifdef HAVE_GSSAPI - { - get_gss_name(&ahs->gssname, (isproxy ? sess->proxy.hostname - : sess->server.hostname)); - ahs->gssctx = GSS_C_NO_CONTEXT; - ahs->gssmech = GSS_C_NO_OID; - } -#endif - } else { + else ahs->context = AUTH_ANY; - } /* Register hooks */ ne_hook_create_request(sess, ah_create, ahs); diff --git a/src/ne_basic.c b/src/ne_basic.c index 1462ad4..d3b4eb3 100644 --- a/src/ne_basic.c +++ b/src/ne_basic.c @@ -1,6 +1,6 @@ /* Basic HTTP and WebDAV methods - Copyright (C) 1999-2004, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 1999-2003, Joe Orton <joe@manyfish.co.uk> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -22,7 +22,6 @@ #include "config.h" #include <sys/types.h> -#include <sys/stat.h> /* for struct stat */ #ifdef HAVE_STRING_H #include <string.h> @@ -42,11 +41,13 @@ #include "ne_basic.h" #include "ne_207.h" -#ifdef NE_HAVE_DAV +#ifndef NEON_NODAV #include "ne_uri.h" -#include "ne_locks.h" #endif +#ifdef USE_DAV_LOCKS +#include "ne_locks.h" +#endif #include "ne_dates.h" #include "ne_i18n.h" @@ -81,27 +82,15 @@ int ne_getmodtime(ne_session *sess, const char *uri, time_t *modtime) /* PUT's from fd to URI */ int ne_put(ne_session *sess, const char *uri, int fd) { - ne_request *req; - struct stat st; + ne_request *req = ne_request_create(sess, "PUT", uri); int ret; - - if (fstat(fd, &st)) { - int errnum = errno; - char buf[200]; - - ne_set_error(sess, _("Could not determine file size: %s"), - ne_strerror(errnum, buf, sizeof buf)); - return NE_ERROR; - } - req = ne_request_create(sess, "PUT", uri); - -#ifdef NE_HAVE_DAV +#ifdef USE_DAV_LOCKS ne_lock_using_resource(req, uri, 0); ne_lock_using_parent(req, uri); #endif - ne_set_request_body_fd(req, fd, 0, st.st_size); + ne_set_request_body_fd(req, fd); ret = ne_request_dispatch(req); @@ -113,6 +102,59 @@ int ne_put(ne_session *sess, const char *uri, int fd) return ret; } +/* Conditional HTTP put. + * PUTs from fd to uri, returning NE_FAILED if resource as URI has + * been modified more recently than 'since'. + */ +int +ne_put_if_unmodified(ne_session *sess, const char *uri, int fd, + time_t since) +{ + ne_request *req; + char *date; + int ret; + + if (ne_version_pre_http11(sess)) { + time_t modtime; + /* Server is not minimally HTTP/1.1 compliant. Do a HEAD to + * check the remote mod time. Of course, this makes the + * operation very non-atomic, but better than nothing. */ + ret = ne_getmodtime(sess, uri, &modtime); + if (ret != NE_OK) return ret; + if (modtime != since) + return NE_FAILED; + } + + req = ne_request_create(sess, "PUT", uri); + + date = ne_rfc1123_date(since); + /* Add in the conditionals */ + ne_add_request_header(req, "If-Unmodified-Since", date); + ne_free(date); + +#ifdef USE_DAV_LOCKS + ne_lock_using_resource(req, uri, 0); + /* FIXME: this will give 412 if the resource doesn't exist, since + * PUT may modify the parent... does that matter? */ +#endif + + ne_set_request_body_fd(req, fd); + + ret = ne_request_dispatch(req); + + if (ret == NE_OK) { + if (ne_get_status(req)->code == 412) { + ret = NE_FAILED; + } else if (ne_get_status(req)->klass != 2) { + ret = NE_ERROR; + } + } + + ne_request_destroy(req); + + return ret; +} + struct get_context { int error; ne_session *session; @@ -354,14 +396,9 @@ void ne_content_type_handler(void *userdata, const char *value) /* set subtype, losing any trailing whitespace */ ct->subtype = ne_shave(stype, " \t"); - if (ct->charset == NULL && strcasecmp(ct->type, "text") == 0) { - /* 3280§3.1: text/xml without charset implies us-ascii. */ - if (strcasecmp(ct->subtype, "xml") == 0) - ct->charset = "us-ascii"; - /* 2616§3.7.1: subtypes of text/ default to charset ISO-8859-1. */ - else - ct->charset = "ISO-8859-1"; - } + /* 2616#3.7.1: subtypes of text/ default to charset ISO-8859-1. */ + if (ct->charset == NULL && strcasecmp(ct->type, "text") == 0) + ct->charset = "ISO-8859-1"; } static void dav_hdr_handler(void *userdata, const char *value) @@ -408,7 +445,7 @@ int ne_options(ne_session *sess, const char *uri, return ret; } -#ifdef NE_HAVE_DAV +#ifndef NEON_NODAV void ne_add_depth_header(ne_request *req, int depth) { @@ -437,7 +474,7 @@ static int copy_or_move(ne_session *sess, int is_move, int overwrite, ne_add_depth_header(req, depth); } -#ifdef NE_HAVE_DAV +#ifdef USE_DAV_LOCKS if (is_move) { ne_lock_using_resource(req, src, NE_DEPTH_INFINITE); } @@ -472,7 +509,7 @@ int ne_delete(ne_session *sess, const char *uri) { ne_request *req = ne_request_create(sess, "DELETE", uri); -#ifdef NE_HAVE_DAV +#ifdef USE_DAV_LOCKS ne_lock_using_resource(req, uri, NE_DEPTH_INFINITE); ne_lock_using_parent(req, uri); #endif @@ -502,7 +539,7 @@ int ne_mkcol(ne_session *sess, const char *uri) req = ne_request_create(sess, "MKCOL", real_uri); -#ifdef NE_HAVE_DAV +#ifdef USE_DAV_LOCKS ne_lock_using_resource(req, real_uri, 0); ne_lock_using_parent(req, real_uri); #endif @@ -514,4 +551,4 @@ int ne_mkcol(ne_session *sess, const char *uri) return ret; } -#endif /* NE_HAVE_DAV */ +#endif /* NEON_NODAV */ diff --git a/src/ne_basic.h b/src/ne_basic.h index f9b5157..1953fc2 100644 --- a/src/ne_basic.h +++ b/src/ne_basic.h @@ -36,10 +36,13 @@ int ne_get(ne_session *sess, const char *path, int fd); * body to submit from 'fd'. */ int ne_put(ne_session *sess, const char *path, int fd); +#ifndef NEON_NODAV + #define NE_DEPTH_ZERO (0) #define NE_DEPTH_ONE (1) #define NE_DEPTH_INFINITE (2) + /* For ne_copy and ne_move: * * If a resource exists at "dest" and overwrite is zero, the operation @@ -67,6 +70,17 @@ int ne_mkcol(ne_session *sess, const char *path); /* Adds a Depth: header to a request */ void ne_add_depth_header(ne_request *req, int depth); +#endif /* NEON_NODAV */ + +/* PUT resource at location as above, only if it has not been modified + * since given modtime. If server is HTTP/1.1, uses If-Unmodified-Since + * header; guaranteed failure if resource is modified after 'modtime'. + * If server is HTTP/1.0, HEAD's the resource first to fetch current + * modtime; race condition if resource is modified between HEAD and PUT. + */ +int ne_put_if_unmodified(ne_session *sess, + const char *path, int fd, time_t modtime); + /* Retrieve modification time of resource at location 'path', place in * *modtime. (uses HEAD) */ int ne_getmodtime(ne_session *sess, const char *path, time_t *modtime); diff --git a/src/ne_compress.c b/src/ne_compress.c index 3610d79..56db5a5 100644 --- a/src/ne_compress.c +++ b/src/ne_compress.c @@ -1,6 +1,6 @@ /* Handling of compressed HTTP responses - Copyright (C) 2001-2004, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 2001-2002, Joe Orton <joe@manyfish.co.uk> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -33,7 +33,7 @@ #include "ne_utils.h" #include "ne_i18n.h" -#ifdef NE_HAVE_ZLIB +#ifdef NEON_ZLIB #include <zlib.h> @@ -53,7 +53,6 @@ struct ne_decompress_s { /* pass blocks back to this. */ ne_block_reader reader; - ne_accept_response acceptor; void *userdata; /* buffer for gzip header bytes. */ @@ -160,8 +159,6 @@ static void process_footer(ne_decompress *ctx, uLong crc = BUF2UINT(ctx->footer) & 0xFFFFFFFF; if (crc == ctx->checksum) { ctx->state = NE_Z_FINISHED; - /* reader requires a size=0 call at end-of-response */ - ctx->reader(ctx->userdata, NULL, 0); NE_DEBUG(NE_DBG_HTTP, "compress: Checksum match.\n"); } else { NE_DEBUG(NE_DBG_HTTP, "compress: Checksum mismatch: " @@ -223,10 +220,9 @@ static void do_inflate(ne_decompress *ctx, const char *buf, size_t len) ctx->checksum = crc32(ctx->checksum, (unsigned char *)ctx->outbuf, ctx->zstr.total_out); - /* pass on the inflated data, if any */ - if (ctx->zstr.total_out > 0) { - ctx->reader(ctx->userdata, ctx->outbuf, ctx->zstr.total_out); - } + /* pass on the inflated data */ + ctx->reader(ctx->userdata, ctx->outbuf, ctx->zstr.total_out); + } while (ret == Z_OK && ctx->zstr.avail_in > 0); if (ret == Z_STREAM_END) { @@ -393,13 +389,6 @@ int ne_decompress_destroy(ne_decompress *ctx) return ret; } -/* Wrapper for user-passed acceptor function. */ -static int gz_acceptor(void *userdata, ne_request *req, const ne_status *st) -{ - ne_decompress *ctx = userdata; - return ctx->acceptor(ctx->userdata, req, st); -} - ne_decompress *ne_decompress_reader(ne_request *req, ne_accept_response acpt, ne_block_reader rdr, void *userdata) { @@ -410,7 +399,7 @@ ne_decompress *ne_decompress_reader(ne_request *req, ne_accept_response acpt, ne_add_response_header_handler(req, "Content-Encoding", ne_duplicate_header, &ctx->enchdr); - ne_add_response_body_reader(req, gz_acceptor, gz_reader, ctx); + ne_add_response_body_reader(req, acpt, gz_reader, ctx); ctx->state = NE_Z_BEFORE_DATA; ctx->reader = rdr; @@ -418,12 +407,11 @@ ne_decompress *ne_decompress_reader(ne_request *req, ne_accept_response acpt, ctx->session = ne_get_session(req); /* initialize the checksum. */ ctx->checksum = crc32(0L, Z_NULL, 0); - ctx->acceptor = acpt; return ctx; } -#else /* !NE_HAVE_ZLIB */ +#else /* !NEON_ZLIB */ /* Pass-through interface present to provide ABI compatibility. */ @@ -440,4 +428,4 @@ int ne_decompress_destroy(ne_decompress *dc) return 0; } -#endif /* NE_HAVE_ZLIB */ +#endif /* NEON_ZLIB */ diff --git a/src/ne_dates.c b/src/ne_dates.c index 1e4921a..27c3517 100644 --- a/src/ne_dates.c +++ b/src/ne_dates.c @@ -1,7 +1,6 @@ /* Date manipulation routines Copyright (C) 1999-2004, Joe Orton <joe@manyfish.co.uk> - Copyright (C) 2004 Jiang Lei <tristone@deluxe.ocn.ne.jp> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -36,7 +35,7 @@ #include "ne_alloc.h" #include "ne_dates.h" -#include "ne_string.h" +#include "ne_utils.h" /* Generic date manipulation routines. */ @@ -62,35 +61,11 @@ static const char *short_months[12] = { #if defined(HAVE_STRUCT_TM_TM_GMTOFF) #define GMTOFF(t) ((t).tm_gmtoff) -#elif defined(HAVE_STRUCT_TM___TM_GMTOFF) -#define GMTOFF(t) ((t).__tm_gmtoff) -#elif defined(WIN32) -#define GMTOFF(t) (gmt_to_local_win32()) #else /* FIXME: work out the offset anyway. */ #define GMTOFF(t) (0) #endif -#ifdef WIN32 -time_t gmt_to_local_win32(void) -{ - TIME_ZONE_INFORMATION tzinfo; - DWORD dwStandardDaylight; - long bias; - - dwStandardDaylight = GetTimeZoneInformation(&tzinfo); - bias = tzinfo.Bias; - - if (dwStandardDaylight == TIME_ZONE_ID_STANDARD) - bias += tzinfo.StandardBias; - - if (dwStandardDaylight == TIME_ZONE_ID_DAYLIGHT) - bias += tzinfo.DaylightBias; - - return (- bias * 60); -} -#endif - /* Returns the time/date GMT, in RFC1123-type format: eg * Sun, 06 Nov 1994 08:49:37 GMT. */ char *ne_rfc1123_date(time_t anytime) { diff --git a/src/ne_defs.h b/src/ne_defs.h index c2bbb22..4dacbda 100644 --- a/src/ne_defs.h +++ b/src/ne_defs.h @@ -1,6 +1,6 @@ /* Standard definitions for neon headers - Copyright (C) 2003-2004, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 2003, Joe Orton <joe@manyfish.co.uk> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -35,13 +35,7 @@ #endif #ifdef __GNUC__ -#if __GNUC__ >= 3 -#define ne_attribute_malloc __attribute__((malloc)) -#else -#define ne_attribute_malloc -#endif #define ne_attribute(x) __attribute__(x) #else #define ne_attribute(x) -#define ne_attribute_malloc #endif diff --git a/src/ne_locks.c b/src/ne_locks.c index 7fc25a4..8863bd4 100644 --- a/src/ne_locks.c +++ b/src/ne_locks.c @@ -725,7 +725,7 @@ int ne_lock(ne_session *sess, struct ne_lock *lock) ne_buffer_destroy(body); ne_buffer_destroy(ctx.cdata); - parse_failed = ne_xml_failed(parser); + parse_failed = !ne_xml_valid(parser); if (ret == NE_OK && ne_get_status(req)->klass == 2) { if (ctx.token == NULL) { @@ -780,13 +780,9 @@ int ne_lock_refresh(ne_session *sess, struct ne_lock *lock) ne_request *req = ne_request_create(sess, "LOCK", lock->uri.path); ne_xml_parser *parser = ne_xml_create(); int ret, parse_failed; - struct lock_ctx ctx; - - memset(&ctx, 0, sizeof ctx); - ctx.cdata = ne_buffer_create(); /* Handle the response and update *lock appropriately. */ - ne_xml_push_handler(parser, lk_startelm, lk_cdata, lk_endelm, &ctx); + ne_xml_push_handler(parser, lk_startelm, NULL, lk_endelm, lock); ne_add_response_body_reader(req, ne_accept_2xx, ne_xml_parse_v, parser); @@ -801,7 +797,7 @@ int ne_lock_refresh(ne_session *sess, struct ne_lock *lock) ret = ne_request_dispatch(req); - parse_failed = ne_xml_failed(parser); + parse_failed = !ne_xml_valid(parser); if (ret == NE_OK && ne_get_status(req)->klass == 2) { if (parse_failed) { @@ -816,7 +812,6 @@ int ne_lock_refresh(ne_session *sess, struct ne_lock *lock) ret = NE_ERROR; } - ne_buffer_destroy(ctx.cdata); ne_request_destroy(req); ne_xml_destroy(parser); diff --git a/src/ne_openssl.c b/src/ne_openssl.c index e88dc75..a19d3d4 100644 --- a/src/ne_openssl.c +++ b/src/ne_openssl.c @@ -323,7 +323,7 @@ static ne_ssl_certificate *make_chain(STACK_OF(X509) *chain) for (n = 0; n < count; n++) { ne_ssl_certificate *cert = ne_malloc(sizeof *cert); populate_cert(cert, X509_dup(sk_X509_value(chain, n))); -#ifdef NE_DEBUGGING +#if NE_DEBUGGING if (ne_debug_mask & NE_DBG_SSL) { fprintf(ne_debug_stream, "Cert #%d:\n", n); X509_print_fp(ne_debug_stream, cert->subject); @@ -502,7 +502,7 @@ void ne_ssl_context_destroy(ne_ssl_context *ctx) } /* For internal use only. */ -int ne__negotiate_ssl(ne_request *req) +int ne_negotiate_ssl(ne_request *req) { ne_session *sess = ne_get_session(req); ne_ssl_context *ctx = sess->ssl_context; diff --git a/src/ne_private.h b/src/ne_private.h index b5d9529..aad98f4 100644 --- a/src/ne_private.h +++ b/src/ne_private.h @@ -1,6 +1,6 @@ /* HTTP Request Handling - Copyright (C) 1999-2004, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 1999-2002, Joe Orton <joe@manyfish.co.uk> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -67,16 +67,14 @@ struct ne_session_s { char *scheme; struct host_info server, proxy; - /* application-provided address list */ - const ne_inet_addr **addrlist; - size_t numaddrs, curaddr; - /* Settings */ unsigned int use_proxy:1; /* do we have a proxy server? */ unsigned int no_persist:1; /* set to disable persistent connections */ unsigned int use_ssl:1; /* whether a secure connection is required */ unsigned int in_connect:1; /* doing a proxy CONNECT */ + int expect100_works; /* known state of 100-continue support */ + ne_progress progress_cb; void *progress_ud; @@ -90,7 +88,7 @@ struct ne_session_s { char *user_agent; /* full User-Agent: header field */ -#ifdef NE_HAVE_SSL +#ifdef NEON_SSL ne_ssl_client_cert *client_cert; ne_ssl_certificate *server_cert; ne_ssl_context *ssl_context; @@ -107,15 +105,14 @@ struct ne_session_s { char error[BUFSIZ]; }; -/* Pushes block of 'count' bytes at 'buf'. Returns non-zero on - * error. */ typedef int (*ne_push_fn)(void *userdata, const char *buf, size_t count); /* Pulls the request body for the given request, passing blocks to the - * given callback. */ -int ne__pull_request_body(ne_request *req, ne_push_fn fn, void *ud); + * given callback. + */ +int ne_pull_request_body(ne_request *req, ne_push_fn fn, void *ud); /* Do the SSL negotiation. */ -int ne__negotiate_ssl(ne_request *req); +int ne_negotiate_ssl(ne_request *req); #endif /* HTTP_PRIVATE_H */ diff --git a/src/ne_privssl.h b/src/ne_privssl.h index ea3a840..1f63759 100644 --- a/src/ne_privssl.h +++ b/src/ne_privssl.h @@ -27,7 +27,7 @@ /* This is the private interface between ne_socket and ne_openssl. */ -#ifdef NE_HAVE_SSL +#ifdef NEON_SSL #include <openssl/ssl.h> @@ -43,6 +43,6 @@ struct ne_ssl_socket_s { SSL *ssl; }; -#endif /* NE_HAVE_SSL */ +#endif /* NEON_SSL */ #endif diff --git a/src/ne_props.c b/src/ne_props.c index 5a680ad..057085e 100644 --- a/src/ne_props.c +++ b/src/ne_props.c @@ -141,7 +141,7 @@ static int propfind(ne_propfind_handler *handler, if (ret == NE_OK && ne_get_status(req)->klass != 2) { ret = NE_ERROR; - } else if (ne_xml_failed(handler->parser)) { + } else if (!ne_xml_valid(handler->parser)) { ne_set_error(handler->sess, "%s", ne_xml_get_error(handler->parser)); ret = NE_ERROR; } @@ -220,7 +220,7 @@ int ne_proppatch(ne_session *sess, const char *uri, ne_set_request_body_buffer(req, body->data, ne_buffer_size(body)); ne_add_request_header(req, "Content-Type", NE_XML_MEDIA_TYPE); -#ifdef NE_HAVE_DAV +#ifdef USE_DAV_LOCKS ne_lock_using_resource(req, uri, NE_DEPTH_ZERO); #endif diff --git a/src/ne_request.c b/src/ne_request.c index 4469168..f3a64b2 100644 --- a/src/ne_request.c +++ b/src/ne_request.c @@ -1,6 +1,6 @@ /* HTTP request/response handling - Copyright (C) 1999-2004, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 1999-2003, Joe Orton <joe@manyfish.co.uk> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -26,6 +26,10 @@ #include "config.h" #include <sys/types.h> +#include <sys/stat.h> +#ifdef __EMX__ +#include <sys/select.h> +#endif #ifdef HAVE_LIMITS_H #include <limits.h> /* for UINT_MAX etc */ @@ -86,33 +90,6 @@ struct body_reader { struct body_reader *next; }; -#ifdef NE_LFS -#define ne_lseek lseek64 -typedef off64_t ne_off_t; -#define FMT_NE_OFF_T NE_FMT_OFF64_T -#if defined(LONG_LONG_MAX) && !defined(LLONG_MAX) -#define LLONG_MAX LONG_LONG_MAX -#endif -#define NE_OFFT_MAX LLONG_MAX -#ifdef HAVE_STRTOLL -#define ne_strtoff strtoll -#else -#define ne_strtoff strtoq -#endif -#else /* !NE_LFS */ -typedef off_t ne_off_t; -#define ne_lseek lseek -#define FMT_NE_OFF_T NE_FMT_OFF_T -#define NE_OFFT_MAX LONG_MAX -#if SIZEOF_OFF_T > SIZEOF_LONG && defined(HAVE_STRTOLL) -#define ne_strtoff strtoll -#elif SIZEOF_OFF_T > SIZEOF_LONG && defined(HAVE_STRTOQ) -#define ne_strtoff strtoq -#else -#define ne_strtoff strtol -#endif -#endif /* NE_LFS */ - struct ne_request_s { char *method, *uri; /* method and Request-URI */ @@ -122,23 +99,16 @@ struct ne_request_s { ne_provide_body body_cb; void *body_ud; - /* Request body source: file or buffer (if not callback). */ + /* Comes from either an fd or a buffer. */ union { - struct { - int fd; - ne_off_t offset, length; - ne_off_t remain; /* remaining bytes to send. */ - } file; + int fd; struct { - /* length bytes @ buffer = whole body. - * remain bytes @ pnt = remaining bytes to send */ const char *buffer, *pnt; - size_t length, remain; + size_t left; } buf; } body; - ne_off_t body_length; /* length of request body */ - ne_off_t body_progress; /* number of bytes of body sent so far */ + size_t body_size, body_progress; /* temporary store for response lines. */ char respbuf[BUFSIZ]; @@ -147,25 +117,17 @@ struct ne_request_s { /* The transfer encoding types */ struct ne_response { + int length; /* Response entity-body content-length */ + size_t left; /* Bytes left to read */ + size_t chunk_left; /* Bytes of chunk left to read */ + size_t total; /* total bytes read so far. */ + /* how the message length is detemined: */ enum { R_TILLEOF = 0, /* read till eof */ R_NO_BODY, /* implicitly no body (HEAD, 204, 205, 304) */ R_CHUNKED, /* using chunked transfer-encoding */ R_CLENGTH /* using given content-length */ } mode; - union { - /* clen: used if mode == R_CLENGTH; total and bytes - * remaining to be read of response body. */ - struct { - ne_off_t total, remain; - } clen; - /* chunk: used if mode == R_CHUNKED; total and bytes - * remaining to be read of current chunk */ - struct { - size_t total, remain; - } chunk; - } body; - ne_off_t progress; /* number of bytes read of response */ } resp; /* List of callbacks which are passed response headers */ @@ -369,16 +331,16 @@ static ssize_t body_string_send(void *userdata, char *buffer, size_t count) ne_request *req = userdata; if (count == 0) { - req->body.buf.remain = req->body.buf.length; + req->body.buf.left = req->body_size; req->body.buf.pnt = req->body.buf.buffer; } else { /* if body_left == 0 we fall through and return 0. */ - if (req->body.buf.remain < count) - count = req->body.buf.remain; + if (req->body.buf.left < count) + count = req->body.buf.left; memcpy(buffer, req->body.buf.pnt, count); req->body.buf.pnt += count; - req->body.buf.remain -= count; + req->body.buf.left -= count; } return count; @@ -389,26 +351,16 @@ static ssize_t body_fd_send(void *userdata, char *buffer, size_t count) ne_request *req = userdata; if (count) { - if (req->body.file.remain == 0) - return 0; - if ((off_t)count > req->body.file.remain) - count = req->body.file.remain; - return read(req->body.file.fd, buffer, count); + return read(req->body.fd, buffer, count); } else { - /* rewind for next send. */ - if (ne_lseek(req->body.file.fd, req->body.file.offset, SEEK_SET) - == req->body.file.offset) { - req->body.file.remain = req->body.file.length; - return 0; - } else { - return -1; - } + /* rewind since we may have to send it again */ + return lseek(req->body.fd, SEEK_SET, 0); } } /* Pulls the request body from the source and pushes it to the given * callback. Returns 0 on success, or NE_* code */ -int ne__pull_request_body(ne_request *req, ne_push_fn fn, void *ud) +int ne_pull_request_body(ne_request *req, ne_push_fn fn, void *ud) { int ret = 0; char buffer[BUFSIZ]; @@ -448,7 +400,7 @@ static int send_with_progress(void *userdata, const char *data, size_t n) if (ret == 0) { req->body_progress += n; req->session->progress_cb(req->session->progress_ud, - req->body_progress, req->body_length); + req->body_progress, req->body_size); } return ret; @@ -463,10 +415,10 @@ static int send_request_body(ne_request *req) if (req->session->progress_cb) { /* with progress callbacks. */ req->body_progress = 0; - ret = ne__pull_request_body(req, send_with_progress, req); + ret = ne_pull_request_body(req, send_with_progress, req); } else { /* without progress callbacks. */ - ret = ne__pull_request_body(req, (ne_push_fn)ne_sock_fullwrite, + ret = ne_pull_request_body(req, (ne_push_fn)ne_sock_fullwrite, req->session->socket); } @@ -486,8 +438,7 @@ static void add_fixed_headers(ne_request *req) * harder to get a persistent connection, except if using a proxy * as per 2068 sec 19.7.1. Always add TE: trailers since those * are understood. */ - if (!req->session->no_persist && !req->session->is_http11 - && !req->session->use_proxy) { + if (!req->session->is_http11 && !req->session->use_proxy) { ne_buffer_zappend(req->headers, "Keep-Alive: " EOL "Connection: TE, Keep-Alive" EOL @@ -517,8 +468,7 @@ static void te_hdr_handler(void *userdata, const char *value) { struct ne_response *resp = userdata; - resp->mode = R_CHUNKED; - resp->body.chunk.remain = 0; + resp->mode = R_CHUNKED; } /* Handler for the "Connection" response header */ @@ -535,10 +485,10 @@ static void connection_hdr_handler(void *userdata, const char *value) static void clength_hdr_handler(void *userdata, const char *value) { struct ne_response *resp = userdata; - ne_off_t len = ne_strtoff(value, NULL, 10); - if (len != NE_OFFT_MAX && len >= 0 && resp->mode == R_TILLEOF) { + size_t len = strtoul(value, NULL, 10); + if (len != ULONG_MAX && resp->mode == R_TILLEOF) { resp->mode = R_CLENGTH; - resp->body.clen.total = resp->body.clen.remain = len; + resp->length = len; } } @@ -591,66 +541,47 @@ ne_request *ne_request_create(ne_session *sess, return req; } -/* Set the request body length to 'length' */ -static void set_body_length(ne_request *req, ne_off_t length) +static void set_body_size(ne_request *req, size_t size) { - req->body_length = length; - ne_print_request_header(req, "Content-Length", "%" FMT_NE_OFF_T, length); + req->body_size = size; + ne_print_request_header(req, "Content-Length", "%" NE_FMT_SIZE_T, size); } void ne_set_request_body_buffer(ne_request *req, const char *buffer, size_t size) { req->body.buf.buffer = buffer; - req->body.buf.length = size; req->body_cb = body_string_send; req->body_ud = req; - set_body_length(req, size); + set_body_size(req, size); } -void ne_set_request_body_provider(ne_request *req, off_t bodysize, +void ne_set_request_body_provider(ne_request *req, size_t bodysize, ne_provide_body provider, void *ud) { req->body_cb = provider; req->body_ud = ud; - set_body_length(req, bodysize); + set_body_size(req, bodysize); } -void ne_set_request_body_fd(ne_request *req, int fd, - off_t offset, off_t length) +int ne_set_request_body_fd(ne_request *req, int fd) { - req->body.file.fd = fd; - req->body.file.offset = offset; - req->body.file.length = length; - req->body_cb = body_fd_send; - req->body_ud = req; - set_body_length(req, length); -} - -#ifdef NE_LFS -void ne_set_request_body_fd64(ne_request *req, int fd, - off64_t offset, off64_t length) -{ - req->body.file.fd = fd; - req->body.file.offset = offset; - req->body.file.length = length; + struct stat bodyst; + + /* Get file length */ + if (fstat(fd, &bodyst) < 0) { + char err[200]; + ne_strerror(errno, err, sizeof err); + ne_set_error(req->session, _("Could not determine file length: %s"), + err); + NE_DEBUG(NE_DBG_HTTP, "Stat failed: %s\n", err); + return -1; + } + req->body.fd = fd; req->body_cb = body_fd_send; req->body_ud = req; - set_body_length(req, length); -} - -void ne_set_request_body_provider64(ne_request *req, off64_t bodysize, - ne_provide_body provider, void *ud) -{ - req->body_cb = provider; - req->body_ud = ud; - set_body_length(req, bodysize); -} -#endif - -void ne_set_request_expect100(ne_request *req, int flag) -{ - req->use_expect100 = flag; + set_body_size(req, bodyst.st_size); + return 0; } void ne_add_request_header(ne_request *req, const char *name, @@ -774,10 +705,10 @@ static int read_response_block(ne_request *req, struct ne_response *resp, * ended by a `CHUNK CRLF 0 CRLF', a 0-sized chunk. * The slight complication is that we have to cope with * partial reads of chunks. - * For this reason, resp.chunk.remain contains the number of + * For this reason, resp.chunk_left contains the number of * bytes left to read in the current chunk. */ - if (resp->body.chunk.remain == 0) { + if (resp->chunk_left == 0) { unsigned long int chunk_len; char *ptr; /* We are at the start of a new chunk. */ @@ -799,12 +730,12 @@ static int read_response_block(ne_request *req, struct ne_response *resp, *buflen = 0; return NE_OK; } - resp->body.chunk.remain = chunk_len; + resp->chunk_left = chunk_len; } - willread = resp->body.chunk.remain > *buflen ? *buflen : resp->body.chunk.remain; + willread = resp->chunk_left; break; case R_CLENGTH: - willread = resp->body.clen.remain > (off_t)*buflen ? *buflen : (size_t)resp->body.clen.remain; + willread = resp->left; break; case R_TILLEOF: willread = *buflen; @@ -814,7 +745,8 @@ static int read_response_block(ne_request *req, struct ne_response *resp, willread = 0; break; } - if (willread == 0) { + if (willread > *buflen) willread = *buflen; + else if (willread == 0) { *buflen = 0; return 0; } @@ -841,8 +773,8 @@ static int read_response_block(ne_request *req, struct ne_response *resp, "Read block (%" NE_FMT_SSIZE_T " bytes):\n[%.*s]\n", readlen, (int)readlen, buffer); if (resp->mode == R_CHUNKED) { - resp->body.chunk.remain -= readlen; - if (resp->body.chunk.remain == 0) { + resp->chunk_left -= readlen; + if (resp->chunk_left == 0) { char crlfbuf[2]; /* If we've read a whole chunk, read a CRLF */ readlen = ne_sock_fullread(sock, crlfbuf, 2); @@ -853,9 +785,8 @@ static int read_response_block(ne_request *req, struct ne_response *resp, return aborted(req, _("Chunk delimiter was invalid"), 0); } } else if (resp->mode == R_CLENGTH) { - resp->body.clen.remain -= readlen; + resp->left -= readlen; } - resp->progress += readlen; return NE_OK; } @@ -863,14 +794,15 @@ ssize_t ne_read_response_block(ne_request *req, char *buffer, size_t buflen) { struct body_reader *rdr; size_t readlen = buflen; - struct ne_response *const resp = &req->resp; - if (read_response_block(req, resp, buffer, &readlen)) + if (read_response_block(req, &req->resp, buffer, &readlen)) return -1; + req->resp.total += readlen; + if (req->session->progress_cb) { - req->session->progress_cb(req->session->progress_ud, resp->progress, - resp->mode==R_CLENGTH ? resp->body.clen.total:-1); + req->session->progress_cb(req->session->progress_ud, req->resp.total, + (req->resp.mode==R_CLENGTH)?req->resp.length:-1); } /* TODO: call the readers when this fails too. */ @@ -1028,7 +960,7 @@ static int send_request(ne_request *req, const ne_buffer *request) return RETRY_RET(retry, ret, aret); } - if (!req->use_expect100 && req->body_length > 0) { + if (!req->use_expect100 && req->body_size > 0) { /* Send request body, if not using 100-continue. */ ret = send_request_body(req); if (ret < 0) { @@ -1048,8 +980,7 @@ static int send_request(ne_request *req, const ne_buffer *request) /* Discard headers with the interim response. */ if ((ret = discard_headers(req)) != NE_OK) break; - if (req->use_expect100 && (status->code == 100) - && req->body_length > 0 && !sentbody) { + if (req->use_expect100 && (status->code == 100) && !sentbody) { /* Send the body after receiving the first 100 Continue */ if ((ret = send_request_body(req)) != NE_OK) break; sentbody = 1; @@ -1185,12 +1116,8 @@ static int read_response_headers(ne_request *req) return ret; } -/* Perform any necessary DNS lookup for the host given by *info; - * return NE_ code. */ static int lookup_host(ne_session *sess, struct host_info *info) { - if (sess->addrlist) return NE_OK; - NE_DEBUG(NE_DBG_HTTP, "Doing DNS lookup on %s...\n", info->hostname); if (sess->notify_cb) sess->notify_cb(sess->notify_ud, ne_conn_namelookup, info->hostname); @@ -1223,6 +1150,10 @@ int ne_begin_request(ne_request *req) req->resp.mode = R_TILLEOF; + /* FIXME: Determine whether to use the Expect: 100-continue header. */ + req->use_expect100 = (req->session->expect100_works > -1) && + (req->body_size > HTTP_EXPECT_MINSIZE) && req->session->is_http11; + /* Build the request string, and send it */ data = build_request(req); DEBUG_DUMP_REQUEST(data->data); @@ -1247,7 +1178,7 @@ int ne_begin_request(ne_request *req) /* Read the headers */ HTTP_ERR(read_response_headers(req)); -#ifdef NE_HAVE_SSL +#ifdef NEON_SSL /* Special case for CONNECT handling: the response has no body, * and the connection can persist. */ if (req->session->in_connect && st->klass == 2) { @@ -1268,6 +1199,9 @@ int ne_begin_request(ne_request *req) rdr->use = rdr->accept_response(rdr->userdata, req, st); } + req->resp.left = req->resp.length; + req->resp.chunk_left = 0; + return NE_OK; } @@ -1339,7 +1273,7 @@ ne_session *ne_get_session(const ne_request *req) return req->session; } -#ifdef NE_HAVE_SSL +#ifdef NEON_SSL /* Create a CONNECT tunnel through the proxy server. * Returns HTTP_* */ static int proxy_tunnel(ne_session *sess) @@ -1371,37 +1305,13 @@ static int proxy_tunnel(ne_session *sess) } #endif -/* Return the first resolved address for the given host. */ -static const ne_inet_addr *resolve_first(ne_session *sess, - struct host_info *host) -{ - if (sess->addrlist) { - sess->curaddr = 0; - return sess->addrlist[0]; - } else { - return ne_addr_first(host->address); - } -} - -/* Return the next resolved address for the given host or NULL if - * there are no more addresses. */ -static const ne_inet_addr *resolve_next(ne_session *sess, - struct host_info *host) -{ - if (sess->addrlist) { - if (sess->curaddr++ < sess->numaddrs) - return sess->addrlist[sess->curaddr]; - else - return NULL; - } else { - return ne_addr_next(host->address); - } -} - /* Make new TCP connection to server at 'host' of type 'name'. Note * that once a connection to a particular network address has * succeeded, that address will be used first for the next attempt to * connect. */ +/* TODO: an alternate implementation could always cycle through the + * addresses: this could ease server load, but could hurt SSL session + * caching for SSL sessions, which would increase server load. */ static int do_connect(ne_request *req, struct host_info *host, const char *err) { ne_session *const sess = req->session; @@ -1413,7 +1323,7 @@ static int do_connect(ne_request *req, struct host_info *host, const char *err) } if (host->current == NULL) - host->current = resolve_first(sess, host); + host->current = ne_addr_first(host->address); do { notify_status(sess, ne_conn_connecting, host->hostport); @@ -1426,7 +1336,7 @@ static int do_connect(ne_request *req, struct host_info *host, const char *err) #endif ret = ne_sock_connect(sess->socket, host->current, host->port); } while (ret && /* try the next address... */ - (host->current = resolve_next(sess, host)) != NULL); + (host->current = ne_addr_next(host->address)) != NULL); if (ret) { ne_set_error(sess, "%s: %s", err, ne_sock_error(sess->socket)); @@ -1434,7 +1344,7 @@ static int do_connect(ne_request *req, struct host_info *host, const char *err) return NE_CONNECT; } - notify_status(sess, ne_conn_connected, host->hostport); + notify_status(sess, ne_conn_connected, sess->proxy.hostport); if (sess->rdtimeout) ne_sock_read_timeout(sess->socket, sess->rdtimeout); @@ -1460,7 +1370,7 @@ static int open_connection(ne_request *req) if (ret != NE_OK) return ret; -#ifdef NE_HAVE_SSL +#ifdef NEON_SSL /* Negotiate SSL layer if required. */ if (sess->use_ssl && !sess->in_connect) { /* CONNECT tunnel */ @@ -1468,7 +1378,7 @@ static int open_connection(ne_request *req) ret = proxy_tunnel(sess); if (ret == NE_OK) - ret = ne__negotiate_ssl(req); + ret = ne_negotiate_ssl(req); /* This is probably only really needed for ne_negotiate_ssl * failures as proxy_tunnel will fail via aborted(). */ diff --git a/src/ne_request.h b/src/ne_request.h index 9378b46..e59b59d 100644 --- a/src/ne_request.h +++ b/src/ne_request.h @@ -1,6 +1,6 @@ /* HTTP Request Handling - Copyright (C) 1999-2004, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 1999-2002, Joe Orton <joe@manyfish.co.uk> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -53,21 +53,17 @@ typedef struct ne_request_s ne_request; ne_request *ne_request_create(ne_session *sess, const char *method, const char *path); -/* The request body will be taken from 'size' bytes of 'buffer'. */ +/* 'buffer' will be sent as the request body with given request. */ void ne_set_request_body_buffer(ne_request *req, const char *buffer, size_t size); -/* The request body will be taken from 'length' bytes read from the - * file descriptor 'fd', starting from file offset 'offset'. */ -void ne_set_request_body_fd(ne_request *req, int fd, - off_t offset, off_t length); - -#ifdef NE_LFS -/* Alternate version of ne_set_request_body_fd taking off64_t - * offset type for systems supporting _LARGEFILE64_SOURCE. */ -void ne_set_request_body_fd64(ne_request *req, int fd, - off64_t offset, off64_t length); -#endif +/* Send the contents of a file as the request body; 'fd' must be a + * file descriptor of an open, seekable file. Current file offset of + * fd is not retained (and ignored: the file is read from the the + * first byte). Returns: + * 0 on okay. + * non-zero if could not determine length of file. */ +int ne_set_request_body_fd(ne_request *req, int fd); /* "Pull"-based request body provider: a callback which is invoked to * provide blocks of request body on demand. @@ -83,20 +79,13 @@ void ne_set_request_body_fd64(ne_request *req, int fd, typedef ssize_t (*ne_provide_body)(void *userdata, char *buffer, size_t buflen); -/* Install a callback which is invoked as needed to provide the - * request body, a block at a time. The total size of the request - * body is 'length'; the callback must ensure that it returns no more - * than 'length' bytes in total. */ -void ne_set_request_body_provider(ne_request *req, off_t length, +/* Install a callback which is invoked as needed to provide request + * body blocks. Total request body is 'size' bytes: the callback MUST + * ensure it returns in total exactly 'size' bytes each time the + * request body is provided. */ +void ne_set_request_body_provider(ne_request *req, size_t size, ne_provide_body provider, void *userdata); -#ifdef NE_LFS -/* Duplicate version of ne_set_request_body_provider, taking an off64_t - * offset. */ -void ne_set_request_body_provider64(ne_request *req, off64_t length, - ne_provide_body provider, void *userdata); -#endif - /* Handling response bodies... you provide TWO callbacks: * * 1) 'acceptance' callback: determines whether you want to handle the @@ -224,12 +213,6 @@ int ne_end_request(ne_request *req); */ ssize_t ne_read_response_block(ne_request *req, char *buffer, size_t buflen); -/* Include the HTTP/1.1 header "Expect: 100-continue" in request 'req' - * if 'flag' is non-zero. Warning: 100-continue support is not - * implemented correctly in some HTTP/1.1 servers, enabling this - * feature may cause requests to hang or time out. */ -void ne_set_request_expect100(ne_request *req, int flag); - /**** Request hooks handling *****/ typedef void (*ne_free_hooks)(void *cookie); @@ -278,3 +261,4 @@ void *ne_get_request_private(ne_request *req, const char *id); END_NEON_DECLS #endif /* NE_REQUEST_H */ + diff --git a/src/ne_session.c b/src/ne_session.c index 49f1634..04b777e 100644 --- a/src/ne_session.c +++ b/src/ne_session.c @@ -1,6 +1,6 @@ /* HTTP session handling - Copyright (C) 1999-2004, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 1999-2003, Joe Orton <joe@manyfish.co.uk> Portions are: Copyright (C) 1999-2000 Tommi Komulainen <Tommi.Komulainen@iki.fi> @@ -33,10 +33,6 @@ #include <errno.h> #endif -#ifdef NE_HAVE_IDNA -#include <idna.h> -#endif - #include "ne_session.h" #include "ne_alloc.h" #include "ne_utils.h" @@ -88,7 +84,7 @@ void ne_session_destroy(ne_session *sess) ne_close_connection(sess); } -#ifdef NE_HAVE_SSL +#ifdef NEON_SSL if (sess->ssl_context) ne_ssl_context_destroy(sess->ssl_context); @@ -122,14 +118,6 @@ static void set_hostport(struct host_info *host, unsigned int defaultport) static void set_hostinfo(struct host_info *info, const char *hostname, unsigned int port) { -#ifdef NE_HAVE_IDNA - char *ihost; - -#define FLAGS IDNA_USE_STD3_ASCII_RULES - if (idna_to_ascii_8z(hostname, &ihost, FLAGS) == IDNA_SUCCESS) - info->hostname = ihost; - else /* fall back to use provided hostname string */ -#endif info->hostname = ne_strdup(hostname); info->port = port; } @@ -151,7 +139,7 @@ ne_session *ne_session_create(const char *scheme, set_hostinfo(&sess->server, hostname, port); set_hostport(&sess->server, sess->use_ssl?443:80); -#ifdef NE_HAVE_SSL +#ifdef NEON_SSL if (sess->use_ssl) { sess->ssl_context = ne_ssl_context_create(); } @@ -159,6 +147,8 @@ ne_session *ne_session_create(const char *scheme, sess->scheme = ne_strdup(scheme); + /* Default expect-100 to OFF. */ + sess->expect100_works = -1; return sess; } @@ -170,12 +160,6 @@ void ne_session_proxy(ne_session *sess, const char *hostname, set_hostinfo(&sess->proxy, hostname, port); } -void ne_set_addrlist(ne_session *sess, const ne_inet_addr **addrs, size_t n) -{ - sess->addrlist = addrs; - sess->numaddrs = n; -} - void ne_set_error(ne_session *sess, const char *format, ...) { va_list params; @@ -200,6 +184,15 @@ void ne_set_status(ne_session *sess, sess->notify_ud = userdata; } +void ne_set_expect100(ne_session *sess, int use_expect100) +{ + if (use_expect100) { + sess->expect100_works = 1; + } else { + sess->expect100_works = -1; + } +} + void ne_set_persist(ne_session *sess, int persist) { sess->no_persist = !persist; @@ -275,7 +268,7 @@ void ne_ssl_provide_clicert(ne_session *sess, void ne_ssl_trust_cert(ne_session *sess, const ne_ssl_certificate *cert) { -#ifdef NE_HAVE_SSL +#ifdef NEON_SSL ne_ssl_ctx_trustcert(sess->ssl_context, cert); #endif } diff --git a/src/ne_session.h b/src/ne_session.h index 5e84635..69e8647 100644 --- a/src/ne_session.h +++ b/src/ne_session.h @@ -1,6 +1,6 @@ /* HTTP session handling - Copyright (C) 1999-2004, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 1999-2003, Joe Orton <joe@manyfish.co.uk> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -27,7 +27,6 @@ #include "ne_ssl.h" #include "ne_uri.h" /* for ne_uri */ #include "ne_defs.h" -#include "ne_socket.h" BEGIN_NEON_DECLS @@ -35,9 +34,7 @@ typedef struct ne_session_s ne_session; /* Create a session to the given server, using the given scheme. If * "https" is passed as the scheme, SSL will be used to connect to the - * server. If neon is built with support for IDNA, 'hostname' can be - * a UTF-8-encoded Unicode string; otherwise, it must be an ASCII - * string. */ + * server. */ ne_session *ne_session_create(const char *scheme, const char *hostname, unsigned int port); @@ -52,13 +49,18 @@ void ne_close_connection(ne_session *sess); void ne_session_proxy(ne_session *sess, const char *hostname, unsigned int port); -/* Disable use of persistent connection if 'flag' is non-zero, else - * enable (the default). */ -void ne_set_persist(ne_session *sess, int flag); - -/* Bypass the normal name resolution; force the use of specific set of - * addresses for this session, addrs[0]...addrs[n-1]. */ -void ne_set_addrlist(ne_session *sess, const ne_inet_addr **addrs, size_t n); +/* Set protocol options for session: + * expect100: Defaults to OFF + * persist: Defaults to ON + * + * expect100: When set, send the "Expect: 100-continue" request header + * with requests with bodies. + * + * persist: When set, use a persistent connection. (Generally, + * you don't want to turn this off.) + * */ +void ne_set_expect100(ne_session *sess, int use_expect100); +void ne_set_persist(ne_session *sess, int persist); /* Progress callback. */ typedef void (*ne_progress)(void *userdata, off_t progress, off_t total); diff --git a/src/ne_socket.c b/src/ne_socket.c index 803cf4b..1bcf257 100644 --- a/src/ne_socket.c +++ b/src/ne_socket.c @@ -29,6 +29,10 @@ #ifdef __hpux /* pick up hstrerror */ #define _XOPEN_SOURCE_EXTENDED 1 +/* don't use the broken getaddrinfo shipped in HP-UX 11.11 */ +#ifdef USE_GETADDRINFO +#undef USE_GETADDRINFO +#endif #endif #include <sys/types.h> @@ -36,16 +40,13 @@ #include <sys/time.h> #endif #include <sys/stat.h> +#ifdef HAVE_SYS_SELECT_H +#include <sys/select.h> +#endif #ifdef HAVE_SYS_SOCKET_H #include <sys/socket.h> #endif -#ifdef NE_USE_POLL -#include <sys/poll.h> -#elif defined(HAVE_SYS_SELECT_H) -#include <sys/select.h> -#endif - #ifdef HAVE_NETINET_IN_H #include <netinet/in.h> #endif @@ -64,7 +65,7 @@ #include <stddef.h> #endif -#if defined(NE_HAVE_SSL) && defined(HAVE_LIMITS_H) +#if defined(NEON_SSL) && defined(HAVE_LIMITS_H) #include <limits.h> /* for INT_MAX */ #endif #ifdef HAVE_STRING_H @@ -90,12 +91,11 @@ #include <socks.h> #endif -#ifdef NE_HAVE_SSL +#ifdef NEON_SSL #include <openssl/ssl.h> #include <openssl/err.h> #include <openssl/pkcs12.h> /* for PKCS12_PBE_add */ #include <openssl/rand.h> -#include <openssl/opensslv.h> /* for OPENSSL_VERSION_NUMBER */ #include "ne_privssl.h" #endif @@ -129,12 +129,18 @@ typedef struct in_addr ne_inet_addr; #if defined(__BEOS__) && !defined(BONE_VERSION) /* pre-BONE */ +#define ne_write(a,b,c) send(a,b,c,0) +#define ne_read(a,b,c) recv(a,b,c,0) #define ne_close(s) closesocket(s) #define ne_errno errno #elif defined(WIN32) +#define ne_write(a,b,c) send(a,b,c,0) +#define ne_read(a,b,c) recv(a,b,c,0) #define ne_close(s) closesocket(s) #define ne_errno WSAGetLastError() #else /* really Unix! */ +#define ne_write(a,b,c) write(a,b,c) +#define ne_read(a,b,c) read(a,b,c) #define ne_close(s) close(s) #define ne_errno errno #endif @@ -173,7 +179,7 @@ struct ne_socket_s { void *progress_ud; int rdtimeout; /* read timeout. */ const struct iofns *ops; -#ifdef NE_HAVE_SSL +#ifdef NEON_SSL ne_ssl_socket ssl; #endif /* The read buffer: ->buffer stores byte which have been read; as @@ -217,7 +223,7 @@ static void print_error(int errnum, char *buffer, size_t buflen) #define set_strerror(s, e) ne_strerror((e), (s)->error, sizeof (s)->error) #endif -#ifdef NE_HAVE_SSL +#ifdef NEON_SSL /* Initialize SSL library. */ static void init_ssl(void) @@ -254,7 +260,7 @@ static int seed_ssl_prng(void) NE_DEBUG(NE_DBG_SOCKET, "No entropy source found; could not seed PRNG.\n"); return -1; } -#endif /* NE_HAVE_SSL */ +#endif /* NEON_SSL */ #ifdef USE_CHECK_IPV6 static int ipv6_disabled = 0; @@ -301,7 +307,7 @@ int ne_sock_init(void) #endif -#ifdef NE_HAVE_SOCKS +#ifdef NEON_SOCKS SOCKSinit("neon"); #endif @@ -313,7 +319,7 @@ int ne_sock_init(void) init_ipv6(); #endif -#ifdef NE_HAVE_SSL +#ifdef NEON_SSL init_ssl(); #endif @@ -339,6 +345,9 @@ int ne_sock_block(ne_socket *sock, int n) /* Cast address object AD to type 'sockaddr_TY' */ #define SACAST(ty, ad) ((struct sockaddr_##ty *)(ad)) +#define SOCK_ERR(x) do { ssize_t _sock_err = (x); \ +if (_sock_err < 0) return _sock_err; } while(0) + ssize_t ne_sock_read(ne_socket *sock, char *buffer, size_t buflen) { ssize_t bytes; @@ -402,20 +411,7 @@ ssize_t ne_sock_peek(ne_socket *sock, char *buffer, size_t buflen) /* Await data on raw fd in socket. */ static int readable_raw(ne_socket *sock, int secs) { - int ret; -#ifdef NE_USE_POLL - struct pollfd fds; - int timeout = secs > 0 ? secs * 1000 : -1; - - fds.fd = sock->fd; - fds.events = POLLIN; - fds.revents = 0; - - do { - ret = poll(&fds, 1, timeout); - } while (ret < 0 && NE_ISINTR(ne_errno)); -#else - int fdno = sock->fd; + int fdno = sock->fd, ret; fd_set rdfds; struct timeval timeout, *tvp = (secs >= 0 ? &timeout : NULL); @@ -429,8 +425,6 @@ static int readable_raw(ne_socket *sock, int secs) } ret = select(fdno + 1, &rdfds, NULL, NULL, tvp); } while (ret < 0 && NE_ISINTR(ne_errno)); -#endif - if (ret < 0) { set_strerror(sock, ne_errno); return NE_SOCK_ERROR; @@ -446,7 +440,7 @@ static ssize_t read_raw(ne_socket *sock, char *buffer, size_t len) if (ret) return ret; do { - ret = recv(sock->fd, buffer, len, 0); + ret = ne_read(sock->fd, buffer, len); } while (ret == -1 && NE_ISINTR(ne_errno)); if (ret == 0) { @@ -469,7 +463,7 @@ static ssize_t write_raw(ne_socket *sock, const char *data, size_t length) ssize_t wrote; do { - wrote = send(sock->fd, data, length, 0); + wrote = ne_write(sock->fd, data, length); if (wrote > 0) { data += wrote; length -= wrote; @@ -487,7 +481,7 @@ static ssize_t write_raw(ne_socket *sock, const char *data, size_t length) static const struct iofns iofns_raw = { read_raw, write_raw, readable_raw }; -#ifdef NE_HAVE_SSL +#ifdef NEON_SSL /* OpenSSL I/O function implementations. */ static int readable_ossl(ne_socket *sock, int secs) { @@ -506,7 +500,6 @@ static int readable_ossl(ne_socket *sock, int secs) static int error_ossl(ne_socket *sock, int sret) { int err = SSL_get_error(sock->ssl.ssl, sret), ret = NE_SOCK_ERROR; - const char *str; switch (err) { case SSL_ERROR_ZERO_RETURN: @@ -527,15 +520,13 @@ static int error_ossl(ne_socket *sock, int sret) ret = MAP_ERR(err); } } else { - str = ERR_reason_error_string(err); - ne_snprintf(sock->error, sizeof sock->error, _("SSL error: %s"), - str ? str : _("unknown error code")); + ne_snprintf(sock->error, sizeof sock->error, + _("SSL error: %s"), ERR_reason_error_string(err)); } break; default: - str = ERR_reason_error_string(ERR_get_error()); ne_snprintf(sock->error, sizeof sock->error, _("SSL error: %s"), - str ? str : _("unknown error code")); + ERR_reason_error_string(ERR_get_error())); break; } return ret; @@ -577,7 +568,7 @@ static const struct iofns iofns_ossl = { readable_ossl }; -#endif /* NE_HAVE_SSL */ +#endif /* NEON_SSL */ int ne_sock_fullwrite(ne_socket *sock, const char *data, size_t len) { @@ -863,14 +854,6 @@ int ne_sock_connect(ne_socket *sock, return -1; } -#ifndef NE_USE_POLL - if (fd > FD_SETSIZE) { - close(fd); - set_error(sock, _("Socket descriptor number exceeds FD_SETSIZE")); - return NE_SOCK_ERROR; - } -#endif - #if defined(TCP_NODELAY) && defined(HAVE_SETSOCKOPT) && defined(IPPROTO_TCP) { /* Disable the Nagle algorithm; better to add write buffering * instead of doing this. */ @@ -925,15 +908,6 @@ ne_inet_addr *ne_iaddr_make(ne_iaddr_type type, const unsigned char *raw) return ia; } -ne_iaddr_type ne_iaddr_typeof(const ne_inet_addr *ia) -{ -#ifdef USE_GETADDRINFO - return ia->ai_family == AF_INET6 ? ne_iaddr_ipv6 : ne_iaddr_ipv4; -#else - return ne_iaddr_ipv4; -#endif -} - int ne_iaddr_cmp(const ne_inet_addr *i1, const ne_inet_addr *i2) { #ifdef USE_GETADDRINFO @@ -985,7 +959,7 @@ void ne_sock_read_timeout(ne_socket *sock, int timeout) sock->rdtimeout = timeout; } -#ifdef NE_HAVE_SSL +#ifdef NEON_SSL void ne_sock_switch_ssl(ne_socket *sock, void *ssl) { @@ -1003,13 +977,6 @@ int ne_sock_connect_ssl(ne_socket *sock, ne_ssl_context *ctx) return NE_SOCK_ERROR; } - /* If runtime library version differs from compile-time version - * number in major/minor/fix level, abort soon. */ - if ((SSLeay() ^ OPENSSL_VERSION_NUMBER) & 0xFFFFF000) { - set_error(sock, _("SSL disabled due to library version mismatch")); - return NE_SOCK_ERROR; - } - sock->ssl.ssl = ssl = SSL_new(ctx->ctx); if (!ssl) { set_error(sock, _("Could not create SSL structure")); @@ -1051,7 +1018,7 @@ const char *ne_sock_error(const ne_socket *sock) int ne_sock_close(ne_socket *sock) { int ret; -#ifdef NE_HAVE_SSL +#ifdef NEON_SSL if (sock->ssl.ssl) { SSL_shutdown(sock->ssl.ssl); SSL_free(sock->ssl.ssl); diff --git a/src/ne_socket.h b/src/ne_socket.h index a684e6a..4da0c0c 100644 --- a/src/ne_socket.h +++ b/src/ne_socket.h @@ -1,6 +1,6 @@ /* socket handling interface - Copyright (C) 1999-2004, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 1999-2003, Joe Orton <joe@manyfish.co.uk> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -36,7 +36,7 @@ BEGIN_NEON_DECLS #define NE_SOCK_CLOSED (-3) /* Connection was reset (e.g. server crashed) */ #define NE_SOCK_RESET (-4) -/* Secure connection was closed without proper SSL shutdown. */ +/* Secure connection was subject to possible truncation attack. */ #define NE_SOCK_TRUNC (-5) /* ne_socket represents a TCP socket. */ @@ -57,7 +57,7 @@ int ne_sock_init(void); /* Shutdown any underlying libraries. */ void ne_sock_exit(void); -/* Resolve the given hostname. 'flags' must be zero. Hex +/* Resolve the given hostname. 'flags' are currently ignored. Hex * string IPv6 addresses (e.g. `::1') may be enclosed in brackets * (e.g. `[::1]'). */ ne_sock_addr *ne_addr_resolve(const char *hostname, int flags); @@ -102,9 +102,6 @@ ne_inet_addr *ne_iaddr_make(ne_iaddr_type type, const unsigned char *raw); * are not equal. */ int ne_iaddr_cmp(const ne_inet_addr *i1, const ne_inet_addr *i2); -/* Returns the type of the given network address. */ -ne_iaddr_type ne_iaddr_typeof(const ne_inet_addr *ia); - /* Prints the string representation of network address 'ia' into the * 'buffer', which is of size 'bufsiz'. Returns 'buffer'. */ char *ne_iaddr_print(const ne_inet_addr *ia, char *buffer, size_t bufsiz); diff --git a/src/ne_string.c b/src/ne_string.c index 31e3612..3cddad9 100644 --- a/src/ne_string.c +++ b/src/ne_string.c @@ -1,6 +1,6 @@ /* String utility functions - Copyright (C) 1999-2004, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 1999-2003, Joe Orton <joe@manyfish.co.uk> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -31,8 +31,6 @@ #include <unistd.h> #endif -#include <stdio.h> - #include <ctype.h> /* for isprint() etc in ne_strclean() */ #include "ne_alloc.h" @@ -103,6 +101,172 @@ char *ne_shave(char *str, const char *whitespace) return ret; } +/* TODO: deprecate all these and use ne_token() instead. */ + +char **split_string(const char *str, const char separator, + const char *quotes, const char *whitespace) +{ + return split_string_c(str, separator, quotes, whitespace, NULL); +} + +char **split_string_c(const char *str, const char separator, + const char *quotes, const char *whitespace, + int *give_count) +{ + char **comps; + const char *pnt, *quot = NULL, + *start, *end; /* The start of the current component */ + int count, /* The number of components */ + iswhite, /* is it whitespace */ + issep, /* is it the separator */ + curr, /* current component index */ + length, /* length of component */ + leading_wspace; /* in leading whitespace still? */ + + /* Inefficient, but easier - first off, count the number of + * components we have. */ + count = 1; + for (pnt = str; *pnt!='\0'; pnt++) { + if (quotes != NULL) { + quot = strchr(quotes, *pnt); + } + if (quot != NULL) { + /* We found a quote, so skip till the next quote */ + for (pnt++; (*pnt!=*quot) && (*pnt!='\0'); pnt++) + /* nullop */; + } else if (*pnt == separator) { + count++; + } + } + + if (give_count) { + /* Write the count */ + *give_count = count; + } + + /* Now, have got the number of components. + * Allocate the comps array. +1 for the NULL */ + comps = ne_malloc(sizeof(char *) * (count + 1)); + + comps[count] = NULL; + + quot = end = start = NULL; + curr = 0; + leading_wspace = 1; + + /* Now fill in the array */ + for (pnt = str; *pnt != '\0'; pnt++) { + /* What is the current character - quote, whitespace, separator? */ + if (quotes != NULL) { + quot = strchr(quotes, *pnt); + } + iswhite = (whitespace!=NULL) && + (strchr(whitespace, *pnt) != NULL); + issep = (*pnt == separator); + /* What to do? */ + if (leading_wspace) { + if (quot!=NULL) { + /* Quoted bit */ + start = pnt; + length = 1; + leading_wspace = 0; + } else if (issep) { + /* Zero-length component */ + comps[curr++] = ne_strdup(""); + } else if (!iswhite) { + start = end = pnt; + length = 1; + leading_wspace = 0; + } + } else { + if (quot!=NULL) { + /* Quoted bit */ + length++; + } else if (issep) { + /* End of component - enter it into the array */ + length = (end - start) + 1; + comps[curr] = ne_malloc(length+1); + memcpy(comps[curr], start, length); + comps[curr][length] = '\0'; + curr++; + leading_wspace = 1; + } else if (!iswhite) { + /* Not whitespace - update end marker */ + end = pnt; + } + } + if (quot != NULL) { + /* Skip to closing quote */ + for (pnt++; *pnt!=*quot && *pnt != '\0'; ++pnt) + /* nullop */; + /* Last non-wspace char is closing quote */ + end = pnt; + } + } + /* Handle final component */ + if (leading_wspace) { + comps[curr] = ne_strdup(""); + } else { + /* End of component - enter it into the array */ + length = (end - start) + 1; + comps[curr] = ne_malloc(length+1); + memcpy(comps[curr], start, length); + comps[curr][length] = '\0'; + } + return comps; +} + +char **pair_string(const char *str, const char compsep, const char kvsep, + const char *quotes, const char *whitespace) +{ + char **comps, **pairs, *split; + int count = 0, n, length; + comps = split_string_c(str, compsep, quotes, whitespace, &count); + /* Allocate space for 2* as many components as split_string returned, + * +2 for the NULLS. */ + pairs = ne_malloc((2*count+2) * sizeof(char *)); + if (pairs == NULL) { + return NULL; + } + for (n = 0; n < count; n++) { + /* Find the split */ + split = strchr(comps[n], kvsep); + if (split == NULL) { + /* No seperator found */ + length = strlen(comps[n]); + } else { + length = split-comps[n]; + } + /* Enter the key into the array */ + pairs[2*n] = comps[n]; + /* Null-terminate the key */ + pairs[2*n][length] = '\0'; + pairs[2*n+1] = split?(split + 1):NULL; + } + ne_free(comps); + pairs[2*count] = pairs[2*count+1] = NULL; + return pairs; +} + +void split_string_free(char **components) +{ + char **pnt = components; + while (*pnt != NULL) { + ne_free(*pnt); + pnt++; + } + ne_free(components); +} + +void pair_string_free(char **pairs) +{ + int n; + for (n = 0; pairs[n] != NULL; n+=2) { + ne_free(pairs[n]); + } + ne_free(pairs); +} + void ne_buffer_clear(ne_buffer *buf) { memset(buf->data, 0, buf->length); @@ -353,31 +517,3 @@ char *ne_strerror(int errnum, char *buf, size_t buflen) #endif return buf; } - - -/* Wrapper for ne_snprintf. */ -size_t ne_snprintf(char *str, size_t size, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); -#ifdef HAVE_TRIO - trio_vsnprintf(str, size, fmt, ap); -#else - vsnprintf(str, size, fmt, ap); -#endif - va_end(ap); - str[size-1] = '\0'; - return strlen(str); -} - -/* Wrapper for ne_vsnprintf. */ -size_t ne_vsnprintf(char *str, size_t size, const char *fmt, va_list ap) -{ -#ifdef HAVE_TRIO - trio_vsnprintf(str, size, fmt, ap); -#else - vsnprintf(str, size, fmt, ap); -#endif - str[size-1] = '\0'; - return strlen(str); -} diff --git a/src/ne_string.h b/src/ne_string.h index 9412c90..81ede09 100644 --- a/src/ne_string.h +++ b/src/ne_string.h @@ -1,6 +1,6 @@ /* String utility functions - Copyright (C) 1999-2002, 2004, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 1999-2002, Joe Orton <joe@manyfish.co.uk> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -57,6 +57,17 @@ char *ne_base64(const unsigned char *text, size_t len); * or zero on decode error (in which case *out is undefined). */ size_t ne_unbase64(const char *data, unsigned char **out); +/*** OBSOLETE INTERFACES ***/ +char **split_string(const char *str, const char seperator, + const char *quotes, const char *whitespace); +char **split_string_c(const char *str, const char seperator, + const char *quotes, const char *whitespace, int *count); +char **pair_string(const char *str, const char compsep, const char kvsep, + const char *quotes, const char *whitespace); +void split_string_free(char **components); +void pair_string_free(char **pairs); +/*** END OF OBSOLETE INTERFACES */ + /* String buffer handling. (Strings are zero-terminated still). A * string buffer ne_buffer * which grows dynamically with the * string. */ @@ -121,15 +132,6 @@ char *ne_concat(const char *str, ...); #define NE_ASC2HEX(x) (((x) <= '9') ? ((x) - '0') : (tolower((x)) + 10 - 'a')) #define NE_HEX2ASC(x) ((char) ((x) > 9 ? ((x) - 10 + 'a') : ((x) + '0'))) -/* Wrapper for snprintf: always NUL-terminates returned buffer, and - * returns strlen(str). */ -size_t ne_snprintf(char *str, size_t size, const char *fmt, ...) - ne_attribute((format(printf, 3, 4))); - -/* Wrapper for vsnprintf. */ -size_t ne_vsnprintf(char *str, size_t size, const char *fmt, va_list ap) - ne_attribute((format(printf, 3, 0))); - END_NEON_DECLS #endif /* NE_STRING_H */ diff --git a/src/ne_uri.c b/src/ne_uri.c index 0aab20d..51107d1 100644 --- a/src/ne_uri.c +++ b/src/ne_uri.c @@ -34,10 +34,9 @@ #include <stdlib.h> #endif -#include <stdio.h> - #include <ctype.h> +#include "ne_utils.h" /* for 'min' */ #include "ne_string.h" /* for ne_buffer */ #include "ne_alloc.h" #include "ne_uri.h" @@ -278,11 +277,6 @@ int ne_uri_cmp(const ne_uri *u1, const ne_uri *u2) #undef CMP #undef CASECMP -#ifndef WIN32 -#undef min -#define min(a,b) ((a)<(b)?(a):(b)) -#endif - /* TODO: implement properly */ int ne_path_compare(const char *a, const char *b) { diff --git a/src/ne_utils.c b/src/ne_utils.c index 1df2414..76929b0 100644 --- a/src/ne_utils.c +++ b/src/ne_utils.c @@ -30,11 +30,7 @@ #include <stdio.h> #include <ctype.h> /* isdigit() for ne_parse_statusline */ -#ifdef NE_HAVE_ZLIB -#include <zlib.h> -#endif - -#ifdef NE_HAVE_SSL +#ifdef NEON_SSL #include <openssl/opensslv.h> #endif @@ -45,6 +41,10 @@ #include <expat.h> #endif +#ifdef NEON_ZLIB +#include <zlib.h> +#endif + #include "ne_utils.h" #include "ne_string.h" /* for ne_strdup */ #include "ne_dates.h" @@ -78,15 +78,12 @@ void ne_debug(int ch, const char *template, ...) #define NE_STRINGIFY(x) # x #define NE_EXPAT_VER(x,y,z) NE_STRINGIFY(x) "." NE_STRINGIFY(y) "." NE_STRINGIFY(z) -static const char version_string[] = "neon " NEON_VERSION ": " +static const char *version_string = "neon " NEON_VERSION ": " #ifdef NEON_IS_LIBRARY "Library build" #else "Bundled build" #endif -#ifdef NE_HAVE_IPV6 - ", IPv6" -#endif #ifdef HAVE_EXPAT ", Expat" /* expat >=1.95.2 exported the version */ @@ -98,16 +95,13 @@ static const char version_string[] = "neon " NEON_VERSION ": " ", libxml " LIBXML_DOTTED_VERSION #endif /* HAVE_LIBXML */ #endif /* !HAVE_EXPAT */ -#if defined(NE_HAVE_ZLIB) && defined(ZLIB_VERSION) +#if defined(NEON_ZLIB) && defined(ZLIB_VERSION) ", zlib " ZLIB_VERSION -#endif /* NE_HAVE_ZLIB && ... */ -#ifdef NE_HAVE_SOCKS +#endif /* NEON_ZLIB && ... */ +#ifdef NEON_SOCKS ", SOCKSv5" #endif -#ifdef NE_HAVE_IDNA - ", IDNA" -#endif -#ifdef NE_HAVE_SSL +#ifdef NEON_SSL #ifdef OPENSSL_VERSION_TEXT ", " OPENSSL_VERSION_TEXT #else @@ -127,31 +121,13 @@ int ne_version_match(int major, int minor) return (NEON_VERSION_MAJOR != major) || (NEON_VERSION_MINOR < minor); } -int ne_has_support(int feature) +int ne_supports_ssl(void) { - switch (feature) { -#ifdef NE_HAVE_SSL - case NE_FEATURE_SSL: -#endif -#ifdef NE_HAVE_ZLIB - case NE_FEATURE_ZLIB: -#endif -#ifdef NE_HAVE_IPV6 - case NE_FEATURE_IPV6: -#endif -#ifdef NE_HAVE_IDNA - case NE_FEATURE_IDNA: -#endif -#ifdef NE_HAVE_SOCKS - case NE_FEATURE_SOCKS: -#endif -#ifdef NE_HAVE_LFS - case NE_FEATURE_LFS: +#ifdef NEON_SSL + return 1; +#else + return 0; #endif - return 1; - default: - return 0; - } } int ne_parse_statusline(const char *status_line, ne_status *st) diff --git a/src/ne_utils.h b/src/ne_utils.h index df07c2f..87e6593 100644 --- a/src/ne_utils.h +++ b/src/ne_utils.h @@ -1,6 +1,6 @@ /* HTTP utility functions - Copyright (C) 1999-2004, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 1999-2002, Joe Orton <joe@manyfish.co.uk> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -46,16 +46,22 @@ const char *ne_version_string(void); * 'minor'. */ int ne_version_match(int major, int minor); -#define NE_FEATURE_SSL (1) /* SSL/TLS support */ -#define NE_FEATURE_ZLIB (2) /* zlib compression in compress interface */ -#define NE_FEATURE_IPV6 (3) /* IPv6 is supported in resolver */ -#define NE_FEATURE_IDNA (4) /* internationalized domain name support */ -#define NE_FEATURE_LFS (5) /* large file support */ -#define NE_FEATURE_SOCKS (6) /* SOCKSv5 support */ +/* Returns non-zero if neon has support for SSL. */ +int ne_supports_ssl(void); -/* Returns non-zero if neon has support for given feature code - * NE_FEATURE_*. */ -int ne_has_support(int feature); +/* Use replacement snprintf's if trio is being used. */ +#ifdef NEON_TRIO +#define ne_snprintf trio_snprintf +#define ne_vsnprintf trio_vsnprintf +#else +#define ne_snprintf snprintf +#define ne_vsnprintf vsnprintf +#endif + +#ifndef WIN32 +#undef min +#define min(a,b) ((a)<(b)?(a):(b)) +#endif /* CONSIDER: mutt has a nicer way of way of doing debugging output... maybe * switch to like that. */ diff --git a/src/ne_xml.c b/src/ne_xml.c index 8a3a9da..d405fa2 100644 --- a/src/ne_xml.c +++ b/src/ne_xml.c @@ -1,5 +1,5 @@ /* - Wrapper interface to XML parser + Higher Level Interface to XML Parsers. Copyright (C) 1999-2004, Joe Orton <joe@manyfish.co.uk> This library is free software; you can redistribute it and/or @@ -96,11 +96,9 @@ struct ne_xml_parser_s { struct element *current; /* current element in the branch */ struct handler *top_handlers; /* always points at the * handler on top of the stack. */ - int failure; /* zero whilst parse should continue */ + int valid; /* non-zero whilst parse should continue */ int prune; /* if non-zero, depth within a dead branch */ - int bom_pos; - #ifdef HAVE_EXPAT XML_Parser parser; char *encoding; @@ -195,16 +193,6 @@ const char *ne_xml_doc_encoding(const ne_xml_parser *p) #endif } -/* The first character of the REC-xml-names "NCName" rule excludes - * "Digit | '.' | '-' | '_' | CombiningChar | Extender"; the XML - * parser will not enforce this rule in a namespace declaration since - * it treats the entire attribute name as a REC-xml "Name" rule. It's - * too hard to check for all of CombiningChar | Digit | Extender here, - * but the valid_ncname_ch1 macro catches some of the rest. */ - -/* Return non-zero if 'ch' is an invalid start character for an NCName: */ -#define invalid_ncname_ch1(ch) ((ch) == '\0' || strchr("-.0123456789", (ch)) != NULL) - /* Extract the namespace prefix declarations from 'atts'. */ static int declare_nspaces(ne_xml_parser *p, struct element *elm, const ne_xml_char **atts) @@ -218,13 +206,7 @@ static int declare_nspaces(ne_xml_parser *p, struct element *elm, } else if (strncasecmp(atts[n], "xmlns:", 6) == 0) { struct namespace *ns; - /* Reject some invalid NCNames as namespace prefix, and an - * empty URI as the namespace URI */ - if (invalid_ncname_ch1(atts[n][6]) || atts[n+1][0] == '\0' -#if 0 /* SVN has widely-deployed names using ':' so avoid breaking these */ - || strchr(atts[n] + 6, ':') != NULL -#endif - ) { + if (atts[n][6] == '\0' || atts[n+1][0] == '\0') { ne_snprintf(p->error, ERR_SIZE, ("XML parse error at line %d: invalid namespace " "declaration"), ne_xml_currentline(p)); @@ -261,21 +243,22 @@ static int expand_qname(ne_xml_parser *p, struct element *elm, elm->name = ne_strdup(qname); elm->nspace = e->default_ns; - } else if (invalid_ncname_ch1(pfx[1]) || qname == pfx || - strchr(pfx+1, ':') != NULL) { - ne_snprintf(p->error, ERR_SIZE, - _("XML parse error at line %d: invalid element name"), - ne_xml_currentline(p)); - return -1; } else { const char *uri = resolve_nspace(elm, qname, pfx-qname); if (uri) { + /* The name is everything after the ':' */ + if (pfx[1] == '\0') { + ne_snprintf(p->error, ERR_SIZE, + ("XML parse error at line %d: element name missing" + "after namespace prefix"), ne_xml_currentline(p)); + return -1; + } elm->name = ne_strdup(pfx+1); elm->nspace = uri; } else { ne_snprintf(p->error, ERR_SIZE, - ("XML parse error at line %d: undeclared namespace prefix"), + ("XML parse error at line %d: undeclared namespace"), ne_xml_currentline(p)); return -1; } @@ -292,7 +275,7 @@ static void start_element(void *userdata, const ne_xml_char *name, struct handler *hand; int state = NE_XML_DECLINE; - if (p->failure) return; + if (!p->valid) return; if (p->prune) { p->prune++; @@ -305,7 +288,7 @@ static void start_element(void *userdata, const ne_xml_char *name, p->current = elm; if (declare_nspaces(p, elm, atts) || expand_qname(p, elm, name)) { - p->failure = 1; + p->valid = 0; return; } @@ -325,8 +308,8 @@ static void start_element(void *userdata, const ne_xml_char *name, else if (state == NE_XML_DECLINE) /* prune this branch. */ p->prune++; - else /* state < 0 => abort parse */ - p->failure = state; + else /* state == NE_XML_ABORT */ + p->valid = 0; } /* Destroys an element structure. */ @@ -354,11 +337,12 @@ static void char_data(void *userdata, const ne_xml_char *data, int len) ne_xml_parser *p = userdata; struct element *elm = p->current; - if (p->failure || p->prune) return; + if (!p->valid || p->prune) return; - if (elm->handler->cdata_cb) { - p->failure = elm->handler->cdata_cb(elm->handler->userdata, elm->state, data, len); - NE_DEBUG(NE_DBG_XML, "Cdata callback returned %d.\n", p->failure); + if (elm->handler->cdata_cb && + elm->handler->cdata_cb(elm->handler->userdata, elm->state, data, len)) { + NE_DEBUG(NE_DBG_XML, "Cdata callback failed.\n"); + p->valid = 0; } } @@ -368,17 +352,15 @@ static void end_element(void *userdata, const ne_xml_char *name) ne_xml_parser *p = userdata; struct element *elm = p->current; - if (p->failure) return; + if (!p->valid) return; if (p->prune) { if (p->prune-- > 1) return; - } else if (elm->handler->endelm_cb) { - p->failure = elm->handler->endelm_cb(elm->handler->userdata, elm->state, - elm->nspace, elm->name); - if (p->failure) { - NE_DEBUG(NE_DBG_XML, "XML: end-element for %d failed with %d.\n", - elm->state, p->failure); - } + } else if (elm->handler->endelm_cb && + elm->handler->endelm_cb(elm->handler->userdata, elm->state, + elm->nspace, elm->name)) { + NE_DEBUG(NE_DBG_XML, "XML: end-element for %d failed.\n", elm->state); + p->valid = 0; } NE_DEBUG(NE_DBG_XMLPARSE, "XML: end-element (%d, {%s, %s})\n", @@ -415,6 +397,8 @@ static const char *resolve_nspace(const struct element *elm, ne_xml_parser *ne_xml_create(void) { ne_xml_parser *p = ne_calloc(sizeof *p); + /* Initialize other stuff */ + p->valid = 1; /* Placeholder for the root element */ p->current = p->root = ne_calloc(sizeof *p->root); p->root->default_ns = ""; @@ -473,14 +457,12 @@ void ne_xml_parse_v(void *userdata, const char *block, size_t len) ne_xml_parse(p, block, len); } -#define BOM_UTF8 "\xEF\xBB\xBF" /* UTF-8 BOM */ - /* Parse the given block of input of length len */ void ne_xml_parse(ne_xml_parser *p, const char *block, size_t len) { int ret, flag; /* duck out if it's broken */ - if (p->failure) { + if (!p->valid) { NE_DEBUG(NE_DBG_XML, "Not parsing %" NE_FMT_SIZE_T " bytes.\n", len); return; @@ -494,54 +476,34 @@ void ne_xml_parse(ne_xml_parser *p, const char *block, size_t len) len); flag = 0; } - - if (p->bom_pos < 3) { - while (len > 0 && p->bom_pos < 3 && - block[0] == BOM_UTF8[p->bom_pos]) { - block++; - len--; - p->bom_pos++; - } - if (len == 0) - return; - if (p->bom_pos == 0) { - p->bom_pos = 3; /* no BOM */ - } else if (p->bom_pos > 0 && p->bom_pos < 3) { - strcpy(p->error, _("Invalid Byte Order Mark")); - p->failure = 1; - return; - } - } - - /* Note, don't write a parser error if p->failure, since an error + /* Note, don't write a parser error if !p->valid, since an error * will already have been written in that case. */ #ifdef HAVE_EXPAT ret = XML_Parse(p->parser, block, len, flag); NE_DEBUG(NE_DBG_XMLPARSE, "XML_Parse returned %d\n", ret); - if (ret == 0 && p->failure == 0) { + if (ret == 0 && p->valid) { ne_snprintf(p->error, ERR_SIZE, "XML parse error at line %d: %s", XML_GetCurrentLineNumber(p->parser), XML_ErrorString(XML_GetErrorCode(p->parser))); - p->failure = 1; + p->valid = 0; } #else ret = xmlParseChunk(p->parser, block, len, flag); NE_DEBUG(NE_DBG_XMLPARSE, "xmlParseChunk returned %d\n", ret); /* Parse errors are normally caught by the sax_error() callback, * which clears p->valid. */ - if (p->parser->errNo && p->failure == 0) { + if (p->parser->errNo && p->valid) { ne_snprintf(p->error, ERR_SIZE, "XML parse error at line %d.", ne_xml_currentline(p)); - p->failure = 1; - NE_DEBUG(NE_DBG_XMLPARSE, "XML parse error: %s\n", p->error); + p->valid = 0; } #endif } -int ne_xml_failed(ne_xml_parser *p) +int ne_xml_valid(ne_xml_parser *p) { - return p->failure; + return p->valid; } void ne_xml_destroy(ne_xml_parser *p) @@ -591,12 +553,11 @@ static void sax_error(void *ctx, const char *msg, ...) ne_vsnprintf(buf, 1024, msg, ap); va_end(ap); - if (p->failure == 0) { - ne_snprintf(p->error, ERR_SIZE, - _("XML parse error at line %d: %s."), - p->parser->input->line, buf); - p->failure = 1; - } + ne_snprintf(p->error, ERR_SIZE, + _("XML parse error at line %d: %s."), + p->parser->input->line, buf); + + p->valid = 0; } #endif diff --git a/src/ne_xml.h b/src/ne_xml.h index e0401ea..58cde9a 100644 --- a/src/ne_xml.h +++ b/src/ne_xml.h @@ -1,6 +1,6 @@ /* neon XML parser interface - Copyright (C) 1999-2004, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 1999-2003, Joe Orton <joe@manyfish.co.uk> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -86,27 +86,16 @@ void ne_xml_push_handler(ne_xml_parser *p, ne_xml_endelm_cb *endelm, void *userdata); -/* ne_xml_failed returns non-zero if there was an error during - * parsing, or zero if the parse completed successfully. If a handler - * callback aborts the parse by returning a negative number, that number - * is returned by ne_xml_failed. If the XML could not be parsed, a - * positive number is returned. */ -int ne_xml_failed(ne_xml_parser *p); - -/* Set error string for parser: the string may be truncated. */ -void ne_xml_set_error(ne_xml_parser *p, const char *msg); - -/* Return the error string (never NULL). After ne_xml_failed returns - * >0, this will describe the parse error. Otherwise it will be a - * default error string. */ -const char *ne_xml_get_error(ne_xml_parser *p); +/* Returns non-zero if the parse was valid, zero if it failed (e.g., + * any of the callbacks failed, the XML was not well-formed, etc). + * Use ne_xml_get_error to retrieve the error message if it failed. */ +int ne_xml_valid(ne_xml_parser *p); /* Destroy the parser object. */ void ne_xml_destroy(ne_xml_parser *p); -/* Parse the given block of input of length len. Parser must be - * called with len=0 to signify the end of the document (for that - * case, the block argument is ignored). */ +/* Parse the given block of input of length len. Block does not need + * to be NUL-terminated. */ void ne_xml_parse(ne_xml_parser *p, const char *block, size_t len); /* As above, casting (ne_xml_parser *)userdata internally. @@ -116,6 +105,12 @@ void ne_xml_parse_v(void *userdata, const char *block, size_t len); /* Return current parse line for errors */ int ne_xml_currentline(ne_xml_parser *p); +/* Set error string for parser. */ +void ne_xml_set_error(ne_xml_parser *p, const char *msg); + +/* Return the error string for the parser and never NULL. */ +const char *ne_xml_get_error(ne_xml_parser *p); + /* From a start_element callback which was passed 'attrs' using given * parser, return attribute of given name and namespace. If nspace is * NULL, no namespace resolution is performed. */ diff --git a/test/.cvsignore b/test/.cvsignore index 4192f5f..2304dc8 100644 --- a/test/.cvsignore +++ b/test/.cvsignore @@ -44,5 +44,3 @@ client.* output.pem libtest.* clog -largefile -sparse.bin diff --git a/test/ChangeLog b/test/ChangeLog index d484ded..77d6f67 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,39 +1,8 @@ -Wed Aug 25 21:05:28 2004 Joe Orton <joe@manyfish.co.uk> +Tue May 18 21:00:07 2004 Joe Orton <joe@manyfish.co.uk> - * cookies.c: Removed. - - * Makefile.in: Updated. - -Wed Aug 25 19:47:28 2004 Joe Orton <joe@manyfish.co.uk> - - * socket.c (do_connect, begin): Simplify do_connect use. - -Wed Aug 25 18:28:19 2004 Joe Orton <joe@manyfish.co.uk> - - * xml.c (matches, fail_parse): Test for UTF-8 BOM handling. - -Mon Jul 5 18:41:07 2004 Joe Orton <joe@manyfish.co.uk> - - * basic.c (content_type): Test for correct default charset for - text/xml content-type by RFC3280. - -Mon Jul 5 10:59:17 2004 Joe Orton <joe@manyfish.co.uk> - - Add XFAIL regression tests for trio of ne_compress.c bugs: - - * compress.c (reader): Validate that a size=0 call comes only - after the expected response data, and use struct string. - (do_fetch): Pass a struct string to reader and adapt for failure - logic. - (auth_cb, retry_compress_helper, retry_compress, - retry_notcompress): New tests. - -Sun Jul 4 21:55:00 2004 Joe Orton <joe@manyfish.co.uk> - - * utils.c (serve_sstring_slowly, serve_sstring): Moved from - sockets.c, renamed from serve_string_slowly, serve_sstring. - - * sockets.c: All callers updated. + * ssl.c (fail_ssl_request): + * basic.c (do_range): Fix false negatives from gcc + -Wformat-security. Sun May 2 21:16:45 2004 Joe Orton <joe@manyfish.co.uk> @@ -44,39 +13,6 @@ Wed Apr 14 10:45:43 2004 Joe Orton <joe@manyfish.co.uk> * props.c (regress, patch_regress): Add regression tests for CAN-2004-0179 issues. -Thu Apr 8 13:57:04 2004 Joe Orton <joe@manyfish.co.uk> - - * largefile.c (read_large_response): Go faster: turn off debugging - during request dispatch. - -Wed Apr 7 13:39:37 2004 Joe Orton <joe@manyfish.co.uk> - - * auth.c (basic): Add some multi-scheme challenges. - -Wed Apr 7 13:14:16 2004 Joe Orton <joe@manyfish.co.uk> - - * request.c (s_progress): Use NE_FMT_OFF_T for printing off_t's - throughout. - -Sun Feb 22 23:38:05 2004 Joe Orton <joe@manyfish.co.uk> - - * request.c (expect_100_once, serve_100_once): Adjust for new - 100-continue interface. - (expect_100_nobody): New test. - -Sun Feb 22 20:39:15 2004 Joe Orton <joe@manyfish.co.uk> - - * cookies.c (parsing): Use ne_cookie_empty_cache. - -Sun Feb 22 17:28:41 2004 Joe Orton <joe@manyfish.co.uk> - - * props.c (pfind_simple): Test for whitespace handling. - -Sun Feb 22 16:31:52 2004 Joe Orton <joe@manyfish.co.uk> - - * auth.c (basic): Test handling of Basic challenge in presence of - multiple challenges. - Sun Feb 15 12:34:13 2004 Joe Orton <joe@manyfish.co.uk> * makekeys.sh, openssl.conf: Create new utf8subj.cert, @@ -85,67 +21,10 @@ Sun Feb 15 12:34:13 2004 Joe Orton <joe@manyfish.co.uk> * ssl.c (dname_readable): Test that ne_ssl_readable_dname always gives back UTF-8. -Sat Feb 14 21:59:17 2004 Joe Orton <joe@manyfish.co.uk> - - * xml.c (fail_parse): Add tests for invalid NCNames in namespace - prefix declaration and as element names. - -Sun Jan 25 15:21:56 2004 Joe Orton <joe@manyfish.co.uk> - - * largefile.c (serve_large_response, read_large_response): New - test. - -Sat Jan 24 18:10:14 2004 Joe Orton <joe@manyfish.co.uk> - - * Makefile.in: Fix test suite for 'make' implementatinos which - don't handle single-suffix inference rules. - -Sat Jan 3 14:10:14 2004 Joe Orton <joe@manyfish.co.uk> - - * largefile.c (send_high_offset): Renamed from send_large_file. - -Sat Jan 3 13:57:16 2004 Joe Orton <joe@manyfish.co.uk> - - * Makefile.in (BASIC_TESTS): Add cookies. - -Thu Jan 1 17:42:30 2004 Joe Orton <joe@manyfish.co.uk> - - * util-tests.c (support): Check for NE_FEATURE_LFS. - - * largefile.c: New file. - - * Makefile.in: Add lfs-check, largefile, largefile.lo targets. - -Sat Nov 15 08:04:22 2003 Joe Orton <joe@manyfish.co.uk> - - * request.c (idna_hostname, dup_header, serve_check_host): New - test. - -Fri Nov 14 14:06:57 2003 Joe Orton <joe@manyfish.co.uk> - - * util-tests.c (support): Test for NE_FEATURE_IDNA. - -Fri Nov 14 11:26:29 2003 Joe Orton <joe@manyfish.co.uk> - - * acl.c: Remove NEON_NODAV condition. - - * stubs.c: Use new NE_HAVE_* conditions. - - * util-tests.c (supports): Test new ne_has_support interface. - Thu Nov 13 20:33:44 2003 Joe Orton <joe@manyfish.co.uk> * request.c (no_body_205): New test. -Tue Nov 11 20:36:43 2003 Joe Orton <joe@manyfish.co.uk> - - Adjust for ne_xml_valid->ne_xml_failure API change. - - * xml.c (chardata, startelm_abort, endelm_abort, parse_match): - Check for propagation of negative failure codes. - (fail_parse): Check for positive failure code. - (attributes): Use ne_xml_failure. - Sat Oct 25 00:11:29 2003 Joe Orton <joe@manyfish.co.uk> * ssl.c (fail_truncated_eof): Remove test. diff --git a/test/Makefile.in b/test/Makefile.in index 4572055..9d89e42 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -19,8 +19,8 @@ CC = @CC@ OPENSSL = @OPENSSL@ HELPERS = @HELPERS@ -BASIC_TESTS = uri-tests util-tests string-tests socket \ - session request auth basic stubs redirect +BASIC_TESTS = uri-tests util-tests string-tests session socket \ + request auth basic stubs redirect ZLIB_TESTS = compress ZLIB_HELPERS = file1.gz file2.gz trailing.gz badcsum.gz truncated.gz corrupt1.gz corrupt2.gz DAV_TESTS = xml acl props lock @@ -52,7 +52,7 @@ clean: rm -f $(TESTS) $(HELPERS) *.*o common/*.*o libtest.a *.log rm -rf ca .libs rm -f ca-stamp client.key *.csr ssigned.pem wrongcn.pem \ - server.cert client.cert client.p12 *.cert sparse.bin + server.cert client.cert client.p12 *.cert check: $(TESTS) $(HELPERS) @SRCDIR=$(srcdir) $(SHELL) $(srcdir)/run.sh $(TESTS) @@ -60,9 +60,6 @@ check: $(TESTS) $(HELPERS) grind: $(TESTS) $(HELPERS) @SRCDIR=$(srcdir) HARNESS="$(VALGRIND)" $(SHELL) $(srcdir)/run.sh $(TESTS) -lfs-check: largefile $(LFS_HELPERS) - @SRCDIR=$(srcdir) $(SHELL) $(srcdir)/run.sh largefile - NEWS = $(top_srcdir)/NEWS file1.gz: $(NEWS) @@ -110,6 +107,9 @@ $(LIBTEST): $(LIBOBJS) .c.lo: $(COMPILE) -c $< -o $@ +.lo: + $(LINK) -o $@ $< $(LIBS) + # Recompile socket.c with SOCKET_SSL defined socket-ssl.lo: $(srcdir)/socket.c $(HDRS) $(COMPILE) -DSOCKET_SSL -c $(srcdir)/socket.c -o $@ @@ -120,9 +120,6 @@ socket-ssl: socket-ssl.lo $(LIBTEST) resolve: resolve.lo $(LIBNEON) $(LINK) -o $@ resolve.lo $(LIBNEON) -common/tests.lo: $(srcdir)/common/tests.c $(OBJDEPS) -common/child.lo: $(srcdir)/common/child.c $(OBJDEPS) -utils.lo: $(srcdir)/utils.c $(OBJDEPS) auth.lo: $(srcdir)/auth.c $(OBJDEPS) uri-tests.lo: $(srcdir)/uri-tests.c $(OBJDEPS) util-tests.lo: $(srcdir)/util-tests.c $(OBJDEPS) @@ -140,46 +137,26 @@ session.lo: $(srcdir)/session.c $(OBJDEPS) redirect.lo: $(srcdir)/redirect.c $(OBJDEPS) basic.lo: $(srcdir)/basic.c $(OBJDEPS) ssl.lo: $(srcdir)/ssl.c $(OBJDEPS) -lock.lo: $(srcdir)/lock.c $(OBJDEPS) -largefile.lo: $(srcdir)/largefile.c $(OBJDEPS) +cookies.lo: $(srcdir)/cookies.c $(OBJDEPS) auth: auth.lo $(DEPS) - $(LINK) -o $@ auth.lo $(DEPS) basic: basic.lo $(DEPS) - $(LINK) -o $@ basic.lo $(DEPS) uri-tests: uri-tests.lo $(DEPS) - $(LINK) -o $@ uri-tests.lo $(DEPS) util-tests: util-tests.lo $(DEPS) - $(LINK) -o $@ util-tests.lo $(DEPS) string-tests: string-tests.lo $(DEPS) - $(LINK) -o $@ string-tests.lo $(DEPS) socket: socket.lo $(DEPS) - $(LINK) -o $@ socket.lo $(DEPS) server: server.lo $(DEPS) - $(LINK) -o $@ server.lo $(DEPS) request: request.lo $(DEPS) - $(LINK) -o $@ request.lo $(DEPS) regress: regress.lo $(DEPS) - $(LINK) -o $@ regress.lo $(DEPS) compress: compress.lo $(DEPS) - $(LINK) -o $@ compress.lo $(DEPS) acl: acl.lo $(DEPS) - $(LINK) -o $@ acl.lo $(DEPS) utils: utils.lo $(DEPS) - $(LINK) -o $@ utils.lo $(DEPS) stubs: stubs.lo $(DEPS) - $(LINK) -o $@ stubs.lo $(DEPS) props: props.lo $(DEPS) - $(LINK) -o $@ props.lo $(DEPS) session: session.lo $(DEPS) - $(LINK) -o $@ session.lo $(DEPS) redirect: redirect.lo $(DEPS) - $(LINK) -o $@ redirect.lo $(DEPS) +basic: basic.lo $(DEPS) ssl: ssl.lo $(DEPS) - $(LINK) -o $@ ssl.lo $(DEPS) xml: xml.lo $(DEPS) - $(LINK) -o $@ xml.lo $(DEPS) lock: lock.lo $(DEPS) - $(LINK) -o $@ lock.lo $(DEPS) -largefile: largefile.lo $(DEPS) - $(LINK) -o $@ largefile.lo $(DEPS) +cookies: cookies.lo $(DEPS) @@ -24,6 +24,18 @@ #include "child.h" #include "utils.h" +#ifdef NEON_NODAV + +static int skip(void) +{ + t_context("built without WebDAV support"); + return SKIP; +} + +ne_test tests[] = { T(skip), T(NULL) }; + +#else + /**** DUMMY TESTS: just makes sure the stuff doesn't dump core. */ static int test_acl(const char *uri, ne_acl_entry *es, int nume) @@ -99,3 +111,5 @@ ne_test tests[] = { T(deny_byprop), T(NULL) }; + +#endif /* NEON_NODAV */ diff --git a/test/auth.c b/test/auth.c index 7f7e993..30fe88e 100644 --- a/test/auth.c +++ b/test/auth.c @@ -1,6 +1,6 @@ /* Authentication tests - Copyright (C) 2001-2004, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 2001-2003, Joe Orton <joe@manyfish.co.uk> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -40,16 +40,11 @@ static const char username[] = "Aladdin", password[] = "open sesame"; static int auth_failed; -#define BASIC_WALLY "Basic realm=WallyWorld" -#define CHAL_WALLY "WWW-Authenticate: " BASIC_WALLY +static const char www_wally[] = "WWW-Authenticate: Basic realm=WallyWorld"; static int auth_cb(void *userdata, const char *realm, int tries, char *un, char *pw) { - if (strcmp(realm, "WallyWorld")) { - NE_DEBUG(NE_DBG_HTTP, "Got wrong realm '%s'!\n", realm); - return -1; - } strcpy(un, username); strcpy(pw, password); return tries; @@ -92,8 +87,6 @@ static int send_response(ne_socket *sock, const char *hdr, int code, int eoc) * second doesn't. */ static int auth_serve(ne_socket *sock, void *userdata) { - char *hdr = userdata; - auth_failed = 1; /* Register globals for discard_request. */ @@ -101,7 +94,7 @@ static int auth_serve(ne_socket *sock, void *userdata) want_header = "Authorization"; discard_request(sock); - send_response(sock, hdr, 401, 0); + send_response(sock, www_wally, 401, 0); discard_request(sock); send_response(sock, NULL, auth_failed?500:200, 1); @@ -109,71 +102,33 @@ static int auth_serve(ne_socket *sock, void *userdata) return 0; } -/* Test that various Basic auth challenges are correctly handled. */ static int basic(void) { - const char *hdrs[] = { - /* simplest case */ - CHAL_WALLY, - - /* several challenges, one header */ - "WWW-Authenticate: BarFooScheme, " BASIC_WALLY, - - /* several challenges, one header */ - CHAL_WALLY ", BarFooScheme realm=\"PenguinWorld\"", - - /* whitespace tests. */ - "WWW-Authenticate: Basic realm=WallyWorld ", - - /* nego test. */ - "WWW-Authenticate: Negotiate fish, Basic realm=WallyWorld", - - /* nego test. */ - "WWW-Authenticate: Negotiate fish, bar=boo, Basic realm=WallyWorld", - - /* multi-header case 1 */ - "WWW-Authenticate: BarFooScheme\r\n" - CHAL_WALLY, - - /* multi-header cases 1 */ - CHAL_WALLY "\r\n" - "WWW-Authenticate: BarFooScheme bar=\"foo\"", - - /* multi-header case 3 */ - "WWW-Authenticate: FooBarChall foo=\"bar\"\r\n" - CHAL_WALLY "\r\n" - "WWW-Authenticate: BarFooScheme bar=\"foo\"" - }; - size_t n; - - for (n = 0; n < sizeof(hdrs)/sizeof(hdrs[0]); n++) { - ne_session *sess; - - CALL(make_session(&sess, auth_serve, (void *)hdrs[n])); - ne_set_server_auth(sess, auth_cb, NULL); - - CALL(any_2xx_request(sess, "/norman")); - - ne_session_destroy(sess); - CALL(await_server()); - } + ne_session *sess; + CALL(make_session(&sess, auth_serve, NULL)); + ne_set_server_auth(sess, auth_cb, NULL); + + CALL(any_2xx_request(sess, "/norman")); + + ne_session_destroy(sess); + CALL(await_server()); return OK; } static int retry_serve(ne_socket *sock, void *ud) { discard_request(sock); - send_response(sock, CHAL_WALLY, 401, 0); + send_response(sock, www_wally, 401, 0); discard_request(sock); - send_response(sock, CHAL_WALLY, 401, 0); + send_response(sock, www_wally, 401, 0); discard_request(sock); send_response(sock, NULL, 200, 0); discard_request(sock); - send_response(sock, CHAL_WALLY, 401, 0); + send_response(sock, www_wally, 401, 0); discard_request(sock); send_response(sock, NULL, 200, 0); @@ -185,19 +140,19 @@ static int retry_serve(ne_socket *sock, void *ud) send_response(sock, NULL, 200, 0); discard_request(sock); - send_response(sock, CHAL_WALLY, 401, 0); + send_response(sock, www_wally, 401, 0); discard_request(sock); send_response(sock, NULL, 200, 0); discard_request(sock); - send_response(sock, CHAL_WALLY, 401, 0); + send_response(sock, www_wally, 401, 0); discard_request(sock); - send_response(sock, CHAL_WALLY, 401, 0); + send_response(sock, www_wally, 401, 0); discard_request(sock); - send_response(sock, CHAL_WALLY, 401, 0); + send_response(sock, www_wally, 401, 0); discard_request(sock); send_response(sock, NULL, 200, 0); @@ -341,8 +296,8 @@ static int tunnel_regress(void) /* test digest auth 2617-style. */ -/* test that digest has precedence over Basic for multi-scheme - * challenges */ +/* negotiation: within a single header, multiple headers. + * check digest has precedence */ /* test auth-int, auth-int FAILURE. chunk trailers/non-trailer */ diff --git a/test/basic.c b/test/basic.c index cabe2d2..9ffe0e1 100644 --- a/test/basic.c +++ b/test/basic.c @@ -46,10 +46,8 @@ static int content_type(void) { "foo/bar", "foo", "bar", NULL }, { "foo/bar ", "foo", "bar", NULL }, { "application/xml", "application", "xml", NULL }, - /* text/ subtypes default to charset ISO-8859-1, per 2616. */ + /* text/ subtypes default to charset ISO-8859-1. */ { "text/lemon", "text", "lemon", "ISO-8859-1" }, - /* text/xml defaults to charset us-ascii, per 3280 */ - { "text/xml", "text", "xml", "us-ascii" }, #undef TXU #define TXU "text", "xml", "utf-8" /* 2616 doesn't *say* that charset can be quoted, but bets are diff --git a/test/common/ChangeLog b/test/common/ChangeLog index f17d47d..7e89c08 100644 --- a/test/common/ChangeLog +++ b/test/common/ChangeLog @@ -1,11 +1,3 @@ -Wed Aug 25 19:27:26 2004 Joe Orton <joe@manyfish.co.uk> - - * child.c (reset_socket): New function. - -Mon Jul 5 18:38:08 2004 Joe Orton <joe@manyfish.co.uk> - - * tests.c (main): Print 'xfail' for expected failures. - Tue Oct 7 21:19:56 2003 Joe Orton <joe@manyfish.co.uk> * child.c (close_socket): New function. diff --git a/test/common/child.c b/test/common/child.c index ee1ea53..5756882 100644 --- a/test/common/child.c +++ b/test/common/child.c @@ -1,6 +1,6 @@ /* Framework for testing with a server process - Copyright (C) 2001-2004, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 2001-2002, Joe Orton <joe@manyfish.co.uk> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -131,17 +131,6 @@ void minisleep(void) #endif } -int reset_socket(ne_socket *sock) -{ -#ifdef SO_LINGER - /* Stevens' magic trick to send an RST on close(). */ - struct linger l = {1, 0}; - return setsockopt(ne_sock_fd(sock), SOL_SOCKET, SO_LINGER, &l, sizeof l); -#else - return 1; -#endif -} - /* close 'sock', performing lingering close to avoid premature RST. */ static int close_socket(ne_socket *sock) { diff --git a/test/common/child.h b/test/common/child.h index 39bdb1d..9c506b9 100644 --- a/test/common/child.h +++ b/test/common/child.h @@ -1,6 +1,6 @@ /* Framework for testing with a server process - Copyright (C) 2001-2004, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 2001-2002, Joe Orton <joe@manyfish.co.uk> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -84,10 +84,6 @@ ssize_t server_send(ne_socket *sock, const char *data, size_t len); /* Utility macro: send given string down socket. */ #define SEND_STRING(sock, str) server_send((sock), (str), strlen((str))) -/* Tries to ensure that the socket will be closed using RST rather - * than FIN. */ -int reset_socket(ne_socket *sock); - /* Utility function: discard request. Sets context on error. */ int discard_request(ne_socket *sock); diff --git a/test/common/tests.c b/test/common/tests.c index 2c1c154..83f0c52 100644 --- a/test/common/tests.c +++ b/test/common/tests.c @@ -1,6 +1,6 @@ /* Stupidly simple test framework - Copyright (C) 2001-2002, 2004, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 2001-2002, Joe Orton <joe@manyfish.co.uk> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -41,7 +41,6 @@ #include <errno.h> #endif -#include "ne_string.h" #include "ne_utils.h" #include "ne_socket.h" @@ -196,7 +195,7 @@ int main(int argc, char *argv[]) printf("-> running `%s':\n", test_suite); for (n = 0; !aborted && tests[n].fn != NULL; n++) { - int result, is_xfail = 0; + int result; #ifdef NEON_MEMLEAK size_t allocated = ne_alloc_used; #endif @@ -234,10 +233,8 @@ int main(int argc, char *argv[]) if (result == OK) { t_context("test passed but expected failure"); result = FAIL; - } else if (result == FAIL) { + } else if (result == FAIL) result = OK; - is_xfail = 1; - } } /* align the result column if we've had warnings. */ @@ -247,12 +244,7 @@ int main(int argc, char *argv[]) switch (result) { case OK: - COL("32"); - if (is_xfail) - printf("xfail"); - else - printf("pass"); - NOCOL; + COL("32"); printf("pass"); NOCOL; if (warned) { printf(" (with %d warning%s)", warned, (warned > 1)?"s":""); } diff --git a/test/compress.c b/test/compress.c index df188e4..6bab4ce 100644 --- a/test/compress.c +++ b/test/compress.c @@ -1,6 +1,6 @@ /* tests for compressed response handling. - Copyright (C) 2001-2004, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 2001-2003, Joe Orton <joe@manyfish.co.uk> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -27,16 +27,20 @@ #include <fcntl.h> #include "ne_compress.h" -#include "ne_auth.h" #include "tests.h" #include "child.h" #include "utils.h" -static enum { f_partial = 0, f_mismatch, f_complete } failed; +static int failed; static char *newsfn = "../NEWS"; +struct body { + const char *str; + size_t len; +}; + static int init(void) { if (test_argc > 1) { @@ -45,41 +49,15 @@ static int init(void) return lookup_localhost(); } -#define EXTRA_DEBUG 0 /* disabled by default */ - static void reader(void *ud, const char *block, size_t len) { - struct string *b = ud; - -#if EXTRA_DEBUG - NE_DEBUG(NE_DBG_HTTP, "reader: got (%d): [[[%.*s]]]\n", (int)len, - (int)len, block); -#endif - - if (failed == f_mismatch) return; - - if (failed == f_partial && len == 0) { - if (b->len != 0) { - NE_DEBUG(NE_DBG_HTTP, "reader: got length %d at EOF\n", - (int)b->len); - failed = f_mismatch; - } else { - failed = f_complete; - } - return; - } - - if (len > b->len || memcmp(b->data, block, len) != 0) { - NE_DEBUG(NE_DBG_HTTP, "reader: failed, got [[%.*s]] not [[%.*s]]\n", - (int)len, block, (int)b->len, b->data); - failed = f_mismatch; + struct body *b = ud; + + if (failed || len > b->len || memcmp(b->str, block, len) != 0) { + failed = 1; } else { - b->data += len; + b->str += len; b->len -= len; -#if EXTRA_DEBUG - NE_DEBUG(NE_DBG_HTTP, "reader: OK, %d bytes remaining\n", - (int)b->len); -#endif } } @@ -104,17 +82,17 @@ static int do_fetch(const char *realfn, const char *gzipfn, ne_buffer *buf = ne_buffer_create(); struct serve_file_args sfargs; ne_decompress *dc; - struct string body; + struct body body; fd = open(realfn, O_RDONLY); ONN("failed to open file", fd < 0); file2buf(fd, buf); (void) close(fd); - body.data = buf->data; + body.str = buf->data; body.len = buf->used - 1; - failed = f_partial; + failed = 0; if (gzipfn) { sfargs.fname = gzipfn; @@ -130,16 +108,8 @@ static int do_fetch(const char *realfn, const char *gzipfn, req = ne_request_create(sess, "GET", "/"); dc = ne_decompress_reader(req, ne_accept_2xx, reader, &body); -#ifdef NE_DEBUGGING - ne_debug_init(ne_debug_stream, ne_debug_mask & ~NE_DBG_HTTPBODY); -#endif - ONREQ(ne_request_dispatch(req)); -#ifdef NE_DEBUGGING - ne_debug_init(ne_debug_stream, ne_debug_mask | NE_DBG_HTTPBODY); -#endif - ONN("file not served", ne_get_status(req)->code != 200); ONN("decompress succeeded", expect_fail && !ne_decompress_destroy(dc)); @@ -153,8 +123,10 @@ static int do_fetch(const char *realfn, const char *gzipfn, CALL(await_server()); if (!expect_fail) { - ONN("inflated response truncated", failed == f_partial); - ONN("inflated response mismatch", failed == f_mismatch); + ONN("inflated response compare", failed); + /* reader will have set body.len == 0 if the whole body + * has been compared. */ + ONN("inflated response truncated", body.len != 0); } return OK; @@ -239,111 +211,6 @@ static int fail_corrupt2(void) return do_fetch(newsfn, "corrupt2.gz", 0, 1); } -static int auth_cb(void *userdata, const char *realm, int tries, - char *un, char *pw) -{ - strcpy(un, "foo"); - strcpy(pw, "bar"); - return tries; -} - -static int retry_compress_helper(ne_accept_response acceptor, - struct string *resp, struct string *expect) -{ - ne_session *sess; - ne_request *req; - ne_decompress *dc; - - CALL(make_session(&sess, serve_sstring, resp)); - - ne_set_server_auth(sess, auth_cb, NULL); - - req = ne_request_create(sess, "GET", "/"); - dc = ne_decompress_reader(req, acceptor, reader, expect); - failed = f_partial; - - ONREQ(ne_request_dispatch(req)); - - ONV(ne_decompress_destroy(dc), - ("decompress failed: %s", ne_get_error(sess))); - - ONN("got bad response body", failed != f_complete); - - CALL(await_server()); - - ne_request_destroy(req); - ne_session_destroy(sess); - - return OK; -} - -static char retry_gz_resp[] = -"HTTP/1.1 401 Get Away\r\n" -"Content-Encoding: gzip\r\n" -"WWW-Authenticate: Basic realm=WallyWorld\r\n" -"Content-Length: 5\r\n" -"\r\n" -"abcde" -"HTTP/1.1 200 OK\r\n" -"Server: foo\r\n" -"Content-Length: 5\r\n" -"Connection: close\r\n" -"\r\n" -"hello"; - -/* Test where the response to the retried request does *not* have - * a content-encoding, whereas the original 401 response did. */ -static int retry_notcompress(void) -{ - struct string response = { retry_gz_resp, strlen(retry_gz_resp) }; - struct string expect = { "hello", 5 }; - return retry_compress_helper(ne_accept_2xx, &response, &expect); -} - -static unsigned char retry_gz_resp2[] = -"HTTP/1.1 401 Get Away\r\n" -"Content-Encoding: gzip\r\n" -"WWW-Authenticate: Basic realm=WallyWorld\r\n" -"Content-Length: 25\r\n" -"\r\n" -"\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03\xcb\x48\xcd\xc9\xc9\x07" -"\x00\x86\xa6\x10\x36\x05\x00\x00\x00" -"HTTP/1.1 200 OK\r\n" -"Server: foo\r\n" -"Content-Encoding: gzip\r\n" -"Content-Length: 25\r\n" -"Connection: close\r\n" -"\r\n" -"\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03\x2b\xcf\x2f\xca\x49\x01" -"\x00\x43\x11\x77\x3a\x05\x00\x00\x00"; - -static int retry_accept(void *ud, ne_request *req, const ne_status *st) -{ - struct string *expect = ud; - - NE_DEBUG(NE_DBG_HTTP, "retry_accept callback for %d response\n", - st->code); - - if (expect->len == 4 && strcmp(expect->data, "fish") == 0) { - /* first time through */ - expect->data = "hello"; - } else { - expect->data = "world"; - } - - expect->len = 5; - return 1; -} - -/* Test where the response to the retried request *does* have a - * content-encoding, as did the original 401 response. */ -static int retry_compress(void) -{ - struct string resp = { retry_gz_resp2, sizeof(retry_gz_resp2) - 1 }; - struct string expect = { "fish", 4 }; - return retry_compress_helper(retry_accept, &resp, &expect); -} - ne_test tests[] = { T_LEAKY(init), T(not_compressed), @@ -360,7 +227,5 @@ ne_test tests[] = { T(chunked_20b), T(chunked_10b), T(chunked_10b_wn), - T_XFAIL(retry_notcompress), - T_XFAIL(retry_compress), T(NULL) }; diff --git a/test/largefile.c b/test/largefile.c deleted file mode 100644 index c68b4fd..0000000 --- a/test/largefile.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - Tests for LFS support in neon - Copyright (C) 2004, Joe Orton <joe@manyfish.co.uk> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include "config.h" - -#include <sys/types.h> - -#include <unistd.h> -#include <fcntl.h> - -#ifdef HAVE_STDINT_H -#include <stdint.h> -#endif - -#include "ne_request.h" - -#include "child.h" -#include "utils.h" -#include "tests.h" - -#ifndef INT64_C -#define INT64_C(x) x ## LL -#endif - -static const char data[] = "Hello, world.\n"; -static off64_t point = INT64_C(2) << 32; -#define SPARSE "sparse.bin" - -/* make a sparse large file */ -static int make_sparse_file(void) -{ - int fd = open64(SPARSE, O_CREAT | O_TRUNC | O_WRONLY, 0644); - - ONN("could not create large file " SPARSE, fd < 0); - ONN("seek to point", lseek64(fd, point, SEEK_SET) != point); - ONN("could not write to file", - write(fd, data, strlen(data)) != (ssize_t)strlen(data)); - ONN("close failed", close(fd)); - - return OK; -} - -/* server function which checks that the request body sent was the - * same as the 'data' array. */ -static int serve_check_body(ne_socket *sock, void *userdata) -{ - CALL(discard_request(sock)); - - if (clength != (ssize_t)strlen(data)) { - CALL(discard_body(sock)); - SEND_STRING(sock, "HTTP/1.0 400 Bad Request Body Length\r\n" - "\r\n"); - } else { - char buf[20]; - - if (ne_sock_fullread(sock, buf, clength) == 0) { - SEND_STRING(sock, "HTTP/1.0 200 OK Then!\r\n\r\n"); - } - } - return 0; -} - -/* sends a small segment of the file from a high offset. */ -static int send_high_offset(void) -{ - int ret, fd = open64(SPARSE, O_RDONLY); - ne_session *sess; - ne_request *req; - - ONN("could not open sparse file", fd < 0); - - CALL(make_session(&sess, serve_check_body, NULL)); - - req = ne_request_create(sess, "PUT", "/sparse"); - ne_set_request_body_fd64(req, fd, point, strlen(data)); - ret = ne_request_dispatch(req); - CALL(await_server()); - ONV(ret != NE_OK || ne_get_status(req)->klass != 2, - ("request failed: %s", ne_get_error(sess))); - ne_request_destroy(req); - ne_session_destroy(sess); - close(fd); - return OK; -} - -#if 1 -#define RESPSIZE INT64_C(4295008256) -#define RESPSTR "4295008256" -#else -#define RESPSIZE INT64_C(2147491840) /* 2^31+8192 */ -#define RESPSTR "2147491840" -#endif - -/* Reads a request, sends a large response, reads a request, then - * sends a little response. */ -static int serve_large_response(ne_socket *sock, void *ud) -{ - int n = 0; - char empty[8192]; - - CALL(discard_request(sock)); - - SEND_STRING(sock, - "HTTP/1.1 200 OK\r\n" - "Content-Length: " RESPSTR "\r\n" - "Server: BigFileServerTM\r\n" "\r\n"); - - memset(empty, 0, sizeof empty); - - for (n = 0; n < RESPSIZE/sizeof(empty); n++) { - if (ne_sock_fullwrite(sock, empty, sizeof empty)) { - NE_DEBUG(NE_DBG_SOCKET, "fullwrite failed\n"); - return 1; - } - } - - NE_DEBUG(NE_DBG_SOCKET, "Wrote %d lots of %d\n", n, (int)sizeof empty); - - CALL(discard_request(sock)); - - SEND_STRING(sock, "HTTP/1.1 200 OK\r\n" - "Connection: close\r\n\r\n"); - - return 0; -} - -static int read_large_response(void) -{ - ne_session *sess; - ne_request *req; - off64_t count = 0; - int ret; - char buf[8192]; - - CALL(make_session(&sess, serve_large_response, NULL)); - - req = ne_request_create(sess, "GET", "/foo"); - -#ifdef NE_DEBUGGING - ne_debug_init(ne_debug_stream, ne_debug_mask & ~(NE_DBG_HTTPBODY|NE_DBG_HTTP)); -#endif - - ret = ne_begin_request(req); - if (ret == NE_OK) { - while ((ret = ne_read_response_block(req, buf, sizeof buf)) > 0) - count += ret; - if (ret == NE_OK) - ret = ne_end_request(req); - } - -#ifdef NE_DEBUGGING - ne_debug_init(ne_debug_stream, ne_debug_mask & (NE_DBG_HTTPBODY|NE_DBG_HTTP)); -#endif - - ONV(ret, ("request failed: %s", ne_get_error(sess))); - ONV(count != RESPSIZE, - ("response body was %" NE_FMT_OFF64_T " not %" NE_FMT_OFF64_T, - count, RESPSIZE)); - - ne_request_destroy(req); - - CALL(any_2xx_request(sess, "/bar")); - CALL(await_server()); - ne_session_destroy(sess); - return OK; -} - -ne_test tests[] = { - T(make_sparse_file), - T(send_high_offset), - T(read_large_response), - T(NULL), -}; diff --git a/test/makekeys.sh b/test/makekeys.sh index ba594a6..d9548b8 100755 --- a/test/makekeys.sh +++ b/test/makekeys.sh @@ -8,7 +8,7 @@ CONF=${srcdir}/openssl.conf REQ="${OPENSSL} req -config ${CONF}" CA="${OPENSSL} ca -config ${CONF} -batch" # MKCERT makes a self-signed cert -MKCERT="${REQ} -x509 -new -days 900" +MKCERT="${REQ} -x509 -new -days 9000" REQDN=reqDN STRMASK=default @@ -117,7 +117,7 @@ fqdn=`hostname -f 2>/dev/null` || true if [ "x${hostname}.${domain}" = "x${fqdn}" ]; then csr_fields "Wildcard Cert Dept" "*.${domain}" | \ ${REQ} -new -key ${srcdir}/server.key -out wildcard.csr - ${CA} -days 900 -in wildcard.csr -out wildcard.cert + ${CA} -days 9000 -in wildcard.csr -out wildcard.cert fi csr_fields "Neon Client Cert" ignored.example.com | \ diff --git a/test/props.c b/test/props.c index 25cdf56..ef0f1e7 100644 --- a/test/props.c +++ b/test/props.c @@ -263,8 +263,8 @@ static int run_207_response(char *resp, const char *expected) CALL(await_server()); - ONV(ne_xml_failed(p), - ("parse error in response body: %s", ne_xml_get_error(p))); + ONV(!ne_xml_valid(p), + ("response body was invalid: %s", ne_xml_get_error(p))); ONV(strcmp(buf->data, expected), ("comparison failed.\n" @@ -521,14 +521,7 @@ static int pfind_simple(void) STAT_207("256 Second is OK")))), "results(/alpha,prop:[{DAV:,fishbone}='strike one':{234 First is OK}];)//" "results(/beta,prop:[{DAV:,fishbone}='strike two':{256 Second is OK}];)//", - 0, 0}, - - /* whitespace handling. */ - { MULTI_207(RESP_207("\r\nhttp://localhost:7777/alpha ", - PSTAT_207(PROPS_207(APROP_207("alpha", "beta")) - "<D:status>\r\nHTTP/1.1 200 OK </D:status>"))), - "results(http://localhost:7777/alpha,prop:[{DAV:,alpha}='beta':{200 OK}];)//", - 0, 0} + 0, 0} }; const ne_propname pset1[] = { { "DAV:", "fishbone", }, diff --git a/test/request.c b/test/request.c index cb6b782..4df5c78 100644 --- a/test/request.c +++ b/test/request.c @@ -1,6 +1,6 @@ /* HTTP request handling tests - Copyright (C) 2001-2004, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 2001-2003, Joe Orton <joe@manyfish.co.uk> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -830,12 +830,17 @@ static int skip_1xx_hdrs(void) #undef sess -/* server for expect_100_once: serves a 100-continue request, and - * fails if the request body is sent twice. */ +/* server for expect_100_once: eats a dummy request, then serves a + * 100-continue request, and fails if the request body is sent + * twice. */ static int serve_100_once(ne_socket *sock, void *ud) { struct s1xx_args args = {2, 0}; char ch; + /* dummy first request. */ + CALL(discard_request(sock)); + CALL(SEND_STRING(sock, RESP200 "Content-Length: 0\r\n\r\n")); + /* now the real 1xx request. */ CALL(serve_1xx(sock, &args)); CALL(discard_body(sock)); ONN("body was served twice", ne_sock_read(sock, &ch, 1) == 1); @@ -852,35 +857,24 @@ static int expect_100_once(void) char body[BUFSIZ]; CALL(make_session(&sess, serve_100_once, NULL)); + ne_set_expect100(sess, 1); + /* 100-continue is only used if the server is known to claim + * HTTP/1.1 compliance; make a dummy request on the socket first, + * to trigger that logic. */ + CALL(any_request(sess, "/foo")); + + /* now the real request. */ req = ne_request_create(sess, "GET", "/foo"); - ne_set_request_expect100(req, 1); memset(body, 'A', sizeof(body)); ne_set_request_body_buffer(req, body, sizeof(body)); - ONREQ(ne_request_dispatch(req)); + ONN("request failed", ne_request_dispatch(req)); ne_request_destroy(req); ne_session_destroy(sess); CALL(await_server()); return OK; } -/* regression test for enabling 100-continue without sending a body. */ -static int expect_100_nobody(void) -{ - ne_session *sess; - ne_request *req; - - CALL(make_session(&sess, serve_100_once, NULL)); - - req = ne_request_create(sess, "GET", "/foo"); - ne_set_request_expect100(req, 1); - ONREQ(ne_request_dispatch(req)); - ne_request_destroy(req); - ne_session_destroy(sess); - - return await_server(); -} - struct body { char *body; size_t size; @@ -1172,13 +1166,11 @@ static enum { static off_t prog_last = -1, prog_total; -#define FOFF "%" NE_FMT_OFF_T - /* callback for send_progress. */ static void s_progress(void *userdata, off_t prog, off_t total) { NE_DEBUG(NE_DBG_HTTP, - "progress callback: " FOFF "/" FOFF ".\n", + "progress callback: %" NE_FMT_OFF_T "/%" NE_FMT_OFF_T ".\n", prog, total); switch (prog_state) { @@ -1187,19 +1179,19 @@ static void s_progress(void *userdata, off_t prog, off_t total) return; case prog_transfer: if (total != prog_total) { - t_context("total unexpected: " FOFF " not " FOFF "", total, prog_total); + t_context("total unexpected: %ld not %ld", total, prog_total); prog_state = prog_error; } else if (prog > total) { - t_context("first progress was invalid (" FOFF "/" FOFF ")", prog, total); + t_context("first progress was invalid (%ld/%ld)", prog, total); prog_state = prog_error; } else if (prog_last != -1 && prog_last > prog) { - t_context("progess went backwards: " FOFF " to " FOFF, prog_last, prog); + t_context("progess went backwards: %ld to %ld", prog_last, prog); prog_state = prog_error; } else if (prog_last == prog) { - t_context("no progress made! " FOFF " to " FOFF, prog_last, prog); + t_context("no progress made! %ld to %ld", prog_last, prog); prog_state = prog_error; } else if (prog == total) { @@ -1211,8 +1203,6 @@ static void s_progress(void *userdata, off_t prog, off_t total) prog_last = prog; } -#undef FOFF - static ssize_t provide_progress(void *userdata, char *buf, size_t bufsiz) { int *count = userdata; @@ -1590,59 +1580,6 @@ static int dup_method(void) return OK; } -#ifdef NE_HAVE_IDNA - -/* "ħêłłø.com" in UTF-8 and ACE form. */ -#define HELLO_DOT_COM "\xc4\xa7" "\xc3\xaa" "\xc5\x82" "\xc5\x82" "\xc3\xb8" ".com" -#define HELLO_IDNA_ACE "xn--bda2a5j8da.com" - -static char *host_hdr = NULL; - -static void dup_header(char *hdr) -{ - host_hdr = strdup(hdr); -} - -static int serve_check_host(ne_socket *sock, void *userdata) -{ - const char *host = userdata; - - want_header = "Host"; - got_header = dup_header; - - CALL(discard_request(sock)); - - if (host_hdr == NULL) { - CALL(SEND_STRING(sock, "HTTP/1.0 500 No Host header!?\r\n\r\n")); - } else if (strcmp(host_hdr, host) != 0) { - CALL(SEND_STRING(sock, "HTTP/1.0 500 Bad Host Header\r\n\r\n")); - } else { - CALL(SEND_STRING(sock, "HTTP/1.0 200 Good Host Header\r\n\r\n")); - } - - return OK; -} - -static int idna_hostname(void) -{ - ne_session *sess = ne_session_create("http", HELLO_DOT_COM, 80); - - ne_session_proxy(sess, "localhost", 7777); - - CALL(spawn_server(7777, serve_check_host, HELLO_IDNA_ACE)); - CALL(any_2xx_request(sess, "/idnafoo")); - CALL(await_server()); - - ne_session_destroy(sess); - return OK; -#else -static int idna_hostname(void) -{ - t_context("IDNA support not enabled"); - return SKIP; -#endif -} - ne_test tests[] = { T(lookup_localhost), T(single_get_clength), @@ -1693,7 +1630,6 @@ ne_test tests[] = { T(skip_1xx_hdrs), T(send_bodies), T(expect_100_once), - T(expect_100_nobody), T(unbounded_headers), T(unbounded_folding), T(blank_response), @@ -1716,6 +1652,5 @@ ne_test tests[] = { T(dup_method), T(versions), T(hook_create_req), - T(idna_hostname), T(NULL) }; diff --git a/test/run.sh b/test/run.sh index a6be539..0464571 100644 --- a/test/run.sh +++ b/test/run.sh @@ -3,8 +3,6 @@ rm -f debug.log rm -f child.log -ulimit -c unlimited - # enable an safety-checking malloc in glibc which will abort() if # heap corruption is detected. MALLOC_CHECK_=2 diff --git a/test/socket.c b/test/socket.c index ba46285..52dc328 100644 --- a/test/socket.c +++ b/test/socket.c @@ -1,6 +1,6 @@ /* Socket handling tests - Copyright (C) 2002-2004, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 2002-2003, Joe Orton <joe@manyfish.co.uk> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -82,22 +82,20 @@ static int multi_init(void) return OK; } -/* Create and connect *sock to address addr on given port. */ -static int do_connect(ne_socket **sock, ne_sock_addr *addr, unsigned int port) +static ne_socket *do_connect(ne_sock_addr *addr, unsigned int port) { + ne_socket *sock = ne_sock_create(); const ne_inet_addr *ia; - *sock = ne_sock_create(); - ONN("could not create socket", *sock == NULL); + if (!sock) return NULL; for (ia = ne_addr_first(addr); ia; ia = ne_addr_next(addr)) { - if (ne_sock_connect(*sock, ia, port) == 0) - return OK; + if (ne_sock_connect(sock, ia, port) == 0) + return sock; } - t_context("could not connect to server: %s", ne_sock_error(*sock)); - ne_sock_close(*sock); - return FAIL; + ne_sock_close(sock); + return NULL; } #ifdef SOCKET_SSL @@ -189,7 +187,8 @@ static int begin(ne_socket **sock, server_fn fn, void *ud) pair.fn = fn; pair.userdata = ud; CALL(spawn_server(7777, wrap_serve, &pair)); - CALL(do_connect(sock, localhost, 7777)); + *sock = do_connect(localhost, 7777); + ONN("could not connect to localhost:7777", *sock == NULL); ONV(ne_sock_connect_ssl(*sock, client_ctx), ("SSL negotation failed: %s", ne_sock_error(*sock))); return OK; @@ -200,7 +199,9 @@ static int begin(ne_socket **sock, server_fn fn, void *ud) static int begin(ne_socket **sock, server_fn fn, void *ud) { CALL(spawn_server(7777, fn, ud)); - return do_connect(sock, localhost, 7777); + *sock = do_connect(localhost, 7777); + ONN("could not connect to localhost:7777", *sock == NULL); + return OK; } #endif @@ -410,6 +411,40 @@ static int peek_close(void) return await_server(); } + +struct string { + char *data; + size_t len; +}; + +static int serve_string(ne_socket *sock, void *ud) +{ + struct string *str = ud; + + NE_DEBUG(NE_DBG_SOCKET, "Serving string: [[[%.*s]]]\n", + (int)str->len, str->data); + + ONN("write failed", ne_sock_fullwrite(sock, str->data, str->len)); + + return 0; +} + +static int serve_string_slowly(ne_socket *sock, void *ud) +{ + struct string *str = ud; + size_t n; + + NE_DEBUG(NE_DBG_SOCKET, "Slowly serving string: [[[%.*s]]]\n", + (int)str->len, str->data); + + for (n = 0; n < str->len; n++) { + ONN("write failed", ne_sock_fullwrite(sock, &str->data[n], 1)); + minisleep(); + } + + return 0; +} + /* Don't change this string. */ #define STR "Hello, World." @@ -446,7 +481,7 @@ static int single_read(void) ne_socket *sock; DECL(hello, STR); - CALL(begin(&sock, serve_sstring, &hello)); + CALL(begin(&sock, serve_string, &hello)); CALL(read_expect(sock, STR, strlen(STR))); CALL(expect_close(sock)); CALL(good_close(sock)); @@ -460,7 +495,7 @@ static int single_peek(void) ne_socket *sock; DECL(hello, STR); - CALL(begin(&sock, serve_sstring, &hello)); + CALL(begin(&sock, serve_string, &hello)); CALL(peek_expect(sock, STR, strlen(STR))); return finish(sock, 0); @@ -473,7 +508,7 @@ static int small_reads(void) char *pnt; DECL(hello, STR); - CALL(begin(&sock, serve_sstring, &hello)); + CALL(begin(&sock, serve_string, &hello)); /* read the string byte-by-byte. */ for (pnt = hello.data; *pnt; pnt++) { @@ -493,7 +528,7 @@ static int read_and_peek(void) ne_socket *sock; DECL(hello, STR); - CALL(begin(&sock, serve_sstring, &hello)); + CALL(begin(&sock, serve_string, &hello)); PEEK("Hello"); PEEK("Hell"); @@ -516,7 +551,7 @@ static int larger_read(void) ssize_t nb; DECL(hello, STR); - CALL(begin(&sock, serve_sstring, &hello)); + CALL(begin(&sock, serve_string, &hello)); nb = ne_sock_read(sock, buffer, hello.len + 10); ONV(nb != (ssize_t)hello.len, @@ -549,7 +584,7 @@ static int line_simple(void) ne_socket *sock; DECL(oneline, STR "\n" STR2 "\n"); - CALL(begin(&sock, serve_sstring, &oneline)); + CALL(begin(&sock, serve_string, &oneline)); LINE(STR "\n"); LINE(STR2 "\n"); @@ -562,7 +597,7 @@ static int line_closure(void) ssize_t ret; DECL(oneline, STR "\n" "foobar"); - CALL(begin(&sock, serve_sstring, &oneline)); + CALL(begin(&sock, serve_string, &oneline)); LINE(STR "\n"); ret = ne_sock_readline(sock, buffer, BUFSIZ); @@ -578,7 +613,7 @@ static int line_empty(void) ne_socket *sock; DECL(oneline, "\n\na\n\n"); - CALL(begin(&sock, serve_sstring, &oneline)); + CALL(begin(&sock, serve_string, &oneline)); LINE("\n"); LINE("\n"); LINE("a\n"); LINE("\n"); @@ -591,7 +626,7 @@ static int line_toolong(void) ssize_t ret; DECL(oneline, "AAAAAA\n"); - CALL(begin(&sock, serve_sstring, &oneline)); + CALL(begin(&sock, serve_string, &oneline)); ret = ne_sock_readline(sock, buffer, 5); ONV(ret != NE_SOCK_ERROR, ("readline should fail on long line: %" NE_FMT_SSIZE_T, ret)); @@ -605,7 +640,7 @@ static int line_mingle(void) ne_socket *sock; DECL(oneline, "alpha\nbeta\ndelta\ngamma\n"); - CALL(begin(&sock, serve_sstring, &oneline)); + CALL(begin(&sock, serve_string, &oneline)); READ("a"); LINE("lpha\n"); READ("beta"); LINE("\n"); @@ -622,7 +657,7 @@ static int line_chunked(void) ne_socket *sock; DECL(oneline, "this is a line\n"); - CALL(begin(&sock, serve_sstring_slowly, &oneline)); + CALL(begin(&sock, serve_string_slowly, &oneline)); LINE("this is a line\n"); @@ -39,7 +39,7 @@ #include "child.h" #include "utils.h" -#ifndef NE_HAVE_SSL +#ifndef NEON_SSL /* this file shouldn't be built if SSL is not enabled. */ #error SSL not supported #endif diff --git a/test/string-tests.c b/test/string-tests.c index 62e8afe..3d0fac1 100644 --- a/test/string-tests.c +++ b/test/string-tests.c @@ -1,6 +1,6 @@ /* String handling tests - Copyright (C) 2001-2004, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 2001-2003, Joe Orton <joe@manyfish.co.uk> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -410,7 +410,7 @@ static int base64(void) unsigned char bits[256]; size_t n; -#define B64B(x, l, y) CALL(b64_check((unsigned char *)x, l, y)) +#define B64B(x, l, y) CALL(b64_check(x, l, y)) #define B64(x, y) B64B(x, strlen(x), y) /* invent these with @@ -464,39 +464,6 @@ static int unbase64(void) return OK; } -static int printing(void) -{ - struct { - const char *in, *out; - size_t pass, ret; - } ts[] = { - { "alpha", "alpha", 10, 5 }, - { "alpha", "alph", 5, 4 }, - { "foobar", "", 1, 0 }, - { NULL, NULL, 0, 0} - }; - size_t n; - - for (n = 0; ts[n].in; n++) { - char buf[512]; - size_t ret; - - memset(buf, 'A', sizeof buf); - - ret = ne_snprintf(buf, ts[n].pass, "%s", ts[n].in); - - ONCMP(buf, ts[n].out); - ONV(ret != ts[n].ret, - ("got return value %" NE_FMT_SIZE_T " not %" NE_FMT_SIZE_T, - ret, ts[n].ret)); - - /* byte past the NUL must still be 'A' */ - ONN("buffer over-ran!", buf[ret + 1] != 'A'); - } - - return OK; -} - ne_test tests[] = { T(simple), T(buf_concat), @@ -520,7 +487,6 @@ ne_test tests[] = { T(cleaner), T(base64), T(unbase64), - T(printing), T(NULL) }; diff --git a/test/stubs.c b/test/stubs.c index 1c59962..494f8f0 100644 --- a/test/stubs.c +++ b/test/stubs.c @@ -42,11 +42,11 @@ #include "child.h" #include "utils.h" -#if defined(NE_HAVE_ZLIB) && defined(NE_HAVE_SSL) +#if defined(NEON_ZLIB) && defined(NEON_SSL) #define NO_TESTS 1 #endif -#ifndef NE_HAVE_ZLIB +#ifndef NEON_ZLIB static int sd_result = OK; static void sd_reader(void *ud, const char *block, size_t len) @@ -90,7 +90,7 @@ static int stub_decompress(void) } #endif -#ifndef NE_HAVE_SSL +#ifndef NEON_SSL static int stub_ssl(void) { ne_session *sess = ne_session_create("https", "localhost", 7777); @@ -156,10 +156,10 @@ static int null_test(void) { return OK; } #endif ne_test tests[] = { -#ifndef NE_HAVE_ZLIB +#ifndef NEON_ZLIB T(stub_decompress), #endif -#ifndef NE_HAVE_SSL +#ifndef NEON_SSL T(stub_ssl), #endif /* to prevent failure when SSL and zlib are supported. */ diff --git a/test/util-tests.c b/test/util-tests.c index 0cee94b..464f338 100644 --- a/test/util-tests.c +++ b/test/util-tests.c @@ -254,30 +254,10 @@ static int version_string(void) static int support(void) { -#ifdef NE_HAVE_SSL - ONN("SSL support not advertised", !ne_has_support(NE_FEATURE_SSL)); +#ifdef NEON_SSL + ONN("SSL support not advertised", !ne_supports_ssl()); #else - ONN("SSL support advertised", ne_has_support(NE_FEATURE_SSL)); -#endif -#ifdef NE_HAVE_ZLIB - ONN("zlib support not advertised", !ne_has_support(NE_FEATURE_ZLIB)); -#else - ONN("zlib support advertised", ne_has_support(NE_FEATURE_ZLIB)); -#endif -#ifdef NE_HAVE_IPV6 - ONN("IPv6 support not advertised", !ne_has_support(NE_FEATURE_IPV6)); -#else - ONN("IPv6 support advertised", ne_has_support(NE_FEATURE_IPV6)); -#endif -#ifdef NE_HAVE_IDNA - ONN("IDNA support not advertised", !ne_has_support(NE_FEATURE_IDNA)); -#else - ONN("IDNA support advertised", ne_has_support(NE_FEATURE_IDNA)); -#endif -#ifdef NE_HAVE_LFS - ONN("LFS support not advertised", !ne_has_support(NE_FEATURE_LFS)); -#else - ONN("LFS support advertised", ne_has_support(NE_FEATURE_LFS)); + ONN("SSL support advertised", ne_supports_ssl()); #endif return OK; } diff --git a/test/utils.c b/test/utils.c index a268461..47e1410 100644 --- a/test/utils.c +++ b/test/utils.c @@ -1,6 +1,6 @@ /* Utility functions for HTTP client tests - Copyright (C) 2001-2004, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 2001-2003, Joe Orton <joe@manyfish.co.uk> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -85,7 +85,7 @@ int any_2xx_request(ne_session *sess, const char *uri) ne_request *req = ne_request_create(sess, "GET", uri); int ret = ne_request_dispatch(req); ONV(ret != NE_OK || ne_get_status(req)->klass != 2, - ("request failed: %s", ne_get_error(sess))); + ("request failed: %s\n", ne_get_error(sess))); ne_request_destroy(req); return ret; } @@ -100,35 +100,8 @@ int any_2xx_request_body(ne_session *sess, const char *uri) ret = ne_request_dispatch(req); ne_free(body); ONV(ret != NE_OK || ne_get_status(req)->klass != 2, - ("request failed: %s", ne_get_error(sess))); + ("request failed: %s\n", ne_get_error(sess))); ne_request_destroy(req); return ret; } -int serve_sstring(ne_socket *sock, void *ud) -{ - struct string *str = ud; - - NE_DEBUG(NE_DBG_SOCKET, "Serving string: [[[%.*s]]]\n", - (int)str->len, str->data); - - ONN("write failed", ne_sock_fullwrite(sock, str->data, str->len)); - - return 0; -} - -int serve_sstring_slowly(ne_socket *sock, void *ud) -{ - struct string *str = ud; - size_t n; - - NE_DEBUG(NE_DBG_SOCKET, "Slowly serving string: [[[%.*s]]]\n", - (int)str->len, str->data); - - for (n = 0; n < str->len; n++) { - ONN("write failed", ne_sock_fullwrite(sock, &str->data[n], 1)); - minisleep(); - } - - return 0; -} diff --git a/test/utils.h b/test/utils.h index 2b466b6..55c61ab 100644 --- a/test/utils.h +++ b/test/utils.h @@ -1,6 +1,6 @@ /* neon-specific test utils - Copyright (C) 2001-2004, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 2001-2003, Joe Orton <joe@manyfish.co.uk> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -54,15 +54,4 @@ int make_session(ne_session **sess, server_fn fn, void *userdata); /* Server which sleeps for 10 seconds then closes the socket. */ int sleepy_server(ne_socket *sock, void *userdata); -struct string { - char *data; - size_t len; -}; - -/* Serve a struct string. */ -int serve_sstring(ne_socket *sock, void *ud); - -/* Serve a struct string slowly. */ -int serve_sstring_slowly(ne_socket *sock, void *ud); - #endif /* UTILS_H */ @@ -1,6 +1,6 @@ /* neon test suite - Copyright (C) 2002-2004, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 2002-2003, Joe Orton <joe@manyfish.co.uk> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -35,8 +35,6 @@ #include "child.h" #include "utils.h" -#define ABORT (-42) /* magic code for abort handlers */ - /* A set of SAX handlers which serialize SAX events back into a * pseudo-XML-like string. */ static int startelm(void *userdata, int state, @@ -62,7 +60,7 @@ static int chardata(void *userdata, int state, const char *cdata, size_t len) { ne_buffer *buf = userdata; ne_buffer_append(buf, cdata, len); - return strncmp(cdata, "!ABORT!", len) == 0 ? ABORT : NE_XML_DECLINE; + return !strncmp(cdata, "!ABORT!", len); } static int endelm(void *userdata, int state, @@ -141,7 +139,7 @@ static int startelm_abort(void *buf, int parent, { if (strcmp(name, "abort-start") == 0) { ne_buffer_zappend(buf, "ABORT"); - return ABORT; + return NE_XML_ABORT; } else return startelm(buf, parent, nspace, name, atts); } @@ -151,7 +149,7 @@ static int endelm_abort(void *buf, int state, { if (strcmp(name, "abort-end") == 0) { ne_buffer_zappend(buf, "ABORT"); - return ABORT; + return -1; } else return 0; } @@ -180,11 +178,9 @@ static int parse_match(const char *doc, const char *result, enum match_type t) ne_xml_parse(p, "", 0); if (t == match_invalid) - ONV(ne_xml_failed(p) != ABORT, - ("parse got %d not abort failure: %s", - ne_xml_failed(p), buf->data)); + ONV(ne_xml_valid(p), ("parse did not fail: %s", buf->data)); else - ONV(ne_xml_failed(p), ("parse failed: %s", ne_xml_get_error(p))); + ONV(!ne_xml_valid(p), ("parse failed: %s", ne_xml_get_error(p))); if (t == match_encoding) { const char *enc = ne_xml_doc_encoding(p); @@ -219,9 +215,6 @@ static int matches(void) { PFX "<hello>\r\n<wide> world</wide></hello>", "<{}hello>\n<{}wide> world</{}wide></{}hello>"}, - /* UTF-8 XML Byte Order Mark */ - { "\xEF\xBB\xBF" PFX "<hello/>", "<{}hello></{}hello>" }, - /*** Tests for namespace handling. ***/ #define NSA "xmlns:foo='bar'" { PFX "<foo:widget " NSA "/>", @@ -336,26 +329,7 @@ static int fail_parse(void) /* malformed namespace declarations */ PFX "<foo xmlns:D=''/>", PFX "<foo xmlns:='fish'/>", - PFX "<foo xmlns:.bar='fish'/>", - PFX "<foo xmlns:-bar='fish'/>", - PFX "<foo xmlns:0bar='fish'/>", - PFX "<fee xmlns:8baz='bar'/>", - /* element names which are not valid QNames. */ - PFX "<foo:bar:baz xmlns:foo='bar'/>", PFX "<foo: xmlns:foo='bar'/>", - PFX "<:fee/>", - PFX "<0fish/>", - PFX "<foo:0fish xmlns:foo='bar'/>", - PFX "<foo:9fish xmlns:foo='bar'/>", - PFX "<foo:-fish xmlns:foo='bar'/>", - PFX "<foo:.fish xmlns:foo='bar'/>", - -#if 0 /* currently disabled for SVN */ - PFX "<fee xmlns:baz:bar='bar'/>", - PFX "<fee xmlns::bar='bar'/>", - PFX "<foo::fish xmlns:foo='bar'/>", -#endif - #if 0 /* 2-byte encoding of '.': */ PFX "<foo>" "\x2F\xC0\xAE\x2E\x2F" "</foo>", @@ -367,14 +341,9 @@ static int fail_parse(void) PFX "<foo>" "\x2F\xF8\x80\x80\x80\xAE\x2E\x2F" "</foo>", /* 6-byte encoding of '.': */ PFX "<foo>" "\x2F\xFC\x80\x80\x80\x80\xAE\x2E\x2F" "</foo>", -#endif /* two-byte encoding of '<' must not be parsed as a '<': */ PFX "\xC0\xBC" "foo></foo>", - - /* Invalid UTF-8 XML Byte Order Marks */ - "\xEF\xBB" PFX "<hello/>", - "\xEF" PFX "<hello/>", - +#endif NULL }; int n; @@ -385,13 +354,10 @@ static int fail_parse(void) ne_xml_parse(p, docs[n], strlen(docs[n])); ne_xml_parse(p, "", 0); - ONV(ne_xml_failed(p) <= 0, - ("`%s' did not get positive parse error", docs[n])); + ONV(ne_xml_valid(p), ("`%s' was valid", docs[n])); err = ne_xml_get_error(p); - NE_DEBUG(NE_DBG_HTTP, "Parse error for '%s': %s\n", docs[n], err); - ONV(strstr(err, "parse error") == NULL - && strstr(err, "Invalid Byte Order Mark") == NULL, + ONV(strstr(err, "parse error") == NULL, ("bad error %s", err)); ne_xml_destroy(p); @@ -460,7 +426,7 @@ static int attributes(void) ne_xml_parse_v(p, doc, strlen(doc)); - ONV(ne_xml_failed(p), ("parse error: %s", ne_xml_get_error(p))); + ONV(!ne_xml_valid(p), ("parse error: %s", ne_xml_get_error(p))); ne_xml_destroy(p); return OK; |