From 4353dd3ae727c077af2c87ce996291238f939fd8 Mon Sep 17 00:00:00 2001 From: mjansen Date: Fri, 27 Mar 2026 19:19:31 +0100 Subject: [PATCH] [FEATURE] ilServer: Add diagnostics for potential image issues --- .../ilias/services/transformation/FO2PDF.java | 77 ++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/components/ILIAS/WebServices/RPC/lib/src/main/java/de/ilias/services/transformation/FO2PDF.java b/components/ILIAS/WebServices/RPC/lib/src/main/java/de/ilias/services/transformation/FO2PDF.java index 59354c6ed94f..c03e69739ea8 100755 --- a/components/ILIAS/WebServices/RPC/lib/src/main/java/de/ilias/services/transformation/FO2PDF.java +++ b/components/ILIAS/WebServices/RPC/lib/src/main/java/de/ilias/services/transformation/FO2PDF.java @@ -26,17 +26,21 @@ import org.apache.fop.apps.*; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.xml.sax.SAXException; import javax.xml.transform.*; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.stream.StreamSource; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URI; +import java.net.URLConnection; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.util.List; +import java.util.Objects; public class FO2PDF { @@ -89,6 +93,29 @@ public void transform() // foUserAgent.setTargetResolution(300); ByteArrayOutputStream out = new ByteArrayOutputStream(); + foUserAgent.getEventBroadcaster().addEventListener(event -> { + try { + logger.warn( + "FOP EVENT: group={}, id={}", + event.getEventGroupID(), + event.getEventID() + ); + + event.getParams().forEach((k, v) -> { + logger.warn(" {} = {}", k, v); + if (Objects.equals(k, "uri") && v instanceof String uriString) { + try { + logUriFopDiagnostics(new URI(uriString)); + } catch (URISyntaxException | IOException e) { + logger.error("Error while probing URI", e); + } + } + }); + } catch (Exception e) { + logger.error("Error while logging FOP event", e); + } + }); + Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out); // Setup JAXP using identity transformer @@ -148,6 +175,54 @@ public void setPdf(byte[] ba) { this.pdfByteArray = ba; } + private void logUriFopDiagnostics(URI uri) throws IOException { + logger.warn("Trying to load URI which could not be processed by FOP: {}", uri); + + URLConnection connection = uri.toURL().openConnection(); + if (!(connection instanceof HttpURLConnection conn)) { + logger.warn("URI does not point to an HTTP resource: {}", uri); + return; + } + conn.setInstanceFollowRedirects(false); + conn.setConnectTimeout(15000); + conn.setReadTimeout(15000); + + try { + int code = conn.getResponseCode(); + logger.warn("HTTP status: {}", code); + + conn.getHeaderFields().forEach((key, values) -> { + logger.warn("Header: {} = {}", key, values); + }); + + InputStream stream; + if (code >= 200 && code < 300) { + stream = conn.getInputStream(); + } else { + stream = conn.getErrorStream(); + if (stream == null) { + logger.warn("HTTP error {} with no body", code); + return; + } + } + + try (stream) { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + byte[] data = new byte[4096]; + int n; + while ((n = stream.read(data)) != -1) { + buffer.write(data, 0, n); + } + String bodyPreview = buffer.toString(StandardCharsets.UTF_8); + logger.warn( + "Response body (first 1000 chars):\n{}", + bodyPreview.substring(0, Math.min(1000, bodyPreview.length())) + ); + } + } finally { + conn.disconnect(); + } + } private InputStream getFoInputStream() { return new ByteArrayInputStream(getFoString().getBytes(StandardCharsets.UTF_8));