Libcurl - CURLMOPT_TIMERFUNCTION - what is it for? - c++

Tell me please, i just can't figure out what the CURLMOPT_TIMERFUNCTION parameter is used for.
Yes, of course I read the entire description about CURLMOPT_TIMERFUNCTION:
CURLMOPT_TIMERFUNCTION
timer_callback
hiperfifo
And I still don't understand what he does and why he is wanted.
For example:
Certain features, such as timeouts and retries, require you to call
libcurl even when there is no activity on the file descriptors.
Your callback function timer_callback should install a non-repeating
timer with an expire time of timeout_ms milliseconds. When that timer
fires, call either curl_multi_socket_action or curl_multi_perform,
depending on which interface you use.
I don't understand why I should call curl_multi_socket_action() from the CURLMOPT_TIMERFUNCTION callback and not from the event callback?

This is for curl to take action when requests were not answered in time. You need to call curl back periodically so it does its own internal housekeeping.
Imagine you made a request to curl and curl took action on it but could not connect at that time. Curl cannot hang the process waiting for the connect so it returns the control to you and relies on you returning the control back to curl for checking if it can connect periodically.

Related

GRPC C++ Async Server How differentiate between WritesDone and broken connection

When developing an Async C++ GRPC Server, how can I differentiate between the client being done with writing and the connection being broken ?
I am Streaming data from the client to the server and once the client is done it will call WritesDone to let the server know it should finish storing the file. If I have a sync server I can differentiate between the client calling WritesDone and the connection being broken by calling context->IsCancelled() but in async mode you can not call IsCancelled until you get the tag specified in AsyncNotifyWhenDone.
In both cases (WritesDone and Call done) the Read tag gets returned with ok set to false. However, the AsyncNotifyWhenDone tag, which would allow me to differentiate arrives after the read tag.
I will know after I try to call finish (it will also return false) but I need to know before I call finish as my final processing might fail and I can't return the error anymore if I already called finish.
There's no way to distinguish until the AsyncNotifyWhenDone tag returns. It may come after the Read in which case you may need to buffer it up. In the sync API you can check IsCancelled() anytime (and you can also do that in the Callback API which should be available for general use soon).

Howto implement http streaming using libcurl

I am trying to use CURL to implement Microsoft’s EWS Streaming Notifications i.e. HTTP Streaming where the request is sent once and the server responds with a header with "Transfer Encoding: chunked". The server will send multiple keepalive or notification chunks before the final packet. The chunks are terminated with cr lf.
If I create a standard CURL client then curl_easy_perform will not return until the final chunk is received whereas I need curl_easy_perform to return upon receipt of each chunk whereupon the application will process the received chunk and call curl_easy_perform to wait for the next chunk.
I realize that I could process the chunk in the CURLOPT_WRITEFUNCTION callback but the architecture of the application doesn’t allow for that (this is a GSOAP plugin)
Any suggestions other than switching to CURLOPT_CONNECT_ONLY and handling the write all subsequent reads with curl_easy_send and curl_easy_recv? Which seems a shame as I will have to duplicate CURL’s formatting and parsing.
Alan
curl_easy_perform is completely synchronous and will return only once the entire transfer is done. There's really no way around that (you already mentioned CURLOPT_CONNECT_ONLY and I wouldn't recommend that either) with this API.
If you want control back in the same thread before the entire transfer is done, which your question suggests, you probably rather want to use the multi interface.
Using that interface, curl_multi_perform will only do as much as it can right now without blocking and return control back to your function. It does however put the responsibility over to your code to wait for socket activity and call libcurl again when there is.
(Sorry, but I don't know what restrictions a "GSOAP plugin" has and you didn't state them here, so maybe this is all crap)

Download progress using SFML's HTTP class?

So I'm wondering what is a good way of getting the progress of a download when using SFML's HTTP Class / using HTTP in general. The only way I've thought of being able to do it is using tons of ranged GET requests in a separate thread, but that ofc makes the download take much longer with all the requests and all.
Any ideas?
You can't. If you want progress information, you should either implement it yourself (not recommended) or use another library for networking.
From the documentation of sf::Http::sendRequest:
Warning: this function waits for the server's response and may not return instantly; use a thread if you don't want to block your application, or use a timeout to limit the time to wait.
In other words, it's a blocking method that return only on timeout or completion (success or error).
Maybe have a look at libcurl, cpp-netlib or maybe some other libraries.

Boost ASIO Network Timing Issue

I am using boost::asio to implement network programming and running into timing issues. The issue is currently most with the client.
The protocol initially begins by the server returning a date time string to the user, and the client reads it. Up to that part it works fine. But What I also want is to be able to write commands to the server which then processes them. To accomplish this I use the io_service.post() function as shown below.
io_service.post(boost::bind()); // bounded function calls async_write() method.
For some reason the write tries happens before the initial client/server communication, when the socket has not been created yet. And I get bad socket descriptor error.
Now the io_service's run method is indeed called in another thread.
When I place a sleep(2) command before post method, it work fine.
Is there way to synchronize this, so that the socket is created before any posted calls are executed.
When creating the socket and establishing the connection using boost::asio, you can define a method to be called when these operations have either completed or failed. So, you should trigger your "posted call" in the success callback.
Relevant methods and classes are :
boost::asio::ip::tcp::resolver::async_resolve(...)
boost::asio::ip::tcp::socket::async_connect(...)
I think the links below
will give u some help
http://www.boost.org/doc/libs/1_42_0/doc/html/boost_asio/reference/io_service.html

how can I get libcurl to callback BEFORE it sends some information on a post?

I'm uploading information to a server using a post call (using curlpp, but libcurl directly is fine too).
CURLOPT_PROGRESSFUNCTION callback gets called from time to time with reports on how much data was send until now. When I upload a file, I see this call being made with very small delta between calls.
I want to get a callback BEFORE each part of data is sent, with the information of how much data is going to be transmitted now.
There is no such callbacks in libcurl. CURLOPT_DEBUGFUNCTION will tell you basically that info, but after it was sent...
You might use the callback to be set by passing CURLOPT_READFUNCTION to curl_easy_setopt().
This assumes that the amount of data to be read by this callback function will be the size of the next chunk to be sent.
For details please see here: http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTREADFUNCTION