Compare commits
2 Commits
| Author | SHA256 | Date | |
|---|---|---|---|
| 3ecc938a2b | |||
| 8ce94b6e22 |
@@ -1,191 +0,0 @@
|
||||
From 057b4fa188b6b8afdb34cc6b7d103c78e73c1001 Mon Sep 17 00:00:00 2001
|
||||
From: Mihai Patrascoiu <mihai.patrascoiu@cern.ch>
|
||||
Date: Wed, 31 Jul 2024 13:52:55 +0200
|
||||
Subject: [PATCH] DMC-1418: Implement loop protection in the
|
||||
"RedirectionResolver::redirectionResolve()" function
|
||||
|
||||
The function has been extended to also pass along a set of visited URIs. If in the redirection resolve chain process we encounter a previously visited URI, then we stop and return this URI. This mechanism will avoid falling into infinite redirection resolve loops
|
||||
---
|
||||
src/core/RedirectionResolver.cpp | 28 +++++++++++----
|
||||
src/core/RedirectionResolver.hpp | 11 ++++--
|
||||
test/unit/session-factory.cpp | 60 ++++++++++++++++++++++----------
|
||||
3 files changed, 72 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/src/core/RedirectionResolver.cpp b/src/core/RedirectionResolver.cpp
|
||||
index 71361888..405bb002 100644
|
||||
--- a/src/core/RedirectionResolver.cpp
|
||||
+++ b/src/core/RedirectionResolver.cpp
|
||||
@@ -31,7 +31,7 @@ static const std::pair<std::string, std::string> makeKey(const std::string & met
|
||||
if(mymethod == "HEAD")
|
||||
mymethod = "GET";
|
||||
|
||||
- return std::make_pair(origin.getString(), mymethod);
|
||||
+ return {origin.getString(), mymethod};
|
||||
}
|
||||
|
||||
RedirectionResolver::RedirectionResolver(bool act) : active(act), redirCache(256) {
|
||||
@@ -50,13 +50,29 @@ void RedirectionResolver::addRedirection(const std::string & method, const Uri &
|
||||
|
||||
// try to find cached redirection, resolve a full chain
|
||||
std::shared_ptr<Uri> RedirectionResolver::redirectionResolve(const std::string & method, const Uri & origin) {
|
||||
- std::shared_ptr<Uri> res = resolveSingle(method, origin);
|
||||
- if(res.get() != NULL) {
|
||||
- std::shared_ptr<Uri> res_rec = redirectionResolve(method, *res);
|
||||
- if(res_rec.get() != NULL) {
|
||||
- return res_rec;
|
||||
+ std::set<redirectionKey> visited;
|
||||
+ return redirectionResolve(method, origin, visited);
|
||||
+}
|
||||
+
|
||||
+// private function of redirectionResolve (contains set of visited URIs to avoid redirection loop)
|
||||
+std::shared_ptr<Uri> RedirectionResolver::redirectionResolve(const std::string& method, const Uri& origin, std::set<redirectionKey>& visited) {
|
||||
+ auto res = resolveSingle(method, origin);
|
||||
+
|
||||
+ if (res != nullptr) {
|
||||
+ // Identified a loop, stop at the element before the resolved redirection
|
||||
+ if (visited.find(makeKey(method, *res)) != visited.end()) {
|
||||
+ return std::make_shared<Uri>(origin);
|
||||
+ } else {
|
||||
+ // We haven't seen this resolved redirection before
|
||||
+ visited.insert(makeKey(method, origin));
|
||||
+ auto res_rec = redirectionResolve(method, *res, visited);
|
||||
+
|
||||
+ if (res_rec != nullptr) {
|
||||
+ return res_rec;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
+
|
||||
return res;
|
||||
}
|
||||
|
||||
diff --git a/src/core/RedirectionResolver.hpp b/src/core/RedirectionResolver.hpp
|
||||
index 881c8080..3a903490 100644
|
||||
--- a/src/core/RedirectionResolver.hpp
|
||||
+++ b/src/core/RedirectionResolver.hpp
|
||||
@@ -23,6 +23,7 @@
|
||||
#define DAVIX_CORE_REDIRECTION_RESOLVER_HPP
|
||||
|
||||
#include <map>
|
||||
+#include <set>
|
||||
#include <mutex>
|
||||
#include <utils/davix_uri.hpp>
|
||||
#include <memory>
|
||||
@@ -48,10 +49,16 @@ class RedirectionResolver {
|
||||
void redirectionClean(const Uri & origin);
|
||||
|
||||
private:
|
||||
+ using redirectionKey = std::pair<std::string, std::string>;
|
||||
+
|
||||
+ ///< Boolean guarding the redirection cache
|
||||
bool active;
|
||||
|
||||
- // redirection pool
|
||||
- Davix::Cache<std::pair<std::string, std::string>, Uri> redirCache;
|
||||
+ ///< Redirection pool
|
||||
+ Davix::Cache<redirectionKey, Uri> redirCache;
|
||||
+
|
||||
+ // resolve a full redirection chain (with redirection loop protection in-place)
|
||||
+ std::shared_ptr<Uri> redirectionResolve(const std::string& method, const Uri& origin, std::set<redirectionKey>& visited);
|
||||
|
||||
// resolve a single redirection chunk
|
||||
std::shared_ptr<Uri> resolveSingle(const std::string & method, const Uri & origin);
|
||||
diff --git a/test/unit/session-factory.cpp b/test/unit/session-factory.cpp
|
||||
index 2b4562df..dcc87cf2 100644
|
||||
--- a/test/unit/session-factory.cpp
|
||||
+++ b/test/unit/session-factory.cpp
|
||||
@@ -5,16 +5,15 @@
|
||||
|
||||
using namespace Davix;
|
||||
|
||||
-TEST(testRedirectCache, testCacheSimple){
|
||||
+TEST(testRedirectCache, testCacheSimple) {
|
||||
davix_set_log_level(DAVIX_LOG_ALL);
|
||||
|
||||
-
|
||||
- std::shared_ptr<Uri> dest(new Uri("http://sffsdfsd.com/dsffds/fsdfsdsdf"));
|
||||
- std::shared_ptr<Uri> dest2(new Uri("http://sffsdfsd.com/dsffds/fsdfsdsdf"));
|
||||
+ std::shared_ptr<Uri> dest(new Uri("https://sffsdfsd.com/dsffds/fsdfsdsdf"));
|
||||
+ std::shared_ptr<Uri> dest2(new Uri("https://sffsdfsd.com/dsffds/fsdfsdsdf"));
|
||||
Uri u("http://higgs.boson/is/watchingus");
|
||||
|
||||
Uri u_sec("https://higgs.boson/is/watchingus");
|
||||
- Uri u_port("http://higgs.boson:8668/is/watchingus");
|
||||
+ Uri u_port("https://higgs.boson:8668/is/watchingus");
|
||||
|
||||
RedirectionResolver f(true);
|
||||
f.addRedirection("GET", u, dest);
|
||||
@@ -33,17 +32,14 @@ TEST(testRedirectCache, testCacheSimple){
|
||||
ASSERT_TRUE(f.redirectionResolve("GET", u_port) == dest2);
|
||||
}
|
||||
|
||||
-
|
||||
-
|
||||
-TEST(testRedirectCache, testCacheChainRedirection){
|
||||
+TEST(testRedirectCache, testCacheChainRedirection) {
|
||||
davix_set_log_level(DAVIX_LOG_ALL);
|
||||
|
||||
Uri u("http://higgs.boson/is/watchingus");
|
||||
-
|
||||
- std::shared_ptr<Uri> url1(new Uri("http://sffsdfsd.com/dsffds/fsdfsdsdf"));
|
||||
- std::shared_ptr<Uri> url2(new Uri("http://server2.com/dsffds/sfdfdsfsdfdsfdsfds"));
|
||||
- std::shared_ptr<Uri> url3(new Uri("http://server2.com:8080/dsffds/sfdfdsfsdfdsfdsfds"));
|
||||
- std::shared_ptr<Uri> url4(new Uri("http://server3.com/dsffds/fsdaaaaa"));
|
||||
+ std::shared_ptr<Uri> url1(new Uri("https://sffsdfsd.com/dsffds/fsdfsdsdf"));
|
||||
+ std::shared_ptr<Uri> url2(new Uri("https://server2.com/dsffds/sfdfdsfsdfdsfdsfds"));
|
||||
+ std::shared_ptr<Uri> url3(new Uri("https://server2.com:8080/dsffds/sfdfdsfsdfdsfdsfds"));
|
||||
+ std::shared_ptr<Uri> url4(new Uri("https://server3.com/dsffds/fsdaaaaa"));
|
||||
|
||||
RedirectionResolver f(true);
|
||||
f.addRedirection("GET", u, url1);
|
||||
@@ -60,14 +56,12 @@ TEST(testRedirectCache, testCacheChainRedirection){
|
||||
ASSERT_TRUE(f.redirectionResolve("GET", *url4).get() == NULL);
|
||||
}
|
||||
|
||||
-
|
||||
-TEST(testRedirectCache, test_GET_HEAD){
|
||||
+TEST(testRedirectCache, test_GET_HEAD) {
|
||||
davix_set_log_level(DAVIX_LOG_ALL);
|
||||
|
||||
- Uri u("http://higgs.boson/is/watchingus");
|
||||
-
|
||||
- std::shared_ptr<Uri> url1(new Uri("http://sffsdfsd.com/dsffds/fsdfsdsdf"));
|
||||
- std::shared_ptr<Uri> url2(new Uri("http://server2.com/dsffds/sfdfdsfsdfdsfdsfds"));
|
||||
+ Uri u("https://higgs.boson/is/watchingus");
|
||||
+ std::shared_ptr<Uri> url1(new Uri("https://sffsdfsd.com/dsffds/fsdfsdsdf"));
|
||||
+ std::shared_ptr<Uri> url2(new Uri("https://server2.com/dsffds/sfdfdsfsdfdsfdsfds"));
|
||||
|
||||
RedirectionResolver f(true);
|
||||
f.addRedirection("GET", u, url1);
|
||||
@@ -88,3 +82,31 @@ TEST(testRedirectCache, test_GET_HEAD){
|
||||
ASSERT_TRUE(f.redirectionResolve("GET", u) == url1);
|
||||
ASSERT_TRUE(f.redirectionResolve("HEAD", u) == url1);
|
||||
}
|
||||
+
|
||||
+TEST(testRedirectCache, noRedirectLoop) {
|
||||
+ davix_set_log_level(DAVIX_LOG_ALL);
|
||||
+
|
||||
+ std::shared_ptr<Uri> start(new Uri("https://redirection.start/file"));
|
||||
+ std::shared_ptr<Uri> middle(new Uri("https://redirection.middle/file"));
|
||||
+ std::shared_ptr<Uri> end(new Uri("https://redirection.end/loop"));
|
||||
+
|
||||
+ RedirectionResolver f(true);
|
||||
+ f.addRedirection("GET", *start, middle);
|
||||
+ f.addRedirection("GET", *middle, start);
|
||||
+ ASSERT_TRUE(*(f.redirectionResolve("GET", *start)) == *middle);
|
||||
+ ASSERT_TRUE(*(f.redirectionResolve("GET", *middle)) == *start);
|
||||
+
|
||||
+ // Cleaning one item from a loop deletes the full loop
|
||||
+ f.redirectionClean("GET", *middle);
|
||||
+ ASSERT_TRUE(f.redirectionResolve("GET", *start) == NULL);
|
||||
+
|
||||
+ f.addRedirection("GET", *start, middle);
|
||||
+ f.addRedirection("GET", *middle, end);
|
||||
+ f.addRedirection("GET", *end, start);
|
||||
+ ASSERT_TRUE(*(f.redirectionResolve("GET", *start)) == *end);
|
||||
+ ASSERT_TRUE(*(f.redirectionResolve("GET", *middle)) == *start);
|
||||
+ ASSERT_TRUE(*(f.redirectionResolve("GET", *end)) == *middle);
|
||||
+
|
||||
+ f.redirectionClean("GET", *end);
|
||||
+ ASSERT_TRUE(f.redirectionResolve("GET", *start) == NULL);
|
||||
+}
|
||||
3
davix-0.8.10.tar.gz
Normal file
3
davix-0.8.10.tar.gz
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:66aa9adadee6ff2bae14caba731597ba7a7cd158763d9d80a9cfe395afc17403
|
||||
size 6100049
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:78c24e14edd7e4e560392d67147ec8658c2aa0d3640415bdf6bc513afcf695e6
|
||||
size 7376826
|
||||
@@ -1,3 +1,38 @@
|
||||
-------------------------------------------------------------------
|
||||
Wed Apr 23 15:28:50 UTC 2025 - Atri Bhattacharya <badshah400@gmail.com>
|
||||
|
||||
- Update to version 0.8.10:
|
||||
* [gh#cern-fts/davix#137] - Davix 0.8.8 is not thread safe.
|
||||
- Changes from version 0.8.9:
|
||||
- Davix PerformanceMarkers are not propagated upwards for short
|
||||
HTTP-TPC transfers.
|
||||
- Changes from version 0.8.8:
|
||||
* Bug fixes
|
||||
- Davix redirection cache stuck in redirect loops.
|
||||
- [gh#cern-fts/davix#120] - Out of Date RapidJSON dependency
|
||||
causing compile failure.
|
||||
- [gh#cern-fts/davix#122] - S3 listing ignores "IsTruncated =
|
||||
true" property.
|
||||
- [gh#cern-fts/davix#126] - Crash on badly formed davix-cp
|
||||
command.
|
||||
- [gh#cern-fts/davix#129] - Remove non-compiling assignment
|
||||
operator.
|
||||
- [gh#cern-fts/davix#130] - compiler error in
|
||||
rapidjson/document.h.
|
||||
- [gh#cern-fts/davix#131] - Segmentation fault with long
|
||||
Authorization header.
|
||||
* Improvements
|
||||
- Davix error messages should print backend library used.
|
||||
- Remove bundled "googletest" from Davix.
|
||||
- Improve error handling when failing to read GCloud
|
||||
credential file.
|
||||
- [gh#cern-fts/davix#125] - Allow forcing of bundled
|
||||
rapidjson.
|
||||
- Drop 057b4fa188b6b8afdb34cc6b7d103c78e73c1001.patch:
|
||||
incorporated upstream.
|
||||
- Add BuildRequires: cmake(GTest) now needed to build and run
|
||||
tests.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Sat Sep 28 23:24:35 UTC 2024 - Atri Bhattacharya <badshah400@gmail.com>
|
||||
|
||||
|
||||
18
davix.spec
18
davix.spec
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# spec file for package davix
|
||||
#
|
||||
# Copyright (c) 2024 SUSE LLC
|
||||
# Copyright (c) 2025 SUSE LLC
|
||||
#
|
||||
# All modifications and additions to the file contributed by third parties
|
||||
# remain the property of their copyright owners, unless otherwise agreed
|
||||
@@ -19,22 +19,21 @@
|
||||
%define shlib lib%{name}0
|
||||
%define v_maj 0
|
||||
%define v_min 8
|
||||
%define v_pat 7
|
||||
%define v_pat 10
|
||||
Name: davix
|
||||
Version: 0.8.7
|
||||
Version: 0.8.10
|
||||
Release: 0
|
||||
Summary: File management over HTTP-based protocols
|
||||
License: LGPL-2.1-or-later
|
||||
Group: Productivity/Networking/Web/Utilities
|
||||
URL: https://davix.web.cern.ch/davix/docs/devel
|
||||
Source: https://github.com/cern-fts/davix/releases/download/R_%{v_maj}_%{v_min}_%{v_pat}/davix-%{version}.tar.gz
|
||||
# PATCH-FIX-UPSTREAM
|
||||
Patch0: https://github.com/cern-fts/davix/commit/057b4fa188b6b8afdb34cc6b7d103c78e73c1001.patch
|
||||
BuildRequires: cmake >= 2.6
|
||||
BuildRequires: cmake >= 3.0
|
||||
BuildRequires: gcc-c++
|
||||
BuildRequires: git
|
||||
BuildRequires: pkgconfig
|
||||
BuildRequires: python3
|
||||
BuildRequires: cmake(GTest)
|
||||
BuildRequires: pkgconfig(RapidJSON)
|
||||
BuildRequires: pkgconfig(gsoapssl++)
|
||||
BuildRequires: pkgconfig(libcurl)
|
||||
@@ -76,7 +75,9 @@ applications using davix.
|
||||
%build
|
||||
%cmake \
|
||||
-DEMBEDDED_LIBCURL=FALSE \
|
||||
-DENABLE_THIRD_PARTY_COPY:BOOL=TRUE
|
||||
-DENABLE_THIRD_PARTY_COPY:BOOL=TRUE \
|
||||
-DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
|
||||
%{nil}
|
||||
%cmake_build
|
||||
|
||||
%install
|
||||
@@ -88,8 +89,7 @@ rm -fr %{buildroot}%{_datadir}/doc/davix
|
||||
%check
|
||||
%ctest
|
||||
|
||||
%post -n %{shlib} -p /sbin/ldconfig
|
||||
%postun -n %{shlib} -p /sbin/ldconfig
|
||||
%ldconfig_scriptlets -n %{shlib}
|
||||
|
||||
%files
|
||||
%doc README.md RELEASE-NOTES.md
|
||||
|
||||
Reference in New Issue
Block a user