|
7 | 7 | import io.vertx.core.http.HttpClient;
|
8 | 8 | import io.vertx.core.http.HttpServer;
|
9 | 9 | import io.vertx.core.http.HttpServerRequest;
|
| 10 | +import io.vertx.core.http.RequestOptions; |
10 | 11 | import io.vertx.ext.web.Route;
|
11 | 12 | import io.vertx.ext.web.Router;
|
12 | 13 | import io.vertx.ext.web.RoutingContext;
|
13 | 14 | import org.slf4j.Logger;
|
14 | 15 | import org.slf4j.LoggerFactory;
|
15 | 16 |
|
| 17 | +import java.util.ArrayList; |
16 | 18 | import java.util.List;
|
17 | 19 | import java.util.concurrent.ThreadLocalRandom;
|
18 | 20 |
|
@@ -94,25 +96,76 @@ public class VertxHTTPReverseProxy {
|
94 | 96 | private final HttpServer httpServer;
|
95 | 97 | private final HttpClient httpClient;
|
96 | 98 | private final String name;
|
| 99 | + private final String P_METADATA_CONFIG = "cfg"; |
| 100 | + private final String P_STATE = "state"; |
97 | 101 |
|
98 | 102 | private VertxHTTPReverseProxy(Router router, HttpServer httpServer, HttpClient httpClient, String name) {
|
99 | 103 | this.router = router;
|
100 | 104 | this.httpServer = httpServer;
|
101 | 105 | this.httpClient = httpClient;
|
102 | 106 | this.name = name;
|
103 | 107 | this.routingContextHandler = ctx -> {
|
| 108 | + Route route = ctx.currentRoute(); |
| 109 | + ProxyRoute proxyRoute = getProxyRoute(route); |
| 110 | + String[] formatTargetUrl; |
| 111 | + try { |
| 112 | + formatTargetUrl = proxyRoute.formatTargetUrl(); |
| 113 | + } catch (Exception e) { |
| 114 | + ctx.response().setStatusCode(400).end(e.getMessage()); |
| 115 | + return; |
| 116 | + } |
104 | 117 | HttpServerRequest request = ctx.request();
|
105 | 118 | String uri = request.uri();
|
106 |
| - Route route = ctx.currentRoute(); |
107 | 119 | String path;
|
108 | 120 | if (route.getPath().endsWith("/")) {
|
109 | 121 | path = uri.substring(route.getPath().length() - 1);
|
110 | 122 | } else {
|
111 | 123 | path = uri.substring(route.getPath().length());
|
112 | 124 | }
|
| 125 | + RequestOptions requestOptions = new RequestOptions() |
| 126 | + .setSsl("https".equalsIgnoreCase(formatTargetUrl[0])) |
| 127 | + .setHost(formatTargetUrl[1]) |
| 128 | + .setPort(Integer.valueOf(formatTargetUrl[2])) |
| 129 | + .setURI(joinURI(formatTargetUrl[3], path)); |
| 130 | + System.out.println(requestOptions.getURI()); |
| 131 | + httpClient.request(requestOptions) |
| 132 | + .onFailure(e -> { |
| 133 | + ctx.response().setStatusCode(502).end(e.getMessage()); |
| 134 | + }) |
| 135 | + .onSuccess(r -> { |
| 136 | + r.headers().setAll(request.headers()); |
| 137 | + r.putHeader("Host", "reqres.in"); |
| 138 | + r.send() |
| 139 | + .onSuccess(r1 -> { |
| 140 | + ctx.response() |
| 141 | + .setStatusCode(r1.statusCode()) |
| 142 | + .headers().setAll(r1.headers()); |
| 143 | + r1.handler(data -> { |
| 144 | + ctx.response().write(data); |
| 145 | + }); |
| 146 | + r1.endHandler(v -> ctx.response().end()); |
| 147 | + |
| 148 | + }) |
| 149 | + .onFailure(e1 -> { |
| 150 | + ctx.response().setStatusCode(500).end(e1.getMessage()); |
| 151 | + }); |
| 152 | + }); |
113 | 153 | };
|
114 | 154 | }
|
115 | 155 |
|
| 156 | + private static String joinURI(String uri1, String uri2) { |
| 157 | + if (uri1.endsWith("/") && uri2.startsWith("/")) { |
| 158 | + // 两边都有 '/' |
| 159 | + return uri1 + uri2.substring(1); |
| 160 | + } else if (!uri1.endsWith("/") && !uri2.startsWith("/")) { |
| 161 | + // 两边都没有 '/' |
| 162 | + return uri1 + "/" + uri2; |
| 163 | + } else { |
| 164 | + // 只有一个有 '/' |
| 165 | + return uri1 + uri2; |
| 166 | + } |
| 167 | + } |
| 168 | + |
116 | 169 |
|
117 | 170 | public static VertxHTTPReverseProxy create(Vertx vertx, String name) {
|
118 | 171 | return new VertxHTTPReverseProxy(Router.router(vertx), vertx.createHttpServer(), vertx.createHttpClient(), name);
|
@@ -150,40 +203,86 @@ private static String generateName() {
|
150 | 203 | }
|
151 | 204 | }
|
152 | 205 |
|
| 206 | + public boolean enabled(String name) { |
| 207 | + for (Route route : router.getRoutes()) { |
| 208 | + ProxyRoute proxyRoute = getProxyRoute(route); |
| 209 | + if (name.equals(proxyRoute.getName())) { |
| 210 | + return route.getMetadata(P_STATE); |
| 211 | + } |
| 212 | + } |
| 213 | + return false; |
| 214 | + } |
| 215 | + |
| 216 | + private ProxyRoute getProxyRoute(Route route) { |
| 217 | + return route.getMetadata(P_METADATA_CONFIG); |
| 218 | + } |
| 219 | + |
153 | 220 |
|
154 | 221 | /**
|
155 | 222 | * 添加ProxyRoute
|
156 | 223 | */
|
157 | 224 | public void addRoute(ProxyRoute proxyRoute) {
|
158 |
| - |
| 225 | + router.route(proxyRoute.getSourceUrl()) |
| 226 | + .putMetadata(P_STATE, true) |
| 227 | + .putMetadata(P_METADATA_CONFIG, proxyRoute) |
| 228 | + .handler(routingContextHandler); |
159 | 229 | }
|
160 | 230 |
|
161 | 231 | /**
|
162 | 232 | * 删除ProxyRout,并将删除后的ProxyRout返回
|
163 | 233 | */
|
164 | 234 | public ProxyRoute removeRoute(String name) {
|
| 235 | + for (Route route : router.getRoutes()) { |
| 236 | + ProxyRoute proxyRoute = getProxyRoute(route); |
| 237 | + if (name.equals(proxyRoute.getName())) { |
| 238 | + route.remove(); |
| 239 | + return proxyRoute; |
| 240 | + } |
| 241 | + } |
165 | 242 | return null;
|
166 | 243 | }
|
167 | 244 |
|
168 | 245 | /**
|
169 | 246 | * 启用ProxyRout,并将启用后的ProxyRout返回
|
170 | 247 | */
|
171 | 248 | public ProxyRoute enableRoute(String name) {
|
| 249 | + for (Route route : router.getRoutes()) { |
| 250 | + ProxyRoute proxyRoute = getProxyRoute(route); |
| 251 | + if (name.equals(proxyRoute.getName())) { |
| 252 | + route.enable(); |
| 253 | + route.putMetadata(P_STATE, true); |
| 254 | + return proxyRoute; |
| 255 | + } |
| 256 | + } |
172 | 257 | return null;
|
173 | 258 | }
|
174 | 259 |
|
175 | 260 | /**
|
176 | 261 | * 停用ProxyRout,并将停用后的ProxyRout返回
|
177 | 262 | */
|
178 | 263 | public ProxyRoute disableRoute(String name) {
|
| 264 | + for (Route route : router.getRoutes()) { |
| 265 | + ProxyRoute proxyRoute = getProxyRoute(route); |
| 266 | + if (name.equals(proxyRoute.getName())) { |
| 267 | + route.disable(); |
| 268 | + route.putMetadata(P_STATE, false); |
| 269 | + return proxyRoute; |
| 270 | + } |
| 271 | + } |
179 | 272 | return null;
|
180 | 273 | }
|
181 | 274 |
|
182 | 275 | /**
|
183 | 276 | * 获取当前所有ProxyRout
|
184 | 277 | */
|
185 | 278 | public List<ProxyRoute> getRoutes() {
|
186 |
| - return null; |
| 279 | + List<ProxyRoute> proxyRoutes = new ArrayList<>(); |
| 280 | + for (Route route : router.getRoutes()) { |
| 281 | + ProxyRoute proxyRoute = getProxyRoute(route); |
| 282 | + proxyRoute.setEnable(route.getMetadata(P_STATE)); |
| 283 | + proxyRoutes.add(proxyRoute); |
| 284 | + } |
| 285 | + return proxyRoutes; |
187 | 286 | }
|
188 | 287 |
|
189 | 288 | public void start() {
|
|
0 commit comments