@@ -372,22 +372,21 @@ protected String rewriteLocation(Route route, String url, String location) {
372372 return location ;
373373 }
374374
375- protected void doLog (Route route , HttpServerRequest realReq , HttpServerResponse realResp , String realUrl ) {
376-
375+ protected void doLog (Route route , HttpServerRequest serverReq , HttpServerResponse serverResp , String proxyUrl ) {
377376 if (route .getMetadata (P_LOG ) != null && Boolean .parseBoolean (route .getMetadata (P_LOG ))) {
378377 String logFormat = route .getMetadata (P_LOG_FORMAT ).toString ();
379378 if (logFormat == null || logFormat .isEmpty ()) {
380379 logFormat = LOG_FORMAT_DEFAULT ;
381380 }
382381 String logInfo = logFormat
383382 .replace ("{name}" , route .getName ())
384- .replace ("{method}" , realReq .method ().toString ())
385- .replace ("{userAgent}" , realReq .getHeader ("User-Agent" ))
386- .replace ("{remoteAddr}" , realReq .remoteAddress ().hostAddress ())
387- .replace ("{remotePort}" , String .valueOf (realReq .remoteAddress ().port ()))
388- .replace ("{source}" , realReq .uri ())
389- .replace ("{target}" , realUrl )
390- .replace ("{statusCode}" , String .valueOf (realResp .getStatusCode ()))
383+ .replace ("{method}" , serverReq .method ().toString ())
384+ .replace ("{userAgent}" , serverReq .getHeader ("User-Agent" ))
385+ .replace ("{remoteAddr}" , serverReq .remoteAddress ().hostAddress ())
386+ .replace ("{remotePort}" , String .valueOf (serverReq .remoteAddress ().port ()))
387+ .replace ("{source}" , serverReq .uri ())
388+ .replace ("{target}" , proxyUrl )
389+ .replace ("{statusCode}" , String .valueOf (serverResp .getStatusCode ()))
391390 .replace ("{consumedMills}" , String .valueOf (System .currentTimeMillis () - (Long ) route .getMetadata (P_SEND_TIMESTAMP )));
392391 log .info (logInfo );
393392 }
@@ -396,83 +395,97 @@ protected void doLog(Route route, HttpServerRequest realReq, HttpServerResponse
396395 /**
397396 * 发起请求Handler
398397 */
399- protected Handler <AsyncResult <HttpClientResponse >> sendRequestHandler (Route route , HttpServerRequest realReq , HttpServerResponse realResp , String realUrl ) {
398+ protected Handler <AsyncResult <HttpClientResponse >> sendRequestHandler (Route route , HttpServerRequest serverReq , HttpServerResponse serverResp , String proxyUrl ) {
400399 return ar -> {
401400 if (ar .succeeded ()) {
402- HttpClientResponse proxyResp = ar .result ();
401+ HttpClientResponse clientResp = ar .result ();
402+ // 暂停流读取
403+ clientResp .pause ();
403404 // 复制响应头。复制的过程中忽略逐跳标头
404- copyResponseHeaders (route , realReq , realResp , proxyResp );
405- if (!realResp .headers ().contains ("Content-Length" )) {
406- realResp .setChunked (true );
405+ copyResponseHeaders (route , serverReq , serverResp , clientResp );
406+ if (!serverResp .headers ().contains ("Content-Length" )) {
407+ serverResp .setChunked (true );
407408 }
408409 // 设置响应码
409- realResp .setStatusCode (proxyResp .statusCode ());
410+ serverResp .setStatusCode (clientResp .statusCode ());
410411 // 流输出
411- proxyResp .pipeTo (realResp ).onSuccess (v -> {
412- doLog (route , realReq , realResp , realUrl );
412+ clientResp .pipeTo (serverResp ).onSuccess (v -> {
413+ doLog (route , serverReq , serverResp , proxyUrl );
413414 }).onFailure (e -> {
414- realResp .setStatusCode (502 );
415- realResp .end ("Bad Gateway" );
416- log .error ("{} {} proxy response copy error" , realReq .method ().name (), realUrl , e );
415+ badGateway (route , serverReq , serverResp , proxyUrl );
416+ log .error ("{} {} proxy response copy error" , serverReq .method ().name (), proxyUrl , e );
417417 });
418-
419418 } else {
419+ badGateway (route , serverReq , serverResp , proxyUrl );
420420 Throwable e = ar .cause ();
421- realResp .setStatusCode (502 );
422- realResp .end ("Bad Gateway" );
423- log .error ("{} {} send request error" , realReq .method ().name (), realUrl , e );
421+ log .error ("{} {} send request error" , serverReq .method ().name (), proxyUrl , e );
424422 }
425423 };
426424 }
427425
428426 /**
429427 * 建立连接Handler
430428 */
431- protected Handler <AsyncResult <HttpClientRequest >> connectHandler (Route route , HttpServerRequest realReq , HttpServerResponse realResp , String realUrl ) {
429+ protected Handler <AsyncResult <HttpClientRequest >> connectHandler (Route route , HttpServerRequest serverReq , HttpServerResponse serverResp , String proxyUrl ) {
432430 return ar -> {
433431 if (ar .succeeded ()) {
434- HttpClientRequest proxyReq = ar .result ();
432+ HttpClientRequest clientReq = ar .result ();
435433 // 复制请求头。复制的过程中忽略逐跳标头
436- copyRequestHeaders (route , realReq , proxyReq );
434+ copyRequestHeaders (route , serverReq , clientReq );
437435 // 若存在请求体,则将请求体复制。使用流式复制,避免占用大量内存
438- if (proxyReq .headers ().contains ("Content-Length" ) || proxyReq .headers ().contains ("Transfer-Encoding" )) {
439- realReq .pipeTo (proxyReq );
436+ if (clientReq .headers ().contains ("Content-Length" ) || clientReq .headers ().contains ("Transfer-Encoding" )) {
437+ clientReq .send (serverReq ).onComplete (sendRequestHandler (route , serverReq , serverResp , proxyUrl ));
438+ } else {
439+ clientReq .send ().onComplete (sendRequestHandler (route , serverReq , serverResp , proxyUrl ));
440440 }
441- // 发送请求
442- route .putMetadata (P_SEND_TIMESTAMP , System .currentTimeMillis ());
443- proxyReq .send ().onComplete (sendRequestHandler (route , realReq , realResp , realUrl ));
444441 } else {
442+ badGateway (route , serverReq , serverResp , proxyUrl );
445443 Throwable e = ar .cause ();
446- log .error ("{} {} open connection error" , realReq .method ().name (), realUrl , e );
444+ log .error ("{} {} open connection error" , serverReq .method ().name (), proxyUrl , e );
447445 }
448446
449447 };
450448 }
451449
450+ private void badGateway (Route route , HttpServerRequest serverReq , HttpServerResponse serverResp , String proxyUrl ) {
451+ if (!serverResp .ended ()) {
452+ serverResp .setStatusCode (502 ).end ("Bad Gateway" );
453+ }
454+ doLog (route , serverReq , serverResp , proxyUrl );
455+ }
456+
452457 /**
453458 * 路由处理Handler
454459 */
455460 protected Handler <RoutingContext > routingContextHandler (HttpClient httpClient ) {
456461 return ctx -> {
457462 // vertx的uri()是包含query参数的。而path()才是我们常说的不带有query的uri
458463 Route route = ctx .currentRoute ();
464+
465+ // 记录请求开始时间
466+ route .putMetadata (P_SEND_TIMESTAMP , System .currentTimeMillis ());
467+
459468 String result = route .getMetadata (P_TARGET_URL ).toString ();
460- HttpServerRequest realReq = ctx .request ();
461- HttpServerResponse realResp = ctx .response ();
462- String absoluteURI = realReq .absoluteURI ();
469+ HttpServerRequest serverReq = ctx .request ();
470+ HttpServerResponse serverResp = ctx .response ();
471+
472+ // 暂停流读取
473+ serverReq .pause ();
474+
475+ String absoluteURI = serverReq .absoluteURI ();
463476 UrlParser .ParsedUrl parsedUrl = UrlParser .parseUrl (absoluteURI );
464477 String prefix = parsedUrl .getFormatHostPort () + (route .getMetadata (P_SOURCE_URL ).toString ().replace ("/*" , "" ));
465- String realUrl = result + (parsedUrl .getFormatUrl ().replace (prefix , "" ));
478+ String proxyUrl = result + (parsedUrl .getFormatUrl ().replace (prefix , "" ));
466479
467480
468481 // 构建请求参数
469482 RequestOptions requestOptions = new RequestOptions ();
470- requestOptions .setAbsoluteURI (realUrl );
471- requestOptions .setMethod (realReq .method ());
483+ requestOptions .setAbsoluteURI (proxyUrl );
484+ requestOptions .setMethod (serverReq .method ());
472485 requestOptions .setFollowRedirects (route .getMetadata (P_FOLLOW_REDIRECTS ) != null && Boolean .parseBoolean (route .getMetadata (P_FOLLOW_REDIRECTS )));
473486
474487 // 请求
475- httpClient .request (requestOptions ).onComplete (connectHandler (route , realReq , realResp , realUrl ));
488+ httpClient .request (requestOptions ).onComplete (connectHandler (route , serverReq , serverResp , proxyUrl ));
476489 };
477490 }
478491
0 commit comments