Skip to content

Commit d69559a

Browse files
jamesblightSpaceK33z
authored andcommitted
Handle external upgrade for all websocket proxies (#843)
* Upgrade websocket proxies without initial http request * Add websocket upgrade proxy test.
1 parent 35a44d1 commit d69559a

File tree

3 files changed

+61
-1
lines changed

3 files changed

+61
-1
lines changed

lib/Server.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ function Server(compiler, options) {
127127
contentBase = process.cwd();
128128
}
129129

130+
// Keep track of websocket proxies for external websocket upgrade.
131+
const websocketProxies = [];
132+
130133
const features = {
131134
compress() {
132135
if(options.compress) {
@@ -205,6 +208,9 @@ function Server(compiler, options) {
205208
}
206209

207210
proxyMiddleware = getProxyMiddleware(proxyConfig);
211+
if(proxyConfig.ws) {
212+
websocketProxies.push(proxyMiddleware);
213+
}
208214

209215
app.use((req, res, next) => {
210216
if(typeof proxyConfigOrCallback === "function") {
@@ -361,6 +367,12 @@ function Server(compiler, options) {
361367
} else {
362368
this.listeningApp = http.createServer(app);
363369
}
370+
371+
// Proxy websockets without the initial http request
372+
// https://github.com/chimurai/http-proxy-middleware#external-websocket-upgrade
373+
websocketProxies.forEach(function(wsProxy) {
374+
this.listeningApp.on("upgrade", wsProxy.upgrade);
375+
}, this);
364376
}
365377

366378
Server.prototype.use = function() {

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@
4343
"style-loader": "~0.13.0",
4444
"supertest": "^2.0.1",
4545
"url-loader": "~0.5.6",
46-
"webpack": "^2.2.0"
46+
"webpack": "^2.2.0",
47+
"ws": "^1.1.1"
4748
},
4849
"license": "MIT",
4950
"repository": {

test/Proxy.test.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33
const request = require("supertest");
44
const path = require("path");
55
const express = require("express");
6+
const WebSocket = require("ws");
67
const helper = require("./helper");
8+
const should = require("should");
79
const config = require("./fixtures/proxy-config/webpack.config");
810

11+
const WebSocketServer = WebSocket.Server;
912
const contentBase = path.join(__dirname, "fixtures/proxy-config");
1013

1114
const proxyOption = {
@@ -184,4 +187,48 @@ describe("Proxy", function() {
184187
req.get("/proxy2").expect(200, "from proxy", done);
185188
});
186189
});
190+
191+
context("External websocket upgrade", function() {
192+
let ws;
193+
let wsServer;
194+
let responseMessage;
195+
196+
before(function(done) {
197+
helper.start(config, {
198+
contentBase,
199+
proxy: [{
200+
context: "/",
201+
target: "http://localhost:9003",
202+
ws: true
203+
}]
204+
}, done);
205+
206+
wsServer = new WebSocketServer({ port: 9003 });
207+
wsServer.on("connection", function connection(ws) {
208+
ws.on("message", function incoming(message) {
209+
ws.send(message);
210+
});
211+
});
212+
});
213+
214+
beforeEach(function(done) {
215+
ws = new WebSocket("ws://localhost:8080/proxy3/socket");
216+
ws.on("message", function(message) {
217+
responseMessage = message;
218+
done()
219+
});
220+
ws.on("open", function open() {
221+
ws.send("foo");
222+
});
223+
})
224+
225+
it("Should receive response", function() {
226+
should(responseMessage).equal("foo");
227+
});
228+
229+
after(function(done) {
230+
wsServer.close();
231+
helper.close(done);
232+
});
233+
});
187234
});

0 commit comments

Comments
 (0)