Can't get proxying a websocket working with create-react-app - websocket

I created a CRA in a docker container and I'm trying to proxy websockets over to another container running a python backend. I for the life of me cannot get the connection working.
I have verified that the server works by exposing the port outside of docker and connecting to it from the browser directly - it connects and works.
I can also verify that the connection within my CRA docker is set up properly - within it I start up a shell and do
> WS = require('ws')
> new WS(`ws://server:8765/ws/foo`).addEventListener('open', e => console.log('open'))
and that connects and prints open too. (This is why I don't have the docker tag on here, from my understanding this eliminates docker from being a possible issue since I've confirmed I can connect from one to the other)
The only thing that I can think of is that the proxy configuration is wrong
Here's what I'm trying to do on the client
const socket = new WebSocket(`ws:localhost/ws/foo`)
my proxy setup
const proxy = require("http-proxy-middleware")
module.exports = (app) => {
as I can tell. Need to circle back
app.use(`/ws*`, proxy({
target: 'ws://server:8765/ws',
changeOrigin: true,
ws: true,
}))
}
I have tried that with /ws and with putting the url in the proxy clause instead o the use and...still nothing
I'm really not sure what more I can be missing.
Here are my dependency versions
"dependencies": {
"#reach/router": "^1.2.1",
"http-proxy-middleware": "^0.20.0",
"react": "^16.10.2",
"react-dom": "^16.10.2",
"react-scripts": "3.2.0",
"styled-components": "^4.4.0"
},

Related

Cause of "Browser needs to be launched with the global proxy" Playwright error

I'm running a Playwright test that makes a request to http://localhost:3000/somePage and wanted to run the request through a proxy (the Fiddler proxy, so I can inspect the traffic, but that's beside the point).
In my playwright.config.ts I have:
projects: [
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
proxy: {
server: 'http://127.0.0.1:8888'
}
},
},
]
The proxy key is what I added to what was already in the config file generated by Playwright when I set up the project.
When I run my test, I get the following error and the test fails to run:
browser.newContext: Browser needs to be launched with the global proxy. If all contexts override the proxy, global proxy will be never used and can be any string, for example "launch({ proxy: { server: 'http://per-context' } })"
A search online turns up little other than a couple github issues that were closed a long time ago. It seems like it's complaining that it should use the proxy, but only... when I tell it to use the proxy.
When I remove the proxy from the config, the test runs just fine. What am I missing?

esBuild serve over HTTPS

