Re: Working with curl connections as with sockets.
Date: Mon, 28 Apr 2008 20:45:59 +0400
Sunday, April 27, 2008, 2:11:28 AM, you wrote:
>> 'Send' for sending, 'recv' for receiving, and something like 'poll' (or
>> 'select') to check if data is available for reading or sendable. That should
>> be pretty enough for everyone. Other functionality (like reading strings in
>> string-oriented protocols) could easily be implemented using these three
>> basic functions.
DS> I would think that poll() and select() are already perfectly fine to use as
DS> they are, and I'd rather avoid introducing our own versions as long as we
DS> don't have to. Remember that we do provide an API for the app to extract the
DS> raw socket and that could be used fine with select()/poll()/epoll()/whatever
DS> even if libcurl-specific recv and send functions are then invoked to actually
I agree with you.
>> And those geeks who send OOB data over non-blocking sockets should resort to
>> good old CURLINFO_LASTSOCKET.
DS> I don't understand this remark. The socket will be non-blocking and thus
DS> send() and recv() will only send and receive as much as they can without
DS> blocking. Or are you also suggesting we should support a blocking mode?
Hmmm... Sorry, it's my fault - just discard the remark.
I thought that the socket returned by CURLINFO_LASTSOCKET was a blocking
Anyway, I have done some experiments, and here are the results:
- curl_easy_send() and curl_easy_recv() are fairly easy to implement
on the basis of Curl_write(), Curl_read(),
curl_easy_getopt(CURLINFO_LASTSOCKET), and some glue code.
Yet, I must admit that the initial idea of using option
CURLOPT_CONNECT_ONLY does not work fine. At least, it requires some
modifications to the existing code:
Currently, if you use this option, curl_easy_perform() returns
immediately after it connects to the proxy. It leaves you with the
socket that is basically unusable: you must perform the proxy
negotiation yourself. So, CURLOPT_CONNECT_ONLY should connect you
THROUGH the proxy, and not TO the proxy.
In fact, it is more logical: if you connect, say, to google.com, you
expect that you get the socket to google, and not to some proxy that
was loaded from your .netrc file.
Fix: Curl_perform() should return somewhat farther in the code, just
after the negotiation with proxy is over.
Not all kinds of proxies can be used with send/recv. Namely, you
cannot use 'usual' (non-tunnelling) HTTP proxies: they require that
you send specially-formed requests.
Fix: nothing can be done here from libcurl's perspective; should be
handled by the application.
Currently, proxy negotiation is added to every supported protocol
individually (correct me if I'm wrong here, but I didn't see any proxy
support in, say, tftp.c or telnet.c). So I have two options:
- introduce some imaginary "protocol" that will be used together with
CURLOPT_CONNECT_ONLY to establish a connection through proxy.
Moreover, such a protocol could automatically set
CURLOPT_CONNECT_ONLY option: getting "raw://www.google.com:80/"
would connect to google via your proxy and return.
The downside of this approach is clear: one more protocol means that
you have more things to synchronize when adding new features.
- Or, use existing protocol with good support for proxies (e.g., HTTP);
add minor modifications that will check that set.connect_only ==
TRUE, and cause the handler to stop transfer as soon as the
connection through proxy is established.
Clearly, I better like the second approach. I have checked it with
some proxies out there, and it works. Besides, it requires fewer
modifications to the code.
Please inform if you have any comments, questions, corrections or
-- Best regards, Tetetest mailto:tetetest_at_rambler.ruReceived on 2008-04-28