Understanding connectHeaders when using stomp client - stomp

I am connecting to an websocket endpoint using stompjs. One of the parameters is connectHeaders headers but it does not use these headers in the http request headers? Where does it use these headers?
export const stompClient = new Client({
brokerURL: "ws://localhost:8080/gs-guide-websocket",
connectHeaders: {
Ad: "asjfasfjldskfjsklfajsdklfasdf",
login: "user",
passcode: "password"
},
debug: function (str) {
console.log(str);
},
});

Those headers are used in the Stomp frame, specifically the CONNECT frame. Stomp frames are modeled on HTTP frames, but they are not synonymous. Stomp headers are distinct from HTTP headers as Stomp is not tied to HTTP. As noted in the Stomp 1.2 specification for the CONNECT frame:
STOMP 1.2 clients MUST set the following headers:
accept-version : The versions of the STOMP protocol the client supports. See Protocol Negotiation for more details.
host : The name of a virtual host that the client wishes to connect to. It is recommended clients set this to the host name that the socket was established against, or to any name of their choosing. If this header does not match a known virtual host, servers supporting virtual hosting MAY select a default virtual host or reject the connection.
STOMP 1.2 clients MAY set the following headers:
login : The user identifier used to authenticate against a secured STOMP server.
passcode : The password used to authenticate against a secured STOMP server.
heart-beat : The Heart-beating settings.

Related

HTTPS over Socks5 server implementation

I am trying to implement a Socks5 server that could relay both HTTP and HTTPS traffic.
As the RFC1928 mentions, the following steps to establish a connection and forward the data must be taken :
Client sends a greeting message to the proxy.
Client & proxy authentication (assuming it is successful).
Client sends a request to the proxy to connect to the destination.
The proxy connects to the destination and sends back a response to the client to indicate a successful open tunnel.
The proxy reads the data from the client and forwards it to the destination.
The proxy reads the data from the destination and forwards it to the client.
So far, the proxy works as it should. It is able to relay HTTP traffic using its basic data forwarding mechanism. However, any request from the client to an HTTPS website will be aborted because of SSL/TLS encryption.
Is there another sequence/steps that should be followed to be able to handle SSL/TLS (HTTPS) traffic?
The sequence you have described is correct, even for HTTPS. When the client wants to send a request to an HTTPS server through a proxy, it will request the proxy to connect to the target server's HTTPS port, and then once the tunnel is established, the client will negotiate a TLS handshake with the target server, then send an (encrypted) HTTP request and receive an (encrypted) HTTP response. The tunnel is just a passthrough of raw bytes, the proxy has no concept of any encryption between the client and server. It doesn't care what the bytes represent, its job is just to pass them along as-is.

Implementing websocket support for HTTP/2 proxies

I am developing an https http/2 proxy server as mentioned here:
https://chromium.googlesource.com/chromium/src/+/HEAD/net/docs/proxy.md#HTTPS-proxy-scheme
It is mentioned there that
HTTPS proxies using HTTP/2 can offer better performance in Chrome than a regular HTTP proxy due to higher connection limits (HTTP/1.1 proxies in Chrome are limited to 32 simultaneous connections across all domains).
But when users try to surf a website which is using websocket over raw http connection, the response contains 'Upgrade' http header which is forbidden to be used in http/2 as there is no websockets for HTTP/2.
https://daniel.haxx.se/blog/2016/06/15/no-websockets-over-http2/#:~:text=There%20is%20no%20websockets%20for%20HTTP%2F2.&text=That%20spec%20details%20how%20a,connection%20into%20a%20websockets%20connection.
The problem comes from the fact that when http1.1 traffic passes through an https proxy which implements http/2, headers must be transferred from http1.1 to http/2. Of course when the webpage is using TLS, there is no such a problem as all traffic passes through a connection made by http 'CONNECT' method. The problem occurs when the website does not use TLS.
If there is no solution to this problem, it means that HTTPS proxies should not implement HTTP/2 protocol.
As there is no websockets for HTTP/2
The link you posted is old, and since then WebSocket over HTTP/2 has been specified by RFC 8441.
The behavior of a HTTP/2 proxy is specified in RFC 7540, section 8.3.
When the client communicates with the proxy using secure HTTP/2, each HTTP/2 stream is a "tunnel" to the server.
Client and proxy communicate using secure HTTP/2, and the "tunnelling" happens because each HTTP/2 stream becomes an "infinite" request with an "infinite" response, i.e. an "infinite" series of HTTP/2 DATA frames in both directions that carry an opaque byte array payload.
The job of the proxy is to unwrap the DATA frames received by the client, and forward the byte array payload to the server, perhaps re-wrapping it into an HTTP/2 DATA frame if the communication between proxy and server is also HTTP/2 (it may be possible to optimize away the unwrapping and re-wrapping but it may be tricky -- for example the stream numbering could be different).
When a client attempts to perform WebSocket over HTTP/2, the browser will do as specified by RFC 8441, and the proxy will receive a CONNECT request with a :protocol pseudo-header, and the proxy will have to know what to do in that case, depending on what protocol it uses to communicate with the server.
What above describes what your proxy need to support when the communication with the client is HTTP/2.
If your proxy needs to support clients that speak HTTP/1.1, then you need to implement what is required for a proxy to support HTTP/1.1 and WebSocket proxying, and it's typically not difficult: the first is just HTTP/1.1 forwarding or HTTP CONNECT "tunnelling", the second is WebSocket HTTP Upgrade request forwarding followed by a "tunnel" connection or even a fully fledged WebSocket proxy.
Disclaimer, I have implemented all of the above in the Jetty Project.
You can use Jetty 10 or later to implement an HTTP/1.1, HTTP/2, or WebSocket, both client and server (and therefore a proxy). WebSocket over HTTP/2 is supported too.
Finally, to answer your last question, it is perfectly possible to have secure proxies support HTTP/2, even in presence of WebSocket.
For example, a clear-text WebSocket connection to a server starts with an HTTP upgrade request; this request will be sent, encrypted, to the proxy which will decrypt it and forward it to the server (using any protocol the server supports -- could even be WebSocket over secure HTTP/2); the server will reply with a 101 and upgrade the connection to WebSocket; the proxy will receive the 101 from the server and upgrade to a "tunnel" or to a WebSocket proxy; the proxy encrypts the 101 response and forward it to the client; the client decrypts it and upgrades the connection to WebSocket.
At this point, the client is speaking clear-text WebSocket to the server through a secure connection with the proxy (the proxy sees the clear-text WebSocket communication).
Viceversa, a secure WebSocket connection to a server starts with establishing a HTTP CONNECT tunnel through the proxy to the server; then the client will establish the secure communication with the server; then it will send the HTTP upgrade to WebSocket to the server (through the proxy tunnel).
At this point, the client is speaking secure WebSocket to the server through a secure connection with the proxy (the proxy cannot see the WebSocket communication).
The HTTP/2 variants are similar, just taking into account the HTTP/2 specific ways of "tunnelling" and transporting WebSocket.

