@@ -35,12 +35,14 @@ public class ReverseHttpProxy {
35
35
*/
36
36
public static final String LOG_FORMAT_DEFAULT = "" +
37
37
"{name} -- " +
38
+ "{method} -- " +
38
39
"{serverHttpVersion} -- " +
39
40
"{clientHttpVersion} -- " +
40
- "{method} -- " +
41
41
"{userAgent} -- " +
42
42
"{serverRemoteAddr} -- " +
43
+ "{serverLocalAddr} -- " +
43
44
"{clientLocalAddr} -- " +
45
+ "{clientRemoteAddr} -- " +
44
46
"{sourceUri} -- " +
45
47
"{proxyUrl} -- " +
46
48
"{statusCode} -- " +
@@ -113,12 +115,12 @@ public class ReverseHttpProxy {
113
115
/**
114
116
* 连接状态:客户端--代理服务
115
117
*/
116
- protected static final String INTERNAL_CLIENT_CONNECTION_OPEN = "INTERNAL_CLIENT_CONNECTION_OPEN " ;
118
+ protected static final String INTERNAL_SERVER_CONNECTION_OPEN = "INTERNAL_SERVER_CONNECTION_OPEN " ;
117
119
118
120
/**
119
121
* 连接状态:代理服务--后端服务
120
122
*/
121
- protected static final String INTERNAL_PROXY_SERVER_CONNECTION_OPEN = "INTERNAL_PROXY_SERVER_CONNECTION_OPEN " ;
123
+ protected static final String INTERNAL_CLIENT_CONNECTION_OPEN = "INTERNAL_CLIENT_CONNECTION_OPEN " ;
122
124
123
125
/**
124
126
* 代理服务接收请求的HTTP版本
@@ -146,12 +148,21 @@ public class ReverseHttpProxy {
146
148
*/
147
149
protected static final String INTERNAL_SERVER_REMOTE_ADDR = "INTERNAL_SERVER_REMOTE_ADDR" ;
148
150
151
+ /**
152
+ * 代理服务收到的请求的本地地址
153
+ */
154
+ protected static final String INTERNAL_SERVER_LOCAL_ADDR = "INTERNAL_SERVER_LOCAL_ADDR" ;
149
155
150
156
/**
151
157
* 代理服务发起请求的本端地址
152
158
*/
153
159
protected static final String INTERNAL_CLIENT_LOCAL_ADDR = "INTERNAL_CLIENT_LOCAL_ADDR" ;
154
160
161
+ /**
162
+ * 代理服务发起请求的远端地址
163
+ */
164
+ protected static final String INTERNAL_CLIENT_REMOTE_ADDR = "INTERNAL_CLIENT_REMOTE_ADDR" ;
165
+
155
166
156
167
/**
157
168
* 代理服务收到的请求路径
@@ -300,15 +311,17 @@ protected void doLog(RoutingContext ctx) {
300
311
}
301
312
String logInfo = logFormat
302
313
.replace ("{name}" , getContextData (ctx , P_NAME ).toString ())
303
- .replace ("{serverHttpVersion}" , getContextData (ctx , INTERNAL_SERVER_HTTP_VERSION ).toString ())
304
- .replace ("{clientHttpVersion}" , getContextData (ctx , INTERNAL_CLIENT_HTTP_VERSION ).toString ())
305
314
.replace ("{method}" , getContextData (ctx , INTERNAL_METHOD ).toString ())
306
315
.replace ("{userAgent}" , getContextData (ctx , INTERNAL_USER_AGENT ).toString ())
307
- .replace ("{serverRemoteAddr}" , getContextData (ctx , INTERNAL_SERVER_REMOTE_ADDR ).toString ())
308
- .replace ("{clientLocalAddr}" , getContextData (ctx , INTERNAL_CLIENT_LOCAL_ADDR ).toString ())
309
316
.replace ("{sourceUri}" , getContextData (ctx , INTERNAL_SOURCE_URI ).toString ())
310
317
.replace ("{proxyUrl}" , getContextData (ctx , INTERNAL_PROXY_URL ).toString ())
311
318
.replace ("{statusCode}" , getContextData (ctx , INTERNAL_STATUS_CODE ).toString ())
319
+ .replace ("{serverHttpVersion}" , getContextData (ctx , INTERNAL_SERVER_HTTP_VERSION ).toString ())
320
+ .replace ("{clientHttpVersion}" , getContextData (ctx , INTERNAL_CLIENT_HTTP_VERSION ).toString ())
321
+ .replace ("{serverRemoteAddr}" , getContextData (ctx , INTERNAL_SERVER_REMOTE_ADDR ).toString ())
322
+ .replace ("{serverLocalAddr}" , getContextData (ctx , INTERNAL_SERVER_LOCAL_ADDR ).toString ())
323
+ .replace ("{clientLocalAddr}" , getContextData (ctx , INTERNAL_CLIENT_LOCAL_ADDR ).toString ())
324
+ .replace ("{clientRemoteAddr}" , getContextData (ctx , INTERNAL_CLIENT_REMOTE_ADDR ).toString ())
312
325
.replace ("{consumedMills}" , String .valueOf (System .currentTimeMillis () - (Long ) getContextData (ctx , INTERNAL_SEND_TIMESTAMP )));
313
326
log .info (logInfo );
314
327
}
@@ -333,8 +346,7 @@ public void start() {
333
346
if (ar .succeeded ()) {
334
347
log .info ("{} started on {}:{}" , name , sourceHost , sourcePort );
335
348
} else {
336
- Throwable e = ar .cause ();
337
- log .error ("{} start failed" , name , e );
349
+ log .error ("{} start failed" , name , ar .cause ());
338
350
339
351
}
340
352
};
@@ -576,20 +588,26 @@ protected Handler<AsyncResult<HttpClientResponse>> sendRequestHandler(RoutingCon
576
588
// 设置响应码
577
589
setStatusCode (ctx , serverResp , clientResp .statusCode ());
578
590
579
- if ((boolean ) getContextData (ctx , INTERNAL_PROXY_SERVER_CONNECTION_OPEN ) && (boolean ) getContextData (ctx , INTERNAL_CLIENT_CONNECTION_OPEN )) {
591
+ if ((boolean ) getContextData (ctx , INTERNAL_CLIENT_CONNECTION_OPEN ) && (boolean ) getContextData (ctx , INTERNAL_SERVER_CONNECTION_OPEN )) {
580
592
// 流输出
581
- clientResp .pipeTo (serverResp ).onSuccess (v -> {
582
- doLog (ctx );
583
- }).onFailure (e -> {
584
- badGateway (ctx , serverResp );
585
- log .error ("{} {} clientResp pipeto serverResp error" , serverReq .method ().name (), proxyUrl , e );
593
+ clientResp .pipeTo (serverResp ).onComplete (ar1 -> {
594
+ if (ar1 .succeeded ()) {
595
+ doLog (ctx );
596
+ } else {
597
+ badGateway (ctx , serverResp );
598
+ log .error ("pipeTo failed. {} <-- {} <-- {} <-- {}" ,
599
+ getContextData (ctx , INTERNAL_SERVER_REMOTE_ADDR ),
600
+ getContextData (ctx , INTERNAL_SERVER_LOCAL_ADDR ),
601
+ getContextData (ctx , INTERNAL_CLIENT_LOCAL_ADDR ),
602
+ getContextData (ctx , INTERNAL_CLIENT_REMOTE_ADDR ),
603
+ ar1 .cause ());
604
+ }
586
605
});
587
606
}
588
607
589
608
} else {
590
609
badGateway (ctx , serverResp );
591
- Throwable e = ar .cause ();
592
- log .error ("{} {} send request error" , serverReq .method ().name (), proxyUrl , e );
610
+ log .error ("{} {} send request error" , serverReq .method ().name (), proxyUrl , ar .cause ());
593
611
}
594
612
};
595
613
}
@@ -609,35 +627,34 @@ protected Handler<AsyncResult<HttpClientRequest>> connectHandler(RoutingContext
609
627
HttpClientRequest clientReq = ar .result ();
610
628
setContextData (ctx , INTERNAL_CLIENT_HTTP_VERSION , clientReq .version ().alpnName ());
611
629
// 记录连接状态
612
- setContextData (ctx , INTERNAL_PROXY_SERVER_CONNECTION_OPEN , true );
630
+ setContextData (ctx , INTERNAL_CLIENT_CONNECTION_OPEN , true );
613
631
614
632
// 注册客户端与代理服务之间连接的断开监听事件。可监听主动关闭和被动关闭
615
633
setContextData (ctx , INTERNAL_CLIENT_LOCAL_ADDR , clientReq .connection ().localAddress ().toString ());
634
+ setContextData (ctx , INTERNAL_CLIENT_REMOTE_ADDR , clientReq .connection ().remoteAddress ().toString ());
635
+ log .debug ("{} --> {} connected" , getContextData (ctx , INTERNAL_CLIENT_LOCAL_ADDR ), getContextData (ctx , INTERNAL_CLIENT_REMOTE_ADDR ));
636
+
637
+
616
638
clientReq .connection ().closeHandler (v -> {
617
- setContextData (ctx , INTERNAL_PROXY_SERVER_CONNECTION_OPEN , false );
618
- log .debug ("proxyClient local connection {} closed" ,
619
- getContextData (ctx , INTERNAL_CLIENT_LOCAL_ADDR ).toString ());
639
+ setContextData (ctx , INTERNAL_CLIENT_CONNECTION_OPEN , false );
640
+ log .debug ("{} --> {} closed" , getContextData (ctx , INTERNAL_CLIENT_LOCAL_ADDR ), getContextData (ctx , INTERNAL_CLIENT_REMOTE_ADDR ));
620
641
});
621
642
622
643
623
644
// 复制请求头。复制的过程中忽略逐跳标头
624
645
copyRequestHeaders (ctx , serverReq , clientReq );
625
646
626
- if ((boolean ) getContextData (ctx , INTERNAL_PROXY_SERVER_CONNECTION_OPEN ) && (boolean ) getContextData (ctx , INTERNAL_CLIENT_CONNECTION_OPEN )) {
647
+ if ((boolean ) getContextData (ctx , INTERNAL_CLIENT_CONNECTION_OPEN ) && (boolean ) getContextData (ctx , INTERNAL_SERVER_CONNECTION_OPEN )) {
627
648
// 若存在请求体,则将请求体复制。使用流式复制,避免占用大量内存
628
649
if (clientReq .headers ().contains ("Content-Length" ) || clientReq .headers ().contains ("Transfer-Encoding" )) {
629
650
clientReq .send (serverReq ).onComplete (sendRequestHandler (ctx , serverReq , serverResp , proxyUrl ));
630
651
} else {
631
652
clientReq .send ().onComplete (sendRequestHandler (ctx , serverReq , serverResp , proxyUrl ));
632
653
}
633
- } else if ((boolean ) getContextData (ctx , INTERNAL_PROXY_SERVER_CONNECTION_OPEN ) && !(boolean ) getContextData (ctx , INTERNAL_CLIENT_CONNECTION_OPEN )) {
634
- // 整体链路连接不可用,释放资源
635
- clientReq .connection ().close ();
636
654
}
637
655
} else {
638
656
badGateway (ctx , serverResp );
639
- Throwable e = ar .cause ();
640
- log .error ("{} {} open connection error" , serverReq .method ().name (), proxyUrl , e );
657
+ log .error ("{} {} open connection error" , serverReq .method ().name (), proxyUrl , ar .cause ());
641
658
}
642
659
643
660
};
@@ -659,6 +676,9 @@ protected void badGateway(RoutingContext ctx, HttpServerResponse serverResp) {
659
676
*/
660
677
protected Handler <RoutingContext > routingContextHandler (HttpClient httpClient ) {
661
678
return ctx -> {
679
+ // 暂停流读取
680
+ ctx .request ().pause ();
681
+
662
682
// vertx的uri()是包含query参数的。而path()才是我们常说的不带有query的uri
663
683
// route不是线程安全的。route里的metadata应以路由为单元存储,而不是以请求为单元存储。一个路由会有很多请求。
664
684
// 若想要以请求为单元存储数据,应该使用routingContext.put
@@ -670,11 +690,7 @@ protected Handler<RoutingContext> routingContextHandler(HttpClient httpClient) {
670
690
// 记录请求开始时间
671
691
setContextData (ctx , INTERNAL_SEND_TIMESTAMP , System .currentTimeMillis ());
672
692
// 记录连接状态
673
- setContextData (ctx , INTERNAL_CLIENT_CONNECTION_OPEN , true );
674
-
675
- // 暂停流读取
676
- ctx .request ().pause ();
677
-
693
+ setContextData (ctx , INTERNAL_SERVER_CONNECTION_OPEN , true );
678
694
679
695
// 获取代理地址
680
696
String proxyUrl = getProxyUrl (ctx , ctx .request (), ctx .response ());
@@ -691,13 +707,15 @@ protected Handler<RoutingContext> routingContextHandler(HttpClient httpClient) {
691
707
requestOptions .setMethod (ctx .request ().method ());
692
708
requestOptions .setFollowRedirects (getContextData (ctx , P_FOLLOW_REDIRECTS ) != null && Boolean .parseBoolean (getContextData (ctx , P_FOLLOW_REDIRECTS ).toString ()));
693
709
694
-
695
710
// 注册客户端与代理服务之间连接的断开监听事件。可监听主动关闭和被动关闭
696
711
setContextData (ctx , INTERNAL_SERVER_REMOTE_ADDR , ctx .request ().connection ().remoteAddress ().toString ());
712
+ setContextData (ctx , INTERNAL_SERVER_LOCAL_ADDR , ctx .request ().connection ().localAddress ().toString ());
713
+
714
+ log .debug ("{} <-- {} connected" , getContextData (ctx , INTERNAL_SERVER_LOCAL_ADDR ), getContextData (ctx , INTERNAL_SERVER_REMOTE_ADDR ));
697
715
698
716
ctx .request ().connection ().closeHandler (v -> {
699
- setContextData (ctx , INTERNAL_CLIENT_CONNECTION_OPEN , false );
700
- log .debug ("proxyServer remote connection {} closed" , getContextData (ctx , INTERNAL_SERVER_REMOTE_ADDR ). toString ( ));
717
+ setContextData (ctx , INTERNAL_SERVER_CONNECTION_OPEN , false );
718
+ log .debug ("{} <-- {} closed" , getContextData (ctx , INTERNAL_SERVER_LOCAL_ADDR ), getContextData ( ctx , INTERNAL_SERVER_REMOTE_ADDR ));
701
719
});
702
720
703
721
// 如果跨域由代理服务接管,那么针对跨域使用的OPTIONS预检请求,就由代理服务接管,而不经过实际的后端服务
@@ -721,7 +739,7 @@ protected Handler<RoutingContext> routingContextHandler(HttpClient httpClient) {
721
739
}
722
740
723
741
// 请求
724
- if ((boolean ) getContextData (ctx , INTERNAL_CLIENT_CONNECTION_OPEN )) {
742
+ if ((boolean ) getContextData (ctx , INTERNAL_SERVER_CONNECTION_OPEN )) {
725
743
httpClient .request (requestOptions ).onComplete (connectHandler (ctx , ctx .request (), ctx .response (), proxyUrl ));
726
744
}
727
745
};
0 commit comments