@@ -40,6 +40,8 @@ public void addTrace(MethodEvent event, PolicyNode policyNode) {
40
40
traceId = addTraceToApacheHttpClientLegacy (event );
41
41
} else if (HttpClient .matchOkhttp (this .matchedSignature )) {
42
42
traceId = addTraceToOkhttp (event );
43
+ } else if (HttpClient .matchApacheHttpComponents (this .matchedSignature )) {
44
+ traceId = addTraceToApacheHttpComponents (event );
43
45
}
44
46
45
47
if (traceId != null && !traceId .isEmpty ()) {
@@ -273,13 +275,66 @@ private void addHeaderToOkhttp(MethodEvent event, Map<String, String> headers) {
273
275
}
274
276
}
275
277
278
+ /**
279
+ * 添加traceId到Apache HttpComponents的请求上
280
+ *
281
+ * @param event
282
+ * @return
283
+ */
284
+ private String addTraceToApacheHttpComponents (MethodEvent event ) {
285
+ Object obj = event .objectInstance ;
286
+ if (obj == null ) {
287
+ return null ;
288
+ }
289
+ try {
290
+ String className = obj .getClass ().getName ();
291
+ if (!HttpClient .matchApacheHttpComponents (className )) {
292
+ return null ;
293
+ }
294
+
295
+ // 关于库的版本兼容性:
296
+ // 在GA org.apache.httpcomponents:fluent-hc的[4.4, 4.5.14]这个区间的版本里的request字段是这个org.apache.http.client.fluent.InternalHttpRequest类型
297
+ // private final InternalHttpRequest request;
298
+ // 然后org.apache.http.client.fluent.InternalHttpRequest这个类继承的org.apache.http.message.AbstractHttpMessage上有个setHeader方法:
299
+ // @Override // org.apache.http.HttpMessage
300
+ // public void setHeader(String name, String value) {
301
+ // Args.notNull(name, "Header name");
302
+ // this.headergroup.updateHeader(new BasicHeader(name, value));
303
+ // }
304
+ // 另外一提,org.apache.http.message.AbstractHttpMessage是在httpcomponents-httpcore:httpcore下的,它自从4.0-alpha5版本被添加了之后就没有变更过
305
+ //
306
+ // 在GA org.apache.httpcomponents:fluent-hc的[4.2, 4.4) 版本区间的request字段是org.apache.http.client.methods.HttpRequestBase类型,这个类属于依赖中的org.apache.httpcomponents:httpclient
307
+ // private final HttpRequestBase request;
308
+ // 在org.apache.httpcomponents:httpclient的[4.0.1, 4.2.6]版本区间,org.apache.http.client.methods.HttpRequestBase这个类是继承的org.apache.http.message.AbstractHttpMessage,此条分支可以与上面的合并
309
+ // org.apache.httpcomponents:httpclient的[4.3, 4.5.14]区间内是继承的org.apache.http.client.methods.AbstractExecutionAwareRequest
310
+ // org.apache.http.client.methods.AbstractExecutionAwareRequest自从4.3.4版本被添加依赖,一直继承的org.apache.http.message.AbstractHttpMessage,此条分支又可以与上面合并
311
+ // 所有版本的实现最终都会直接继承或者间接继承到org.apache.http.message.AbstractHttpMessage,所以下面的操作才可以统一
312
+
313
+ Field reqField = obj .getClass ().getDeclaredField ("request" );
314
+ reqField .setAccessible (true );
315
+ Object internalHttpRequest = reqField .get (obj );
316
+ Method setHeaderMethod = internalHttpRequest .getClass ().getMethod ("setHeader" , String .class , String .class );
317
+
318
+ // 然后把追踪的头加上
319
+ final String traceId = ContextManager .nextTraceId ();
320
+ setHeaderMethod .invoke (internalHttpRequest , ContextManager .getHeaderKey (), traceId );
321
+ setHeaderMethod .invoke (internalHttpRequest , ContextManager .getParentKey (), String .valueOf (EngineManager .getAgentId ()));
322
+ return traceId ;
323
+ } catch (Throwable e ) {
324
+ DongTaiLog .debug ("add traceId header to apache http components failed: {}, {}" , e .getMessage (), e .getCause () != null ? e .getCause ().getMessage () : "" );
325
+ }
326
+ return null ;
327
+ }
328
+
276
329
public static boolean validate (MethodEvent event ) {
277
330
if (HttpClient .matchJavaNetUrl (event .signature )) {
278
331
return validateURLConnection (event );
279
332
} else if (HttpClient .matchApacheHttp4 (event .signature ) || HttpClient .matchApacheHttp5 (event .signature )) {
280
333
return validateApacheHttpClient (event );
281
334
} else if (HttpClient .matchOkhttp (event .signature )) {
282
335
return validateOkhttp (event );
336
+ } else if (HttpClient .matchApacheHttpComponents (event .signature )) {
337
+ return validateApacheHttpComponents (event );
283
338
}
284
339
return true ;
285
340
}
@@ -377,4 +432,37 @@ public static boolean validateOkhttp(MethodEvent event) {
377
432
}
378
433
return false ;
379
434
}
435
+
436
+ /**
437
+ * 验证是否是合法的
438
+ *
439
+ * @param event
440
+ * @return
441
+ */
442
+ public static boolean validateApacheHttpComponents (MethodEvent event ) {
443
+ Object obj = event .objectInstance ;
444
+ if (obj == null ) {
445
+ return false ;
446
+ }
447
+ try {
448
+ String className = obj .getClass ().getName ();
449
+ if (!HttpClient .matchApacheHttpComponents (className )) {
450
+ return false ;
451
+ }
452
+
453
+ // 关于类的版本兼容性,详见 #addTraceToApacheHttpComponents方法
454
+ Field reqField = obj .getClass ().getDeclaredField ("request" );
455
+ reqField .setAccessible (true );
456
+ Object internalHttpRequest = reqField .get (obj );
457
+ Object header = internalHttpRequest .getClass ().getMethod ("getFirstHeader" , String .class ).invoke (internalHttpRequest , ContextManager .getHeaderKey ());
458
+ // traceId header not exists
459
+ if (header == null ) {
460
+ return true ;
461
+ }
462
+ } catch (Throwable e ) {
463
+ DongTaiLog .debug ("validate apache http components failed: {}, {}" , e .getMessage (), e .getCause () != null ? e .getCause ().getMessage () : "" );
464
+ }
465
+ return false ;
466
+ }
467
+
380
468
}
0 commit comments