Difference between ws and wss?

What is the procedure to change ws into wss?
Whether wss is make upgrade over normal HTTP or wss works only HTTPS?
webSocket = new WebSocket("ws://localhost:port/Esv/ocp");
works fine, when I changed ws to wss
webSocket = new WebSocket("wss://localhost:port/Esv/ocp");
it shows this error:
Error in connection establishment: net::ERR_SSL_PROTOCOL_ERROR
Short version
To SSL or not SSL
You may have a SSL certificate issue. The connection point rule can be summarized as:
wss connects on https only
ws connects on http
and vice-versa:
https accepts wss only
http accepts ws only
Errors
Following situations will lead you to an error (tests done under Firefox):
If you want to connect a wss connection to a http endpoint. In my tests, I had an
InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable
If you want to connect a ws connection to a https endpoint, you'll have the error
SecurityError: The operation is insecure.
Formal answer
The bible of websocket is RFC 6455. In section 4.1.5:
If /secure/ is true, the client MUST perform a TLS handshake over the connection after opening the connection and before sending the handshake data [RFC2818]. If this fails (e.g., the server's certificate could not be verified), then the client MUST Fail the WebSocket Connection and abort the connection. Otherwise, all further communication on this channel MUST run through the encrypted tunnel [RFC5246].
The secure flag is defined by the URI. Section 3 defines what is secure
The URI is called "secure" (and it is said that "the secure flag is set") if the scheme component matches "wss" case-insensitively.
TL;DR
If you want to use wss:
you must have SSL activated
your endpoint point must be secured (https://...): "security downgrade" is not allowed
If you want to use ws:
Make sure your endpoint does not have SSL enabled (http://...)

Advanced Restclient socket implementation can not connect to Spring Websocket

I have developed a chat application by using Spring Stomp and socketjs .
I have successfully connected to the websocket over my clients but I can not connect to websocket by using Advanced Restclient -> socket implementation.
Why?
Thanks
if i didnt use socketjs , i can succeed to connect over Advanced Rest Client. To connect websocket without using socketjs, you should set the allowed origins : setAllowedOrigins('*')
Also if you are using stomp without socketjs , you can succeed to open a websocket connection via Advanced Rest Client, because stomp just a sub-protocol over websocket connection. But to receive messages over websocket, you should subscribe to STOMP queue, it is impossible with Advanced Rest Client.
-
Restclients runs on http protocol. Restclients not yet understand the web socket and sock JS protocol. That is the reason your rest client didn't connected to server.

RabbitMQ Web STOMP without SockJS

Is it possible to setup RabbitMQ Web STOMP connection without SockJS library?
I have played around with rabbitmq-web-stomp plugin without a success as the initial response generated by the server is Welcome to SockJS! (which is obviously not a STOMP based message).
Is SockJS really required? What does it bring into the game (besides legacy browser support)?
SockJS protocol does support raw WebSocket clients under /websocket path.
Any SockJS server complying with 0.3 protocol does support a raw WebSocket url. The raw WebSocket url for the test server looks like:
ws://localhost:8081/echo/websocket
You can connect any WebSocket RFC 6455 compliant WebSocket client to this url.
This is supported by Rabbit's implementation as well. So the default endpoint is: http://example.com:15674/stomp/websocket.

Resources