I've proved that libcurl IS NOT sending parameters! In certain conditions, when using NTLM proxy.
It basically makes libcurl's NTLM proxy unusable for us, because while it doesn't happen every connection, it happens more like 1/10 connections, and we fire off hundreds of connections. And sometimes it will reliably happen on a certain URL, meaning certain URLs are unaccessable.
This bug appears more often using the multi interface, especially when firing off one connection quickly after the last has been completed.
The timing seems to be the most important thing. A delay before one connection and the next, seems to make the bug less likely to occur. However, sometimes the bug always appears even if we are talking about the first connection. So this behaviour is quite random, but it appears to have something to do with timing, and reusing of connections.
This bug also appears in the curl command line tool. But it's much rarer probably because it doesn't reuse connections quite as often as an application will, due to the fact that the tool will quit and be reopened once per connection.
Here is my debug trace. I did this using libcurl, as a C API, so I tried to make my debug function output text like libcurl's although it's not exactly the same. What's the problem? No form data! I've removed sensitive information from this example by replacing with ****
== Info: Expire cleared
== Info: Connection #0 to host **.**.**.** left intact
== Info: About to connect() to proxy **.**.**.** port 808 (#0)
== Info: Trying **.**.**.**... == Info: connected
== Info: Connected to **.**.**.** (**.**.**.**) port 808 (#0)
== Info: Proxy auth using NTLM with user ********
=> Send header: POST http://\*******.com HTTP/1.1
Proxy-Authorization: NTLM *************************
Host: *******.com
Pragma: no-cache
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 0
<= Recv header: HTTP/1.1 200 OK
<= Recv header: Date: Thu, 30 Oct 2008 13:45:44 GMT
<= Recv header: Server: Apache/2.2.8 (Ubuntu) mod_jk/1.2.25 mod_ssl/2.2.8 OpenSSL/0.9.8g
<= Recv header: Keep-Alive: timeout=15, max=100
<= Recv header: Transfer-Encoding: chunked
<= Recv header: Content-Type: text/plain
<= Recv header: Proxy-connection: Keep-Alive
<= Recv header:
=> Send data
10
Sometimes, with the exact same connection code... I see this instead amoungst the (long) debug output.
"
------------------------------9ea4b9344a58
Content-Disposition: form-data; name="lea"
Content-Type: application/binary
le2
"
You didn't mention what libcurl version on what platform this is.
Here's the version and platform:
curl 7.19.0 (i386-apple-darwin9.5.0) libcurl/7.19.0 OpenSSL/0.9.7l zlib/1.2.3
I also tried this on the PC. Same result.
curl 7.19.0 (i586-pc-mingw32msvc) libcurl/7.19.0 zlib/1.2.3
Please let me know what other information is needed.
That Windows version doesn't have OpenSSL but I guess it says "NTLM" as a feature in the curl -V output? If so it uses the windows internal SSPI interface and that then of course rules out that this is a problem in our NTLM code.
I would like a more complete trace dump from the POST. Does it really only issue a single POST?
I'd also like to see the code for a full app (as small as possible) that you can use to reproduce this problem.
Unfortunately, I don't personally have a NTLM proxy to try against.
OK... there was a mistake in my explanation below.
I have curl in two places on the PC. I have curl.exe the command line tool. And libcurl.dll.
my curl.exe says: curl 7.19.0 (i586-pc-mingw32msvc) libcurl/7.19.0 zlib/1.2.3
my libcurl says: libcurl/7.19.0 OpenSSL/0.9.8h zlib/1.2.3 libssh2/0.18
Hopefully it doesn't make a difference. I am experiencing this "disappearing form-data" problem with libcurl.dll.
I am unable to find out if the problem appears with curl.exe, right this second, but I am working on it. The main problem is our servers have passwords that are hashed with the current unix time, so I can't just type up a testing string in curl.exe because the password will be wrong. I am working on a system that will let me expose development areas on the server so timehashing isn't needed for passwords. I'll get that done by tomorrow. then I'll be able to test for this bug under curl.exe, tomorrow.
I'm not sure this will help, because I am seeing the problem in libcurl.dll, (and I don't yet know if it appears in curl.exe), but here is what curl.exe gives me.
C:\Documents and Settings\Administrator\Desktop>curl.exe -V
curl 7.19.0 (i586-pc-mingw32msvc) libcurl/7.19.0 zlib/1.2.3
Protocols: tftp ftp telnet dict ldap http file
Features: Largefile NTLM SSPI libz
The trace I gave you was a complete trace of a failiure. I didn't give any complete trace from a successful run.
I'll have to work on getting you the code to replicate this. My current code isn't actually C, but I can write C easily enough. I'll update this bug report when I have it.
Thanks a lot.
File Added: 1~555_AlfieConnection.pl
Connection 1: Successfully test that server exists
File Added: 5~794_p_AlfieLister.pl
Connection 5: Fails to send any form-data
File Added: 6~794_p_AlfieLister.pl
Connection 6: Retry sending with same code. This time the form-data is sent!
Connection 4: What we did just before the failiure on connection 5
File Added: 4~555_AlfieConnection.pl
I've uploaded a few files. My app made 6 connections, but I didn't upload them all as it might be a waste. I numbered them so connection 1 starts with "1~", connection 2 starts with "2~", etc, etc.
The error I get from my server is: "Undefined 'lea'"
If you look for that text in the file: "5~" you'll see that line near the bottom. That's my server returning an error message saying that it couldn't find "lea".
At this point, I'm in the GUI seeing an error message of "The server gave an error of: Undefined 'lea'" on my screen. So I press the "Refresh" button in my app. This creates a new curl object, and fills it in with the same data I filled it in with last time. So it creates connection 6.
However... on "6~" we see that we DO send an "lea", and the server instead of complaining, sends us back some XML.
So... I'm doing the same thing on 5 and 6. But 5 fails. I don't know why.
On some other URLs, no matter how many times I try to redo it, it fails. Then I give up, and do the same thing another day, and it works! Wierd.
In the "Connection 5: Fails to send any form-data" dump and in your original description, it is clearly that the site _doesn_ require NTLM but it responds with a 200 immediately on the first POST (with no 407 + NTLM requirement in a response header). I think perhaps that's a clue to this problem.
File Added: main.cpp
Our server does not require NTLM. This is true. It is unprotected.
However, we are working with some schools, who have NTLM networks set up, and they cannot access our server except via an NTLM proxy.
That's what I've been told.
I got a test code and credentials from Theodore but was unable to repeat the problem with 7.19.0. He would come back when he can repeat it with a recent version.
Do note that we now should deal with 7.19.1 since that's been released in the mean time.
This report will therefore be set to 'pending' now.
That NTLM bug I had before, I finally found out why it was happening in REALbasic but not in C++.
Basically, I had assumed that REALbasic is single threaded (that's what I've always been told) so I it should be OK to call libcurl functions whenever I want. On a guess... I decided to move all my libcurl function calls into one REALbasic method. This way, it's impossible for it to be called from another thread even if REALbasic was multi-threaded.
Everything worked then! I have to create and destroy a multi handle in the same method, but that's OK because everything works now.
So that's great.
This bug is not really a bug, just an error in my code caused by not realising that REALbasic isn't quite single threaded.