byte-buddy icon indicating copy to clipboard operation
byte-buddy copied to clipboard

Intercept Input Streams

Open SamHoque opened this issue 1 year ago • 2 comments

I am trying to intercept an input stream and then return an unconsumed input stream so the original method can still read from the input stream. but for some reason the inputStream is being returned empty.

heres my advice:

        @Advice.OnMethodExit
        static void interceptGetInputStream(@Advice.Return(readOnly = false) InputStream inputStream) {
            System.out.println("exit...");
            try {
                if (inputStream != null) {
                    // Read the entire content of the input stream into a buffer
                    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
                    byte[] data = new byte[4096];
                    int bytesRead;
                    while ((bytesRead = inputStream.read(data, 0, data.length)) != -1) {
                        buffer.write(data, 0, bytesRead);
                    }
                    buffer.flush();
                    byte[] responseData = buffer.toByteArray();

                    // Print the response data
                    String responseDataString = new String(responseData, StandardCharsets.UTF_8);
                    System.out.println("Response content:\n" + responseDataString);

                    // Reset the input stream by creating a new ByteArrayInputStream
                    inputStream = new ByteArrayInputStream(responseData);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        new AgentBuilder.Default()
                .disableClassFormatChanges()
                .with(RETRANSFORMATION)
                // Make sure we see helpful logs
                .with(AgentBuilder.RedefinitionStrategy.Listener.StreamWriting.toSystemError())
                .with(AgentBuilder.Listener.StreamWriting.toSystemError().withTransformationsOnly())
                .with(AgentBuilder.InstallationListener.StreamWriting.toSystemError())
                .ignore(none())
                // Ignore Byte Buddy and JDK classes we are not interested in
                .ignore(
                        nameStartsWith("net.bytebuddy.")
                                .or(nameStartsWith("jdk.internal.reflect."))
                                .or(nameStartsWith("java.lang.invoke."))
                                .or(nameStartsWith("com.sun.proxy."))
                )
                .disableClassFormatChanges()
                .with(RETRANSFORMATION)
                .with(AgentBuilder.InitializationStrategy.NoOp.INSTANCE)
                .with(AgentBuilder.TypeStrategy.Default.REDEFINE)
                .type(nameContains("HttpURLConnection"))
                .transform((builder, type, classLoader, transformer, module) -> builder.visit(Advice.to(HttpUrlConnectionInstrumentation.GetResponseCodeAdvice.class).on(named("getInputStream"))))
                .installOnByteBuddyAgent();

SamHoque avatar Apr 18 '24 05:04 SamHoque

Are you sure your advice is applied? Did you dump the class file snd look st the generated class?

raphw avatar Apr 19 '24 20:04 raphw

Hey, I was able to fix this by only reading the input stream once and for future exits, I return a file output stream from my saved response.

SamHoque avatar Apr 20 '24 19:04 SamHoque