[cpp-sp] 02/02: CPPSP-13 Move remoting tracing to different output sink

Codeberg noreply at shibboleth.net
Mon Aug 24 19:01:00 UTC 2026


This is an automated email from the git hooks/post-receive script.

codeberg pushed a commit to branch main
in repository cpp-sp.

View the commit online:
https://codeberg.org/Shibboleth/cpp-sp/commit/ae9d9e857fae894c6bbffd29b3bd9643672058f3

commit ae9d9e857fae894c6bbffd29b3bd9643672058f3
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Mon Aug 24 19:37:15 2026 +0100

    CPPSP-13 Move remoting tracing to different output sink
    
    https://shibboleth.atlassian.net/browse/CPPSP-13
    
    Use Win32 to create and write single log file.
---
 shibsp/remoting/impl/WinHTTPRemotingService.cpp | 67 ++++++++++++++++++++++++-
 1 file changed, 66 insertions(+), 1 deletion(-)

diff --git a/shibsp/remoting/impl/WinHTTPRemotingService.cpp b/shibsp/remoting/impl/WinHTTPRemotingService.cpp
index 8c32f434..5c444c0e 100644
--- a/shibsp/remoting/impl/WinHTTPRemotingService.cpp
+++ b/shibsp/remoting/impl/WinHTTPRemotingService.cpp
@@ -31,6 +31,7 @@
 #include "remoting/impl/AbstractHTTPRemotingService.h"
 #include "util/BoostPropertySet.h"
 #include "util/Misc.h"
+#include "util/Date.h"
 
 #include <stdexcept>
 #include <boost/algorithm/string.hpp>
@@ -82,6 +83,11 @@ namespace {
         set<string> m_tls12CipherSet;
         set<string> m_tls13CipherSet;
         string getCertName(PCCERT_CONTEXT certContext) const;
+        void writeTraceHeader(string message) const;
+        HANDLE m_traceHandle;
+        bool isTracing() const {
+            return m_traceHandle != INVALID_HANDLE_VALUE && m_traceHandle != nullptr;
+        }
     };
 
     class HINTERNETJanitor
@@ -246,7 +252,7 @@ WinHTTPRemotingService::WinHTTPRemotingService(ptree& pt)
     AbstractHTTPRemotingService(pt),
     m_log(Category::getInstance(SHIBSP_LOGCAT ".RemotingService")),
     m_secure(false), m_caChainEngine(nullptr), m_caStore(nullptr),
-    m_init(false)
+    m_init(false), m_traceHandle(INVALID_HANDLE_VALUE)
 {
     if (getUserAgent() == nullptr) {
         string useragent = string(PACKAGE_NAME) + '/' + PACKAGE_VERSION + '/' + "WINHTTP";
@@ -363,6 +369,21 @@ WinHTTPRemotingService::WinHTTPRemotingService(ptree& pt)
         throw runtime_error("WinHHHTP failed to initialize: Could not connect");
     }
 
+    if (!getTraceFileBase().empty()) {
+        m_traceHandle = CreateFileA(getTraceFileBase().c_str(),
+                                  GENERIC_WRITE,
+                                  FILE_SHARE_READ,
+                                  NULL,
+                                  CREATE_ALWAYS,
+                                  FILE_ATTRIBUTE_NORMAL,
+                                  NULL);
+        if (!isTracing()) {
+             m_log.error("Could not open tracing file %s : %d", getTraceFileBase().c_str(), GetLastError());
+        } else {
+            writeTraceHeader("DDIF Tracing Initialized");
+        }
+    }
+
     m_log.info("WinHTTP RemotingService installed for agent ID (%s), baseURL (%s)", getAgentID(), getBaseURL());
 }
 
@@ -379,11 +400,17 @@ WinHTTPRemotingService::~WinHTTPRemotingService()
 
     if (m_caStore)
         CertCloseStore(m_caStore, 0);
