@@ -71,6 +71,27 @@ public void methodAdvice(MethodTransformer transformer) {
7171 .and (takesArgument (1 , Class .class ))
7272 .and (takesArgument (2 , named ("org.springframework.http.HttpInputMessage" ))),
7373 HttpMessageConverterInstrumentation .class .getName () + "$HttpMessageConverterReadAdvice" );
74+
75+ transformer .applyAdvice (
76+ isMethod ()
77+ .and (isPublic ())
78+ .and (named ("write" ))
79+ .and (takesArguments (3 ))
80+ .and (takesArgument (0 , Object .class ))
81+ .and (takesArgument (1 , named ("org.springframework.http.MediaType" )))
82+ .and (takesArgument (2 , named ("org.springframework.http.HttpOutputMessage" ))),
83+ HttpMessageConverterInstrumentation .class .getName () + "$HttpMessageConverterWriteAdvice" );
84+
85+ transformer .applyAdvice (
86+ isMethod ()
87+ .and (isPublic ())
88+ .and (named ("write" ))
89+ .and (takesArguments (4 ))
90+ .and (takesArgument (0 , Object .class ))
91+ .and (takesArgument (1 , Type .class ))
92+ .and (takesArgument (2 , named ("org.springframework.http.MediaType" )))
93+ .and (takesArgument (3 , named ("org.springframework.http.HttpOutputMessage" ))),
94+ HttpMessageConverterInstrumentation .class .getName () + "$HttpMessageConverterWriteAdvice" );
7495 }
7596
7697 @ RequiresRequestContext (RequestContextSlot .APPSEC )
@@ -106,4 +127,37 @@ public static void after(
106127 }
107128 }
108129 }
130+
131+ @ RequiresRequestContext (RequestContextSlot .APPSEC )
132+ public static class HttpMessageConverterWriteAdvice {
133+ @ Advice .OnMethodEnter (suppress = Throwable .class )
134+ public static void before (
135+ @ Advice .Argument (0 ) final Object obj , @ ActiveRequestContext RequestContext reqCtx ) {
136+ if (obj == null ) {
137+ return ;
138+ }
139+
140+ CallbackProvider cbp = AgentTracer .get ().getCallbackProvider (RequestContextSlot .APPSEC );
141+ BiFunction <RequestContext , Object , Flow <Void >> callback =
142+ cbp .getCallback (EVENTS .responseBodyProcessed ());
143+ if (callback == null ) {
144+ return ;
145+ }
146+
147+ Flow <Void > flow = callback .apply (reqCtx , obj );
148+ Flow .Action action = flow .getAction ();
149+ if (action instanceof Flow .Action .RequestBlockingAction ) {
150+ Flow .Action .RequestBlockingAction rba = (Flow .Action .RequestBlockingAction ) action ;
151+ BlockResponseFunction brf = reqCtx .getBlockResponseFunction ();
152+ if (brf != null ) {
153+ brf .tryCommitBlockingResponse (
154+ reqCtx .getTraceSegment (),
155+ rba .getStatusCode (),
156+ rba .getBlockingContentType (),
157+ rba .getExtraHeaders ());
158+ }
159+ throw new BlockingException ("Blocked response (for HttpMessageConverter/write)" );
160+ }
161+ }
162+ }
109163}
0 commit comments