@@ -102,14 +102,14 @@ public class ReverseHttpProxy {
102
102
protected static final char [] ID_CHARACTERS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" .toCharArray ();
103
103
104
104
105
- private String sourceHost = "0.0.0.0" ;
106
- private int sourcePort = 998 ;
105
+ protected String sourceHost = "0.0.0.0" ;
106
+ protected int sourcePort = 998 ;
107
107
108
108
109
- private final HttpServer httpServer ;
110
- private final HttpClient httpClient ;
111
- private final Router router ;
112
- private final String name ;
109
+ protected final HttpServer httpServer ;
110
+ protected final HttpClient httpClient ;
111
+ protected final Router router ;
112
+ protected final String name ;
113
113
114
114
115
115
/**
@@ -238,7 +238,7 @@ public ReverseHttpProxy addRoute(
238
238
return this ;
239
239
}
240
240
241
- private void jsonLog (ProxyRoute proxyRoute ) {
241
+ protected void jsonLog (ProxyRoute proxyRoute ) {
242
242
Map <String , Object > map = new LinkedHashMap <>(proxyRoute .toMap ());
243
243
log .info ("add Route\n {}" , new JsonObject (map ).encodePrettily ());
244
244
}
@@ -481,13 +481,14 @@ protected Handler<AsyncResult<HttpClientRequest>> connectHandler(Route route, Ht
481
481
};
482
482
}
483
483
484
- private void badGateway (Route route , HttpServerRequest serverReq , HttpServerResponse serverResp , String proxyUrl ) {
484
+ protected void badGateway (Route route , HttpServerRequest serverReq , HttpServerResponse serverResp , String proxyUrl ) {
485
485
if (!serverResp .ended ()) {
486
486
serverResp .setStatusCode (502 ).end ("Bad Gateway" );
487
487
}
488
488
doLog (route , serverReq , serverResp , proxyUrl );
489
489
}
490
490
491
+
491
492
/**
492
493
* 路由处理Handler
493
494
*/
@@ -501,18 +502,16 @@ protected Handler<RoutingContext> routingContextHandler(HttpClient httpClient) {
501
502
// 记录连接状态
502
503
route .putMetadata (INTERNAL_CLIENT_CONNECTION_OPEN , true );
503
504
504
- String result = route . getMetadata ( P_TARGET_URL ). toString ();
505
+
505
506
HttpServerRequest serverReq = ctx .request ();
506
507
HttpServerResponse serverResp = ctx .response ();
507
508
508
509
// 暂停流读取
509
510
serverReq .pause ();
510
511
511
512
512
- String absoluteURI = serverReq .absoluteURI ();
513
- UrlParser .ParsedUrl parsedUrl = UrlParser .parseUrl (absoluteURI );
514
- String prefix = parsedUrl .getFormatHostPort () + (route .getMetadata (P_SOURCE_URL ).toString ().replace ("/*" , "" ));
515
- String proxyUrl = result + (parsedUrl .getFormatUrl ().replace (prefix , "" ));
513
+ // 获取代理地址
514
+ String proxyUrl = getProxyUrl (route , serverReq , serverResp );
516
515
517
516
// 构建请求参数
518
517
RequestOptions requestOptions = new RequestOptions ();
@@ -539,5 +538,49 @@ protected Handler<RoutingContext> routingContextHandler(HttpClient httpClient) {
539
538
};
540
539
}
541
540
541
+ /**
542
+ * 获取代理后的完整proxyUrl,不区分代理目标路径是否以/结尾。
543
+ * 处理逻辑为删除掉匹配的路径,并将剩下的内容追加到代理目标路径后面。
544
+ */
545
+ protected String getProxyUrl (Route route , HttpServerRequest serverReq , HttpServerResponse serverResp ) {
546
+ String targetUrl = route .getMetadata (P_TARGET_URL ).toString ();
547
+ // 不区分targetUrl是否以/结尾,均以targetUrl不带/来处理
548
+ if (targetUrl .endsWith ("/" )) {
549
+ targetUrl = targetUrl .substring (0 , targetUrl .length () - 1 );
550
+ }
551
+
552
+
553
+ // 在vertx中,uri表示hostPort后面带有参数的地址。而这里的uri表示不带有参数的地址。
554
+ final String uri = serverReq .path ();
555
+ final String params = serverReq .uri ().replace (uri , "" );
556
+
557
+
558
+ // 若不是多级匹配,则直接代理到目标地址。注意要带上请求参数
559
+ if (!route .getMetadata (P_SOURCE_URL ).toString ().endsWith ("*" )) {
560
+ return targetUrl + params ;
561
+ }
562
+
563
+ String matchedUri = route .getPath ();
564
+ if (matchedUri .endsWith ("/" )) {
565
+ matchedUri = matchedUri .substring (0 , matchedUri .length () - 1 );
566
+ }
567
+ String suffixUri = uri .replace (matchedUri , "" );
568
+
569
+ // 代理路径尾部与用户初始请求保持一致
570
+ if (uri .endsWith ("/" ) && !suffixUri .endsWith ("/" )) {
571
+ suffixUri = suffixUri + "/" ;
572
+ }
573
+ if (!uri .endsWith ("/" ) && suffixUri .endsWith ("/" )) {
574
+ suffixUri = suffixUri .substring (0 , suffixUri .length () - 1 );
575
+ }
576
+
577
+ // 因为targetUrl后面不带/,因此后缀需要以/开头
578
+ if (!suffixUri .isEmpty () && !suffixUri .startsWith ("/" )) {
579
+ suffixUri = "/" + suffixUri ;
580
+ }
581
+
582
+ return targetUrl + suffixUri + params ;
583
+ }
584
+
542
585
543
586
}
0 commit comments