From d004d6d43d548d968090eb741059fe9c4b37b003 Mon Sep 17 00:00:00 2001
From: Pavol Loffay
Date: Thu, 18 Feb 2021 19:07:05 +0100
Subject: [PATCH] Capture servlet request bodies explicitly (#270)
Signed-off-by: Pavol Loffay
---
.../servlet/v3_0/nowrapping/Utils.java | 21 ++++++++++++---
...ervlet30NoWrappingInstrumentationTest.java | 14 ++++++++++
.../servlet/v3_0/nowrapping/TestServlets.java | 26 +++++++++++++++++++
3 files changed, 57 insertions(+), 4 deletions(-)
diff --git a/instrumentation/servlet/servlet-3.0-no-wrapping/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/servlet/v3_0/nowrapping/Utils.java b/instrumentation/servlet/servlet-3.0-no-wrapping/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/servlet/v3_0/nowrapping/Utils.java
index f102c4f60..1a0101092 100644
--- a/instrumentation/servlet/servlet-3.0-no-wrapping/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/servlet/v3_0/nowrapping/Utils.java
+++ b/instrumentation/servlet/servlet-3.0-no-wrapping/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/servlet/v3_0/nowrapping/Utils.java
@@ -96,11 +96,24 @@ public static void resetRequestBodyBuffers(
requestContextStore.put(httpServletRequest, null);
if (requestStreamReaderHolder.getAssociatedObject() instanceof ServletInputStream) {
- streamContextStore.put(
- (ServletInputStream) requestStreamReaderHolder.getAssociatedObject(), null);
+ ServletInputStream servletInputStream =
+ (ServletInputStream) requestStreamReaderHolder.getAssociatedObject();
+ ByteBufferSpanPair byteBufferSpanPair = streamContextStore.get(servletInputStream);
+ if (byteBufferSpanPair != null) {
+ // capture body explicitly e.g. Jackson does not call ServletInputStream$read() until -1 is
+ // returned
+ // it does not even call ServletInputStream#available()
+ byteBufferSpanPair.captureBody(HypertraceSemanticAttributes.HTTP_REQUEST_BODY);
+ streamContextStore.put(servletInputStream, null);
+ }
} else if (requestStreamReaderHolder.getAssociatedObject() instanceof BufferedReader) {
- bufferedReaderContextStore.put(
- (BufferedReader) requestStreamReaderHolder.getAssociatedObject(), null);
+ BufferedReader bufferedReader =
+ (BufferedReader) requestStreamReaderHolder.getAssociatedObject();
+ CharBufferSpanPair charBufferSpanPair = bufferedReaderContextStore.get(bufferedReader);
+ if (charBufferSpanPair != null) {
+ charBufferSpanPair.captureBody(HypertraceSemanticAttributes.HTTP_REQUEST_BODY);
+ bufferedReaderContextStore.put(bufferedReader, null);
+ }
}
}
}
diff --git a/instrumentation/servlet/servlet-3.0-no-wrapping/src/test/java/io/opentelemetry/javaagent/instrumentation/hypertrace/servlet/v3_0/nowrapping/Servlet30NoWrappingInstrumentationTest.java b/instrumentation/servlet/servlet-3.0-no-wrapping/src/test/java/io/opentelemetry/javaagent/instrumentation/hypertrace/servlet/v3_0/nowrapping/Servlet30NoWrappingInstrumentationTest.java
index fcec81541..636172c69 100644
--- a/instrumentation/servlet/servlet-3.0-no-wrapping/src/test/java/io/opentelemetry/javaagent/instrumentation/hypertrace/servlet/v3_0/nowrapping/Servlet30NoWrappingInstrumentationTest.java
+++ b/instrumentation/servlet/servlet-3.0-no-wrapping/src/test/java/io/opentelemetry/javaagent/instrumentation/hypertrace/servlet/v3_0/nowrapping/Servlet30NoWrappingInstrumentationTest.java
@@ -18,9 +18,11 @@
import io.opentelemetry.javaagent.instrumentation.hypertrace.servlet.v3_0.nowrapping.TestServlets.EchoAsyncResponse_stream;
import io.opentelemetry.javaagent.instrumentation.hypertrace.servlet.v3_0.nowrapping.TestServlets.EchoAsyncResponse_writer;
+import io.opentelemetry.javaagent.instrumentation.hypertrace.servlet.v3_0.nowrapping.TestServlets.EchoReader_read_large_array;
import io.opentelemetry.javaagent.instrumentation.hypertrace.servlet.v3_0.nowrapping.TestServlets.EchoStream_arr;
import io.opentelemetry.javaagent.instrumentation.hypertrace.servlet.v3_0.nowrapping.TestServlets.EchoStream_arr_offset;
import io.opentelemetry.javaagent.instrumentation.hypertrace.servlet.v3_0.nowrapping.TestServlets.EchoStream_readLine_print;
+import io.opentelemetry.javaagent.instrumentation.hypertrace.servlet.v3_0.nowrapping.TestServlets.EchoStream_read_large_array;
import io.opentelemetry.javaagent.instrumentation.hypertrace.servlet.v3_0.nowrapping.TestServlets.EchoStream_single_byte;
import io.opentelemetry.javaagent.instrumentation.hypertrace.servlet.v3_0.nowrapping.TestServlets.EchoWriter_single_char;
import io.opentelemetry.javaagent.instrumentation.hypertrace.servlet.v3_0.nowrapping.TestServlets.GetHello;
@@ -73,6 +75,8 @@ public static void startServer() throws Exception {
handler.addServlet(TestServlets.Forward_to_post.class, "/forward_to_echo");
handler.addServlet(EchoAsyncResponse_stream.class, "/echo_async_response_stream");
handler.addServlet(EchoAsyncResponse_writer.class, "/echo_async_response_writer");
+ handler.addServlet(EchoStream_read_large_array.class, "/echo_stream_read_large_array");
+ handler.addServlet(EchoReader_read_large_array.class, "/echo_reader_read_large_array");
server.setHandler(handler);
server.start();
serverPort = server.getConnectors()[0].getLocalPort();
@@ -103,6 +107,16 @@ public void postJson_stream_single_byte() throws Exception {
postJson(String.format("http://localhost:%d/echo_stream_single_byte", serverPort));
}
+ @Test
+ public void postJson_stream_read_large_array() throws Exception {
+ postJson(String.format("http://localhost:%d/echo_stream_read_large_array", serverPort));
+ }
+
+ @Test
+ public void postJson_reader_read_large_array() throws Exception {
+ postJson(String.format("http://localhost:%d/echo_reader_read_large_array", serverPort));
+ }
+
@Test
public void postJson_stream_arr() throws Exception {
postJson(String.format("http://localhost:%d/echo_stream_arr", serverPort));
diff --git a/instrumentation/servlet/servlet-3.0-no-wrapping/src/test/java/io/opentelemetry/javaagent/instrumentation/hypertrace/servlet/v3_0/nowrapping/TestServlets.java b/instrumentation/servlet/servlet-3.0-no-wrapping/src/test/java/io/opentelemetry/javaagent/instrumentation/hypertrace/servlet/v3_0/nowrapping/TestServlets.java
index fc01547fb..b79f1b742 100644
--- a/instrumentation/servlet/servlet-3.0-no-wrapping/src/test/java/io/opentelemetry/javaagent/instrumentation/hypertrace/servlet/v3_0/nowrapping/TestServlets.java
+++ b/instrumentation/servlet/servlet-3.0-no-wrapping/src/test/java/io/opentelemetry/javaagent/instrumentation/hypertrace/servlet/v3_0/nowrapping/TestServlets.java
@@ -265,4 +265,30 @@ protected void service(HttpServletRequest req, HttpServletResponse resp)
req.getRequestDispatcher("/echo_stream_single_byte").forward(req, resp);
}
}
+
+ public static class EchoStream_read_large_array extends HttpServlet {
+ @Override
+ protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+ req.getInputStream().read(new byte[1000], 0, 1000);
+
+ resp.setStatus(200);
+ resp.setContentType("application/json");
+ resp.setHeader(RESPONSE_HEADER, RESPONSE_HEADER_VALUE);
+
+ resp.getWriter().print(RESPONSE_BODY.toCharArray());
+ }
+ }
+
+ public static class EchoReader_read_large_array extends HttpServlet {
+ @Override
+ protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+ req.getReader().read(new char[1000], 0, 1000);
+
+ resp.setStatus(200);
+ resp.setContentType("application/json");
+ resp.setHeader(RESPONSE_HEADER, RESPONSE_HEADER_VALUE);
+
+ resp.getWriter().print(RESPONSE_BODY.toCharArray());
+ }
+ }
}