esBuild makes it pretty easy to serve http requests over it's own dev server, e.g.
require('esbuild').serve({
servedir: 'www',
}, {
entryPoints: ['src/app.js'],
outdir: 'www/js',
bundle: true,
}).then(server => {
// Call "stop" on the web server to stop serving
server.stop()
})
How do I enable HTTPS serving in this case? I can make it serve on port 443, but how do I attach a self-signed certificate?
I've found two solutions, that worked for me:
using http-proxy, in an extra file or inside your esbuild config. The limitation I've found here, you cannot use esbuild's --serve and --watch together (https://github.com/evanw/esbuild/issues/805), so if you need auto reload/live server functionality, you have to create this on your own, which is slightly complicated (https://github.com/evanw/esbuild/issues/802)
httpProxy.createServer({
target: {
host: 'localhost',
port: 3000
},
ssl: {
key: fs.readFileSync('key.pem', 'utf8'),
cert: fs.readFileSync('cert.pem', 'utf8')
}
}).listen(3001);
Using servor, here with npm scripts only, but you can also use servor in an esbuild config. Be aware to name your certificate files servor.crt and servor.key (https://github.com/lukejacksonn/servor/issues/79). I prefer this solution because of even less dependencies, simpler setup and auto reload/live server already build in.
"scripts": {
"build": "esbuild --bundle src/index.tsx --outfile=public/bundle.js",
"start": "npm run server & npm run build -- --watch",
"server": "servor public index.html 3000 --reload --secure"
}

Error during Websocket handshake with error code 500 using Daphne on Heroku

So I tried to deploy my docker django chat app to heroku. Previously I had been running the app with runserver command, but now I'm switching to daphne since I need to use websocket but I can't use runserver anymore in order to connect to webserver. After deployment, when I access the app page that shows the chat window this error occurs
WebSocket connection to 'wss://xxx.herokuapp.com/ws/chat/room/' failed: Error during WebSocket handshake: Unexpected response code: 500
(xxx is actually the url of my app)
Here's a piece of my js code
<script>
var roomName = "{{ room_name|escapejs }}";
var wsStart = 'ws://';
if (window.location.protocol === 'https:') {
wsStart = 'wss://';
}
var chatSocket = new WebSocket(
wsStart + window.location.host +
'/ws/chat/' + roomName + '/');
chatSocket.onmessage = function(e) {
var data = JSON.parse(e.data);
var message = data['message'];
document.querySelector('#chat-log').value += (message + '\n');
};
ws didn't work (error message Django can only use ASGI not websocket) so I changed to wss (according to another post in stackoverflow it's because security reason), which made the other error go away but still can't connect to websocket
This is my run command:
daphne -p $PORT --bind 0.0.0.0 -v2 test_project.asgi:application
EDIT: if I don't use wss (just use ws instead) this is the error message in js console
The page at 'https://xxx/chat/m/' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint 'ws://xxx/ws/chat/room/'. This request has been blocked; this endpoint must be available over WSS.
Extremely appreciate any help, or ideas of what went wrong. Thank you so much!
Turns out it has just about nothing to do with daphne or my js code that doesn't work. I didn't connect to a heroku-redis at the time and thus was not running redis. Configured REDISTOGO_URL with
heroku config --app <appname> | grep REDISTOGO_URL
, changed host in channel_layer from "hosts": ('redis', 6379), (something similar) to "hosts": [os.environ.get('REDISTOGO_URL',('redis', 6379))] allowed me to connect to heroku redis.

webpack dev server proxy has an error : HPE_INVALID_CHUNK_SIZE

I use webpack-dev-server on my project.
Project uses Spring boot + Tiles + Vue + webpack.
Environment:
OS: Mac OS
Node Version: 9.4.0
NPM Version: 5.6.0
Webpack Version: 4.25.1
webpack-dev-server Version: 3.1.10
In local environment, FE port use 8080 and webpack-dev-server port is 9090.
Bundled files by webpack are created in /front/static-dev/build/.
So, I use proxy options like below.
devServer: {
publicPath: 'http://localhost:9090/front/static-dev/build/',
port: 9090,
proxy: {
'/**': {
target: 'http://localhost:8080',
secure: false,
changeOrigin: true
}
},
open: true
}
After starting webpack-dev-server, static resources like (JSP, bundled js files, CSS files or image, ...) are loaded normally. However, whenever I request some api, webpack-dev-server occured same error. Error logs are like below.
[HPM] Error occurred while trying to proxy
request /api/v1/users/name from localhost:9090 to
http://localhost:8080 (HPE_INVALID_CHUNK_SIZE)
(https://nodejs.org/api/errors.html#errors_common_system_errors)
After request some API, I checked logs on Eclipse and Api requests are normally being made. In Chrome Consloe log like below.
http://localhost:9090/api/v1/users/name net::ERR_CONTENT_DECODING_FAILED 502 (Bad Gateway)
I think the problems are in response part.
Searching HPE_INVALID_CHUNK_SIZE with Webpack in google, I can find no information.
How can I solve this problem.
Thanks.
I resolve this issue using Connection options.
proxy: {
'/**': {
target: 'http://localhost:8080/',
secure: false,
changeOrigin: true,
headers: {
Connection: 'keep-alive'
}
}
This error might be caused by wrong headers sent to your proxy. In case of any further problems you could try Transport-Encoding: chunked or set Content-Length http headers. You can see this answer https://stackoverflow.com/a/55433376/996895

proxy.conf.json is not working in angular 6 when i use ng build

I am trying to create a project using proxy to connect to the backend, but when generating the project with ng build, the proxy configuration does not work as it does with ng serve.
To generate use the following command:
ng build --prod --base-href = / myproyect /
Next I pass the files that I have of configuration:
proxy.conf.json:
{
"/api/*": {
"target": "http://localhost:8080/cystock/",
"secure": false,
"pathRewrite": {"^/api" : ""},
"changeOrigin": true,
"logLevel": "debug"
}
}
global.ts:
export const GLOBAL = {
production: true,
url: 'api'//<-- 'API/' prefix needed for proxy configuration
};
Note: The idea is to be able to consume localhost services, which is developed with JAVA using Spring as framework
As #vikas said, the proxy-config is strictly for development. It makes it easy to "mock" your endpoints while you're developing your application without the need for multiple configuration files.
The idea with proxy-config is that you proxy your production URL to a dev server (remote or local), and when you build your code without the proxy, it points to your production server.
To solve your issue specifically, just change /api to your production endpoint, and map it to a development server.

Resources