Buy commercial curl support. We
help you work out your issues, debug your libcurl applications, use the API,
port to new platforms, add new features and more. With a team lead by the
curl founder Daniel himself.
Re: Libcurl and WebSockets
- Contemporary messages sorted: [ by date ] [ by thread ] [ by subject ] [ by author ] [ by messages with attachments ]
From: Gavin D. Howard via curl-library <curl-library_at_lists.haxx.se>
Date: Mon, 20 Jan 2025 21:19:14 +0000
> It is a continued conversation because I can't quite understand how the API
> you speak of would work. You don't need any implementation for that, you can
> just explain it.
After rereading RFC 6455, and looking at the Curl Websocket API, I think
that the only API change would be to add something like `CURLWS_SERVER`
to `CURLOPT_WS_OPTIONS`.
If that is set in the options, libcurl would not do any masking, but it
would unmask any frames it receives.
This will work because WebSockets are purely bidirectional. As far as I
can tell, the *only* difference between client frames and server frames
is masking, unlike HTTP where requests and responses are entirely
different. I think that even `curl_ws_meta()` can work without changes.
Of the "Future work" [1] items, two are client-specific:
* Verify the Sec-WebSocket-Accept response.
* Verify Sec-WebSocket-Extensions and Sec-WebSocket-Protocol in the
response
The other items would apply equally to servers and would make server use
that much better.
As far as I can tell, the sole server-only API that libcurl might need
would be in handling the upgrade request. For that, there needs to be:
* Verify:
* Request-URI
* Host
* Origin
* A way to select which of the extensions to send back.
But I think this can be done outside of libcurl, so if it is, the sole
API change would be the addition of `CURLWS_SERVER`.
Obviously, the implementation would need to change:
* Masking
* Only mask if `CURLWS_SERVER` is not set.
* Unmask if `CURLWS_SERVER` is set.
* Closing
* The RFC requires servers to close the connection as soon as they
have sent or received the second `Close` frame, so close the
connection immediately when `CURLWS_SERVER` is set.
> > I already have a FastCGI implementation that I was going to use behind a
> > real server, as you say.
> >
> > But as far as I understand it, I still need to parse HTTP stuff with
> > that. Thus, I need to implement HTTP/1.1.
>
> It is true that you will have to parse some of HTTP 1.1 in a [Fast]CGI process. But that's a far cry from "implement HTTP 1.1".
Fair. But now you know what I meant: parsing HTTP 1.1 requests and
generating HTTP 1.1 responses.
> A real server handles logging, process management, persistence, connection management, .... It also interprets much of (and some of the trickiest parts of) HTTP - authentication, access controls, rate limits, usually some protection from malformed HTML [e.g. mod_security], and more.
Yes, and those are beyond my requirements for that reason.
> The URL is broken down; remote user, authentication type, request method - etc.
The URL could be taken care of by libcurl as-is, but yes, the rest
servers would take care of.
> Rather than re-invent these, it can be much easier (and more perfomant) to create a loadable module for the real server. This provides access to all the services of the server.
That would lock my VCS into one server.
> Never re-invent the wheel; use it.
Yes, that is what I am trying to do. I hope that is clear by now.
Gavin D. Howard
Member and Manager
Yzena, LLC
[1]: https://curl.se/docs/websocket.html#future-work
Date: Mon, 20 Jan 2025 21:19:14 +0000
> It is a continued conversation because I can't quite understand how the API
> you speak of would work. You don't need any implementation for that, you can
> just explain it.
After rereading RFC 6455, and looking at the Curl Websocket API, I think
that the only API change would be to add something like `CURLWS_SERVER`
to `CURLOPT_WS_OPTIONS`.
If that is set in the options, libcurl would not do any masking, but it
would unmask any frames it receives.
This will work because WebSockets are purely bidirectional. As far as I
can tell, the *only* difference between client frames and server frames
is masking, unlike HTTP where requests and responses are entirely
different. I think that even `curl_ws_meta()` can work without changes.
Of the "Future work" [1] items, two are client-specific:
* Verify the Sec-WebSocket-Accept response.
* Verify Sec-WebSocket-Extensions and Sec-WebSocket-Protocol in the
response
The other items would apply equally to servers and would make server use
that much better.
As far as I can tell, the sole server-only API that libcurl might need
would be in handling the upgrade request. For that, there needs to be:
* Verify:
* Request-URI
* Host
* Origin
* A way to select which of the extensions to send back.
But I think this can be done outside of libcurl, so if it is, the sole
API change would be the addition of `CURLWS_SERVER`.
Obviously, the implementation would need to change:
* Masking
* Only mask if `CURLWS_SERVER` is not set.
* Unmask if `CURLWS_SERVER` is set.
* Closing
* The RFC requires servers to close the connection as soon as they
have sent or received the second `Close` frame, so close the
connection immediately when `CURLWS_SERVER` is set.
> > I already have a FastCGI implementation that I was going to use behind a
> > real server, as you say.
> >
> > But as far as I understand it, I still need to parse HTTP stuff with
> > that. Thus, I need to implement HTTP/1.1.
>
> It is true that you will have to parse some of HTTP 1.1 in a [Fast]CGI process. But that's a far cry from "implement HTTP 1.1".
Fair. But now you know what I meant: parsing HTTP 1.1 requests and
generating HTTP 1.1 responses.
> A real server handles logging, process management, persistence, connection management, .... It also interprets much of (and some of the trickiest parts of) HTTP - authentication, access controls, rate limits, usually some protection from malformed HTML [e.g. mod_security], and more.
Yes, and those are beyond my requirements for that reason.
> The URL is broken down; remote user, authentication type, request method - etc.
The URL could be taken care of by libcurl as-is, but yes, the rest
servers would take care of.
> Rather than re-invent these, it can be much easier (and more perfomant) to create a loadable module for the real server. This provides access to all the services of the server.
That would lock my VCS into one server.
> Never re-invent the wheel; use it.
Yes, that is what I am trying to do. I hope that is clear by now.
Gavin D. Howard
Member and Manager
Yzena, LLC
[1]: https://curl.se/docs/websocket.html#future-work
-- Unsubscribe: https://lists.haxx.se/mailman/listinfo/curl-library Etiquette: https://curl.se/mail/etiquette.htmlReceived on 2025-01-20