Connecting a Websocket over a Caddy Proxy returns 405 Method Not Allowed with a POST call

hey folks, Im newer to websocket integration so bear with me. I have a spring boot project connecting to a websocket using sockjs-client from my react front end and connecting to a STOMP entrypoint on the spring boot backend. Locally, this works great. However, I am getting a 405 method not allowed when connecting to out railway project. We are using Caddy Proxy to create a proxied URL so this may have something to do with it although Im not sure.
my react call is: let sock = new SockJS('ws'); stompClient = over(sock); stompClient.connect({} ,onConnected, onError); which I get the error: Request URL: https://XXXXXXX.XXXXXXX.com/ws/021/bntqbx12/xhr_streaming?t=1721787651124 Request Method: POST Status Code: 405 Method Not Allowed Remote Address: 34.86.119.124:443 Referrer Policy: strict-origin-when-cross-origin this is because railway only allows for GET and HEAD requests.
Allow: GET, HEAD Content-Length: 0 Date: Wed, 24 Jul 2024 02:20:51 GMT Server: railway on the back end: @Configuration @EnableWebSocketMessageBroker @EnableWebSocket public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) { stompEndpointRegistry.addEndpoint("/ws") .setAllowedOriginPatterns("*") .withSockJS(); } we also have a package json proxy as well for our api requests if that is also important: "proxy": "http://locahost:8081" I can provide more info if you need it. Thanks in advance!
22 Replies
Percy
Percy3mo ago
Project ID: e48131f7-096a-4b0a-8733-ecc43f93da7b
knightlock_
knightlock_3mo ago
e48131f7-096a-4b0a-8733-ecc43f93da7b
Brody
Brody3mo ago
why the need for caddy to begin with? also, please dont obfuscate things like this xxxxxxx.xxxxxxx.com its not helpful
knightlock_
knightlock_3mo ago
sorry, ya no worries --> https://assignments-dev.coderscampus.com/ws/021/bntqbx12/xhr_streaming?t=1721787651124 Request Method: POST Status Code: 405 Method Not Allowed Remote Address: 34.86.119.124:443 Referrer Policy: strict-origin-when-cross-origin
Assignment Submission
Web site created using create-react-app
knightlock_
knightlock_3mo ago
I believe we were using caddy to generate a public domain
Brody
Brody3mo ago
Railway generates a public domain for you with SSL and for websocket connections wouldnt you send a GET request to wss://assignments-dev.coderscampus.com/ws/021/bntqbx12/xhr_streaming?t=1721787651124
knightlock_
knightlock_3mo ago
hmmm, Im getting the error
main.js:73 Uncaught
SyntaxError: The URL's scheme must be either 'http:' or 'https:'. 'wss:' is not allowed.
main.js:73 Uncaught
SyntaxError: The URL's scheme must be either 'http:' or 'https:'. 'wss:' is not allowed.
Brody
Brody3mo ago
why would wss not be allowed for a websocket endpoint does the request need to be a post type? are you sending data in the body?
knightlock_
knightlock_3mo ago
hmm maybe its the library Im using? Im not exaclty sure, using sock-js-client nope, just trying to connect
Brody
Brody3mo ago
either way, why caddy? send the caddyfile so i can get an idea of what you are trying to do
knightlock_
knightlock_3mo ago
ya for sure,
{ # global options
admin off # theres no need for the admin api in railway's environment
persist_config off # storage isn't persistent anyway
auto_https off # railway handles https for us, this would cause issues if left enabled
log { # runtime logs
format console # set runtime log format to console mode
}
servers { # server options
trusted_proxies static private_ranges # trust railway's proxy
}
}

:{$PORT} { # site block, listens on the $PORT environment variable, automatically assigned by railway
log { # access logs
format console # set access log format to console mode
}

# health check for railway
respond /health 200

# serve from the 'build' folder
root * build

# enable gzipping responses
encode gzip

# serve files from 'build'
file_server

# if path doesn't exist, redirect it to 'index.html' for client side routing
try_files {path} /index.html
}
{ # global options
admin off # theres no need for the admin api in railway's environment
persist_config off # storage isn't persistent anyway
auto_https off # railway handles https for us, this would cause issues if left enabled
log { # runtime logs
format console # set runtime log format to console mode
}
servers { # server options
trusted_proxies static private_ranges # trust railway's proxy
}
}

