Reputation: 92149
I see that there is websocket endpoint which works out fins with Java tests. In logs I see
Connecting to: ws://127.0.0.1:8080/76f48a44-0af8-444c-ba97-3f1ed34afc91/tweets
Just like any other REST
API I would like to hit it via browser or curl, but when I do that I see
➜ tweetstream git:(master) ✗ curl ws://127.0.0.1:8080/b9b90525-4cd4-43de-b893-7ef107ad06c2/tweets
curl: (1) Protocol ws not supported or disabled in libcurl
and
➜ tweetstream git:(master) ✗ curl http://127.0.0.1:8080/b9b90525-4cd4-43de-b893-7ef107ad06c2/tweets
<html><head><title>Error</title></head><body>Not Found</body></html>%
Is there a way to test websocket APIs with browser/curl?
Upvotes: 20
Views: 49500
Reputation: 18973
tl;dr curl -H 'Upgrade: websocket' -H "Sec-WebSocket-Key: `openssl rand -base64 16`" -H 'Sec-WebSocket-Version: 13' --http1.1 -sSv https://ws.ifelse.io
(depending on the server you might need to provide Origin
and/or Connection: Upgrade
)
First, how does the websocket protocol work in a few words? A client connects to a server, sends a handshake request, receives "101 Switching Protocols" (a handshake response) after which they send frames back and forth.
The handshake looks along the following lines:
GET / HTTP/1.1
Host: ws.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Version: 13
Origin: http://example.com
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Upgrade
makes it switch from HTTP(s) to the websocket protocol.
Connection
specifies that Upgrade
is a hop-by-hop header (headers that intermediaries should consume, not forward). But my experiments show that it works w/o this header. Or to be more precise, it might be optional if there's a reverse proxy in front of the server (e.g. nginx
).
Sec-WebSocket-Key
/Sec-WebSocket-Accept
is a security measure described here, here and here.
Sec-WebSocket-Version
specifies the websocket protocol version. According to RFC 6455 it should be equal 13.
Origin
is needed when the client is a browser and the origin of the requesting page doesn't match the origin of the websocket server URL.
A detailed description of what should constitute a websocket handshake request can be found here.
That's how it goes with HTTP/1.1. HTTP/2 is a different story.
Knowing this to establish a websocket connection with curl
:
$ curl -H 'Upgrade: websocket' \
-H "Sec-WebSocket-Key: `openssl rand -base64 16`" \
-H 'Sec-WebSocket-Version: 13' \
--http1.1 \
-sSv \
https://ws.ifelse.io
...
> GET / HTTP/1.1
> Host: ws.ifelse.io
> Upgrade: websocket
> Sec-WebSocket-Key: e2dujvcbYbN747lapeH+WA==
> Sec-WebSocket-Version: 13
...
< HTTP/1.1 101 Switching Protocols
< Connection: upgrade
< upgrade: websocket
< sec-websocket-accept: 6wmMGMtN00aWw3loYd6P36EHKMI=
The other options are wscat
, websocat
.
Upvotes: 2
Reputation: 77
curl --include \
--no-buffer \
--header "Connection: Upgrade" \
--header "Upgrade: websocket" \
--header "Host: echo.websocket.org" \
--header "Origin: http://echo.websocket.org" \
--header "Sec-WebSocket-Version: 13" \
http://echo.websocket.org
Add the header if you have an additional sub-protocol configured for the WebSocket endpoint:
--header "Sec-protocol: protocol-name"
Replace thee Origin, Host and endpoint to test with your own server. If you have basic auth enabled, add the Authorization header like this:
--header "Authorization: Basic RVZCLVAxNzI2MzAzOv"
Upvotes: 1
Reputation: 38742
For completeness, I'd like to add my own CLI tool: websocat.
$ websocat wss://echo.websocket.org/
qwer
qwer
1234
1234
It does not do the "browser" part of the question, but should be a valid substitute for "curl" in this case.
Upvotes: 9
Reputation: 31
I have used this and found it to be quite simple
http://www.websocket.org/echo.html
Upvotes: 2
Reputation: 3043
I had to use this command to make it work:
$ curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Host: echo.websocket.org" -H "Origin: http://www.websocket.org" -H "Sec-WebSocket-Version: 13" -H 'Sec-WebSocket-Key: +onQ3ZxjWlkNa0na6ydhNg==' http://www.websocket.org
I am using Jetty, and if I didn't add the Sec-WebSocket-Version/Sec-WebSocket-Key doesn't work. Just for the record.
Upvotes: 5
Reputation: 9
I wrote a cURL like WebSocket client. You can send single data frame (text/binary) via this tool and then it closes the socket. Also you can add HTTP headers in the initial HTTP upgrade process.
https://github.com/jussmen/WebSocket_cURL
Upvotes: 0
Reputation: 2788
This did the trick for me:
$ curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Host: echo.websocket.org" -H "Origin: http://www.websocket.org" http://echo.websocket.org
from: http://www.thenerdary.net/post/24889968081/debugging-websockets-with-curl
Upvotes: 17
Reputation: 331
If you mean literally to test the implementation of websockets, I found Autobahn's test suite to be very useful: http://autobahn.ws/
If you just want to noodle with a websocket I would recommend using the developer tools in a browser like chrome to make a connection and send/recv data:
var ws = new WebSocket("ws://127.0.0.1:8080/76f48a44-0af8-444c-ba97-3f1ed34afc91/tweets");
ws.onclose = function() { // thing to do on close
};
ws.onerror = function() { // thing to do on error
};
ws.onmessage = function() { // thing to do on message
};
ws.onopen = function() { // thing to do on open
};
ws.send("Hello World");
Upvotes: 11