I want to add my interceptor at runtime in okhttpclient, I am making Agent using bytebuddy in premain class. And i am trying to intercept the constructor of "okhttp3.OkHttpClient.Builder" to add my interceptor in the interceptors list. But the problem is that the type() method is unable to find my class, I've tried different ways for eg: ElementMatchers .is(), .nameStartsWith(), .nameContains(), named() etc. but couldn't find the class.
I know that okhttp uses Kotlin & java adds $ in the namespace to invoke some methods, so for my case i changed it to "okhttp3.OkHttpClient$Builder", but again it was not finding the matching class.
I also want to know my approach that am i doing the right way to add the custom interceptor.
Agent:
public static void premain(String arg, Instrumentation instrumentation) {
new AgentBuilder.Default()
.type(ElementMatchers.named("okhttp3.OkHttpClient.Builder"))
.transform((builder, typeDescription, classLoader, javaModule, protectionDomain) -> {
System.out.println("Transformer: adding custom okhttpinterceptor using agent: " + typeDescription.getName());
return builder.constructor(ElementMatchers.takesArgument(1, OkHttpClient.class))
.intercept(MethodDelegation.to(ConstructorInterceptor.class));
})
.installOn(instrumentation);
}
ConstructorInterceptor:
public class ConstructorInterceptor {
public static void doProceed(
@SuperCall
Callable<?> client,
@Argument(0)
OkHttpClient okHttpClient, @Origin String method) throws Exception {
System.out.println("Constructor Interceptor was called for: " + method);
client.call();
okHttpClient.interceptors().add(new HttpInterceptor());
}
}
HttpInterceptor:
public class HttpInterceptor implements Interceptor{
@NotNull
@Override
public Response intercept(@NotNull Interceptor.Chain chain) throws IOException {
Request request = chain.request();
String reqBody = getRequestBody(request);
System.out.println("Inside HttpInterceptor before next()");
Response response = chain.proceed(request);
System.out.println("Inside HttpInterceptor after next()");
return response;
}
}
I assume that the binary name is
type(ElementMatchers.named("okhttp3.OkHttpClient$Builder"))
You can otherwise register a listener in your builder to see if a type is processed or ignored and what its name is.