:{$PORT} { # site block, listens on the $PORT environment variable, automatically assigned by railway
log { # access logs
format console # set access log format to console mode
}

# health check for railway
respond /health 200

# serve from the 'build' folder
root * build

# enable gzipping responses
encode gzip

# serve files from 'build'
file_server

# if path doesn't exist, redirect it to 'index.html' for client side routing
try_files {path} /index.html
}
Brody
Brody3mo ago
this just serves a frontend website i know that, because i wrote that
knightlock_
knightlock_3mo ago
ooo nice! Thanks for writing it! We were just experimenting, my co worker and I and we came on some examples, so far its working as it should, but you think its overkill? Maybe messing with the domain?
Brody
Brody3mo ago
no one has ever had issues with that caddyfile that i know of, using caddy to serve a frontend website is going to be by far the best way to do it on railway in my experience so the issue is elsewhere can you send a screenshot of your project canvas please
knightlock_
knightlock_3mo ago
yup for sure, is this it here?
No description
Brody
Brody3mo ago
okay and what is the caddy proxy for? i wrote that too, but i see a lot of people using it when they actually dont need to be
knightlock_
knightlock_3mo ago
well, it looks like all we're doing here is connecting our front and back end under one domain
Brody
Brody3mo ago
is that strictly needed?
knightlock_
knightlock_3mo ago
honestly cant say for sure, Id have to ask my co worker but is there an alternative you think instead? By removing the caddy proxy, you think it should clear the air? oop, holdup, I may have sent you the wrong caddy file -->
# global options
{
admin off # theres no need for the admin api in railway's environment
persist_config off # storage isn't persistent anyway
auto_https off # railway handles https for us, this would cause issues if left enabled
# runtime logs
log {
format json # set runtime log format to json mode
}
# server options
servers {
trusted_proxies static private_ranges # trust railway's proxy
}
}

# site block, listens on the $PORT environment variable, automatically assigned by railway
:{$PORT} {
# access logs
log {
format json # set access log format to json mode
}

reverse_proxy {$FRONTEND_HOST} # proxy all requests for /* to the frontend, configure this variable in the service settings

# the handle_path directive will strip /api/ from the path before proxying
# this is needed if your backend's api routes don't start with /api/
# change paths as needed
#handle_path /api/* {
# this strips the /api/ prefix from the uri sent to the proxy address
# reverse_proxy {$BACKEND_HOST} # proxy all requests for /api/* to the backend, configure this variable in the service settings
#}

# if your backend's api routes do start with /api/ then you wouldn't want to strip the path prefix
# if so, comment out the above handle_path block, and uncomment this reverse_proxy directive
# change paths as needed
reverse_proxy /api/* {$BACKEND_HOST} # configure this variable in the service settings
}
# global options
{
admin off # theres no need for the admin api in railway's environment
persist_config off # storage isn't persistent anyway
auto_https off # railway handles https for us, this would cause issues if left enabled
# runtime logs
log {
format json # set runtime log format to json mode
}
# server options
servers {
trusted_proxies static private_ranges # trust railway's proxy
}
}

# site block, listens on the $PORT environment variable, automatically assigned by railway
:{$PORT} {
# access logs
log {
format json # set access log format to json mode
}

reverse_proxy {$FRONTEND_HOST} # proxy all requests for /* to the frontend, configure this variable in the service settings

# the handle_path directive will strip /api/ from the path before proxying
# this is needed if your backend's api routes don't start with /api/
# change paths as needed
#handle_path /api/* {
# this strips the /api/ prefix from the uri sent to the proxy address
# reverse_proxy {$BACKEND_HOST} # proxy all requests for /api/* to the backend, configure this variable in the service settings
#}

# if your backend's api routes do start with /api/ then you wouldn't want to strip the path prefix
# if so, comment out the above handle_path block, and uncomment this reverse_proxy directive
# change paths as needed
reverse_proxy /api/* {$BACKEND_HOST} # configure this variable in the service settings
}
Brody
Brody3mo ago
i think there are some misunderstandings on your side as to why you need the proxy, i would eliminate it and go from there have your frontend call the backend's domain directly, you of course will need to setup cors on your backend but thats a 5 minute tutorial and done
knightlock_
knightlock_3mo ago
okay ya for sure! I'll try this and get back to you. Thanks for your help!
Brody
Brody3mo ago
no problem oh and the reason you where getting 405 Method Not Allowed is because the path /ws/021/bntqbx12/xhr_streaming is a path in the frontend. my proposed solution still stands though
Want results from more Discord servers?
Add your server