cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re[2]: Working with curl connections as with sockets.

From: Tetetest <tetetest_at_rambler.ru>
Date: Mon, 28 Apr 2008 20:45:59 +0400

Hello Daniel,

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
DS> perform.

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
one.

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:

Issue 1.
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.

Issue 2.
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.

Item 3.
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
objections.

-- 
Best regards,
 Tetetest                            mailto:tetetest_at_rambler.ru
Received on 2008-04-28