diff -Nru davix-0.6.6/cmake/modules/FindgSOAP.cmake davix-0.6.7/cmake/modules/FindgSOAP.cmake --- davix-0.6.6/cmake/modules/FindgSOAP.cmake 2017-05-11 12:06:42.000000000 +0000 +++ davix-0.6.7/cmake/modules/FindgSOAP.cmake 2017-11-07 13:08:40.000000000 +0000 @@ -3,7 +3,7 @@ # include files and libraries are. # # This code sets the following variables: -# +# # GSOAP_LIBRARIES = full path to the gsoap libraries # GSOAP_SSL_LIBRARIES = full path to the gsoap ssl libraries # GSOAP_INCLUDE_DIR = include dir to be used when using the gsoap library @@ -20,13 +20,13 @@ # ----------------------------------------------------- find_library(GSOAP_LIBRARIES NAMES gsoap - HINTS ${GSOAP_LOCATION}/lib ${GSOAP_LOCATION}/lib64 + HINTS ${GSOAP_LOCATION}/lib ${GSOAP_LOCATION}/lib64 ${GSOAP_LOCATION}/lib32 DOC "The main gsoap library" ) find_library(GSOAP_SSL_LIBRARIES NAMES gsoapssl - HINTS ${GSOAP_LOCATION}/lib ${GSOAP_LOCATION}/lib64 + HINTS ${GSOAP_LOCATION}/lib ${GSOAP_LOCATION}/lib64 ${GSOAP_LOCATION}/lib32 DOC "The ssl gsoap library" ) @@ -34,7 +34,7 @@ # ----------------------------------------------------- # GSOAP Include Directories # ----------------------------------------------------- -find_path(GSOAP_INCLUDE_DIR +find_path(GSOAP_INCLUDE_DIR NAMES stdsoap2.h HINTS ${GSOAP_LOCATION} ${GSOAP_LOCATION}/include ${GSOAP_LOCATION}/include/* DOC "The gsoap include directory" @@ -65,26 +65,26 @@ string(REGEX MATCH "[0-9]*\\.[0-9]*\\.[0-9]*" GSOAP_VERSION ${GSOAP_STRING_VERSION}) if( "${GSOAP_VERSION}" STREQUAL "..") - execute_process(COMMAND ${GSOAP_SOAPCPP2} "-v" OUTPUT_VARIABLE GSOAP_STRING_VERSION ERROR_VARIABLE GSOAP_STRING_VERSION ) + execute_process(COMMAND ${GSOAP_SOAPCPP2} "-v" TIMEOUT 1 OUTPUT_VARIABLE GSOAP_STRING_VERSION ERROR_VARIABLE GSOAP_STRING_VERSION ) string(REGEX MATCH "[0-9]*\\.[0-9]*\\.[0-9]*" GSOAP_VERSION ${GSOAP_STRING_VERSION}) endif() message(STATUS " - GSOAP VERSION : ${GSOAP_VERSION}") if( "${GSOAP_VERSION}" VERSION_LESS "2.7.6") set(GSOAP_276_COMPAT_FLAGS "") -elseif ( "${GSOAP_VERSION}" VERSION_LESS "2.7.14") - set(GSOAP_276_COMPAT_FLAGS "-z") -else ( "${GSOAP_VERSION}" VERSION_LESS "2.7.14") - set(GSOAP_276_COMPAT_FLAGS "-z1 -z2") +elseif ( "${GSOAP_VERSION}" VERSION_LESS "2.7.14") + set(GSOAP_276_COMPAT_FLAGS "-z") +else ( "${GSOAP_VERSION}" VERSION_LESS "2.7.14") + set(GSOAP_276_COMPAT_FLAGS "-z1 -z2") endif ( "${GSOAP_VERSION}" VERSION_LESS "2.7.6") # ----------------------------------------------------- -# handle the QUIETLY and REQUIRED arguments and set GSOAP_FOUND to TRUE if +# handle the QUIETLY and REQUIRED arguments and set GSOAP_FOUND to TRUE if # all listed variables are TRUE # ----------------------------------------------------- include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(gsoap DEFAULT_MSG GSOAP_LIBRARIES +find_package_handle_standard_args(gsoap DEFAULT_MSG GSOAP_LIBRARIES GSOAP_INCLUDE_DIR GSOAP_WSDL2H GSOAP_SOAPCPP2) mark_as_advanced(GSOAP_INCLUDE_DIR GSOAP_LIBRARIES GSOAP_WSDL2H GSOAP_SOAPCPP2) diff -Nru davix-0.6.6/CMakeLists.txt davix-0.6.7/CMakeLists.txt --- davix-0.6.6/CMakeLists.txt 2017-05-11 12:06:42.000000000 +0000 +++ davix-0.6.7/CMakeLists.txt 2017-11-07 13:08:40.000000000 +0000 @@ -29,7 +29,7 @@ set(OUTPUT_NAME_DAVIX "davix") set(VERSION_MAJOR 0) set(VERSION_MINOR 6) -set(VERSION_PATCH 6) +set(VERSION_PATCH 7) set(VERSION_STRING ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) set(VERSION_TAG "") @@ -79,7 +79,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX11_FLAG_ENABLE}") -include_directories( ${HTTPLIB_PKG_INCLUDE_DIRS} ${GLIB2_PKG_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/deps ${CMAKE_CURRENT_SOURCE_DIR}/deps/libneon/src/ ) +include_directories( ${HTTPLIB_PKG_INCLUDE_DIRS} ${GLIB2_PKG_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/deps ${CMAKE_CURRENT_SOURCE_DIR}/deps/libneon/src/ ${UUID_INCLUDE_DIRS} ) include_directories( ${CMAKE_SOURCE_DIR}/include/davix ) include_directories( ${CMAKE_SOURCE_DIR}/src/libs/) diff -Nru davix-0.6.6/debian/changelog davix-0.6.7/debian/changelog --- davix-0.6.6/debian/changelog 2018-02-07 11:35:23.000000000 +0000 +++ davix-0.6.7/debian/changelog 2018-02-22 12:57:34.000000000 +0000 @@ -1,14 +1,11 @@ -davix (0.6.6-1build2) bionic; urgency=high +davix (0.6.7-1) unstable; urgency=medium - * No change rebuild against openssl1.1. + * Update to version 0.6.7 + * Migrate to dbgsym packages + * Fix warnings about code examples that can not be parsed in documentation + * Remove .doctrees directory from documentation - -- Dimitri John Ledkov Wed, 07 Feb 2018 11:35:23 +0000 - -davix (0.6.6-1build1) artful; urgency=medium - - * Rebuild against new libgsoap-2.8.49. - - -- Gianfranco Costamagna Thu, 20 Jul 2017 08:30:26 +0200 + -- Mattias Ellert Thu, 22 Feb 2018 13:57:34 +0100 davix (0.6.6-1) unstable; urgency=medium diff -Nru davix-0.6.6/debian/control davix-0.6.7/debian/control --- davix-0.6.6/debian/control 2018-02-07 11:35:23.000000000 +0000 +++ davix-0.6.7/debian/control 2018-02-22 12:57:34.000000000 +0000 @@ -1,10 +1,11 @@ Source: davix Priority: optional -Maintainer: Ubuntu Developers -XSBC-Original-Maintainer: Mattias Ellert -Build-Depends: debhelper (>= 9), cmake, libxml2-dev, libssl-dev, gsoap, libgtest-dev, abi-compliance-checker, pkg-config, doxygen, python-sphinx, python-sphinx-rtd-theme, zlib1g-dev, uuid-dev -Standards-Version: 3.9.8 +Maintainer: Mattias Ellert +Build-Depends: debhelper (>= 9), cmake, libxml2-dev, libssl-dev, gsoap, libgtest-dev, abi-compliance-checker, pkg-config, doxygen, python3-sphinx, python3-sphinx-rtd-theme, zlib1g-dev, uuid-dev +Standards-Version: 4.1.3 Section: net +Vcs-Browser: https://salsa.debian.org/ellert/davix +Vcs-Git: https://salsa.debian.org/ellert/davix.git Homepage: http://dmc.web.cern.ch/projects/davix/home Package: davix @@ -44,23 +45,3 @@ Description: Documentation for davix Documentation and examples for davix. Davix is a toolkit designed for file operations with Http based protocols (WebDav, Amazon S3, ...). - -Package: davix-dbg -Section: debug -Priority: extra -Architecture: any -Multi-Arch: foreign -Depends: ${misc:Depends}, davix (= ${binary:Version}) -Description: Debug symbols for the davix tools - Debug symbols for the davix tools. Davix is a toolkit designed for - file operations with http based protocols (WebDav, Amazon S3, ...). - -Package: libdavix-dbg -Section: debug -Priority: extra -Architecture: any -Multi-Arch: same -Depends: ${misc:Depends}, libdavix0v5 (= ${binary:Version}) -Description: Debug symbols for the davix library - Debug symbols for the davix library. Davix is a toolkit designed for - file operations with http based protocols (WebDav, Amazon S3, ...). diff -Nru davix-0.6.6/debian/copyright davix-0.6.7/debian/copyright --- davix-0.6.6/debian/copyright 2017-05-16 09:50:20.000000000 +0000 +++ davix-0.6.7/debian/copyright 2018-02-22 12:57:34.000000000 +0000 @@ -1,6 +1,6 @@ -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: davix -Source: https://github.com/cern-it-sdc-id/davix/archive/R_0_6_6.tar.gz +Source: https://github.com/cern-it-sdc-id/davix/archive/R_0_6_7.tar.gz Files: * Copyright: 2013-2017 CERN @@ -182,7 +182,7 @@ network access and can therefore not be run as part of the package build. Files: debian/* -Copyright: 2013-2017 Mattias Ellert +Copyright: 2013-2018 Mattias Ellert License: LGPL-2.1+ Files: debian/missing-sources/modernizr.js diff -Nru davix-0.6.6/debian/davix-doc.lintian-overrides davix-0.6.7/debian/davix-doc.lintian-overrides --- davix-0.6.6/debian/davix-doc.lintian-overrides 2017-03-22 20:50:31.000000000 +0000 +++ davix-0.6.7/debian/davix-doc.lintian-overrides 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -# See /usr/share/doc/doxygen/README.jquery -embedded-javascript-library usr/share/doc/*/html/doxygen/jquery.js * diff -Nru davix-0.6.6/debian/patches/davix-straight-quotes-in-code-example.patch davix-0.6.7/debian/patches/davix-straight-quotes-in-code-example.patch --- davix-0.6.6/debian/patches/davix-straight-quotes-in-code-example.patch 1970-01-01 00:00:00.000000000 +0000 +++ davix-0.6.7/debian/patches/davix-straight-quotes-in-code-example.patch 2018-02-22 12:57:34.000000000 +0000 @@ -0,0 +1,38 @@ +From 7409a53dbb16b8460d92688f05274ad0703f6e56 Mon Sep 17 00:00:00 2001 +From: Mattias Ellert +Date: Thu, 22 Feb 2018 14:47:49 +0100 +Subject: [PATCH] Use straight quotes in code example + +--- + doc/sphinx/lib-examples.rst | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/doc/sphinx/lib-examples.rst b/doc/sphinx/lib-examples.rst +index 4c43bc9..b6d2b37 100644 +--- a/doc/sphinx/lib-examples.rst ++++ b/doc/sphinx/lib-examples.rst +@@ -688,18 +688,18 @@ Davix::DavixException + + .. code-block:: cpp + +- throw DavixException(“Where”, “What”, “This is what has happened...”); ++ throw DavixException("Where", "What", "This is what has happened..."); + + * Catch a ``DavixException`` + + .. code-block:: cpp + + TRY_DAVIX{ +- DavFile myDavCollection(c, Uri(“davs://example.org/doomed_to_fail”)); ++ DavFile myDavCollection(c, Uri("davs://example.org/doomed_to_fail")); + myDavCollection.deletion(NULL); + }CATCH_DAVIX(&err){ + std::cerr << err->getErrScope() << +- “ Error code: “ << err->getStatus() << ++ " Error code: " << err->getStatus() << + " Error: " << err->getErrMsg() << std::endl; + + // handle error or propagate +-- +2.14.3 + diff -Nru davix-0.6.6/debian/patches/series davix-0.6.7/debian/patches/series --- davix-0.6.6/debian/patches/series 2017-03-22 20:50:31.000000000 +0000 +++ davix-0.6.7/debian/patches/series 2018-02-22 12:57:34.000000000 +0000 @@ -1 +1,6 @@ +# Avoid some overlinking davix-linking.patch + +# Fix warnings about code examples that can not be parsed in documentation +# https://github.com/cern-it-sdc-id/davix/pull/22 +davix-straight-quotes-in-code-example.patch diff -Nru davix-0.6.6/debian/rules davix-0.6.7/debian/rules --- davix-0.6.6/debian/rules 2017-05-16 10:55:22.000000000 +0000 +++ davix-0.6.7/debian/rules 2018-02-22 12:57:34.000000000 +0000 @@ -34,6 +34,7 @@ rm -rf debian/tmp/usr/include/gtest rm debian/tmp/usr/lib/libgtest.a rm debian/tmp/usr/lib/libgtest_main.a + rm -rf debian/tmp/usr/share/doc/davix/html/.doctrees rm -rf debian/tmp/usr/share/doc/davix/html/_static/css ln -s /usr/share/sphinx_rtd_theme/static/css \ debian/tmp/usr/share/doc/davix/html/_static/css @@ -49,11 +50,11 @@ rm debian/tmp/usr/share/doc/davix/html/_static/underscore.js ln -s /usr/share/javascript/underscore/underscore.js \ debian/tmp/usr/share/doc/davix/html/_static/underscore.js - dh_install --fail-missing + dh_install + dh_missing --fail-missing override_dh_strip: - dh_strip -X/lib/ --dbg-package davix-dbg - dh_strip -X/bin/ --dbg-package libdavix-dbg + dh_strip --dbgsym-migration='davix-dbg (<< 0.6.7), libdavix-dbg (<< 0.6.7)' override_dh_auto_clean: rm -f deps/googletest/googletest diff -Nru davix-0.6.6/debian/source/lintian-overrides davix-0.6.7/debian/source/lintian-overrides --- davix-0.6.6/debian/source/lintian-overrides 2013-11-28 06:27:48.000000000 +0000 +++ davix-0.6.7/debian/source/lintian-overrides 2018-02-22 12:57:34.000000000 +0000 @@ -1,3 +1,2 @@ # The autotools files are not used - build uses cmake -davix source: outdated-autotools-helper-file deps/libneon/config.* - +davix source: autotools-pkg-config-macro-not-cross-compilation-safe deps/libneon/configure.in* diff -Nru davix-0.6.6/deps/libneon/src/ne_openssl.c davix-0.6.7/deps/libneon/src/ne_openssl.c --- davix-0.6.6/deps/libneon/src/ne_openssl.c 2017-05-11 12:06:42.000000000 +0000 +++ davix-0.6.7/deps/libneon/src/ne_openssl.c 2017-11-07 13:08:40.000000000 +0000 @@ -58,6 +58,7 @@ typedef const unsigned char ne_d2i_uchar; #endif +#include "time.h" #define NE_SSL_UNHANDLED (0x20) /* failure bit for unhandled case. */ @@ -165,7 +166,9 @@ * 'NE_SSL_VDATELEN'. */ static time_t asn1time_to_timet(const ASN1_TIME *atm) { - struct tm tm = {0}; + struct tm tm; + memset(&tm, 0, sizeof(struct tm)); + int i = atm->length; if (i < 10) @@ -478,11 +481,11 @@ #if OPENSSL_VERSION_NUMBER < 0x10100000L void X509_up_ref(X509 *x) { - x->references++; + CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509); } void EVP_PKEY_up_ref(EVP_PKEY *pkey) { - pkey->references++; + CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY); } #endif diff -Nru davix-0.6.6/deps/libneon/src/ne_request.c davix-0.6.7/deps/libneon/src/ne_request.c --- davix-0.6.6/deps/libneon/src/ne_request.c 2017-05-11 12:06:42.000000000 +0000 +++ davix-0.6.7/deps/libneon/src/ne_request.c 2017-11-07 13:08:40.000000000 +0000 @@ -535,7 +535,7 @@ void ne_set_request_flag(ne_request *req, ne_request_flag flag, int value) { - if (flag < NE_SESSFLAG_LAST) { + if (flag < NE_REQFLAG_LAST) { req->flags[flag] = value; } } diff -Nru davix-0.6.6/packaging/debian/changelog davix-0.6.7/packaging/debian/changelog --- davix-0.6.6/packaging/debian/changelog 2017-05-11 12:06:42.000000000 +0000 +++ davix-0.6.7/packaging/debian/changelog 2017-11-07 13:08:40.000000000 +0000 @@ -1,3 +1,15 @@ +davix (0.6.7-1) unstable; urgency=low + + * Update to version 0.6.7 + + -- Georgios Bitzes Tue, 07 Nov 2017 14:08:40 +0100 + +davix (0.6.7-1) unstable; urgency=low + + * Update to version 0.6.7 + + -- Georgios Bitzes Wed, 17 May 2017 09:46:22 +0200 + davix (0.6.6-1) unstable; urgency=low * Update to version 0.6.6 diff -Nru davix-0.6.6/packaging/rpm/specs/davix.spec davix-0.6.7/packaging/rpm/specs/davix.spec --- davix-0.6.6/packaging/rpm/specs/davix.spec 2017-05-11 12:06:42.000000000 +0000 +++ davix-0.6.7/packaging/rpm/specs/davix.spec 2017-11-07 13:08:40.000000000 +0000 @@ -2,7 +2,7 @@ %{!?_pkgdocdir: %global _pkgdocdir %{_docdir}/%{name}-%{version}} Name: davix -Version: 0.6.6 +Version: 0.6.7 Release: 1%{?dist} Summary: Toolkit for Http-based file management Group: Applications/Internet @@ -81,11 +81,13 @@ %build # setup a virtualenv with sphinx -#%if %{?fedora}%{!?fedora:0} >= 10 || %{?rhel}%{!?rhel:0} >= 7 -#virtualenv /tmp/sphinx-venv -#source /tmp/sphinx-venv/bin/activate -# pip install sphinx -#%endif +%if %{?fedora}%{!?fedora:0} >= 10 || %{?rhel}%{!?rhel:0} >= 7 +virtualenv /tmp/sphinx-venv +source /tmp/sphinx-venv/bin/activate + +pip install --upgrade pip +pip install sphinx +%endif %cmake \ -DDOC_INSTALL_DIR=%{_pkgdocdir} \ @@ -140,6 +142,12 @@ %changelog +* Tue Nov 07 2017 Georgios Bitzes - 0.6.7-1 + - davix 0.6.7 release, see RELEASE-NOTES for changes + +* Wed May 17 2017 Georgios Bitzes - 0.6.7-1 + - davix 0.6.7 release, see RELEASE-NOTES for changes + * Thu May 11 2017 Georgios Bitzes - 0.6.6-1 - davix 0.6.6 release, see RELEASE-NOTES for changes diff -Nru davix-0.6.6/packaging/rpm/specs/davix.spec.in davix-0.6.7/packaging/rpm/specs/davix.spec.in --- davix-0.6.6/packaging/rpm/specs/davix.spec.in 2017-05-11 12:06:42.000000000 +0000 +++ davix-0.6.7/packaging/rpm/specs/davix.spec.in 2017-11-07 13:08:40.000000000 +0000 @@ -81,11 +81,13 @@ %build # setup a virtualenv with sphinx -#%if %{?fedora}%{!?fedora:0} >= 10 || %{?rhel}%{!?rhel:0} >= 7 -#virtualenv /tmp/sphinx-venv -#source /tmp/sphinx-venv/bin/activate -# pip install sphinx -#%endif +%if %{?fedora}%{!?fedora:0} >= 10 || %{?rhel}%{!?rhel:0} >= 7 +virtualenv /tmp/sphinx-venv +source /tmp/sphinx-venv/bin/activate + +pip install --upgrade pip +pip install sphinx +%endif %cmake \ -DDOC_INSTALL_DIR=%{_pkgdocdir} \ @@ -140,6 +142,12 @@ %changelog +* Tue Nov 07 2017 Georgios Bitzes - 0.6.7-1 + - davix 0.6.7 release, see RELEASE-NOTES for changes + +* Wed May 17 2017 Georgios Bitzes - 0.6.7-1 + - davix 0.6.7 release, see RELEASE-NOTES for changes + * Thu May 11 2017 Georgios Bitzes - 0.6.6-1 - davix 0.6.6 release, see RELEASE-NOTES for changes diff -Nru davix-0.6.6/RELEASE-NOTES davix-0.6.7/RELEASE-NOTES --- davix-0.6.6/RELEASE-NOTES 2017-05-11 12:06:42.000000000 +0000 +++ davix-0.6.7/RELEASE-NOTES 2017-11-07 13:08:40.000000000 +0000 @@ -1,3 +1,12 @@ +Version - 0.6.7 +** Bug + * [DMC-950] - davix calculates invalid v4 s3 signature when using a non-default port + * [DMC-957] - davix appends an extra space with --header + * [DMC-961] - A neon session never retries after DNS lookup failure + * [DMC-969] - davix increments the refcount for OpenSSL structures in a non-atomic way + * [DMC-993] - Use-after-free in the davix cache +** Improvement + * [DMC-958] - Resume on xfer with metalinks creates file with a wrong filesize Version - 0.6.6 ** Bug diff -Nru davix-0.6.6/src/fileops/davix_reliability_ops.cpp davix-0.6.7/src/fileops/davix_reliability_ops.cpp --- davix-0.6.6/src/fileops/davix_reliability_ops.cpp 2017-05-11 12:06:42.000000000 +0000 +++ davix-0.6.7/src/fileops/davix_reliability_ops.cpp 2017-11-07 13:08:40.000000000 +0000 @@ -69,14 +69,18 @@ // get all replicas from Metalink chain.getReplicas(io_context, replicas); for(std::vector::iterator it = replicas.begin();it != replicas.end(); ++it){ + IOChainContext internal_context(io_context._context, it->getUri(), io_context._reqparams); + internal_context.fdHandler = io_context.fdHandler; + try{ - IOChainContext internal_context(io_context._context, it->getUri(), io_context._reqparams); return fun(internal_context); }catch(DavixException & replica_error){ DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_CHAIN, "Fail access to replica {}: {}", it->getUri(), replica_error.what()); }catch(...){ DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_CHAIN, "Fail access to replica: Unknown Error"); } + + io_context.fdHandler = internal_context.fdHandler; // check timeout again between two iterations io_context.checkTimeout(); } diff -Nru davix-0.6.6/src/fileops/httpiochain.hpp davix-0.6.7/src/fileops/httpiochain.hpp --- davix-0.6.6/src/fileops/httpiochain.hpp 2017-05-11 12:06:42.000000000 +0000 +++ davix-0.6.7/src/fileops/httpiochain.hpp 2017-11-07 13:08:40.000000000 +0000 @@ -38,6 +38,15 @@ }while(0) +// stores state for readToFd operations - necessary, so as not to write the same +// data again to an fd after a retry / metalink recovery. +struct FdHandler { + FdHandler() : fd(-1), bytes_written_to_fd(0) { } + + int fd; + dav_ssize_t bytes_written_to_fd; +}; + // parameter handler for any IO Chain operation struct IOChainContext{ @@ -68,6 +77,9 @@ // Operation parameter Chrono::TimePoint _end_time; + // Keep track of how many bytes we've written to an fd, so as to avoid + // writing the same bytes again in an event of retries / metalink recovery + FdHandler fdHandler; }; // Davix IO chain diff -Nru davix-0.6.6/src/fileops/iobuffmap.cpp davix-0.6.7/src/fileops/iobuffmap.cpp --- davix-0.6.6/src/fileops/iobuffmap.cpp 2017-05-11 12:06:42.000000000 +0000 +++ davix-0.6.7/src/fileops/iobuffmap.cpp 2017-11-07 13:08:40.000000000 +0000 @@ -210,17 +210,28 @@ return ret; } +#define SSTR(message) static_cast(std::ostringstream().flush() << message).str() dav_ssize_t HttpIO::readToFd(IOChainContext & iocontext, int fd, dav_size_t read_size){ DavixError * tmp_err=NULL; dav_ssize_t ret = -1; + if(iocontext.fdHandler.fd != fd) { + iocontext.fdHandler.fd = fd; + iocontext.fdHandler.bytes_written_to_fd = 0; + } + DAVIX_SCOPE_TRACE(DAVIX_LOG_CHAIN, fun_readToFd); DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, "request size {}", read_size); GetRequest req (iocontext._context, iocontext._uri, &tmp_err); if(!tmp_err){ RequestParams params(iocontext._reqparams); req.setParameters(iocontext._reqparams); + if(iocontext.fdHandler.bytes_written_to_fd > 0) { + DAVIX_SLOG(DAVIX_LOG_WARNING, DAVIX_LOG_CHAIN, "{} bytes were already written to fd before transfer failed; attempting to resume from that point on", iocontext.fdHandler.bytes_written_to_fd); + req.addHeaderField("Range", SSTR("bytes=" << iocontext.fdHandler.bytes_written_to_fd << "-")); + } + ret = req.beginRequest(&tmp_err); if(!tmp_err){ if(httpcodeIsValid(req.getRequestCode()) == false){ @@ -232,6 +243,9 @@ } } + if(ret > 0) { + iocontext.fdHandler.bytes_written_to_fd += ret; + } DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, "read size {}", ret); checkDavixError(&tmp_err); diff -Nru davix-0.6.6/src/libs/alibxx/containers/cache.hpp davix-0.6.7/src/libs/alibxx/containers/cache.hpp --- davix-0.6.6/src/libs/alibxx/containers/cache.hpp 2017-05-11 12:06:42.000000000 +0000 +++ davix-0.6.7/src/libs/alibxx/containers/cache.hpp 2017-11-07 13:08:40.000000000 +0000 @@ -87,10 +87,11 @@ shrPtr_type take( const Key & key){ std::lock_guard l(_m); typename Map::iterator it = map.find( key); - if(it == map.end()) - return shrPtr_type(); - map.erase(key); - return it->second; + if(it == map.end()) return shrPtr_type(); + + shrPtr_type ret = it->second; + map.erase(it); + return ret; } /// diff -Nru davix-0.6.6/src/neon/neonrequest.cpp davix-0.6.7/src/neon/neonrequest.cpp --- davix-0.6.6/src/neon/neonrequest.cpp 2017-05-11 12:06:42.000000000 +0000 +++ davix-0.6.7/src/neon/neonrequest.cpp 2017-11-07 13:08:40.000000000 +0000 @@ -428,7 +428,7 @@ return startRequest(err); } - if( status == NE_CONNECT && requestCleanup() ){ + if( (status == NE_CONNECT || status == NE_LOOKUP) && requestCleanup() ){ DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_HTTP, "Impossible to connect to {}, retry from origin {}", _current->getString(), _orig->getString()); _number_try++; return startRequest(err); @@ -743,7 +743,8 @@ }while(write_len >0); } - return (ret>= 0)?total:ret; + if(total > 0) return total; + return ret; } diff -Nru davix-0.6.6/src/params/davixrequestparams.cpp davix-0.6.7/src/params/davixrequestparams.cpp --- davix-0.6.6/src/params/davixrequestparams.cpp 2017-05-11 12:06:42.000000000 +0000 +++ davix-0.6.7/src/params/davixrequestparams.cpp 2017-11-07 13:08:40.000000000 +0000 @@ -33,8 +33,10 @@ const char * default_agent = "libdavix/" DAVIX_VERSION; volatile int state_value =0; +std::mutex state_value_mtx; inline int get_requeste_uid(){ + std::lock_guard lock(state_value_mtx); state_value +=1; return state_value; } diff -Nru davix-0.6.6/src/request/httprequest.cpp davix-0.6.7/src/request/httprequest.cpp --- davix-0.6.6/src/request/httprequest.cpp 2017-05-11 12:06:42.000000000 +0000 +++ davix-0.6.7/src/request/httprequest.cpp 2017-11-07 13:08:40.000000000 +0000 @@ -42,7 +42,7 @@ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_HTTP, "Create HttpRequest for {}", uri.getString()); if(uri.getStatus() != StatusCode::OK){ - DavixError::setupError(err, davix_scope_http_request(), StatusCode::UriParsingError, fmt::format(" {} is not not a valid HTTP or Webdav URL", uri)); + DavixError::setupError(err, davix_scope_http_request(), StatusCode::UriParsingError, fmt::format(" {} is not a valid HTTP or Webdav URL", uri)); } } @@ -51,7 +51,7 @@ Uri uri(url); d_ptr= new NEONRequest(*this, context, uri); if(uri.getStatus() != StatusCode::OK){ - DavixError::setupError(err, davix_scope_http_request(), StatusCode::UriParsingError, fmt::format(" {} is not not a valid HTTP or Webdav URL", uri)); + DavixError::setupError(err, davix_scope_http_request(), StatusCode::UriParsingError, fmt::format(" {} is not a valid HTTP or Webdav URL", uri)); } } diff -Nru davix-0.6.6/src/tools/davix_tool_get_main.cpp davix-0.6.7/src/tools/davix_tool_get_main.cpp --- davix-0.6.6/src/tools/davix_tool_get_main.cpp 2017-05-11 12:06:42.000000000 +0000 +++ davix-0.6.7/src/tools/davix_tool_get_main.cpp 2017-11-07 13:08:40.000000000 +0000 @@ -278,7 +278,7 @@ opts.help_msg = help_msg(argv[0]); if( (retcode= Tool::parse_davix_get_options(argc, argv, opts, &tmp_err)) ==0 - && (retcode = Tool::configureAuth(opts)) == 0){ + && (retcode = Tool::configureAuth(opts)) == 0 && checkProtocolSanity(opts, opts.vec_arg[0], &tmp_err)){ retcode = preGetCheck(opts, &tmp_err); } Tool::errorPrint(&tmp_err); diff -Nru davix-0.6.6/src/tools/davix_tool_ls_main.cpp davix-0.6.7/src/tools/davix_tool_ls_main.cpp --- davix-0.6.6/src/tools/davix_tool_ls_main.cpp 2017-05-11 12:06:42.000000000 +0000 +++ davix-0.6.7/src/tools/davix_tool_ls_main.cpp 2017-11-07 13:08:40.000000000 +0000 @@ -233,35 +233,30 @@ if( (retcode= Tool::parse_davix_ls_options(argc, argv, opts, &tmp_err)) ==0){ if( (retcode = Tool::configureAuth(opts)) == 0){ - // if recursive and S3 - if(opts.params.getRecursiveMode() && (opts.vec_arg[0].compare(0,2,"s3") ==0)){ - // don't need to use -r switch for S3, just set listing mode to SemiHierarchical and do a normal listing - opts.params.setS3ListingMode(S3ListingMode::SemiHierarchical); - // unfortunately s3 defaults max-keys to 1000 and doesn't provide a way to disable the cap, set to large number - opts.params.setS3MaxKey(999999999); - - retcode = listing(opts, fstream, &tmp_err); - } - else if(opts.params.getRecursiveMode()){ // dav recursive listing - retcode = recursiveListing(opts, fstream, &tmp_err); - } - else{ // normal listing - retcode = listing(opts, fstream, &tmp_err); - } - // just a single file - if(retcode < 0 && tmp_err->getStatus() == StatusCode::IsNotADirectory){ - DavixError::clearError(&tmp_err); - retcode = get_info(opts, fstream, &tmp_err); + if(checkProtocolSanity(opts, opts.vec_arg[0], &tmp_err)) { + // if recursive and S3 + if(opts.params.getRecursiveMode() && (opts.vec_arg[0].compare(0,2,"s3") ==0)){ + // don't need to use -r switch for S3, just set listing mode to SemiHierarchical and do a normal listing + opts.params.setS3ListingMode(S3ListingMode::SemiHierarchical); + // unfortunately s3 defaults max-keys to 1000 and doesn't provide a way to disable the cap, set to large number + opts.params.setS3MaxKey(999999999); + + retcode = listing(opts, fstream, &tmp_err); + } + else if(opts.params.getRecursiveMode()){ // dav recursive listing + retcode = recursiveListing(opts, fstream, &tmp_err); + } + else{ // normal listing + retcode = listing(opts, fstream, &tmp_err); + } + // just a single file + if(retcode < 0 && tmp_err->getStatus() == StatusCode::IsNotADirectory){ + DavixError::clearError(&tmp_err); + retcode = get_info(opts, fstream, &tmp_err); + } } } } Tool::errorPrint(&tmp_err); return retcode; } - - - - - - - diff -Nru davix-0.6.6/src/tools/davix_tool_mkcol_main.cpp davix-0.6.7/src/tools/davix_tool_mkcol_main.cpp --- davix-0.6.6/src/tools/davix_tool_mkcol_main.cpp 2017-05-11 12:06:42.000000000 +0000 +++ davix-0.6.7/src/tools/davix_tool_mkcol_main.cpp 2017-11-07 13:08:40.000000000 +0000 @@ -59,18 +59,13 @@ if( (retcode= Tool::parse_davix_options(argc, argv, opts, &tmp_err)) ==0){ Context c; if( (retcode = Tool::configureAuth(opts)) == 0){ - configureContext(c, opts); - DavFile f(c,opts.vec_arg[0]); - f.makeCollection(&opts.params, &tmp_err); + if(checkProtocolSanity(opts, opts.vec_arg[0], &tmp_err)) { + configureContext(c, opts); + DavFile f(c,opts.vec_arg[0]); + f.makeCollection(&opts.params, &tmp_err); + } } } Tool::errorPrint(&tmp_err); return retcode; } - - - - - - - diff -Nru davix-0.6.6/src/tools/davix_tool_mkdir_main.cpp davix-0.6.7/src/tools/davix_tool_mkdir_main.cpp --- davix-0.6.6/src/tools/davix_tool_mkdir_main.cpp 2017-05-11 12:06:42.000000000 +0000 +++ davix-0.6.7/src/tools/davix_tool_mkdir_main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,72 +0,0 @@ -/* - * This File is part of Davix, The IO library for HTTP based protocols - * Copyright (C) CERN 2013 - * Author: Adrien Devresse - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * -*/ - -#include -#include -#include -#include -#include - - -// @author : Devresse Adrien -// main file for davix mkdir cmd line tool - - -using namespace Davix; -using namespace std; - -#define READ_BLOCK_SIZE 4096 - - -const std::string scope_main = "Davix::Tools::davix"; - - - -static std::string help_msg(const std::string & cmd_path){ - return Tool::get_base_description_options() + - Tool::get_common_options(); -} - - - -int main(int argc, char** argv){ - int retcode=-1; - Tool::OptParams opts; - DavixError* tmp_err=NULL; - opts.help_msg = help_msg(argv[0]); - - if( (retcode= Tool::parse_davix_options(argc, argv, opts, &tmp_err)) ==0){ - Context c; - if( (retcode = Tool::configureAuth(opts, &tmp_err)) == 0){ - DavFile f(c,opts.vec_arg[0]); - f.makeCollection(&opts.params, &tmp_err); - } - } - Tool::errorPrint(&tmp_err); - return retcode; -} - - - - - - - diff -Nru davix-0.6.6/src/tools/davix_tool_params.cpp davix-0.6.7/src/tools/davix_tool_params.cpp --- davix-0.6.6/src/tools/davix_tool_params.cpp 2017-05-11 12:06:42.000000000 +0000 +++ davix-0.6.7/src/tools/davix_tool_params.cpp 2017-11-07 13:08:40.000000000 +0000 @@ -173,7 +173,12 @@ DavixError::setupError(err, scope_params, StatusCode::InvalidArgument, " Invalid header field argument"); return -1; } - p.params.addHeader(arg.substr(0,pos), arg.substr(pos+1)); + + dav_size_t value_pos = pos+1; + if(arg.size() > pos+1 && arg[pos+1] == ' ') { + value_pos = pos+2; + } + p.params.addHeader(arg.substr(0,pos), arg.substr(value_pos)); return 0; } diff -Nru davix-0.6.6/src/tools/davix_tool_put_main.cpp davix-0.6.7/src/tools/davix_tool_put_main.cpp --- davix-0.6.6/src/tools/davix_tool_put_main.cpp 2017-05-11 12:06:42.000000000 +0000 +++ davix-0.6.7/src/tools/davix_tool_put_main.cpp 2017-11-07 13:08:40.000000000 +0000 @@ -206,7 +206,7 @@ opts.help_msg = help_msg(argv[0]); if(( (retcode = Tool::parse_davix_put_options(argc, argv, opts, &tmp_err)) == 0) - && ((retcode = Tool::configureAuth(opts)) == 0)){ + && ((retcode = Tool::configureAuth(opts)) == 0) && checkProtocolSanity(opts, opts.vec_arg[1], &tmp_err)){ retcode = prePutCheck(opts, &tmp_err); } Tool::errorPrint(&tmp_err); diff -Nru davix-0.6.6/src/tools/davix_tool_rm_main.cpp davix-0.6.7/src/tools/davix_tool_rm_main.cpp --- davix-0.6.6/src/tools/davix_tool_rm_main.cpp 2017-05-11 12:06:42.000000000 +0000 +++ davix-0.6.7/src/tools/davix_tool_rm_main.cpp 2017-11-07 13:08:40.000000000 +0000 @@ -197,38 +197,32 @@ if( (retcode= Tool::parse_davix_rm_options(argc, argv, opts, &tmp_err)) ==0){ if( (retcode = Tool::configureAuth(opts)) == 0){ - if ( opts.params.getAzureKey().size() != 0) { - opts.params.setProtocol(RequestProtocol::Azure); - }else if (opts.vec_arg[0].compare(0,4,"http") ==0){ - opts.params.setProtocol(RequestProtocol::Http); - }else if( opts.vec_arg[0].compare(0,2,"s3") ==0){ - opts.params.setProtocol(RequestProtocol::AwsS3); - }else if ( opts.vec_arg[0].compare(0, 3,"dav") ==0){ - opts.params.setProtocol(RequestProtocol::Webdav); + if(checkProtocolSanity(opts, opts.vec_arg[0], &tmp_err)) { + if ( opts.params.getAzureKey().size() != 0) { + opts.params.setProtocol(RequestProtocol::Azure); + }else if (opts.vec_arg[0].compare(0,4,"http") ==0){ + opts.params.setProtocol(RequestProtocol::Http); + }else if( opts.vec_arg[0].compare(0,2,"s3") ==0){ + opts.params.setProtocol(RequestProtocol::AwsS3); + }else if ( opts.vec_arg[0].compare(0, 3,"dav") ==0){ + opts.params.setProtocol(RequestProtocol::Webdav); + } + + // only s3 needs special treatment, WebDAV delete on collection already works + if((opts.params.getProtocol() == RequestProtocol::AwsS3) && (opts.params.getRecursiveMode())){ + preDeleteCheck(opts, &tmp_err); + } + else{ + Context c; + configureContext(c, opts); + + DavFile f(c,opts.vec_arg[0]); + f.deletion(&opts.params, &tmp_err); + } + if(tmp_err != NULL) retcode = 1; } - - // only s3 needs special treatment, WebDAV delete on collection already works - if((opts.params.getProtocol() == RequestProtocol::AwsS3) && (opts.params.getRecursiveMode())){ - preDeleteCheck(opts, &tmp_err); - } - else{ - Context c; - configureContext(c, opts); - - DavFile f(c,opts.vec_arg[0]); - f.deletion(&opts.params, &tmp_err); - } - - if(tmp_err != NULL) retcode = 1; } } Tool::errorPrint(&tmp_err); return retcode; } - - - - - - - diff -Nru davix-0.6.6/src/tools/davix_tool_util.cpp davix-0.6.7/src/tools/davix_tool_util.cpp --- davix-0.6.6/src/tools/davix_tool_util.cpp 2017-05-11 12:06:42.000000000 +0000 +++ davix-0.6.7/src/tools/davix_tool_util.cpp 2017-11-07 13:08:40.000000000 +0000 @@ -118,6 +118,26 @@ return 0; } +bool startswith(const std::string &str, const std::string &prefix) { + if(prefix.size() > str.size()) return false; + + for(size_t i = 0; i < prefix.size(); i++) { + if(str[i] != prefix[i]) return false; + } + return true; +} + +const std::string scope_params = "Davix::Tools::Params"; +bool checkProtocolSanity(OptParams &opts, const std::string &url, DavixError **err) { + if(!opts.aws_auth.first.empty()) { + if(!startswith(url, "s3://") && !startswith(url, "s3s://") && !startswith(url, "http://") && !startswith(url, "https://")) { + DavixError::setupError(err, scope_params, StatusCode::InvalidArgument, fmt::format(" S3 credentials cannot be used with the protocol given in this URL : {}", url)); + return false; + } + } + return true; +} + static void printHookHeaders(char symbol, const std::string & first_msg, const std::string & start_line){ std::string req_header(start_line); diff -Nru davix-0.6.6/src/tools/davix_tool_util.hpp davix-0.6.7/src/tools/davix_tool_util.hpp --- davix-0.6.6/src/tools/davix_tool_util.hpp 2017-05-11 12:06:42.000000000 +0000 +++ davix-0.6.7/src/tools/davix_tool_util.hpp 2017-11-07 13:08:40.000000000 +0000 @@ -37,6 +37,8 @@ int configureAuth(OptParams & opts); +bool checkProtocolSanity(OptParams &opts, const std::string &url, DavixError **err); + void configureContext(Context &context, const OptParams & opts); void errorPrint(DavixError ** err); diff -Nru davix-0.6.6/src/utils/davix_s3_utils.cpp davix-0.6.7/src/utils/davix_s3_utils.cpp --- davix-0.6.6/src/utils/davix_s3_utils.cpp 2017-05-11 12:06:42.000000000 +0000 +++ davix-0.6.7/src/utils/davix_s3_utils.cpp 2017-11-07 13:08:40.000000000 +0000 @@ -255,6 +255,7 @@ } } +#define SSTR(message) static_cast(std::ostringstream().flush() << message).str() Uri signURIv4(const RequestParams & params, const std::string & method, const Uri & url, const HeaderVec headers, const time_t expirationTime) { // references @@ -262,9 +263,19 @@ // http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_S3, "Using S3 v4 signature authentication"); + // using a non-default port? + bool defaultPort; + std::string portPart; + + defaultPort = (url.getPort() == 0); + defaultPort |= (url.getPort() == 80 && (url.getProtocol() == "http" || url.getProtocol() == "s3")); + defaultPort |= (url.getPort() == 443 && (url.getProtocol() == "https" || url.getProtocol() == "s3s")); + + if(!defaultPort) portPart = SSTR(":" << url.getPort()); + // calculate canonical headers HeaderVec can_headers = getAmzCanonHeaders_vec(headers); - can_headers.push_back(HeaderLine("Host", url.getHost())); + can_headers.push_back(HeaderLine("Host", SSTR(url.getHost() << portPart))); std::sort(can_headers.begin(), can_headers.end()); std::ostringstream can_headers_str; for(HeaderVec::iterator it = can_headers.begin(); it != can_headers.end(); it++) { diff -Nru davix-0.6.6/src/utils/davixuri.cpp davix-0.6.7/src/utils/davixuri.cpp --- davix-0.6.6/src/utils/davixuri.cpp 2017-05-11 12:06:42.000000000 +0000 +++ davix-0.6.7/src/utils/davixuri.cpp 2017-11-07 13:08:40.000000000 +0000 @@ -33,7 +33,7 @@ int davix_uri_parse(const std::string & uri_str, UriPrivate & res); int davix_uri_cmp(const UriPrivate &u1, const UriPrivate &u2); -std::string davix_path_escape(const std::string & str); +std::string davix_path_escape(const std::string & str, bool escapeSlashes); std::string davix_path_unescape(const std::string & str); struct UriPrivate{ @@ -78,10 +78,15 @@ void addParam(const std::string & key, const std::string & value, std::string & target) { if(target.size() == 0) { - target = key + "=" + value; + target = key; + target.append("="); + target.append(value); } else { - target += "&" + key + "=" + value; + target.append("&"); + target.append(key); + target.append("="); + target.append(value); } _update_string(); } @@ -330,7 +335,7 @@ std::string Uri::escapeString(const std::string & str){ - return davix_path_escape(str); + return davix_path_escape(str, false); } std::string Uri::unescapeString(const std::string & str){ @@ -338,21 +343,7 @@ } std::string Uri::queryParamEscape(const std::string & str) { - std::string tmp = escapeString(str); - - // replace all '/' with '%2F' - std::stringstream ss; - for(size_t i = 0; i < tmp.size(); i++) { - if(tmp[i] == '/') { - ss << "%2F"; - } - else { - ss << tmp[i]; - } - } - - return ss.str(); - + return davix_path_escape(str, true); } // Determine whether this is a URL, and if so, URI-escape the right part. @@ -588,9 +579,11 @@ /* No colon; => p = path-abempty */ } else if (p + 1 != pa) { /* => p = colon */ - res.port = atoi(p + 1); - if( res.port == 0) - res.port = UINT_MAX; + if(*p == ':') { + res.port = atoi(p + 1); + if( res.port == 0) + res.port = UINT_MAX; + } } res.host.assign(s, p - s); @@ -696,16 +689,18 @@ /* CH must be an unsigned char; evaluates to 1 if CH should be * percent-encoded. */ -#define path_escape_ch(ch) (uri_lookup(ch) & URI_ESCAPE) +inline bool path_escape_ch(const char ch, bool escapeSlashes) { + return (uri_lookup(ch) & URI_ESCAPE) || (escapeSlashes && ch == '/'); +} -std::string davix_path_escape(const std::string & str) +std::string davix_path_escape(const std::string & str, bool escapeSlashes) { const unsigned char *pnt, *path= (const unsigned char*)(str.c_str()); char *p; size_t count = 0; for (pnt = (const unsigned char *)path; *pnt != '\0'; pnt++) { - count += path_escape_ch(*pnt); + count += path_escape_ch(*pnt, escapeSlashes); } if (count == 0) { @@ -715,7 +710,7 @@ char buffer[str.size() + 2 * count + 1]; p = buffer; for (pnt = (const unsigned char *)path; *pnt != '\0'; pnt++) { - if (path_escape_ch(*pnt)) { + if (path_escape_ch(*pnt, escapeSlashes)) { /* Escape it - % */ sprintf(p, "%%%02X", (unsigned char) *pnt); p += 3; @@ -729,7 +724,6 @@ #undef path_escape_ch - std::ostream& operator<< (std::ostream& stream, const Davix::Uri & _u){ stream << _u.getString(); return stream; diff -Nru davix-0.6.6/test/unit/parser/parser_test.cpp davix-0.6.7/test/unit/parser/parser_test.cpp --- davix-0.6.6/test/unit/parser/parser_test.cpp 2017-05-11 12:06:42.000000000 +0000 +++ davix-0.6.7/test/unit/parser/parser_test.cpp 2017-11-07 13:08:40.000000000 +0000 @@ -246,3 +246,51 @@ ASSERT_STREQ("http://datagrid.lbl.gov/testdata/R/test01.data/blabla/test", res.getString().c_str()); } + +TEST(UriTests, addParamWithSlashes) { + Davix::Uri u("http://datagrid.lbl.gov/testdata/R/test01.data"); + ASSERT_EQ(u.getString(), "http://datagrid.lbl.gov/testdata/R/test01.data"); + + u.addQueryParam("test1", "test2"); + u.addQueryParam("test1/with/slashes", "aaa/aaa"); + u.addQueryParam("test1!with?evil*chars", "aaa/aaa"); + + ASSERT_EQ(u.getString(), "http://datagrid.lbl.gov/testdata/R/test01.data?test1=test2&test1%2Fwith%2Fslashes=aaa%2Faaa&test1%21with%3Fevil%2Achars=aaa%2Faaa"); + + std::string hugeKey, hugeVal; + hugeKey.resize(8000); + hugeVal.resize(8000); + + for(uint64_t i = 0; i < 8000; i++) { + hugeKey[i] = '/'; + hugeVal[i] = '/'; + } + + u.addQueryParam(hugeKey, hugeVal); +} + +TEST(UriTests, ips) { + Davix::Uri u("http://192.168.1.1/testdata/R/test01.data"); + ASSERT_EQ(u.getStatus(), StatusCode::OK); + ASSERT_EQ(u.getString(), "http://192.168.1.1/testdata/R/test01.data"); + ASSERT_EQ(u.getPort(), 0); + ASSERT_EQ(u.getHost(), "192.168.1.1"); + + u = Davix::Uri("http://192.168.1.1:123/testdata/R/test01.data"); + ASSERT_EQ(u.getStatus(), StatusCode::OK); + ASSERT_EQ(u.getString(), "http://192.168.1.1:123/testdata/R/test01.data"); + ASSERT_EQ(u.getPort(), 123); + ASSERT_EQ(u.getHost(), "192.168.1.1"); + + u = Davix::Uri("http://[2001:1458:301:a8ae::100:23]:443/testdata/R/test01.data"); + ASSERT_EQ(u.getStatus(), StatusCode::OK); + ASSERT_EQ(u.getString(), "http://[2001:1458:301:a8ae::100:23]:443/testdata/R/test01.data"); + ASSERT_EQ(u.getPort(), 443); + ASSERT_EQ(u.getHost(), "[2001:1458:301:a8ae::100:23]"); + + u = Davix::Uri("http://[2001:1458:301:a8ae::100:23]/testdata/R/test01.data"); + ASSERT_EQ(u.getStatus(), StatusCode::OK); + ASSERT_EQ(u.getString(), "http://[2001:1458:301:a8ae::100:23]/testdata/R/test01.data"); + ASSERT_EQ(u.getPort(), 0); + ASSERT_EQ(u.getHost(), "[2001:1458:301:a8ae::100:23]"); +}