java启动参数 -Dport="9898" -Ddst="https://www.baidu.com"
port 应用端口 dst 目标http地址
public class HttpProxyVerticle extends AbstractVerticle {
private static final Logger logger_ = LogManager.getLogger(HttpProxyVerticle.class);
@Override
public void stop() throws Exception {
super.stop();
}
@Override
public void init(Vertx vertx, Context context) {
String port = System.getProperty("port");
String des = System.getProperty("dst");
Integer proxyPort = StringUtil.isNullOrEmpty(port) ? 80 : Integer.valueOf(port);
context.config().put("proxyPort",proxyPort);
if (StringUtil.isNullOrEmpty(des)) {
logger_.info("启动参数未设置! -Dport=\"应用端口\" -Ddst=\"目标地址\" ");
logger_.info("例子-> -Dport=\"9898\" -Ddst=\"http://10.17.10.65:9897\" ");
try {
stop();
vertx.close();
} catch (Exception e) {
e.printStackTrace();
}
return;
}
logger_.info("application port:{},dst:{} ", proxyPort, des);
URI proxyUri;
try {
proxyUri = new URI(des);
} catch (URISyntaxException e) {
e.printStackTrace();
try {
stop();
vertx.close();
} catch (Exception e1) {
e1.printStackTrace();
}
return;
}
context.config().put("proxyUri",proxyUri);
super.init(vertx, context);
}
@Override
public void start() {
Integer proxyPort = config().getInteger("proxyPort");
URI proxyUri = (URI)config().getValue("proxyUri");
boolean https = proxyUri.getScheme().equals("https");
HttpServer httpServer = vertx.createHttpServer();
HttpClientOptions httpClientOptions = new HttpClientOptions();
httpClientOptions.setDefaultHost(proxyUri.getHost());
httpClientOptions.setSsl(https);
httpClientOptions.setConnectTimeout(1500);
Integer port =proxyUri.getPort()==-1?80:proxyUri.getPort();
if(https){
port=443;
}
httpClientOptions.setDefaultPort(port).setLogActivity(true);
HttpClient httpClient = vertx.createHttpClient(httpClientOptions);
HttpProxy httpProxy = HttpProxy.reverseProxy(httpClient);
httpServer.exceptionHandler(ex -> {
/* httpClient.close();*/
ex.printStackTrace();
}).requestHandler(httpProxy).listen(proxyPort);
}
}
public interface HttpProxy extends Handler<HttpServerRequest> {
static HttpProxy reverseProxy(HttpClient client) {
return new HttpProxyImpl(client);
}
}
public class HttpProxyImpl implements HttpProxy {
private static final Logger logger_ = LogManager.getLogger(HttpProxyImpl.class);
HttpClient httpClient;
// 目标地址
String proxy;
// 本机地址
String dst;
public HttpProxyImpl(HttpClient httpClient) {
this.httpClient = httpClient;
}
@Override
public void handle(HttpServerRequest httpServerRequest) {
HttpServerResponse httpServerResponse = httpServerRequest.response();
logger_.info("handler:{}", httpServerRequest.absoluteURI());
httpServerRequest.bodyHandler(reqTotalBuffer -> {
httpClient.request(httpServerRequest.method(), httpServerRequest.uri())
.onComplete(r -> {
if (r.succeeded()) {
HttpClientRequest httpClientRequest = r.result();
httpClientRequest.response()
.onComplete(c -> {
if (c.succeeded()) {
HttpClientResponse httpClientResponse = c.result();
// 复制httpclientreponse 响应头给httpreponse
copyHttpClientReposeHeaderToRequest(httpClientResponse, httpServerResponse);
// 拿到httpclient 响应处理
// 1. 直接把httpclientreponse 响应写给httpreponse
httpClientResponse.pipe().to(httpServerResponse);
} else {
httpServerResponse.reset();
c.cause().printStackTrace();
}
});
copyRequestHeaderToHttpClient(httpServerRequest, httpClientRequest);
httpClientRequest.send(reqTotalBuffer);
} else {
httpServerResponse.reset();
r.cause().printStackTrace();
}
});
});
}
/**
* @param httpServerRequest
* @param request
*/
public void copyRequestHeaderToHttpClient(HttpServerRequest httpServerRequest, HttpClientRequest request) {
if (proxy == null || dst == null) {
proxy = request.getHost();
if (request.getPort() != 80) {
proxy = proxy + ":" + (request.getPort() == 80 ? "" : request.getPort());
}
dst = httpServerRequest.host();
}
// 复制request header
logger_.info("request proxy:{}->dst:{}", proxy, dst);
String key;
String value;
for (Map.Entry<String, String> m : httpServerRequest.headers()) {
key = m.getKey();
value = m.getValue();
if (key.equalsIgnoreCase(HttpHeaderNames.HOST.toString())) {
value = proxy;
} else if (key.equalsIgnoreCase(HttpHeaderNames.REFERER.toString()) || key.equalsIgnoreCase(HttpHeaderNames.ORIGIN.toString())) {
value = value.replace(dst, proxy);
}
request.headers().add(key, value);
}
}
public void copyHttpClientReposeHeaderToRequest(HttpClientResponse httpClientResponse, HttpServerResponse httpServerResponse) {
logger_.info("reponse proxy:{}->dst:{}", proxy, dst);
String key;
String value;
for (Map.Entry<String, String> map : httpClientResponse.headers()) {
key = map.getKey();
value = map.getValue();
if (key.equalsIgnoreCase(HttpHeaderNames.LOCATION.toString())) {
value = value.replace(proxy, dst);
}
httpServerResponse.putHeader(key, value);
}
httpServerResponse.setStatusCode(httpClientResponse.statusCode());
}