From 6367080a4315402bddf79179a29aa6d075915d85 Mon Sep 17 00:00:00 2001
From: "Alexander A. Klimov" <alexander.klimov@icinga.com>
Date: Mon, 26 Apr 2021 18:13:15 +0200
Subject: [PATCH] Support Boost v1.74

---
 01-boost174.patch |  25 ++++++++++
 02-boost174.patch |  24 +++++++++
 03-boost174.patch | 125 ++++++++++++++++++++++++++++++++++++++++++++++
 04-boost174.patch |  54 ++++++++++++++++++++
 icinga2.spec      |  11 ++++
 5 files changed, 239 insertions(+)
 create mode 100644 01-boost174.patch
 create mode 100644 02-boost174.patch
 create mode 100644 03-boost174.patch
 create mode 100644 04-boost174.patch

diff --git a/01-boost174.patch b/01-boost174.patch
new file mode 100644
index 0000000..1a6b2a1
--- /dev/null
+++ b/01-boost174.patch
@@ -0,0 +1,25 @@
+commit c30bae2994f1e5f33f6da51eb96d423e9bf0f75c (origin/pull/8184)
+Author: Louis Sautier <sautier.louis@gmail.com>
+Date:   Thu Aug 20 18:25:48 2020 +0200
+
+    Fix ‘fs::copy_option’ has not been declared with boost 1.74.0
+    
+    It was deprecated in
+    https://github.com/boostorg/filesystem/commit/f199152b7df036ff1606c85e4ea1b28edfeda6cc
+
+diff --git lib/base/utility.cpp lib/base/utility.cpp
+index 1add7616c..d8e6f20b0 100644
+--- lib/base/utility.cpp
++++ lib/base/utility.cpp
+@@ -725,7 +725,11 @@ void Utility::CopyFile(const String& source, const String& target)
+ {
+ 	namespace fs = boost::filesystem;
+ 
++#if BOOST_VERSION >= 107400
++	fs::copy_file(fs::path(source.Begin(), source.End()), fs::path(target.Begin(), target.End()), fs::copy_options::overwrite_existing);
++#else /* BOOST_VERSION */
+ 	fs::copy_file(fs::path(source.Begin(), source.End()), fs::path(target.Begin(), target.End()), fs::copy_option::overwrite_if_exists);
++#endif /* BOOST_VERSION */
+ }
+ 
+ /*
diff --git a/02-boost174.patch b/02-boost174.patch
new file mode 100644
index 0000000..189a256
--- /dev/null
+++ b/02-boost174.patch
@@ -0,0 +1,24 @@
+commit 7da65ce23e89212980da94f3804f38b907cd135f (HEAD)
+Author: Alexander A. Klimov <alexander.klimov@icinga.com>
+Date:   Mon Dec 14 15:59:56 2020 +0100
+
+    Define BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT
+    
+    ... to enable compiling with Boost v1.74.
+    
+    refs #8185
+
+diff --git CMakeLists.txt CMakeLists.txt
+index 046f23cf2..46e765415 100644
+--- CMakeLists.txt
++++ CMakeLists.txt
+@@ -172,6 +172,9 @@ add_definitions(-DBOOST_COROUTINES_NO_DEPRECATION_WARNING)
+ 
+ add_definitions(-DBOOST_FILESYSTEM_NO_DEPRECATED)
+ 
++# Required for Boost v1.74+
++add_definitions(-DBOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
++
+ link_directories(${Boost_LIBRARY_DIRS})
+ include_directories(${Boost_INCLUDE_DIRS})
+ 
diff --git a/03-boost174.patch b/03-boost174.patch
new file mode 100644
index 0000000..76903ac
--- /dev/null
+++ b/03-boost174.patch
@@ -0,0 +1,125 @@
+commit e1c9bcf17a9962d34f2a0d4c8389b1de2e6a915b
+Author: Julian Brost <julian.brost@icinga.com>
+Date:   Tue Dec 22 14:32:56 2020 +0100
+
+    Use content_length method for setting the Content-Length header
+    
+    Boost.Beast changed the signature of the previously used generic `set`
+    method so that it no longer accepts integer types, however there is
+    alreay a more specific method for setting the Content-Length header, so
+    use this one instead.
+
+diff --git lib/perfdata/elasticsearchwriter.cpp lib/perfdata/elasticsearchwriter.cpp
+index 6870198e4..9ab277f20 100644
+--- lib/perfdata/elasticsearchwriter.cpp
++++ lib/perfdata/elasticsearchwriter.cpp
+@@ -494,7 +494,7 @@ void ElasticsearchWriter::SendRequest(const String& body)
+ 		request.set(http::field::authorization, "Basic " + Base64::Encode(username + ":" + password));
+ 
+ 	request.body() = body;
+-	request.set(http::field::content_length, request.body().size());
++	request.content_length(request.body().size());
+ 
+ 	/* Don't log the request body to debug log, this is already done above. */
+ 	Log(LogDebug, "ElasticsearchWriter")
+diff --git lib/perfdata/influxdbwriter.cpp lib/perfdata/influxdbwriter.cpp
+index 4692b8b5d..508fcff64 100644
+--- lib/perfdata/influxdbwriter.cpp
++++ lib/perfdata/influxdbwriter.cpp
+@@ -505,7 +505,7 @@ void InfluxdbWriter::Flush()
+ 	request.set(http::field::host, url->GetHost() + ":" + url->GetPort());
+ 
+ 	request.body() = body;
+-	request.set(http::field::content_length, request.body().size());
++	request.content_length(request.body().size());
+ 
+ 	try {
+ 		if (stream.first) {
+diff --git lib/remote/configfileshandler.cpp lib/remote/configfileshandler.cpp
+index d714f4d86..6013d9722 100644
+--- lib/remote/configfileshandler.cpp
++++ lib/remote/configfileshandler.cpp
+@@ -84,7 +84,7 @@ bool ConfigFilesHandler::HandleRequest(
+ 		response.result(http::status::ok);
+ 		response.set(http::field::content_type, "application/octet-stream");
+ 		response.body() = content;
+-		response.set(http::field::content_length, response.body().size());
++		response.content_length(response.body().size());
+ 	} catch (const std::exception& ex) {
+ 		HttpUtility::SendJsonError(response, params, 500, "Could not read file.",
+ 			DiagnosticInformation(ex));
+diff --git lib/remote/httpserverconnection.cpp lib/remote/httpserverconnection.cpp
+index 9c8a50a64..6c7f7b4b0 100644
+--- lib/remote/httpserverconnection.cpp
++++ lib/remote/httpserverconnection.cpp
+@@ -186,7 +186,7 @@ bool EnsureValidHeaders(
+ 		} else {
+ 			response.set(http::field::content_type, "text/html");
+ 			response.body() = String("<h1>Bad Request</h1><p><pre>") + errorMsg + "</pre></p>";
+-			response.set(http::field::content_length, response.body().size());
++			response.content_length(response.body().size());
+ 		}
+ 
+ 		response.set(http::field::connection, "close");
+@@ -259,7 +259,7 @@ bool HandleAccessControl(
+ 					response.set(http::field::access_control_allow_methods, "GET, POST, PUT, DELETE");
+ 					response.set(http::field::access_control_allow_headers, "Authorization, X-HTTP-Method-Override");
+ 					response.body() = "Preflight OK";
+-					response.set(http::field::content_length, response.body().size());
++					response.content_length(response.body().size());
+ 					response.set(http::field::connection, "close");
+ 
+ 					boost::system::error_code ec;
+@@ -290,7 +290,7 @@ bool EnsureAcceptHeader(
+ 		response.result(http::status::bad_request);
+ 		response.set(http::field::content_type, "text/html");
+ 		response.body() = "<h1>Accept header is missing or not set to 'application/json'.</h1>";
+-		response.set(http::field::content_length, response.body().size());
++		response.content_length(response.body().size());
+ 		response.set(http::field::connection, "close");
+ 
+ 		boost::system::error_code ec;
+@@ -331,7 +331,7 @@ bool EnsureAuthenticatedUser(
+ 		} else {
+ 			response.set(http::field::content_type, "text/html");
+ 			response.body() = "<h1>Unauthorized. Please check your user credentials.</h1>";
+-			response.set(http::field::content_length, response.body().size());
++			response.content_length(response.body().size());
+ 		}
+ 
+ 		boost::system::error_code ec;
+@@ -423,7 +423,7 @@ bool EnsureValidBody(
+ 		} else {
+ 			response.set(http::field::content_type, "text/html");
+ 			response.body() = String("<h1>Bad Request</h1><p><pre>") + ec.message() + "</pre></p>";
+-			response.set(http::field::content_length, response.body().size());
++			response.content_length(response.body().size());
+ 		}
+ 
+ 		response.set(http::field::connection, "close");
+diff --git lib/remote/httputility.cpp lib/remote/httputility.cpp
+index 91902ba50..a2142e5d8 100644
+--- lib/remote/httputility.cpp
++++ lib/remote/httputility.cpp
+@@ -58,7 +58,7 @@ void HttpUtility::SendJsonBody(boost::beast::http::response<boost::beast::http::
+ 
+ 	response.set(http::field::content_type, "application/json");
+ 	response.body() = JsonEncode(val, params && GetLastParameter(params, "pretty"));
+-	response.set(http::field::content_length, response.body().size());
++	response.content_length(response.body().size());
+ }
+ 
+ void HttpUtility::SendJsonError(boost::beast::http::response<boost::beast::http::string_body>& response,
+diff --git lib/remote/infohandler.cpp lib/remote/infohandler.cpp
+index 18c18c0e0..80ebba77b 100644
+--- lib/remote/infohandler.cpp
++++ lib/remote/infohandler.cpp
+@@ -92,7 +92,7 @@ bool InfoHandler::HandleRequest(
+ 
+ 		body += R"(<p>More information about API requests is available in the <a href="https://icinga.com/docs/icinga2/latest/" target="_blank">documentation</a>.</p></html>)";
+ 		response.body() = body;
+-		response.set(http::field::content_length, response.body().size());
++		response.content_length(response.body().size());
+ 	}
+ 
+ 	return true;
diff --git a/04-boost174.patch b/04-boost174.patch
new file mode 100644
index 0000000..88a392e
--- /dev/null
+++ b/04-boost174.patch
@@ -0,0 +1,54 @@
+commit 41a8011560c16c969e66c0701e1c0f69f7883d3d
+Author: Julian Brost <julian.brost@icinga.com>
+Date:   Tue Dec 22 14:36:48 2020 +0100
+
+    Provide a conversion function from icinga::String to boost::string_view
+    
+    Boost.Beast changed the signature of
+    boost::beast::http::basic_fields::set in version 1.74 so that no longer
+    allows passing an icinga::String instance as value. This adds a
+    conversion function so that it works again.
+
+diff --git lib/base/string.cpp lib/base/string.cpp
+index c4617e357..eec5b8372 100644
+--- lib/base/string.cpp
++++ lib/base/string.cpp
+@@ -127,6 +127,18 @@ String::operator const std::string&() const
+ 	return m_Data;
+ }
+ 
++/**
++ * Conversion function to boost::string_view.
++ *
++ * This allows using String as the value for HTTP headers in boost::beast::http::basic_fields::set.
++ *
++ * @return A boost::string_view representing this string.
++ */
++String::operator boost::string_view() const
++{
++	return boost::string_view(m_Data);
++}
++
+ const char *String::CStr() const
+ {
+ 	return m_Data.c_str();
+diff --git lib/base/string.hpp lib/base/string.hpp
+index e9799e7eb..b9290eeee 100644
+--- lib/base/string.hpp
++++ lib/base/string.hpp
+@@ -6,6 +6,7 @@
+ #include "base/i2-base.hpp"
+ #include "base/object.hpp"
+ #include <boost/range/iterator.hpp>
++#include <boost/utility/string_view.hpp>
+ #include <string>
+ #include <iosfwd>
+ 
+@@ -71,6 +72,7 @@ public:
+ 	bool operator<(const String& rhs) const;
+ 
+ 	operator const std::string&() const;
++	operator boost::string_view() const;
+ 
+ 	const char *CStr() const;
+ 
diff --git a/icinga2.spec b/icinga2.spec
index d222f65..5674518 100644
--- a/icinga2.spec
+++ b/icinga2.spec
@@ -102,6 +102,11 @@ Release:        %{revision}%{?dist}
 Url:            https://www.icinga.com/
 Source:         https://github.com/Icinga/%{name}/archive/v%{version}%{?src_version_suffix}.tar.gz
 
+Patch0:         01-boost174.patch
+Patch1:         02-boost174.patch
+Patch2:         03-boost174.patch
+Patch3:         04-boost174.patch
+
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 Requires:       %{name}-bin = %{version}-%{release}
 Requires:       %{name}-common = %{version}-%{release}
@@ -335,6 +340,12 @@ Provides Nano syntax highlighting for icinga2.
 
 %prep
 %setup -q -n %{name}-%{version}%{?src_version_suffix}
+
+%patch0
+%patch1
+%patch2
+%patch3
+
 # use absolute shebang instead of env on SUSE distributions
 %if "%{_vendor}" == "suse"
 find . -type f -name '*.sh' -exec sed -i -e 's|\/usr\/bin\/env bash|\/bin\/bash|g' {} \;
-- 
GitLab