1111package io .vertx .httpproxy .impl ;
1212
1313import io .vertx .core .Future ;
14+ import io .vertx .core .buffer .Buffer ;
1415import io .vertx .core .http .*;
1516import io .vertx .core .internal .logging .Logger ;
1617import io .vertx .core .internal .logging .LoggerFactory ;
1718import io .vertx .core .net .NetSocket ;
19+ import io .vertx .core .streams .ReadStream ;
1820import io .vertx .httpproxy .*;
1921import io .vertx .httpproxy .cache .CacheOptions ;
2022import io .vertx .httpproxy .spi .cache .Cache ;
@@ -64,13 +66,8 @@ public void handle(HttpServerRequest request) {
6466 return ;
6567 }
6668
67- // WebSocket upgrade tunneling
68- if (supportWebSocket && request .canUpgradeToWebSocket ()) {
69- handleWebSocketUpgrade (proxyRequest );
70- return ;
71- }
72-
73- Proxy proxy = new Proxy (proxyRequest );
69+ boolean isWebSocket = supportWebSocket && request .canUpgradeToWebSocket ();
70+ Proxy proxy = new Proxy (proxyRequest , isWebSocket );
7471 proxy .filters = interceptors .listIterator ();
7572 proxy .sendRequest ()
7673 .recover (throwable -> {
@@ -84,57 +81,6 @@ public void handle(HttpServerRequest request) {
8481 });
8582 }
8683
87- private void handleWebSocketUpgrade (ProxyRequest proxyRequest ) {
88- HttpServerRequest proxiedRequest = proxyRequest .proxiedRequest ();
89- resolveOrigin (proxiedRequest ).onComplete (ar -> {
90- if (ar .succeeded ()) {
91- HttpClientRequest request = ar .result ();
92- request .setMethod (HttpMethod .GET );
93- request .setURI (proxiedRequest .uri ());
94- request .headers ().addAll (proxiedRequest .headers ());
95- Future <HttpClientResponse > fut2 = request .connect ();
96- proxiedRequest .handler (request ::write );
97- proxiedRequest .endHandler (v -> request .end ());
98- proxiedRequest .resume ();
99- fut2 .onComplete (ar2 -> {
100- if (ar2 .succeeded ()) {
101- HttpClientResponse proxiedResponse = ar2 .result ();
102- if (proxiedResponse .statusCode () == 101 ) {
103- HttpServerResponse response = proxiedRequest .response ();
104- response .setStatusCode (101 );
105- response .headers ().addAll (proxiedResponse .headers ());
106- Future <NetSocket > otherso = proxiedRequest .toNetSocket ();
107- otherso .onComplete (ar3 -> {
108- if (ar3 .succeeded ()) {
109- NetSocket responseSocket = ar3 .result ();
110- NetSocket proxyResponseSocket = proxiedResponse .netSocket ();
111- responseSocket .handler (proxyResponseSocket ::write );
112- proxyResponseSocket .handler (responseSocket ::write );
113- responseSocket .closeHandler (v -> proxyResponseSocket .close ());
114- proxyResponseSocket .closeHandler (v -> responseSocket .close ());
115- } else {
116- // Find reproducer
117- System .err .println ("Handle this case" );
118- ar3 .cause ().printStackTrace ();
119- }
120- });
121- } else {
122- // Rejection
123- proxiedRequest .resume ();
124- end (proxyRequest , proxiedResponse .statusCode ());
125- }
126- } else {
127- proxiedRequest .resume ();
128- end (proxyRequest , 502 );
129- }
130- });
131- } else {
132- proxiedRequest .resume ();
133- end (proxyRequest , 502 );
134- }
135- });
136- }
137-
13884 private void end (ProxyRequest proxyRequest , int sc ) {
13985 proxyRequest
14086 .response ()
@@ -155,9 +101,16 @@ private class Proxy implements ProxyContext {
155101 private ProxyResponse response ;
156102 private final Map <String , Object > attachments = new HashMap <>();
157103 private ListIterator <ProxyInterceptor > filters ;
104+ private final boolean isWebSocket ;
158105
159- private Proxy (ProxyRequest request ) {
106+ private Proxy (ProxyRequest request , boolean isWebSocket ) {
160107 this .request = request ;
108+ this .isWebSocket = isWebSocket ;
109+ }
110+
111+ @ Override
112+ public boolean isWebSocket () {
113+ return isWebSocket ;
161114 }
162115
163116 @ Override
@@ -180,8 +133,25 @@ public ProxyRequest request() {
180133 public Future <ProxyResponse > sendRequest () {
181134 if (filters .hasNext ()) {
182135 ProxyInterceptor next = filters .next ();
136+ if (isWebSocket && !next .allowApplyToWebSocket ()) {
137+ return sendRequest ();
138+ }
183139 return next .handleProxyRequest (this );
184140 } else {
141+ if (isWebSocket ) {
142+ HttpServerRequest proxiedRequest = request ().proxiedRequest ();
143+ return resolveOrigin (proxiedRequest ).compose (request -> {
144+ request .setMethod (request ().getMethod ());
145+ request .setURI (request ().getURI ());
146+ request .headers ().addAll (request ().headers ());
147+ Future <HttpClientResponse > responseFuture = request .connect ();
148+ ReadStream <Buffer > readStream = request ().getBody ().stream ();
149+ readStream .handler (request ::write );
150+ readStream .resume ();
151+ proxiedRequest .resume ();
152+ return responseFuture ;
153+ }).map (response -> new ProxiedResponse ((ProxiedRequest ) request (), request ().proxiedRequest ().response (), response ));
154+ }
185155 return sendProxyRequest (request );
186156 }
187157 }
@@ -195,8 +165,38 @@ public ProxyResponse response() {
195165 public Future <Void > sendResponse () {
196166 if (filters .hasPrevious ()) {
197167 ProxyInterceptor filter = filters .previous ();
168+ if (isWebSocket && !filter .allowApplyToWebSocket ()) {
169+ return sendResponse ();
170+ }
198171 return filter .handleProxyResponse (this );
199172 } else {
173+ if (isWebSocket ) {
174+ HttpClientResponse proxiedResponse = response ().proxiedResponse ();
175+ if (response .getStatusCode () == 101 ) {
176+ HttpServerResponse clientResponse = request ().proxiedRequest ().response ();
177+ clientResponse .setStatusCode (101 );
178+ clientResponse .headers ().addAll (response .headers ());
179+ Future <NetSocket > otherso = request .proxiedRequest ().toNetSocket ();
180+ otherso .onComplete (ar3 -> {
181+ if (ar3 .succeeded ()) {
182+ NetSocket responseSocket = ar3 .result ();
183+ NetSocket proxyResponseSocket = proxiedResponse .netSocket ();
184+ responseSocket .handler (proxyResponseSocket ::write );
185+ proxyResponseSocket .handler (responseSocket ::write );
186+ responseSocket .closeHandler (v -> proxyResponseSocket .close ());
187+ proxyResponseSocket .closeHandler (v -> responseSocket .close ());
188+ } else {
189+ // Find reproducer
190+ System .err .println ("Handle this case" );
191+ ar3 .cause ().printStackTrace ();
192+ }
193+ });
194+ } else {
195+ request ().proxiedRequest ().resume ();
196+ end (request (), proxiedResponse .statusCode ());
197+ }
198+ return Future .succeededFuture ();
199+ }
200200 return response .send ();
201201 }
202202 }
0 commit comments