curl / Mailing Lists / curl-library / Single Mail
Buy commercial curl support from WolfSSL. 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 himself.

RE: About a websockets write callback

From: Dmitry Karpov via curl-library <>
Date: Mon, 20 Jun 2022 21:58:59 +0000

Yes, it would be nice to have just one callback for all WS modes (RAW, FRAME, MESSAGE) but using CURLOPT_WRITEFUNCTION callback for that purpose doesn't seem like an optimal solution to me because of the problems related to passing curl handle to it and making a function call to get WS context metadata.

All WS levels above RAW (frames, messages) require using WS context metadata for a WS data chunk to use it properly, and calling 'curl_ws_metadata(curl_handle, ...)' in every CURLOPT_WRITEFUNCTION callback seems as a too high price.
No matter how fast is libcurl searching mechanism used to find WS "context data" by a curl handle, it can't compare to the instant time which a pointer to WS "context data" passed in the "write callback" provides.

And if we look at typical WS frameworks, they provide WS metadata as part of their WS events and callbacks.

I think if we separate CURLOPT_WRITEFUNCTION callback (Raw data) from CURLOPT_WS_WRITEFUNCTION callback (WS data) it will not really make things obscure, especially for folks familiar with WebSockets.
The CURLOPT_WRITEFUNCTION will carry the same meaning - opaque HTTP data and CURLOPT_WS_WRITEFUNCTION callback will carry WS payloads with WS metadata available (frame or message depending on the context).

And we can extend CURLOPT_WS_WRITEFUNCTION to an even more generic callback - "high_level_protocol_write_function " - a callback which can be used to pass high-level protocol data running on top of HTTP (or some other transport protocol).

This callback can have parameters: protocol (WS in our case), data, size, protocol_context, userdata (maybe some more), and can be used as a general mechanism for protocols like WS.
With this approach, the CURLOPT_WRITEFUNCTION will be always kept as a callback for the "primary" transport protocol (like HTTP for WS) - and provide raw data carried over that protocol.

And I think that such separation between the low-level transport layer and high-level protocol layers is not difficult to understand and document, and it provides a quite flexible mechanism for implementing data callbacks for complex protocols with many options.

Dmitry Karpov

-----Original Message-----
From: Daniel Stenberg <>
Sent: Saturday, June 18, 2022 4:08 AM
To: Dmitry Karpov via curl-library <>
Cc: Dmitry Karpov <>
Subject: RE: About a websockets write callback

On Fri, 17 Jun 2022, Dmitry Karpov via curl-library wrote:

> 1. CURLOPT_WRITEFUNCTION callback - provides raw WS data after initial
> WS negotiation over HTTP is done.

> - This would allow to plugin easily existing custom WS implementations
> that use their own frame parsing and message assembling.

Oh yes that's a neat idea! I like this.

> 2. WS_FRAME_WRITEFUNC callback - provides parsed WS frame information
> - header and frame data.
> - This would allow to provide custom WS extensions, like multiplexing etc.

I think I prefer to re-use the same callback, in particular if you think of applications that would use a mix of websocket and other protocols to download data. But in the frame-parse mode there needs to be a way for the application to figure out the parsed details of the frame.

> 3. WS_MSG_WRITEFUNC callback - provides assembled WS message
> information - message data and metadata.

I think I prefer to have an option for "ws mode" that would be RAW, FRAME or MESSAGE and have the same callback used for all of them. But the 'MESSAGE'
mode might be something I save for a later PR once RAW and FRAME have landed work.

Having the same callback also removes the problems of having mulitple mutually exclusive options and protocol-specific behaviors for options == easier to document and for users to understand the data flow.

  | Commercial curl support up to 24x7 is available!
  | Private help, bug fixes, support, ports, new features
Received on 2022-06-20