@@ -102,14 +102,14 @@ public class ReverseHttpProxy {
102102 protected static final char [] ID_CHARACTERS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" .toCharArray ();
103103
104104
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 ;
107107
108108
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 ;
113113
114114
115115 /**
@@ -238,7 +238,7 @@ public ReverseHttpProxy addRoute(
238238 return this ;
239239 }
240240
241- private void jsonLog (ProxyRoute proxyRoute ) {
241+ protected void jsonLog (ProxyRoute proxyRoute ) {
242242 Map <String , Object > map = new LinkedHashMap <>(proxyRoute .toMap ());
243243 log .info ("add Route\n {}" , new JsonObject (map ).encodePrettily ());
244244 }
@@ -481,13 +481,14 @@ protected Handler<AsyncResult<HttpClientRequest>> connectHandler(Route route, Ht
481481 };
482482 }
483483
484- private void badGateway (Route route , HttpServerRequest serverReq , HttpServerResponse serverResp , String proxyUrl ) {
484+ protected void badGateway (Route route , HttpServerRequest serverReq , HttpServerResponse serverResp , String proxyUrl ) {
485485 if (!serverResp .ended ()) {
486486 serverResp .setStatusCode (502 ).end ("Bad Gateway" );
487487 }
488488 doLog (route , serverReq , serverResp , proxyUrl );
489489 }
490490
491+
491492 /**
492493 * 路由处理Handler
493494 */
@@ -501,18 +502,16 @@ protected Handler<RoutingContext> routingContextHandler(HttpClient httpClient) {
501502 // 记录连接状态
502503 route .putMetadata (INTERNAL_CLIENT_CONNECTION_OPEN , true );
503504
504- String result = route . getMetadata ( P_TARGET_URL ). toString ();
505+
505506 HttpServerRequest serverReq = ctx .request ();
506507 HttpServerResponse serverResp = ctx .response ();
507508
508509 // 暂停流读取
509510 serverReq .pause ();
510511
511512
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 );
516515
517516 // 构建请求参数
518517 RequestOptions requestOptions = new RequestOptions ();
@@ -539,5 +538,49 @@ protected Handler<RoutingContext> routingContextHandler(HttpClient httpClient) {
539538 };
540539 }
541540
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+
542585
543586}
0 commit comments