+
+    if (isTracing()) {
+        CloseHandle(m_traceHandle);
+    }
 }
 
 void WinHTTPRemotingService::send(const char* path, istream& input, ostream& output) const
 {
     wstring wPath(m_baseURLPath + utf8ToUtf16(path));
+    const string startCallMessage("----- AGENT CALL START -----\r\n");
+    const string endCallMessage("----- AGENT CALL END -----\r\n");
 
     HINTERNET request = WinHttpOpenRequest(
                     m_connection, 
@@ -461,6 +488,10 @@ void WinHTTPRemotingService::send(const char* path, istream& input, ostream& out
         throw RemotingException("Send failed");
     }
 
+    if (isTracing() && !WriteFile(m_traceHandle, startCallMessage.c_str(), static_cast<DWORD>(startCallMessage.length()), NULL, NULL)) {
+            m_log.error("Could not write message to trace file %d", GetLastError());
+    }
+
     //
     // As per CPPSP=73, chunked IO has regressed (when tested against the test harness)
     //
@@ -473,6 +504,7 @@ void WinHTTPRemotingService::send(const char* path, istream& input, ostream& out
             m_log.crit("Send. Failed to send request to %s : %d", path, GetLastError());
             throw RemotingException("Send failed");
         }
+        writeTraceHeader("Chunked DDF request");
 
         DWORD written;
         while (input) {
@@ -502,6 +534,11 @@ void WinHTTPRemotingService::send(const char* path, istream& input, ostream& out
                 m_log.crit("Send. Failed to send chunk trailer to %s : %d", path, GetLastError());
                 throw RemotingException("Send failed");
             }
+            if (isTracing()) {
+                if (!WriteFile(m_traceHandle, buf, transferSize, NULL, NULL) || !WriteFile(m_traceHandle, "\r\n", 2, NULL, NULL)) {
+                    m_log.error("Could not write chunk to trace file %d", GetLastError());
+                }
+            }
         }
         //
         // And when all the data is gone we say that the last chunk is zero long
@@ -528,11 +565,18 @@ void WinHTTPRemotingService::send(const char* path, istream& input, ostream& out
             input.read(buf, sizeof(buf));
             msg.append(buf, input.gcount());
         }
+        writeTraceHeader("Unchunked DDF request");
         m_log.debug("Sending %d bytes to %s", msg.length(), path);
         if (!WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, const_cast<char*>(msg.c_str()), static_cast<DWORD>(msg.length()), static_cast<DWORD>(msg.length()), 0)) {
             m_log.crit("Send. Failed to send request to %s : %d", path, GetLastError());
             throw RemotingException("Send failed");
         }
+        if (isTracing()) {
+            if (!WriteFile(m_traceHandle, msg.c_str(), static_cast<DWORD>(msg.length()), NULL, NULL) ||
+                !WriteFile(m_traceHandle, "\r\n", 2, NULL, NULL)) {
+                m_log.error("Could not write data to trace file %d", GetLastError());
+            }
+        }
     }
 
     if (!WinHttpReceiveResponse(request, NULL)) {
@@ -563,6 +607,7 @@ void WinHTTPRemotingService::send(const char* path, istream& input, ostream& out
 
     DWORD bufferSize = 0;
     char *buffer = nullptr;
+    writeTraceHeader("DDF response");
     while (true)  {
 
         DWORD bytesAvailable = 0;
@@ -592,8 +637,17 @@ void WinHTTPRemotingService::send(const char* path, istream& input, ostream& out
             throw RemotingException("Send failed");
         }
         m_log.debug("%d bytes read from %s", bytesRead, path);
+        if (isTracing()) {
+            if (!WriteFile(m_traceHandle, buffer, bytesRead, NULL, NULL) || !WriteFile(m_traceHandle, "\r\n", 2, NULL, NULL)) {
+                m_log.error("Could not write message to trace file %d", GetLastError());
+            }
+        }
         output.write(buffer, bytesRead);
     }
+    if (isTracing() && !WriteFile(m_traceHandle, endCallMessage.c_str(), static_cast<DWORD>(endCallMessage.length()), NULL, NULL)) {
+        m_log.error("Could not write message to trace file %d", GetLastError());
+    }
+
     if (buffer) {
         delete[] buffer;
     }
@@ -738,3 +792,14 @@ string WinHTTPRemotingService::getCertName(PCCERT_CONTEXT certContext) const {
     return string(buffer);
 
 }
+
+void WinHTTPRemotingService::writeTraceHeader(string message) const {
+
+    if (!isTracing())
+        return;
+    stringstream sink;
+    sink << message << date::format("  %FT%TZ", date::floor<chrono::milliseconds>(chrono::system_clock::now())) << "\r\n";
+    string msg(sink.str());
+    if (!WriteFile(m_traceHandle, msg.c_str(), static_cast<DWORD>(msg.length()), NULL, NULL))
+        m_log.error("Could not write to travce file %d", GetLastError());
+}

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list