Compare commits

...

614 Commits

Author SHA1 Message Date
Daniel Stenberg
f77e89c5d2 RELEASE-NOTES: synced with 92cf6141ed 2013-10-13 23:24:21 +02:00
Daniel Stenberg
92cf6141ed curl: fix --oauth2-bearer in the --help output
After the option rename in 5df04bfafd
2013-10-13 23:21:12 +02:00
Daniel Stenberg
cf12d5b62f OpenSSL: improve the grammar of the language in 39beaa5ffb
Reported-by: Petr Pisar
2013-10-13 23:08:12 +02:00
Andrej E Baranov
39beaa5ffb OpenSSL: use failf() when subjectAltName mismatches
Write to CURLOPT_ERRORBUFFER information about mismatch alternative
certificate subject names.

Signed-off-by: Andrej E Baranov <admin@andrej-andb.ru>
2013-10-13 19:12:58 +02:00
Daniel Stenberg
5df04bfafd curl: rename --bearer to --oauth2-bearer
The option '--bearer' might be slightly ambiguous in name. It doesn't
create any conflict that I am aware of at the moment, however, OAUTH v2
is not the only authentication mechanism which uses "bearer" tokens.

Reported-by: Kyle L. Huff
URL: http://curl.haxx.se/mail/lib-2013-10/0064.html
2013-10-12 23:26:38 +02:00
Kamil Dudka
d015f4ccac ssh: improve the logic for detecting blocking direction
This fixes a regression introduced by commit 0feeab78 limiting the speed
of SCP upload to 16384 B/s on a fast connection (such as localhost).
2013-10-12 23:03:28 +02:00
Dan Fandrich
143d7c13d8 Fixed typo in Makefile.inc that left http2.h out of the tar ball 2013-10-12 21:09:17 +02:00
Heinrich Schaefer
9b33ecfd01 minor fix in doc 2013-10-11 11:57:26 +02:00
Gisle Vanem
ca1b34b887 curl_setup_once: fix errno access for lwip on Windows
lib/curl_setup_once.h assumed lwIP on Windows uses 'SetLastError()' to
set network errors. It doesn't; it uses 'errno'.
2013-10-09 14:45:42 +02:00
Daniel Stenberg
f0f95c97f7 test1239: verify 4cd444e01a and the simulated 304 response 2013-10-07 14:42:21 +02:00
Derek Higgins
4cd444e01a HTTP: Output http response 304 when modified time is too old
When using the -w '%{http_code}' flag and simulating a Not Modified then
304 should be output.
2013-10-07 14:16:39 +02:00
Daniel Stenberg
8264478490 contributors: helper script to dig out contributors from git 2013-10-07 09:47:03 +02:00
Daniel Stenberg
b46491900d RELEASE-NOTES: add twos refs to bug reports 2013-10-07 00:10:59 +02:00
Daniel Stenberg
725288bf2f RELEASE-NOTES: synced with 173160c0d0 2013-10-06 23:36:21 +02:00
Nick Zitzmann
173160c0d0 darwinssl: block TLS_RSA_WITH_NULL_SHA256 cipher
Credit (for catching a cipher I forgot to add to the blocked ciphers list):
https://www.ssllabs.com/ssltest/viewMyClient.html
2013-10-02 21:19:28 -05:00
Daniel Stenberg
3c3622b662 OpenSSL: acknowledge CURLOPT_SSL_VERIFYHOST without VERIFYPEER
Setting only CURLOPT_SSL_VERIFYHOST without CURLOPT_SSL_VERIFYPEER set
should still verify that the host name fields in the server certificate
is fine or return failure.

Bug: http://curl.haxx.se/mail/lib-2013-10/0002.html
Reported-by: Ishan SinghLevett
2013-10-02 15:40:02 +02:00
Daniel Stenberg
a22c478ed7 KNOWN_BUGS: #84: CURLINFO_SSL_VERIFYRESULT
CURLINFO_SSL_VERIFYRESULT is only implemented for the OpenSSL and NSS
backends and not for any other!
2013-10-02 15:39:47 +02:00
François Charlier
3d43a48781 xattr: add support for FreeBSD xattr API 2013-10-01 22:53:47 +02:00
Daniel Stenberg
c8b05b809e curl_easy_setopt.3: slight clarification of SEEKFUNCTION 2013-09-30 14:58:06 +02:00
Steve Holme
ca995010d0 tests: Fixed typos from commit 25a0c96a49 2013-09-29 20:32:23 +01:00
Steve Holme
25a0c96a49 tests: Updated email addresses in SMTP tests following recent changes 2013-09-29 16:48:02 +01:00
Steve Holme
a8b606b1a6 test909: Removed custom EHLO response after recent changes
...as it is no longer required following capability and authentication
changes and is now causing problems following commit 49341628b5 as
the test number is obtained from the client address in the EHLO.
2013-09-29 16:25:11 +01:00
Steve Holme
20a99a45c0 ftpserver.pl: Fixed compilation error from commit 49341628b5 2013-09-29 13:13:13 +01:00
Steve Holme
49341628b5 ftpserver.pl: Moved specifying the test number from the RCPT address
...to the client address as this frees the RCPT strings to contain
just an email address and by passing the test number into curl as the
client address remains consistent with POP3 and IMAP tests as they are
specified in the URL.
2013-09-29 10:02:00 +01:00
Steve Holme
ab7e6afd44 ftpserver.pl: Added unwanted argument check to SMTP DATA command handler 2013-09-29 09:25:23 +01:00
Daniel Stenberg
4d7bf73fc3 getinmemory: remove a comment
The comment mentioned the need to free the data, but the example already
does that free
2013-09-29 00:16:21 +02:00
Daniel Stenberg
3c34f453fa postinmemory: new example
This is similar to getinmemory.c but with an initial POST.

Combined-by: Ulf Samuelsson
2013-09-29 00:12:30 +02:00
Daniel Stenberg
d5f687ed8f win32: fix Visual Studio 2010 build with WINVER >= 0x600
If no WINVER and/or _WIN32_IWNNT define was set, the Windows platform
SDK often defaults to high value, e.g. 0x601 (whoch may probably depend
on the Windows version being used, in my case Windows 7).

If WINVER >= 0x600 then winsock2.h includes some defines for WSAPoll(),
e.g. POLLIN, POLLPRI, POLLOUT etc. These defines clash with cURL's
lib/select.h.

Make sure HAVE_STRUCT_POLLFD is defined then.

Bug: http://curl.haxx.se/bug/view.cgi?id=1282
Reported-by: "kdekker"
Patch-by: Marcel Raad
2013-09-28 23:18:19 +02:00
Steve Holme
a377fab015 ssluse.c: Fixed compilation warnings when ENGINE not supported
The function "ssl_ui_reader" was declared but never referenced
The function "ssl_ui_writer" was declared but never referenced
2013-09-28 17:24:22 +01:00
Daniel Stenberg
092f33d6bf configure: use icc options without space
The latest version(s) of the icc compiler no longer accept the extra
space in the -we (warning enable), -wd (warning disable), etc.

Reported-by: Elmira A Semenova
Bug: http://curl.haxx.se/mail/lib-2013-09/0182.html
2013-09-27 10:57:20 +02:00
Steve Holme
09a13a1c01 imap: Added clarification to the code about odd continuation responses 2013-09-25 17:44:51 +01:00
Steve Holme
30a09783b2 ftp.c: Fixed compilation warning
There is an implicit conversion from "unsigned long" to "long"
2013-09-25 07:09:41 +01:00
Steve Holme
733a4419d0 sasl: Centralised the authentication mechanism strings
Moved the standard SASL mechanism strings into curl_sasl.h rather than
hard coding the same values over and over again in the protocols that
use SASL authentication.

For more information about the mechanism strings see:

http://www.iana.org/assignments/sasl-mechanisms
2013-09-24 20:12:50 +01:00
Daniel Stenberg
77dc4ba877 RELEASE-NOTES: added recent contributors missing 2013-09-23 23:23:51 +02:00
Steve Holme
14d8209adc test906: Fixed type-2 response 2013-09-23 07:10:25 +01:00
Steve Holme
a942d8ff5b test915: Corrected test number from commit 22bccb0eda 2013-09-23 00:19:56 +01:00
Steve Holme
1695c67818 test906: Fixed type-1 message not handled error
...from commit f81d1e1666 due to copy paste error.
2013-09-23 00:15:37 +01:00
Steve Holme
f81d1e1666 tests: Added SMTP AUTH NTLM test 2013-09-22 20:53:29 +01:00
Steve Holme
b71ed1fb3d tests: Added SMTP multiple and invalid --mail-rcpt test 2013-09-22 20:25:32 +01:00
Steve Holme
86ccfaa3fd tests: Added SMTP multiple --mail-rcpt test 2013-09-22 20:23:27 +01:00
Steve Holme
3b69462fc0 tests: Added SMTP invalid --mail-rcpt test 2013-09-22 20:12:20 +01:00
Steve Holme
22bccb0eda tests: Regrouping of SMTP tests 2013-09-22 20:09:57 +01:00
Benoit Sigoure
4f591b9148 test1112: Increase the timeout from 7s to 16s
As someone reported on the mailing list a while back, the hard-coded
arbitrary timeout of 7s in test 1112 is not sufficient in some build
environments. At Arista Networks we build and test curl as part of our
automated build system, and we've run into this timeout 170 times so
far. Our build servers are typically quite busy building and testing a
lot of code in parallel, so despite being beefy machines with 32 cores
and 128GB of RAM we still hit this 7s timeout regularly.

URL: http://curl.haxx.se/mail/lib-2010-02/0200.html
2013-09-22 18:23:09 +02:00
Steve Holme
52cefc8cd7 tests: Fixed smtp rcpt to addresses 2013-09-22 15:14:26 +01:00
Steve Holme
8880f84e1a ftpserver.pl: Expanded the SMTP RCPT handler to validate TO addresses
RCPT_smtp() will now check for a correctly formatted TO address which
allows for invalid recipient addresses to be added.
2013-09-22 15:05:43 +01:00
Steve Holme
9d4a8c7936 ftpserver.pl: Added cURL SMTP server detection to HELO command handler
As curl will send a HELO command after an negative EHLO response, added
the same detection from commit b07709f741 to the HELO handler to
ensure the test server is identified correctly and an upload isn't
performed.
2013-09-22 13:21:15 +01:00
Steve Holme
fd8dc21fd0 ftpserver.pl: Corrected response code for successful RCPT command 2013-09-22 12:59:28 +01:00
Steve Holme
8ec6486d05 ftpserver.pl: Moved invalid RCPT TO: address detection to RCPT handler
Rather than detecting the TO address as missing in the DATA handler,
moved the detection to the RCPT command handler where an error response
can be generated.
2013-09-22 11:03:18 +01:00
Steve Holme
59c1743c78 RELEASE-NOTES: Corrected missed addition
Somehow commit 60a2046162 missed the last item in the sync list
even though I'm sure I added it during editing.
2013-09-21 22:28:07 +01:00
Steve Holme
60a2046162 RELEASE-NOTES: Synced with 6dd8bd8d2f 2013-09-21 22:20:40 +01:00
Steve Holme
6dd8bd8d2f curl.1: Added information about optional login options to --user in manpage
Added missing information, from curl 7.31.0, regarding the use of the
optional login options that may be specified as part of --user.

For example:

--user 'user:password;auth=NTLM' in IMAP, POP3 and SMTP protocols.
2013-09-21 22:05:12 +01:00
Steve Holme
b07709f741 ftpserver.pl: Moved cURL SMTP server detection into EHLO command handler
Moved the special SMTP server detection code from the DATA command
handler, which happens further down the operation chain after EHLO,
MAIL and RCPT commands, to the EHLO command as it is the first command
to be generated by a SMTP operation as well as containing the special
"verifiedserver" string from the URL.

This not only makes it easier and quicker to detect but also means that
cURL doesn't need to specify "verifiedserver" as --mail-from and
--mail-rcpt arguments.

More importantly, this also makes the upcoming verification changes to
the RCPT handler easier to implement.
2013-09-21 20:49:23 +01:00
Daniel Stenberg
9215cee4c6 openssl: use correct port number in error message
In ossl_connect_step2() when the "Unknown SSL protocol error" occurs, it
would output the local port number instead of the remote one which
showed when doing SSL over a proxy (but with the correct remote host
name). As libcurl only speaks SSL to the remote we know it is the remote
port.

Bug: http://curl.haxx.se/bug/view.cgi?id=1281
Reported-by: Gordon Marler
2013-09-21 21:01:00 +02:00
Daniel Stenberg
34df869f99 test1415: adjusted to work for 32bit time_t
The libcurl date parser returns INT_MAX for all dates > 2037 so this
test is now made to use 2037 instead of 2038 to work the same for both
32bit and 64bit time_t systems.
2013-09-21 13:46:42 -05:00
Steve Holme
3f04d48495 tests: Reworked existing SMTP tests to be single recipient based
...in preparation of upcoming multiple recipient tests.
2013-09-21 19:44:09 +01:00
Steve Holme
517b8e2290 ftpserver.pl: Corrected SMTP QUIT response to be more realistic 2013-09-20 23:08:28 +01:00
Daniel Stenberg
af44da38d6 curl_easy_setopt.3: clarify that TIMEOUT and TIMEOUT_MS set the same value 2013-09-20 23:16:04 +02:00
Kim Vandry
fcfa26a7ee Documented --dns-* options in curl manpage 2013-09-20 23:09:39 +02:00
Steve Holme
18db743851 pop3: Added basic SASL XOAUTH2 support
Added the ability to use an XOAUTH2 bearer token [RFC6750] with POP3 for
authentication using RFC6749 "OAuth 2.0 Authorization Framework".

The bearer token is expected to be valid for the user specified in
conn->user. If CURLOPT_XOAUTH2_BEARER is defined and the connection has
an advertised auth mechanism of "XOAUTH2", the user and access token are
formatted as a base64 encoded string and sent to the server as
"AUTH XOAUTH2 <bearer token>".
2013-09-20 21:56:30 +01:00
Steve Holme
0e188e2dc3 curl: Added clarification to the --mail options in the --help output
... that these options apply to SMTP only.
2013-09-20 21:35:44 +01:00
Steve Holme
eecb0e969f ftpserver.pl: Moved SMTP RCPT response text into command handler 2013-09-20 21:25:48 +01:00
Steve Holme
bd7d56ec71 tests: Added SMTP invalid --mail-from test 2013-09-20 07:09:39 +01:00
Nick Zitzmann
6f78aaad6f darwinssl: enable BEAST workaround on iOS 7 & later
iOS 7 finally added the option to enable 1/n-1 when using TLS 1.0
and a CBC cipher, so we now always turn that on unless the user
manually turns it off using CURLSSLOPT_ALLOW_BEAST.

It appears Apple also added some new PSK ciphers, but no interface to
use them yet, so we at least support printing them if we find them.
2013-09-19 17:28:54 -05:00
Steve Holme
89d320c2fd tests: Updated SMTP AUTH tests to use the new AUTH directive
...rather than specify a customised EHLO response.
2013-09-19 20:29:59 +01:00
Steve Holme
b809bafb0c tests: Corrected test913 as the QUIT response is received 2013-09-19 20:13:08 +01:00
Steve Holme
3b6a1681dc tests: Added SMTP large message SIZE test 2013-09-19 18:17:11 +01:00
Steve Holme
9300bb826d ftpserver.pl: Updated email regex from commit 98f7ca7e97
...to not be as strict as it was rejecting valid numeric email
addresses.
2013-09-19 12:44:27 +01:00
Steve Holme
dfe7ee1429 tests: Fixed smtp mail from addresses 2013-09-19 07:19:25 +01:00
Steve Holme
841103c776 ftpserver.pl: Standardised CAPA and AUTH responses 2013-09-18 19:38:26 +01:00
Steve Holme
8d2335ca23 ftpserver.pl: Corrected POP3 QUIT reply to be more realistic 2013-09-18 19:37:03 +01:00
Steve Holme
04064e89c1 runtests.pl: Fixed syntax error in commit c873375123
Possible unintended interpolation in string at line 796
2013-09-18 19:32:20 +01:00
Steve Holme
c873375123 runtests.pl: Fixed smtp mail from address
Following changes to ftpserver.pl fixed the mail from address to be a
correctly formatted address otherwise the server response will be 501
Invalid address.
2013-09-18 18:04:26 +01:00
Steve Holme
62d232c131 ftpserver.pl: Fixed syntax error in commit 98f7ca7e97
Can't modify constant item in scalar assignment line 779, near "0;"
2013-09-18 12:58:34 +01:00
Steve Holme
98f7ca7e97 ftpserver.pl: Expanded the SMTP MAIL handler to validate messages
MAIl_smtp() will now check for a correctly formatted FROM address as
well as the optional SIZE parameter comparing it against the server
capability when specified.
2013-09-18 07:23:32 +01:00
YAMADA Yasuharu
4cfbb201c4 cookies: add expiration
Implement: Expired Cookies These following situation, curl removes
cookie(s) from struct CookieInfo if the cookie expired.
 - Curl_cookie_add()
 - Curl_cookie_getlist()
 - cookie_output()
2013-09-17 23:25:56 +02:00
Steve Holme
dc016567ce ftpserver.pl: Corrected response code for successful MAIL command 2013-09-17 22:10:17 +01:00
Steve Holme
96b68c57ce ftpserver.pl: Moved SMTP MAIL handler into own function 2013-09-17 22:09:30 +01:00
Steve Holme
158dfe2c5c dns: fix compilation with MinGW from commit df69440d05
Avoid 'interface' literal that some MinGW versions define as a macro

Additionally, corrected some very, very minor coding style errors.
2013-09-17 20:59:43 +01:00
Steve Holme
8f5336a2fa tests: Fixed test 1406 following recent changes in ftpserver.pl
By default the mail server doesn't send the SIZE capability but instead
it has to be specified as a supported capability.
2013-09-16 00:24:46 +01:00
Steve Holme
f8a9dbd391 tests: Added test for SMTP SIZE capability 2013-09-16 00:24:30 +01:00
Steve Holme
016879d477 ftpserver.pl: Added the ability to include spaces in capabilities
For example:

CAPA "SIZE 1048576" 8BITMIME BINARYMIME

will populate the capabilities list with the following in:

SIZE 1048576
8BITMIME
BINARYMIME
2013-09-15 20:56:16 +01:00
Steve Holme
c03335ec68 ftpserver.pl: Corrected response code for successful SMTP QUIT command 2013-09-15 20:09:49 +01:00
Steve Holme
894585784c ftpserver.pl: Fixed syntax error in commit 33c1f2876b
Can't modify constant item in postincrement line 727, near "i++"
2013-09-15 20:07:43 +01:00
Steve Holme
33c1f2876b ftpserver.pl: Added CAPA & AUTH directive support to the SMTP EHLO handler 2013-09-15 16:53:20 +01:00
Steve Holme
00ee5c5cf1 ftpserver.pl: Fixed SMTP QUIT handler from dadc495540 2013-09-15 12:47:36 +01:00
Steve Holme
dadc495540 ftpserver.pl: Moved SMTP EHLO and QUIT handlers in own functions 2013-09-15 09:20:53 +01:00
Steve Holme
eae86ba62d ftpserver.pl: Added support for SMTP HELO command
...and updated test902 as explicit HELO response is no longer required.
2013-09-15 09:10:11 +01:00
Steve Holme
e9cca79dd1 ftpserver.pl: Added mailbox check to IMAP SELECT handler 2013-09-15 09:00:13 +01:00
Steve Holme
4ba3b6c05a ftpserver.pl: Corrected invalid user details check
...in both the IMAP LOGIN and POP3 PASS handlers introduced in commit
187ac69374 and 84ad1569e5 respectively.
2013-09-15 00:31:55 +01:00
Steve Holme
187ac69374 ftpserver.pl: Moved IMAP LOGIN handler into own function 2013-09-14 20:52:29 +01:00
Steve Holme
84ad1569e5 ftpserver.pl: Moved POP3 USER and PASS handlers into own functions 2013-09-14 20:46:45 +01:00
Steve Holme
45e0a661ce ftpserver.pl: Corrected invalid argument check in POP3 TOP handler
...which was accidentally introduced in commit 4d6ef6297a.
2013-09-14 16:18:47 +01:00
Steve Holme
4d6ef6297a ftpserver.pl: Added capability prerequisite for extended POP3 commands 2013-09-14 15:04:26 +01:00
Steve Holme
b68c52704b tests: Updated descriptions to be more meaningful 2013-09-14 15:04:25 +01:00
Steve Holme
4f4dc5832d ftpserver.pl: Added support for IMAP NOOP command 2013-09-14 10:44:54 +01:00
Steve Holme
fbcefc0ce0 imap: Fixed response check for NOOP command 2013-09-14 10:44:28 +01:00
Steve Holme
83f6f58834 tests: Updated descriptions to be more meaningful 2013-09-14 10:41:17 +01:00
Daniel Stenberg
0a691f8935 curl.1: detail how short/long options work
URL: http://curl.haxx.se/bug/view.cgi?id=1279
Suggested-by: Jerry Krinock
2013-09-13 23:14:41 +02:00
Steve Holme
c243d45aad curl: Fixed usage of DNS options when not using c-ares resolver
Commit 32352ed6ad introduced various DNS options, however, these
would cause curl to exit with CURLE_NOT_BUILT_IN when c-ares wasn't
being used as the backend resolver even if the options weren't set
by the user.

Additionally corrected some minor coding style errors from the same
commit.
2013-09-13 18:50:11 +01:00
Daniel Stenberg
8a6dba520b curl_easy_setopt.3: mention RTMP URL quirks
URL: http://curl.haxx.se/bug/view.cgi?id=1278
Reported-by: Gorilla Maguila
2013-09-13 14:06:20 +02:00
Ben Greear
32352ed6ad curl: Add support for various DNS binding options.
(Passed on to c-ares.)

Allows something like this:

curl --dns-interface sta8 --dns-ipv4-addr 8.8.1.111 --interface sta8 \
--localaddr 8.8.1.111 --dns-servers 8.8.8.1 www.google.com

Signed-off-by: Ben Greear <greearb@candelatech.com>
2013-09-12 21:11:47 +02:00
Kim Vandry
df69440d05 libcurl: New options to bind DNS to local interfaces or IP addresses 2013-09-12 21:11:47 +02:00
Daniel Stenberg
345955e87e libcurl.3: for multi interface connections are held in the multi handle
... and a few more cleanups/clarifications
2013-09-12 13:59:05 +02:00
Steve Holme
6f5b46855c ftpserver.pl: Fixed missing comma from 7fd84b14d2 2013-09-12 11:52:19 +01:00
Steve Holme
5f93c5d658 ftpserver.pl: Fixed variable error introduced in 7fd84b14d2
Global symbol "$mailbox" requires explicit package name
2013-09-12 07:10:41 +01:00
Steve Holme
7fd84b14d2 ftpserver.pl: Added support for UID command 2013-09-11 20:27:13 +01:00
Steve Holme
f2403140f9 ftpserver.pl: Added support for LSUB command 2013-09-11 20:25:48 +01:00
Steve Holme
f3c9749a40 imap: Fixed response check for LSUB and UID commands 2013-09-11 20:15:21 +01:00
Steve Holme
3f6991766f ftpserver.pl: Added support for IMAP COPY command 2013-09-11 19:57:29 +01:00
Steve Holme
cfe5f7dbf4 ftpserver.pl: Added support for IMAP CLOSE and EXPUNGE commands 2013-09-11 18:19:38 +01:00
Steve Holme
5840c918d5 ftpserver.pl: Added support for POP3 RSET command 2013-09-11 18:11:33 +01:00
Steve Holme
b0afb00000 ftpserver.pl: Added the ability to remember what messages are deleted
...as this will be required for IMAP CLOSE and EXPUNGE commands as well
as the POP3 RSET command.
2013-09-11 18:10:28 +01:00
Daniel Stenberg
0b5ae7c80e NI_MAXSERV: remove all use of it
Solaris with the SunStudio Compiler is reportedly missing this define,
but as we're using it without any good reason on all the places it was
used I've now instead switched to just use sensible buffer sizes that
fit a 32 bit decimal number. Which also happens to be smaller than the
common NI_MAXSERV value which is 32 on most machines.

Bug: http://curl.haxx.se/bug/view.cgi?id=1277
Reported-by: D.Flinkmann
2013-09-10 23:18:43 +02:00
Daniel Stenberg
0d55f4e1bc http2: use the support HTTP2 draft version in the upgrade header
... instead of HTTP/2.0 to work fine with the nghttpx proxy/server.
2013-09-10 23:06:20 +02:00
Steve Holme
86d340af27 ldap.c: Fix compilation warning
warning: comparison between signed and unsigned integer expressions
2013-09-10 20:27:52 +01:00
Jiri Hruska
5c14a7f068 imap/pop3/smtp: Speed up SSL connection initialization
Don't wait for the next callback call (usually 1 second) before
continuing with protocol specific connection initialization.
2013-09-10 19:47:54 +01:00
Steve Holme
2879ffacfa ldap.c: Corrected build error from commit 857f999353 2013-09-10 19:30:07 +01:00
Steve Holme
d89eb55906 RELEASE-NOTES: Corrected duplicate in bfefe2400a 2013-09-10 15:35:20 +01:00
Steve Holme
4a85e60cfe RELEASE-NOTES: Corrected typo from bfefe2400a 2013-09-10 14:06:50 +01:00
Steve Holme
bfefe2400a RELEASE-NOTES: synced with 25c6890375 2013-09-10 13:12:56 +01:00
Daniel Stenberg
25c6890375 README.http2: explain nghttp2 a little 2013-09-10 00:21:27 +02:00
Steve Holme
eb6314260d tests: Added test for POP3 TOP command 2013-09-09 17:13:28 +01:00
Steve Holme
313c38c9de ftpserver.pl: Added support for POP3 TOP command 2013-09-09 17:13:25 +01:00
Steve Holme
ae6096471a tests: Added test for POP3 UIDL command 2013-09-09 17:10:40 +01:00
Steve Holme
66ea5c415b ftpserver.pl: Added support for POP3 UIDL command 2013-09-09 17:10:38 +01:00
Daniel Stenberg
2481ac358c http2: adjust to new nghttp2_pack_settings_payload proto
This function was modified in nghttp2 git commit a1c3f89c72e51
2013-09-09 15:18:09 +02:00
Kamil Dudka
c639d725a3 url: handle abortion by read/write callbacks, too
Otherwise, the FTP protocol would unnecessarily hang 60 seconds if
aborted in the CURLOPT_HEADERFUNCTION callback.

Reported by: Tomas Mlcoch
Bug: https://bugzilla.redhat.com/1005686
2013-09-09 13:23:04 +02:00
Daniel Stenberg
857f999353 ldap: fix the build for systems with ldap_url_parse()
Make sure that the custom struct fields are only used by code that
doesn't use a struct defintion from the outside.

Attempts to fix the problem introduced in 3dc6fc42bf
2013-09-09 09:39:08 +02:00
Jiri Hruska
6d9cddc513 pingpong: Check SSL library buffers for already read data
Otherwise the connection can get stuck during various phases, waiting
for new data on the socket using select() etc., but it will never be
received as the data has already been read into SSL library.
2013-09-09 07:40:40 +01:00
Steve Holme
e20e48cbf2 imap: Fixed calculation of transfer when partial FETCH received
The transfer size would be calculated incorrectly if the email contained
within the FETCH response, had been partially received by the pingpong
layer. As such the following, example output, would be seen if the
amount remaining was smaller than the amount received:

* Excess found in a non pipelined read: excess = 1394, size = 262,
  maxdownload = 262, bytecount = 1374
* transfer closed with -1112 bytes remaining to read

Bug: http://curl.haxx.se/mail/lib-2013-08/0170.html
Reported-by: John Dunn
2013-09-09 07:40:38 +01:00
Steve Holme
ee5e2cf6cb ftpserver.pl: Fixed empty array checks
...from commits 28427b4083 and e8313697b6.
2013-09-08 23:59:49 +01:00
Steve Holme
e8313697b6 ftpserver: Reworked AUTH support to allow for specifying the mechanisms
Renamed SUPPORTAUTH to AUTH and added support for specifying a list of
supported SASL mechanisms to return to the client.

Additionally added the directive to the FILEFORMAT document.
2013-09-08 21:47:56 +01:00
Steve Holme
28427b4083 ftpserver: Reworked CAPA support to allow for specifying the capabilities
Renamed SUPPORTCAPA to CAPA and added support for specifying a list of
supported capabilities to return to the client.

Additionally added the directive to the FILEFORMAT document.
2013-09-08 21:45:36 +01:00
Steve Holme
131649a121 ftpserver.pl: Corrected POP3 LIST as message numbers should be contiguous
The message numbers given in the LIST response are an index into the
list, which are only valid for the current session, rather than being a
unique message identifier. An index would only be missing from the LIST
response if a DELE command had been issued within the same session and
had not been committed by the end of session QUIT command. Once
committed the POP3 server will regenerate the message numbers in the
next session to be contiguous again. As such our LIST response should
list message numbers contiguously until we support a DELE command in the
same session.

Should a POP3 user require the unique message ID for any or all
messages then they should use the extended UIDL command. This command
will be supported by the test ftpserver in an upcoming commit.
2013-09-08 20:19:20 +01:00
Clemens Gruber
632b3d81d6 curl_easy_pause: suggest one way to unpause 2013-09-08 19:26:28 +02:00
Steve Holme
241aeadc50 tests: Updated descriptions to be more meaningful 2013-09-08 16:59:57 +01:00
Steve Holme
669e4ca366 tests: Added test for POP3 NOOP command 2013-09-08 16:59:55 +01:00
Steve Holme
c9617d9f93 ftpserver.pl: Added support for POP3 NOOP command 2013-09-08 16:45:52 +01:00
Steve Holme
f8986a2b34 ftpserver.pl: Fixed 'Use of uninitialized value $args in string ne' 2013-09-08 16:39:41 +01:00
Steve Holme
1b96ce04b2 tests: Added test for POP3 STAT command 2013-09-08 08:52:53 +01:00
Steve Holme
f851df88fb ftpserver.pl: Added support for POP STAT command 2013-09-08 08:49:40 +01:00
Steve Holme
18c595fde2 ftpserver.pl: Moved POP3 QUIT handler into own function 2013-09-08 08:44:49 +01:00
Steve Holme
56abdd07e7 ftpserver.pl: Reordered the POP3 handlers to be alphabetical
In preparation for additional POP3 tests, re-ordered the command
function defintions to be sorted alphabetically.
2013-09-08 02:48:34 +01:00
Steve Holme
7e06c336d6 ftpserver.pl: Corrected misaligned indentation in POP3 handlers
Fixed incorrect indentation used in both the RETR_pop3 and LIST_pop3
functions which was 5 and 9 characters rather than 4 and 8.
2013-09-08 02:48:33 +01:00
Steve Holme
8a4069fb17 tests: Added test for POP3 DELE command 2013-09-07 19:49:12 +01:00
Steve Holme
243ad539fe ftpserver.pl: Added support for POP3 DELE command 2013-09-07 19:31:46 +01:00
Daniel Stenberg
3d60590422 http2: include curl_memory.h
Detected by test 1132
2013-09-07 19:48:01 +02:00
Nick Zitzmann
08fa4fed70 http: fix build warning under LLVM
When building the code using LLVM Clang without NGHTTP2, I was getting
this warning:
../lib/http.h:155:1: warning: empty struct is a GNU extension [-Wgnu]
Placing a dummy variable into the data structure silenced the warning.
2013-09-07 10:00:11 -05:00
Daniel Stenberg
4344fa926a http2: actually init nghttp2 and send HTTP2-Settings properly 2013-09-07 13:01:43 +02:00
Daniel Stenberg
61672bde44 README.http2: how to use it best with the multi API? 2013-09-07 11:28:12 +02:00
Daniel Stenberg
13dbb41c49 http2: first embryo toward Upgrade: 2013-09-07 11:28:12 +02:00
Daniel Stenberg
e5c2354fd5 http: rename use_http_1_1 to use_http_1_1plus
Since it now actually says if 1.1 or a later version should be used.
2013-09-07 11:28:12 +02:00
Daniel Stenberg
09634f46fb configure: improve CURL_CHECK_COMPILER_PROTOTYPE_MISMATCH
The compiler test used a variable before it was assigned when it tried
to see how it acts on a mismatching prototype, which could cause a false
positive.
2013-09-07 11:15:18 +02:00
Petr Písař
0119a93b33 Pass password to OpenSSL engine by user interface
Recent OpenSSL uses user interface abstraction to negotiate access to
private keys in the cryprographical engines. An OpenSSL application is
expected to implement the user interface. Otherwise a default one
provided by OpenSSL (interactive standard I/O) will be used and the
aplication will have no way how to pass a password to the engine.

Longer-desc: http://curl.haxx.se/mail/lib-2013-08/0265.html
2013-09-07 00:11:21 +02:00
Daniel Stenberg
9fa42beddc urlglob: improved error messages and column number on bad use
Introduce a convenience macro and keep of the column better so that it
can point out the offending column better.

Updated test 75 accordingly.
2013-09-06 23:27:47 +02:00
Daniel Stenberg
d6cda9e8ab urlglob: avoid error code translation
By using the correct values from the start we don't have to translate
them!
2013-09-06 14:20:48 +02:00
Daniel Stenberg
2a7f1425d9 urlglob: avoid NULL pointer dereference
Thanks to clang-analyzer
2013-09-06 14:12:44 +02:00
Gisle Vanem
900ccc26ae http2: use correct include for snprintf
Using the first little merge of nghttp2 into libcurl, I stumbeled on the
missing 'snprintf' in MSVCRT. Isn't this how we do it for other libcurl
files?  I.e. use 'curl_msnprintf' and not 'snprintf' directly:
2013-09-06 13:56:35 +02:00
Daniel Stenberg
01d7bbbebe --data: mention CRLF treatment when reading from file 2013-09-06 13:52:56 +02:00
Geoff Beier
3dc6fc42bf LDAP: fix bad free() when URL parsing failed
When an error occurs parsing an LDAP URL, The ludp->lud_attrs[i] entries
could be freed even though they sometimes point to data within an
allocated area.

This change introduces a lud_attrs_dup[] array for the duplicated string
pointers, and it removes the unused lud_exts array.

Bug: http://curl.haxx.se/mail/lib-2013-08/0209.html
2013-09-06 13:32:49 +02:00
Nick Zitzmann
d2fe616e7e darwinssl: add support for PKCS#12 files for client authentication
I also documented the fact that the OpenSSL engine also supports them.
2013-09-05 18:57:06 -05:00
Daniel Stenberg
316ca865e3 symbols: added HTTP2 symbols and sorted list
CURL_HTTP_VERSION_2_0 and CURL_VERSION_HTTP2 are new
2013-09-05 12:04:41 +02:00
Daniel Stenberg
812d49db90 configure: add HTTP2 as a curl-config --feature output
Fixes the test 1014 failure
2013-09-05 12:03:24 +02:00
Daniel Stenberg
02370fff3a curl: unbreak --http1.0 again
I broke it in 2eabb7d590
2013-09-05 09:56:05 +02:00
Daniel Stenberg
e9de8e78f0 SASL: fix compiler warnings
comparison between signed and unsigned integer expressions

suggest parentheses around '&&' within '||' (twice)
2013-09-04 22:33:29 +02:00
Daniel Stenberg
2eabb7d590 curl: add --http1.1 and --http2.0 options 2013-09-04 22:29:38 +02:00
Daniel Stenberg
d707a975f6 Curl_setopt: refuse CURL_HTTP_VERSION_2_0 if built without support 2013-09-04 22:29:38 +02:00
Daniel Stenberg
ac487842a1 http2: add http2.[ch] and add nghttp2 version output 2013-09-04 22:29:38 +02:00
Daniel Stenberg
06b6e1d0d2 curl -V: output HTTP2 as a feature if present 2013-09-04 22:29:38 +02:00
Daniel Stenberg
b77997e6da curl.h: add CURL_VERSION_HTTP2 as a feature
It isn't added as a separate protocol as HTTP2 will be done over HTTP://
URLs that can be upgraded to HTTP2 if the server supports it as well.
2013-09-04 22:29:38 +02:00
Steve Holme
9e8ced9890 imap/smtp: Fixed incorrect SASL mechanism selection with XOAUTH2 servers
XOAUTH2 would be selected in preference to LOGIN and PLAIN if the IMAP
or SMTP server advertised support for it even though a user's password
was supplied but bearer token wasn't.

Modified the selection logic so that XOAUTH2 will only be selected if
the server supports it and A) The curl user/libcurl programmer has
specifically asked for XOAUTH via the ;AUTH=XOAUTH login option or 2)
The bearer token is specified. Obviously if XOAUTH is asked for via
the login option but no token is specified the user will receive a
authentication failure which makes more sense than no known
authentication mechanisms supported!
2013-09-04 21:27:01 +01:00
Daniel Stenberg
698e3bdf82 curl.h: added CURL_HTTP_VERSION_2_0
Initial library considerations documented in lib/README.http2
2013-09-04 10:05:00 +02:00
Daniel Stenberg
9011fb3f0c configure: added --with-nghttp2 2013-09-04 10:04:48 +02:00
Daniel Stenberg
073b03fab7 acinclude: fix --without-ca-path when cross-compiling
The commit 7b074a460b to CURL_CHECK_CA_BUNDLE in 7.31 (don't check
for paths when cross-compiling) causes --without-ca-path to no longer
works when cross-compiling, since ca and capath only ever get set to
"no" when not cross-compiling, I attach a patch that works for me. Also
in the cross-compilation case, no ca-path seems to be a better default
(IMVHO) than empty ca-path.

Bug: http://curl.haxx.se/bug/view.cgi?id=1273
Patch-by: Stefan Neis
2013-09-04 00:01:03 +02:00
Steve Holme
f73f052010 lib1512.c: Fixed compilation warning
An enumerated type is mixed with another type.

...as well as a small coding style error.
2013-09-02 20:39:53 +01:00
Guenter Knauf
97ed1ac905 Killed warning 'res' might be used uninitialized. 2013-09-01 23:08:29 +02:00
Steve Holme
322f0bc2f1 url.c: Fixed compilation warning
An enumerated type is mixed with another type
2013-09-01 13:30:12 +01:00
Steve Holme
af4bddf20b easy.c: Fixed compilation warning
warning: `code' might be used uninitialized in this function
2013-09-01 12:48:50 +01:00
Daniel Stenberg
f19efd07e7 -x: rephrased the --proxy section somewhat 2013-08-31 22:55:53 +02:00
Steve Holme
83f5332536 tests: Added test for IMAP CHECK command 2013-08-31 18:40:48 +01:00
Steve Holme
497775024c ftpserver.pl: Added support for the IMAP CHECK command 2013-08-31 18:40:46 +01:00
Guenter Knauf
ea38a70539 Removed reference to krb4.c. 2013-08-31 19:12:35 +02:00
Steve Holme
5eea336d01 ftpserver.pl: Corrected flawed logic in commit 1ca6ed7b75 2013-08-31 11:10:20 +01:00
Steve Holme
f3849a7b84 imap: Fixed response check for EXPUNGE command 2013-08-31 10:49:49 +01:00
Steve Holme
1ca6ed7b75 ftpserver.pl: Added argument check to IMAP command handlers
Added BAD argument check to the following IMAP command handlers:

APPEND, STORE, LIST, EXAMINE, STATUS and SEARCH
2013-08-31 10:41:25 +01:00
Steve Holme
aa51d3a139 ftpserver.pl: More whitespace corrections
LIST_imap() had a second level of indentation at 9 characters and not 8.
2013-08-31 10:35:05 +01:00
Steve Holme
64c8909071 ftpserver.pl: Small correction tidy up
Corrected some IMAP variable names and whitespace issues.
2013-08-30 22:11:17 +01:00
Kyle L. Huff
e848942505 docs: Added documentation for CURLOPT_BEARER 2013-08-30 21:43:13 +01:00
Kyle L. Huff
7e489c42f7 curl.1: Add usage of '--bearer' option 2013-08-30 21:34:20 +01:00
Steve Holme
75b52f9dcc tests: Added tests for IMAP CREATE, DELETE and RENAME commands 2013-08-30 18:56:56 +01:00
Daniel Stenberg
221825aebf ftpserver: Bareword "to_mailbox" not allowed
Added missing $
2013-08-30 15:21:39 +02:00
Steve Holme
9d35ad9552 ftpserver.pl: Added support for IMAP CREATE, DELETE and RENAME commands 2013-08-30 07:35:00 +01:00
Daniel Stenberg
c4a7ca038e FTP: fix getsock during DO_MORE state
... when doing upload it would return the wrong values at times. This
commit attempts to cleanup the mess.

Bug: http://curl.haxx.se/mail/lib-2013-08/0109.html
Reported-by: Mike Mio
2013-08-29 23:09:31 +02:00
Daniel Stenberg
84f3b3dd44 curl_multi_remove_handle: allow multiple removes
When removing an already removed handle, avoid that to ruin the
internals and just return OK instead.
2013-08-29 22:08:45 +02:00
Steve Holme
2ef83136d4 ftpserver.pl: Updated IMAP EXAMINE handler to use dynamic test data 2013-08-29 20:08:27 +01:00
Daniel Stenberg
d737aa19c8 unit1304: include memdebug and free everything correctly 2013-08-29 12:50:15 +02:00
Daniel Stenberg
78e6683bb0 Curl_parsenetrc: document that the arguments must be allocated 2013-08-29 12:49:56 +02:00
Daniel Stenberg
2f9b64ac33 easy: rename struct monitor to socketmonitor
'struct monitor', introduced in 6cf8413e, already exists in an IRIX
header file (sys/mon.h) which gets included via various standard headers
by lib/easy.c

cc-1101 cc: ERROR File = ../../curl/lib/easy.c, Line = 458
"monitor" has already been declared in the current scope.

Reported-by: Tor Arntsen
2013-08-29 09:58:11 +02:00
Steve Holme
6a353049ac ftpserver.pl: Added SELECT check to IMAP FETCH and STORE handlers 2013-08-29 07:20:03 +01:00
Steve Holme
49e3d803ab ftpserver.pl: Corrected accidental move of logmsg() call
Corrected the call to logmsg() in the IMAP SEARCH handler from commit
4ae7b7ea69 as it should have been outputting the what argument and
not the test number.
2013-08-28 22:58:33 +01:00
Daniel Stenberg
b644ae68c8 ftpserver: add missing '}' from 4ae7b7ea69 2013-08-28 22:59:19 +02:00
Steve Holme
4ae7b7ea69 ftpserver.pl: Added SELECT check to IMAP SEARCH command 2013-08-28 18:56:19 +01:00
Steve Holme
13a2e32548 ftpserver.pl: Fixed IMAP SEARCH command 2013-08-28 18:51:59 +01:00
Daniel Stenberg
c3b513e75c bump: next release is 7.33.0 due to added features 2013-08-28 09:32:48 +02:00
Daniel Stenberg
a74b36af2a symbols-in-versions: add CURLOPT_XOAUTH2_BEARER 2013-08-28 09:31:37 +02:00
Steve Holme
1b4dc10393 tests: Added test for IMAP SEARCH command 2013-08-28 07:27:10 +01:00
Daniel Stenberg
45b6e2dd89 valgrind.supp: fix for regular curl_easy_perform too
When we introduced curl_easy_perform_ev, this got a slightly modified
call trace. Without this, test 165 causes a false positive valgrind
error.
2013-08-28 00:09:27 +02:00
Daniel Stenberg
6dca35c0e5 valgrind.supp: add the event-based call stack-trace too
Without this, test 165 triggers a valgrind error when ran with
curl_easy_perform_ev
2013-08-28 00:07:12 +02:00
Daniel Stenberg
a691e04470 multi_socket: improved 100-continue timeout handling
When waiting for a 100-continue response from the server, the
Curl_readwrite() will refuse to run if called until the timeout has been
reached.

We timeout code in multi_socket() allows code to run slightly before the
actual timeout time, so for test 154 it could lead to the function being
executed but refused in Curl_readwrite() and then the application would
just sit idling forever.

This was detected with runtests.pl -e on test 154.
2013-08-28 00:07:12 +02:00
Steve Holme
3d1a453d88 ftpserver.pl: Added support for IMAP SEARCH command 2013-08-27 20:47:31 +01:00
Steve Holme
d7a39f8f97 tool_operate.c: Fixed compilation warning
warning: implicit declaration of function 'checkpasswd'
2013-08-27 16:39:16 +01:00
Steve Holme
3c929ff9f6 curl: Moved check for password out of get parameter loop
Moved the calls to checkpasswd() out of the getparameter() function
which allows for any related arguments to be specified on the command
line before or after --user (and --proxy-user).

For example: --bearer doesn't need to be specified before --user to
prevent curl from asking for an unnecessary password as is the case
with commit e7dcc454c6.
2013-08-27 15:31:21 +01:00
Steve Holme
9d957294cb RELEASE-NOTES: synced with acf59be7f0 2013-08-26 23:27:07 +01:00
Kyle L. Huff
acf59be7f0 curl: added --bearer option to help
Added the --bearer option to the help output
2013-08-26 20:44:05 +01:00
Kyle L. Huff
e7dcc454c6 curl: added basic SASL XOAUTH2 support
Added the ability to specify an XOAUTH2 bearer token [RFC6750] via the
--bearer option.

Example usage:
  curl --url "imaps://imap.gmail.com:993/INBOX/;UID=1" --ssl-reqd
  --bearer ya29.AHES6Z...OMfsHYI --user username@example.com
2013-08-26 20:43:02 +01:00
Steve Holme
84789e12fb tool_urlglob.c: Fixed compiler warnings
warning: 'variable' may be used uninitialized in this function
2013-08-26 11:41:35 +01:00
Daniel Stenberg
460fb12097 security.h: rename to curl_sec.h to avoid name collision
I brought back security.h in commit bb55293313. As we actually
already found out back in 2005 in commit 62970da675, the file name
security.h causes problems so I renamed it curl_sec.h instead.
2013-08-26 11:51:18 +02:00
Daniel Stenberg
63d8b3a507 runtests.pl: allow -vc point to a separate curl binary to verify with
The specified curl binary will then be used to verify the running
server(s) instead of the development version. This is very useful in
some cases when the development version fails to verify correctly as
then the test case may not run at all.

The actual test will still be run with the "normal" curl executable
(unless the test case specifies something differently).
2013-08-26 11:38:38 +02:00
Kyle L. Huff
90ab65c632 smtp: added basic SASL XOAUTH2 support
Added the ability to use an XOAUTH2 bearer token [RFC6750] with SMTP for
authentication using RFC6749 "OAuth 2.0 Authorization Framework".

The bearer token is expected to be valid for the user specified in
conn->user. If CURLOPT_XOAUTH2_BEARER is defined and the connection has
an advertised auth mechanism of "XOAUTH2", the user and access token are
formatted as a base64 encoded string and sent to the server as
"AUTH XOAUTH2 <bearer token>".
2013-08-26 10:16:44 +01:00
Kyle L. Huff
34122800b8 imap: added basic SASL XOAUTH2 support
Added the ability to use an XOAUTH2 bearer token [RFC6750] with IMAP for
authentication using RFC6749 "OAuth 2.0 Authorization Framework".

The bearer token is expected to be valid for the user specified in
conn->user. If CURLOPT_XOAUTH2_BEARER is defined and the connection has
an advertised auth mechanism of "XOAUTH2", the user and access token are
formatted as a base64 encoded string and sent to the server as
"A001 AUTHENTICATE XOAUTH2 <bearer token>".
2013-08-26 10:16:32 +01:00
Steve Holme
7f41eab395 security.h: Fixed compilation warning
ISO C forbids forward references to 'enum' types
2013-08-26 10:14:16 +01:00
Daniel Stenberg
0192ad65bb KNOWN_BUGS: refer to bug numbers with the existing number series
The old numbers would still redirect but who knows for how long...
2013-08-26 00:29:33 +02:00
Kyle L. Huff
06c1bea72f options: added basic SASL XOAUTH2 support
Added the ability to specify an XOAUTH2 bearer token [RFC6750] via the
option CURLOPT_XOAUTH2_BEARER for authentication using RFC6749 "OAuth
2.0 Authorization Framework".
2013-08-25 22:03:57 +01:00
Kyle L. Huff
19a05c908f sasl: added basic SASL XOAUTH2 support
Added the ability to generated a base64 encoded XOAUTH2 token
containing: "user=<username>^Aauth=Bearer <bearer token>^A^A"
as per RFC6749 "OAuth 2.0 Authorization Framework".
2013-08-25 22:02:38 +01:00
Daniel Stenberg
bb55293313 FTP: remove krb4 support
We've announced this pending removal for a long time and we've
repeatedly asked if anyone would care or if anyone objects. Nobody has
objected. It has probably not even been working for a good while since
nobody has tested/used this code recently.

The stuff in krb4.h that was generic enough to be used by other sources
is now present in security.h
2013-08-25 19:16:36 +02:00
Daniel Stenberg
817ceb09e0 easy: define away easy_events() for non-debug builds 2013-08-25 19:10:02 +02:00
Daniel Stenberg
1a911f7ec4 FAQ: editorial updates
Several language fixes. Several reformats that should make the HTML
generation of this document look better.

Reported-by: Dave Thompson
2013-08-24 17:13:46 +02:00
Daniel Stenberg
ea464d72e9 RELEASE-NOTES: synced with 22adb46a32 2013-08-23 15:39:03 +02:00
Daniel Stenberg
22adb46a32 multi: move on from STATE_DONE faster
Make sure we always return CURLM_CALL_MULTI_PERFORM when we reach
CURLM_STATE_DONE since the state is transient and it can very well
continue executing as there is nothing to wait for.

Bug: http://curl.haxx.se/mail/lib-2013-08/0211.html
Reported-by: Yi Huang
2013-08-22 22:55:25 +02:00
Daniel Stenberg
fc99eaa5ae curl.h: name space pollution by "enum type"
Renamed to "enum curl_khtype" now. Will break compilation for programs
that rely on the enum name.

Bug: https://github.com/bagder/curl/pull/76
Reported-by: Shawn Landden
2013-08-22 22:45:51 +02:00
Daniel Stenberg
4bea91fc67 TFTP: make the CURLOPT_LOW_SPEED* options work
... this also makes sure that the progess callback gets called more
often during TFTP transfers.

Added test 1238 to verify.

Bug: http://curl.haxx.se/bug/view.cgi?id=1269
Reported-by: Jo3
2013-08-22 22:42:27 +02:00
Daniel Stenberg
06d1b10cbe tftpd: support "writedelay" within <servercmd> 2013-08-22 19:23:08 +02:00
Daniel Stenberg
816b639035 tftpd: convert 6 global variables into local ones 2013-08-22 13:44:37 +02:00
Gisle Vanem
8804ffd4fa curl_easy_perform_ev: make it CURL_EXTERN
I build curl.exe (using MingW) with '-DCURLDEBUG' and by importing from
libcurl.dll.  Which means the new curl_easy_perform_ev() must be
exported from libcurl.dll.
2013-08-21 22:19:52 +02:00
Daniel Stenberg
19122c0768 CURLM_ADDED_ALREADY: new error code
Doing curl_multi_add_handle() on an easy handle that is already added to
a multi handle now returns this error code. It previously returned
CURLM_BAD_EASY_HANDLE for this condition.
2013-08-20 23:13:19 +02:00
Daniel Stenberg
c346c4c8f9 multi_init: moved init code here from add_handle
The closure_handle is "owned" by the multi handle and it is
unconditional so the setting up of it should be in the Curl_multi_handle
function rather than curl_multi_add_handle.
2013-08-20 23:13:19 +02:00
Daniel Stenberg
bc7d806e3a multi: remove dns cache creation code from *add_handle
As it is done unconditionally in multi_init() this code will never run!
2013-08-20 23:13:19 +02:00
Daniel Stenberg
6cf8413e31 curl_easy_perform_ev: debug/test function
This function is meant to work *exactly* as curl_easy_perform() but will
use the event-based libcurl API internally instead of
curl_multi_perform(). To avoid relying on an actual event-based library
and to not use non-portable functions (like epoll or similar), there's a
rather inefficient emulation layer implemented on top of Curl_poll()
instead.

There's currently some convenience logging done in curl_easy_perform_ev
which helps when tracking down problems. They may be suitable to remove
or change once things seem to be fine enough.

curl has a new --test-event option when built with debug enabled that
then uses curl_easy_perform_ev() instead of curl_easy_perform(). If
built without debug, using --test-event will only output a warning
message.

NOTE: curl_easy_perform_ev() is not part if the public API on purpose.
It is only present in debug builds of libcurl and MUST NOT be considered
stable even then. Use it for libcurl-testing purposes only.

runtests.pl now features an -e command line option that makes it use
--test-event for all curl command line tests. The man page is updated.
2013-08-20 11:56:06 +02:00
Gisle Vanem
062e5bfd9c transfer: the recent sessionhandle change broke CURL_DOES_CONVERSIONS 2013-08-20 11:42:34 +02:00
Daniel Stenberg
e4a1888bd0 test1237: verify 1000+ letter user name + passwords 2013-08-20 11:23:31 +02:00
Jonathan Nieder
2f1a0bc0bf url: handle arbitrary-length username and password before '@'
libcurl quietly truncates usernames, passwords, and options from
before an '@' sign in a URL to 255 (= MAX_CURL_PASSWORD_LENGTH - 1)
characters to fit in fixed-size buffers on the stack.  Allocate a
buffer large enough to fit the parsed fields on the fly instead to
support longer passwords.

After this change, there are no more uses of MAX_CURL_OPTIONS_LENGTH
left, so stop defining that constant while at it.  The hardcoded max
username and password length constants, on the other hand, are still
used in HTTP proxy credential handling (which this patch doesn't
touch).

Reported-by: Colby Ranger
2013-08-20 11:16:38 +02:00
Jonathan Nieder
09ddb1d61c url: handle exceptional cases first in parse_url_login()
Instead of nesting "if(success)" blocks and leaving the reader in
suspense about what happens in the !success case, deal with failure
cases early, usually with a simple goto to clean up and return from
the function.

No functional change intended.  The main effect is to decrease the
indentation of this function slightly.
2013-08-20 11:16:38 +02:00
Jonathan Nieder
15f76bf7bb Curl_setopt: handle arbitrary-length username and password
libcurl truncates usernames, passwords, and options set with
curl_easy_setopt to 255 (= MAX_CURL_PASSWORD_LENGTH - 1) characters.
This doesn't affect the return value from curl_easy_setopt(), so from
the caller's point of view, there is no sign anything strange has
happened, except that authentication fails.

For example:

  # Prepare a long (300-char) password.
  s=0123456789; s=$s$s$s$s$s$s$s$s$s$s; s=$s$s$s;
  # Start a server.
  nc -l -p 8888 | tee out & pid=$!
  # Tell curl to pass the password to the server.
  curl --user me:$s http://localhost:8888 & sleep 1; kill $pid
  # Extract the password.
  userpass=$(
	awk '/Authorization: Basic/ {print $3}' <out |
	tr -d '\r' |
	base64 -d
  )
  password=${userpass#me:}
  echo ${#password}

Expected result: 300
Actual result: 255

The fix is simple: allocate appropriately sized buffers on the heap
instead of trying to squeeze the provided values into fixed-size
on-stack buffers.

Bug: http://bugs.debian.org/719856
Reported-by: Colby Ranger
2013-08-20 11:16:38 +02:00
Jonathan Nieder
36585b5395 netrc: handle longer username and password
libcurl truncates usernames and passwords it reads from .netrc to
LOGINSIZE and PASSWORDSIZE (64) characters without any indication to
the user, to ensure the values returned from Curl_parsenetrc fit in a
caller-provided buffer.

Fix the interface by passing back dynamically allocated buffers
allocated to fit the user's input.  The parser still relies on a
256-character buffer to read each line, though.

So now you can include an ~246-character password in your .netrc,
instead of the previous limit of 63 characters.

Reported-by: Colby Ranger
2013-08-20 11:16:38 +02:00
Jonathan Nieder
11baffbff6 url: allocate username, password, and options on the heap
This makes it possible to increase the size of the buffers when needed
in later patches.  No functional change yet.
2013-08-20 11:16:38 +02:00
Jonathan Nieder
53333a43a1 url: use goto in create_conn() for exception handling
Instead of remembering before each "return" statement which temporary
allocations, if any, need to be freed, take care to set pointers to
NULL when no longer needed and use a goto to a common block to exit
the function and free all temporaries.

No functional change intended.  Currently the only temporary buffer in
this function is "proxy" which is already correctly freed when
appropriate, but there will be more soon.
2013-08-20 11:16:38 +02:00
Jonathan Nieder
c56f9797e7 sasl: allow arbitrarily long username and password
Use appropriately sized buffers on the heap instead of fixed-size
buffers on the stack, to allow for longer usernames and passwords.

Callers never pass anything longer than MAX_CURL_USER_LENGTH (resp.
MAX_CURL_PASSWORD_LENGTH), so no functional change inteded yet.
2013-08-20 11:16:38 +02:00
Alex McLellan
9281be36d5 imap: Fixed response check for SEARCH command
Adding this line allows libcurl to return the server response when
performing a search command via a custom request.
2013-08-19 10:23:14 +01:00
Daniel Stenberg
f15a88f2b2 glob: error out on range overflow
The new multiply() function detects range value overflows. 32bit
machines will overflow on a 32bit boundary while 64bit hosts support
ranges up to the full 64 bit range.

Added test 1236 to verify.

Bug: http://curl.haxx.se/bug/view.cgi?id=1267
Reported-by: Will Dietz
2013-08-16 11:55:04 +02:00
Daniel Stenberg
5ca96cb844 urlglob: better detect unclosed braces, empty lists and overflows
A rather big overhaul and cleanup.

1 - curl wouldn't properly detect and reject globbing that ended with an
open brace if there were brackets or braces before it. Like "{}{" or
"[0-1]{"

2 - curl wouldn't properly reject empty lists so that "{}{}" would
result in curl getting (nil) strings in the output.

3 - By using strtoul() instead of sscanf() the code will now detected
over and underflows. It now also better parses the step argument to only
accept positive numbers and only step counters that is smaller than the
delta between the maximum and minimum numbers.

4 - By switching to unsigned longs instead of signed ints for the
counters, the max values for []-ranges are now very large (on 64bit
machines).

5 - Bumped the maximum number of globs in a single URL to 100 (from 10)

6 - Simplified the code somewhat and now it stores fixed strings as
single- entry lists. That's also one of the reasons why I did (5) as now
all strings between "globs" will take a slot in the array.

Added test 1234 and 1235 to verify. Updated test 87.

This commit fixes three separate bug reports.

Bug: http://curl.haxx.se/bug/view.cgi?id=1264
Bug: http://curl.haxx.se/bug/view.cgi?id=1265
Bug: http://curl.haxx.se/bug/view.cgi?id=1266
Reported-by: Will Dietz
2013-08-16 11:52:08 +02:00
John Malmberg
10afe7cf10 VMS: Add RELEASE-NOTES to vms document
Add the curl release notes to the release note document generated for
VMS packages.

Add the different filenames generated by a daily build to the
cleanup procedures.
2013-08-15 10:57:52 +02:00
Tor Arntsen
6972335f50 tests 2032, 2033: Don't hardcode port in expected output 2013-08-15 10:55:44 +02:00
Daniel Stenberg
d5e2d0b6bf ftp: convert state names to a global array
... just to make them easier to print in debug ouputs while debugging.
They are still within #ifdef [debugbuild].
2013-08-14 22:41:30 +02:00
Daniel Stenberg
f34b5fb4d8 --help: fix the --sasl-ir in the help output 2013-08-14 22:39:58 +02:00
Daniel Stenberg
f584312e81 ftp_domore_getsock: when passive mode, the second conn is already there
This makes the socket callback get called with the proper bitmask as
otherwise the application could be left hanging waiting for reading on
an upload connection!

Bug: http://curl.haxx.se/mail/lib-2013-08/0043.html
Reported-by: Bill Doyle
2013-08-14 22:30:24 +02:00
Daniel Stenberg
0b4557f766 curl: make --no-[option] work properly for several options
--create-dirs, --crlf, --socks5-gssapi-nec and --sasl-ir
2013-08-14 11:39:04 +02:00
Kamil Dudka
204126a5f1 nss: make sure that NSS is initialized
... prior to calling PK11_GenerateRandom()
2013-08-12 15:17:39 +02:00
Daniel Stenberg
2ae3d28f3d multi: s/easy/data
With everything being struct SessionHandle pointers now, this rename
makes multi.c use the library-wide practise of calling that pointer
'data' instead of the previously used 'easy'.
2013-08-12 13:52:58 +02:00
Daniel Stenberg
8a42c2ef8d cleanup: removed one function, made one static
Moved Curl_easy_addmulti() from easy.c to multi.c, renamed it to
easy_addmulti and made it static.

Removed Curl_easy_initHandleData() and uses of it since it was emptied
in commit cdda92ab67b47d74a.
2013-08-12 13:17:57 +02:00
Daniel Stenberg
e79535bc5e SessionHandle: the protocol specific pointer is now a void *
All protocol handler structs are now opaque (void *) in the
SessionHandle struct and moved in the request-specific sub-struct
'SingleRequest'. The intension is to keep the protocol specific
knowledge in their own dedicated source files [protocol].c etc.

There's some "leakage" where this policy is violated, to be addressed at
a later point in time.
2013-08-12 13:17:57 +02:00
Daniel Stenberg
4ad8e142da urldata: clean up the use of the protocol specific structs
1 - always allocate the struct in protocol->setup_connection. Some
protocol handlers had to get this function added.

2 - always free at the end of a request. This is also an attempt to keep
less memory in the handle after it is completed.
2013-08-12 13:17:57 +02:00
Daniel Stenberg
e3ee73b70c version number: bump to 7.32.1 for now
Start working on the next version and up some counters.
2013-08-12 13:16:44 +02:00
Daniel Stenberg
70812c2f32 THANKS: added contributors from the 7.32.0 release notes 2013-08-11 23:43:32 +02:00
Fabian Keil
a64bca68c7 test1228: add 'HTTP proxy' to the keywords 2013-08-11 19:56:23 +02:00
Fabian Keil
67633e1308 tests: add keywords for a couple of FILE tests 2013-08-11 19:56:14 +02:00
Fabian Keil
715ca7c5fe tests: add 'FAILURE' keywords to tests 1409 and 1410 2013-08-11 19:56:11 +02:00
Fabian Keil
001758760b tests: add keywords for a couple of HTTP tests 2013-08-11 19:56:05 +02:00
Fabian Keil
2f06265e39 tests: add keywords for a couple of FTP tests 2013-08-11 19:56:01 +02:00
Fabian Keil
432431368f test1511: consistently terminate headers with CRLF 2013-08-11 19:55:44 +02:00
Daniel Stenberg
4b0028f82d DISABLED: shut of test 1512 for now
It shows intermittent failures and I haven't been able to track them
down yet. Disable this test for now.
2013-08-10 23:55:10 +02:00
Daniel Stenberg
8c9236bb2c curl_multi_add_handle.3: ... that timer callback is for event-based 2013-08-09 23:53:51 +02:00
Daniel Stenberg
2af0b10c95 comments: remove old and wrong multi/easy interface statements 2013-08-09 23:39:09 +02:00
Daniel Stenberg
08adecc9a1 curl_multi_add_handle.3: mention the CURLMOPT_TIMERFUNCTION use 2013-08-09 23:27:43 +02:00
John E. Malmberg
015556d74c KNOWN_BUGS: 22 and 57 have been fixed and committed 2013-08-08 23:34:36 +02:00
Daniel Stenberg
4c40fe64b8 RELEASE-NOTES: synced with d20def2046 2013-08-08 16:37:17 +02:00
Daniel Stenberg
d20def2046 global dns cache: fix memory leak
The take down of the global dns cache didn't take CURLOPT_RESOLVE names
into account.
2013-08-08 16:28:46 +02:00
Daniel Stenberg
d2b36e466a global dns cache: didn't work [regression]
CURLOPT_DNS_USE_GLOBAL_CACHE broke in commit c43127414d (been
broken since the libcurl 7.29.0 release). While this option has been
documented as deprecated for almost a decade and nobody even reported
this bug, it should remain functional.

Added test case 1512 to verify
2013-08-08 16:28:46 +02:00
John Malmberg
27f8c93daf packages/vms: update VMS build files
VMS modified files either missing from a previous commit and changes
to remove references to CVS repositories.
2013-08-08 13:13:56 +02:00
Daniel Stenberg
058b86e6f3 FTP: renamed several local functions
The previous naming scheme ftp_state_post_XXXX() wasn't really helpful
as it wasn't always immediately after 'xxxx' and it wasn't easy to
understand what it does based on such a name.

This new one is instead ftp_state_yyyy() where yyyy describes what it
does or sends.
2013-08-08 12:19:01 +02:00
Daniel Stenberg
0018d6830e mk-ca-bundle.1: don't install on make install
Since the mk-ca-bundle tool itself isn't installed with make install,
there's no point in installing its documentation.

Bug: http://curl.haxx.se/mail/lib-2013-08/0057.html
Reported-by: Guenter Knauf
2013-08-08 09:45:51 +02:00
Yang Tse
59224a31fd packages/vms/Makefile.am: add latest file additions to EXTRA_DIST 2013-08-07 12:21:56 +02:00
John Malmberg
0994d737c8 Building_vms_pcsi_kit
These are the files needed to build VMS distribution packages known as
PCSI kits.

Also minor update to the existing files, mainly to the documentation and
file clean up code.
2013-08-07 12:16:08 +02:00
Daniel Stenberg
96749554fd LIBCURL-STRUCTS: new document
This is the first version of this new document, detailing the seven
perhaps most important internal structs in libcurl source code:

  1.1 SessionHandle
  1.2 connectdata
  1.3 Curl_multi
  1.4 Curl_handler
  1.5 conncache
  1.6 Curl_share
  1.7 CookieInfo
2013-08-06 14:13:33 +02:00
Daniel Stenberg
785749405f CONTRIBUTE: minor language polish 2013-08-06 14:12:45 +02:00
Daniel Stenberg
7cc00d9a83 FTP: when EPSV gets a 229 but fails to connect, retry with PASV
This is a regression as this logic used to work. It isn't clear when it
broke, but I'm assuming in 7.28.0 when we went all-multi internally.

This likely never worked with the multi interface. As the failed
connection is detected once the multi state has reached DO_MORE, the
Curl_do_more() function was now expanded somewhat so that the
ftp_do_more() function can request to go "back" to the previous state
when it makes another attempt - using PASV.

Added test case 1233 to verify this fix. It has the little issue that it
assumes no service is listening/accepting connections on port 1...

Reported-by: byte_bucket in the #curl IRC channel
2013-08-06 09:57:59 +02:00
Nick Zitzmann
230e16dc03 md5: remove use of CommonCrypto-to-OpenSSL macros for the benefit of Leopard
For some reason, OS X 10.5's GCC suddenly stopped working correctly with
macros that change MD5_Init etc. in the code to CC_MD5_Init etc., so I
worked around this by removing use of the macros and inserting static
functions that just call CommonCrypto's implementations of the functions
instead.
2013-08-05 19:47:56 -06:00
Guenter Knauf
0ce410a629 Simplify check for trusted certificates.
This changes the previous check for untrusted certs to a check for
certs explicitely marked as trusted.
The change is backward-compatible (tested with certdata.txt v1.80).
2013-08-05 13:02:27 +02:00
Daniel Stenberg
5d3cbde72e configure: warn on bad env variable use, don't error
Use XC_CHECK_BUILD_FLAGS instead XC_CHECK_USER_FLAGS.
2013-08-05 09:31:59 +02:00
Daniel Stenberg
8fe8fd2b17 Revert "configure: don't error out on variable confusions, just warn"
This reverts commit 6b27703b5f.
2013-08-05 09:28:44 +02:00
Daniel Stenberg
0ddc678927 formadd: wrong pointer for file name when CURLFORM_BUFFERPTR used
The internal function that's used to detect known file extensions for
the default Content-Type got the the wrong pointer passed in when
CURLFORM_BUFFER + CURLFORM_BUFFERPTR were used. This had the effect that
strlen() would be used which could lead to an out-of-bounds read (and
thus segfault). In most cases it would only lead to it not finding or
using the correct default content-type.

It also showed that test 554 and test 587 were testing for the
previous/wrong behavior and now they're updated as well.

Bug: http://curl.haxx.se/bug/view.cgi?id=1262
Reported-by: Konstantin Isakov
2013-08-04 23:32:36 +02:00
Guenter Knauf
51f0b798fa Skip more untrusted certificates.
Christian Heimes brought to our attention that the certdata.txt
format has recently changed [1], causing ca-bundle.crt created
with mk-ca-bundle.[pl|vbs] to include untrusted certs.

[1] http://lists.debian.org/debian-release/2012/11/msg00411.html
2013-08-04 21:30:11 +02:00
Daniel Stenberg
6b27703b5f configure: don't error out on variable confusions, just warn 2013-08-04 10:28:26 +02:00
Daniel Stenberg
045ccb59a4 configure: rephrase the notice in _XC_CHECK_VAR_*
Instead of claiming it is an error, we call it a "note" to reduce the
severity level. But the following text now says the [variable] "*should*
only be used to specify"... instead of previously having said "may".
2013-08-03 23:39:23 +02:00
Daniel Stenberg
784336deec multi: remove data->state.current_conn struct field
Not needed
2013-08-03 22:51:35 +02:00
Daniel Stenberg
eb41e8eebe multi: remove the one_easy struct field
Since the merge of SessionHandle with Curl_one_easy, this indirection
isn't used anymore.
2013-08-03 22:51:35 +02:00
Daniel Stenberg
3cd43bbfec multi: rename all Curl_one_easy to SessionHandle 2013-08-03 22:51:35 +02:00
Daniel Stenberg
204e340bcd multi: remove the multi_pos struct field
Since Curl_one_easy is really a SessionHandle now, this indirection
doesn't exist anymore.
2013-08-03 22:51:35 +02:00
Daniel Stenberg
37f2ba7e57 multi: remove easy_handle struct field
It isn't needed anymore
2013-08-03 22:51:35 +02:00
Daniel Stenberg
09b9fc9009 multi: remove 'Curl_one_easy' struct, phase 1
The motivation for having a separate struct that keep track of an easy
handle when using the multi handle was removed when we switched to
always using the multi interface internally. Now they were just two
separate struct that was always allocated for each easy handle.

This first step just moves the Curl_one_easy struct members into the
SessionHandle struct and hides this somehow (== keeps the source code
changes to a minimum) by defining Curl_one_easy to SessionHandle

The biggest changes in this commit are:

 1 - the linked list of easy handles had to be changed somewhat due
     to the new struct layout. This made the main linked list pointer
     get renamed to 'easyp' and there's also a new pointer to the last
     node, called easylp. It is no longer circular but ends with ->next
     pointing to NULL. New nodes are still added last.

 2 - easy->state is now called easy->mstate to avoid name collision
2013-08-03 22:51:35 +02:00
Steve Holme
7da3caaf95 Revert "DOCS: Added IMAP URL example for listing new messages"
This reverts commit 82ab5f1b0c as this was the wrong place to
document the complexity of IMAP URLs and Custom Requests.
2013-08-02 14:25:21 +01:00
Steve Holme
82ab5f1b0c DOCS: Added IMAP URL example for listing new messages
In addition to listing the folder contents, in the URL examples, added
an example to list the new messages waiting in the user's inbox.
2013-08-02 10:08:55 +01:00
Yang Tse
7ae64af368 packages/vms/Makefile.am: add latest file additions to EXTRA_DIST 2013-08-01 13:57:00 +02:00
John Malmberg
2ad688ed7c Add in the files needed to build libcurl shared images on VMS.
Update the packages/vms/readme file to be current.

Also some files for the GNV based build were either missing or needed an
update.

curl_crtl_init.c is a special file that is run before main() to
set up the proper C runtime behavior.

generate_vax_transfer.com generates the VAX transfer vector modules from
the gnv_libcurl_symbols.opt file.

gnv_conftest.c_first is a helper file needed for configure scripts to
come up with the expected answers on VMS.

gnv_libcurl_symbols.opt is the public symbols for the libcurl shared
image.

gnv_link_curl.com builds the shared libcurl image and rebuilds other
programs to use it.

macro32_exactcase.patch is a hack to make a local copy of the VMS Macro32
assembler case sensitive, which is needed to build the VAX transfer modules.

report_openssl_version.c is a tool for help verify that the libcurl
shared image is being built for a minium version of openssl.
2013-08-01 13:51:52 +02:00
Yang Tse
ca786233d2 curl: second follow-up for commit 5af2bfb9
Display progress-bar unconditionally on first call
2013-08-01 12:25:01 +02:00
Yang Tse
14a3139c4d curl: follow-up for commit 5af2bfb9
Use tvnow() and tvdiff() to avoid introducing new linkage issues
2013-07-31 15:36:56 +02:00
Daniel Stenberg
5af2bfb955 curl: --progress-bar max update frequency now at 5Hz 2013-07-31 13:41:00 +02:00
Daniel Stenberg
1691a31cab curl: make --progress-bar update the line less frequently
Also, use memset() instead of a lame loop.

The previous logic that tried to avoid too many updates were very
ineffective for really fast transfers, as then it could easily end up
doing hundreds of updates per second that would make a significant
impact in transfer performance!

Bug: http://curl.haxx.se/mail/archive-2013-07/0031.html
Reported-by: Marc Doughty
2013-07-31 13:41:00 +02:00
Nick Zitzmann
9dedcbf9ec darwinssl: added LFs to some strings passed into infof()
(This doesn't need to appear in the release notes.) I noticed a few places
where infof() was called, and there should've been an LF at the end of the
string, but there wasn't.
2013-07-30 20:32:18 -06:00
Nick Zitzmann
537ffc4c69 darwinssl: fix build error in crypto authentication under Snow Leopard
It turns out Snow Leopard not only has SecItemCopyMatching() defined in
a header not included by the omnibus header, but it won't work for our
purposes, because searching for SecIdentityRef objects wasn't added
to that API until Lion. So we now use the old SecKeychainSearch API
instead if the user is building under, or running under, Snow Leopard.

Bug: http://sourceforge.net/p/curl/bugs/1255/
Reported by: Edward Rudd
2013-07-30 20:25:38 -06:00
Nick Zitzmann
c3e7210548 md5 & metalink: use better build macros on Apple operating systems
Previously we used __MAC_10_X and __IPHONE_X to mark digest-generating
code that was specific to OS X and iOS. Now we use
__MAC_OS_X_VERSION_MAX_ALLOWED and __IPHONE_OS_VERSION_MAX_ALLOWED
instead of those macros.

Bug: http://sourceforge.net/p/curl/bugs/1255/
Reported by: Edward Rudd
2013-07-30 20:20:20 -06:00
Yang Tse
9a5c2d8373 tool_operhlp.c: fix add_file_name_to_url() OOM handling 2013-07-29 18:32:39 +02:00
Yang Tse
8693bbd8c4 tool_operate.c: fix brace placement for vi/emacs delimiter matching 2013-07-29 18:32:38 +02:00
Yang Tse
251dd03b88 tool_operate.c: move <fabdef.h> header inclusion location 2013-07-29 18:32:37 +02:00
Daniel Stenberg
55ea83d622 RELEASE-NOTES: synced with b5478a0e03 2013-07-29 14:51:09 +02:00
Daniel Stenberg
b5478a0e03 curl_easy_pause: on unpause, trigger mulit-socket handling
When the multi-socket API is used, we need the handle to be checked
again when it gets unpaused.

Bug: http://curl.haxx.se/mail/lib-2013-07/0239.html
Reported-by: Justin Karneges
2013-07-29 14:37:08 +02:00
John E. Malmberg
db2deba6b4 curl_formadd: fix file upload on VMS
For the standard VMS text file formats, VMS needs to read the file to
get the actual file size.

For the standard VMS binary file formats, VMS needs a special format of
fopen() call so that it stops reading at the logical end of file instead
of at the end of the blocks allocated to the file.

I structured the patch this way as I was not sure about changing the
structures or parameters to the routines, but would prefer to only call
the stat() function once and pass the information to where the fopen()
call is made.

Bug: https://sourceforge.net/p/curl/bugs/758/
2013-07-29 13:09:08 +02:00
Daniel Stenberg
41fb6443ce formadd: CURLFORM_FILECONTENT wrongly rejected some option combos
The code for CURLFORM_FILECONTENT had its check for duplicate options
wrong so that it would reject CURLFORM_PTRNAME if used in combination
with it (but not CURLFORM_COPYNAME)! The flags field used for this
purpose cannot be interpreted that broadly.

Bug: http://curl.haxx.se/mail/lib-2013-07/0258.html
Reported-by: Byrial Jensen
2013-07-26 23:45:01 +02:00
Yang Tse
e5dfe6c282 packages/vms/Makefile.am: add latest file additions to EXTRA_DIST 2013-07-25 13:18:50 +02:00
John E. Malmberg
e277e20a6d VMS: intial set of files to allow building using GNV toolkit. 2013-07-25 13:04:29 +02:00
Yang Tse
a23e56d109 string formatting: fix too many arguments for format 2013-07-24 17:06:28 +02:00
Yang Tse
ca89a0a092 string formatting: fix zero-length printf format string 2013-07-24 17:05:02 +02:00
Yang Tse
50a74be125 easy.c: curl_easy_getinfo() fix va_start/va_end matching 2013-07-24 16:46:26 +02:00
Yang Tse
8c1e3bb713 imap.c: imap_sendf() fix va_start/va_end matching 2013-07-24 16:46:25 +02:00
Yang Tse
4fad1943a2 string formatting: fix 15+ printf-style format strings 2013-07-24 16:46:24 +02:00
Patrick Monnerat
4d346673a2 OS400: sync ILE/RPG binding with current curl.h 2013-07-24 16:12:35 +02:00
Yang Tse
de052ca6fc string formatting: fix 25+ printf-style format strings 2013-07-24 01:21:26 +02:00
Daniel Stenberg
1a593191c2 Makefile.am: use LDFLAGS as well when linking libcurl
Linking on Solaris 10 x86 with Sun Studio 12 failed when we upgraded
automake for the release builds.

Bug: http://curl.haxx.se/bug/view.cgi?id=1217
Reported-by: Dagobert Michelsen
2013-07-23 21:51:12 +02:00
Fabian Keil
2c4ef997b9 url.c: Fix dot file path cleanup when using an HTTP proxy
Previously the path was cleaned, but the URL wasn't properly updated.
2013-07-23 20:51:15 +02:00
Fabian Keil
d020e2c381 tests: test1232 verifies dotdot removal from path with proxy 2013-07-23 20:51:15 +02:00
Fabian Keil
48fe9226a0 dotdot.c: Fix a RFC section number in a comment for Curl_dedotdotify() 2013-07-23 20:50:59 +02:00
John E. Malmberg
a77ac42e52 build_vms.com: fix debug and float options
In the reorganization of the build_vms.com the debug and float options
were not fixed up correctly.
2013-07-22 22:30:05 +02:00
John E. Malmberg
5880db8abd curl: fix upload of a zip file in OpenVMS
Two fixes:

1. Force output file format to be stream-lf so that partial downloads
can be continued.

This should have minor impact as if the file does not exist, it was
created with stream-lf format.  The only time this was an issue is if
there was already an existing file with a different format.

2. Fix file uploads are now fixed.

   a. VMS binary files such as ZIP archives are now uploaded
      correctly.

   b. VMS text files are read once to get the correct size
      and then converted to line-feed terminated records as
      they are read into curl.

The default VMS text formats do not contain either line-feed or
carriage-return terminated records.  Those delimiters are added by the
operating system file read calls if the application requests them.

Bug: http://curl.haxx.se/bug/view.cgi?id=496
2013-07-22 22:30:05 +02:00
Yang Tse
0f4ba89ffd libtest: fix data type of some *_setopt() 'long' arguments 2013-07-22 21:40:45 +02:00
Yang Tse
edeb1ae65f curl: fix symbolic names for CURL_NETRC_* enum in --libcurl output 2013-07-22 21:40:44 +02:00
Yang Tse
82232bbbaf curl: fix symbolic names for CURLUSESSL_* enum in --libcurl output 2013-07-22 21:40:43 +02:00
Yang Tse
bb2e0686ab tool_operate.c: fix passing curl_easy_setopt long arg on some x64 ABIs
We no longer pass our 'bool' data type variables nor constants as
an argument to my_setopt(), instead we use proper 1L or 0L values.

This also fixes macro used to pass string argument for CURLOPT_SSLCERT,
CURLOPT_SSLKEY and CURLOPT_EGDSOCKET using my_setopt_str() instead of
my_setopt().

This also casts enum or int argument data types to long when passed to
my_setopt_enum().
2013-07-22 21:40:43 +02:00
Daniel Stenberg
513e587c5e curl_multi_wait: fix revents
Commit 6d30f8ebed didn't work properly. First, it used the wrong
array index, but this fix also:

1 - only does the copying if indeed there was any activity

2 - makes sure to properly translate between internal and external
bitfields, which are not guaranteed to match

Reported-by: Evgeny Turnaev
2013-07-21 21:54:47 +02:00
Daniel Stenberg
6ed2bcc5f5 RELEASE-NOTES: synced with d529f3882b 2013-07-19 23:38:43 +02:00
Daniel Stenberg
d529f3882b curl_easy_perform: gradually increase the delay time
Instead of going 50,100,150 etc millisecond delay time when nothing has
been found to do or wait for, we now start lower and double each loop as
in 4,8,16,32 etc.

This lowers the minimum wait without sacrifizing the longer wait too
much with unnecessary CPU cycles burnt.

Bug: http://curl.haxx.se/mail/lib-2013-07/0103.html
Reported-by: Andreas Malzahn
2013-07-19 23:27:17 +02:00
Daniel Stenberg
e2e92486a7 ftp_do_more: consider DO_MORE complete when server connects back
In the case of an active connection when ftp_do_more() detects that the
server has connected back, it must make sure to mark it as complete so
that the multi_runsingle() function will detect this and move on to the
next state.

Bug: http://curl.haxx.se/mail/lib-2013-07/0115.html
Reported-by: Clemens Gruber
2013-07-19 23:02:30 +02:00
Yang Tse
2e5b3168d6 Makefile.b32: Borland makefile adjustments. Tested with BCC 5.5.1 2013-07-19 12:33:11 +02:00
Yang Tse
6bcacff1a5 WIN32 MemoryTracking: require UNICODE for wide strdup code support 2013-07-19 12:33:10 +02:00
Daniel Stenberg
12d01cb6fa CURLOPT_XFERINFOFUNCTION: introducing a new progress callback
CURLOPT_XFERINFOFUNCTION is now the preferred progress callback function
and CURLOPT_PROGRESSFUNCTION is considered deprecated.

This new callback uses pure 'curl_off_t' arguments to pass on full
resolution sizes. It otherwise retains the same characteristics: the
same call rate, the same meanings for the arguments and the return code
is used the same way.

The progressfunc.c example is updated to show how to use the new
callback for newer libcurls while supporting the older one if built with
an older libcurl or even built with a newer libcurl while running with
an older.
2013-07-18 23:44:06 +02:00
Yang Tse
90695fb2c5 Reinstate "WIN32 MemoryTracking: track wcsdup() _wcsdup() and _tcsdup() usage".
This reverts commit 7ed25cc, reinstating commit 8ec2cb5.

As of 18-jul-2013 we still do have code in libcurl that makes use of these
memory functions. Commit 8ec2cb5 comment still applies and is yet valid.

These memory functions are solely used in Windows builds, so all related
code is protected with '#ifdef WIN32' preprocessor conditional compilation
directives.

Specifically, wcsdup() _wcsdup() are used when building a Windows target with
UNICODE and USE_WINDOWS_SSPI preprocessor symbols defined. This is the case
when building a Windows UNICODE target with Windows native SSL/TLS support
enabled.

Realizing that wcsdup() _wcsdup() are used is a bit tricky given that usage
of these is hidden behind _tcsdup() which is MS way of dealing with code
that must tolerate UNICODE and non-UNICODE compilation. Additionally, MS
header files and those compatible from other compilers use this preprocessor
conditional compilation directive in order to select at compilation time
whether 'wide' or 'ansi' MS API functions are used.

Without this code, Windows build targets with Windows native SSL/TLS support
enabled and MemoryTracking support enabled misbehave in tracking memory usage,
regardless of being a UNICODE enabled build or not.
2013-07-18 23:37:33 +02:00
Yang Tse
dd17069c9e xc-am-iface.m4: comments refinement 2013-07-18 16:03:15 +02:00
Yang Tse
26b0cb6ae2 configure: fix 'subdir-objects' distclean related issue
See XC_AMEND_DISTCLEAN comments for details.
2013-07-18 04:48:33 +02:00
Evgeny Turnaev
6d30f8ebed curl_multi_wait: set revents for extra fds
Pass back the revents that happened for the user-provided file
descriptors.
2013-07-18 00:06:09 +02:00
Ben Greear
11220678c4 asyn-ares: Don't blank ares servers if none configured.
Best to just let c-ares use it's defaults if none are configured
in (lib)curl.

Signed-off-by: Ben Greear <greearb@candelatech.com>
2013-07-17 23:55:58 +02:00
Sergei Nikulov
448d55ef0a cmake: Fix for MSVC2010 project generation
Fixed issue with static build for MSVC2010.

After some investigation I've discovered known issue
http://public.kitware.com/Bug/view.php?id=11240 When .rc file is linked
to static lib it fails with following linker error

LINK : warning LNK4068: /MACHINE not specified; defaulting to X86
file.obj : fatal error LNK1112: module machine type 'x64' conflicts with
target machine type 'X86'

Fix add target property /MACHINE: for MSVC generation.

Also removed old workarounds - it caused errors during msvc build.

Bug: http://curl.haxx.se/mail/lib-2013-07/0046.html
2013-07-17 00:26:58 +02:00
Daniel Stenberg
7b115cc1e1 mk-ca-bundle.1: point out certdata.txt format docs 2013-07-17 00:06:16 +02:00
Yang Tse
a10d5e3851 slist.c: Curl_slist_append_nodup() OOM handling fix 2013-07-16 23:59:05 +02:00
Daniel Stenberg
1016637f5a test1414: FTP PORT download without SIZE support 2013-07-16 22:54:31 +02:00
Yang Tse
2e00872c04 tests/Makefile.am: add configurehelp.pm to DISTCLEANFILES 2013-07-16 22:51:35 +02:00
Patrick Monnerat
56ece42c81 curl_slist_append(): fix error detection 2013-07-15 19:49:30 +02:00
Patrick Monnerat
99924f6606 slist.c: fix indentation 2013-07-15 19:46:19 +02:00
Patrick Monnerat
0eba02fd41 OS400: new SSL backend GSKit 2013-07-15 19:00:36 +02:00
Patrick Monnerat
464c8693d2 OS400: add slist and certinfo EBCDIC support 2013-07-15 18:48:02 +02:00
Patrick Monnerat
50af17ef24 config-os400.h: enable system strdup(), strcmpi(), etc. 2013-07-15 18:38:17 +02:00
Patrick Monnerat
3a24cb7bc4 x509asn1.c,x509asn1.h: new module to support ASN.1/X509 parsing & info extract
Use from qssl backend
2013-07-15 18:16:13 +02:00
Patrick Monnerat
e839446c2a ssluse.c,sslgen.c,sslgen.h: move certinfo support to generic SSL 2013-07-15 17:26:59 +02:00
Patrick Monnerat
695931cf8e Merge branch 'master' of github.com:bagder/curl
Merge for resync
2013-07-15 16:55:30 +02:00
Patrick Monnerat
964a7600b9 slist.c, slist.h, cookie.c: new internal procedure Curl_slist_append_nodup() 2013-07-15 16:53:43 +02:00
Yang Tse
d4492f955d sslgen.c: fix Curl_rand() compiler warning
Use simple seeding method upon RANDOM_FILE seeding method failure.
2013-07-15 16:00:32 +02:00
Yang Tse
9c15325d34 sslgen.c: fix unreleased Curl_rand() infinite recursion 2013-07-15 13:22:08 +02:00
Dave Reisner
d8c04909fa src/tool: allow timeouts to accept decimal values
Implement wrappers around strtod to convert the user argument to a
double with sane error checking. Use this to allow --max-time and
--connect-timeout to accept decimal values instead of strictly integers.

The manpage is updated to make mention of this feature and,
additionally, forewarn that the actual timeout of the operation can
vary in its precision (particularly as the value increases in its
decimal precision).
2013-07-14 23:04:05 +02:00
Dave Reisner
c0a7a98aee curl.1: fix long line, found by checksrc.pl 2013-07-14 22:50:29 +02:00
Dave Reisner
f5005dd8d0 src/tool_paramhlp: try harder to catch negatives
strto* functions happily chomp off leading whitespace, so simply
checking for str[0] can lead to false negatives. Do the full parse and
check the out value instead.
2013-07-14 22:48:29 +02:00
John E. Malmberg
d3aaa68f55 build_vms.com: detect and use zlib shared image
Update the build_vms.com to detect and use zlib shared image installed
by the ZLIB kit produced by Jean-Francois Pieronne, and the also the
future ZLIB 1.2.8 kit in addition to the older ZLIB kits.

Also fix the indentation to match one of the common standards used for
VMS DCL command files and removed the hard tab characters.

Tested on OpenVMS 8.4 Alpha and IA64, and OpenVMS 7.3 VAX.
2013-07-14 17:37:49 +02:00
Yang Tse
cfc907e43d url.c: fix parse_url_login() OOM handling 2013-07-14 12:19:57 +02:00
Yang Tse
2af64c6432 http_digest.c: SIGSEGV and OOM handling fixes 2013-07-12 19:32:13 +02:00
Yang Tse
83f0dae129 url.c: fix parse_login_details() OOM handling 2013-07-12 12:17:31 +02:00
John E. Malmberg
65d53cf6ef setup-vms.h: sk_pop symbol tweak
Newer versions of curl are referencing a sk_pop symbol while the HP
OpenSSL library has the symbol in uppercase only.
2013-07-12 12:11:11 +02:00
Yang Tse
0d9e65f79f getinfo.c: fix enumerated type mixed with another type 2013-07-11 17:07:36 +02:00
Yang Tse
c983aa9efc test 1511: fix enumerated type mixed with another type 2013-07-11 17:01:02 +02:00
Yang Tse
b16b7f9d3a url.c: fix SIGSEGV 2013-07-11 13:31:08 +02:00
Yang Tse
5c6f12b9f2 dotdot.c: fix global declaration shadowing 2013-07-11 13:31:07 +02:00
Yang Tse
2022b10e50 easy.c: fix global declaration shadowing 2013-07-11 13:31:06 +02:00
Kamil Dudka
45339625bc Revert "curl.1: document the --time-cond option in the man page"
This reverts commit 3a0e931fc7 because
the documentation of --time-cond was duplicated by mistake.

Reported by: Dave Reisner
2013-07-09 15:46:49 +02:00
Kamil Dudka
20ff820ef2 curl.1: document the --sasl-ir option in the man page 2013-07-09 15:18:39 +02:00
Kamil Dudka
39e85d99fe curl.1: document the --post303 option in the man page 2013-07-09 15:18:39 +02:00
Kamil Dudka
3a0e931fc7 curl.1: document the --time-cond option in the man page 2013-07-09 15:18:39 +02:00
Yang Tse
fe7e3229f8 configure: automake 1.14 compatibility tweak (use XC_AUTOMAKE) 2013-07-09 00:10:38 +02:00
Yang Tse
ecf042ff3c xc-am-iface.m4: provide XC_AUTOMAKE macro 2013-07-09 00:07:26 +02:00
Guenter Knauf
aff245b360 Added winssl-zlib target to VC builds. 2013-07-08 17:46:15 +02:00
Guenter Knauf
e01469907a Synced Makefile.vc6 with recent changes.
Issue posted to the list by malinowsky AT FTW DOT at.
2013-07-08 15:05:10 +02:00
Guenter Knauf
b7a933154a Added libmetalink URL; added Android versions. 2013-07-04 04:35:22 +02:00
Dan Fandrich
54f18e5427 examples: Moved usercertinmem.c to COMPLICATED_EXAMPLES
This prevents it from being built during a "make check" since it
depends on OpenSSL.
2013-07-03 21:13:12 +02:00
Nick Zitzmann
833fba265d Merge branch 'master' of https://github.com/bagder/curl 2013-07-02 19:40:14 -06:00
Nick Zitzmann
d633052905 darwinssl: SSLv2 connections are aborted if unsupported by the OS
I just noticed that OS X no longer supports SSLv2. Other TLS engines return
an error if the requested protocol isn't supported by the underlying
engine, so we do that now for SSLv2 if the framework returns an error
when trying to turn on SSLv2 support. (Note: As always, SSLv2 support is
only enabled in curl when starting the app with the -2 argument; it's off
by default. SSLv2 is really old and insecure.)
2013-07-02 19:34:54 -06:00
Marc Hoersken
009d2336fe lib506.c: Fixed possible use of uninitialized variables 2013-07-01 21:42:15 +02:00
Kamil Dudka
abca89aaa0 url: restore the functionality of 'curl -u :'
This commit fixes a regression introduced in
fddb7b44a7.

Reported by: Markus Moeller
Bug: http://curl.haxx.se/mail/archive-2013-06/0052.html
2013-06-30 20:13:14 +02:00
Daniel Stenberg
d689376cb0 digest: append the timer to the random for the nonce 2013-06-25 11:37:27 +02:00
Daniel Stenberg
98b0d66eb4 digest: improve nonce generation
Use the new improved Curl_rand() to generate better random nonce for
Digest auth.
2013-06-25 11:28:22 +02:00
Daniel Stenberg
9c2853f2ae curl.1: fix typo in --xattr description
Bug: http://curl.haxx.se/bug/view.cgi?id=1252
Reported-by: Jean-Noël Rouvignac
2013-06-25 10:41:16 +02:00
Daniel Stenberg
aff7562922 RELEASE-NOTES: synced with 365c5ba395
The 10 first bug fixes for the pending release...
2013-06-25 10:35:21 +02:00
Daniel Stenberg
365c5ba395 formpost: better random boundaries
When doing multi-part formposts, libcurl used a pseudo-random value that
was seeded with time(). This turns out to be bad for users who formpost
data that is provided with users who then can guess how the boundary
string will look like and then they can forge a different formpost part
and trick the receiver.

My advice to such implementors is (still even after this change) to not
rely on the boundary strings being cryptographically strong. Fix your
code and logic to not depend on them that much!

I moved the Curl_rand() function into the sslgen.c source file now to be
able to take advantage of the SSL library's random function if it
provides one. If not, try to use the RANDOM_FILE for seeding and as a
last resort keep the old logic, just modified to also add microseconds
which makes it harder to properly guess the exact seed.

The formboundary() function in formdata.c is now using 64 bit entropy
for the boundary and therefore the string of dashes was reduced by 4
letters and there are 16 hex digits following it. The total length is
thus still the same.

Bug: http://curl.haxx.se/bug/view.cgi?id=1251
Reported-by: "Floris"
2013-06-25 09:55:49 +02:00
Daniel Stenberg
cb1aa8b0e3 printf: make sure %x are treated unsigned
When using %x, the number must be treated as unsigned as otherwise it
would get sign-extended on for example 64bit machines and do wrong
output. This problem showed when doing printf("%08x", 0xffeeddcc) on a
64bit host.
2013-06-25 09:55:49 +02:00
Daniel Stenberg
d3d5c4a40e tests: add test1395 to the tarball 2013-06-24 09:25:58 +02:00
Daniel Stenberg
6117d4025e SIGPIPE: don't use 'data' in sigpipe restore
Follow-up fix from 7d80ed64e4.

The SessionHandle may not be around to use when we restore the sigpipe
sighandler so we store the no_signal boolean in the local struct to know
if/how to restore.
2013-06-24 09:02:49 +02:00
Daniel Stenberg
d23745f7c9 TODO: 1.8 Modified buffer size approach
Thoughts around buffer sizes and what might be possible to do...
2013-06-23 22:49:06 +02:00
Daniel Stenberg
ad47d8e263 c-ares: improve error message on failed resolve
When the c-ares based resolver backend failed to resolve a name, it
tried to show the name that failed from existing structs. This caused
the wrong output and shown hostname when for example --interface
[hostname] was used and that name resolving failed.

Now we use the hostname used in the actual resolve attempt in the error
message as well.

Bug: http://curl.haxx.se/bug/view.cgi?id=1191
Reported-by: Kim Vandry
2013-06-23 20:25:38 +02:00
Daniel Stenberg
8a7a277c08 ossl_recv: check for an OpenSSL error, don't assume
When we recently started to treat a zero return code from SSL_read() as
an error we also got false positives - which primarily looks to be
because the OpenSSL documentation is wrong and a zero return code is not
at all an error case in many situations.

Now ossl_recv() will check with ERR_get_error() to see if there is a
stored error and only then consider it to be a true error if SSL_read()
returned zero.

Bug: http://curl.haxx.se/bug/view.cgi?id=1249
Reported-by: Nach M. S.
Patch-by: Nach M. S.
2013-06-23 12:05:21 +02:00
Nick Zitzmann
0030fbd382 Merge branch 'master' of https://github.com/bagder/curl 2013-06-22 15:16:05 -06:00
Nick Zitzmann
f3052c8a81 darwinssl: fix crash that started happening in Lion
Something (a recent security update maybe?) changed in Lion, and now it
has changed SSLCopyPeerTrust such that it may return noErr but also give
us a null trust, which caught us off guard and caused an eventual crash.
2013-06-22 15:13:36 -06:00
Daniel Stenberg
7d80ed64e4 SIGPIPE: ignored while inside the library
... and restore the ordinary handling again when it returns. This is
done for curl_easy_perform() and curl_easy_cleanup() only for now - and
only when built to use OpenSSL as backend as this is the known culprit
for the spurious SIGPIPEs people have received.

Bug: http://curl.haxx.se/bug/view.cgi?id=1180
Reported by: Lluís Batlle i Rossell
2013-06-22 22:35:06 +02:00
Daniel Stenberg
a2e0ce86ba KNOWN_BUGS: #83 unable to load non-default openssl engines 2013-06-22 22:24:36 +02:00
Daniel Stenberg
6fab0bd9f1 test1396: invoke the correct test tool!
This erroneously run unit test 1310 instead of 1396!
2013-06-22 22:20:31 +02:00
Kamil Dudka
02964ed630 test1230: avoid using hard-wired port number
... to prevent failure when a non-default -b option is given
2013-06-22 22:12:49 +02:00
Kamil Dudka
6f3e7aabdc curl-config.in: replace tabs by spaces 2013-06-22 22:08:42 +02:00
Nick Zitzmann
631e3e13a9 darwinssl: reform OS-specific #defines
This doesn't need to be in the release notes. I cleaned up a lot of the #if
lines in the code to use MAC_OS_X_VERSION_MIN_REQUIRED and
MAC_OS_X_VERSION_MAX_ALLOWED instead of checking for whether things like
__MAC_10_6 or whatever were defined, because for some SDKs Apple has released
they were defined out of place.
2013-06-22 12:23:26 -06:00
Alessandro Ghedini
832c195179 docs: fix typo in curl_easy_getinfo manpage 2013-06-22 18:28:18 +02:00
Daniel Stenberg
7877619f85 dotdot: introducing dot file path cleanup
RFC3986 details how a path part passed in as part of a URI should be
"cleaned" from dot sequences before getting used. The described
algorithm is now implemented in lib/dotdot.c with the accompanied test
case in test 1395.

Bug: http://curl.haxx.se/bug/view.cgi?id=1200
Reported-by: Alex Vinnik
2013-06-22 14:15:07 +02:00
Daniel Stenberg
ec248b590d bump: start working towards what most likely will become 7.32.0 2013-06-22 14:13:28 +02:00
Daniel Stenberg
4846b5e9fe THANKS: added 24 new contributors from the 7.31.0 release 2013-06-22 13:52:27 +02:00
Daniel Stenberg
85c710e11e RELEASE-NOTES: synced with 0de7249bb3 - 7.31.0 2013-06-22 11:30:31 +02:00
Daniel Stenberg
0de7249bb3 unit1396: unit tests to verify curl_easy_(un)escape 2013-06-22 11:21:35 +02:00
Daniel Stenberg
192c4f788d Curl_urldecode: no peeking beyond end of input buffer
Security problem: CVE-2013-2174

If a program would give a string like "%FF" to curl_easy_unescape() but
ask for it to decode only the first byte, it would still parse and
decode the full hex sequence. The function then not only read beyond the
allowed buffer but it would also deduct the *unsigned* counter variable
for how many more bytes there's left to read in the buffer by two,
making the counter wrap. Continuing this, the function would go on
reading beyond the buffer and soon writing beyond the allocated target
buffer...

Bug: http://curl.haxx.se/docs/adv_20130622.html
Reported-by: Timo Sirainen
2013-06-22 11:21:35 +02:00
Guenter Knauf
da0db499fd Use opened body.out file and write content to it. 2013-06-20 22:53:37 +02:00
Daniel Stenberg
88c5c63ffc multi_socket: react on socket close immediately
As a remedy to the problem when a socket gets closed and a new one is
opened with the same file descriptor number and as a result
multi.c:singlesocket() doesn't detect the difference, the new function
Curl_multi_closed() gets told when a socket is closed so that it can be
removed from the socket hash. When the old one has been removed, a new
socket should be detected fine by the singlesocket() on next invoke.

Bug: http://curl.haxx.se/bug/view.cgi?id=1248
Reported-by: Erik Johansson
2013-06-20 22:36:52 +02:00
Daniel Stenberg
a9f5ad0e2a RELEASE-NOTES: synced with e305f5ec71 2013-06-20 22:27:33 +02:00
Daniel Stenberg
e305f5ec71 TODO: mention the DANE patch from March 2013-06-18 09:38:06 +02:00
Daniel Stenberg
7ac3e9f1ba CURLOPT_COOKIELIST: take cookie share lock
When performing COOKIELIST operations the cookie lock needs to be taken
for the cases where the cookies are shared among multiple handles!

Verified by Benjamin Gilbert's updated test 506

Bug: http://curl.haxx.se/bug/view.cgi?id=1215
Reported-by: Benjamin Gilbert
2013-06-17 23:29:05 +02:00
Benjamin Gilbert
03a3dd9ee3 test506: verify that CURLOPT_COOKIELIST takes share lock
It doesn't right now: http://curl.haxx.se/bug/view.cgi?id=1215
2013-06-17 23:28:35 +02:00
Daniel Stenberg
5fc24a5297 TODO: HTTP2/SPDY support 2013-06-15 14:36:35 +02:00
Daniel Stenberg
b1a295ac4e curl_easy_setopt.3: clarify CURLOPT_PROGRESSFUNCTION frequency
Make it clearer that the CURLOPT_PROGRESSFUNCTION callback will be
called more frequently than once per second when things are happening.
2013-06-14 23:17:14 +02:00
Daniel Stenberg
1826c768ab RELEASE-NOTES: synced with 9c3e098259
Mention 7 recent bug fixes and their associated contributors
2013-06-13 23:01:32 +02:00
Daniel Stenberg
9c3e098259 curl_multi_wait.3: clarify the numfds counter 2013-06-13 22:38:53 +02:00
Daniel Stenberg
0feeab7802 curl_easy_perform: avoid busy-looping
When curl_multi_wait() finds no file descriptor to wait for, it returns
instantly and this must be handled gracefully within curl_easy_perform()
or cause a busy-loop. Starting now, repeated fast returns without any
file descriptors is detected and a gradually increasing sleep will be
used (up to a max of 1000 milliseconds) before continuing the loop.

Bug: http://curl.haxx.se/bug/view.cgi?id=1238
Reported-by: Miguel Angel
2013-06-13 19:27:12 +02:00
YAMADA Yasuharu
f24dc09d20 cookies: follow-up fix for path checking
The initial fix to only compare full path names were done in commit
04f52e9b4d but found out to be incomplete. This takes should make the
change more complete and there's now two additional tests to verify
(test 31 and 62).
2013-06-12 11:19:56 +02:00
Sergei Nikulov
9e10963c20 lib1900: use tutil_tvnow instead of gettimeofday
Makes it build on windows
2013-06-12 10:52:23 +02:00
Eric Hu
10b6d81c64 axtls: now done non-blocking 2013-06-12 10:37:32 +02:00
Eric Hu
8026bd7abd test2033: requires NTLM support 2013-06-12 10:34:10 +02:00
Daniel Stenberg
9b8df58169 KNOWN_BUGS: #82 failed build with Borland compiler 2013-06-11 00:21:16 +02:00
Daniel Stenberg
529a2e9110 Curl_output_digest: support auth-int for empty entity body
By always returning the md5 for an empty body when auth-int is asked
for, libcurl now at least sometimes does the right thing.

Bug: http://curl.haxx.se/bug/view.cgi?id=1235
Patched-by: Nach M. S.
2013-06-11 00:08:13 +02:00
Daniel Stenberg
21091549c0 multi_socket: reduce timeout inaccuracy margin
Allow less room for "triggered too early" mistakes by applications /
timers on non-windows platforms. Starting now, we assume that a timeout
call is never made earlier than 3 milliseconds before the actual
timeout. This greatly improves timeout accuracy on Linux.

Bug: http://curl.haxx.se/bug/view.cgi?id=1228
Reported-by: Hang Su
2013-06-11 00:02:29 +02:00
Daniel Stenberg
7b97f03f09 cert_stuff: avoid double free in the PKCS12 code
In the pkcs12 code, we get a list of x509 records returned from
PKCS12_parse but when iterating over the list and passing each to
SSL_CTX_add_extra_chain_cert() we didn't also properly remove them from
the "stack", which made them get freed twice (both in sk_X509_pop_free()
and then later in SSL_CTX_free).

This isn't really documented anywhere...

Bug: http://curl.haxx.se/bug/view.cgi?id=1236
Reported-by: Nikaiw
2013-06-10 23:42:48 +02:00
Daniel Stenberg
ce362e8eb9 cert_stuff: remove code duplication in the pkcs12 logic 2013-06-10 23:04:01 +02:00
Aleksey Tulinov
a4decb49a6 axtls: honor disabled VERIFYHOST
When VERIFYHOST == 0, libcurl should let invalid certificates to pass.
2013-06-08 00:23:05 +02:00
Peter Gal
c53fb36b0c curl_easy_setopt.3: HTTP header with no content
Update the documentation on how to specify a HTTP header with no
content.
2013-06-08 00:15:40 +02:00
Daniel Stenberg
dc19e656b5 RELEASE-NOTES: synced with 87cf677eca
Added 11 bugs and 7 contributors
2013-06-07 10:39:21 +02:00
Daniel Stenberg
87cf677eca lib1500: remove bad check
After curl_multi_wait() returns, this test checked that we got exactly
one file descriptor told to read from, but we cannot be sure that is
true. curl_multi_wait() will sometimes return earlier without any file
descriptor to handle, just just because it is a suitable time to call
*perform().

This problem showed up with commit 29bf0598.

Bug: http://curl.haxx.se/mail/lib-2013-06/0029.html
Reported-by: Fabian Keil
2013-06-06 22:22:14 +02:00
Daniel Stenberg
5657c56f63 tests/Makefile: typo in the perlcheck target
Bug: http://curl.haxx.se/bug/view.cgi?id=1239
Reported-by: Christian Weisgerber
2013-06-04 23:22:11 +02:00
Daniel Stenberg
51b3445e84 test1230: verify CONNECT to a numerical ipv6-address 2013-06-04 22:52:13 +02:00
Daniel Stenberg
a7452b8b8c sws: support extracting test number from CONNECT ipv6-address!
If an ipv6-address is provided to CONNECT, the last hexadecimal group in
the address will be used as the test number! For example the address
"[1234::ff]" would be treated as test case 255.
2013-06-04 22:50:58 +02:00
Daniel Stenberg
0bf5ce77aa curl_multi_wait: only use internal timer if not -1
commit 29bf0598aa introduced a problem when the "internal" timeout is
prefered to the given if shorter, as it didn't consider the case where
-1 was returned. Now the internal timeout is only considered if not -1.

Reported-by: Tor Arntsen
Bug: http://curl.haxx.se/mail/lib-2013-06/0015.html
2013-06-04 13:22:40 +02:00
Dan Fandrich
159d34b58e libcurl-tutorial.3: added a section on IPv6
Also added a (correctly-escaped) backslash to the autoexec.bat
example file and a new Windows character device name with
a colon as examples of other characters that are special
and potentially dangerous (this reverts and reworks commit
7d8d2a54).
2013-06-03 22:44:05 +02:00
Daniel Stenberg
29bf0598aa curl_multi_wait: reduce timeout if the multi handle wants to
If the multi handle's pending timeout is less than what is passed into
this function, it will now opt to use the shorter time anyway since it
is a very good hint that the handle wants to process something in a
shorter time than what otherwise would happen.

curl_multi_wait.3 was updated accordingly to clarify

This is the reason for bug #1224

Bug: http://curl.haxx.se/bug/view.cgi?id=1224
Reported-by: Andrii Moiseiev
2013-06-03 20:27:08 +02:00
Daniel Stenberg
239b58d34d multi_runsingle: switch an if() condition for readability
... because there's an identical check right next to it so using the
operators in the check in the same order increases readability.
2013-06-03 20:23:01 +02:00
Marc Hoersken
74f1810546 curl_schannel.c: Removed variable unused since 35874298e4 2013-06-02 20:21:42 +02:00
Marc Hoersken
f4b08b8f40 curl_setup.h: Fixed redefinition warning using mingw-w64 2013-06-02 15:53:08 +02:00
Daniel Stenberg
6691fdf517 multi_runsingle: add braces to clarify the code 2013-05-30 23:34:33 +02:00
Daniel Stenberg
7d8d2a54ba libcurl-tutorial.3: remove incorrect backslash
A single backslash in the content is not legal nroff syntax.

Reported and fixed by: Eric S. Raymond
Bug: http://curl.haxx.se/bug/view.cgi?id=1234
2013-05-28 13:37:08 +02:00
Daniel Stenberg
9986c6cb2b curl_formadd.3: fixed wrong "end-marker" syntax
Reported and fixed by: Eric S. Raymond
Bug: http://curl.haxx.se/bug/view.cgi?id=1233
2013-05-28 13:35:13 +02:00
Daniel Stenberg
ba9a66663a curl.1: clarify that --silent still outputs data 2013-05-28 11:37:58 +02:00
Daniel Stenberg
ac419bf562 Digest auth: escape user names with \ or " in them
When sending the HTTP Authorization: header for digest, the user name
needs to be escaped if it contains a double-quote or backslash.

Test 1229 was added to verify

Reported and fixed by: Nach M. S
Bug: http://curl.haxx.se/bug/view.cgi?id=1230
2013-05-27 19:45:12 +02:00
Mike Giancola
520833cbe1 ossl_recv: SSL_read() returning 0 is an error too
SSL_read can return 0 for "not successful", according to the open SSL
documentation: http://www.openssl.org/docs/ssl/SSL_read.html
2013-05-22 23:42:33 +02:00
Mike Giancola
e58d9c87f7 ossl_send: SSL_write() returning 0 is an error too
We found that in specific cases if the connection is abruptly closed,
the underlying socket is listed in a close_wait state. We continue to
call the curl_multi_perform, curl_mutli_fdset etc. None of these APIs
report the socket closed / connection finished.  Since we have cases
where the multi connection is only used once, this can pose a problem
for us. I've read that if another connection was to come in, curl would
see the socket as bad and attempt to close it at that time -
unfortunately, this does not work for us.

I found that in specific situations, if SSL_write returns 0, curl did
not recognize the socket as closed (or errored out) and did not report
it to the application. I believe we need to change the code slightly, to
check if ssl_write returns 0. If so, treat it as an error - the same as
a negative return code.

For OpenSSL - the ssl_write documentation is here:
http://www.openssl.org/docs/ssl/SSL_write.html
2013-05-22 23:08:27 +02:00
Daniel Stenberg
84f7991474 KNOWN_BUGS: curl -OJC- fails to resume
Bug: http://curl.haxx.se/bug/view.cgi?id=1169
2013-05-21 23:58:52 +02:00
Daniel Stenberg
85b9dc8023 Curl_cookie_add: handle IPv6 hosts
1 - don't skip host names with a colon in them in an attempt to bail out
on HTTP headers in the cookie file parser. It was only a shortcut anyway
and trying to parse a file with HTTP headers will still be handled, only
slightly slower.

2 - don't skip domain names based on number of dots. The original
netscape cookie spec had this oddity mentioned and while our code
decreased the check to only check for two, the existing cookie spec has
no such dot counting required.

Bug: http://curl.haxx.se/bug/view.cgi?id=1221
Reported-by: Stefan Neis
2013-05-21 23:28:59 +02:00
Daniel Stenberg
7d4d4892d8 curl_easy_setopt.3: expand the PROGRESSFUNCTION section
Explain the callback and its arguments better and with more descriptive
text.
2013-05-20 10:50:51 +02:00
Daniel Stenberg
fc4759af9d tests: add test1394 file to the tarball 2013-05-19 12:44:44 +02:00
Daniel Stenberg
ee84c47655 tarball: include the xmlstream example 2013-05-19 11:21:56 +02:00
David Strauss
ce32176db7 xmlstream: XML stream parsing example source code
Add an XML stream parsing example using Expat. Add missing ignore for
the binary from an unrelated example.
2013-05-19 11:19:28 +02:00
YAMADA Yasuharu
04f52e9b4d cookies: only consider full path matches
I found a bug which cURL sends cookies to the path not to aim at.
For example:
- cURL sends a request to http://example.fake/hoge/
- server returns cookie which with path=/hoge;
  the point is there is NOT the '/' end of path string.
- cURL sends a request to http://example.fake/hogege/ with the cookie.

The reason for this old "feature" is because that behavior is what is
described in the original netscape cookie spec:
http://curl.haxx.se/rfc/cookie_spec.html

The current cookie spec (RFC6265) clarifies the situation:
http://tools.ietf.org/html/rfc6265#section-5.2.4
2013-05-18 22:54:48 +02:00
Eric Hu
100a33f7ff axtls: prevent memleaks on SSL handshake failures 2013-05-16 20:26:42 +02:00
Daniel Stenberg
7ed25ccf0d Revert "WIN32 MemoryTracking: track wcsdup() _wcsdup() and _tcsdup() usage"
This reverts commit 8ec2cb5544.

We don't have any code anywhere in libcurl (or the curl tool) that use
wcsdup so there's no such memory use to track. It seems to cause mild
problems with the Borland compiler though that we may avoid by reverting
this change again.

Bug: http://curl.haxx.se/mail/lib-2013-05/0070.html
2013-05-12 15:10:01 +02:00
Daniel Stenberg
01eede2662 RELEASE-NOTES: synced with ae26ee3489 2013-05-12 14:36:04 +02:00
Guenter Knauf
ae26ee3489 Updated zlib version in build files. 2013-05-11 17:08:00 +02:00
Renaud Guillard
992bee504d OS X framework: fix invalid symbolic link 2013-05-09 21:51:35 +02:00
Daniel Stenberg
01a2abedd7 nss: give PR_INTERVAL_NO_WAIT instead of -1 to PR_Recv/PR_Send
Reported by: David Strauss
Bug: http://curl.haxx.se/mail/lib-2013-05/0088.html
2013-05-09 11:23:15 +02:00
Daniel Stenberg
a45e3f93e4 libtest: gitignore more binary files 2013-05-08 14:35:45 +02:00
Daniel Stenberg
bdb396ef2a servercert: allow empty subject
Bug: http://curl.haxx.se/bug/view.cgi?id=1220
Patch by: John Gardiner Myers
2013-05-07 23:02:01 +02:00
Steve Holme
6add1901a1 tests: Added new SMTP tests to verify commit 99b4045183 2013-05-07 22:52:43 +02:00
Daniel Stenberg
51b0f09b5e runtests.pl: support nonewline="yes" in client/stdin sections 2013-05-07 22:52:43 +02:00
Daniel Stenberg
8dac7be438 build: fixed unit1394 for debug and metlink builds 2013-05-06 23:28:04 +02:00
Kamil Dudka
bcf1b9dec1 unit1394.c: plug the curl tool unit test in 2013-05-06 15:03:13 +02:00
Jared Jennings
b045d079f8 unit1394.c: basis of a unit test for parse_cert_parameter() 2013-05-06 15:03:13 +02:00
Kamil Dudka
683f2b8323 src/Makefile.am: build static lib for unit tests if enabled 2013-05-06 15:03:12 +02:00
Kamil Dudka
2de20dd9a1 tool_getparam: ensure string termination in parse_cert_parameter() 2013-05-06 15:00:10 +02:00
Kamil Dudka
b47cf4f688 tool_getparam: fix memleak in handling the -E option 2013-05-06 15:00:10 +02:00
Kamil Dudka
a15b2b6c62 tool_getparam: describe what parse_cert_parameter() does
... and de-duplicate the code initializing *passphrase
2013-05-06 15:00:10 +02:00
Kamil Dudka
42e01cff9a curl.1: document escape sequences recognized by -E 2013-05-06 14:32:26 +02:00
Jared Jennings
865d4138a0 curl -E: allow to escape ':' in cert nickname 2013-05-06 14:32:26 +02:00
Marc Hoersken
35874298e4 curl_schannel.c: Fixed invalid memory access during SSL shutdown 2013-05-05 17:57:37 +02:00
Steve Holme
52d72e66c2 smtp: Fix trailing whitespace warning 2013-05-04 18:37:50 +01:00
Steve Holme
f3d10aa0d4 smtp: Fix compilation warning
comparison between signed and unsigned integer expressions
2013-05-04 13:24:05 +01:00
Steve Holme
7632bc911b RELEASE-NOTES: synced with 92ef5f19c8 2013-05-04 10:13:43 +01:00
Steve Holme
92ef5f19c8 smtp: Updated RFC-2821 references to RFC-5321 2013-05-04 10:12:01 +01:00
Steve Holme
99b4045183 smtp: Fixed sending of double CRLF caused by first in EOB
If the mail sent during the transfer contains a terminating <CRLF> then
we should not send the first <CRLF> of the EOB as specified in RFC-5321.

Additionally don't send the <CRLF> if there is "no mail data" as the
DATA command already includes it.
2013-05-04 10:00:33 +01:00
Steve Holme
087f9bb20a tests: Corrected MAIL SIZE for CRLF line endings
... which was missed in commit: f5c3d95384
2013-05-03 20:08:21 +01:00
Steve Holme
e2c7e19144 tests: Corrected infilesize for CRLF line endings
... which was missed in commit: f5c3d95384
2013-05-03 18:27:06 +01:00
Steve Holme
f5c3d95384 tests: Corrected test1406 to be RFC2821 compliant 2013-05-03 18:22:18 +01:00
Steve Holme
6b10f5b963 tests: Corrected test1320 to be RFC2821 compliant 2013-05-02 22:49:16 +01:00
Steve Holme
ee74b77d45 tests: Corrected typo in test909
Introduced in commit: 514817669e
2013-05-02 20:03:50 +01:00
Steve Holme
734bdb68c2 tests: Corrected test909 to be RFC2821 compliant 2013-05-02 18:52:52 +01:00
Steve Holme
514817669e tests: Updated test references to 909 from 1411
...and removed references to libcurl and test1406.
2013-05-02 18:50:00 +01:00
Steve Holme
cb9c0ac7d7 tests: Renamed test1411 to test909 as this is a main SMTP test 2013-05-02 18:46:11 +01:00
Lars Johannesen
1c435295b8 bindlocal: move brace out of #ifdef
The code within #ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID wrongly had two
closing braces when it should only have one, so builds without that
define would fail.

Bug: http://curl.haxx.se/mail/lib-2013-05/0000.html
2013-05-01 14:18:47 +02:00
Steve Holme
46d26a0e77 smtp: Tidy up to move the eob counter to the per-request structure
Move the eob counter from the smtp_conn structure to the SMTP structure
as it is associated with a SMTP payload on a per-request basis.
2013-04-30 22:25:23 +01:00
Steve Holme
f4e3cae8a7 TODO: Updated following the addition of CURLOPT_SASL_IR 2013-04-30 00:12:41 +01:00
Steve Holme
b52cf5d2cd smtp: Fixed unknown percentage complete in progress bar
The curl command line utility would display the the completed progress
bar with a percentage of zero as the progress routines didn't know the
size of the transfer.
2013-04-29 22:34:26 +01:00
Daniel Stenberg
073e83b543 ftpserver: silence warnings
Fix regressions in commit b56e3d43e5. Make @data local and filter off
non-numerical digits from $testno in STATUS_imap.
2013-04-29 14:58:08 +02:00
Steve Holme
c3e6d69acb ftpserver.pl: Corrected the imap LOGIN response
...to be more realistic and consistent with the other imap responses.
2013-04-29 12:58:41 +01:00
Steve Holme
b56e3d43e5 tests: Added imap STATUS command test 2013-04-29 12:53:09 +01:00
Steve Holme
f317ffb7bb tests: Corrected the SMTP tests to be RFC2821 compliant
The emails that are sent to the server during these tests were
incorrectly formatted as they contained one or more LF terminated lines
rather than being CRLF terminated as per Section 2.3.7 of RFC-2821.

This wasn't a problem for the test suite as the <stdin> data matched the
<upload> data but anyone using these tests as reference would be sending
incorrect data to a server.
2013-04-28 16:14:58 +01:00
Steve Holme
9ea5145952 email: Tidy up of *_perform_authenticate()
Removed the hard returns from imap and pop3 by using the same style for
sending the authentication string as smtp. Moved the "Other mechanisms
not supported" check in smtp to match that of imap and pop3 to provide
consistency between the three email protocols.
2013-04-28 12:57:42 +01:00
Steve Holme
1d7c38e1f0 smtp: Updated limit check to be more readable like the check in pop3 2013-04-28 12:26:44 +01:00
Steve Holme
18bfc8f2d7 pop3: Added 255 octet limit check when sending initial response
Added 255 octet limit check as per Section 4. Paragraph 8 of RFC-5034.
2013-04-28 12:26:11 +01:00
Steve Holme
945246988d DOCS: Corrected line length of recent Secure Transport changes 2013-04-28 12:17:15 +01:00
Nick Zitzmann
a5c0e20939 darwinssl: add TLS crypto authentication
Users using the Secure Transport (darwinssl) back-end can now use a
certificate and private key to authenticate with a site using TLS. Because
Apple's security system is based around the keychain and does not have any
non-public function to create a SecIdentityRef data structure from data
loaded outside of the Keychain, the certificate and private key have to be
loaded into the Keychain first (using the certtool command line tool or
the Security framework's C API) before we can find it and use it.
2013-04-27 23:15:07 -06:00
Steve Holme
128517649c Corrected version numbers after bump 2013-04-27 23:02:20 +01:00
Daniel Stenberg
219358b93d bump version
Since we're adding new stuff, the next release will bump the minor
version and we're looking forward to 7.31.0
2013-04-27 23:15:35 +02:00
Steve Holme
f133719f73 RELEASE-NOTES: synced with f4e6e201b1 2013-04-27 20:43:55 +01:00
Steve Holme
f4e6e201b1 DOCS: Updated following the addition of CURLOPT_SASL_IR
Documented the the option in curl_easy_setopt() and added it to
symbols-in-versions.
2013-04-27 17:08:08 +01:00
Steve Holme
790b2086d7 tests: Corrected command line arguments in test907 and test908 2013-04-27 16:36:17 +01:00
Steve Holme
f9b691cdb0 tests: Added SMTP AUTH with initial response tests 2013-04-27 13:04:02 +01:00
Steve Holme
4118c30261 tests: Updated SMTP tests to decouple client initial response
Updated test903 and test904 following the addition of CURLOPT_SASL_IR
as the default behaviour of SMTP AUTH responses is now to not include
the initial response. New tests with --sasl-ir support to follow.
2013-04-27 12:32:27 +01:00
Steve Holme
dacbdaab94 imap: Added support for overriding the SASL initial response
In addition to checking for the SASL-IR capability the user can override
the sending of the client's initial response in the AUTHENTICATION
command with the use of CURLOPT_SASL_IR should the server erroneously
not report SASL-IR when it does support it.
2013-04-27 12:12:59 +01:00
Steve Holme
70e30f6caa smtp: Added support for disabling the SASL initial response
Updated the default behaviour of sending the client's initial response in the AUTH
command to not send it and added support for CURLOPT_SASL_IR to allow the user to
specify including the response.

Related Bug: http://curl.haxx.se/mail/lib-2012-03/0114.html
Reported-by: Gokhan Sengun
2013-04-27 12:09:15 +01:00
Steve Holme
7cb6c31370 pop3: Added support for enabling the SASL initial response
Allowed the user to specify whether to send the client's intial response
in the AUTH command via CURLOPT_SASL_IR.
2013-04-27 12:07:39 +01:00
Steve Holme
5d3a031ca7 sasl-ir: Added --sasl-ir option to curl command line tool 2013-04-27 10:03:10 +01:00
Steve Holme
a846fbbe2a sasl-ir: Added CURLOPT_SASL_IR to enable/disable the SASL initial response 2013-04-27 09:58:20 +01:00
Daniel Stenberg
6420672879 curl_easy_init: use less mallocs
By introducing an internal alternative to curl_multi_init() that accepts
parameters to set the hash sizes, easy handles will now use tiny socket
and connection hash tables since it will only ever add a single easy
handle to that multi handle.

This decreased the number mallocs in test 40 (which is a rather simple
and typical easy interface use case) from 1142 to 138. The maximum
amount of memory allocated used went down from 118969 to 78805.
2013-04-26 22:55:55 +02:00
Steve Holme
c4067a5678 ftpserver.pl: Fixed imap logout confirmation data
An IMAP server should response with the BYE continuation response before
confirming the LOGOUT command was successful.
2013-04-26 21:12:36 +01:00
Daniel Stenberg
0523152ad6 ftp_state_pasv_resp: connect through proxy also when set by env
When connecting back to an FTP server after having sent PASV/EPSV,
libcurl sometimes didn't use the proxy properly even though the proxy
was used for the initial connect.

The function wrongly checked for the CURLOPT_PROXY variable to be set,
which made it act wrongly if the proxy information was set with an
environment variable.

Added test case 711 to verify (based on 707 which uses --socks5). Also
added test712 to verify another variation of setting the proxy: with
--proxy socks5://

Bug: http://curl.haxx.se/bug/view.cgi?id=1218
Reported-by: Zekun Ni
2013-04-26 16:49:25 +02:00
Zdenek Pavlas
b37b5233ca url: initialize speed-check data for file:// protocol
... in order to prevent an artificial timeout event based on stale
speed-check data from a previous network transfer.  This commit fixes
a regression caused by 9dd85bced5.

Bug: https://bugzilla.redhat.com/906031
2013-04-26 15:38:22 +02:00
Daniel Stenberg
c68c7e588e test709: clarify the test in the name 2013-04-25 23:42:38 +02:00
Daniel Stenberg
1498a0073e sshserver: disable StrictHostKeyChecking
I couldn't figure out why the host key logic isn't working, but having
it set to yes prevents my SSH-based test cases to run. I also don't see
a strong need to use strict host key checking on this test server.

So I disabled it.
2013-04-25 23:40:31 +02:00
Daniel Stenberg
27777949a0 runtests: log more commands in verbose mode
... to aid tracking down failures
2013-04-25 23:40:01 +02:00
Steve Holme
4dc2d965d6 TODO: Corrected copy/paste typo 2013-04-25 20:18:08 +01:00
Steve Holme
70bbbccc39 TODO: Added new ideas for future SMTP, POP3 and IMAP features 2013-04-25 20:10:09 +01:00
Steve Holme
0dd470fc61 TODO: Updated following the addition of ;auth=<MECH> support 2013-04-25 19:48:34 +01:00
Steve Holme
89acdf50fa DOCS: Minor rewording / clarification of host name protocol detection 2013-04-25 13:30:17 +01:00
Steve Holme
c0d502785f RELEASE-NOTES: synced with a8c92cb608 2013-04-24 19:40:06 +01:00
Steve Holme
a8c92cb608 DOCS: Added reference to IETF draft for SMTP URL Interface
...when mentioning login options. Additional minor clarification of
"Windows builds" to be "Windows builds with SSPI"as a way of enabling
NTLM as Windows builds may be built with OpenSSL to enable NTLM or
without NTLM support altogether.
2013-04-24 19:35:38 +01:00
Linus Nielsen Feltzing
53fda844cc HISTORY: Fix spelling error. 2013-04-23 21:41:38 +02:00
Steve Holme
bbf63b0faa DOCS: Reworked the scheme calculation explanation under CURLOPT_URL 2013-04-23 19:57:58 +01:00
Steve Holme
2af9fd4960 url: Added smtp and pop3 hostnames to the protocol detection list 2013-04-23 19:44:14 +01:00
Daniel Stenberg
2c0d65785f HISTORY: correct some years/dates
Thanks to archive.org's wayback machine I updated this document with
some facts from the early httpget/urlget web page:

http://web.archive.org/web/19980216125115/http://www.inf.ufrgs.br/~sagula/urlget.html
2013-04-23 16:21:29 +02:00
Alessandro Ghedini
d791179d7f tests: add test1511 to check timecond clean-up
Verifies the timecond fix in commit c49ed0b6c0
2013-04-22 22:46:47 +02:00
Alessandro Ghedini
c49ed0b6c0 getinfo.c: reset timecond when clearing session-info variables
Bug: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=705783
Reported-by: Ludovico Cavedon <cavedon@debian.org>
2013-04-22 22:43:32 +02:00
Steve Holme
868d8e6831 DOCS: Added information about login options to CURLOPT_USERPWD 2013-04-22 20:22:12 +01:00
Steve Holme
e3aca1b2ce DOCS: Added information about login options in the URL 2013-04-22 20:22:10 +01:00
Steve Holme
ddac43b38e url: Fixed missing length check in parse_proxy()
Commit 11332577b3 removed the length check that was performed by the
old scanf() code.
2013-04-21 18:29:33 +01:00
Steve Holme
416ecc1584 url: Fixed crash when no username or password supplied for proxy
Fixed an issue in parse_proxy(), introduced in commit 11332577b3,
where an empty username or password (For example: http://:@example.com)
would cause a crash.
2013-04-21 16:55:19 +01:00
Steve Holme
455ba691a7 url: Removed unused text length constants 2013-04-21 12:16:12 +01:00
Steve Holme
11332577b3 url: Updated proxy URL parsing to use parse_login_details() 2013-04-21 12:12:29 +01:00
Steve Holme
702b0dd408 url: Tidy up of setstropt_userpwd() parameters
Updated the naming convention of the login parameters to match those of
other functions.
2013-04-21 10:27:42 +01:00
Steve Holme
e8a9f794f0 url: Tidy up of code and comments following recent changes
Tidy up of variable names and comments in setstropt_userpwd() and
parse_login_details().
2013-04-21 10:23:47 +01:00
Steve Holme
bddf3d4705 url: Simplified setstropt_userpwd() following recent changes
There is no need to perform separate clearing of data if a NULL option
pointer is passed in. Instead this operation can be performed by simply
not calling parse_login_details() and letting the rest of the code do
the work.
2013-04-20 20:04:00 +01:00
Steve Holme
e99c81a07c url: Correction to scope of if statements when setting data 2013-04-20 19:10:10 +01:00
Steve Holme
fe880475ed url: Fixed memory leak in setstropt_userpwd()
setstropt_userpwd() was calling setstropt() in commit fddb7b44a7 to
set each of the login details which would duplicate the strings and
subsequently cause a memory leak.
2013-04-20 18:40:13 +01:00
Steve Holme
5821d5f111 RELEASE-NOTES: synced with d535c4a2e1 2013-04-20 09:56:16 +01:00
Steve Holme
d535c4a2e1 url: Added overriding of URL login options from CURLOPT_USERPWD 2013-04-20 09:18:51 +01:00
Steve Holme
ca8f17a303 tool_paramhlp: Fixed options being included in username
Fix to prevent the options from being displayed when curl requests the
user's password if the following command line is specified:

--user username;options
2013-04-20 09:16:21 +01:00
Steve Holme
fddb7b44a7 url: Added support for parsing login options from the CURLOPT_USERPWD
In addition to parsing the optional login options from the URL, added
support for parsing them from CURLOPT_USERPWD, to allow the following
supported command line:

--user username:password;options
2013-04-20 09:08:28 +01:00
Steve Holme
49184c3723 url: Added bounds checking to parse_login_details()
Added bounds checking when searching for the separator characters within
the login string as this string may not be NULL terminated (For example
it is the login part of a URL). We do this in preference to allocating a
new string to copy the login details into which could then be passed to
parse_login_details() for performance reasons.
2013-04-19 19:37:55 +01:00
Steve Holme
cc7f6a2ddf url: Added size_t cast to pointer based length calculations 2013-04-19 14:11:43 +01:00
Steve Holme
90fe59b829 url: Corrected minor typo in comment 2013-04-19 12:53:59 +01:00
Daniel Stenberg
7b074a460b CURL_CHECK_CA_BUNDLE: don't check for paths when cross-compiling
When cross-compiling we can't scan and detect existing files or paths.

Bug: http://curl.haxx.se/mail/lib-2013-04/0294.html
2013-04-18 23:37:56 +02:00
Ishan SinghLevett
993cdcd6ee usercertinmem.c: add example showing user cert in memory
Relies on CURLOPT_SSL_CTX_FUNCTION, which is OpenSSL specific
2013-04-18 23:07:15 +02:00
Steve Holme
8763374f0e url: Fix chksrc longer than 79 columns warning 2013-04-18 20:21:11 +01:00
Steve Holme
63388fe1f3 url: Fix incorrect variable type for result code 2013-04-18 19:18:02 +01:00
Steve Holme
b75a88aa72 url: Fix compiler warning
signed and unsigned type in conditional expression
2013-04-18 19:14:25 +01:00
Steve Holme
bb20989a63 url: Moved parsing of login details out of parse_url_login()
Separated the parsing of login details from the processing of them in
parse_url_login() ready for use by setstropt_userpwd().
2013-04-18 18:09:53 +01:00
Steve Holme
0d49e408a4 url: Re-factored set_userpass() and parse_url_userpass()
Re-factored these functions to reflect their new behaviour following the
addition of login options.
2013-04-18 17:36:15 +01:00
Steve Holme
90c87f311e url: Reworked URL parsing to allow overriding by CURLOPT_USERPWD 2013-04-18 17:20:43 +01:00
Daniel Stenberg
da06ac7f3f maketgz: make bzip2 creation work with Parallel BZIP2 too
Apparently the previous usage didn't work with that implementation,
while this updated version works with at least both Parallel BZIP2
v1.1.8 and regular bzip "Version 1.0.6, 6-Sept-2010".
2013-04-18 11:13:56 +02:00
Linus Nielsen Feltzing
6d9236e805 Add tests/http_pipe.py to the tarball build 2013-04-18 10:55:41 +02:00
Steve Holme
c306d2e42f smtp: Re-factored all perform based functions
Standardised the naming of all perform based functions to be in the form
smtp_perform_something().
2013-04-16 19:48:20 +01:00
Steve Holme
f737e3a3dd smtp: Added description comments to all perform based functions 2013-04-16 19:44:53 +01:00
Steve Holme
686586b0f9 smtp: Moved smtp_quit() to be with the other perform functions 2013-04-16 19:44:52 +01:00
Steve Holme
e621a5f6ea smtp: Moved smtp_rcpt_to() to be with the other perform functions 2013-04-16 19:44:49 +01:00
Steve Holme
8093f9541e smtp: Moved smtp_mail() to be with the other perform functions 2013-04-16 19:44:47 +01:00
Wouter Van Rooy
68e7fb499d curl-config: don't output static libs when they are disabled
Curl-config outputs static libraries even when they are disabled in
configure.

This causes problems with the build of pycurl.
2013-04-16 16:07:41 +02:00
Dave Reisner
d9569720dd docs/libcurl: fix formatting in manpage
Commit c3ea3eb6 introduced some minor cosmetic errors in
curl_mutli_socket_action(3).
2013-04-16 09:52:12 +02:00
Paul Howarth
1c40685d32 Add extra libs for lib1900 and lib2033 test programs
These are needed in cases where clock_gettime is used, from librt.
2013-04-15 23:06:10 +02:00
Dan Fandrich
31c6e7af6a FAQ: mention that the network connection can be monitored
Also note the prohibition on sharing handles across threads.
2013-04-15 22:26:18 +02:00
Steve Holme
552ba67bb1 pop3: Added missing comment for pop3_state_apop_resp() 2013-04-15 20:27:49 +01:00
Steve Holme
651254dcc7 smtp: Updated the coding style of smtp_state_servergreet_resp()
Updated the coding style, in this function, to be consistant with other
response functions rather then performing a hard return on failure.
2013-04-15 20:27:47 +01:00
Steve Holme
26bdafcbf9 pop3: Updated the coding style of pop3_state_servergreet_resp()
Updated the coding style, in this function, to be consistent with other
response functions rather then performing a hard return on failure.
2013-04-15 20:27:45 +01:00
Steve Holme
02dc9e788f pop3: Re-factored all perform based functions
Standardised the naming of all perform based functions to be in the form
pop3_perform_something() following the changes made to IMAP.
2013-04-14 10:06:10 +01:00
Steve Holme
e11c6e9961 pop3: Added description comments to all perform based functions 2013-04-14 10:06:08 +01:00
Steve Holme
e4eaa92728 pop3: Moved pop3_quit() to be with the other perform functions 2013-04-14 10:06:07 +01:00
Steve Holme
577f8e5ac6 pop3: Moved pop3_command() to be with the other perform functions
Started to apply the same tidy up to the POP3 code as applied to the
IMAP code in the 7.30.0 release.
2013-04-14 10:06:05 +01:00
Steve Holme
95ba6cdd54 RELEASE-NOTES: Removed erroneous spaces 2013-04-13 18:35:16 +01:00
Steve Holme
7ce6cb9ab4 RELEASE-NOTES: synced with 8723cade21 2013-04-13 16:43:30 +01:00
Steve Holme
8723cade21 smtp: Added support for ;auth=<mech> in the URL
Added support for specifying the preferred authentication mechanism in
the URL as per Internet-Draft 'draft-earhart-url-smtp-00'.
2013-04-13 16:23:00 +01:00
Steve Holme
d956d9db47 pop3: Reworked authentication type constants
... to use left-shifted values, like those defined in curl.h, rather
than 16-bit hexadecimal values.
2013-04-13 16:20:48 +01:00
Steve Holme
ecf93ac986 pop3: Small consistency tidy up 2013-04-13 16:16:23 +01:00
Steve Holme
b3a01be2f3 pop3: Added support for ;auth=<mech> in the URL
Added support for specifying the preferred authentication type and SASL
mechanism in the URL as per RFC-2384.
2013-04-13 16:16:21 +01:00
Steve Holme
00045a3009 imap: Added support for ;auth=<mech> in the URL
Added support for specifying the preferred authentication mechanism in
the URL as per RFC-5092.
2013-04-13 16:11:27 +01:00
Steve Holme
3f7188dd94 sasl: Reworked SASL mechanism constants
... to use left-shifted values, like those defined in curl.h, rather
than 16-bit hexadecimal values.
2013-04-13 13:29:50 +01:00
Steve Holme
720218fea1 sasl: Added predefined preferred mechanism values
In preparation for the upcoming changes to IMAP, POP3 and SMTP added
preferred mechanism values.
2013-04-13 13:11:37 +01:00
Steve Holme
73aa95592f url: Added support for parsing login options from the URL
As well as parsing the username and password from the URL, added support
for parsing the optional options part from the login details, to allow
the following supported URL format:

schema://username:password;options@example.com/path?q=foobar

This will only be used by IMAP, POP3 and SMTP at present but any
protocol that may be given login options in the URL will be able to
add support for them.
2013-04-13 10:49:42 +01:00
Steve Holme
ad3fdbc0a4 smtp: Fix compiler warning
warning: unused variable 'smtp' introduced in commit 73cbd21b5e.
2013-04-13 00:06:19 +01:00
Steve Holme
73cbd21b5e smtp: Moved parsing of url path into separate function 2013-04-12 23:15:51 +01:00
Daniel Stenberg
c5ba0c2f54 FTP: handle a 230 welcome response
...instead of the 220 we otherwise expect.

Made the ftpserver.pl support sending a custom "welcome" and then
created test 1219 to verify this fix with such a 230 welcome.

Bug: http://curl.haxx.se/mail/lib-2013-02/0102.html
Reported by: Anders Havn
2013-04-12 23:59:37 +02:00
Daniel Stenberg
edddf394b8 configure: try pthread_create without -lpthread
For libc variants without a spearate pthread lib (like bionic), try
using pthreads without the pthreads lib first and only if that fails try
the -lpthread linker flag.

Bug: http://curl.haxx.se/bug/view.cgi?id=1216
Reported by: Duncan
2013-04-12 22:58:28 +02:00
Daniel Stenberg
61d259f950 FTP: access files in root dir correctly
Accessing a file with an absolute path in the root dir but with no
directory specified was not handled correctly. This fix comes with four
new test cases that verify it.

Bug: http://curl.haxx.se/mail/lib-2013-04/0142.html
Reported by: Sam Deane
2013-04-12 22:43:13 +02:00
Steve Holme
c01735865f pop3: Reworked the function description for Curl_pop3_write() 2013-04-12 20:22:14 +01:00
Steve Holme
ca46c5dbe2 pop3: Added function description to pop3_parse_custom_request() 2013-04-12 20:22:12 +01:00
Steve Holme
2da127abb5 pop3: Moved utility functions to end of pop3.c 2013-04-12 20:22:10 +01:00
Nick Zitzmann
bc33f2200d darwinssl: add TLS session resumption
This ought to speed up additional TLS handshakes, at least in theory.
2013-04-12 12:20:10 -06:00
Steve Holme
fd399cde00 imap: Added function description to imap_parse_custom_request() 2013-04-12 18:27:51 +01:00
Steve Holme
00c74019f4 imap: Moved utility functions to end of imap.c (Part 3/3)
Moved imap_is_bchar() be with the other utility based functions.
2013-04-12 18:24:46 +01:00
Steve Holme
9d0063befa imap: Moved utility functions to end of imap.c (Part 2/3)
Moved imap_parse_url_path() and imap_parse_custom_request() to the end of the
file allowing all utility functions to be grouped together.
2013-04-12 18:24:44 +01:00
Steve Holme
01e55ebb26 imap: Moved utility functions to end of imap.c (Part 1/3)
Moved imap_atom() and imap_sendf() to the end of the file allowing all
utility functions to be grouped together.
2013-04-12 18:24:43 +01:00
Steve Holme
4bbad1dac7 imap: Corrected function description for imap_connect() 2013-04-12 18:14:43 +01:00
Kamil Dudka
ddbda328b3 tests: prevent test206, test1060, and test1061 from failing
... in case runtests.pl is invoked with non-default -b option

Fixes a regression caused by 1e29d275c6.
2013-04-12 14:25:58 +02:00
David Strauss
8ffbeeda80 libcurl-share.3: update what it does and does not share.
Update sharing interface documentation to provide exhaustive list of
what it does and does not share.
2013-04-12 13:35:29 +02:00
Daniel Stenberg
1d1ffaf912 THANKS: remove duplicated names 2013-04-12 12:37:47 +02:00
Daniel Stenberg
e0cff02061 bump: start working towards next release 2013-04-12 11:30:32 +02:00
Daniel Stenberg
7fe95bb0d5 THANKS: added people from the 7.30.0 RELEASE-NOTES 2013-04-12 11:30:12 +02:00
382 changed files with 23035 additions and 5688 deletions

View File

@@ -103,7 +103,7 @@ if test ! -z $SDK32; then
ln -fs ${FRAMEWORK_VERSION}/Resources Resources
ln -fs ${FRAMEWORK_VERSION}/Headers Headers
cd Versions
ln -fs ${FRAMEWORK_VERSION} Current
ln -fs $(basename "${FRAMEWORK_VERSION}") Current
echo Testing for SDK64
if test -d $SDK64_DIR; then

View File

@@ -148,12 +148,24 @@ vc-ssl-zlib: $(VC)
cd ..\src
nmake /f Makefile.$(VC) cfg=release-ssl-zlib
vc-winssl-zlib: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-winssl-zlib
cd ..\src
nmake /f Makefile.$(VC) cfg=release-winssl-zlib
vc-x64-ssl-zlib: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-zlib
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-zlib
vc-x64-winssl-zlib: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-winssl-zlib
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-winssl-zlib
vc-ssl-dll: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-ssl-dll

View File

@@ -1,88 +1,68 @@
Curl and libcurl 7.30.0
Curl and libcurl 7.33.0
Public curl releases: 132
Command line options: 152
curl_easy_setopt() options: 199
Public curl releases: 135
Command line options: 161
curl_easy_setopt() options: 205
Public functions in libcurl: 58
Known libcurl bindings: 42
Contributors: 1005
***
krb4 support is up for removal. If you care about it at all, speak up
on the curl-library list asap!
***
Contributors: 1057
This release includes the following changes:
o imap: Changed response tag generation to be completely unique
o imap: Added support for SASL-IR extension
o imap: Added support for the list command
o imap: Added support for the append command
o imap: Added custom request parsing
o imap: Added support to the fetch command for UID and SECTION properties
o imap: Added parsing and verification of the UIDVALIDITY mailbox attribute
o darwinssl: Make certificate errors less techy
o imap/pop3/smtp: Added support for the STARTTLS capability
o checksrc: ban use of sprintf, vsprintf, strcat, strncat and gets
o curl_global_init() now accepts the CURL_GLOBAL_ACK_EINTR flag [10]
o Added CURLMOPT_MAX_HOST_CONNECTIONS, CURLMOPT_MAX_TOTAL_CONNECTIONS for
new multi interface connection handling
o Added CURLMOPT_MAX_PIPELINE_LENGTH, CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE,
CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE, CURLMOPT_PIPELINING_SITE_BL and
CURLMOPT_PIPELINING_SERVER_BL for new pipelining control [15]
o test code for testing the event based API [3]
o CURLM_ADDED_ALREADY: new error code
o test TFTP server: support "writedelay" within <servercmd>
o krb4 support has been removed
o imap/pop3/smtp: added basic SASL XOAUTH2 support [9]
o darwinssl: add support for PKCS#12 files for client authentication
o darwinssl: enable BEAST workaround on iOS 7 & later
o Pass password to OpenSSL engine by user interface [15]
o c-ares: Add support for various DNS binding options
o cookies: add expiration
o curl: added --oauth2-bearer option
This release includes the following bugfixes:
o SECURITY ADVISORY: cookie tailmatching to avoid cross-domain leakage [25]
o darwinssl: Fix build under Leopard
o DONE: consider callback-aborted transfers premature [1]
o ntlm: Fixed memory leaks
o smtp: Fixed an issue when processing EHLO failure responses
o pop3: Fixed incorrect return value from pop3_endofresp()
o pop3: Fixed SASL authentication capability detection
o pop3: Fixed blocking SSL connect when connecting via POP3S
o imap: Fixed memory leak when performing multiple selects
o nss: fix misplaced code enabling non-blocking socket mode
o AddFormData: prevent only directories from being posted [2]
o darwinssl: fix infinite loop if server disconnected abruptly [3]
o metalink: fix improbable crash parsing metalink filename
o show proper host name on failed resolve
o MacOSX-Framework: Make script work in Xcode 4.0 and later
o strlcat: remove function [4]
o darwinssl: Fix send glitchiness with data > 32 or so KB [5]
o polarssl: better 1.1.x and 1.2.x support
o various documentation improvements
o multi: NULL pointer reference when closing an unused multi handle [9]
o SOCKS: fix socks proxy when noproxy matched [7]
o install-sh: updated to support multiple source files as arguments [6]
o PolarSSL: added human readable error strings
o resolver_error: remove wrong error message output
o docs: updates HTML index and general improvements
o curlbuild.h.dist: enhance non-configure GCC ABI detection logic
o sasl: Fixed null pointer reference when decoding empty digest challenge [8]
o easy: do not ignore poll() failures other than EINTR
o darwinssl: disable ECC ciphers under Mountain Lion by default
o CONNECT: count received headers [11]
o build: fixes for VMS
o CONNECT: clear 'rewindaftersend' on success [12]
o HTTP proxy: insert slash in URL if missing [13]
o hiperfifo: updated to use current libevent API [14]
o getinmemory.c: abort the transfer nicely if not enough memory
o improved win32 memorytracking
o corrected proxy header response headers count [16]
o FTP quote operations on re-used connection [17]
o tcpkeepalive on win32 [18]
o tcpkeepalive on Mac OS X [23]
o easy: acknowledge the CURLOPT_MAXCONNECTS option properly [19]
o easy interface: restore default MAXCONNECTS to 5
o win32: don't set SO_SNDBUF for windows vista or later versions [20]
o HTTP: made cookie sort function more deterministic
o winssl: Fixed memory leak if connection was not successful
o FTP: wait on both connections during active STOR state [21]
o connect: treat a failed local bind of an interface as a non-fatal error [22]
o darwinssl: disable insecure ciphers by default
o FTP: handle "rubbish" in front of directory name in 257 responses [24]
o mk-ca-bundle: Fixed lost OpenSSL output with "-t"
o nss: make sure that NSS is initialized
o curl: make --no-[option] work properly for several options
o FTP: with socket_action send better socket updates in active mode [1]
o curl: fix the --sasl-ir in the --help output
o tests 2032, 2033: Don't hardcode port in expected output
o urlglob: better detect unclosed braces, empty lists and overflows [7]
o urlglob: error out on range overflow [8]
o imap: Fixed response check for SEARCH, EXPUNGE, LSUB, UID and NOOP commands [10]
o handle arbitrary-length username and password [2]
o TFTP: make the CURLOPT_LOW_SPEED* options work [4]
o curl.h: name space pollution by "enum type" [5]
o multi: move on from STATE_DONE faster [6]
o FTP: 60 secs delay if aborted in the CURLOPT_HEADERFUNCTION callback [11]
o multi_socket: improved 100-continue timeout handling
o curl_multi_remove_handle: allow multiple removes
o FTP: fix getsock during DO_MORE state [12]
o -x: rephrased the --proxy section somewhat
o acinclude: fix --without-ca-path when cross-compiling [13]
o LDAP: fix bad free() when URL parsing failed [14]
o --data: mention CRLF treatment when reading from file
o curl_easy_pause: suggest one way to unpause
o imap: Fixed calculation of transfer when partial FETCH received [16]
o pingpong: Check SSL library buffers for already read data [16]
o imap/pop3/smtp: Speed up SSL connection initialization
o libcurl.3: for multi interface connections are held in the multi handle
o curl_easy_setopt.3: mention RTMP URL quirks [17]
o curl.1: detail how short/long options work [18]
o curl.1: Added information about optional login options to --user option
o curl: Added clarification to the --mail options in the --help output
o curl_easy_setopt.3: clarify that TIMEOUT and TIMEOUT_MS set the same value
o openssl: use correct port number in error message [19]
o darwinssl: block TLS_RSA_WITH_NULL_SHA256 cipher
o OpenSSL: acknowledge CURLOPT_SSL_VERIFYHOST without VERIFYPEER
o xattr: add support for FreeBSD xattr API
o win32: fix Visual Studio 2010 build with WINVER >= 0x600 [22]
o configure: use icc options without space [21]
o test1112: Increase the timeout from 7s to 16s [20]
o SCP: upload speed on a fast connection limited to 16384 B/s
o curl_setup_once: fix errno access for lwip on Windows [24]
o HTTP: Output http response 304 when modified time is too old [23]
This release includes the following known bugs:
@@ -91,43 +71,41 @@ This release includes the following known bugs:
This release would not have looked like this without help, code, reports and
advice from friends like these:
Kamil Dudka, Steve Holme, Nick Zitzmann, Patricia Muscalu, Dan Fandrich,
Gisle Vanem, Guenter Knauf, Yang Tse, Oliver Gondža, Aki Koskinen,
Alexander Klauer, Kim Vandry, Willem Sparreboom, Jeremy Huddleston,
Bruno de Carvalho, Rainer Jung, Jeremy Huddleston, Kim Vandry, Jiri Hruska,
Alexander Klauer, Saran Neti, Alessandro Ghedini, Linus Nielsen Feltzing,
Martin Jansen, John E. Malmberg, Tom Grace, Patrick Monnerat,
Zdenek Pavlas, Myk Taylor, Cédric Deltheil, Robert Wruck, Sam Deane,
Clemens Gruber, Marc Hoersken, Tomas Mlcoch, Fredrik Thulin, Steven Gu,
Andrew Kurushin, Christian Hägele, Daniel Theron, Bill Middlecamp,
Richard Michael, Yamada Yasuharu
Alex McLellan, Bill Doyle, Colby Ranger, Fabian Keil, Gisle Vanem,
John E. Malmberg, Jonathan Nieder, Kamil Dudka, Shawn Landden,
Tor Arntsen, Will Dietz, Yi Huang, Kyle L. Huff, Steve Holme, Mike Mio,
Stefan Neis, Nick Zitzmann, Geoff Beier, John Dunn, Jiri Hruska,
Tomas Mlcoch, Kim Vandry, Ben Greear, Gorilla Maguila, Jerry Krinock,
Yamada Yasuharu, Gordon Marler, Dave Thompson, D. Flinkmann,
Benoit Sigoure, Clemens Gruber, Guenter Knauf, Petr Pisar, Elmira A Semenova,
Francois Charlier, Ishan SinghLevett, Marcel Raad, Ulf Samuelsson,
Andrej E Baranov, Derek Higgins, Heinrich Schaefer
Thanks! (and sorry if I forgot to mention someone)
References to bug reports and discussions on issues:
[1] = http://curl.haxx.se/bug/view.cgi?id=1184
[2] = http://curl.haxx.se/mail/archive-2013-02/0040.html
[3] = http://curl.haxx.se/mail/lib-2013-03/0014.html
[4] = http://curl.haxx.se/bug/view.cgi?id=1192
[5] = http://curl.haxx.se/mail/lib-2013-02/0145.html
[6] = http://curl.haxx.se/bug/view.cgi?id=1195
[7] = http://curl.haxx.se/bug/view.cgi?id=1190
[8] = http://curl.haxx.se/bug/view.cgi?id=1193
[9] = http://curl.haxx.se/bug/view.cgi?id=1194
[10] = http://curl.haxx.se/bug/view.cgi?id=1168
[11] = http://curl.haxx.se/bug/view.cgi?id=1204
[12] = https://groups.google.com/d/msg/msysgit/B31LNftR4BI/KhRTz0iuGmUJ
[13] = http://curl.haxx.se/bug/view.cgi?id=1206
[14] = http://curl.haxx.se/bug/view.cgi?id=1199
[15] = http://daniel.haxx.se/blog/2013/03/26/better-pipelining-in-libcurl-7-30-0/
[16] = http://curl.haxx.se/bug/view.cgi?id=1204
[17] = http://curl.haxx.se/mail/lib-2013-03/0319.html
[18] = http://curl.haxx.se/bug/view.cgi?id=1209
[19] = http://curl.haxx.se/bug/view.cgi?id=1212
[20] = http://curl.haxx.se/bug/view.cgi?id=1188
[21] = http://curl.haxx.se/bug/view.cgi?id=1183
[22] = http://curl.haxx.se/bug/view.cgi?id=1189
[23] = http://curl.haxx.se/bug/view.cgi?id=1214
[24] = http://curl.haxx.se/mail/lib-2013-04/0113.html
[25] = http://curl.haxx.se/docs/adv_20130412.html
[1] = http://curl.haxx.se/mail/lib-2013-08/0043.html
[2] = http://bugs.debian.org/719856
[3] = http://daniel.haxx.se/blog/2013/08/20/testing-curl_multi_socket_action/
[4] = http://curl.haxx.se/bug/view.cgi?id=1269
[5] = https://github.com/bagder/curl/pull/76
[6] = http://curl.haxx.se/mail/lib-2013-08/0211.html
[7] = http://curl.haxx.se/bug/view.cgi?id=1264
[8] = http://curl.haxx.se/bug/view.cgi?id=1267
[9] = http://curl.haxx.se/mail/lib-2013-08/0234.html
[10] = http://curl.haxx.se/mail/lib-2013-08/0136.html
[11] = https://bugzilla.redhat.com/1005686
[12] = http://curl.haxx.se/mail/lib-2013-08/0109.html
[13] = http://curl.haxx.se/bug/view.cgi?id=1273
[14] = http://curl.haxx.se/mail/lib-2013-08/0209.html
[15] = http://curl.haxx.se/mail/lib-2013-08/0265.html
[16] = http://curl.haxx.se/mail/lib-2013-08/0170.html
[17] = http://curl.haxx.se/bug/view.cgi?id=1278
[18] = http://curl.haxx.se/bug/view.cgi?id=1279
[19] = http://curl.haxx.se/bug/view.cgi?id=1281
[20] = http://curl.haxx.se/mail/lib-2010-02/0200.html
[21] = http://curl.haxx.se/mail/lib-2013-09/0182.html
[22] = http://curl.haxx.se/bug/view.cgi?id=1282
[23] = http://curl.haxx.se/bug/view.cgi?id=1288
[24] = http://curl.haxx.se/mail/lib-2013-10/0048.html

View File

@@ -2620,46 +2620,50 @@ AC_HELP_STRING([--without-ca-path], [Don't use a default CA path]),
capath="$want_capath"
ca="no"
else
dnl neither of --with-ca-* given
dnl first try autodetecting a CA bundle , then a CA path
dnl both autodetections can be skipped by --without-ca-*
ca="no"
capath="no"
if test "x$want_ca" = "xunset"; then
dnl the path we previously would have installed the curl ca bundle
dnl to, and thus we now check for an already existing cert in that place
dnl in case we find no other
if test "x$prefix" != xNONE; then
cac="${prefix}/share/curl/curl-ca-bundle.crt"
else
cac="$ac_default_prefix/share/curl/curl-ca-bundle.crt"
fi
if test "x$cross_compiling" != "xyes"; then
dnl NOT cross-compiling and...
dnl neither of the --with-ca-* options are provided
if test "x$want_ca" = "xunset"; then
dnl the path we previously would have installed the curl ca bundle
dnl to, and thus we now check for an already existing cert in that
dnl place in case we find no other
if test "x$prefix" != xNONE; then
cac="${prefix}/share/curl/curl-ca-bundle.crt"
else
cac="$ac_default_prefix/share/curl/curl-ca-bundle.crt"
fi
for a in /etc/ssl/certs/ca-certificates.crt \
/etc/pki/tls/certs/ca-bundle.crt \
/usr/share/ssl/certs/ca-bundle.crt \
/usr/local/share/certs/ca-root.crt \
/etc/ssl/cert.pem \
"$cac"; do
if test -f "$a"; then
ca="$a"
break
fi
done
fi
if test "x$want_capath" = "xunset" -a "x$ca" = "xno" -a \
"x$OPENSSL_ENABLED" = "x1"; then
for a in /etc/ssl/certs/; do
if test -d "$a" && ls "$a"/[[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]].0 >/dev/null 2>/dev/null; then
capath="$a"
break
fi
done
for a in /etc/ssl/certs/ca-certificates.crt \
/etc/pki/tls/certs/ca-bundle.crt \
/usr/share/ssl/certs/ca-bundle.crt \
/usr/local/share/certs/ca-root.crt \
/etc/ssl/cert.pem \
"$cac"; do
if test -f "$a"; then
ca="$a"
break
fi
done
fi
if test "x$want_capath" = "xunset" -a "x$ca" = "xno" -a \
"x$OPENSSL_ENABLED" = "x1"; then
for a in /etc/ssl/certs/; do
if test -d "$a" && ls "$a"/[[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]].0 >/dev/null 2>/dev/null; then
capath="$a"
break
fi
done
fi
else
dnl no option given and cross-compiling
AC_MSG_WARN([skipped the ca-cert path detection when cross-compiling])
fi
fi
if test "x$ca" != "xno"; then
CURL_CA_BUNDLE='"'$ca'"'
AC_DEFINE_UNQUOTED(CURL_CA_BUNDLE, "$ca", [Location of default ca bundle])

View File

@@ -126,7 +126,7 @@ fi
dnl figure out the libcurl version
CURLVERSION=`$SED -ne 's/^#define LIBCURL_VERSION "\(.*\)"/\1/p' ${srcdir}/include/curl/curlver.h`
XC_CHECK_PROG_CC
AM_INIT_AUTOMAKE
XC_AUTOMAKE
AC_MSG_CHECKING([curl version])
AC_MSG_RESULT($CURLVERSION)
@@ -150,7 +150,6 @@ dnl initialize all the info variables
curl_ssl_msg="no (--with-{ssl,gnutls,nss,polarssl,cyassl,axtls,winssl,darwinssl} )"
curl_ssh_msg="no (--with-libssh2)"
curl_zlib_msg="no (--with-zlib)"
curl_krb4_msg="no (--with-krb4*)"
curl_gss_msg="no (--with-gssapi)"
curl_spnego_msg="no (--with-spnego)"
curl_tls_srp_msg="no (--enable-tls-srp)"
@@ -1134,101 +1133,6 @@ no)
;;
esac
dnl **********************************************************************
dnl Check for the presence of Kerberos4 libraries and headers
dnl **********************************************************************
AC_ARG_WITH(krb4-includes,
AC_HELP_STRING([--with-krb4-includes=DIR],
[Specify location of kerberos4 headers]),[
CPPFLAGS="$CPPFLAGS -I$withval"
KRB4INC="$withval"
want_krb4=yes
])
AC_ARG_WITH(krb4-libs,
AC_HELP_STRING([--with-krb4-libs=DIR],[Specify location of kerberos4 libs]),[
LDFLAGS="$LDFLAGS -L$withval"
KRB4LIB="$withval"
want_krb4=yes
])
OPT_KRB4=off
AC_ARG_WITH(krb4,dnl
AC_HELP_STRING([--with-krb4=DIR],[where to look for Kerberos4]),[
OPT_KRB4="$withval"
if test X"$OPT_KRB4" != Xno; then
want_krb4="yes"
if test X"$OPT_KRB4" != Xyes; then
LDFLAGS="$LDFLAGS -L$OPT_KRB4/lib$libsuff"
KRB4LIB="$OPT_KRB4/lib$libsuff"
CPPFLAGS="$CPPFLAGS -I$OPT_KRB4/include"
KRB4INC="$OPT_KRB4/include"
fi
fi
])
AC_MSG_CHECKING([if Kerberos4 support is requested])
if test "$want_krb4" = yes
then
if test "$ipv6" = "yes"; then
echo krb4 is not compatible with IPv6
exit 1
fi
AC_MSG_RESULT(yes)
dnl Check for & handle argument to --with-krb4
AC_MSG_CHECKING(where to look for Kerberos4)
if test X"$OPT_KRB4" = Xyes
then
AC_MSG_RESULT([defaults])
else
AC_MSG_RESULT([libs in $KRB4LIB, headers in $KRB4INC])
fi
dnl Check for DES library
AC_CHECK_LIB(des, des_pcbc_encrypt,
[
AC_CHECK_HEADERS(des.h)
dnl resolv lib?
AC_CHECK_FUNC(res_search, , [AC_CHECK_LIB(resolv, res_search)])
dnl Check for the Kerberos4 library
AC_CHECK_LIB(krb, krb_net_read,
[
dnl Check for header files
AC_CHECK_HEADERS(krb.h)
dnl we found the required libraries, add to LIBS
LIBS="-lkrb -lcom_err -ldes $LIBS"
dnl Check for function krb_get_our_ip_for_realm
dnl this is needed for NAT networks
AC_CHECK_FUNCS(krb_get_our_ip_for_realm)
dnl add define KRB4
AC_DEFINE(HAVE_KRB4, 1,
[if you have the Kerberos4 libraries (including -ldes)])
dnl substitute it too!
KRB4_ENABLED=1
AC_SUBST(KRB4_ENABLED)
curl_krb4_msg="enabled"
dnl the krb4 stuff needs a strlcpy()
AC_CHECK_FUNCS(strlcpy)
])
])
else
AC_MSG_RESULT(no)
fi
dnl **********************************************************************
dnl Check for FBopenssl(SPNEGO) libraries
dnl **********************************************************************
@@ -2808,6 +2712,92 @@ dnl http://publibn.boulder.ibm.com/doc_link/en_US/a_doc_lib/aixprggd/ \
dnl genprogc/thread_quick_ref.htm
dnl **********************************************************************
dnl Check for nghttp2
dnl **********************************************************************
AC_MSG_CHECKING([whether to build with nghttp2])
OPT_H2="no"
AC_ARG_WITH(nghttp2,
AC_HELP_STRING([--with-nghttp2=PATH],[Enable nghttp2 usage])
AC_HELP_STRING([--without-nghttp2],[Disable nghttp2 usage]),
[OPT_H2=$withval])
case "$OPT_H2" in
no)
dnl --without-nghttp2 option used
want_idn="no"
AC_MSG_RESULT([no])
;;
default)
dnl configure option not specified
want_h2="no"
want_h2_path="default"
AC_MSG_RESULT([no])
;;
yes)
dnl --with-nghttp2 option used without path
want_h2="yes"
want_h2_path=""
AC_MSG_RESULT([yes])
;;
*)
dnl --with-nghttp2 option used with path
want_h2="yes"
want_h2_path="$withval"
AC_MSG_RESULT([yes ($withval)])
;;
esac
curl_h2_msg="disabled (--with-nghttp2)"
if test X"$OPT_H2" != Xno; then
dnl backup the pre-librtmp variables
CLEANLDFLAGS="$LDFLAGS"
CLEANCPPFLAGS="$CPPFLAGS"
CLEANLIBS="$LIBS"
h2pcdir=${want_h2_path}/lib/pkgconfig
CURL_CHECK_PKGCONFIG(libnghttp2, $h2pcdir)
if test "$PKGCONFIG" != "no" ; then
LIB_H2=`CURL_EXPORT_PCDIR([$h2pcdir])
$PKGCONFIG --libs-only-l libnghttp2`
AC_MSG_NOTICE([-l is $LIB_H2])
CPP_H2=`CURL_EXPORT_PCDIR([$h2pcdir]) dnl
$PKGCONFIG --cflags-only-I libnghttp2`
AC_MSG_NOTICE([-I is $CPP_H2])
LD_H2=`CURL_EXPORT_PCDIR([$h2pcdir])
$PKGCONFIG --libs-only-L libnghttp2`
AC_MSG_NOTICE([-L is $LD_H2])
else
dnl To avoid link errors, we do not allow --libnghttp2 without
dnl a pkgconfig file
AC_MSG_ERROR([--with-nghttp2 was specified but could not find libnghttp2 pkg-config file.])
fi
LDFLAGS="$LDFLAGS $LD_H2"
CPPFLAGS="$CPPFLAGS $CPP_H2"
LIBS="$LIB_H2 $LIBS"
AC_CHECK_LIB(nghttp2, nghttp2_session_client_new,
[
AC_CHECK_HEADERS(nghttp2/nghttp2.h,
curl_h2_msg="enabled (nghttp2)"
NGHTTP2_ENABLED=1
AC_DEFINE(USE_NGHTTP2, 1, [if nghttp2 is in use])
AC_SUBST(USE_NGHTTP2, [1])
)
],
dnl not found, revert back to clean variables
LDFLAGS=$CLEANLDFLAGS
CPPFLAGS=$CLEANCPPFLAGS
LIBS=$CLEANLIBS
)
fi
dnl **********************************************************************
dnl Back to "normal" configuring
dnl **********************************************************************
@@ -3158,14 +3148,26 @@ if test "$want_thres" = "yes"; then
AC_CHECK_HEADER(pthread.h,
[ AC_DEFINE(HAVE_PTHREAD_H, 1, [if you have <pthread.h>])
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -pthread"
AC_CHECK_LIB(pthread, pthread_create,
[ AC_MSG_NOTICE([using POSIX threaded DNS lookup])
AC_DEFINE(USE_THREADS_POSIX, 1, [if you want POSIX threaded DNS lookup])
USE_THREADS_POSIX=1
curl_res_msg="threaded"
],
[ CFLAGS="$save_CFLAGS"])
dnl first check for function without lib
AC_CHECK_FUNC(pthread_create, [USE_THREADS_POSIX=1] )
dnl if it wasn't found without lib, search for it in pthread lib
if test "$USE_THREADS_POSIX" != "1"
then
CFLAGS="$CFLAGS -pthread"
AC_CHECK_LIB(pthread, pthread_create,
[USE_THREADS_POSIX=1],
[ CFLAGS="$save_CFLAGS"])
fi
if test "x$USE_THREADS_POSIX" = "x1"
then
AC_DEFINE(USE_THREADS_POSIX, 1, [if you want POSIX threaded DNS lookup])
curl_res_msg="POSIX threaded"
fi
])
fi
@@ -3338,6 +3340,11 @@ dnl yes or no
ENABLE_SHARED="$enable_shared"
AC_SUBST(ENABLE_SHARED)
dnl to let curl-config output the static libraries correctly
ENABLE_STATIC="$enable_static"
AC_SUBST(ENABLE_STATIC)
dnl
dnl For keeping supported features and protocols also in pkg-config file
dnl since it is more cross-compile friendly than curl-config
@@ -3348,9 +3355,6 @@ if test "x$USE_SSLEAY" = "x1"; then
elif test -n "$SSL_ENABLED"; then
SUPPORT_FEATURES="$SUPPORT_FEATURES SSL"
fi
if test "@KRB4_ENABLED@" = "x1"; then
SUPPORT_FEATURES="$SUPPORT_FEATURES KRB4"
fi
if test "x$IPV6_ENABLED" = "x1"; then
SUPPORT_FEATURES="$SUPPORT_FEATURES IPv6"
fi
@@ -3380,6 +3384,10 @@ if test "x$USE_TLS_SRP" = "x1"; then
SUPPORT_FEATURES="$SUPPORT_FEATURES TLS-SRP"
fi
if test "x$USE_NGHTTP2" = "x1"; then
SUPPORT_FEATURES="$SUPPORT_FEATURES HTTP2"
fi
AC_SUBST(SUPPORT_FEATURES)
dnl For supported protocols in pkg-config file
@@ -3514,6 +3522,8 @@ AC_OUTPUT
CURL_GENERATE_CONFIGUREHELP_PM
XC_AMEND_DISTCLEAN([lib src tests/unit tests/server tests/libtest docs/examples])
AC_MSG_NOTICE([Configured to build curl/libcurl:
curl version: ${CURLVERSION}
@@ -3523,7 +3533,6 @@ AC_MSG_NOTICE([Configured to build curl/libcurl:
SSL support: ${curl_ssl_msg}
SSH support: ${curl_ssh_msg}
zlib support: ${curl_zlib_msg}
krb4 support: ${curl_krb4_msg}
GSSAPI support: ${curl_gss_msg}
SPNEGO support: ${curl_spnego_msg}
TLS-SRP support: ${curl_tls_srp_msg}
@@ -3542,6 +3551,7 @@ AC_MSG_NOTICE([Configured to build curl/libcurl:
RTSP support: ${curl_rtsp_msg}
RTMP support: ${curl_rtmp_msg}
metalink support: ${curl_mtlnk_msg}
HTTP2 support: ${curl_h2_msg}
Protocols: ${SUPPORT_PROTOCOLS}
])

46
contributors.sh Executable file
View File

@@ -0,0 +1,46 @@
#!/bin/sh
#***************************************************************************
# _ _ ____ _
# Project ___| | | | _ \| |
# / __| | | | |_) | |
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at http://curl.haxx.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
# furnished to do so, under the terms of the COPYING file.
#
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
###########################################################################
#
# This script shows all mentioned contributors from <hash> until HEAD. To aid
# when writing RELEASE-NOTES and THANKS.
#
start=$1
if test -z "$start"; then
echo "Usage: $0 <since this tag/hash>"
fi
# filter out Author:, Commit: and *by: lines
# cut off the email parts
# cut off spaces first and last on the line
# only count names with a space (ie more than one word)
# sort all unique names
git log $start..HEAD | \
egrep '(Author|Commit|by):' | \
cut -d: -f2- | \
cut '-d<' -f1 | \
sed -e 's/^ //' -e 's/ $//g' | \
grep ' ' | \
sort -u

View File

@@ -155,7 +155,12 @@ while test $# -gt 0; do
;;
--static-libs)
echo @libdir@/libcurl.@libext@ @LDFLAGS@ @LIBCURL_LIBS@
if test "X@ENABLE_STATIC@" != "Xno" ; then
echo @libdir@/libcurl.@libext@ @LDFLAGS@ @LIBCURL_LIBS@
else
echo "curl was built with static libraries disabled" >&2
exit 1
fi
;;
--configure)

View File

@@ -79,9 +79,9 @@
1.3 What To Read
Source code, the man pages, the INTERNALS document, TODO, KNOWN_BUGS, the
most recent CHANGES. Just lurking on the libcurl mailing list is gonna give
you a lot of insights on what's going on right now. Asking there is a good
idea too.
most recent CHANGES. Just lurking on the curl-library mailing list is gonna
give you a lot of insights on what's going on right now. Asking there is a
good idea too.
2. cURL Coding Standards
@@ -98,12 +98,12 @@
2.2 Indenting
Please try using the same indenting levels and bracing method as all the
other code already does. It makes the source code a lot easier to follow if
all of it is written using the same style. We don't ask you to like it, we
just ask you to follow the tradition! ;-) This mainly means: 2-level indents,
using spaces only (no tabs) and having the opening brace ({) on the same line
as the if() or while().
Use the same indenting levels and bracing method as all the other code
already does. It makes the source code easier to follow if all of it is
written using the same style. We don't ask you to like it, we just ask you to
follow the tradition! ;-) This mainly means: 2-level indents, using spaces
only (no tabs) and having the opening brace ({) on the same line as the if()
or while().
Also note that we use if() and while() with no space before the parenthesis.
@@ -151,6 +151,9 @@
description exactly what they correct so that all patches can be selectively
applied by the maintainer or other interested parties.
Also, separate patches enable bisecting much better when we track problems in
the future.
2.9 Patch Against Recent Sources
Please try to get the latest available sources to make your patches
@@ -178,6 +181,10 @@
test case that verifies that it works as documented. If every submitter also
posts a few test cases, it won't end up as a heavy burden on a single person!
If you don't have test cases or perhaps you have done something that is very
hard to write tests for, do explain exactly how you have otherwise tested and
verified your changes.
3. Pushing Out Your Changes
3.1 Write Access to git Repository

146
docs/FAQ
View File

@@ -202,27 +202,25 @@ FAQ
better. We do however believe in a few rules when it comes to the future of
curl:
* Curl -- the command line tool -- is to remain a non-graphical command line
tool. If you want GUIs or fancy scripting capabilities, you should look
for another tool that uses libcurl.
Curl -- the command line tool -- is to remain a non-graphical command line
tool. If you want GUIs or fancy scripting capabilities, you should look for
another tool that uses libcurl.
* We do not add things to curl that other small and available tools already
do very fine at the side. Curl's output is fine to pipe into another
program or redirect to another file for the next program to interpret.
We do not add things to curl that other small and available tools already do
very fine at the side. Curl's output is fine to pipe into another program or
redirect to another file for the next program to interpret.
* We focus on protocol related issues and improvements. If you wanna do more
magic with the supported protocols than curl currently does, chances are
big we will agree. If you wanna add more protocols, we may very well
agree.
We focus on protocol related issues and improvements. If you wanna do more
magic with the supported protocols than curl currently does, chances are big
we will agree. If you wanna add more protocols, we may very well agree.
* If you want someone else to make all the work while you wait for us to
implement it for you, that is not a very friendly attitude. We spend a
considerable time already on maintaining and developing curl. In order to
get more out of us, you should consider trading in some of your time and
efforts in return.
If you want someone else to make all the work while you wait for us to
implement it for you, that is not a very friendly attitude. We spend a
considerable time already on maintaining and developing curl. In order to
get more out of us, you should consider trading in some of your time and
efforts in return.
* If you write the code, chances are bigger that it will get into curl
faster.
If you write the code, chances are bigger that it will get into curl faster.
1.5 Who makes curl?
@@ -263,7 +261,7 @@ FAQ
Our project name curl has been in effective use since 1998. We were not the
first computer related project to use the name "curl" and do not claim any
first-hand rights to the name.
rights to the name.
We recognize that we will be living in parallel with curl.com and wish them
every success.
@@ -620,15 +618,15 @@ FAQ
Some workarounds usually suggested to overcome this Javascript dependency:
- Depending on the Javascript complexity, write up a script that
translates it to another language and execute that.
Depending on the Javascript complexity, write up a script that translates it
to another language and execute that.
- Read the Javascript code and rewrite the same logic in another language.
Read the Javascript code and rewrite the same logic in another language.
- Implement a Javascript interpreter, people have successfully used the
Mozilla Javascript engine in the past.
Implement a Javascript interpreter, people have successfully used the
Mozilla Javascript engine in the past.
- Ask your admins to stop this, for a static proxy setup or similar.
Ask your admins to stop this, for a static proxy setup or similar.
3.15 Can I do recursive fetches with curl?
@@ -644,34 +642,38 @@ FAQ
There are three different kinds of "certificates" to keep track of when we
talk about using SSL-based protocols (HTTPS or FTPS) using curl or libcurl.
- Client certificate. The server you communicate may require that you can
provide this in order to prove that you actually are who you claim to be.
If the server doesn't require this, you don't need a client certificate.
CLIENT CERTIFICATE
A client certificate is always used together with a private key, and the
private key has a pass phrase that protects it.
The server you communicate may require that you can provide this in order to
prove that you actually are who you claim to be. If the server doesn't
require this, you don't need a client certificate.
- Server certificate. The server you communicate with has a server
certificate. You can and should verify this certificate to make sure that
you are truly talking to the real server and not a server impersonating
it.
A client certificate is always used together with a private key, and the
private key has a pass phrase that protects it.
- Certificate Authority certificate ("CA cert"). You often have several CA
certs in a CA cert bundle that can be used to verify a server certificate
that was signed by one of the authorities in the bundle. curl does not
come with a CA cert bundle but most curl installs provide one. You can
also override the default.
SERVER CERTIFICATE
The server certificate verification process is made by using a Certificate
Authority certificate ("CA cert") that was used to sign the server
certificate. Server certificate verification is enabled by default in curl
and libcurl and is often the reason for problems as explained in FAQ entry
4.12 and the SSLCERTS document
(http://curl.haxx.se/docs/sslcerts.html). Server certificates that are
"self-signed" or otherwise signed by a CA that you do not have a CA cert
for, cannot be verified. If the verification during a connect fails, you
are refused access. You then need to explicitly disable the verification
to connect to the server.
The server you communicate with has a server certificate. You can and should
verify this certificate to make sure that you are truly talking to the real
server and not a server impersonating it.
CERTIFICATE AUTHORITY CERTIFICATE ("CA cert")
You often have several CA certs in a CA cert bundle that can be used to
verify a server certificate that was signed by one of the authorities in the
bundle. curl does not come with a CA cert bundle but most curl installs
provide one. You can also override the default.
The server certificate verification process is made by using a Certificate
Authority certificate ("CA cert") that was used to sign the server
certificate. Server certificate verification is enabled by default in curl
and libcurl and is often the reason for problems as explained in FAQ entry
4.12 and the SSLCERTS document
(http://curl.haxx.se/docs/sslcerts.html). Server certificates that are
"self-signed" or otherwise signed by a CA that you do not have a CA cert
for, cannot be verified. If the verification during a connect fails, you are
refused access. You then need to explicitly disable the verification to
connect to the server.
3.17 How do I list the root dir of an FTP server?
@@ -728,7 +730,7 @@ FAQ
When passing on a URL to curl to use, it may respond that the particular
protocol is not supported or disabled. The particular way this error message
is phrased is because curl doesn't make a distinction internally of whether
a particular protocol is not supported (ie never got any code added that
a particular protocol is not supported (i.e. never got any code added that
knows how to speak that protocol) or if it was explicitly disabled. curl can
be built to only support a given set of protocols, and the rest would then
be disabled or not supported.
@@ -794,12 +796,13 @@ FAQ
curl 'http://www.altavista.com/cgi-bin/query?text=yes&q=curl'
In Windows, the standard DOS shell treats the %-symbol specially and you
need to use TWO %-symbols for each single one you want to use in the URL.
In Windows, the standard DOS shell treats the percent sign specially and you
need to use TWO percent signs for each single one you want to use in the
URL.
Also note that if you want the literal %-symbol to be part of the data you
pass in a POST using -d/--data you must encode it as '%25' (which then also
needs the %-symbol doubled on Windows machines).
If you want a literal percent sign to be part of the data you pass in a POST
using -d/--data you must encode it as '%25' (which then also needs the
percent sign doubled on Windows machines).
4.3 How can I use {, }, [ or ] to specify multiple URLs?
@@ -968,13 +971,13 @@ FAQ
4.14 Redirects work in browser but not with curl!
curl supports HTTP redirects fine (see item 3.8). Browsers generally support
at least two other ways to perform directs that curl does not:
at least two other ways to perform redirects that curl does not:
- Meta tags. You can write a HTML tag that will cause the browser to
redirect to another given URL after a certain time.
Meta tags. You can write a HTML tag that will cause the browser to redirect
to another given URL after a certain time.
- Javascript. You can write a Javascript program embedded in a HTML page
that redirects the browser to another given URL.
Javascript. You can write a Javascript program embedded in a HTML page that
redirects the browser to another given URL.
There is no way to make curl follow these redirects. You must either
manually figure out what the page is set to do, or you write a script that
@@ -1055,11 +1058,11 @@ FAQ
4.19 Why doesn't cURL return an error when the network cable is unplugged?
Unplugging the cable is not an error situation. The TCP/IP protocol stack
Unplugging a cable is not an error situation. The TCP/IP protocol stack
was designed to be fault tolerant, so even though there may be a physical
break somewhere the connection shouldn't be affected, just possibly
delayed. Eventually, the physical break will be fixed or the data will be
re-routed around the physical problem.
re-routed around the physical problem through another path.
In such cases, the TCP/IP stack is responsible for detecting when the
network connection is irrevocably lost. Since with some protocols it is
@@ -1077,6 +1080,12 @@ FAQ
falls too low, and --connect-timeout and --max-time can be used to put an
overall timeout on the connection phase or the entire transfer.
A libcurl-using application running in a known physical environment (e.g.
an embedded device with only a single network connection) may want to act
immediately if its lone network connection goes down. That can be achieved
by having the application monitor the network connection on its own using an
OS-specific mechanism, then signalling libcurl to abort (see also item 5.13).
5. libcurl Issues
@@ -1086,7 +1095,9 @@ FAQ
We have written the libcurl code specifically adjusted for multi-threaded
programs. libcurl will use thread-safe functions instead of non-safe ones if
your system has such.
your system has such. Note that you must never share the same handle in
multiple threads.
If you use a OpenSSL-powered libcurl in a multi-threaded environment, you
need to provide one or two locking functions:
@@ -1262,17 +1273,18 @@ FAQ
5.12 Can I make libcurl fake or hide my real IP address?
No. libcurl operates on a higher level than so. Besides, faking IP address
would imply sending IP packages with a made-up source address, and then you
normally get a problem with intercepting the packages sent back as they
would then not be routed to you!
No. libcurl operates on a higher level. Besides, faking IP address would
imply sending IP packet with a made-up source address, and then you normally
get a problem with receiving the packet sent back as they would then not be
routed to you!
If you use a proxy to access remote sites, the sites will not see your local
IP address but instead the address of the proxy.
Also note that on many networks NATs or other IP-munging techniques are used
that makes you see and use a different IP address locally than what the
remote server will see you coming from.
remote server will see you coming from. You may also consider using
http://www.torproject.org .
5.13 How do I stop an ongoing transfer?

View File

@@ -7,19 +7,19 @@
How cURL Became Like This
In the second half of 1997, Daniel Stenberg came up with the idea to make
Towards the end of 1996, Daniel Stenberg came up with the idea to make
currency-exchange calculations available to Internet Relay Chat (IRC)
users. All the necessary data are published on the Web; he just needed to
automate their retrieval.
Daniel simply adopted an existing command-line open-source tool, httpget, that
Brazilian Rafael Sagula had written. After a few minor adjustments, it did
just what he needed.
Brazilian Rafael Sagula had written and recently release version 0.1 of. After
a few minor adjustments, it did just what he needed. HttpGet 1.0 was released
on April 8th 1997 with brand new HTTP proxy support.
Soon, he found currencies on a GOPHER site, so support for that had to go in,
and not before long FTP download support was added as well. The name of the
project was changed to urlget to better fit what it actually did now, since
the http-only days were already passed.
We soon found and fixed support for getting currencies over GOPHER. Once FTP
download support was added, the name of the project was changed and urlget 2.0
was released in August 1997. The http-only days were already passed.
The project slowly grew bigger. When upload capabilities were added and the
name once again was misleading, a second name change was made and on March 20,

View File

@@ -220,7 +220,7 @@ Win32
adjust as necessary. It is also possible to override these paths with
environment variables, for example:
set ZLIB_PATH=c:\zlib-1.2.7
set ZLIB_PATH=c:\zlib-1.2.8
set OPENSSL_PATH=c:\openssl-0.9.8y
set LIBSSH2_PATH=c:\libssh2-1.4.3
@@ -323,7 +323,7 @@ Win32
documentation on how to compile zlib. Define the ZLIB_PATH environment
variable to the location of zlib.h and zlib.lib, for example:
set ZLIB_PATH=c:\zlib-1.2.7
set ZLIB_PATH=c:\zlib-1.2.8
Then run 'nmake vc-zlib' in curl's root directory.
@@ -1045,7 +1045,7 @@ PORTS
- Alpha OpenVMS V7.1-1H2
- Alpha Tru64 v5.0 5.1
- AVR32 Linux
- ARM Android 1.5, 2.1
- ARM Android 1.5, 2.1, 2.3, 3.2, 4.x
- ARM INTEGRITY
- ARM iOS
- Cell Linux
@@ -1116,6 +1116,7 @@ GNU GSS http://www.gnu.org/software/gss/
GnuTLS http://www.gnu.org/software/gnutls/
Heimdal http://www.pdc.kth.se/heimdal/
libidn http://www.gnu.org/software/libidn/
libmetalink https://launchpad.net/libmetalink/
libssh2 http://www.libssh2.org/
MIT Kerberos http://web.mit.edu/kerberos/www/dist/
NSS http://www.mozilla.org/projects/security/pki/nss/

View File

@@ -111,6 +111,9 @@ Windows vs Unix
Library
=======
(See LIBCURL-STRUCTS for a separate document describing all major internal
structs and their purposes.)
There are plenty of entry points to the library, namely each publicly defined
function that libcurl offers to applications. All of those functions are
rather small and easy-to-follow. All the ones prefixed with 'curl_easy' are
@@ -135,16 +138,18 @@ Library
options is documented in the man page. This function mainly sets things in
the 'SessionHandle' struct.
curl_easy_perform() does a whole lot of things:
curl_easy_perform() is just a wrapper function that makes use of the multi
API. It basically curl_multi_init(), curl_multi_add_handle(),
curl_multi_wait(), and curl_multi_perform() until the transfer is done and
then returns.
It starts off in the lib/easy.c file by calling Curl_perform() and the main
work then continues in lib/url.c. The flow continues with a call to
Curl_connect() to connect to the remote site.
Some of the most important key functions in url.c are called from multi.c
when certain key steps are to be made in the transfer operation.
o Curl_connect()
... analyzes the URL, it separates the different components and connects to
the remote host. This may involve using a proxy and/or using SSL. The
Analyzes the URL, it separates the different components and connects to the
remote host. This may involve using a proxy and/or using SSL. The
Curl_resolv() function in lib/hostip.c is used for looking up host names
(it does then use the proper underlying method, which may vary between
platforms and builds).
@@ -160,10 +165,7 @@ Library
o Curl_do()
Curl_do() makes sure the proper protocol-specific function is called. The
functions are named after the protocols they handle. Curl_ftp(),
Curl_http(), Curl_dict(), etc. They all reside in their respective files
(ftp.c, http.c and dict.c). HTTPS is handled by Curl_http() and FTPS by
Curl_ftp().
functions are named after the protocols they handle.
The protocol-specific functions of course deal with protocol-specific
negotiations and setup. They have access to the Curl_sendf() (from
@@ -182,10 +184,9 @@ Library
be called with some basic info about the upcoming transfer: what socket(s)
to read/write and the expected file transfer sizes (if known).
o Transfer()
o Curl_readwrite()
Curl_perform() then calls Transfer() in lib/transfer.c that performs the
entire file transfer.
Called during the transfer of the actual protocol payload.
During transfer, the progress functions in lib/progress.c are called at a
frequent interval (or at the user's choice, a specified callback might get
@@ -207,33 +208,11 @@ Library
used. This function is only used when we are certain that no more transfers
is going to be made on the connection. It can be also closed by force, or
it can be called to make sure that libcurl doesn't keep too many
connections alive at the same time (there's a default amount of 5 but that
can be changed with the CURLOPT_MAXCONNECTS option).
connections alive at the same time.
This function cleans up all resources that are associated with a single
connection.
Curl_perform() is the function that does the main "connect - do - transfer -
done" loop. It loops if there's a Location: to follow.
When completed, the curl_easy_cleanup() should be called to free up used
resources. It runs Curl_disconnect() on all open connections.
A quick roundup on internal function sequences (many of these call
protocol-specific function-pointers):
Curl_connect - connects to a remote site and does initial connect fluff
This also checks for an existing connection to the requested site and uses
that one if it is possible.
Curl_do - starts a transfer
Curl_handler::do_it() - transfers data
Curl_done - ends a transfer
Curl_disconnect - disconnects from a remote site. This is called when the
disconnect is really requested, which doesn't necessarily have to be
exactly after curl_done in case we want to keep the connection open for
a while.
HTTP(S)
@@ -316,48 +295,38 @@ Persistent Connections
hold connection-oriented data. It is meant to hold the root data as well as
all the options etc that the library-user may choose.
o The 'SessionHandle' struct holds the "connection cache" (an array of
pointers to 'connectdata' structs). There's one connectdata struct
allocated for each connection that libcurl knows about. Note that when you
use the multi interface, the multi handle will hold the connection cache
and not the particular easy handle. This of course to allow all easy handles
in a multi stack to be able to share and re-use connections.
pointers to 'connectdata' structs).
o This enables the 'curl handle' to be reused on subsequent transfers.
o When we are about to perform a transfer with curl_easy_perform(), we first
check for an already existing connection in the cache that we can use,
otherwise we create a new one and add to the cache. If the cache is full
already when we add a new connection, we close one of the present ones. We
select which one to close dependent on the close policy that may have been
previously set.
o When the transfer operation is complete, we try to leave the connection
open. Particular options may tell us not to, and protocols may signal
closure on connections and then we don't keep it open of course.
o When libcurl is told to perform a transfer, it first checks for an already
existing connection in the cache that we can use. Otherwise it creates a
new one and adds that the cache. If the cache is full already when a new
conncetion is added added, it will first close the oldest unused one.
o When the transfer operation is complete, the connection is left
open. Particular options may tell libcurl not to, and protocols may signal
closure on connections and then they won't be kept open of course.
o When curl_easy_cleanup() is called, we close all still opened connections,
unless of course the multi interface "owns" the connections.
You do realize that the curl handle must be re-used in order for the
persistent connections to work.
The curl handle must be re-used in order for the persistent connections to
work.
multi interface/non-blocking
============================
We make an effort to provide a non-blocking interface to the library, the
multi interface. To make that interface work as good as possible, no
low-level functions within libcurl must be written to work in a blocking
manner.
The multi interface is a non-blocking interface to the library. To make that
interface work as good as possible, no low-level functions within libcurl
must be written to work in a blocking manner. (There are still a few spots
violating this rule.)
One of the primary reasons we introduced c-ares support was to allow the name
resolve phase to be perfectly non-blocking as well.
The ultimate goal is to provide the easy interface simply by wrapping the
multi interface functions and thus treat everything internally as the multi
interface is the single interface we have.
The FTP and the SFTP/SCP protocols are thus perfect examples of how we adapt
and adjust the code to allow non-blocking operations even on multi-stage
protocols. They are built around state machines that return when they could
block waiting for data. The DICT, LDAP and TELNET protocols are crappy
examples and they are subject for rewrite in the future to better fit the
libcurl protocol family.
The FTP and the SFTP/SCP protocols are examples of how we adapt and adjust
the code to allow non-blocking operations even on multi-stage command-
response protocols. They are built around state machines that return when
they would otherwise block waiting for data. The DICT, LDAP and TELNET
protocols are crappy examples and they are subject for rewrite in the future
to better fit the libcurl protocol family.
SSL libraries
=============
@@ -408,12 +377,12 @@ API/ABI
Client
======
main() resides in src/main.c together with most of the client code.
main() resides in src/tool_main.c.
src/tool_hugehelp.c is automatically generated by the mkhelp.pl perl script
to display the complete "manual" and the src/urlglob.c file holds the
functions used for the URL-"globbing" support. Globbing in the sense that
the {} and [] expansion stuff is there.
to display the complete "manual" and the src/tool_urlglob.c file holds the
functions used for the URL-"globbing" support. Globbing in the sense that the
{} and [] expansion stuff is there.
The client mostly messes around to setup its 'config' struct properly, then
it calls the curl_easy_*() functions of the library and when it gets back
@@ -425,8 +394,8 @@ Client
curl_easy_getinfo() function to extract useful information from the curl
session.
Recent versions may loop and do all this several times if many URLs were
specified on the command line or config file.
It may loop and do all this several times if many URLs were specified on the
command line or config file.
Memory Debugging
================

View File

@@ -3,20 +3,42 @@ join in and help us correct one or more of these! Also be sure to check the
changelog of the current development status, as one or more of these problems
may have been fixed since this was written!
84. CURLINFO_SSL_VERIFYRESULT is only implemented for the OpenSSL and NSS
backends, so relying on this information in a generic app is flaky.
83. curl is unable to load non-default openssl engines, because openssl isn't
initialized properly. This seems to require OpenSSL_config() or
CONF_modules_load_file() to be used by libcurl but the first seems to not
work and we've gotten not reports from tests with the latter. Possibly we
need to discuss with OpenSSL developers how this is supposed to be done. We
need users with actual external openssl engines for testing to work on this.
http://curl.haxx.se/bug/view.cgi?id=1208
82. When building with the Windows Borland compiler, it fails because the
"tlib" tool doesn't support hyphens (minus signs) in file names and we have
such in the build.
http://curl.haxx.se/bug/view.cgi?id=1222
81. When using -J (with -O), automaticly resumed downloading together with "-C
-" fails. Without -J the same command line works! This happens because the
resume logic is worked out before the target file name (and thus its
pre-transfer size) has been figured out!
http://curl.haxx.se/bug/view.cgi?id=1169
80. Curl doesn't recognize certificates in DER format in keychain, but it
works with PEM.
http://curl.haxx.se/bug/view.cgi?id=3439999
http://curl.haxx.se/bug/view.cgi?id=1065
79. SMTP. When sending data to multiple recipients, curl will abort and return
failure if one of the recipients indicate failure (on the "RCPT TO"
command). Ordinary mail programs would proceed and still send to the ones
that can receive data. This is subject for change in the future.
http://curl.haxx.se/bug/view.cgi?id=3438362
http://curl.haxx.se/bug/view.cgi?id=1116
78. curl and libcurl don't always signal the client properly when "sending"
zero bytes files - it makes for example the command line client not creating
any file at all. Like when using FTP.
http://curl.haxx.se/bug/view.cgi?id=3438362
http://curl.haxx.se/bug/view.cgi?id=1063
77. CURLOPT_FORBID_REUSE on a handle prevents NTLM from working since it
"abuses" the underlying connection re-use system and if connections are
@@ -31,7 +53,7 @@ may have been fixed since this was written!
properly if built with UNICODE defined together with the schannel/winssl
backend. The original problem was mentioned in:
http://curl.haxx.se/mail/lib-2009-10/0024.html
http://curl.haxx.se/bug/view.cgi?id=2944325
http://curl.haxx.se/bug/view.cgi?id=896
The schannel version verified to work as mentioned in
http://curl.haxx.se/mail/lib-2012-07/0073.html
@@ -41,7 +63,7 @@ may have been fixed since this was written!
acknowledge the connection timeout during that phase but only the "real"
timeout - which may surprise users as it is probably considered to be the
connect phase to most people. Brought up (and is being misunderstood) in:
http://curl.haxx.se/bug/view.cgi?id=2844077
http://curl.haxx.se/bug/view.cgi?id=856
72. "Pausing pipeline problems."
http://curl.haxx.se/mail/lib-2009-07/0214.html
@@ -59,7 +81,7 @@ may have been fixed since this was written!
http://tools.ietf.org/html/draft-reschke-rfc2231-in-http-02
66. When using telnet, the time limitation options don't work.
http://curl.haxx.se/bug/view.cgi?id=2818950
http://curl.haxx.se/bug/view.cgi?id=846
65. When doing FTP over a socks proxy or CONNECT through HTTP proxy and the
multi interface is used, libcurl will fail if the (passive) TCP connection
@@ -85,19 +107,12 @@ may have been fixed since this was written!
CURLOPT_FAILONERROR with FTP to detect if a file exists or not, but it is
not working: http://curl.haxx.se/mail/lib-2008-07/0295.html
57. On VMS-Alpha: When using an http-file-upload the file is not sent to the
Server with the correct content-length. Sending a file with 511 or less
bytes, content-length 512 is used. Sending a file with 513 - 1023 bytes,
content-length 1024 is used. Files with a length of a multiple of 512 Bytes
show the correct content-length. Only these files work for upload.
http://curl.haxx.se/bug/view.cgi?id=2057858
56. When libcurl sends CURLOPT_POSTQUOTE commands when connected to a SFTP
server using the multi interface, the commands are not being sent correctly
and instead the connection is "cancelled" (the operation is considered done)
prematurely. There is a half-baked (busy-looping) patch provided in the bug
report but it cannot be accepted as-is. See
http://curl.haxx.se/bug/view.cgi?id=2006544
http://curl.haxx.se/bug/view.cgi?id=748
55. libcurl fails to build with MIT Kerberos for Windows (KfW) due to KfW's
library header files exporting symbols/macros that should be kept private
@@ -121,12 +136,12 @@ may have been fixed since this was written!
protocol code. This should be very rare.
43. There seems to be a problem when connecting to the Microsoft telnet server.
http://curl.haxx.se/bug/view.cgi?id=1720605
http://curl.haxx.se/bug/view.cgi?id=649
41. When doing an operation over FTP that requires the ACCT command (but not
when logging in), the operation will fail since libcurl doesn't detect this
and thus fails to issue the correct command:
http://curl.haxx.se/bug/view.cgi?id=1693337
http://curl.haxx.se/bug/view.cgi?id=635
39. Steffen Rumler's Race Condition in Curl_proxyCONNECT:
http://curl.haxx.se/mail/lib-2007-01/0045.html
@@ -139,7 +154,7 @@ may have been fixed since this was written!
34. The SOCKS4 connection codes don't properly acknowledge (connect) timeouts.
Also see #12. According to bug #1556528, even the SOCKS5 connect code does
not do it right: http://curl.haxx.se/bug/view.cgi?id=1556528,
not do it right: http://curl.haxx.se/bug/view.cgi?id=604
31. "curl-config --libs" will include details set in LDFLAGS when configure is
run that might be needed only for building libcurl. Further, curl-config
@@ -154,13 +169,12 @@ may have been fixed since this was written!
IDs in URLs to get around the problem of percent signs being
special. According to the reporter, Firefox deals with the URL _with_ a
percent letter (which seems like a blatant URL spec violation).
libcurl supports zone IDs where the percent sign is URL-escaped (i.e. %25).
See http://curl.haxx.se/bug/view.cgi?id=1371118
libcurl supports zone IDs where the percent sign is URL-escaped (i.e. %25):
http://curl.haxx.se/bug/view.cgi?id=555
26. NTLM authentication using SSPI (on Windows) when (lib)curl is running in
"system context" will make it use wrong(?) user name - at least when compared
to what winhttp does. See http://curl.haxx.se/bug/view.cgi?id=1281867
to what winhttp does. See http://curl.haxx.se/bug/view.cgi?id=535
23. SOCKS-related problems:
B) libcurl doesn't support FTPS over a SOCKS proxy.
@@ -169,12 +183,6 @@ may have been fixed since this was written!
We probably have even more bugs and lack of features when a SOCKS proxy is
used.
22. Sending files to a FTP server using curl on VMS, might lead to curl
complaining on "unaligned file size" on completion. The problem is related
to VMS file structures and the perceived file sizes stat() returns. A
possible fix would involve sending a "STRU VMS" command.
http://curl.haxx.se/bug/view.cgi?id=1156287
21. FTP ASCII transfers do not follow RFC959. They don't convert the data
accordingly (not for sending nor for receiving). RFC 959 section 3.1.1.1
clearly describes how this should be done:
@@ -212,7 +220,7 @@ may have been fixed since this was written!
10. To get HTTP Negotiate authentication to work fine, you need to provide a
(fake) user name (this concerns both curl and the lib) because the code
wrongly only considers authentication if there's a user name provided.
http://curl.haxx.se/bug/view.cgi?id=1004841. How?
http://curl.haxx.se/bug/view.cgi?id=440 How?
http://curl.haxx.se/mail/lib-2004-08/0182.html
8. Doing resumed upload over HTTP does not work with '-C -', because curl

245
docs/LIBCURL-STRUCTS Normal file
View File

@@ -0,0 +1,245 @@
_ _ ____ _
___| | | | _ \| |
/ __| | | | |_) | |
| (__| |_| | _ <| |___
\___|\___/|_| \_\_____|
Structs in libcurl
This document should cover 7.32.0 pretty accurately, but will make sense even
for older and later versions as things don't change drastically that often.
1. The main structs in libcurl
1.1 SessionHandle
1.2 connectdata
1.3 Curl_multi
1.4 Curl_handler
1.5 conncache
1.6 Curl_share
1.7 CookieInfo
==============================================================================
1. The main structs in libcurl
1.1 SessionHandle
The SessionHandle handle struct is the one returned to the outside in the
external API as a "CURL *". This is usually known as an easy handle in API
documentations and examples.
Information and state that is related to the actual connection is in the
'connectdata' struct. When a transfer is about to be made, libcurl will
either create a new connection or re-use an existing one. The particular
connectdata that is used by this handle is pointed out by
SessionHandle->easy_conn.
Data and information that regard this particular single transfer is put in
the SingleRequest sub-struct.
When the SessionHandle struct is added to a multi handle, as it must be in
order to do any transfer, the ->multi member will point to the Curl_multi
struct it belongs to. The ->prev and ->next members will then be used by the
multi code to keep a linked list of SessionHandle structs that are added to
that same multi handle. libcurl always uses multi so ->multi *will* point to
a Curl_multi when a transfer is in progress.
->mstate is the multi state of this particular SessionHandle. When
multi_runsingle() is called, it will act on this handle according to which
state it is in. The mstate is also what tells which sockets to return for a
speicific SessionHandle when curl_multi_fdset() is called etc.
The libcurl source code generally use the name 'data' for the variable that
points to the SessionHandle.
1.2 connectdata
A general idea in libcurl is to keep connections around in a connection
"cache" after they have been used in case they will be used again and then
re-use an existing one instead of creating a new as it creates a significant
performance boost.
Each 'connectdata' identifies a single physical conncetion to a server. If
the connection can't be kept alive, the connection will be closed after use
and then this struct can be removed from the cache and freed.
Thus, the same SessionHandle can be used multiple times and each time select
another connectdata struct to use for the connection. Keep this in mind, as
it is then important to consider if options or choices are based on the
connection or the SessionHandle.
Functions in libcurl will assume that connectdata->data points to the
SessionHandle that uses this connection.
As a special complexity, some protocols supported by libcurl require a
special disconnect procedure that is more than just shutting down the
socket. It can involve sending one or more commands to the server before
doing so. Since connections are kept in the connection cache after use, the
original SessionHandle may no longer be around when the time comes to shut
down a particular connection. For this purpose, libcurl holds a special
dummy 'closure_handle' SessionHandle in the Curl_multi struct to
FTP uses two TCP connections for a typical transfer but it keeps both in
this single struct and thus can be considered a single connection for most
internal concerns.
The libcurl source code generally use the name 'conn' for the variable that
points to the connectdata.
1.3 Curl_multi
Internally, the easy interface is implemented as a wrapper around multi
interface functions. This makes everything multi interface.
Curl_multi is the multi handle struct exposed as "CURLM *" in external APIs.
This struct holds a list of SessionHandle structs that have been added to
this handle with curl_multi_add_handle(). The start of the list is ->easyp
and ->num_easy is a counter of added SessionHandles.
->msglist is a linked list of messages to send back when
curl_multi_info_read() is called. Basically a node is added to that list
when an individual SessionHandle's transfer has completed.
->hostcache points to the name cache. It is a hash table for looking up name
to IP. The nodes have a limited life time in there and this cache is meant
to reduce the time for when the same name is wanted within a short period of
time.
->timetree points to a tree of SessionHandles, sorted by the remaining time
until it should be checked - normally some sort of timeout. Each
SessionHandle has one node in the tree.
->sockhash is a hash table to allow fast lookups of socket descriptor to
which SessionHandle that uses that descriptor. This is necessary for the
multi_socket API.
->conn_cache points to the connection cache. It keeps track of all
connections that are kept after use. The cache has a maximum size.
->closure_handle is described in the 'connectdata' section.
The libcurl source code generally use the name 'multi' for the variable that
points to the Curl_multi struct.
1.4 Curl_handler
Each unique protocol that is supported by libcurl needs to provide at least
one Curl_handler struct. It defines what the protocol is called and what
functions the main code should call to deal with protocol specific issues.
In general, there's a source file named [protocol].c in which there's a
"struct Curl_handler Curl_handler_[protocol]" declared. In url.c there's
then the main array with all individual Curl_handler structs pointed to from
a single array which is scanned through when a URL is given to libcurl to
work with.
->scheme is the URL scheme name, usually spelled out in uppercase. That's
"HTTP" or "FTP" etc. SSL versions of the protcol need its own Curl_handler
setup so HTTPS separate from HTTP.
->setup_connection is called to allow the protocol code to allocate protocol
specific data that then gets associated with that SessionHandle for the rest
of this transfer. It gets freed again at the end of the transfer. It will be
called before the 'connectdata' for the transfer has been selected/created.
Most protocols will allocate its private 'struct [PROTOCOL]' here and assign
SessionHandle->req.protop to point to it.
->connect_it allows a protocol to do some specific actions after the TCP
connect is done, that can still be considered part of the connection phase.
Some protocols will alter the connectdata->recv[] and connectdata->send[]
function pointers in this function.
->connecting is similarly a function that keeps getting called as long as the
protocol considers itself still in the connecting phase.
->do_it is the function called to issue the transfer request. What we call
the DO action internally. If the DO is not enough and things need to be kept
getting done for the entier DO sequence to complete, ->doing is then usually
also provided. Each protocol that needs to do multiple commands or similar
for do/doing need to implement their own state machines (see SCP, SFTP,
FTP). Some protocols (only FTP and only due to historical reasons) has a
separate piece of the DO state called DO_MORE.
->doing keeps getting called while issudeing the transfer request command(s)
->done gets called when the transfer is complete and DONE. That's after the
main data has been transferred.
->do_more gets called doring the DO_MORE state. The FTP protocol uses this
state when setting up the second connection.
->proto_getsock
->doing_getsock
->domore_getsock
->perform_getsock
Functions that return socket information. Which socket(s) to wait for which
action(s) during the particular multi state.
->disconnect is called immediately before the TCP connection is shutdown.
->readwrite gets called during transfer to allow the protocol to do extra
reads/writes
->defport is the default report TCP or UDP port this protocol uses
->protocol is one or more bits in the CURLPROTO_* set. The SSL versions have
their "base" protocol set and then the SSL variation. Like "HTTP|HTTPS".
->flags is a bitmask with additional information about the protocol that will
make it get treated differently by the generic engine:
PROTOPT_SSL - will make it connect and negotiate SSL
PROTOPT_DUAL - this protocol uses two connections
PROTOPT_CLOSEACTION - this protocol has actions to do before closing the
connection. This flag is no longer used by code, yet still set for a bunch
protocol handlers.
PROTOPT_DIRLOCK - "direction lock". The SSH protocols set this bit to
limit which "direction" of socket actions that the main engine will
concern itself about.
PROTOPT_NONETWORK - a protocol that doesn't use network (read file:)
PROTOPT_NEEDSPWD - this protocol needs a password and will use a default
one unless one is provided
PROTOPT_NOURLQUERY - this protocol can't handle a query part on the URL
(?foo=bar)
1.5 conncache
Is a hash table with connections for later re-use. Each SessionHandle has
a pointer to its connection cache. Each multi handle sets up a connection
cache that all added SessionHandles share by default.
1.6 Curl_share
The libcurl share API allocates a Curl_share struct, exposed to the external
API as "CURLSH *".
The idea is that the struct can have a set of own versions of caches and
pools and then by providing this struct in the CURLOPT_SHARE option, those
specific SessionHandles will use the caches/pools that this share handle
holds.
Then individual SessionHandle structs can be made to share specific things
that they otherwise wouldn't, such as cookies.
The Curl_share struct can currently hold cookies, DNS cache and the SSL
session cache.
1.7 CookieInfo
This is the main cookie struct. It holds all known cookies and related
information. Each SessionHandle has its own private CookieInfo even when
they are added to a multi handle. They can be made to share cookies by using
the share API.

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
# Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -22,7 +22,8 @@
AUTOMAKE_OPTIONS = foreign no-dependencies
man_MANS = curl.1 curl-config.1 mk-ca-bundle.1
man_MANS = curl.1 curl-config.1
noinst_man_MANS = mk-ca-bundle.1
GENHTMLPAGES = curl.html curl-config.html mk-ca-bundle.html
PDFPAGES = curl.pdf curl-config.pdf mk-ca-bundle.pdf
@@ -36,7 +37,7 @@ EXTRA_DIST = MANUAL BUGS CONTRIBUTE FAQ FEATURES INTERNALS SSLCERTS \
README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS VERSIONS \
KNOWN_BUGS BINDINGS $(man_MANS) $(HTMLPAGES) HISTORY INSTALL \
$(PDFPAGES) LICENSE-MIXING README.netware DISTRO-DILEMMA INSTALL.devcpp \
MAIL-ETIQUETTE HTTP-COOKIES
MAIL-ETIQUETTE HTTP-COOKIES LIBCURL-STRUCTS
MAN2HTML= roffit < $< >$@

View File

@@ -13,14 +13,15 @@ Adam Tkac
Adrian Schuur
Adriano Meirelles
Ajit Dhumale
Aki Koskinen
Akos Pasztory
Alan Pinstein
Albert Chin
Albert Chin-A-Young
Albert Choy
Ale Vesely
Alejandro Alvarez
Aleksandar Milivojevic
Aleksey Tulinov
Alessandro Ghedini
Alessandro Vesely
Alex Bligh
@@ -31,6 +32,7 @@ Alex Suykov
Alex Vinnik
Alex aka WindEagle
Alexander Beedie
Alexander Klauer
Alexander Kourakos
Alexander Krasnostavsky
Alexander Lazic
@@ -46,11 +48,13 @@ Amol Pattekar
Amr Shahin
Anatoli Tubman
Anders Gustafsson
Anders Havn
Andi Jahja
Andre Guibert de Bruet
Andreas Damm
Andreas Faerber
Andreas Farber
Andreas Malzahn
Andreas Ntaflos
Andreas Olsson
Andreas Rieke
@@ -64,9 +68,11 @@ Andrew Biggs
Andrew Bushnell
Andrew Francis
Andrew Fuller
Andrew Kurushin
Andrew Moise
Andrew Wansink
Andrew de los Reyes
Andrii Moiseiev
Andrés García
Andy Cedilnik
Andy Serpa
@@ -101,12 +107,14 @@ Ben Van Hof
Ben Winslow
Benbuck Nason
Benjamin Gerard
Benjamin Gilbert
Benjamin Johnson
Bernard Leak
Bernhard Reutner-Fischer
Bertrand Demiddelaer
Bill Egert
Bill Hoffman
Bill Middlecamp
Bjoern Sikora
Bjorn Augustsson
Bjorn Reese
@@ -133,6 +141,7 @@ Bruce Mitchener
Bruno de Carvalho
Bryan Henderson
Bryan Kemp
Byrial Jensen
Cameron Kaiser
Camille Moncelier
Caolan McNamara
@@ -153,13 +162,13 @@ Chris Maltby
Chris Mumford
Chris Smowton
Christian Grothoff
Christian Hagele
Christian Hägele
Christian Krause
Christian Kurz
Christian Robottom Reis
Christian Schmitz
Christian Vogt
Christian Weisgerber
Christophe Demory
Christophe Legry
Christopher Conroy
@@ -169,6 +178,7 @@ Christopher Stone
Ciprian Badescu
Claes Jakobsson
Clarence Gardner
Clemens Gruber
Clifford Wolf
Cody Jones
Colin Hogben
@@ -180,10 +190,10 @@ Craig A West
Craig Davison
Craig Markwardt
Cris Bailiff
Cristian Rodriguez
Cristian Rodríguez
Curt Bogmine
Cyrill Osterwalder
Cédric Deltheil
Dag Ekengren
Dagobert Michelsen
Damien Adant
@@ -231,6 +241,7 @@ David Odin
David Phillips
David Rosenstrauch
David Shaw
David Strauss
David Tarendash
David Thiel
David Wright
@@ -263,6 +274,7 @@ Douglas R. Horner
Douglas Steinwand
Dov Murik
Duane Cathey
Duncan
Duncan Mac-Vicar Prett
Dustin Boswell
Dylan Ellicott
@@ -271,6 +283,7 @@ Early Ehlinger
Ebenezer Ikonne
Edin Kadribasic
Eduard Bloch
Edward Rudd
Edward Sheldrake
Eelco Dolstra
Eetu Ojanen
@@ -288,15 +301,18 @@ Eric Lavigne
Eric Melville
Eric Mertens
Eric Rautman
Eric S. Raymond
Eric Thelin
Eric Vergnaud
Eric Wong
Eric Young
Erick Nuwendam
Erik Johansson
Erwan Legrand
Erwin Authried
Eugene Kotlyarov
Evan Jordan
Evgeny Turnaev
Eygene Ryabinkin
Fabian Hiernaux
Fabian Keil
@@ -317,6 +333,7 @@ Fred Machado
Fred New
Fred Noz
Frederic Lepied
Fredrik Thulin
Gabriel Kuri
Gabriel Sjoberg
Garrett Holmstrom
@@ -360,6 +377,7 @@ Gwenole Beauchesne
Götz Babin-Ebell
Hamish Mackenzie
Hang Kin Lau
Hang Su
Hanno Kranzhoff
Hans Steegers
Hans-Jurgen May
@@ -394,6 +412,7 @@ Immanuel Gregoire
Ingmar Runge
Ingo Ralf Blum
Ingo Wilken
Ishan SinghLevett
Jack Zhang
Jacky Lam
Jacob Meuser
@@ -415,6 +434,7 @@ Jan Koen Annot
Jan Kunder
Jan Schaumann
Jan Van Boghout
Jared Jennings
Jared Lundell
Jari Sundell
Jason Glasgow
@@ -429,6 +449,7 @@ Jean-Claude Chauve
Jean-Francois Bertrand
Jean-Louis Lemaire
Jean-Marc Ranger
Jean-Noel Rouvignac
Jean-Philippe Barrette-LaPierre
Jeff Connelly
Jeff Johnson
@@ -438,6 +459,7 @@ Jeff Pohlmeyer
Jeff Weber
Jeffrey Pohlmeyer
Jeremy Friesner
Jeremy Huddleston
Jerome Muffat-Meridol
Jerome Vouillon
Jerry Wu
@@ -449,8 +471,8 @@ Jim Drash
Jim Freeman
Jim Hollinger
Jim Meyering
Jiri Jaburek
Jiri Hruska
Jiri Jaburek
Jocelyn Jaubert
Joe Halpin
Joe Malicki
@@ -465,6 +487,7 @@ John Bradshaw
John Crow
John Dennis
John E. Malmberg
John Gardiner Myers
John Janssen
John Joseph Bachir
John Kelly
@@ -506,6 +529,7 @@ Julien Royer
Jun-ichiro itojun Hagino
Jurij Smakov
Justin Fletcher
Justin Karneges
Jörg Mueller-Tolk
Jörn Hartroth
Kai Engert
@@ -534,10 +558,12 @@ Kevin Lussier
Kevin Reed
Kevin Roth
Kim Rinnewitz
Kim Vandry
Kimmo Kinnunen
Kjell Ericson
Kjetil Jacobsen
Klevtsov Vadim
Konstantin Isakov
Kris Kennaway
Krishnendu Majumdar
Krister Johansen
@@ -550,6 +576,7 @@ Larry Fahnoe
Lars Buitinck
Lars Gustafsson
Lars J. Aas
Lars Johannesen
Lars Nilsson
Lars Torben Wilson
Lau Hang Kin
@@ -572,6 +599,7 @@ Loren Kirkby
Luca Altea
Luca Alteas
Lucas Adamski
Ludovico Cavedon
Lukasz Czekierda
Luke Amery
Luke Call
@@ -583,6 +611,7 @@ Mandy Wu
Manfred Schwarb
Manuel Massing
Marc Boucher
Marc Doughty
Marc Hoersken
Marc Kleine-Budde
Marcel Raad
@@ -614,6 +643,7 @@ Martin C. Martin
Martin Drasar
Martin Hager
Martin Hedenfalk
Martin Jansen
Martin Lemke
Martin Skinner
Martin Storsjo
@@ -661,12 +691,14 @@ Michal Gorny
Michal Kowalczyk
Michal Marek
Michele Bini
Miguel Angel
Mihai Ionescu
Mikael Johansson
Mikael Sennerholm
Mike Bytnar
Mike Crowe
Mike Dobbs
Mike Giancola
Mike Hommey
Mike Power
Mike Protts
@@ -676,6 +708,8 @@ Mitz Wark
Mohamed Lrhazi
Mohun Biswas
Moonesamy
Myk Taylor
Nach M. S.
Nathan Coulter
Nathan O'Sullivan
Nathanael Nerode
@@ -709,6 +743,7 @@ Ofer
Olaf Flebbe
Olaf Stueben
Olaf Stüben
Oliver Gondža
Olivier Berger
Oren Tirosh
Ori Avtalion
@@ -720,6 +755,7 @@ Pascal Terjan
Pasha Kuznetsov
Pat Ray
Patrice Guerin
Patricia Muscalu
Patrick Bihan-Faou
Patrick Monnerat
Patrick Scott
@@ -742,6 +778,7 @@ Pedro Neves
Pete Su
Peter Bray
Peter Forret
Peter Gal
Peter Heuchert
Peter Hjalmarsson
Peter Korsgaard
@@ -779,6 +816,7 @@ Quinn Slack
Rafa Muyo
Rafael Sagula
Rainer Canavan
Rainer Jung
Rainer Koenig
Rajesh Naganathan
Ralf S. Engelschall
@@ -793,6 +831,7 @@ Reinout van Schouwen
Renato Botelho
Renaud Chaillat
Renaud Duhaut
Renaud Guillard
Rene Bernhardt
Rene Rebe
Reuven Wachtfogel
@@ -806,6 +845,7 @@ Richard Bramante
Richard Clayton
Richard Cooper
Richard Gorton
Richard Michael
Richard Prescott
Richard Silverman
Rick Jones
@@ -822,6 +862,7 @@ Robert Iakobashvili
Robert Olson
Robert Schumann
Robert Weaver
Robert Wruck
Robin Cornelius
Robin Johnson
Robin Kay
@@ -846,6 +887,7 @@ Ryan Schmidt
S. Moonesamy
Salvador Dávila
Salvatore Sorrentino
Sam Deane
Sam Listopad
Sampo Kellomaki
Samuel Díaz García
@@ -856,6 +898,7 @@ Sandor Feldi
Santhana Todatry
Saqib Ali
Sara Golemon
Saran Neti
Saul good
Scott Bailey
Scott Barrett
@@ -888,6 +931,7 @@ Stan van de Burgt
Stanislav Ivochkin
Stefan Esser
Stefan Krause
Stefan Neis
Stefan Teleman
Stefan Tomanek
Stefan Ulrich
@@ -906,6 +950,7 @@ Steve Oliphant
Steve Roskowski
Steven Bazyl
Steven G. Johnson
Steven Gu
Steven M. Schweda
Steven Parkes
Stoned Elipot
@@ -934,6 +979,7 @@ Tim Harder
Tim Heckman
Tim Newsome
Tim Sneddon
Timo Sirainen
Tinus van den Berg
Tobias Rundström
Toby Peterson
@@ -943,6 +989,7 @@ Todd Ouska
Todd Vierling
Tom Benoist
Tom Donovan
Tom Grace
Tom Lee
Tom Mattison
Tom Moers
@@ -994,9 +1041,12 @@ Wesley Laxton
Wesley Miaw
Wez Furlong
Wilfredo Sanchez
Willem Sparreboom
Wojciech Zwiefka
Wouter Van Rooy
Wu Yongzheng
Xavier Bouchoux
Yamada Yasuharu
Yang Tse
Yarram Sunil
Yehoshua Hershberg
@@ -1004,6 +1054,8 @@ Yukihiro Kawada
Yuriy Sosov
Yves Arrouye
Yves Lejeune
Zdenek Pavlas
Zekun Ni
Zmey Petroff
Zvi Har'El
nk

133
docs/TODO
View File

@@ -16,8 +16,8 @@
1.3 struct lifreq
1.4 signal-based resolver timeouts
1.5 get rid of PATH_MAX
1.6 progress callback without doubles
1.7 Happy Eyeball dual stack connect
1.6 Happy Eyeball dual stack connect
1.7 Modified buffer size approach
2. libcurl - multi interface
2.1 More non-blocking
@@ -38,6 +38,7 @@
5.1 Better persistency for HTTP 1.0
5.2 support FF3 sqlite cookie files
5.3 Rearrange request header order
5.4 HTTP2/SPDY
6. TELNET
6.1 ditch stdin
@@ -46,19 +47,18 @@
6.4 send data in chunks
7. SMTP
7.1 Specify the preferred authentication mechanism
7.2 Initial response
7.3 Pipelining
7.4 Graceful base64 decoding failure
7.1 Pipelining
7.2 Graceful base64 decoding failure
7.3 Enhanced capability support
8. POP3
8.1 auth= in URLs
8.2 Initial response
8.3 Graceful base64 decoding failure
8.1 Pipelining
8.2 Graceful base64 decoding failure
8.3 Enhanced capability support
9. IMAP
9.1 auth= in URLs
9.2 Graceful base64 decoding failure
9.1 Graceful base64 decoding failure
9.2 Enhanced capability support
10. LDAP
10.1 SASL based authentication mechanisms
@@ -157,16 +157,7 @@
we need libssh2 to properly tell us when we pass in a too small buffer and
its current API (as of libssh2 1.2.7) doesn't.
1.6 progress callback without doubles
The progress callback was introduced way back in the days and the choice to
use doubles in the arguments was possibly good at the time. Today the doubles
only confuse users and make the amounts less precise. We should introduce
another progress callback option that take precedence over the old one and
have both co-exist for a forseeable time until we can remove the double-using
one.
1.7 Happy Eyeball dual stack connect
1.6 Happy Eyeball dual stack connect
In order to make alternative technologies not suffer when transitioning, like
when introducing IPv6 as an alternative to IPv4 and there are more than one
@@ -178,6 +169,28 @@
http://tools.ietf.org/html/rfc6555
1.7 Modified buffer size approach
Current libcurl allocates a fixed 16K size buffer for download and an
additional 16K for upload. They are always unconditionally part of the easy
handle. If CRLF translations are requested, an additional 32K "scratch
buffer" is allocated. A total of 64K transfer buffers in the worst case.
First, while the handles are not actually in use these buffers could be freed
so that lingering handles just kept in queues or whatever waste less memory.
Secondly, SFTP is a protocol that needs to handle many ~30K blocks at once
since each need to be individually acked and therefore libssh2 must be
allowed to send (or receive) many separate ones in parallel to achieve high
transfer speeds. A current libcurl build with a 16K buffer makes that
impossible, but one with a 512K buffer will reach MUCH faster transfers. But
allocating 512K unconditionally for all buffers just in case they would like
to do fast SFTP transfers at some point is not a good solution either.
Dynamically allocate buffer size depending on protocol in use in combination
with freeing it after each individual transfer? Other suggestions?
2. libcurl - multi interface
2.1 More non-blocking
@@ -269,6 +282,25 @@
headers use a default value so only headers that need to be moved have to be
specified.
5.4 HTTP2/SPDY
The first drafts for HTTP2 have been published
(http://tools.ietf.org/html/draft-ietf-httpbis-http2-03) and is so far based
on SPDY (http://www.chromium.org/spdy) designs and experiences. Chances are
it will end up in that style. Chrome and Firefox already support SPDY and
lots of web services do.
It would make sense to implement SPDY support now and later transition into
or add HTTP2 support as well.
We should base or HTTP2/SPDY work on a 3rd party library for the protocol
fiddling. The Spindy library (http://spindly.haxx.se/) was an attempt to make
such a library with an API suitable for use by libcurl but that effort has
more or less stalled. spdylay (https://github.com/tatsuhiro-t/spdylay) may
be a better option, either used directly or wrapped with a more spindly-like
API.
6. TELNET
6.1 ditch stdin
@@ -295,65 +327,54 @@ to provide the data to send.
7. SMTP
7.1 Specify the preferred authentication mechanism
Add the ability to specify the preferred authentication mechanism or a list
of mechanisms that should be used. Not only that, but the order that is
returned by the server during the EHLO response should be honored by curl.
7.2 Initial response
Add the ability for the user to specify whether the initial response is
included in the AUTH command. Some email servers, such as Microsoft
Exchange, can work with either whilst others need to have the initial
response sent separately:
http://curl.haxx.se/mail/lib-2012-03/0114.html
7.3 Pipelining
7.1 Pipelining
Add support for pipelining emails.
7.4 Graceful base64 decoding failure
7.2 Graceful base64 decoding failure
Rather than shutting down the session and returning an error when the
decoding of a base64 encoded authentication response fails, we should
gracefully shutdown the authentication process by sending a * response to the
server as per RFC4954.
7.3 Enhanced capability support
Add the ability, for an application that uses libcurl, to obtain the list of
capabilities returned from the EHLO command.
8. POP3
8.1 auth= in URLs
8.1 Pipelining
Being able to specify the preferred authentication mechanism in the URL as
per RFC2384.
Add support for pipelining commands.
8.2 Initial response
Add the ability for the user to specify whether the initial response is
included in the AUTH command as per RFC5034.
8.3 Graceful base64 decoding failure
8.2 Graceful base64 decoding failure
Rather than shutting down the session and returning an error when the
decoding of a base64 encoded authentication response fails, we should
gracefully shutdown the authentication process by sending a * response to the
server as per RFC5034.
8.3 Enhanced capability support
Add the ability, for an application that uses libcurl, to obtain the list of
capabilities returned from the CAPA command.
9. IMAP
9.1 auth= in URLs
Being able to specify the preferred authentication mechanism in the URL as
per RFC5092.
9.2 Graceful base64 decoding failure
9.1 Graceful base64 decoding failure
Rather than shutting down the session and returning an error when the
decoding of a base64 encoded authentication response fails, we should
gracefully shutdown the authentication process by sending a * response to the
server as per RFC3501.
9.2 Enhanced capability support
Add the ability, for an application that uses libcurl, to obtain the list of
capabilities returned from the CAPABILITY command.
10. LDAP
10.1 SASL based authentication mechanisms
@@ -429,6 +450,12 @@ to provide the data to send.
keys and certs over DNS using DNSSEC as an alternative to the CA model.
http://www.rfc-editor.org/rfc/rfc6698.txt
An initial patch was posted by Suresh Krishnaswamy on March 7th 2013
(http://curl.haxx.se/mail/lib-2013-03/0075.html) but it was a too simple
approach. See Daniel's comments:
http://curl.haxx.se/mail/lib-2013-03/0103.html . libunbound may be the
correct library to base this development on.
13. GnuTLS
13.1 SSL engine stuff

View File

@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
@@ -103,6 +103,18 @@ any response data to the terminal.
If you prefer a progress "bar" instead of the regular meter, \fI-#\fP is your
friend.
.SH OPTIONS
Options start with one or two dashes. Many of the options require an addition
value next to it.
The short "single-dash" form of the options, -d for example, may be used with
or without a space between it and its value, although a space is a recommended
separator. The long "double-dash" form, --data for example, requires a space
between it and its value.
Short version options that don't need any additional values can be used
immediately next to each other, like for example you can specify all the
options -O, -L and -v at once as -OLv.
In general, all boolean options are enabled with --\fBoption\fP and yet again
disabled with --\fBno-\fPoption. That is, you use the exact same option name
but prefix it with "no-". However, in this list we mostly only list and show
@@ -113,8 +125,14 @@ same command line option.)
Make curl display progress as a simple progress bar instead of the standard,
more informational, meter.
.IP "-0, --http1.0"
(HTTP) Forces curl to issue its requests using HTTP 1.0 instead of using its
internally preferred: HTTP 1.1.
(HTTP) Tells curl to use HTTP version 1.0 instead of using its internally
preferred: HTTP 1.1.
.IP "--http1.1"
(HTTP) Tells curl to use HTTP version 1.1. This is the internal default
version. (Added in 7.33.0)
.IP "--http2.0"
(HTTP) Tells curl to issue its requests using HTTP 2.0. This requires that the
underlying libcurl was built to support it. (Added in 7.33.0)
.IP "-1, --tlsv1"
(SSL)
Forces curl to use TLS version 1 when negotiating with a remote TLS server.
@@ -230,7 +248,9 @@ server sends an unsupported encoding, curl will report an error.
.IP "--connect-timeout <seconds>"
Maximum time in seconds that you allow the connection to the server to take.
This only limits the connection phase, once curl has connected this option is
of no more use. See also the \fI-m, --max-time\fP option.
of no more use. Since 7.32.0, this option accepts decimal values, but the
actual timeout will decrease in accuracy as the specified timeout increases in
decimal precision. See also the \fI-m, --max-time\fP option.
If this option is used several times, the last one will be used.
.IP "--create-dirs"
@@ -270,7 +290,8 @@ If you start the data with the letter @, the rest should be a file name to
read the data from, or - if you want curl to read the data from stdin. The
contents of the file must already be URL-encoded. Multiple files can also be
specified. Posting data from a file named 'foobar' would thus be done with
\fI--data @foobar\fP.
\fI--data\fP @foobar. When --data is told to read from a file like that,
carriage returns and newlines will be stripped out.
.IP "-D, --dump-header <file>"
Write the protocol headers to the specified file.
@@ -292,7 +313,7 @@ whatsoever.
If you start the data with the letter @, the rest should be a filename. Data
is posted in a similar manner as \fI--data-ascii\fP does, except that newlines
are preserved and conversions are never done.
and carriage returns are preserved and conversions are never done.
If this option is used several times, the ones following the first will append
data as described in \fI-d, --data\fP.
@@ -367,6 +388,39 @@ is an alias for \fB--disable-epsv\fP.
Disabling EPSV only changes the passive behavior. If you want to switch to
active mode you need to use \fI-P, --ftp-port\fP.
.IP "--dns-interface <interface>"
Tell curl to send outgoing DNS requests through <interface>. This option
is a counterpart to \fI--interface\fP (which does not affect DNS). The
supplied string must be an interface name (not an address).
This option requires that libcurl was built with a resolver backend that
supports this operation. The c-ares backend is the only such one. (Added in
7.33.0)
.IP "--dns-ipv4-addr <ip-address>"
Tell curl to bind to <ip-address> when making IPv4 DNS requests, so that
the DNS requests originate from this address. The argument should be a
single IPv4 address.
This option requires that libcurl was built with a resolver backend that
supports this operation. The c-ares backend is the only such one. (Added in
7.33.0)
.IP "--dns-ipv6-addr <ip-address>"
Tell curl to bind to <ip-address> when making IPv6 DNS requests, so that
the DNS requests originate from this address. The argument should be a
single IPv6 address.
This option requires that libcurl was built with a resolver backend that
supports this operation. The c-ares backend is the only such one. (Added in
7.33.0)
.IP "--dns-servers <ip-address,ip-address>"
Set the list of DNS servers to be used instead of the system default.
The list of IP addresses should be separated with commas. Port numbers
may also optionally be given as \fI:<port-number>\fP after each IP
address.
This option requires that libcurl was built with a resolver backend that
supports this operation. The c-ares backend is the only such one. (Added in
7.33.0)
.IP "-e, --referer <URL>"
(HTTP) Sends the "Referer Page" information to the HTTP server. This can also
be set with the \fI-H, --header\fP flag of course. When used with
@@ -378,7 +432,8 @@ If this option is used several times, the last one will be used.
.IP "-E, --cert <certificate[:password]>"
(SSL) Tells curl to use the specified client certificate file when getting a
file with HTTPS, FTPS or another SSL-based protocol. The certificate must be
in PEM format. If the optional password isn't specified, it will be queried
in PKCS#12 format if using Secure Transport, or PEM format if using any other
engine. If the optional password isn't specified, it will be queried
for on the terminal. Note that this option assumes a \&"certificate" file that
is the private key and the private certificate concatenated! See \fI--cert\fP
and \fI--key\fP to specify them independently.
@@ -388,7 +443,16 @@ curl the nickname of the certificate to use within the NSS database defined
by the environment variable SSL_DIR (or by default /etc/pki/nssdb). If the
NSS PEM PKCS#11 module (libnsspem.so) is available then PEM files may be
loaded. If you want to use a file from the current directory, please precede
it with "./" prefix, in order to avoid confusion with a nickname.
it with "./" prefix, in order to avoid confusion with a nickname. If the
nickname contains ":", it needs to be preceded by "\\" so that it is not
recognized as password delimiter. If the nickname contains "\\", it needs to
be escaped as "\\\\" so that it is not recognized as an escape character.
(iOS and Mac OS X only) If curl is built against Secure Transport, then the
certificate string can either be the name of a certificate/private key in the
system or user keychain, or the path to a PKCS#12-encoded certificate and
private key. If you want to use a file from the current directory, please
precede it with "./" prefix, in order to avoid confusion with a nickname.
If this option is used several times, the last one will be used.
.IP "--engine <name>"
@@ -805,7 +869,10 @@ Basic authentication).
.IP "-m, --max-time <seconds>"
Maximum time in seconds that you allow the whole operation to take. This is
useful for preventing your batch jobs from hanging for hours due to slow
networks or links going down. See also the \fI--connect-timeout\fP option.
networks or links going down. Since 7.32.0, this option accepts decimal
values, but the actual timeout will decrease in accuracy as the specified
timeout increases in decimal precision. See also the \fI--connect-timeout\fP
option.
If this option is used several times, the last one will be used.
.IP "--mail-auth <address>"
@@ -987,6 +1054,14 @@ you want the file saved in a different directory, make sure you change current
working directory before you invoke curl with the \fB-O, --remote-name\fP flag!
You may use this option as many times as the number of URLs you have.
.IP "--oauth2-bearer"
(IMAP/POP3/SMTP) Specify the Bearer Token for OAUTH 2.0 server authentication.
The Bearer Token is used in conjuction with the user name which can be
specified as part of the \fI--url\fP or \fI-u, --user\fP options.
The Bearer Token and user name are formatted according to RFC 6750.
If this option is used several times, the last one will be used.
.IP "-p, --proxytunnel"
When an HTTP proxy is used (\fI-x, --proxy\fP), this option will cause non-HTTP
protocols to attempt to tunnel through the proxy instead of merely using it to
@@ -1038,6 +1113,13 @@ ubiquitous in web browsers, so curl does the conversion by default to maintain
consistency. However, a server may require a POST to remain a POST after such
a redirection. This option is meaningful only when using \fI-L, --location\fP
(Added in 7.19.1)
.IP "--post303"
(HTTP) Tells curl to respect RFC 2616/10.3.2 and not convert POST requests
into GET requests when following a 303 redirection. The non-RFC behaviour is
ubiquitous in web browsers, so curl does the conversion by default to maintain
consistency. However, a server may require a POST to remain a POST after such
a redirection. This option is meaningful only when using \fI-L, --location\fP
(Added in 7.26.0)
.IP "--proto <protocols>"
Tells curl to use the listed protocols for its initial retrieval. Protocols
are evaluated left to right, are comma separated, and are each a protocol
@@ -1272,8 +1354,12 @@ Set this option to zero to not timeout retries. (Added in 7.12.3)
If this option is used several times, the last one will be used.
.IP "-s, --silent"
Silent or quiet mode. Don't show progress meter or error messages. Makes
Curl mute.
Silent or quiet mode. Don't show progress meter or error messages. Makes Curl
mute. It will still output the data you ask for, potentially even to the
terminal/stdout unless you redirect it.
.IP "--sasl-ir"
Enable initial response in SASL authentication.
(Added in 7.31.0)
.IP "-S, --show-error"
When used with \fI-s\fP it makes curl show an error message if it fails.
.IP "--ssl"
@@ -1449,16 +1535,23 @@ If this option is used several times, the last one will be used.
.IP "--trace-time"
Prepends a time stamp to each trace or verbose line that curl displays.
(Added in 7.14.0)
.IP "-u, --user <user:password>"
Specify the user name and password to use for server authentication. Overrides
\fI-n, --netrc\fP and \fI--netrc-optional\fP.
.IP "-u, --user <user:password;options>"
Specify the user name, password and optional login options to use for server
authentication. Overrides \fI-n, --netrc\fP and \fI--netrc-optional\fP.
If you just give the user name (without entering a colon) curl will prompt for
a password.
If you simply specify the user name, with or without the login options, curl
will prompt for a password.
If you use an SSPI-enabled curl binary and do NTLM authentication, you can
force curl to pick up the user name and password from your environment by
simply specifying a single colon with this option: "-u :".
If you use an SSPI-enabled curl binary and perform NTLM authentication, you
can force curl to select the user name and password from your environment by
simply specifying a single colon with this option: "-u :" or by specfying the
login options on their own, for example "-u ;auth=NTLM".
You can use the optional login options part to specify protocol specific
options that may be used during authentication. At present only IMAP, POP3 and
SMTP support login options as part of the user login information. For more
information about the login options please see RFC 2384, RFC 5092 and IETF
draft draft-earhart-url-smtp-00.txt (Added in 7.31.0).
If this option is used several times, the last one will be used.
.IP "-U, --proxy-user <user:password>"
@@ -1619,8 +1712,16 @@ to follow location: headers.
If this option is used several times, the last one will be used.
.IP "-x, --proxy <[protocol://][user:password@]proxyhost[:port]>"
Use the specified HTTP proxy. If the port number is not specified, it is
assumed at port 1080.
Use the specified proxy.
The proxy string can be specified with a protocol:// prefix to specify
alternative proxy protocols. Use socks4://, socks4a://, socks5:// or
socks5h:// to request the specific SOCKS version to be used. No protocol
specified, http:// and all others will be treated as HTTP proxies. (The
protocol support was added in curl 7.21.7)
If the port number is not specified in the proxy string, it is assumed to be
1080.
This option overrides existing environment variables that set the proxy to
use. If there's an environment variable setting a proxy, you can set proxy to
@@ -1639,11 +1740,6 @@ The proxy host can be specified the exact same way as the proxy environment
variables, including the protocol prefix (http://) and the embedded user +
password.
From 7.21.7, the proxy string may be specified with a protocol:// prefix to
specify alternative proxy protocols. Use socks4://, socks4a://, socks5:// or
socks5h:// to request the specific SOCKS version to be used. No protocol
specified, http:// and all others will be treated as HTTP proxies.
If this option is used several times, the last one will be used.
.IP "-X, --request <command>"
(HTTP) Specifies a custom request method to use when communicating with the
@@ -1669,7 +1765,7 @@ If this option is used several times, the last one will be used.
.IP "--xattr"
When saving output to a file, this option tells curl to store certain file
metadata in extened file attributes. Currently, the URL is stored in the
metadata in extended file attributes. Currently, the URL is stored in the
xdg.origin.url attribute and, for HTTP, the content type is stored in
the mime_type attribute. If the file system does not support extended
attributes, a warning is issued.
@@ -1689,7 +1785,7 @@ speed-time seconds it gets aborted. speed-time is set with \fI-y\fP and is 30
if not set.
If this option is used several times, the last one will be used.
.IP "-z/--time-cond <date expression>|<file>"
.IP "-z, --time-cond <date expression>|<file>"
(HTTP/FTP) Request a file that has been modified later than the given time and
date, or one that has been modified before that time. The <date expression>
can be all sorts of date strings or if it doesn't match any internal ones, it

View File

@@ -43,3 +43,5 @@ simplessl
smtp-multi
smtp-tls
url2file
usercertinmem
xmlstream

View File

@@ -5,7 +5,7 @@ check_PROGRAMS = 10-at-a-time anyauthput cookie_interface debug fileupload \
persistant post-callback postit2 sepheaders simple simplepost simplessl \
sendrecv httpcustomheader certinfo chkspeed ftpgetinfo ftp-wildcard \
smtp-multi simplesmtp smtp-tls rtsp externalsocket resolve \
progressfunc pop3s pop3slist imap url2file sftpget ftpsget
progressfunc pop3s pop3slist imap url2file sftpget ftpsget postinmemory
# These examples require external dependencies that may not be commonly
# available on POSIX systems, so don't bother attempting to compile them here.
@@ -13,4 +13,4 @@ COMPLICATED_EXAMPLES = curlgtk.c curlx.c htmltitle.cpp cacertinmem.c \
ftpuploadresume.c ghiper.c hiperfifo.c htmltidy.c multithread.c \
opensslthreadlock.c sampleconv.c synctime.c threaded-ssl.c evhiperfifo.c \
smooth-gtk-thread.c version-check.pl href_extractor.c asiohiper.cpp \
multi-uv.c
multi-uv.c xmlstream.c usercertinmem.c

View File

@@ -27,14 +27,14 @@
## Example: mingw32-make -f Makefile.m32 CFG=-zlib-ssl-spi-winidn
##
## Hint: you can also set environment vars to control the build, f.e.:
## set ZLIB_PATH=c:/zlib-1.2.7
## set ZLIB_PATH=c:/zlib-1.2.8
## set ZLIB=1
#
###########################################################################
# Edit the path below to point to the base of your Zlib sources.
ifndef ZLIB_PATH
ZLIB_PATH = ../../../zlib-1.2.7
ZLIB_PATH = ../../../zlib-1.2.8
endif
# Edit the path below to point to the base of your OpenSSL package.
ifndef OPENSSL_PATH

View File

@@ -14,7 +14,7 @@ endif
# Edit the path below to point to the base of your Zlib sources.
ifndef ZLIB_PATH
ZLIB_PATH = ../../../zlib-1.2.7
ZLIB_PATH = ../../../zlib-1.2.8
endif
# Edit the path below to point to the base of your OpenSSL package.

View File

@@ -78,4 +78,5 @@ simplepost.c - HTTP POST
simplessl.c - HTTPS example with certificates many options set
synctime.c - Sync local time by extracting date from remote HTTP servers
url2file.c - download a document and store it in a file
xmlstream.c - Stream-parse a document using the streaming Expat parser
10-at-a-time.c - Download many files simultaneously, 10 at a time.

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -98,10 +98,6 @@ int main(void)
* bytes big and contains the remote file.
*
* Do something nice with it!
*
* You should be aware of the fact that at this point we might have an
* allocated data block, and nothing has yet deallocated that data. So when
* you're done with it, you should free() it as a nice application.
*/
printf("%lu bytes retrieved\n", (long)chunk.size);

View File

@@ -0,0 +1,111 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
struct MemoryStruct {
char *memory;
size_t size;
};
static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
size_t realsize = size * nmemb;
struct MemoryStruct *mem = (struct MemoryStruct *)userp;
mem->memory = realloc(mem->memory, mem->size + realsize + 1);
if(mem->memory == NULL) {
/* out of memory! */
printf("not enough memory (realloc returned NULL)\n");
return 0;
}
memcpy(&(mem->memory[mem->size]), contents, realsize);
mem->size += realsize;
mem->memory[mem->size] = 0;
return realsize;
}
int main(void)
{
CURL *curl;
CURLcode res;
struct MemoryStruct chunk;
static const char *postthis="Field=1&Field=2&Field=3";
chunk.memory = malloc(1); /* will be grown as needed by realloc above */
chunk.size = 0; /* no data at this point */
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "http://www.example.org/");
/* send all data to this function */
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
/* we pass our 'chunk' struct to the callback function */
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
/* some servers don't like requests that are made without a user-agent
field, so we provide one */
curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postthis);
/* if we don't provide POSTFIELDSIZE, libcurl will strlen() by
itself */
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)strlen(postthis));
/* Perform the request, res will get the return code */
res = curl_easy_perform(curl);
/* Check for errors */
if(res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}
else {
/*
* Now, our chunk.memory points to a memory block that is chunk.size
* bytes big and contains the remote file.
*
* Do something nice with it!
*/
printf("%s\n",chunk.memory);
}
/* always cleanup */
curl_easy_cleanup(curl);
if(chunk.memory)
free(chunk.memory);
/* we're done with libcurl, so clean it up */
curl_global_cleanup();
}
return 0;
}

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -30,9 +30,10 @@ struct myprogress {
CURL *curl;
};
static int progress(void *p,
double dltotal, double dlnow,
double ultotal, double ulnow)
/* this is how the CURLOPT_XFERINFOFUNCTION callback works */
static int xferinfo(void *p,
curl_off_t dltotal, curl_off_t dlnow,
curl_off_t ultotal, curl_off_t ulnow)
{
struct myprogress *myp = (struct myprogress *)p;
CURL *curl = myp->curl;
@@ -48,7 +49,9 @@ static int progress(void *p,
fprintf(stderr, "TOTAL TIME: %f \r\n", curtime);
}
fprintf(stderr, "UP: %g of %g DOWN: %g of %g\r\n",
fprintf(stderr, "UP: %" CURL_FORMAT_CURL_OFF_T " of %" CURL_FORMAT_CURL_OFF_T
" DOWN: %" CURL_FORMAT_CURL_OFF_T " of %" CURL_FORMAT_CURL_OFF_T
"\r\n",
ulnow, ultotal, dlnow, dltotal);
if(dlnow > STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES)
@@ -56,6 +59,19 @@ static int progress(void *p,
return 0;
}
/* for libcurl older than 7.32.0 (CURLOPT_PROGRESSFUNCTION) */
static int older_progress(void *p,
double dltotal, double dlnow,
double ultotal, double ulnow)
{
return xferinfo(p,
(curl_off_t)dltotal,
(curl_off_t)dlnow,
(curl_off_t)ultotal,
(curl_off_t)ulnow);
}
int main(void)
{
CURL *curl;
@@ -68,9 +84,28 @@ int main(void)
prog.curl = curl;
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/");
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress);
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, older_progress);
/* pass the struct pointer into the progress function */
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &prog);
#if LIBCURL_VERSION_NUM >= 0x072000
/* xferinfo was introduced in 7.32.0, no earlier libcurl versions will
compile as they won't have the symbols around.
If built with a newer libcurl, but running with an older libcurl:
curl_easy_setopt() will fail in run-time trying to set the new
callback, making the older callback get used.
New libcurls will prefer the new callback and instead use that one even
if both callbacks are set. */
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, xferinfo);
/* pass the struct pointer into the xferinfo function, note that this is
an alias to CURLOPT_PROGRESSDATA */
curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &prog);
#endif
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
res = curl_easy_perform(curl);

View File

@@ -54,23 +54,22 @@ int main(void)
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);
/* open the files */
headerfile = fopen(headerfilename,"w");
headerfile = fopen(headerfilename,"wb");
if (headerfile == NULL) {
curl_easy_cleanup(curl_handle);
return -1;
}
bodyfile = fopen(bodyfilename,"w");
bodyfile = fopen(bodyfilename,"wb");
if (bodyfile == NULL) {
curl_easy_cleanup(curl_handle);
return -1;
}
/* we want the headers to this file handle */
/* we want the headers be written to this file handle */
curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER, headerfile);
/*
* Notice here that if you want the actual data sent anywhere else but
* stdout, you should consider using the CURLOPT_WRITEDATA option. */
/* we want the body be written to this file handle instead of stdout */
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, bodyfile);
/* get it! */
curl_easy_perform(curl_handle);
@@ -78,6 +77,9 @@ int main(void)
/* close the header file */
fclose(headerfile);
/* close the body file */
fclose(bodyfile);
/* cleanup curl stuff */
curl_easy_cleanup(curl_handle);

View File

@@ -0,0 +1,211 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
/* Example using an in memory PEM user certificate and RSA key to retrieve an
* https page.
* Written by Ishan SinghLevett, based on Theo Borm's cacertinmem.c.
* Note this example does not use a CA certificate, however one should be used
* if you want a properly secure connection
*/
#include <openssl/ssl.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <curl/curl.h>
#include <stdio.h>
static size_t writefunction(void *ptr, size_t size, size_t nmemb, void *stream)
{
fwrite(ptr,size,nmemb,stream);
return(nmemb*size);
}
static CURLcode sslctx_function(CURL *curl, void *sslctx, void *parm)
{
X509 *cert = NULL;
BIO *bio = NULL;
BIO *kbio = NULL;
RSA *rsa = NULL;
int ret;
const char *mypem = /* www.cacert.org */
"-----BEGIN CERTIFICATE-----\n"\
"MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290\n"\
"IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB\n"\
"IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA\n"\
"Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO\n"\
"BgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEi\n"\
"MCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJ\n"\
"ARYSc3VwcG9ydEBjYWNlcnQub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC\n"\
"CgKCAgEAziLA4kZ97DYoB1CW8qAzQIxL8TtmPzHlawI229Z89vGIj053NgVBlfkJ\n"\
"8BLPRoZzYLdufujAWGSuzbCtRRcMY/pnCujW0r8+55jE8Ez64AO7NV1sId6eINm6\n"\
"zWYyN3L69wj1x81YyY7nDl7qPv4coRQKFWyGhFtkZip6qUtTefWIonvuLwphK42y\n"\
"fk1WpRPs6tqSnqxEQR5YYGUFZvjARL3LlPdCfgv3ZWiYUQXw8wWRBB0bF4LsyFe7\n"\
"w2t6iPGwcswlWyCR7BYCEo8y6RcYSNDHBS4CMEK4JZwFaz+qOqfrU0j36NK2B5jc\n"\
"G8Y0f3/JHIJ6BVgrCFvzOKKrF11myZjXnhCLotLddJr3cQxyYN/Nb5gznZY0dj4k\n"\
"epKwDpUeb+agRThHqtdB7Uq3EvbXG4OKDy7YCbZZ16oE/9KTfWgu3YtLq1i6L43q\n"\
"laegw1SJpfvbi1EinbLDvhG+LJGGi5Z4rSDTii8aP8bQUWWHIbEZAWV/RRyH9XzQ\n"\
"QUxPKZgh/TMfdQwEUfoZd9vUFBzugcMd9Zi3aQaRIt0AUMyBMawSB3s42mhb5ivU\n"\
"fslfrejrckzzAeVLIL+aplfKkQABi6F1ITe1Yw1nPkZPcCBnzsXWWdsC4PDSy826\n"\
"YreQQejdIOQpvGQpQsgi3Hia/0PsmBsJUUtaWsJx8cTLc6nloQsCAwEAAaOCAc4w\n"\
"ggHKMB0GA1UdDgQWBBQWtTIb1Mfz4OaO873SsDrusjkY0TCBowYDVR0jBIGbMIGY\n"\
"gBQWtTIb1Mfz4OaO873SsDrusjkY0aF9pHsweTEQMA4GA1UEChMHUm9vdCBDQTEe\n"\
"MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0\n"\
"IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy\n"\
"dC5vcmeCAQAwDwYDVR0TAQH/BAUwAwEB/zAyBgNVHR8EKzApMCegJaAjhiFodHRw\n"\
"czovL3d3dy5jYWNlcnQub3JnL3Jldm9rZS5jcmwwMAYJYIZIAYb4QgEEBCMWIWh0\n"\
"dHBzOi8vd3d3LmNhY2VydC5vcmcvcmV2b2tlLmNybDA0BglghkgBhvhCAQgEJxYl\n"\
"aHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4LnBocD9pZD0xMDBWBglghkgBhvhC\n"\
"AQ0ESRZHVG8gZ2V0IHlvdXIgb3duIGNlcnRpZmljYXRlIGZvciBGUkVFIGhlYWQg\n"\
"b3ZlciB0byBodHRwOi8vd3d3LmNhY2VydC5vcmcwDQYJKoZIhvcNAQEEBQADggIB\n"\
"ACjH7pyCArpcgBLKNQodgW+JapnM8mgPf6fhjViVPr3yBsOQWqy1YPaZQwGjiHCc\n"\
"nWKdpIevZ1gNMDY75q1I08t0AoZxPuIrA2jxNGJARjtT6ij0rPtmlVOKTV39O9lg\n"\
"18p5aTuxZZKmxoGCXJzN600BiqXfEVWqFcofN8CCmHBh22p8lqOOLlQ+TyGpkO/c\n"\
"gr/c6EWtTZBzCDyUZbAEmXZ/4rzCahWqlwQ3JNgelE5tDlG+1sSPypZt90Pf6DBl\n"\
"Jzt7u0NDY8RD97LsaMzhGY4i+5jhe1o+ATc7iwiwovOVThrLm82asduycPAtStvY\n"\
"sONvRUgzEv/+PDIqVPfE94rwiCPCR/5kenHA0R6mY7AHfqQv0wGP3J8rtsYIqQ+T\n"\
"SCX8Ev2fQtzzxD72V7DX3WnRBnc0CkvSyqD/HMaMyRa+xMwyN2hzXwj7UfdJUzYF\n"\
"CpUCTPJ5GhD22Dp1nPMd8aINcGeGG7MW9S/lpOt5hvk9C8JzC6WZrG/8Z7jlLwum\n"\
"GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk\n"\
"zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW\n"\
"omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD\n"\
"-----END CERTIFICATE-----\n";
/*replace the XXX with the actual RSA key*/
const char *mykey =
"-----BEGIN RSA PRIVATE KEY-----\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"-----END RSA PRIVATE KEY-----\n";
(void)curl; /* avoid warnings */
(void)parm; /* avoid warnings */
/* get a BIO */
bio = BIO_new_mem_buf((char *)mypem, -1);
if (bio == NULL) {
printf("BIO_new_mem_buf failed\n");
}
/* use it to read the PEM formatted certificate from memory into an X509
* structure that SSL can use
*/
cert = PEM_read_bio_X509(bio, NULL, 0, NULL);
if (cert == NULL) {
printf("PEM_read_bio_X509 failed...\n");
}
/*tell SSL to use the X509 certificate*/
ret = SSL_CTX_use_certificate((SSL_CTX*)sslctx, cert);
if (ret != 1) {
printf("Use certificate failed\n");
}
/*create a bio for the RSA key*/
kbio = BIO_new_mem_buf((char *)mykey, -1);
if (kbio == NULL) {
printf("BIO_new_mem_buf failed\n");
}
/*read the key bio into an RSA object*/
rsa = PEM_read_bio_RSAPrivateKey(kbio, NULL, 0, NULL);
if (rsa == NULL) {
printf("Failed to create key bio\n");
}
/*tell SSL to use the RSA key from memory*/
ret = SSL_CTX_use_RSAPrivateKey((SSL_CTX*)sslctx, rsa);
if (ret != 1) {
printf("Use Key failed\n");
}
/* all set to go */
return CURLE_OK ;
}
int main(void)
{
CURL *ch;
CURLcode rv;
rv = curl_global_init(CURL_GLOBAL_ALL);
ch = curl_easy_init();
rv = curl_easy_setopt(ch,CURLOPT_VERBOSE, 0L);
rv = curl_easy_setopt(ch,CURLOPT_HEADER, 0L);
rv = curl_easy_setopt(ch,CURLOPT_NOPROGRESS, 1L);
rv = curl_easy_setopt(ch,CURLOPT_NOSIGNAL, 1L);
rv = curl_easy_setopt(ch,CURLOPT_WRITEFUNCTION, *writefunction);
rv = curl_easy_setopt(ch,CURLOPT_WRITEDATA, stdout);
rv = curl_easy_setopt(ch,CURLOPT_HEADERFUNCTION, *writefunction);
rv = curl_easy_setopt(ch,CURLOPT_WRITEHEADER, stderr);
rv = curl_easy_setopt(ch,CURLOPT_SSLCERTTYPE,"PEM");
/* both VERIFYPEER and VERIFYHOST are set to 0 in this case because there is
no CA certificate*/
rv = curl_easy_setopt(ch,CURLOPT_SSL_VERIFYPEER, 0L);
rv = curl_easy_setopt(ch,CURLOPT_SSL_VERIFYHOST, 0L);
rv = curl_easy_setopt(ch, CURLOPT_URL, "https://www.example.com/");
rv = curl_easy_setopt(ch, CURLOPT_SSLKEYTYPE, "PEM");
/* first try: retrieve page without user certificate and key -> will fail
*/
rv = curl_easy_perform(ch);
if (rv==CURLE_OK) {
printf("*** transfer succeeded ***\n");
}
else {
printf("*** transfer failed ***\n");
}
/* second try: retrieve page using user certificate and key -> will succeed
* load the certificate and key by installing a function doing the necessary
* "modifications" to the SSL CONTEXT just before link init
*/
rv = curl_easy_setopt(ch,CURLOPT_SSL_CTX_FUNCTION, *sslctx_function);
rv = curl_easy_perform(ch);
if (rv==CURLE_OK) {
printf("*** transfer succeeded ***\n");
}
else {
printf("*** transfer failed ***\n");
}
curl_easy_cleanup(ch);
curl_global_cleanup();
return rv;
}

158
docs/examples/xmlstream.c Normal file
View File

@@ -0,0 +1,158 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
/* Stream-parse a document using the streaming Expat parser.
* Written by David Strauss
*
* Expat => http://www.libexpat.org/
*
* gcc -Wall -I/usr/local/include xmlstream.c -lcurl -lexpat -o xmlstream
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <expat.h>
#include <curl/curl.h>
struct MemoryStruct {
char *memory;
size_t size;
};
struct ParserStruct {
int ok;
size_t tags;
size_t depth;
struct MemoryStruct characters;
};
static void startElement(void *userData, const XML_Char *name, const XML_Char **atts)
{
struct ParserStruct *state = (struct ParserStruct *) userData;
state->tags++;
state->depth++;
/* Get a clean slate for reading in character data. */
free(state->characters.memory);
state->characters.memory = NULL;
state->characters.size = 0;
}
static void characterDataHandler(void *userData, const XML_Char *s, int len)
{
struct ParserStruct *state = (struct ParserStruct *) userData;
struct MemoryStruct *mem = &state->characters;
mem->memory = realloc(mem->memory, mem->size + len + 1);
if(mem->memory == NULL) {
/* Out of memory. */
fprintf(stderr, "Not enough memory (realloc returned NULL).\n");
state->ok = 0;
return;
}
memcpy(&(mem->memory[mem->size]), s, len);
mem->size += len;
mem->memory[mem->size] = 0;
}
static void endElement(void *userData, const XML_Char *name)
{
struct ParserStruct *state = (struct ParserStruct *) userData;
state->depth--;
printf("%5lu %10lu %s\n", state->depth, state->characters.size, name);
}
static size_t parseStreamCallback(void *contents, size_t length, size_t nmemb, void *userp)
{
XML_Parser parser = (XML_Parser) userp;
size_t real_size = length * nmemb;
struct ParserStruct *state = (struct ParserStruct *) XML_GetUserData(parser);
/* Only parse if we're not already in a failure state. */
if (state->ok && XML_Parse(parser, contents, real_size, 0) == 0) {
int error_code = XML_GetErrorCode(parser);
fprintf(stderr, "Parsing response buffer of length %lu failed with error code %d (%s).\n",
real_size, error_code, XML_ErrorString(error_code));
state->ok = 0;
}
return real_size;
}
int main(void)
{
CURL *curl_handle;
CURLcode res;
XML_Parser parser;
struct ParserStruct state;
/* Initialize the state structure for parsing. */
memset(&state, 0, sizeof(struct ParserStruct));
state.ok = 1;
/* Initialize a namespace-aware parser. */
parser = XML_ParserCreateNS(NULL, '\0');
XML_SetUserData(parser, &state);
XML_SetElementHandler(parser, startElement, endElement);
XML_SetCharacterDataHandler(parser, characterDataHandler);
/* Initalize a libcurl handle. */
curl_global_init(CURL_GLOBAL_ALL ^ CURL_GLOBAL_SSL);
curl_handle = curl_easy_init();
curl_easy_setopt(curl_handle, CURLOPT_URL, "http://www.w3schools.com/xml/simple.xml");
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, parseStreamCallback);
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)parser);
printf("Depth Characters Closing Tag\n");
/* Perform the request and any follow-up parsing. */
res = curl_easy_perform(curl_handle);
if(res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}
else if (state.ok) {
/* Expat requires one final call to finalize parsing. */
if (XML_Parse(parser, NULL, 0, 1) == 0) {
int error_code = XML_GetErrorCode(parser);
fprintf(stderr, "Finalizing parsing failed with error code %d (%s).\n",
error_code, XML_ErrorString(error_code));
}
else {
printf(" --------------\n");
printf(" %lu tags total\n", state.tags);
}
}
/* Clean up. */
free(state.characters.memory);
XML_ParserFree(parser);
curl_easy_cleanup(curl_handle);
curl_global_cleanup();
return 0;
}

View File

@@ -232,7 +232,7 @@ Pass a pointer to a char pointer to receive a pointer to a string holding the
most recent RTSP Session ID.
Applications wishing to resume an RTSP session on another connection should
retreive this info before closing the active connection.
retrieve this info before closing the active connection.
.IP CURLINFO_RTSP_CLIENT_CSEQ
Pass a pointer to a long to receive the next CSeq that will be used by the
application.
@@ -244,7 +244,7 @@ by the application.
unimplemented).\fP
Applications wishing to resume an RTSP session on another connection should
retreive this info before closing the active connection.
retrieve this info before closing the active connection.
.IP CURLINFO_RTSP_CSEQ_RECV
Pass a pointer to a long to receive the most recently received CSeq from the
server. If your application encounters a \fICURLE_RTSP_CSEQ_ERROR\fP then you

View File

@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
@@ -38,8 +38,11 @@ that returns pause signals to the library that it couldn't take care of any
data at all, and that data will then be delivered again to the callback when
the writing is later unpaused.
NOTE: while it may feel tempting, take care and notice that you cannot call
this function from another thread.
While it may feel tempting, take care and notice that you cannot call this
function from another thread. To unpause, you may for example call it from the
progress callback (see \fIcurl_easy_setopt(3)\fP's
\fICURLOPT_PROGRESSFUNCTION\fP), which gets called at least once per second,
even if the connection is paused.
When this function is called to unpause reading, the chance is high that you
will get your write callback called before this function returns.
@@ -68,6 +71,18 @@ code means something wrong occurred after the new state was set. See the
.SH AVAILABILITY
This function was added in libcurl 7.18.0. Before this version, there was no
explicit support for pausing transfers.
.SH "USAGE WITH THE MULTI-SOCKET INTERFACE"
Before libcurl 7.32.0, when a specific handle was unpaused with this function,
there was no particular forced rechecking or similar of the socket's state,
which made the continuation of the transfer get delayed until next
multi-socket call invoke or even longer. Alternatively, the user could
forcibly call for example curl_multi_socket_all(3) - with a rather hefty
performance penalty.
Starting in libcurl 7.32.0, unpausing a transfer will schedule a timeout
trigger for that handle 1 millisecond into the future, so that a
curl_multi_socket_action( ... CURL_SOCKET_TIMEOUT) can be used immediately
afterwards to get the transfer going again as desired.
.SH "MEMORY USE"
When pausing a read by returning the magic return code from a write callback,
the read data is already in libcurl's internal buffers so it'll have to keep

View File

@@ -260,9 +260,9 @@ used to fast forward a file in a resumed upload (instead of reading all
uploaded bytes with the normal read function/callback). It is also called to
rewind a stream when doing a HTTP PUT or POST with a multi-pass authentication
method. The function shall work like "fseek" or "lseek" and accepted SEEK_SET,
SEEK_CUR and SEEK_END as argument for origin, although (in 7.18.0) libcurl
only passes SEEK_SET. The callback must return 0 (CURL_SEEKFUNC_OK) on
success, 1 (CURL_SEEKFUNC_FAIL) to cause the upload operation to fail or 2
SEEK_CUR and SEEK_END as argument for origin, although libcurl currently only
passes SEEK_SET. The callback must return 0 (CURL_SEEKFUNC_OK) on success, 1
(CURL_SEEKFUNC_FAIL) to cause the upload operation to fail or 2
(CURL_SEEKFUNC_CANTSEEK) to indicate that while the seek failed, libcurl is
free to work around the problem if possible. The latter can sometimes be done
by instead reading from the input or similar.
@@ -342,15 +342,34 @@ argument in the closesocket callback set with
The default value of this parameter is unspecified.
(Option added in 7.21.7)
.IP CURLOPT_PROGRESSFUNCTION
Pass a pointer to a function that matches the following prototype: \fBint
function(void *clientp, double dltotal, double dlnow, double ultotal, double
ulnow); \fP. This function gets called by libcurl instead of its internal
equivalent with a frequent interval during operation (roughly once per second
or sooner) no matter if data is being transferred or not. Unknown/unused
argument values passed to the callback will be set to zero (like if you only
download data, the upload size will remain 0). Returning a non-zero value from
this callback will cause libcurl to abort the transfer and return
\fICURLE_ABORTED_BY_CALLBACK\fP.
Pass a pointer to a function that matches the following prototype:
\fBint function(void *clientp, double dltotal, double dlnow, double ultotal,
double ulnow);\fP
This function gets called by libcurl instead of its internal equivalent with a
frequent interval. While data is being transferred it will be called very
frequently, and during slow periods like when nothing is being transferred it
can slow down to about one call per second.
\fIclientp\fP is the pointer set with \fICURLOPT_PROGRESSDATA\fP, it is not
actually used by libcurl but is only passed along from the application to the
callback.
The callback gets told how much data libcurl will transfer and has
transferred, in number of bytes. \fIdltotal\fP is the total number of bytes
libcurl expects to download in this transfer. \fIdlnow\fP is the number of
bytes downloaded so far. \fIultotal\fP is the total number of bytes libcurl
expects to upload in this transfer. \fIulnow\fP is the number of bytes
uploaded so far.
Unknown/unused argument values passed to the callback will be set to zero
(like if you only download data, the upload size will remain 0). Many times
the callback will be called one or more times first, before it knows the data
sizes so a program must be made to handle that.
Returning a non-zero value from this callback will cause libcurl to abort the
transfer and return \fICURLE_ABORTED_BY_CALLBACK\fP.
If you transfer data with the multi interface, this function will not be
called during periods of idleness unless you call the appropriate libcurl
@@ -358,10 +377,54 @@ function that performs transfers.
\fICURLOPT_NOPROGRESS\fP must be set to 0 to make this function actually
get called.
.IP CURLOPT_XFERINFOFUNCTION
Pass a pointer to a function that matches the following prototype:
.nf
\fBint function(void *clientp, curl_off_t dltotal, curl_off_t dlnow,
curl_off_t ultotal, curl_off_t ulnow);\fP
.fi
This function gets called by libcurl instead of its internal equivalent with a
frequent interval. While data is being transferred it will be called very
frequently, and during slow periods like when nothing is being transferred it
can slow down to about one call per second.
\fIclientp\fP is the pointer set with \fICURLOPT_XFERINFODATA\fP, it is only
passed along from the application to the callback.
The callback gets told how much data libcurl will transfer and has
transferred, in number of bytes. \fIdltotal\fP is the total number of bytes
libcurl expects to download in this transfer. \fIdlnow\fP is the number of
bytes downloaded so far. \fIultotal\fP is the total number of bytes libcurl
expects to upload in this transfer. \fIulnow\fP is the number of bytes
uploaded so far.
Unknown/unused argument values passed to the callback will be set to zero
(like if you only download data, the upload size will remain 0). Many times
the callback will be called one or more times first, before it knows the data
sizes so a program must be made to handle that.
Returning a non-zero value from this callback will cause libcurl to abort the
transfer and return \fICURLE_ABORTED_BY_CALLBACK\fP.
If you transfer data with the multi interface, this function will not be
called during periods of idleness unless you call the appropriate libcurl
function that performs transfers.
\fICURLOPT_NOPROGRESS\fP must be set to 0 to make this function actually
get called.
(Added in 7.32.0)
.IP CURLOPT_PROGRESSDATA
Pass a pointer that will be untouched by libcurl and passed as the first
argument in the progress callback set with \fICURLOPT_PROGRESSFUNCTION\fP.
The default value of this parameter is unspecified.
.IP CURLOPT_XFERINFODATA
Pass a pointer that will be untouched by libcurl and passed as the first
argument in the progress callback set with \fICURLOPT_XFERINFOFUNCTION\fP.
The default value of this parameter is unspecified. This option is an alias
for CURLOPT_PROGRESSDATA. (Added in 7.32.0)
.IP CURLOPT_HEADERFUNCTION
Pass a pointer to a function that matches the following prototype:
\fBsize_t function( void *ptr, size_t size, size_t nmemb, void
@@ -620,12 +683,20 @@ scheme://host:port/path
For a greater explanation of the format please see RFC3986.
If the given URL lacks the scheme, or protocol, part ("http://" or "ftp://"
etc), libcurl will attempt to resolve which protocol to use based on the
given host mame. If the protocol is not supported, libcurl will return
(\fICURLE_UNSUPPORTED_PROTOCOL\fP) when you call \fIcurl_easy_perform(3)\fP
or \fIcurl_multi_perform(3)\fP. Use \fIcurl_version_info(3)\fP for detailed
information on which protocols are supported.
If the given URL lacks the scheme (such as "http://" or "ftp://" etc) then
libcurl will attempt to resolve the protocol based on one of the following
given host names:
HTTP, FTP, DICT, LDAP, IMAP, POP3 or SMTP
(POP3 and SMTP added in 7.31.0)
Should the protocol, either that specified by the scheme or deduced by libcurl
from the host name, not be supported by libcurl then
(\fICURLE_UNSUPPORTED_PROTOCOL\fP) will be returned from either the
\fIcurl_easy_perform(3)\fP or \fIcurl_multi_perform(3)\fP functions when you
call them. Use \fIcurl_version_info(3)\fP for detailed information of which
protocols are supported by the build of libcurl you are using.
The host part of the URL contains the address of the server that you want to
connect to. This can be the fully qualified domain name of the server, the
@@ -640,17 +711,23 @@ http://192.168.0.1/
http://[2001:1890:1112:1::20]/
It is also possible to specify the user name and password as part of the
host, for some protocols, when connecting to servers that require
authentication.
For example the following types of authentication support this:
It is also possible to specify the user name, password and any supported login
options as part of the host, for the following protocols, when connecting to
servers that require authentication:
http://user:password@www.example.com
ftp://user:password@ftp.example.com
pop3://user:password@mail.example.com
imap://user:password;options@mail.example.com
pop3://user:password;options@mail.example.com
smtp://user:password;options@mail.example.com
At present only IMAP, POP3 and SMTP support login options as part of the host.
For more information about the login options in URL syntax please see RFC2384,
RFC5092 and IETF draft draft-earhart-url-smtp-00.txt (Added in 7.31.0).
The port is optional and when not specified libcurl will use the default port
based on the determined or specified protocol: 80 for HTTP, 21 for FTP and 25
@@ -814,6 +891,19 @@ Active Directory server.
For more information about the individual components of a LDAP URL please
see RFC4516.
.B RTMP
There's no official URL spec for RTMP so libcurl uses the URL syntax supported
by the underlying librtmp library. It has a syntax where it wants a
traditional URL, followed by a space and a series of space-separated
name=value pairs.
While space is not typically a "legal" letter, libcurl accepts them. When a
user wants to pass in a '#' (hash) character it will be treated as a fragment
and get cut off by libcurl if provided literally. You will instead have to
escape it by providing it as backslash and its ASCII value in hexadecimal:
"\\23".
.B NOTES
Starting with version 7.20.0, the fragment part of the URI will not be sent as
@@ -1040,8 +1130,8 @@ the full path name to the file you want libcurl to use as .netrc file. If this
option is omitted, and \fICURLOPT_NETRC\fP is set, libcurl will attempt to
find a .netrc file in the current user's home directory. (Added in 7.10.9)
.IP CURLOPT_USERPWD
Pass a char * as parameter, which should be [user name]:[password] to use for
the connection. Use \fICURLOPT_HTTPAUTH\fP to decide the authentication method.
Pass a char * as parameter, pointing to a zero terminated login details string
for the connection. The format of which is: [user name]:[password];[options].
When using NTLM, you can set the domain by prepending it to the user name and
separating the domain and name with a forward (/) or backward slash (\\). Like
@@ -1054,10 +1144,18 @@ and password information to hosts using the initial host name (unless
\fICURLOPT_UNRESTRICTED_AUTH\fP is set), so if libcurl follows locations to
other hosts it will not send the user and password to those. This is enforced
to prevent accidental information leakage.
At present only IMAP, POP3 and SMTP support login options as part of the
details string. For more information about the login options please see
RFC2384, RFC5092 and IETF draft draft-earhart-url-smtp-00.txt (Added in 7.31.0).
Use \fICURLOPT_HTTPAUTH\fP to specify the authentication method for HTTP based
connections.
.IP CURLOPT_PROXYUSERPWD
Pass a char * as parameter, which should be [user name]:[password] to use for
the connection to the HTTP proxy. Use \fICURLOPT_PROXYAUTH\fP to decide
the authentication method.
the connection to the HTTP proxy.
Use \fICURLOPT_PROXYAUTH\fP to specify the authentication method.
.IP CURLOPT_USERNAME
Pass a char * as parameter, which should be pointing to the zero terminated
user name to use for the transfer.
@@ -1134,7 +1232,7 @@ Microsoft. It uses a challenge-response and hash concept similar to Digest, to
prevent the password from being eavesdropped.
You need to build libcurl with either OpenSSL, GnuTLS or NSS support for this
option to work, or build libcurl on Windows.
option to work, or build libcurl on Windows with SSPI support.
.IP CURLAUTH_NTLM_WB
NTLM delegating to winbind helper. Authentication is performed by a separate
binary application that is executed when needed. The name of the application
@@ -1195,6 +1293,22 @@ actual name and password with the \fICURLOPT_PROXYUSERPWD\fP option. The
bitmask can be constructed by or'ing together the bits listed above for the
\fICURLOPT_HTTPAUTH\fP option. As of this writing, only Basic, Digest and NTLM
work. (Added in 7.10.7)
.IP CURLOPT_SASL_IR
Pass a long. If the value is 1, curl will send the initial response to the
server in the first authentication packet in order to reduce the number of
ping pong requests. Only applicable to supporting SASL authentication
mechanisms and to the IMAP, POP3 and SMTP protocols. (Added in 7.31.0)
Note: Whilst IMAP supports this option there is no need to explicitly set it,
as libcurl can determine the feature itself when the server supports the
SASL-IR CAPABILITY.
.IP CURLOPT_BEARER
Pass a char * as parameter, which should point to the zero terminated OAUTH
2.0 Bearer Access Token for use with IMAP. POP3 and SMTP servers that support
the OAUTH 2.0 Authorization Framework. (Added in 7.33.0)
Note: The user name used to generate the Bearer Token should be supplied via
the \fICURLOPT_USERNAME\fP option.
.SH HTTP OPTIONS
.IP CURLOPT_AUTOREFERER
Pass a parameter set to 1 to enable this. When enabled, libcurl will
@@ -1392,10 +1506,12 @@ internally, your added one will be used instead. If you add a header with no
content as in 'Accept:' (no data on the right side of the colon), the
internally used header will get disabled. Thus, using this option you can add
new headers, replace internal headers and remove internal headers. To add a
header with no content, make the content be two quotes: \&"". The headers
included in the linked list must not be CRLF-terminated, because curl adds
CRLF after each header item. Failure to comply with this will result in
strange bugs because the server will most likely ignore part of the headers
header with no content (nothing to the right side of the colon), use the
form 'MyHeader;' (note the ending semicolon).
The headers included in the linked list must not be CRLF-terminated, because
curl adds CRLF after each header item. Failure to comply with this will result
in strange bugs because the server will most likely ignore part of the headers
you specified.
The first line in a request (containing the method, usually a GET or POST) is
@@ -2046,10 +2162,14 @@ In unix-like systems, this might cause signals to be used unless
Default timeout is 0 (zero) which means it never times out.
.IP CURLOPT_TIMEOUT_MS
Like \fICURLOPT_TIMEOUT\fP but takes number of milliseconds instead. If
libcurl is built to use the standard system name resolver, that portion
of the transfer will still use full-second resolution for timeouts with
a minimum timeout allowed of one second.
An alternative to \fICURLOPT_TIMEOUT\fP but takes number of milliseconds
instead. If libcurl is built to use the standard system name resolver, that
portion of the transfer will still use full-second resolution for timeouts
with a minimum timeout allowed of one second.
If both \fICURLOPT_TIMEOUT\fP and \fICURLOPT_TIMEOUT_MS\fP are set, the value
set last will be used.
(Added in 7.16.2)
.IP CURLOPT_LOW_SPEED_LIMIT
Pass a long as parameter. It contains the transfer speed in bytes per second
@@ -2195,6 +2315,36 @@ This option requires that libcurl was built with a resolver backend that
supports this operation. The c-ares backend is the only such one.
(Added in 7.24.0)
.IP CURLOPT_DNS_INTERFACE
Pass a char * as parameter. Set the name of the network interface that
the DNS resolver should bind to. This must be an interface name (not an
address). Set this option to NULL to use the default setting (don't
bind to a specific interface).
This option requires that libcurl was built with a resolver backend that
supports this operation. The c-ares backend is the only such one.
(Added in 7.33.0)
.IP CURLOPT_DNS_LOCAL_IP4
Set the local IPv4 address that the resolver should bind to. The argument
should be of type char * and contain a single IPv4 address as a string.
Set this option to NULL to use the default setting (don't
bind to a specific IP address).
This option requires that libcurl was built with a resolver backend that
supports this operation. The c-ares backend is the only such one.
(Added in 7.33.0)
.IP CURLOPT_DNS_LOCAL_IP6
Set the local IPv6 address that the resolver should bind to. The argument
should be of type char * and contain a single IPv6 address as a string.
Set this option to NULL to use the default setting (don't
bind to a specific IP address).
This option requires that libcurl was built with a resolver backend that
supports this operation. The c-ares backend is the only such one.
(Added in 7.33.0)
.IP CURLOPT_ACCEPTTIMEOUT_MS
Pass a long telling libcurl the maximum number of milliseconds to wait for a
server to connect back to libcurl when an active FTP connection is used. If no
@@ -2202,20 +2352,28 @@ timeout is set, the internal default of 60000 will be used. (Added in 7.24.0)
.SH SSL and SECURITY OPTIONS
.IP CURLOPT_SSLCERT
Pass a pointer to a zero terminated string as parameter. The string should be
the file name of your certificate. The default format is "PEM" and can be
changed with \fICURLOPT_SSLCERTTYPE\fP.
the file name of your certificate. The default format is "P12" on Secure
Transport and "PEM" on other engines, and can be changed with
\fICURLOPT_SSLCERTTYPE\fP.
With NSS this can also be the nickname of the certificate you wish to
authenticate with. If you want to use a file from the current directory, please
precede it with "./" prefix, in order to avoid confusion with a nickname.
With NSS or Secure Transport, this can also be the nickname of the certificate
you wish to authenticate with as it is named in the security database. If you
want to use a file from the current directory, please precede it with "./"
prefix, in order to avoid confusion with a nickname.
.IP CURLOPT_SSLCERTTYPE
Pass a pointer to a zero terminated string as parameter. The string should be
the format of your certificate. Supported formats are "PEM" and "DER". (Added
in 7.9.3)
the format of your certificate. Supported formats are "PEM" and "DER", except
with Secure Transport. OpenSSL (versions 0.9.3 and later) and Secure Transport
(on iOS 5 or later, or OS X 10.6 or later) also support "P12" for
PKCS#12-encoded files. (Added in 7.9.3)
.IP CURLOPT_SSLKEY
Pass a pointer to a zero terminated string as parameter. The string should be
the file name of your private key. The default format is "PEM" and can be
changed with \fICURLOPT_SSLKEYTYPE\fP.
(iOS and Mac OS X only) This option is ignored if curl was built against Secure
Transport. Secure Transport expects the private key to be already present in
the keychain or PKCS#12 file containing the certificate.
.IP CURLOPT_SSLKEYTYPE
Pass a pointer to a zero terminated string as parameter. The string should be
the format of your private key. Supported formats are "PEM", "DER" and "ENG".

View File

@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
@@ -42,7 +42,7 @@ After the \fIlastitem\fP pointer follow the real arguments.
The pointers \fIfirstitem\fP and \fIlastitem\fP should both be pointing to
NULL in the first call to this function. All list-data will be allocated by
the function itself. You must call \fIcurl_formfree(3)\fP on the
\fIfirstitem\P after the form post has been done to free the resources.
\fIfirstitem\fP after the form post has been done to free the resources.
Using POST with HTTP 1.1 implies the use of a "Expect: 100-continue" header.
You can disable this header with \fICURLOPT_HTTPHEADER\fP as usual.

View File

@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
@@ -29,9 +29,9 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle, CURL *easy_handle);
.ad
.SH DESCRIPTION
Adds a standard easy handle to the multi stack. This function call will make
this \fImulti_handle\fP control the specified \fIeasy_handle\fP.
Furthermore, libcurl now initiates the connection associated with the
specified \fIeasy_handle\fP.
this \fImulti_handle\fP control the specified \fIeasy_handle\fP. Furthermore,
libcurl now initiates the connection associated with the specified
\fIeasy_handle\fP.
When an easy handle has been added to a multi stack, you can not and you must
not use \fIcurl_easy_perform(3)\fP on that handle!
@@ -41,6 +41,12 @@ cache (CURLOPT_DNS_USE_GLOBAL_CACHE), it will be made to use the DNS cache
that is shared between all easy handles within the multi handle when
\fIcurl_multi_add_handle(3)\fP is called.
If you have CURLMOPT_TIMERFUNCTION set in the multi handle (and you really
should if you're working event-based with \fIcurl_multi_socket_action(3)\fP
and friends), that callback will be called from within this function to ask
for an updated timer so that your main event loop will get the activity on
this handle to get started.
The easy handle will remain added until you remove it again with
\fIcurl_multi_remove_handle(3)\fP. You should remove the easy handle from the
multi stack before you terminate first the easy handle and then the multi

View File

@@ -74,9 +74,9 @@ The socket \fBcallback\fP function uses a prototype like this
int action, /* see values below */
void *userp, /* private callback pointer */
void *socketp); /* private socket pointer,
\fBNULL\fI if not
\fBNULL\fP if not
previously assigned with
\fIcurl_multi_assign(3)\fP */
\fBcurl_multi_assign(3)\fP */
.fi
The callback MUST return 0.

View File

@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
@@ -36,12 +36,17 @@ CURLMcode curl_multi_wait(CURLM *multi_handle,
This function polls on all file descriptors used by the curl easy handles
contained in the given multi handle set. It will block until activity is
detected on at least one of the handles or \fItimeout_ms\fP has passed.
Alternatively, if the multi handle has a pending internal timeout that has a
shorter expiry time than \fItimeout_ms\fP, that shorter time will be used
instead to make sure timeout accuracy is reasonably kept.
The calling application may pass additional curl_waitfd structures which are
similar to \fIpoll(2)\fP's pollfd structure to be waited on in the same call.
On completion, if \fInumfds\fP is supplied, it will be populated with the
number of file descriptors on which interesting events occured.
total number of file descriptors on which interesting events occured. This
number can include both libcurl internal descriptors as well as descriptors
provided in \fIextra_fds\fP.
If no extra file descriptors are provided and libcurl has no file descriptor
to offer to wait for, this function will return immediately.

View File

@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
@@ -273,6 +273,9 @@ The passed-in socket is not a valid one that libcurl already knows about.
.IP "CURLM_UNKNOWN_OPTION (6)"
curl_multi_setopt() with unsupported option
(Added in 7.15.4)
.IP "CURLM_ADDED_ALREADY (7)"
An easy handle already added to a multi handle was attempted to get added a
second time. (Added in 7.32.1)
.SH "CURLSHcode"
The "share" interface will return a CURLSHcode to indicate when an error has
occurred. Also consider \fIcurl_share_strerror(3)\fP.

View File

@@ -34,8 +34,10 @@ The share interface was added to enable sharing of data between curl
\&"handles".
.SH "ONE SET OF DATA - MANY TRANSFERS"
You can have multiple easy handles share data between them. Have them update
and use the \fBsame\fP cookie database or DNS cache! This way, each single
transfer will take advantage from data updates made by the other transfer(s).
and use the \fBsame\fP cookie database, DNS cache, TLS session cache! This
way, each single transfer will take advantage from data updates made by the
other transfer(s). The sharing interface, however, does not share active or
persistent connections between different easy handles.
.SH "SHARE OBJECT"
You create a shared object with \fIcurl_share_init(3)\fP. It returns a handle
for a newly created one.

View File

@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
@@ -1157,13 +1157,13 @@ and install a CURLOPT_OPENSOCKETFUNCTION callback function in which addresses
are sanitized before use.
.IP "Private Resources"
A user who can control the DNS server of a domain being passed in within
a URL can change the address of the host to a local, private address
which the libcurl application will then use. e.g. The innocuous URL
http://fuzzybunnies.example.com/ could actually resolve to the IP address
of a server behind a firewall, such as 127.0.0.1 or 10.1.2.3
Apps can mitigate against this by setting a CURLOPT_OPENSOCKETFUNCTION
and checking the address before a connection.
A user who can control the DNS server of a domain being passed in within a URL
can change the address of the host to a local, private address which a
server-side libcurl-using application could then use. e.g. the innocuous URL
http://fuzzybunnies.example.com/ could actually resolve to the IP address of a
server behind a firewall, such as 127.0.0.1 or 10.1.2.3. Apps can mitigate
against this by setting a CURLOPT_OPENSOCKETFUNCTION and checking the address
before a connection.
All the malicious scenarios regarding redirected URLs apply just as well
to non-redirected URLs, if the user is allowed to specify an arbitrary URL
@@ -1178,6 +1178,19 @@ IP address and port number for a server local to the app running libcurl
but behind a firewall. Apps can mitigate against this by using the
CURLOPT_FTP_SKIP_PASV_IP option or CURLOPT_FTPPORT.
.IP "IPv6 Addresses"
libcurl will normally handle IPv6 addresses transparently and just as easily
as IPv4 addresses. That means that a sanitizing function that filters out
addressses like 127.0.0.1 isn't sufficient--the equivalent IPv6 addresses ::1,
::, 0:00::0:1, ::127.0.0.1 and ::ffff:7f00:1 supplied somehow by an attacker
would all bypass a naive filter and could allow access to undesired local
resources. IPv6 also has special address blocks like link-local and site-local
that generally shouldn't be accessed by a server-side libcurl-using
application. A poorly-configured firewall installed in a data center,
organization or server may also be configured to limit IPv4 connections but
leave IPv6 connections wide open. In some cases, the CURL_IPRESOLVE_V4 option
can be used to limit resolved addresses to IPv4 only and bypass these issues.
.IP Uploads
When uploading, a redirect can cause a local (or remote) file to be
overwritten. Apps must not allow any unsanitized URL to be passed in
@@ -1250,7 +1263,7 @@ using the Content-disposition: header to generate a file name. An application
could also use CURLINFO_EFFECTIVE_URL to generate a file name from a
server-supplied redirect URL. Special care must be taken to sanitize such
names to avoid the possibility of a malicious server supplying one like
"/etc/passwd", "\autoexec.bat" or even ".bashrc".
"/etc/passwd", "\\autoexec.bat", "prn:" or even ".bashrc".
.IP "Server Certificates"
A secure application should never use the CURLOPT_SSL_VERIFYPEER option to
@@ -1263,10 +1276,15 @@ validated certificates is potentially as insecure as a plain HTTP connection.
On a related issue, be aware that even in situations like when you have
problems with libcurl and ask someone for help, everything you reveal in order
to get best possible help might also impose certain security related
risks. Host names, user names, paths, operating system specifics, etc (not to
risks. Host names, user names, paths, operating system specifics, etc. (not to
mention passwords of course) may in fact be used by intruders to gain
additional information of a potential target.
Be sure to limit access to application logs if they could hold private or
security-related data. Besides the obvious candidates like user names and
passwords, things like URLs, cookies or even file names could also hold
sensitive data.
To avoid this problem, you must of course use your common sense. Often, you
can just edit out the sensitive data or just search/replace your true
information with faked data.
@@ -1347,10 +1365,10 @@ automatically share a lot of the data that otherwise would be kept on a
per-easy handle basis when the easy interface is used.
The DNS cache is shared between handles within a multi handle, making
subsequent name resolvings faster and the connection pool that is kept to
better allow persistent connections and connection re-use is shared. If you're
using the easy interface, you can still share these between specific easy
handles by using the share interface, see \fIlibcurl-share(3)\fP.
subsequent name resolving faster, and the connection pool that is kept to
better allow persistent connections and connection re-use is also shared. If
you're using the easy interface, you can still share these between specific
easy handles by using the share interface, see \fIlibcurl-share(3)\fP.
Some things are never shared automatically, not within multi handles, like for
example cookies so the only way to share that is with the share interface.

View File

@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
@@ -39,8 +39,15 @@ maintain while using libcurl. This essentially means you call
for details.
To transfer files, you always set up an "easy handle" using
\fIcurl_easy_init(3)\fP, but when you want the file(s) transferred you have
the option of using the "easy" interface, or the "multi" interface.
\fIcurl_easy_init(3)\fP for a single specific transfer (in either
direction). You then set your desired set of options in that handle with
\fIcurk_easy_setopt(3)\fP. Options you set with \fIcurl_easy_setopt(3)\fP will
be used on every repeated use of this handle until you either call the
function again and change the option, or you reset them all with
\fIcurl_easy_reset(3)\fP.
To actually transfer data you have the option of using the "easy" interface,
or the "multi" interface.
The easy interface is a synchronous interface with which you call
\fIcurl_easy_perform(3)\fP and let it perform the transfer. When it is
@@ -51,7 +58,8 @@ The multi interface on the other hand is an asynchronous interface, that you
call and that performs only a little piece of the transfer on each invoke. It
is perfect if you want to do things while the transfer is in progress, or
similar. The multi interface allows you to select() on libcurl action, and
even to easily download multiple files simultaneously using a single thread. See further details in the \fIlibcurl-multi(3)\fP man page.
even to easily download multiple files simultaneously using a single
thread. See further details in the \fIlibcurl-multi(3)\fP man page.
You can have multiple easy handles share certain data, even if they are used
in different threads. This magic is setup using the share interface, as
@@ -115,19 +123,21 @@ Persistent connections means that libcurl can re-use the same connection for
several transfers, if the conditions are right.
libcurl will \fBalways\fP attempt to use persistent connections. Whenever you
use \fIcurl_easy_perform(3)\fP or \fIcurl_multi_perform(3)\fP, libcurl will
attempt to use an existing connection to do the transfer, and if none exists
it'll open a new one that will be subject for re-use on a possible following
call to \fIcurl_easy_perform(3)\fP or \fIcurl_multi_perform(3)\fP.
use \fIcurl_easy_perform(3)\fP or \fIcurl_multi_perform(3)\fP etc, libcurl
will attempt to use an existing connection to do the transfer, and if none
exists it'll open a new one that will be subject for re-use on a possible
following call to \fIcurl_easy_perform(3)\fP or \fIcurl_multi_perform(3)\fP.
To allow libcurl to take full advantage of persistent connections, you should
do as many of your file transfers as possible using the same curl handle. When
you call \fIcurl_easy_cleanup(3)\fP, all the possibly open connections held by
libcurl will be closed and forgotten.
do as many of your file transfers as possible using the same handle.
Note that the options set with \fIcurl_easy_setopt(3)\fP will be used on
every repeated \fIcurl_easy_perform(3)\fP call.
If you use the easy interface, and you call \fIcurl_easy_cleanup(3)\fP, all
the possibly open connections held by libcurl will be closed and forgotten.
When you've created a multi handle and are using the multi interface, the
connection pool is instead kept in the multi handle so closing and creating
new easy handles to do transfers will not affect them. Instead all added easy
handles can take advantage of the single shared pool.
.SH "GLOBAL CONSTANTS"
There are a variety of constants that libcurl uses, mainly through its
internal use of other libraries, which are too complicated for the

View File

@@ -85,8 +85,8 @@ CURLE_LDAP_SEARCH_FAILED 7.1
CURLE_LIBRARY_NOT_FOUND 7.1 7.17.0
CURLE_LOGIN_DENIED 7.13.1
CURLE_MALFORMAT_USER 7.1 7.17.0
CURLE_NO_CONNECTION_AVAILABLE 7.30.0
CURLE_NOT_BUILT_IN 7.21.5
CURLE_NO_CONNECTION_AVAILABLE 7.30.0
CURLE_OK 7.1
CURLE_OPERATION_TIMEDOUT 7.10.2
CURLE_OPERATION_TIMEOUTED 7.1 7.17.0
@@ -270,10 +270,10 @@ CURLKHTYPE_RSA1 7.19.6
CURLKHTYPE_UNKNOWN 7.19.6
CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE 7.30.0
CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE 7.30.0
CURLMOPT_MAXCONNECTS 7.16.3
CURLMOPT_MAX_HOST_CONNECTIONS 7.30.0
CURLMOPT_MAX_PIPELINE_LENGTH 7.30.0
CURLMOPT_MAX_TOTAL_CONNECTIONS 7.30.0
CURLMOPT_MAXCONNECTS 7.16.3
CURLMOPT_PIPELINING 7.16.0
CURLMOPT_PIPELINING_SERVER_BL 7.30.0
CURLMOPT_PIPELINING_SITE_BL 7.30.0
@@ -283,6 +283,7 @@ CURLMOPT_TIMERDATA 7.16.0
CURLMOPT_TIMERFUNCTION 7.16.0
CURLMSG_DONE 7.9.6
CURLMSG_NONE 7.9.6
CURLM_ADDED_ALREADY 7.32.1
CURLM_BAD_EASY_HANDLE 7.9.6
CURLM_BAD_HANDLE 7.9.6
CURLM_BAD_SOCKET 7.15.4
@@ -331,6 +332,9 @@ CURLOPT_DEBUGDATA 7.9.6
CURLOPT_DEBUGFUNCTION 7.9.6
CURLOPT_DIRLISTONLY 7.17.0
CURLOPT_DNS_CACHE_TIMEOUT 7.9.3
CURLOPT_DNS_INTERFACE 7.33.0
CURLOPT_DNS_LOCAL_IP4 7.33.0
CURLOPT_DNS_LOCAL_IP6 7.33.0
CURLOPT_DNS_SERVERS 7.24.0
CURLOPT_DNS_USE_GLOBAL_CACHE 7.9.3 7.11.1
CURLOPT_EGDSOCKET 7.7
@@ -428,7 +432,7 @@ CURLOPT_POSTREDIR 7.19.1
CURLOPT_PREQUOTE 7.9.5
CURLOPT_PRIVATE 7.10.3
CURLOPT_PROGRESSDATA 7.1
CURLOPT_PROGRESSFUNCTION 7.1
CURLOPT_PROGRESSFUNCTION 7.1 7.32.0
CURLOPT_PROTOCOLS 7.19.4
CURLOPT_PROXY 7.1
CURLOPT_PROXYAUTH 7.10.7
@@ -456,6 +460,7 @@ CURLOPT_RTSP_SERVER_CSEQ 7.20.0
CURLOPT_RTSP_SESSION_ID 7.20.0
CURLOPT_RTSP_STREAM_URI 7.20.0
CURLOPT_RTSP_TRANSPORT 7.20.0
CURLOPT_SASL_IR 7.31.0
CURLOPT_SEEKDATA 7.18.0
CURLOPT_SEEKFUNCTION 7.18.0
CURLOPT_SERVER_RESPONSE_TIMEOUT 7.20.0
@@ -524,6 +529,9 @@ CURLOPT_WRITEDATA 7.9.7
CURLOPT_WRITEFUNCTION 7.1
CURLOPT_WRITEHEADER 7.1
CURLOPT_WRITEINFO 7.1
CURLOPT_XFERINFODATA 7.32.0
CURLOPT_XFERINFOFUNCTION 7.32.0
CURLOPT_XOAUTH2_BEARER 7.33.0
CURLPAUSE_ALL 7.18.0
CURLPAUSE_CONT 7.18.0
CURLPAUSE_RECV 7.18.0
@@ -617,14 +625,15 @@ CURL_FORMADD_NULL 7.9.8
CURL_FORMADD_OK 7.9.8
CURL_FORMADD_OPTION_TWICE 7.9.8
CURL_FORMADD_UNKNOWN_OPTION 7.9.8
CURL_GLOBAL_ACK_EINTR 7.30.0
CURL_GLOBAL_ALL 7.8
CURL_GLOBAL_DEFAULT 7.8
CURL_GLOBAL_NOTHING 7.8
CURL_GLOBAL_SSL 7.8
CURL_GLOBAL_WIN32 7.8.1
CURL_GLOBAL_ACK_EINTR 7.30.0
CURL_HTTP_VERSION_1_0 7.9.1
CURL_HTTP_VERSION_1_1 7.9.1
CURL_HTTP_VERSION_2_0 7.33.0
CURL_HTTP_VERSION_NONE 7.9.1
CURL_IPRESOLVE_V4 7.10.8
CURL_IPRESOLVE_V6 7.10.8
@@ -697,6 +706,7 @@ CURL_VERSION_CONV 7.15.4
CURL_VERSION_CURLDEBUG 7.19.6
CURL_VERSION_DEBUG 7.10.6
CURL_VERSION_GSSNEGOTIATE 7.10.6
CURL_VERSION_HTTP2 7.33.0
CURL_VERSION_IDN 7.12.0
CURL_VERSION_IPV6 7.10
CURL_VERSION_KERBEROS4 7.10

View File

@@ -60,11 +60,16 @@ unlink (remove) certdata.txt after processing
be verbose and print out processed CAs
.SH EXIT STATUS
Returns 0 on success. Returns 1 if it fails to download data.
.SH CERTDATA FORMAT
The file format used by Mozilla for this trust information seems to be documented here:
.nf
http://p11-glue.freedesktop.org/doc/storing-trust-policy/storing-trust-existing.html
.fi
.SH SEE ALSO
.BR curl (1)
.SH HISTORY
\fBmk-ca-bundle\fP is a command line tool that is shipped as part of every
curl and libcurl release (see http://curl.haxx.se/). It was originally based
on the parse-certs script written by Roland Krikava and was later much
improved by Guenter Knauf. This manual page was written by Jan Schaumann
\&<jschauma@netmeister.org>.
improved by Guenter Knauf. This manual page was initially written by Jan
Schaumann \&<jschauma@netmeister.org>.

View File

@@ -156,12 +156,22 @@ struct curl_httppost {
HTTPPOST_CALLBACK posts */
};
/* This is the CURLOPT_PROGRESSFUNCTION callback proto. It is now considered
deprecated but was the only choice up until 7.31.0 */
typedef int (*curl_progress_callback)(void *clientp,
double dltotal,
double dlnow,
double ultotal,
double ulnow);
/* This is the CURLOPT_XFERINFOFUNCTION callback proto. It was introduced in
7.32.0, it avoids floating point and provides more detailed information. */
typedef int (*curl_xferinfo_callback)(void *clientp,
curl_off_t dltotal,
curl_off_t dlnow,
curl_off_t ultotal,
curl_off_t ulnow);
#ifndef CURL_MAX_WRITE_SIZE
/* Tests have proven that 20K is a very bad buffer size for uploads on
Windows, while 16K for some odd reason performed a lot better.
@@ -635,16 +645,18 @@ typedef enum {
#define CURL_ERROR_SIZE 256
enum curl_khtype {
CURLKHTYPE_UNKNOWN,
CURLKHTYPE_RSA1,
CURLKHTYPE_RSA,
CURLKHTYPE_DSS
};
struct curl_khkey {
const char *key; /* points to a zero-terminated string encoded with base64
if len is zero, otherwise to the "raw" data */
size_t len;
enum type {
CURLKHTYPE_UNKNOWN,
CURLKHTYPE_RSA1,
CURLKHTYPE_RSA,
CURLKHTYPE_DSS
} keytype;
enum curl_khtype keytype;
};
/* this is the set of return values expected from the curl_sshkeycallback
@@ -968,13 +980,16 @@ typedef enum {
/* 55 = OBSOLETE */
/* Function that will be called instead of the internal progress display
/* DEPRECATED
* Function that will be called instead of the internal progress display
* function. This function should be defined as the curl_progress_callback
* prototype defines. */
CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56),
/* Data passed to the progress callback */
/* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION
callbacks */
CINIT(PROGRESSDATA, OBJECTPOINT, 57),
#define CURLOPT_XFERINFODATA CURLOPT_PROGRESSDATA
/* We want the referrer field set automatically when following locations */
CINIT(AUTOREFERER, LONG, 58),
@@ -1527,9 +1542,33 @@ typedef enum {
/* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */
CINIT(SSL_OPTIONS, LONG, 216),
/* set the SMTP auth originator */
/* Set the SMTP auth originator */
CINIT(MAIL_AUTH, OBJECTPOINT, 217),
/* Enable/disable SASL initial response */
CINIT(SASL_IR, LONG, 218),
/* Function that will be called instead of the internal progress display
* function. This function should be defined as the curl_xferinfo_callback
* prototype defines. (Deprecates CURLOPT_PROGRESSFUNCTION) */
CINIT(XFERINFOFUNCTION, FUNCTIONPOINT, 219),
/* The XOAUTH2 bearer token */
CINIT(XOAUTH2_BEARER, OBJECTPOINT, 220),
/* Set the interface string to use as outgoing network
* interface for DNS requests.
* Only supported by the c-ares DNS backend */
CINIT(DNS_INTERFACE, OBJECTPOINT, 221),
/* Set the local IPv4 address to use for outgoing DNS requests.
* Only supported by the c-ares DNS backend */
CINIT(DNS_LOCAL_IP4, OBJECTPOINT, 222),
/* Set the local IPv4 address to use for outgoing DNS requests.
* Only supported by the c-ares DNS backend */
CINIT(DNS_LOCAL_IP6, OBJECTPOINT, 223),
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;
@@ -1582,6 +1621,7 @@ enum {
for us! */
CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */
CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */
CURL_HTTP_VERSION_2_0, /* please use HTTP 2.0 in the request */
CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */
};
@@ -2145,6 +2185,7 @@ typedef struct {
#define CURL_VERSION_CURLDEBUG (1<<13) /* debug memory tracking supported */
#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */
#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegating to winbind helper */
#define CURL_VERSION_HTTP2 (1<<16) /* HTTP2 support built-in */
/*
* NAME curl_version_info()

View File

@@ -30,12 +30,12 @@
/* This is the version number of the libcurl package from which this header
file origins: */
#define LIBCURL_VERSION "7.30.0-DEV"
#define LIBCURL_VERSION "7.33.0-DEV"
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBCURL_VERSION_MAJOR 7
#define LIBCURL_VERSION_MINOR 30
#define LIBCURL_VERSION_MINOR 33
#define LIBCURL_VERSION_PATCH 0
/* This is the numeric version of the libcurl version number, meant for easier
@@ -53,7 +53,7 @@
and it is always a greater number in a more recent release. It makes
comparisons with greater than and less than work.
*/
#define LIBCURL_VERSION_NUM 0x071e00
#define LIBCURL_VERSION_NUM 0x072100
/*
* This is the date and time when the full source package was created. The

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -64,6 +64,8 @@ typedef enum {
CURLM_INTERNAL_ERROR, /* this is a libcurl bug */
CURLM_BAD_SOCKET, /* the passed in socket argument did not match */
CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */
CURLM_ADDED_ALREADY, /* an easy handle already added to a multi handle was
attempted to get added - again */
CURLM_LAST
} CURLMcode;

View File

@@ -264,6 +264,11 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
(option) == CURLOPT_RTSP_SESSION_ID || \
(option) == CURLOPT_RTSP_STREAM_URI || \
(option) == CURLOPT_RTSP_TRANSPORT || \
(option) == CURLOPT_XOAUTH2_BEARER || \
(option) == CURLOPT_DNS_SERVERS || \
(option) == CURLOPT_DNS_INTERFACE || \
(option) == CURLOPT_DNS_LOCAL_IP4 || \
(option) == CURLOPT_DNS_LOCAL_IP6 || \
0)
/* evaluates to true if option takes a curl_write_callback argument */

View File

@@ -94,6 +94,10 @@ add_library(
${HHEADERS} ${CSOURCES}
)
if(MSVC AND CURL_STATICLIB)
set_target_properties(${LIB_NAME} PROPERTIES STATIC_LIBRARY_FLAGS ${CMAKE_EXE_LINKER_FLAGS})
endif()
target_link_libraries(${LIB_NAME} ${CURL_LIBS})
if(WIN32)
@@ -108,14 +112,6 @@ setup_curl_dependencies(${LIB_NAME})
set_target_properties(${LIB_NAME} PROPERTIES PREFIX "")
set_target_properties(${LIB_NAME} PROPERTIES IMPORT_PREFIX "")
if(MSVC)
if(NOT BUILD_RELEASE_DEBUG_DIRS)
# Ugly workaround to remove the "/debug" or "/release" in each output
set_target_properties(${LIB_NAME} PROPERTIES PREFIX "../")
set_target_properties(${LIB_NAME} PROPERTIES IMPORT_PREFIX "../")
endif()
endif()
if(WIN32)
if(NOT CURL_STATICLIB)
# Add "_imp" as a suffix before the extension to avoid conflicting with the statically linked "libcurl.lib"

View File

@@ -83,7 +83,7 @@ CFLAGS += -dWANT_IDN_PROTOTYPES
!ifdef %zlib_root
ZLIB_ROOT = $(%zlib_root)
!else
ZLIB_ROOT = ..$(DS)..$(DS)zlib-1.2.7
ZLIB_ROOT = ..$(DS)..$(DS)zlib-1.2.8
!endif
!ifdef %libssh2_root

View File

@@ -141,7 +141,7 @@ libcurl_la_CFLAGS_EXTRA += $(CFLAG_CURL_SYMBOL_HIDING)
endif
libcurl_la_CPPFLAGS = $(AM_CPPFLAGS) $(libcurl_la_CPPFLAGS_EXTRA)
libcurl_la_LDFLAGS = $(AM_LDFLAGS) $(libcurl_la_LDFLAGS_EXTRA) $(LIBCURL_LIBS)
libcurl_la_LDFLAGS = $(AM_LDFLAGS) $(libcurl_la_LDFLAGS_EXTRA) $(LDFLAGS) $(LIBCURL_LIBS)
libcurl_la_CFLAGS = $(AM_CFLAGS) $(libcurl_la_CFLAGS_EXTRA)
libcurlu_la_CPPFLAGS = $(AM_CPPFLAGS) -DCURL_STATICLIB -DUNITTESTS

View File

@@ -22,7 +22,7 @@ BCCDIR = $(MAKEDIR)\..
# Edit the path below to point to the base of your Zlib sources.
!ifndef ZLIB_PATH
ZLIB_PATH = ..\..\zlib-1.2.7
ZLIB_PATH = ..\..\zlib-1.2.8
!endif
# Edit the path below to point to the base of your OpenSSL package.
@@ -52,7 +52,7 @@ LDFLAGS = -q -lq -laa -tWD
SRCDIR = .
OBJDIR = .\BCC_objs
INCDIRS = -I.;..\include
LINKLIB = $(BCCDIR)\lib\cw32mt.lib
LINKLIB = $(BCCDIR)\lib\cw32mt.lib $(BCCDIR)\lib\ws2_32.lib
DEFINES = -DNDEBUG -DWIN32 -DBUILDING_LIBCURL
# By default SSPI support is enabled for BCC
@@ -88,8 +88,24 @@ LINKLIB = $(LINKLIB) $(OPENSSL_PATH)\out32\ssleay32.lib $(OPENSSL_PATH)\out32\l
# Makefile.inc provides the CSOURCES and HHEADERS defines
!include Makefile.inc
OBJECTS = $(CSOURCES:.c=.obj)
PREPROCESSED = $(CSOURCES:.c=.int)
# Borland's command line librarian program TLIB version 4.5 is not capable
# of building a library when any of its objects contains an hypen in its
# name, due to a command line parsing bug. In order to workaround this, we
# build source files with hyphens in their name as objects with underscores
# using explicit compilation build rules instead of implicit ones.
NOHYPHEN = $(CSOURCES:-=_)
OBJECTS = $(NOHYPHEN:.c=.obj)
PREPROCESSED = $(NOHYPHEN:.c=.int)
# Borland's command line compiler (BCC32) version 5.5.1 integrated
# preprocessor has a bug which results in silently generating wrong
# definitions for libcurl macros such as CURL_OFF_T_C, on the other
# hand Borland's command line preprocessor (CPP32) version 5.5.1 does
# not have the bug and achieves proper results. In order to avoid the
# silent bug we first preprocess source files and later compile the
# preprocessed result.
.c.obj:
@-$(RM) $(@R).int
@@ -98,6 +114,21 @@ PREPROCESSED = $(CSOURCES:.c=.int)
all: $(OBJDIR) $(LIBCURL_LIB) $(LIBCURL_DLL)
asyn_ares.obj: asyn-ares.c
@-$(RM) $(@R).int
$(PP_CMD) $(CC_FLAGS) $(INCDIRS) $(DEFINES) -o$(@R).int $(?)
$(CC_CMD) $(CC_FLAGS) -o$(@) $(@R).int
asyn_thread.obj: asyn-thread.c
@-$(RM) $(@R).int
$(PP_CMD) $(CC_FLAGS) $(INCDIRS) $(DEFINES) -o$(@R).int $(?)
$(CC_CMD) $(CC_FLAGS) -o$(@) $(@R).int
non_ascii.obj: non-ascii.c
@-$(RM) $(@R).int
$(PP_CMD) $(CC_FLAGS) $(INCDIRS) $(DEFINES) -o$(@R).int $(?)
$(CC_CMD) $(CC_FLAGS) -o$(@) $(@R).int
clean:
cd $(OBJDIR)
@-$(RM) $(OBJECTS)
@@ -122,7 +153,10 @@ $(LIBCURL_LIB): $(OBJECTS)
$(LIBCURL_DLL) $(LIBCURL_IMPLIB): $(OBJECTS) $(LINKLIB)
@-$(RM) $(LIBCURL_DLL)
@-$(RM) $(LIBCURL_IMPLIB)
$(LD) $(LDFLAGS) -e$(LIBCURL_DLL) $**
$(LD) $(LDFLAGS) -e$(LIBCURL_DLL) @&&!
$(**: = ^
)
!
$(IMPLIB) $(LIBCURL_IMPLIB) $(LIBCURL_DLL)

View File

@@ -10,10 +10,10 @@
CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
cookie.c http.c sendf.c ftp.c url.c dict.c if2ip.c speedcheck.c \
ldap.c ssluse.c version.c getenv.c escape.c mprintf.c telnet.c \
netrc.c getinfo.c transfer.c strequal.c easy.c security.c krb4.c \
netrc.c getinfo.c transfer.c strequal.c easy.c security.c \
curl_fnmatch.c fileinfo.c ftplistparser.c wildcard.c krb5.c \
memdebug.c http_chunks.c strtok.c connect.c llist.c hash.c multi.c \
content_encoding.c share.c http_digest.c md4.c md5.c curl_rand.c \
content_encoding.c share.c http_digest.c md4.c md5.c \
http_negotiate.c inet_pton.c strtoofft.c strerror.c amigaos.c \
hostasyn.c hostip4.c hostip6.c hostsyn.c inet_ntop.c parsedate.c \
select.c gtls.c sslgen.c tftp.c splay.c strdup.c socks.c ssh.c nss.c \
@@ -25,12 +25,13 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
http_proxy.c non-ascii.c asyn-ares.c asyn-thread.c curl_gssapi.c \
curl_ntlm.c curl_ntlm_wb.c curl_ntlm_core.c curl_ntlm_msgs.c \
curl_sasl.c curl_schannel.c curl_multibyte.c curl_darwinssl.c \
hostcheck.c bundles.c conncache.c pipeline.c
hostcheck.c bundles.c conncache.c pipeline.c dotdot.c x509asn1.c \
gskit.c http2.c
HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \
progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \
if2ip.h speedcheck.h urldata.h curl_ldap.h ssluse.h escape.h telnet.h \
getinfo.h strequal.h krb4.h memdebug.h http_chunks.h curl_rand.h \
getinfo.h strequal.h curl_sec.h memdebug.h http_chunks.h \
curl_fnmatch.h wildcard.h fileinfo.h ftplistparser.h strtok.h \
connect.h llist.h hash.h content_encoding.h share.h curl_md4.h \
curl_md5.h http_digest.h http_negotiate.h inet_pton.h amigaos.h \
@@ -44,4 +45,5 @@ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \
asyn.h curl_ntlm.h curl_gssapi.h curl_ntlm_wb.h curl_ntlm_core.h \
curl_ntlm_msgs.h curl_sasl.h curl_schannel.h curl_multibyte.h \
curl_darwinssl.h hostcheck.h bundles.h conncache.h curl_setup_once.h \
multihandle.h setup-vms.h pipeline.h
multihandle.h setup-vms.h pipeline.h dotdot.h x509asn1.h gskit.h \
http2.h

View File

@@ -7,14 +7,14 @@
## Example: mingw32-make -f Makefile.m32 CFG=-zlib-ssl-sspi-winidn
##
## Hint: you can also set environment vars to control the build, f.e.:
## set ZLIB_PATH=c:/zlib-1.2.7
## set ZLIB_PATH=c:/zlib-1.2.8
## set ZLIB=1
#
###########################################################################
# Edit the path below to point to the base of your Zlib sources.
ifndef ZLIB_PATH
ZLIB_PATH = ../../zlib-1.2.7
ZLIB_PATH = ../../zlib-1.2.8
endif
# Edit the path below to point to the base of your OpenSSL package.
ifndef OPENSSL_PATH

View File

@@ -14,7 +14,7 @@ endif
# Edit the path below to point to the base of your Zlib sources.
ifndef ZLIB_PATH
ZLIB_PATH = ../../zlib-1.2.7
ZLIB_PATH = ../../zlib-1.2.8
endif
# Edit the path below to point to the base of your OpenSSL package.

View File

@@ -73,7 +73,7 @@ LIBSSH2_PATH = ../../libssh2-1.4.3
!ENDIF
!IFNDEF ZLIB_PATH
ZLIB_PATH = ../../zlib-1.2.7
ZLIB_PATH = ../../zlib-1.2.8
!ENDIF
!IFNDEF MACHINE
@@ -103,23 +103,24 @@ WINDOWS_SDK_PATH = "$(PROGRAMFILES)\Microsoft SDK"
#############################################################
## Nothing more to do below this line!
CCNODBG = cl.exe /O2 /DNDEBUG
CCDEBUG = cl.exe /Od /Gm /Zi /D_DEBUG /GZ
CFLAGSSSL = /DUSE_SSLEAY /DUSE_OPENSSL /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
CFLAGSSSH2 = /DUSE_LIBSSH2 /DCURL_DISABLE_LDAP /DHAVE_LIBSSH2 /DHAVE_LIBSSH2_H /DLIBSSH2_WIN32 /DLIBSSH2_LIBRARY /I "$(LIBSSH2_PATH)/include"
CFLAGSZLIB = /DHAVE_ZLIB_H /DHAVE_ZLIB /DHAVE_LIBZ /I "$(ZLIB_PATH)"
CFLAGS = /I. /I../include /nologo /W3 /GX /DWIN32 /YX /FD /c /DBUILDING_LIBCURL /D_BIND_TO_CURRENT_VCLIBS_VERSION=1
CFLAGSLIB = /DCURL_STATICLIB
LNKDLL = link.exe /DLL
LNKLIB = link.exe /lib
LFLAGS = /nologo /machine:$(MACHINE)
SSLLIBS = libeay32.lib ssleay32.lib
ZLIBLIBSDLL= zdll.lib
ZLIBLIBS = zlib.lib
WINLIBS = ws2_32.lib wldap32.lib advapi32.lib
CFLAGS = $(CFLAGS)
CCNODBG = cl.exe /O2 /DNDEBUG
CCDEBUG = cl.exe /Od /Gm /Zi /D_DEBUG /GZ
CFLAGSSSL = /DUSE_SSLEAY /DUSE_OPENSSL /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
CFLAGSWINSSL = /DUSE_SCHANNEL
CFLAGSSSH2 = /DUSE_LIBSSH2 /DCURL_DISABLE_LDAP /DHAVE_LIBSSH2 /DHAVE_LIBSSH2_H /DLIBSSH2_WIN32 /DLIBSSH2_LIBRARY /I "$(LIBSSH2_PATH)/include"
CFLAGSZLIB = /DHAVE_ZLIB_H /DHAVE_ZLIB /DHAVE_LIBZ /I "$(ZLIB_PATH)"
CFLAGS = /I. /I../include /nologo /W3 /GX /DWIN32 /YX /FD /c /DBUILDING_LIBCURL /D_BIND_TO_CURRENT_VCLIBS_VERSION=1
CFLAGSLIB = /DCURL_STATICLIB
LNKDLL = link.exe /DLL
LNKLIB = link.exe /lib
LFLAGS = /nologo /machine:$(MACHINE)
SSLLIBS = libeay32.lib ssleay32.lib
ZLIBLIBSDLL = zdll.lib
ZLIBLIBS = zlib.lib
WINLIBS = ws2_32.lib wldap32.lib advapi32.lib
CFLAGS = $(CFLAGS)
CFGSET = FALSE
CFGSET = FALSE
!IFDEF WINDOWS_SSPI
CFLAGS = $(CFLAGS) /DUSE_WINDOWS_SSPI /I$(WINDOWS_SDK_PATH)\include
@@ -189,6 +190,18 @@ CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
CFGSET = TRUE
!ENDIF
######################
# release-winssl-zlib
!IF "$(CFG)" == "release-winssl-zlib"
TARGET = $(LIBCURL_STA_LIB_REL)
DIROBJ = $(CFG)
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
LNK = $(LNKLIB) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
CC = $(CCNODBG) $(RTLIB) $(CFLAGSWINSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
CFGSET = TRUE
!ENDIF
######################
# release-ssl-ssh2-zlib
@@ -515,7 +528,6 @@ X_OBJS= \
$(DIROBJ)\curl_ntlm_core.obj \
$(DIROBJ)\curl_ntlm_msgs.obj \
$(DIROBJ)\curl_ntlm_wb.obj \
$(DIROBJ)\curl_rand.obj \
$(DIROBJ)\curl_rtmp.obj \
$(DIROBJ)\curl_sasl.obj \
$(DIROBJ)\curl_schannel.obj \
@@ -523,6 +535,7 @@ X_OBJS= \
$(DIROBJ)\curl_threads.obj \
$(DIROBJ)\cyassl.obj \
$(DIROBJ)\dict.obj \
$(DIROBJ)\dotdot.obj \
$(DIROBJ)\easy.obj \
$(DIROBJ)\escape.obj \
$(DIROBJ)\file.obj \
@@ -553,7 +566,6 @@ X_OBJS= \
$(DIROBJ)\imap.obj \
$(DIROBJ)\inet_ntop.obj \
$(DIROBJ)\inet_pton.obj \
$(DIROBJ)\krb4.obj \
$(DIROBJ)\krb5.obj \
$(DIROBJ)\ldap.obj \
$(DIROBJ)\llist.obj \

View File

@@ -35,8 +35,8 @@ USER_CFLAGS:=
# directories where to seek for includes and libraries
OPENSSL_INC := D:/libraries/openssl/openssl-0.9.8y-vxWorks6.3/include
OPENSSL_LIB := D:/libraries/openssl/openssl-0.9.8y-vxWorks6.3
ZLIB_INC := D:/libraries/zlib/zlib-1.2.7-VxWorks6.3/zlib-1.2.7
ZLIB_LIB := D:/libraries/zlib/zlib-1.2.7-VxWorks6.3/binaries/vxworks_3.1_gnu/Debug/lib
ZLIB_INC := D:/libraries/zlib/zlib-1.2.8-VxWorks6.3/zlib-1.2.8
ZLIB_LIB := D:/libraries/zlib/zlib-1.2.8-VxWorks6.3/binaries/vxworks_3.1_gnu/Debug/lib
ARES_INC :=
ARES_LIB :=

31
lib/README.http2 Normal file
View File

@@ -0,0 +1,31 @@
HTTP2 with libcurl
Spec: http://tools.ietf.org/html/draft-ietf-httpbis-http2-06
nghttp2 (https://github.com/tatsuhiro-t/nghttp2)
We're depending on this 3rd party library for the actual low level protocol
handling parts. The reason for this is that HTTP2 is much more complex at
that layer than HTTP1.1 (which we implement on our own) and that nghttp2 is
an already existing and well functional library.
Over an http:// URL
If CURLOPT_HTTP_VERSION is set to CURL_HTTP_VERSION_2, libcurl will include
an upgrade header in the initial request to the host to allow upgrading to
http2. Possibly introduce an option that will cause libcurl to fail if not
possible to upgrade. Possibly introduce an option that makes libcurl use
http2 at once over http://
Over an https:// URL
If CURLOPT_HTTP_VERSION is set to CURL_HTTP_VERSION_2, libcurl will use ALPN
(or NPN) to negotiate which protocol to continue with. Possibly introduce an
option that will cause libcurl to fail if not possible to use http2.
To consider:
- How to tell libcurl when using the multi interface that all or some of the
handles are allowed to re-use the same physical connection. Can we just
re-use existing pipelining logic?

View File

@@ -315,6 +315,7 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
struct SessionHandle *data = conn->data;
struct ResolverResults *res = (struct ResolverResults *)
conn->async.os_specific;
CURLcode rc = CURLE_OK;
*dns = NULL;
@@ -325,19 +326,19 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
/* temp_ai ownership is moved to the connection, so we need not free-up
them */
res->temp_ai = NULL;
destroy_async_data(&conn->async);
if(!conn->async.dns) {
failf(data, "Could not resolve %s: %s (%s)",
conn->bits.proxy?"proxy":"host",
conn->host.dispname,
ares_strerror(conn->async.status));
return conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
failf(data, "Could not resolve: %s (%s)",
conn->async.hostname, ares_strerror(conn->async.status));
rc = conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
CURLE_COULDNT_RESOLVE_HOST;
}
*dns = conn->async.dns;
else
*dns = conn->async.dns;
destroy_async_data(&conn->async);
}
return CURLE_OK;
return rc;
}
/*
@@ -415,37 +416,12 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
if(entry)
*entry = conn->async.dns;
if(!conn->async.dns) {
/* a name was not resolved */
if((timeout < 0) || (conn->async.status == ARES_ETIMEOUT)) {
if(conn->bits.proxy) {
failf(data, "Resolving proxy timed out: %s", conn->proxy.dispname);
rc = CURLE_COULDNT_RESOLVE_PROXY;
}
else {
failf(data, "Resolving host timed out: %s", conn->host.dispname);
rc = CURLE_COULDNT_RESOLVE_HOST;
}
}
else if(conn->async.done) {
if(conn->bits.proxy) {
failf(data, "Could not resolve proxy: %s (%s)", conn->proxy.dispname,
ares_strerror(conn->async.status));
rc = CURLE_COULDNT_RESOLVE_PROXY;
}
else {
failf(data, "Could not resolve host: %s (%s)", conn->host.dispname,
ares_strerror(conn->async.status));
rc = CURLE_COULDNT_RESOLVE_HOST;
}
}
else
rc = CURLE_OPERATION_TIMEDOUT;
if(rc)
/* close the connection, since we can't return failure here without
cleaning up this connection properly */
cleaning up this connection properly.
TODO: remove this action from here, it is not a name resolver decision.
*/
conn->bits.close = TRUE;
}
return rc;
}
@@ -614,8 +590,19 @@ CURLcode Curl_set_dns_servers(struct SessionHandle *data,
char *servers)
{
CURLcode result = CURLE_NOT_BUILT_IN;
int ares_result;
/* If server is NULL or empty, this would purge all DNS servers
* from ares library, which will cause any and all queries to fail.
* So, just return OK if none are configured and don't actually make
* any changes to c-ares. This lets c-ares use it's defaults, which
* it gets from the OS (for instance from /etc/resolv.conf on Linux).
*/
if(!(servers && servers[0]))
return CURLE_OK;
#if (ARES_VERSION >= 0x010704)
int ares_result = ares_set_servers_csv(data->state.resolver, servers);
ares_result = ares_set_servers_csv(data->state.resolver, servers);
switch(ares_result) {
case ARES_SUCCESS:
result = CURLE_OK;
@@ -632,8 +619,76 @@ CURLcode Curl_set_dns_servers(struct SessionHandle *data,
}
#else /* too old c-ares version! */
(void)data;
(void)servers;
(void)(ares_result);
#endif
return result;
}
CURLcode Curl_set_dns_interface(struct SessionHandle *data,
const char *interf)
{
#if (ARES_VERSION >= 0x010704)
if(!interf)
interf = "";
ares_set_local_dev((ares_channel)data->state.resolver, interf);
return CURLE_OK;
#else /* c-ares version too old! */
(void)data;
(void)interf;
return CURLE_NOT_BUILT_IN;
#endif
}
CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
const char *local_ip4)
{
#if (ARES_VERSION >= 0x010704)
uint32_t a4;
if((!local_ip4) || (local_ip4[0] == 0)) {
a4 = 0; /* disabled: do not bind to a specific address */
}
else {
if(Curl_inet_pton(AF_INET, local_ip4, &a4) != 1) {
return CURLE_BAD_FUNCTION_ARGUMENT;
}
}
ares_set_local_ip4((ares_channel)data->state.resolver, ntohl(a4));
return CURLE_OK;
#else /* c-ares version too old! */
(void)data;
(void)local_ip4;
return CURLE_NOT_BUILT_IN;
#endif
}
CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data,
const char *local_ip6)
{
#if (ARES_VERSION >= 0x010704)
unsigned char a6[INET6_ADDRSTRLEN];
if((!local_ip6) || (local_ip6[0] == 0)) {
/* disabled: do not bind to a specific address */
memset(a6, 0, sizeof(a6));
}
else {
if(Curl_inet_pton(AF_INET6, local_ip6, a6) != 1) {
return CURLE_BAD_FUNCTION_ARGUMENT;
}
}
ares_set_local_ip6((ares_channel)data->state.resolver, a6);
return CURLE_OK;
#else /* c-ares version too old! */
(void)data;
(void)local_ip6;
return CURLE_NOT_BUILT_IN;
#endif
}
#endif /* CURLRES_ARES */

View File

@@ -265,7 +265,7 @@ static int getaddrinfo_complete(struct connectdata *conn)
static unsigned int CURL_STDCALL getaddrinfo_thread (void *arg)
{
struct thread_sync_data *tsd = (struct thread_sync_data*)arg;
char service [NI_MAXSERV];
char service[12];
int rc;
snprintf(service, sizeof(service), "%d", tsd->port);
@@ -559,7 +559,7 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
struct in_addr in;
Curl_addrinfo *res;
int error;
char sbuf[NI_MAXSERV];
char sbuf[12];
int pf = PF_INET;
#ifdef CURLRES_IPV6
struct in6_addr in6;
@@ -635,4 +635,28 @@ CURLcode Curl_set_dns_servers(struct SessionHandle *data,
}
CURLcode Curl_set_dns_interface(struct SessionHandle *data,
const char *interf)
{
(void)data;
(void)interf;
return CURLE_NOT_BUILT_IN;
}
CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
const char *local_ip4)
{
(void)data;
(void)local_ip4;
return CURLE_NOT_BUILT_IN;
}
CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data,
const char *local_ip6)
{
(void)data;
(void)local_ip6;
return CURLE_NOT_BUILT_IN;
}
#endif /* CURLRES_THREADED */

View File

@@ -41,26 +41,12 @@
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
#include "curl_memory.h"
#include <unistd.h>
/* The last #include file should be: */
#include "memdebug.h"
#include "hostcheck.h"
/* SSL_read is opied from axTLS compat layer */
static int SSL_read(SSL *ssl, void *buf, int num)
{
uint8_t *read_buf;
int ret;
while((ret = ssl_read(ssl, &read_buf)) == SSL_OK);
if(ret > SSL_OK) {
memcpy(buf, read_buf, ret > num ? num : ret);
}
return ret;
}
/* Global axTLS init, called from Curl_ssl_init() */
int Curl_axtls_init(void)
{
@@ -131,31 +117,40 @@ static CURLcode map_error_to_curl(int axtls_err)
static Curl_recv axtls_recv;
static Curl_send axtls_send;
/*
* This function is called after the TCP connect has completed. Setup the TLS
* layer and do all necessary magic.
*/
CURLcode
Curl_axtls_connect(struct connectdata *conn,
int sockindex)
static void free_ssl_structs(struct ssl_connect_data *connssl)
{
if(connssl->ssl) {
ssl_free (connssl->ssl);
connssl->ssl = NULL;
}
if(connssl->ssl_ctx) {
ssl_ctx_free(connssl->ssl_ctx);
connssl->ssl_ctx = NULL;
}
}
/*
* For both blocking and non-blocking connects, this function sets up the
* ssl context and state. This function is called after the TCP connect
* has completed.
*/
static CURLcode connect_prep(struct connectdata *conn, int sockindex)
{
struct SessionHandle *data = conn->data;
SSL_CTX *ssl_ctx;
SSL *ssl;
SSL *ssl = NULL;
int cert_types[] = {SSL_OBJ_X509_CERT, SSL_OBJ_PKCS12, 0};
int key_types[] = {SSL_OBJ_RSA_KEY, SSL_OBJ_PKCS8, SSL_OBJ_PKCS12, 0};
int i, ssl_fcn_return;
const uint8_t *ssl_sessionid;
size_t ssl_idsize;
const char *peer_CN;
uint32_t dns_altname_index;
const char *dns_altname;
int8_t found_subject_alt_names = 0;
int8_t found_subject_alt_name_matching_conn = 0;
/* Assuming users will not compile in custom key/cert to axTLS */
uint32_t client_option = SSL_NO_DEFAULT_KEY|SSL_SERVER_VERIFY_LATER;
/* Assuming users will not compile in custom key/cert to axTLS.
* Also, even for blocking connects, use axTLS non-blocking feature.
*/
uint32_t client_option = SSL_NO_DEFAULT_KEY |
SSL_SERVER_VERIFY_LATER |
SSL_CONNECT_IN_PARTS;
if(conn->ssl[sockindex].state == ssl_connection_complete)
/* to make us tolerant against being called more than once for the
@@ -184,6 +179,9 @@ Curl_axtls_connect(struct connectdata *conn,
return CURLE_SSL_CONNECT_ERROR;
}
conn->ssl[sockindex].ssl_ctx = ssl_ctx;
conn->ssl[sockindex].ssl = NULL;
/* Load the trusted CA cert bundle file */
if(data->set.ssl.CAfile) {
if(ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT, data->set.ssl.CAfile, NULL)
@@ -191,7 +189,6 @@ Curl_axtls_connect(struct connectdata *conn,
infof(data, "error reading ca cert file %s \n",
data->set.ssl.CAfile);
if(data->set.ssl.verifypeer) {
Curl_axtls_close(conn, sockindex);
return CURLE_SSL_CACERT_BADFILE;
}
}
@@ -225,7 +222,6 @@ Curl_axtls_connect(struct connectdata *conn,
if(cert_types[i] == 0) {
failf(data, "%s is not x509 or pkcs12 format",
data->set.str[STRING_CERT]);
Curl_axtls_close(conn, sockindex);
return CURLE_SSL_CERTPROBLEM;
}
}
@@ -250,7 +246,6 @@ Curl_axtls_connect(struct connectdata *conn,
if(key_types[i] == 0) {
failf(data, "Failure: %s is not a supported key file",
data->set.str[STRING_KEY]);
Curl_axtls_close(conn, sockindex);
return CURLE_SSL_CONNECT_ERROR;
}
}
@@ -271,14 +266,25 @@ Curl_axtls_connect(struct connectdata *conn,
else
ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex], NULL, 0);
/* Check to make sure handshake was ok. */
ssl_fcn_return = ssl_handshake_status(ssl);
if(ssl_fcn_return != SSL_OK) {
Curl_axtls_close(conn, sockindex);
ssl_display_error(ssl_fcn_return); /* goes to stdout. */
return map_error_to_curl(ssl_fcn_return);
}
infof (data, "handshake completed successfully\n");
conn->ssl[sockindex].ssl = ssl;
return CURLE_OK;
}
/*
* For both blocking and non-blocking connects, this function finalizes the
* SSL connection.
*/
static CURLcode connect_finish(struct connectdata *conn, int sockindex)
{
struct SessionHandle *data = conn->data;
SSL *ssl = conn->ssl[sockindex].ssl;
const uint8_t *ssl_sessionid;
size_t ssl_idsize;
const char *peer_CN;
uint32_t dns_altname_index;
const char *dns_altname;
int8_t found_subject_alt_names = 0;
int8_t found_subject_alt_name_matching_conn = 0;
/* Here, gtls.c gets the peer certificates and fails out depending on
* settings in "data." axTLS api doesn't have get cert chain fcn, so omit?
@@ -289,7 +295,7 @@ Curl_axtls_connect(struct connectdata *conn,
if(ssl_verify_cert(ssl) != SSL_OK) {
Curl_axtls_close(conn, sockindex);
failf(data, "server cert verify failed");
return CURLE_SSL_CONNECT_ERROR;
return CURLE_PEER_FAILED_VERIFICATION;
}
}
else
@@ -306,7 +312,6 @@ Curl_axtls_connect(struct connectdata *conn,
* this, but a couple fields are available.
*/
/* There is no (DNS) Altnames count in the version 1.4.8 API. There is a
risk of an inifite loop */
for(dns_altname_index = 0; ; dns_altname_index++) {
@@ -326,20 +331,29 @@ Curl_axtls_connect(struct connectdata *conn,
/* RFC2818 checks */
if(found_subject_alt_names && !found_subject_alt_name_matching_conn) {
/* Break connection ! */
Curl_axtls_close(conn, sockindex);
failf(data, "\tsubjectAltName(s) do not match %s\n", conn->host.dispname);
return CURLE_PEER_FAILED_VERIFICATION;
if(data->set.ssl.verifyhost) {
/* Break connection ! */
Curl_axtls_close(conn, sockindex);
failf(data, "\tsubjectAltName(s) do not match %s\n",
conn->host.dispname);
return CURLE_PEER_FAILED_VERIFICATION;
}
else
infof(data, "\tsubjectAltName(s) do not match %s\n",
conn->host.dispname);
}
else if(found_subject_alt_names == 0) {
/* Per RFC2818, when no Subject Alt Names were available, examine the peer
CN as a legacy fallback */
peer_CN = ssl_get_cert_dn(ssl, SSL_X509_CERT_COMMON_NAME);
if(peer_CN == NULL) {
/* Similar behaviour to the OpenSSL interface */
Curl_axtls_close(conn, sockindex);
failf(data, "unable to obtain common name from peer certificate");
return CURLE_PEER_FAILED_VERIFICATION;
if(data->set.ssl.verifyhost) {
Curl_axtls_close(conn, sockindex);
failf(data, "unable to obtain common name from peer certificate");
return CURLE_PEER_FAILED_VERIFICATION;
}
else
infof(data, "unable to obtain common name from peer certificate");
}
else {
if(!Curl_cert_hostcheck((const char *)peer_CN, conn->host.name)) {
@@ -359,8 +373,6 @@ Curl_axtls_connect(struct connectdata *conn,
/* General housekeeping */
conn->ssl[sockindex].state = ssl_connection_complete;
conn->ssl[sockindex].ssl = ssl;
conn->ssl[sockindex].ssl_ctx = ssl_ctx;
conn->recv[sockindex] = axtls_recv;
conn->send[sockindex] = axtls_send;
@@ -374,6 +386,107 @@ Curl_axtls_connect(struct connectdata *conn,
return CURLE_OK;
}
/*
* Use axTLS's non-blocking connection feature to open an SSL connection.
* This is called after a TCP connection is already established.
*/
CURLcode Curl_axtls_connect_nonblocking(
struct connectdata *conn,
int sockindex,
bool *done)
{
CURLcode conn_step;
int ssl_fcn_return;
*done = FALSE;
/* connectdata is calloc'd and connecting_state is only changed in this
function, so this is safe, as the state is effectively initialized. */
if(conn->ssl[sockindex].connecting_state == ssl_connect_1) {
conn_step = connect_prep(conn, sockindex);
if(conn_step != CURLE_OK) {
Curl_axtls_close(conn, sockindex);
return conn_step;
}
conn->ssl[sockindex].connecting_state = ssl_connect_2;
}
if(conn->ssl[sockindex].connecting_state == ssl_connect_2) {
/* Check to make sure handshake was ok. */
if(ssl_handshake_status(conn->ssl[sockindex].ssl) != SSL_OK) {
ssl_fcn_return = ssl_read(conn->ssl[sockindex].ssl, NULL);
if(ssl_fcn_return < 0) {
Curl_axtls_close(conn, sockindex);
ssl_display_error(ssl_fcn_return); /* goes to stdout. */
return map_error_to_curl(ssl_fcn_return);
}
else {
return CURLE_OK; /* Return control to caller for retries */
}
}
infof (conn->data, "handshake completed successfully\n");
conn->ssl[sockindex].connecting_state = ssl_connect_3;
}
if(conn->ssl[sockindex].connecting_state == ssl_connect_3) {
conn_step = connect_finish(conn, sockindex);
if(conn_step != CURLE_OK) {
Curl_axtls_close(conn, sockindex);
return conn_step;
}
/* Reset connect state */
conn->ssl[sockindex].connecting_state = ssl_connect_1;
*done = TRUE;
return CURLE_OK;
}
/* Unrecognized state. Things are very bad. */
conn->ssl[sockindex].state = ssl_connection_none;
conn->ssl[sockindex].connecting_state = ssl_connect_1;
/* Return value perhaps not strictly correct, but distinguishes the issue.*/
return CURLE_BAD_FUNCTION_ARGUMENT;
}
/*
* This function is called after the TCP connect has completed. Setup the TLS
* layer and do all necessary magic for a blocking connect.
*/
CURLcode
Curl_axtls_connect(struct connectdata *conn,
int sockindex)
{
CURLcode conn_step = connect_prep(conn, sockindex);
int ssl_fcn_return;
SSL *ssl = conn->ssl[sockindex].ssl;
if(conn_step != CURLE_OK) {
Curl_axtls_close(conn, sockindex);
return conn_step;
}
/* Check to make sure handshake was ok. */
while(ssl_handshake_status(ssl) != SSL_OK) {
ssl_fcn_return = ssl_read(ssl, NULL);
if(ssl_fcn_return < 0) {
Curl_axtls_close(conn, sockindex);
ssl_display_error(ssl_fcn_return); /* goes to stdout. */
return map_error_to_curl(ssl_fcn_return);
}
usleep(10000);
}
infof (conn->data, "handshake completed successfully\n");
conn_step = connect_finish(conn, sockindex);
if(conn_step != CURLE_OK) {
Curl_axtls_close(conn, sockindex);
return conn_step;
}
return CURLE_OK;
}
/* return number of sent (non-SSL) bytes */
static ssize_t axtls_send(struct connectdata *conn,
@@ -407,7 +520,7 @@ void Curl_axtls_close(struct connectdata *conn, int sockindex)
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
infof(conn->data, " Curl_axtls_close\n");
if(connssl->ssl) {
/* line from ssluse.c: (void)SSL_shutdown(connssl->ssl);
axTLS compat layer does nothing for SSL_shutdown */
@@ -415,13 +528,7 @@ void Curl_axtls_close(struct connectdata *conn, int sockindex)
equivalent. ssl_free and ssl_ctx_free close things.
SSL_set_connect_state(connssl->handle); */
ssl_free (connssl->ssl);
connssl->ssl = NULL;
}
if(connssl->ssl_ctx) {
ssl_ctx_free (connssl->ssl_ctx);
connssl->ssl_ctx = NULL;
}
free_ssl_structs(connssl);
}
/*
@@ -436,8 +543,7 @@ int Curl_axtls_shutdown(struct connectdata *conn, int sockindex)
int retval = 0;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct SessionHandle *data = conn->data;
char buf[120]; /* We will use this for the OpenSSL error buffer, so it has
to be at least 120 bytes long. */
uint8_t *buf;
ssize_t nread;
infof(conn->data, " Curl_axtls_shutdown\n");
@@ -457,9 +563,10 @@ int Curl_axtls_shutdown(struct connectdata *conn, int sockindex)
CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
if(what > 0) {
/* Something to read, let's do it and hope that it is the close
notify alert from the server */
nread = (ssize_t)SSL_read(conn->ssl[sockindex].ssl, buf,
sizeof(buf));
notify alert from the server. buf is managed internally by
axTLS and will be released upon calling ssl_free via
free_ssl_structs. */
nread = (ssize_t)ssl_read(connssl->ssl, &buf);
if(nread < SSL_OK) {
failf(data, "close notify alert not received during shutdown");
@@ -476,8 +583,7 @@ int Curl_axtls_shutdown(struct connectdata *conn, int sockindex)
retval = -1;
}
ssl_free (connssl->ssl);
connssl->ssl = NULL;
free_ssl_structs(connssl);
}
return retval;
}
@@ -490,26 +596,36 @@ static ssize_t axtls_recv(struct connectdata *conn, /* connection data */
{
struct ssl_connect_data *connssl = &conn->ssl[num];
ssize_t ret = 0;
uint8_t *read_buf;
infof(conn->data, " axtls_recv\n");
*err = CURLE_OK;
if(connssl) {
ret = (ssize_t)SSL_read(conn->ssl[num].ssl, buf, (int)buffersize);
/* axTLS isn't terribly generous about error reporting */
/* With patched axTLS, SSL_CLOSE_NOTIFY=-3. Hard-coding until axTLS
team approves proposed fix. */
if(ret == -3 ) {
ret = ssl_read(connssl->ssl, &read_buf);
if(ret > SSL_OK) {
/* ssl_read returns SSL_OK if there is more data to read, so if it is
larger, then all data has been read already. */
memcpy(buf, read_buf,
(size_t)ret > buffersize ? buffersize : (size_t)ret);
}
else if(ret == SSL_OK) {
/* more data to be read, signal caller to call again */
*err = CURLE_AGAIN;
ret = -1;
}
else if(ret == -3) {
/* With patched axTLS, SSL_CLOSE_NOTIFY=-3. Hard-coding until axTLS
team approves proposed fix. */
Curl_axtls_close(conn, num);
}
else if(ret < 0) {
failf(conn->data, "axTLS recv error (%d)", (int)ret);
else {
failf(conn->data, "axTLS recv error (%d)", ret);
*err = map_error_to_curl(ret);
return -1;
ret = -1;
}
}
*err = CURLE_OK;
return ret;
}

View File

@@ -30,6 +30,10 @@
int Curl_axtls_init(void);
int Curl_axtls_cleanup(void);
CURLcode Curl_axtls_connect(struct connectdata *conn, int sockindex);
CURLcode Curl_axtls_connect_nonblocking(
struct connectdata *conn,
int sockindex,
bool *done);
/* tell axTLS to close down all open information regarding connections (and
thus session ID caching etc) */
@@ -47,6 +51,7 @@ int Curl_axtls_check_cxn(struct connectdata *conn);
#define curlssl_init Curl_axtls_init
#define curlssl_cleanup Curl_axtls_cleanup
#define curlssl_connect Curl_axtls_connect
#define curlssl_connect_nonblocking Curl_axtls_connect_nonblocking
#define curlssl_session_free(x) Curl_axtls_session_free(x)
#define curlssl_close_all Curl_axtls_close_all
#define curlssl_close Curl_axtls_close

View File

@@ -277,21 +277,27 @@
/* Define if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H
/* The following define is needed on OS400 to enable strcmpi(), stricmp() and
strdup(). */
#define __cplusplus__strings__
/* Define if you have the `strcasecmp' function. */
#undef HAVE_STRCASECMP
/* Define if you have the `strcmpi' function. */
#undef HAVE_STRCMPI
#define HAVE_STRCMPI
/* Define if you have the `stricmp' function. */
#define HAVE_STRICMP
/* Define if you have the `strdup' function. */
#undef HAVE_STRDUP
#define HAVE_STRDUP
/* Define if you have the `strftime' function. */
#define HAVE_STRFTIME
/* Define if you have the `stricmp' function. */
#undef HAVE_STRICMP
/* Define if you have the <strings.h> header file. */
#define HAVE_STRINGS_H
@@ -525,6 +531,9 @@
/* Define to use the QsoSSL package. */
#define USE_QSOSSL
/* Define to use the GSKit package. */
#undef USE_GSKIT
/* Use the system keyring as the default CA bundle. */
#define CURL_CA_BUNDLE "/QIBM/UserData/ICSS/Cert/Server/DEFAULT.KDB"

View File

@@ -390,21 +390,6 @@
# define SIZEOF_SIZE_T 4
#endif
/* ---------------------------------------------------------------- */
/* STRUCT RELATED */
/* ---------------------------------------------------------------- */
/* Define if you have struct sockaddr_storage. */
#if !defined(__SALFORDC__) && !defined(__BORLANDC__)
#define HAVE_STRUCT_SOCKADDR_STORAGE 1
#endif
/* Define if you have struct timeval. */
#define HAVE_STRUCT_TIMEVAL 1
/* Define if struct sockaddr_in6 has the sin6_scope_id member. */
#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
/* ---------------------------------------------------------------- */
/* BSD-style lwIP TCP/IP stack SPECIFIC */
/* ---------------------------------------------------------------- */
@@ -572,6 +557,25 @@
# endif
#endif
/* ---------------------------------------------------------------- */
/* STRUCT RELATED */
/* ---------------------------------------------------------------- */
/* Define if you have struct sockaddr_storage. */
#if !defined(__SALFORDC__) && !defined(__BORLANDC__)
#define HAVE_STRUCT_SOCKADDR_STORAGE 1
#endif
/* Define if you have struct timeval. */
#define HAVE_STRUCT_TIMEVAL 1
/* Define if struct sockaddr_in6 has the sin6_scope_id member. */
#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
#if HAVE_WINSOCK2_H && defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)
#define HAVE_STRUCT_POLLFD 1
#endif
/* ---------------------------------------------------------------- */
/* LARGE FILE SUPPORT */
/* ---------------------------------------------------------------- */

View File

@@ -38,8 +38,6 @@
/* The last #include file should be: */
#include "memdebug.h"
#define CONNECTION_HASH_SIZE 97
static void free_bundle_hash_entry(void *freethis)
{
struct connectbundle *b = (struct connectbundle *) freethis;
@@ -47,7 +45,7 @@ static void free_bundle_hash_entry(void *freethis)
Curl_bundle_destroy(b);
}
struct conncache *Curl_conncache_init(void)
struct conncache *Curl_conncache_init(int size)
{
struct conncache *connc;
@@ -55,7 +53,7 @@ struct conncache *Curl_conncache_init(void)
if(!connc)
return NULL;
connc->hash = Curl_hash_alloc(CONNECTION_HASH_SIZE, Curl_hash_str,
connc->hash = Curl_hash_alloc(size, Curl_hash_str,
Curl_str_key_compare, free_bundle_hash_entry);
if(!connc->hash) {

View File

@@ -27,7 +27,7 @@ struct conncache {
size_t num_connections;
};
struct conncache *Curl_conncache_init(void);
struct conncache *Curl_conncache_init(int size);
void Curl_conncache_destroy(struct conncache *connc);

View File

@@ -413,23 +413,22 @@ static CURLcode bindlocal(struct connectdata *conn,
if(af == AF_INET6) {
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
char *scope_ptr = strchr(myhost, '%');
if(scope_ptr) *(scope_ptr++) = 0;
if(scope_ptr)
*(scope_ptr++) = 0;
#endif
if(Curl_inet_pton(AF_INET6, myhost, &si6->sin6_addr) > 0) {
si6->sin6_family = AF_INET6;
si6->sin6_port = htons(port);
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
if(scope_ptr) {
/* The "myhost" string either comes from Curl_if2ip or
from Curl_printable_address. The latter returns only
numeric scope IDs and the former returns none at all.
So the scope ID, if present, is known to be numeric */
if(scope_ptr)
/* The "myhost" string either comes from Curl_if2ip or from
Curl_printable_address. The latter returns only numeric scope
IDs and the former returns none at all. So the scope ID, if
present, is known to be numeric */
si6->sin6_scope_id = atoi(scope_ptr);
}
}
#endif
sizeof_sa = sizeof(struct sockaddr_in6);
}
sizeof_sa = sizeof(struct sockaddr_in6);
}
else
#endif
@@ -1145,7 +1144,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
if(sockfd == CURL_SOCKET_BAD) {
/* no good connect was made */
failf(data, "couldn't connect to %s at %s:%d",
failf(data, "couldn't connect to %s at %s:%ld",
conn->bits.proxy?"proxy":"host",
conn->bits.proxy?conn->proxy.name:conn->host.name, conn->port);
return CURLE_COULDNT_CONNECT;
@@ -1240,7 +1239,7 @@ curl_socket_t Curl_getconnectinfo(struct SessionHandle *data,
* 'conn' can be NULL, beware!
*/
int Curl_closesocket(struct connectdata *conn,
curl_socket_t sock)
curl_socket_t sock)
{
if(conn && conn->fclosesocket) {
if((sock == conn->sock[SECONDARYSOCKET]) &&
@@ -1252,7 +1251,13 @@ int Curl_closesocket(struct connectdata *conn,
else
return conn->fclosesocket(conn->closesocket_client, sock);
}
return sclose(sock);
sclose(sock);
if(conn)
/* tell the multi-socket code about this */
Curl_multi_closed(conn, sock);
return 0;
}
/*

View File

@@ -89,6 +89,7 @@ Example set of cookies:
#include "strequal.h"
#include "strtok.h"
#include "sendf.h"
#include "slist.h"
#include "curl_memory.h"
#include "share.h"
#include "strtoofft.h"
@@ -106,6 +107,8 @@ static void freecookie(struct Cookie *co)
free(co->domain);
if(co->path)
free(co->path);
if(co->spath)
free(co->spath);
if(co->name)
free(co->name);
if(co->value)
@@ -143,6 +146,116 @@ static bool tailmatch(const char *cooke_domain, const char *hostname)
return FALSE;
}
/*
* matching cookie path and url path
* RFC6265 5.1.4 Paths and Path-Match
*/
static bool pathmatch(const char* cookie_path, const char* request_uri)
{
size_t cookie_path_len;
size_t uri_path_len;
char* uri_path = NULL;
char* pos;
bool ret = FALSE;
/* cookie_path must not have last '/' separator. ex: /sample */
cookie_path_len = strlen(cookie_path);
if(1 == cookie_path_len) {
/* cookie_path must be '/' */
return TRUE;
}
uri_path = strdup(request_uri);
if(!uri_path)
return FALSE;
pos = strchr(uri_path, '?');
if(pos)
*pos = 0x0;
/* #-fragments are already cut off! */
if(0 == strlen(uri_path) || uri_path[0] != '/') {
free(uri_path);
uri_path = strdup("/");
if(!uri_path)
return FALSE;
}
/* here, RFC6265 5.1.4 says
4. Output the characters of the uri-path from the first character up
to, but not including, the right-most %x2F ("/").
but URL path /hoge?fuga=xxx means /hoge/index.cgi?fuga=xxx in some site
without redirect.
Ignore this algorithm because /hoge is uri path for this case
(uri path is not /).
*/
uri_path_len = strlen(uri_path);
if(uri_path_len < cookie_path_len) {
ret = FALSE;
goto pathmatched;
}
/* not using checkprefix() because matching should be case-sensitive */
if(strncmp(cookie_path, uri_path, cookie_path_len)) {
ret = FALSE;
goto pathmatched;
}
/* The cookie-path and the uri-path are identical. */
if(cookie_path_len == uri_path_len) {
ret = TRUE;
goto pathmatched;
}
/* here, cookie_path_len < url_path_len */
if(uri_path[cookie_path_len] == '/') {
ret = TRUE;
goto pathmatched;
}
ret = FALSE;
pathmatched:
free(uri_path);
return ret;
}
/*
* cookie path sanitize
*/
static char *sanitize_cookie_path(const char *cookie_path)
{
size_t len;
char *new_path = strdup(cookie_path);
if(!new_path)
return NULL;
/* some stupid site sends path attribute with '"'. */
if(new_path[0] == '\"') {
memmove((void *)new_path, (const void *)(new_path + 1), strlen(new_path));
}
if(new_path[strlen(new_path) - 1] == '\"') {
new_path[strlen(new_path) - 1] = 0x0;
}
/* RFC6265 5.2.4 The Path Attribute */
if(new_path[0] != '/') {
/* Let cookie-path be the default-path. */
free(new_path);
new_path = strdup("/");
return new_path;
}
/* convert /hoge/ to /hoge */
len = strlen(new_path);
if(1 < len && new_path[len - 1] == '/') {
new_path[len - 1] = 0x0;
}
return new_path;
}
/*
* Load cookies from all given cookie files (CURLOPT_COOKIEFILE).
*/
@@ -177,6 +290,34 @@ static void strstore(char **str, const char *newstr)
*str = strdup(newstr);
}
/*
* remove_expired() removes expired cookies.
*/
static void remove_expired(struct CookieInfo *cookies)
{
struct Cookie *co, *nx, *pv;
curl_off_t now = (curl_off_t)time(NULL);
co = cookies->cookies;
pv = NULL;
while(co) {
nx = co->next;
if((co->expirestr || co->maxage) && co->expires < now) {
if(co == cookies->cookies) {
cookies->cookies = co->next;
}
else {
pv->next = co->next;
}
cookies->numcookies--;
freecookie(co);
}
else {
pv = co;
}
co = nx;
}
}
/****************************************************************************
*
@@ -184,6 +325,9 @@ static void strstore(char **str, const char *newstr)
*
* Add a single cookie line to the cookie keeping object.
*
* Be aware that sometimes we get an IP-only host name, and that might also be
* a numerical IPv6 address.
*
***************************************************************************/
struct Cookie *
@@ -288,72 +432,39 @@ Curl_cookie_add(struct SessionHandle *data,
badcookie = TRUE; /* out of memory bad */
break;
}
co->spath = sanitize_cookie_path(co->path);
if(!co->spath) {
badcookie = TRUE; /* out of memory bad */
break;
}
}
else if(Curl_raw_equal("domain", name)) {
/* note that this name may or may not have a preceding dot, but
we don't care about that, we treat the names the same anyway */
const char *domptr=whatptr;
const char *nextptr;
int dotcount=1;
/* Count the dots, we need to make sure that there are enough
of them. */
/* Now, we make sure that our host is within the given domain,
or the given domain is not valid and thus cannot be set. */
if('.' == whatptr[0])
/* don't count the initial dot, assume it */
domptr++;
whatptr++; /* ignore preceding dot */
do {
nextptr = strchr(domptr, '.');
if(nextptr) {
if(domptr != nextptr)
dotcount++;
domptr = nextptr+1;
if(!domain || tailmatch(whatptr, domain)) {
const char *tailptr=whatptr;
if(tailptr[0] == '.')
tailptr++;
strstore(&co->domain, tailptr); /* don't prefix w/dots
internally */
if(!co->domain) {
badcookie = TRUE;
break;
}
} while(nextptr);
/* The original Netscape cookie spec defined that this domain name
MUST have three dots (or two if one of the seven holy TLDs),
but it seems that these kinds of cookies are in use "out there"
so we cannot be that strict. I've therefore lowered the check
to not allow less than two dots. */
if(dotcount < 2) {
/* Received and skipped a cookie with a domain using too few
dots. */
badcookie=TRUE; /* mark this as a bad cookie */
infof(data, "skipped cookie with illegal dotcount domain: %s\n",
whatptr);
co->tailmatch=TRUE; /* we always do that if the domain name was
given */
}
else {
/* Now, we make sure that our host is within the given domain,
or the given domain is not valid and thus cannot be set. */
if('.' == whatptr[0])
whatptr++; /* ignore preceding dot */
if(!domain || tailmatch(whatptr, domain)) {
const char *tailptr=whatptr;
if(tailptr[0] == '.')
tailptr++;
strstore(&co->domain, tailptr); /* don't prefix w/dots
internally */
if(!co->domain) {
badcookie = TRUE;
break;
}
co->tailmatch=TRUE; /* we always do that if the domain name was
given */
}
else {
/* we did not get a tailmatch and then the attempted set domain
is not a domain to which the current host belongs. Mark as
bad. */
badcookie=TRUE;
infof(data, "skipped cookie with bad tailmatch domain: %s\n",
whatptr);
}
/* we did not get a tailmatch and then the attempted set domain
is not a domain to which the current host belongs. Mark as
bad. */
badcookie=TRUE;
infof(data, "skipped cookie with bad tailmatch domain: %s\n",
whatptr);
}
}
else if(Curl_raw_equal("version", name)) {
@@ -461,6 +572,9 @@ Curl_cookie_add(struct SessionHandle *data,
if(co->path) {
memcpy(co->path, path, pathlen);
co->path[pathlen]=0; /* zero terminate */
co->spath = sanitize_cookie_path(co->path);
if(!co->spath)
badcookie = TRUE; /* out of memory bad */
}
else
badcookie = TRUE;
@@ -512,12 +626,6 @@ Curl_cookie_add(struct SessionHandle *data,
firstptr=strtok_r(lineptr, "\t", &tok_buf); /* tokenize it on the TAB */
/* Here's a quick check to eliminate normal HTTP-headers from this */
if(!firstptr || strchr(firstptr, ':')) {
free(co);
return NULL;
}
/* Now loop through the fields and init the struct we already have
allocated */
for(ptr=firstptr, fields=0; ptr && !badcookie;
@@ -552,12 +660,21 @@ Curl_cookie_add(struct SessionHandle *data,
co->path = strdup(ptr);
if(!co->path)
badcookie = TRUE;
else {
co->spath = sanitize_cookie_path(co->path);
if(!co->spath) {
badcookie = TRUE; /* out of memory bad */
}
}
break;
}
/* this doesn't look like a path, make one up! */
co->path = strdup("/");
if(!co->path)
badcookie = TRUE;
co->spath = strdup("/");
if(!co->spath)
badcookie = TRUE;
fields++; /* add a field and fall down to secure */
/* FALLTHROUGH */
case 3:
@@ -611,6 +728,9 @@ Curl_cookie_add(struct SessionHandle *data,
superceeds an already existing cookie, which it may if the previous have
the same domain and path as this */
/* at first, remove expired cookies */
remove_expired(c);
clist = c->cookies;
replace_old = FALSE;
while(clist) {
@@ -628,14 +748,14 @@ Curl_cookie_add(struct SessionHandle *data,
if(replace_old) {
/* the domains were identical */
if(clist->path && co->path) {
if(Curl_raw_equal(clist->path, co->path)) {
if(clist->spath && co->spath) {
if(Curl_raw_equal(clist->spath, co->spath)) {
replace_old = TRUE;
}
else
replace_old = FALSE;
}
else if(!clist->path && !co->path)
else if(!clist->spath && !co->spath)
replace_old = TRUE;
else
replace_old = FALSE;
@@ -664,6 +784,8 @@ Curl_cookie_add(struct SessionHandle *data,
free(clist->domain);
if(clist->path)
free(clist->path);
if(clist->spath)
free(clist->spath);
if(clist->expirestr)
free(clist->expirestr);
@@ -840,6 +962,9 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
if(!c || !c->cookies)
return NULL; /* no cookie struct or no cookies in the struct */
/* at first, remove expired cookies */
remove_expired(c);
co = c->cookies;
while(co) {
@@ -858,10 +983,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
/* now check the left part of the path with the cookies path
requirement */
if(!co->path ||
/* not using checkprefix() because matching should be
case-sensitive */
!strncmp(co->path, path, strlen(co->path)) ) {
if(!co->spath || pathmatch(co->spath, path) ) {
/* and now, we know this is a match and we should create an
entry for the return-linked-list */
@@ -1085,6 +1207,9 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
destination file */
return 0;
/* at first, remove expired cookies */
remove_expired(c);
if(strequal("-", dumphere)) {
/* use stdout */
out = stdout;
@@ -1145,9 +1270,9 @@ struct curl_slist *Curl_cookie_list(struct SessionHandle *data)
curl_slist_free_all(list);
return NULL;
}
beg = curl_slist_append(list, line);
free(line);
beg = Curl_slist_append_nodup(list, line);
if(!beg) {
free(line);
curl_slist_free_all(list);
return NULL;
}

View File

@@ -29,7 +29,8 @@ struct Cookie {
struct Cookie *next; /* next in the chain */
char *name; /* <this> = value */
char *value; /* name = <this> */
char *path; /* path = <this> */
char *path; /* path = <this> which is in Set-Cookie: */
char *spath; /* sanitized cookie path */
char *domain; /* domain = <this> */
curl_off_t expires; /* expires = <this> */
char *expirestr; /* the plain text version */

View File

@@ -38,9 +38,58 @@
#include <Security/SecureTransport.h>
#include <CoreFoundation/CoreFoundation.h>
#include <CommonCrypto/CommonDigest.h>
/* The Security framework has changed greatly between iOS and different OS X
versions, and we will try to support as many of them as we can (back to
Leopard and iOS 5) by using macros and weak-linking.
IMPORTANT: If TLS 1.1 and 1.2 support are important for you on OS X, then
you must build this project against the 10.8 SDK or later. */
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
#error "The darwinssl back-end requires Leopard or later."
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1050 */
#define CURL_BUILD_IOS 0
#define CURL_BUILD_IOS_7 0
#define CURL_BUILD_MAC 1
/* This is the maximum API level we are allowed to use when building: */
#define CURL_BUILD_MAC_10_5 MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
#define CURL_BUILD_MAC_10_6 MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
#define CURL_BUILD_MAC_10_7 MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
#define CURL_BUILD_MAC_10_8 MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
#define CURL_BUILD_MAC_10_9 MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
/* These macros mean "the following code is present to allow runtime backward
compatibility with at least this cat or earlier":
(You set this at build-time by setting the MACOSX_DEPLOYMENT_TARGET
environmental variable.) */
#define CURL_SUPPORT_MAC_10_5 MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
#define CURL_SUPPORT_MAC_10_6 MAC_OS_X_VERSION_MIN_REQUIRED <= 1060
#define CURL_SUPPORT_MAC_10_7 MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
#define CURL_SUPPORT_MAC_10_8 MAC_OS_X_VERSION_MIN_REQUIRED <= 1080
#define CURL_SUPPORT_MAC_10_9 MAC_OS_X_VERSION_MIN_REQUIRED <= 1090
#elif TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
#define CURL_BUILD_IOS 1
#define CURL_BUILD_IOS_7 __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
#define CURL_BUILD_MAC 0
#define CURL_BUILD_MAC_10_5 0
#define CURL_BUILD_MAC_10_6 0
#define CURL_BUILD_MAC_10_7 0
#define CURL_BUILD_MAC_10_8 0
#define CURL_SUPPORT_MAC_10_5 0
#define CURL_SUPPORT_MAC_10_6 0
#define CURL_SUPPORT_MAC_10_7 0
#define CURL_SUPPORT_MAC_10_8 0
#else
#error "The darwinssl back-end requires iOS or OS X."
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
#if CURL_BUILD_MAC
#include <sys/sysctl.h>
#endif
#endif /* CURL_BUILD_MAC */
#include "urldata.h"
#include "sendf.h"
@@ -61,16 +110,6 @@
#define ioErr -36
#define paramErr -50
/* In Mountain Lion and iOS 5, Apple made some changes to the API. They
added TLS 1.1 and 1.2 support, and deprecated and replaced some
functions. You need to build against the Mountain Lion or iOS 5 SDK
or later to get TLS 1.1 or 1.2 support working in cURL. We'll weak-link
to the newer functions and use them if present in the user's OS.
Builders: If you want TLS 1.1 and 1.2 but still want to retain support
for older cats, don't forget to set the MACOSX_DEPLOYMENT_TARGET
environmental variable prior to building cURL. */
/* The following two functions were ripped from Apple sample code,
* with some modifications: */
static OSStatus SocketRead(SSLConnectionRef connection,
@@ -361,7 +400,7 @@ CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) {
case TLS_DH_anon_WITH_AES_256_CBC_SHA:
return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
break;
#if defined(__MAC_10_6) || defined(__IPHONE_5_0)
#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
/* TLS 1.0 with ECDSA (RFC 4492) */
case TLS_ECDH_ECDSA_WITH_NULL_SHA:
return "TLS_ECDH_ECDSA_WITH_NULL_SHA";
@@ -438,8 +477,8 @@ CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) {
case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA";
break;
#endif /* defined(__MAC_10_6) || defined(__IPHONE_5_0) */
#if defined(__MAC_10_8) || defined(__IPHONE_5_0)
#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
/* TLS 1.2 (RFC 5246) */
case TLS_RSA_WITH_NULL_MD5:
return "TLS_RSA_WITH_NULL_MD5";
@@ -624,12 +663,116 @@ CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) {
case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
break;
#endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */
#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
/* TLS PSK (RFC 4279): */
case TLS_PSK_WITH_RC4_128_SHA:
return "TLS_PSK_WITH_RC4_128_SHA";
break;
case TLS_PSK_WITH_3DES_EDE_CBC_SHA:
return "TLS_PSK_WITH_3DES_EDE_CBC_SHA";
break;
case TLS_PSK_WITH_AES_128_CBC_SHA:
return "TLS_PSK_WITH_AES_128_CBC_SHA";
break;
case TLS_PSK_WITH_AES_256_CBC_SHA:
return "TLS_PSK_WITH_AES_256_CBC_SHA";
break;
case TLS_DHE_PSK_WITH_RC4_128_SHA:
return "TLS_DHE_PSK_WITH_RC4_128_SHA";
break;
case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
return "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA";
break;
case TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA";
break;
case TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA";
break;
case TLS_RSA_PSK_WITH_RC4_128_SHA:
return "TLS_RSA_PSK_WITH_RC4_128_SHA";
break;
case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
return "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA";
break;
case TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA";
break;
case TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA";
break;
/* More TLS PSK (RFC 4785): */
case TLS_PSK_WITH_NULL_SHA:
return "TLS_PSK_WITH_NULL_SHA";
break;
case TLS_DHE_PSK_WITH_NULL_SHA:
return "TLS_DHE_PSK_WITH_NULL_SHA";
break;
case TLS_RSA_PSK_WITH_NULL_SHA:
return "TLS_RSA_PSK_WITH_NULL_SHA";
break;
/* Even more TLS PSK (RFC 5487): */
case TLS_PSK_WITH_AES_128_GCM_SHA256:
return "TLS_PSK_WITH_AES_128_GCM_SHA256";
break;
case TLS_PSK_WITH_AES_256_GCM_SHA384:
return "TLS_PSK_WITH_AES_256_GCM_SHA384";
break;
case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256";
break;
case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384";
break;
case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
return "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256";
break;
case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
return "TLS_PSK_WITH_AES_256_GCM_SHA384";
break;
case TLS_PSK_WITH_AES_128_CBC_SHA256:
return "TLS_PSK_WITH_AES_128_CBC_SHA256";
break;
case TLS_PSK_WITH_AES_256_CBC_SHA384:
return "TLS_PSK_WITH_AES_256_CBC_SHA384";
break;
case TLS_PSK_WITH_NULL_SHA256:
return "TLS_PSK_WITH_NULL_SHA256";
break;
case TLS_PSK_WITH_NULL_SHA384:
return "TLS_PSK_WITH_NULL_SHA384";
break;
case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256";
break;
case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384";
break;
case TLS_DHE_PSK_WITH_NULL_SHA256:
return "TLS_DHE_PSK_WITH_NULL_SHA256";
break;
case TLS_DHE_PSK_WITH_NULL_SHA384:
return "TLS_RSA_PSK_WITH_NULL_SHA384";
break;
case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256";
break;
case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384";
break;
case TLS_RSA_PSK_WITH_NULL_SHA256:
return "TLS_RSA_PSK_WITH_NULL_SHA256";
break;
case TLS_RSA_PSK_WITH_NULL_SHA384:
return "TLS_RSA_PSK_WITH_NULL_SHA384";
break;
#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
}
return "TLS_NULL_WITH_NULL_NULL";
}
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if CURL_BUILD_MAC
CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
{
int mib[2];
@@ -658,7 +801,7 @@ CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
*minor = atoi(os_version_minor);
free(os_version);
}
#endif
#endif /* CURL_BUILD_MAC */
/* Apple provides a myriad of ways of getting information about a certificate
into a string. Some aren't available under iOS or newer cats. So here's
@@ -668,29 +811,184 @@ CF_INLINE CFStringRef CopyCertSubject(SecCertificateRef cert)
{
CFStringRef server_cert_summary = CFSTR("(null)");
#if (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)
#if CURL_BUILD_IOS
/* iOS: There's only one way to do this. */
server_cert_summary = SecCertificateCopySubjectSummary(cert);
#else
#if defined(__MAC_10_7)
#if CURL_BUILD_MAC_10_7
/* Lion & later: Get the long description if we can. */
if(SecCertificateCopyLongDescription != NULL)
server_cert_summary =
SecCertificateCopyLongDescription(NULL, cert, NULL);
else
#endif /* defined(__MAC_10_7) */
#if defined(__MAC_10_6)
#endif /* CURL_BUILD_MAC_10_7 */
#if CURL_BUILD_MAC_10_6
/* Snow Leopard: Get the certificate summary. */
if(SecCertificateCopySubjectSummary != NULL)
server_cert_summary = SecCertificateCopySubjectSummary(cert);
else
#endif /* defined(__MAC_10_6) */
#endif /* CURL_BUILD_MAC_10_6 */
/* Leopard is as far back as we go... */
(void)SecCertificateCopyCommonName(cert, &server_cert_summary);
#endif /* (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) */
#endif /* CURL_BUILD_IOS */
return server_cert_summary;
}
#if CURL_SUPPORT_MAC_10_7
/* The SecKeychainSearch API was deprecated in Lion, and using it will raise
deprecation warnings, so let's not compile this unless it's necessary: */
static OSStatus CopyIdentityWithLabelOldSchool(char *label,
SecIdentityRef *out_c_a_k)
{
OSStatus status = errSecItemNotFound;
SecKeychainAttributeList attr_list;
SecKeychainAttribute attr;
SecKeychainSearchRef search = NULL;
SecCertificateRef cert = NULL;
/* Set up the attribute list: */
attr_list.count = 1L;
attr_list.attr = &attr;
/* Set up our lone search criterion: */
attr.tag = kSecLabelItemAttr;
attr.data = label;
attr.length = (UInt32)strlen(label);
/* Start searching: */
status = SecKeychainSearchCreateFromAttributes(NULL,
kSecCertificateItemClass,
&attr_list,
&search);
if(status == noErr) {
status = SecKeychainSearchCopyNext(search,
(SecKeychainItemRef *)&cert);
if(status == noErr && cert) {
/* If we found a certificate, does it have a private key? */
status = SecIdentityCreateWithCertificate(NULL, cert, out_c_a_k);
CFRelease(cert);
}
}
if(search)
CFRelease(search);
return status;
}
#endif /* CURL_SUPPORT_MAC_10_7 */
static OSStatus CopyIdentityWithLabel(char *label,
SecIdentityRef *out_cert_and_key)
{
OSStatus status = errSecItemNotFound;
#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
/* SecItemCopyMatching() was introduced in iOS and Snow Leopard.
kSecClassIdentity was introduced in Lion. If both exist, let's use them
to find the certificate. */
if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) {
CFTypeRef keys[4];
CFTypeRef values[4];
CFDictionaryRef query_dict;
CFStringRef label_cf = CFStringCreateWithCString(NULL, label,
kCFStringEncodingUTF8);
/* Set up our search criteria and expected results: */
values[0] = kSecClassIdentity; /* we want a certificate and a key */
keys[0] = kSecClass;
values[1] = kCFBooleanTrue; /* we want a reference */
keys[1] = kSecReturnRef;
values[2] = kSecMatchLimitOne; /* one is enough, thanks */
keys[2] = kSecMatchLimit;
/* identity searches need a SecPolicyRef in order to work */
values[3] = SecPolicyCreateSSL(false, label_cf);
keys[3] = kSecMatchPolicy;
query_dict = CFDictionaryCreate(NULL, (const void **)keys,
(const void **)values, 4L,
&kCFCopyStringDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFRelease(values[3]);
CFRelease(label_cf);
/* Do we have a match? */
status = SecItemCopyMatching(query_dict, (CFTypeRef *)out_cert_and_key);
CFRelease(query_dict);
}
else {
#if CURL_SUPPORT_MAC_10_7
/* On Leopard and Snow Leopard, fall back to SecKeychainSearch. */
status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
#endif /* CURL_SUPPORT_MAC_10_7 */
}
#elif CURL_SUPPORT_MAC_10_7
/* For developers building on older cats, we have no choice but to fall back
to SecKeychainSearch. */
status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
return status;
}
static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
const char *cPassword,
SecIdentityRef *out_cert_and_key)
{
OSStatus status = errSecItemNotFound;
CFURLRef pkcs_url = CFURLCreateFromFileSystemRepresentation(NULL,
(const UInt8 *)cPath, strlen(cPath), false);
CFStringRef password = cPassword ? CFStringCreateWithCString(NULL,
cPassword, kCFStringEncodingUTF8) : NULL;
CFDataRef pkcs_data = NULL;
/* We can import P12 files on iOS or OS X 10.6 or later: */
#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
if(CFURLCreateDataAndPropertiesFromResource(NULL, pkcs_url, &pkcs_data,
NULL, NULL, &status)) {
const void *cKeys[] = {kSecImportExportPassphrase};
const void *cValues[] = {password};
CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues,
password ? 1L : 0L, NULL, NULL);
CFArrayRef items = NULL;
/* Here we go: */
status = SecPKCS12Import(pkcs_data, options, &items);
if(status == noErr) {
CFDictionaryRef identity_and_trust = CFArrayGetValueAtIndex(items, 0L);
const void *temp_identity = CFDictionaryGetValue(identity_and_trust,
kSecImportItemIdentity);
/* Retain the identity; we don't care about any other data... */
CFRetain(temp_identity);
*out_cert_and_key = (SecIdentityRef)temp_identity;
CFRelease(items);
}
CFRelease(options);
CFRelease(pkcs_data);
}
#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
if(password)
CFRelease(password);
CFRelease(pkcs_url);
return status;
}
/* This code was borrowed from nss.c, with some modifications:
* Determine whether the nickname passed in is a filename that needs to
* be loaded as a PEM or a regular NSS nickname.
*
* returns 1 for a file
* returns 0 for not a file
*/
CF_INLINE bool is_file(const char *filename)
{
struct_stat st;
if(filename == NULL)
return false;
if(stat(filename, &st) == 0)
return S_ISREG(st.st_mode);
return false;
}
static CURLcode darwinssl_connect_step1(struct connectdata *conn,
int sockindex)
{
@@ -701,17 +999,19 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
struct in6_addr addr;
#else
struct in_addr addr;
#endif
#endif /* ENABLE_IPV6 */
size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL;
char *ssl_sessionid;
size_t ssl_sessionid_len;
OSStatus err = noErr;
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if CURL_BUILD_MAC
int darwinver_maj = 0, darwinver_min = 0;
GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
#endif
#endif /* CURL_BUILD_MAC */
#if defined(__MAC_10_8) || defined(__IPHONE_5_0)
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
if(SSLCreateContext != NULL) { /* use the newer API if avaialble */
if(connssl->ssl_ctx)
CFRelease(connssl->ssl_ctx);
@@ -723,7 +1023,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
}
else {
/* The old ST API does not exist under iOS, so don't compile it: */
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if CURL_SUPPORT_MAC_10_8
if(connssl->ssl_ctx)
(void)SSLDisposeContext(connssl->ssl_ctx);
err = SSLNewContext(false, &(connssl->ssl_ctx));
@@ -731,7 +1031,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
failf(data, "SSL: couldn't create a context: OSStatus %d", err);
return CURLE_OUT_OF_MEMORY;
}
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
#endif /* CURL_SUPPORT_MAC_10_8 */
}
#else
if(connssl->ssl_ctx)
@@ -741,11 +1041,11 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
failf(data, "SSL: couldn't create a context: OSStatus %d", err);
return CURLE_OUT_OF_MEMORY;
}
#endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */
#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
connssl->ssl_write_buffered_length = 0UL; /* reset buffered write length */
/* check to see if we've been told to use an explicit SSL/TLS version */
#if defined(__MAC_10_8) || defined(__IPHONE_5_0)
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
if(SSLSetProtocolVersionMax != NULL) {
switch(data->set.ssl.version) {
case CURL_SSLVERSION_DEFAULT: default:
@@ -761,12 +1061,16 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
break;
case CURL_SSLVERSION_SSLv2:
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2);
err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2);
if(err != noErr) {
failf(data, "Your version of the OS does not support SSLv2");
return CURLE_SSL_CONNECT_ERROR;
}
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol2);
}
}
else {
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if CURL_SUPPORT_MAC_10_8
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
kSSLProtocolAll,
false);
@@ -802,12 +1106,16 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
true);
break;
case CURL_SSLVERSION_SSLv2:
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
kSSLProtocol2,
true);
if(err != noErr) {
failf(data, "Your version of the OS does not support SSLv2");
return CURLE_SSL_CONNECT_ERROR;
}
break;
}
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
#endif /* CURL_SUPPORT_MAC_10_8 */
}
#else
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
@@ -827,9 +1135,13 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
true);
break;
case CURL_SSLVERSION_SSLv2:
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
kSSLProtocol2,
true);
if(err != noErr) {
failf(data, "Your version of the OS does not support SSLv2");
return CURLE_SSL_CONNECT_ERROR;
}
break;
case CURL_SSLVERSION_SSLv3:
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
@@ -837,16 +1149,104 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
true);
break;
}
#endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */
#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
/* No need to load certificates here. SecureTransport uses the Keychain
* (which is also part of the Security framework) to evaluate trust. */
if(data->set.str[STRING_KEY]) {
infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
"Transport. The private key must be in the Keychain.\n");
}
if(data->set.str[STRING_CERT]) {
SecIdentityRef cert_and_key = NULL;
bool is_cert_file = is_file(data->set.str[STRING_CERT]);
/* User wants to authenticate with a client cert. Look for it:
If we detect that this is a file on disk, then let's load it.
Otherwise, assume that the user wants to use an identity loaded
from the Keychain. */
if(is_cert_file) {
if(!data->set.str[STRING_CERT_TYPE])
infof(data, "WARNING: SSL: Certificate type not set, assuming "
"PKCS#12 format.\n");
else if(strncmp(data->set.str[STRING_CERT_TYPE], "P12",
strlen(data->set.str[STRING_CERT_TYPE])) != 0)
infof(data, "WARNING: SSL: The Security framework only supports "
"loading identities that are in PKCS#12 format.\n");
err = CopyIdentityFromPKCS12File(data->set.str[STRING_CERT],
data->set.str[STRING_KEY_PASSWD], &cert_and_key);
}
else
err = CopyIdentityWithLabel(data->set.str[STRING_CERT], &cert_and_key);
if(err == noErr) {
SecCertificateRef cert = NULL;
CFTypeRef certs_c[1];
CFArrayRef certs;
/* If we found one, print it out: */
err = SecIdentityCopyCertificate(cert_and_key, &cert);
if(err == noErr) {
CFStringRef cert_summary = CopyCertSubject(cert);
char cert_summary_c[128];
if(cert_summary) {
memset(cert_summary_c, 0, 128);
if(CFStringGetCString(cert_summary,
cert_summary_c,
128,
kCFStringEncodingUTF8)) {
infof(data, "Client certificate: %s\n", cert_summary_c);
}
CFRelease(cert_summary);
CFRelease(cert);
}
}
certs_c[0] = cert_and_key;
certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
&kCFTypeArrayCallBacks);
err = SSLSetCertificate(connssl->ssl_ctx, certs);
if(certs)
CFRelease(certs);
if(err != noErr) {
failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err);
return CURLE_SSL_CERTPROBLEM;
}
CFRelease(cert_and_key);
}
else {
switch(err) {
case errSecPkcs12VerifyFailure: case errSecAuthFailed:
failf(data, "SSL: Incorrect password for the certificate \"%s\" "
"and its private key.", data->set.str[STRING_CERT]);
break;
case errSecDecode: case errSecUnknownFormat:
failf(data, "SSL: Couldn't make sense of the data in the "
"certificate \"%s\" and its private key.",
data->set.str[STRING_CERT]);
break;
case errSecPassphraseRequired:
failf(data, "SSL The certificate \"%s\" requires a password.",
data->set.str[STRING_CERT]);
break;
case errSecItemNotFound:
failf(data, "SSL: Can't find the certificate \"%s\" and its private "
"key in the Keychain.", data->set.str[STRING_CERT]);
break;
default:
failf(data, "SSL: Can't load the certificate \"%s\" and its private "
"key: OSStatus %d", data->set.str[STRING_CERT], err);
break;
}
return CURLE_SSL_CERTPROBLEM;
}
}
/* SSL always tries to verify the peer, this only says whether it should
* fail to connect if the verification fails, or if it should continue
* anyway. In the latter case the result of the verification is checked with
* SSL_get_verify_result() below. */
#if defined(__MAC_10_6) || defined(__IPHONE_5_0)
#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
/* Snow Leopard introduced the SSLSetSessionOption() function, but due to
a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag
works, it doesn't work as expected under Snow Leopard or Lion.
@@ -855,11 +1255,11 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
(SecureTransport will always validate the certificate chain by
default.) */
/* (Note: Darwin 12.x.x is Mountain Lion.) */
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if CURL_BUILD_MAC
if(SSLSetSessionOption != NULL && darwinver_maj >= 12) {
#else
if(SSLSetSessionOption != NULL) {
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
#endif /* CURL_BUILD_MAC */
err = SSLSetSessionOption(connssl->ssl_ctx,
kSSLSessionOptionBreakOnServerAuth,
data->set.ssl.verifypeer?false:true);
@@ -869,14 +1269,14 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
}
}
else {
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if CURL_SUPPORT_MAC_10_8
err = SSLSetEnableCertVerify(connssl->ssl_ctx,
data->set.ssl.verifypeer?true:false);
if(err != noErr) {
failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
return CURLE_SSL_CONNECT_ERROR;
}
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
#endif /* CURL_SUPPORT_MAC_10_8 */
}
#else
err = SSLSetEnableCertVerify(connssl->ssl_ctx,
@@ -885,7 +1285,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
return CURLE_SSL_CONNECT_ERROR;
}
#endif /* defined(__MAC_10_6) || defined(__IPHONE_5_0) */
#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
/* If this is a domain name and not an IP address, then configure SNI.
* Also: the verifyhost setting influences SNI usage */
@@ -898,7 +1298,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
err = SSLSetPeerDomainName(connssl->ssl_ctx, conn->host.name,
strlen(conn->host.name));
if(err != noErr) {
infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d",
infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n",
err);
}
}
@@ -915,7 +1315,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
SSLGetSupportedCiphers(connssl->ssl_ctx, all_ciphers,
&all_ciphers_count) == noErr) {
for(i = 0UL ; i < all_ciphers_count ; i++) {
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if CURL_BUILD_MAC
/* There's a known bug in early versions of Mountain Lion where ST's ECC
ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
Work around the problem here by disabling those ciphers if we are
@@ -924,17 +1324,27 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
continue;
}
#endif
#endif /* CURL_BUILD_MAC */
switch(all_ciphers[i]) {
/* Disable NULL ciphersuites: */
case SSL_NULL_WITH_NULL_NULL:
case SSL_RSA_WITH_NULL_MD5:
case SSL_RSA_WITH_NULL_SHA:
case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */
case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */
case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */
case 0x002C: /* TLS_PSK_WITH_NULL_SHA */
case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */
case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */
case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */
case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */
case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */
case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */
case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */
case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */
/* Disable anonymous ciphersuites: */
case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
case SSL_DH_anon_WITH_RC4_128_MD5:
@@ -990,6 +1400,45 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
Curl_safefree(all_ciphers);
Curl_safefree(allowed_ciphers);
#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
/* We want to enable 1/n-1 when using a CBC cipher unless the user
specifically doesn't want us doing that: */
SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
!data->set.ssl_enable_beast);
#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
/* Check if there's a cached ID we can/should use here! */
if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid,
&ssl_sessionid_len)) {
/* we got a session id, use it! */
err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
if(err != noErr) {
failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
return CURLE_SSL_CONNECT_ERROR;
}
/* Informational message */
infof(data, "SSL re-using session ID\n");
}
/* If there isn't one, then let's make one up! This has to be done prior
to starting the handshake. */
else {
CURLcode retcode;
ssl_sessionid = malloc(256*sizeof(char));
ssl_sessionid_len = snprintf(ssl_sessionid, 256, "curl:%s:%hu",
conn->host.name, conn->remote_port);
err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
if(err != noErr) {
failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
return CURLE_SSL_CONNECT_ERROR;
}
retcode = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len);
if(retcode!= CURLE_OK) {
failf(data, "failed to store ssl session");
return retcode;
}
}
err = SSLSetIOFuncs(connssl->ssl_ctx, SocketRead, SocketWrite);
if(err != noErr) {
failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
@@ -1059,6 +1508,20 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
"certificate format");
return CURLE_SSL_CONNECT_ERROR;
/* These are all certificate problems with the client: */
case errSecAuthFailed:
failf(data, "SSL authentication failed");
return CURLE_SSL_CONNECT_ERROR;
case errSSLPeerHandshakeFail:
failf(data, "SSL peer handshake failed, the server most likely "
"requires a client certificate to connect");
return CURLE_SSL_CONNECT_ERROR;
case errSSLPeerUnknownCA:
failf(data, "SSL server rejected the client certificate due to "
"the certificate being signed by an unknown certificate "
"authority");
return CURLE_SSL_CONNECT_ERROR;
/* This error is raised if the server's cert didn't match the server's
host name: */
case errSSLHostNameMismatch:
@@ -1111,7 +1574,7 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
infof(data, "TLS 1.0 connection using %s\n",
TLSCipherNameForNumber(cipher));
break;
#if defined(__MAC_10_8) || defined(__IPHONE_5_0)
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
case kTLSProtocol11:
infof(data, "TLS 1.1 connection using %s\n",
TLSCipherNameForNumber(cipher));
@@ -1138,20 +1601,22 @@ darwinssl_connect_step3(struct connectdata *conn,
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
CFStringRef server_cert_summary;
char server_cert_summary_c[128];
CFArrayRef server_certs;
CFArrayRef server_certs = NULL;
SecCertificateRef server_cert;
OSStatus err;
CFIndex i, count;
SecTrustRef trust;
SecTrustRef trust = NULL;
/* There is no step 3!
* Well, okay, if verbose mode is on, let's print the details of the
* server certificates. */
#if defined(__MAC_10_7) || defined(__IPHONE_5_0)
#if (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)
#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
#if CURL_BUILD_IOS
#pragma unused(server_certs)
err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
if(err == noErr) {
/* For some reason, SSLCopyPeerTrust() can return noErr and yet return
a null trust, so be on guard for that: */
if(err == noErr && trust) {
count = SecTrustGetCertificateCount(trust);
for(i = 0L ; i < count ; i++) {
server_cert = SecTrustGetCertificateAtIndex(trust, i);
@@ -1177,7 +1642,9 @@ darwinssl_connect_step3(struct connectdata *conn,
if(SecTrustEvaluateAsync != NULL) {
#pragma unused(server_certs)
err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
if(err == noErr) {
/* For some reason, SSLCopyPeerTrust() can return noErr and yet return
a null trust, so be on guard for that: */
if(err == noErr && trust) {
count = SecTrustGetCertificateCount(trust);
for(i = 0L ; i < count ; i++) {
server_cert = SecTrustGetCertificateAtIndex(trust, i);
@@ -1195,8 +1662,10 @@ darwinssl_connect_step3(struct connectdata *conn,
}
}
else {
#if CURL_SUPPORT_MAC_10_8
err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
if(err == noErr) {
/* Just in case SSLCopyPeerCertificates() returns null too... */
if(err == noErr && server_certs) {
count = CFArrayGetCount(server_certs);
for(i = 0L ; i < count ; i++) {
server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
@@ -1214,8 +1683,9 @@ darwinssl_connect_step3(struct connectdata *conn,
}
CFRelease(server_certs);
}
#endif /* CURL_SUPPORT_MAC_10_8 */
}
#endif /* (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) */
#endif /* CURL_BUILD_IOS */
#else
#pragma unused(trust)
err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
@@ -1235,7 +1705,7 @@ darwinssl_connect_step3(struct connectdata *conn,
}
CFRelease(server_certs);
}
#endif /* defined(__MAC_10_7) || defined(__IPHONE_5_0) */
#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
connssl->connecting_state = ssl_connect_done;
return CURLE_OK;
@@ -1387,16 +1857,16 @@ void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
if(connssl->ssl_ctx) {
(void)SSLClose(connssl->ssl_ctx);
#if defined(__MAC_10_8) || defined(__IPHONE_5_0)
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
if(SSLCreateContext != NULL)
CFRelease(connssl->ssl_ctx);
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if CURL_SUPPORT_MAC_10_8
else
(void)SSLDisposeContext(connssl->ssl_ctx);
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
#endif /* CURL_SUPPORT_MAC_10_8 */
#else
(void)SSLDisposeContext(connssl->ssl_ctx);
#endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */
#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
connssl->ssl_ctx = NULL;
}
connssl->ssl_sockfd = 0;
@@ -1462,6 +1932,17 @@ int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
return rc;
}
void Curl_darwinssl_session_free(void *ptr)
{
/* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a
cached session ID inside the Security framework. There is a private
function that does this, but I don't want to have to explain to you why I
got your application rejected from the App Store due to the use of a
private API, so the best we can do is free up our own char array that we
created way back in darwinssl_connect_step1... */
Curl_safefree(ptr);
}
size_t Curl_darwinssl_version(char *buffer, size_t size)
{
return snprintf(buffer, size, "SecureTransport");

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2012, Nick Zitzmann, <nickzman@gmail.com>.
* Copyright (C) 2012 - 2013, Nick Zitzmann, <nickzman@gmail.com>.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -37,6 +37,7 @@ void Curl_darwinssl_close_all(struct SessionHandle *data);
/* close a SSL connection */
void Curl_darwinssl_close(struct connectdata *conn, int sockindex);
void Curl_darwinssl_session_free(void *ptr);
size_t Curl_darwinssl_version(char *buffer, size_t size);
int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex);
int Curl_darwinssl_check_cxn(struct connectdata *conn);
@@ -51,12 +52,16 @@ void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
unsigned char *md5sum, /* output */
size_t md5len);
/* this backend provides these functions: */
#define have_curlssl_random 1
#define have_curlssl_md5sum 1
/* API setup for SecureTransport */
#define curlssl_init() (1)
#define curlssl_cleanup() Curl_nop_stmt
#define curlssl_connect Curl_darwinssl_connect
#define curlssl_connect_nonblocking Curl_darwinssl_connect_nonblocking
#define curlssl_session_free(x) Curl_nop_stmt
#define curlssl_session_free(x) Curl_darwinssl_session_free(x)
#define curlssl_close_all Curl_darwinssl_close_all
#define curlssl_close Curl_darwinssl_close
#define curlssl_shutdown(x,y) 0

View File

@@ -87,7 +87,7 @@ extern curl_free_callback Curl_cfree;
extern curl_realloc_callback Curl_crealloc;
extern curl_strdup_callback Curl_cstrdup;
extern curl_calloc_callback Curl_ccalloc;
#ifdef WIN32
#if defined(WIN32) && defined(UNICODE)
extern curl_wcsdup_callback Curl_cwcsdup;
#endif
@@ -114,14 +114,15 @@ extern curl_wcsdup_callback Curl_cwcsdup;
#define free(ptr) Curl_cfree(ptr)
#ifdef WIN32
# undef wcsdup
# define wcsdup(ptr) Curl_cwcsdup(ptr)
# undef _wcsdup
# define _wcsdup(ptr) Curl_cwcsdup(ptr)
# undef _tcsdup
# ifdef UNICODE
# undef wcsdup
# define wcsdup(ptr) Curl_cwcsdup(ptr)
# undef _wcsdup
# define _wcsdup(ptr) Curl_cwcsdup(ptr)
# undef _tcsdup
# define _tcsdup(ptr) Curl_cwcsdup(ptr)
# else
# undef _tcsdup
# define _tcsdup(ptr) Curl_cstrdup(ptr)
# endif
#endif

View File

@@ -22,6 +22,7 @@
* RFC2831 DIGEST-MD5 authentication
* RFC4422 Simple Authentication and Security Layer (SASL)
* RFC4616 PLAIN authentication
* RFC6749 OAuth 2.0 Authorization Framework
*
***************************************************************************/
@@ -32,7 +33,7 @@
#include "curl_base64.h"
#include "curl_md5.h"
#include "curl_rand.h"
#include "sslgen.h"
#include "curl_hmac.h"
#include "curl_ntlm_msgs.h"
#include "curl_sasl.h"
@@ -94,18 +95,18 @@ CURLcode Curl_sasl_create_plain_message(struct SessionHandle *data,
const char *passwdp,
char **outptr, size_t *outlen)
{
char plainauth[2 * MAX_CURL_USER_LENGTH + MAX_CURL_PASSWORD_LENGTH];
CURLcode result;
char *plainauth;
size_t ulen;
size_t plen;
ulen = strlen(userp);
plen = strlen(passwdp);
if(2 * ulen + plen + 2 > sizeof(plainauth)) {
plainauth = malloc(2 * ulen + plen + 2);
if(!plainauth) {
*outlen = 0;
*outptr = NULL;
/* Plainauth too small */
return CURLE_OUT_OF_MEMORY;
}
@@ -117,8 +118,10 @@ CURLcode Curl_sasl_create_plain_message(struct SessionHandle *data,
memcpy(plainauth + 2 * ulen + 2, passwdp, plen);
/* Base64 encode the reply */
return Curl_base64_encode(data, plainauth, 2 * ulen + plen + 2, outptr,
outlen);
result = Curl_base64_encode(data, plainauth, 2 * ulen + plen + 2, outptr,
outlen);
Curl_safefree(plainauth);
return result;
}
/*
@@ -190,7 +193,7 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
size_t chlglen = 0;
HMAC_context *ctxt;
unsigned char digest[MD5_DIGEST_LEN];
char response[MAX_CURL_USER_LENGTH + 2 * MD5_DIGEST_LEN + 1];
char *response;
/* Decode the challenge if necessary */
if(chlg64len && *chlg64 != '=') {
@@ -220,14 +223,19 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
Curl_HMAC_final(ctxt, digest);
/* Prepare the response */
snprintf(response, sizeof(response),
response = aprintf(
"%s %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
userp, digest[0], digest[1], digest[2], digest[3], digest[4],
digest[5], digest[6], digest[7], digest[8], digest[9], digest[10],
digest[11], digest[12], digest[13], digest[14], digest[15]);
if(!response)
return CURLE_OUT_OF_MEMORY;
/* Base64 encode the reply */
return Curl_base64_encode(data, response, 0, outptr, outlen);
result = Curl_base64_encode(data, response, 0, outptr, outlen);
Curl_safefree(response);
return result;
}
/*
@@ -314,7 +322,7 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
/* Generate 64 bits of random data */
for(i = 0; i < 8; i++)
cnonce[i] = table16[Curl_rand()%16];
cnonce[i] = table16[Curl_rand(data)%16];
/* So far so good, now calculate A1 and H(A1) according to RFC 2831 */
ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
@@ -470,6 +478,40 @@ CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data,
}
#endif /* USE_NTLM */
/*
* Curl_sasl_create_xoauth2_message()
*
* This is used to generate an already encoded XOAUTH2 message ready
* for sending to the recipient.
*
* Parameters:
*
* data [in] - The session handle.
* user [in] - The user name.
* bearer [in] - The XOAUTH Bearer token.
* outptr [in/out] - The address where a pointer to newly allocated memory
* holding the result will be stored upon completion.
* outlen [out] - The length of the output message.
*
* Returns CURLE_OK on success.
*/
CURLcode Curl_sasl_create_xoauth2_message(struct SessionHandle *data,
const char *user,
const char *bearer,
char **outptr, size_t *outlen)
{
char *xoauth;
xoauth = aprintf("user=%s\1auth=Bearer %s\1\1", user, bearer);
if(!xoauth)
return CURLE_OUT_OF_MEMORY;
/* Base64 encode the reply */
return Curl_base64_encode(data, xoauth, strlen(xoauth), outptr,
outlen);
}
/*
* Curl_sasl_cleanup()
*

View File

@@ -24,14 +24,34 @@
#include "pingpong.h"
/* Authentication mechanism values */
#define SASL_AUTH_NONE 0
#define SASL_AUTH_ANY ~0U
/* Authentication mechanism flags */
#define SASL_MECH_LOGIN 0x0001
#define SASL_MECH_PLAIN 0x0002
#define SASL_MECH_CRAM_MD5 0x0004
#define SASL_MECH_DIGEST_MD5 0x0008
#define SASL_MECH_GSSAPI 0x0010
#define SASL_MECH_EXTERNAL 0x0020
#define SASL_MECH_NTLM 0x0040
#define SASL_MECH_LOGIN (1 << 0)
#define SASL_MECH_PLAIN (1 << 1)
#define SASL_MECH_CRAM_MD5 (1 << 2)
#define SASL_MECH_DIGEST_MD5 (1 << 3)
#define SASL_MECH_GSSAPI (1 << 4)
#define SASL_MECH_EXTERNAL (1 << 5)
#define SASL_MECH_NTLM (1 << 6)
#define SASL_MECH_XOAUTH2 (1 << 7)
/* Authentication mechanism strings */
#define SASL_MECH_STRING_LOGIN "LOGIN"
#define SASL_MECH_STRING_PLAIN "PLAIN"
#define SASL_MECH_STRING_CRAM_MD5 "CRAM-MD5"
#define SASL_MECH_STRING_DIGEST_MD5 "DIGEST-MD5"
#define SASL_MECH_STRING_GSSAPI "GSSAPI"
#define SASL_MECH_STRING_EXTERNAL "EXTERNAL"
#define SASL_MECH_STRING_NTLM "NTLM"
#define SASL_MECH_STRING_XOAUTH2 "XOAUTH2"
/* This is used to test whether the line starts with the given mechanism */
#define sasl_mech_equal(line, wordlen, mech) \
(wordlen == (sizeof(mech) - 1) / sizeof(char) && \
!memcmp(line, mech, wordlen))
/* This is used to generate a base64 encoded PLAIN authentication message */
CURLcode Curl_sasl_create_plain_message(struct SessionHandle *data,
@@ -81,6 +101,13 @@ CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data,
#endif /* USE_NTLM */
/* This is used to generate a base64 encoded XOAUTH2 authentication message
containing the user name and bearer token */
CURLcode Curl_sasl_create_xoauth2_message(struct SessionHandle *data,
const char *user,
const char *bearer,
char **outptr, size_t *outlen);
/* This is used to cleanup any libraries or curl modules used by the sasl
functions */
void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused);

View File

@@ -534,6 +534,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
return retcode;
}
else {
connssl->cred->cached = TRUE;
infof(data, "schannel: stored credential handle in session cache\n");
}
}
@@ -1063,7 +1064,6 @@ int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
*/
struct SessionHandle *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct curl_schannel_cred *cached_cred = NULL;
infof(data, "schannel: shutting down SSL/TLS connection with %s port %hu\n",
conn->host.name, conn->remote_port);
@@ -1141,17 +1141,11 @@ int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
connssl->cred->refcount);
}
/* if the handle refcount is zero, check if we have not cached it */
if(connssl->cred->refcount == 0) {
if(Curl_ssl_getsessionid(conn, (void**)&cached_cred, NULL)) {
cached_cred = NULL;
}
/* if the handle was not cached, it is stale to be freed */
if(connssl->cred != cached_cred) {
infof(data, "schannel: clear credential handle\n");
s_pSecFn->FreeCredentialsHandle(&connssl->cred->cred_handle);
Curl_safefree(connssl->cred);
}
/* if the handle was not cached and the refcount is zero */
if(!connssl->cred->cached && connssl->cred->refcount == 0) {
infof(data, "schannel: clear credential handle\n");
s_pSecFn->FreeCredentialsHandle(&connssl->cred->cred_handle);
Curl_safefree(connssl->cred);
}
}
}
@@ -1177,7 +1171,7 @@ void Curl_schannel_session_free(void *ptr)
{
struct curl_schannel_cred *cred = ptr;
if(cred && cred->refcount == 0) {
if(cred && cred->cached && cred->refcount == 0) {
s_pSecFn->FreeCredentialsHandle(&cred->cred_handle);
Curl_safefree(cred);
}

View File

@@ -1,5 +1,5 @@
#ifndef HEADER_CURL_KRB4_H
#define HEADER_CURL_KRB4_H
#ifndef HEADER_CURL_SECURITY_H
#define HEADER_CURL_SECURITY_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -34,24 +34,18 @@ struct Curl_sec_client_mech {
int (*decode)(void *, void*, int, int, struct connectdata *);
};
#define AUTH_OK 0
#define AUTH_CONTINUE 1
#define AUTH_ERROR 2
#ifdef HAVE_KRB4
extern struct Curl_sec_client_mech Curl_krb4_client_mech;
#endif
#ifdef HAVE_GSSAPI
extern struct Curl_sec_client_mech Curl_krb5_client_mech;
#endif
CURLcode Curl_krb_kauth(struct connectdata *conn);
int Curl_sec_read_msg (struct connectdata *conn, char *,
enum protection_level);
void Curl_sec_end (struct connectdata *);
CURLcode Curl_sec_login (struct connectdata *);
int Curl_sec_request_prot (struct connectdata *conn, const char *level);
#endif /* HEADER_CURL_KRB4_H */
extern struct Curl_sec_client_mech Curl_krb5_client_mech;
#endif
#endif /* HEADER_CURL_SECURITY_H */

View File

@@ -270,7 +270,9 @@
# endif
# endif
# include <tchar.h>
typedef wchar_t *(*curl_wcsdup_callback)(const wchar_t *str);
# ifdef UNICODE
typedef wchar_t *(*curl_wcsdup_callback)(const wchar_t *str);
# endif
#endif
/*
@@ -369,7 +371,9 @@
# include <sys/stat.h>
# undef lseek
# define lseek(fdes,offset,whence) _lseeki64(fdes, offset, whence)
# undef fstat
# define fstat(fdes,stp) _fstati64(fdes, stp)
# undef stat
# define stat(fname,stp) _stati64(fname, stp)
# define struct_stat struct _stati64
# define LSEEK_ERROR (__int64)-1
@@ -616,7 +620,7 @@ int netware_init(void);
#if defined(USE_GNUTLS) || defined(USE_SSLEAY) || defined(USE_NSS) || \
defined(USE_QSOSSL) || defined(USE_POLARSSL) || defined(USE_AXTLS) || \
defined(USE_CYASSL) || defined(USE_SCHANNEL) || \
defined(USE_DARWINSSL)
defined(USE_DARWINSSL) || defined(USE_GSKIT)
#define USE_SSL /* SSL support has been enabled */
#endif

View File

@@ -440,7 +440,7 @@ typedef int sig_atomic_t;
* (or equivalent) on this platform to hide platform details to code using it.
*/
#ifdef WIN32
#if defined(WIN32) && !defined(USE_LWIPSOCK)
#define ERRNO ((int)GetLastError())
#define SET_ERRNO(x) (SetLastError((DWORD)(x)))
#else

170
lib/dotdot.c Normal file
View File

@@ -0,0 +1,170 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "curl_setup.h"
#include "dotdot.h"
#include "curl_memory.h"
/* The last #include file should be: */
#include "memdebug.h"
/*
* "Remove Dot Segments"
* http://tools.ietf.org/html/rfc3986#section-5.2.4
*/
/*
* Curl_dedotdotify()
*
* This function gets a zero-terminated path with dot and dotdot sequences
* passed in and strips them off according to the rules in RFC 3986 section
* 5.2.4.
*
* The function handles a query part ('?' + stuff) appended but it expects
* that fragments ('#' + stuff) have already been cut off.
*
* RETURNS
*
* an allocated dedotdotified output string
*/
char *Curl_dedotdotify(char *input)
{
size_t inlen = strlen(input);
char *clone;
size_t clen = inlen; /* the length of the cloned input */
char *out = malloc(inlen+1);
char *outptr;
char *orgclone;
char *queryp;
if(!out)
return NULL; /* out of memory */
/* get a cloned copy of the input */
clone = strdup(input);
if(!clone) {
free(out);
return NULL;
}
orgclone = clone;
outptr = out;
/*
* To handle query-parts properly, we must find it and remove it during the
* dotdot-operation and then append it again at the end to the output
* string.
*/
queryp = strchr(clone, '?');
if(queryp)
*queryp = 0;
do {
/* A. If the input buffer begins with a prefix of "../" or "./", then
remove that prefix from the input buffer; otherwise, */
if(!strncmp("./", clone, 2)) {
clone+=2;
clen-=2;
}
else if(!strncmp("../", clone, 3)) {
clone+=3;
clen-=3;
}
/* B. if the input buffer begins with a prefix of "/./" or "/.", where
"." is a complete path segment, then replace that prefix with "/" in
the input buffer; otherwise, */
else if(!strncmp("/./", clone, 3)) {
clone+=2;
clen-=2;
}
else if(!strcmp("/.", clone)) {
clone[1]='/';
clone++;
clen-=1;
}
/* C. if the input buffer begins with a prefix of "/../" or "/..", where
".." is a complete path segment, then replace that prefix with "/" in
the input buffer and remove the last segment and its preceding "/" (if
any) from the output buffer; otherwise, */
else if(!strncmp("/../", clone, 4)) {
clone+=3;
clen-=3;
/* remove the last segment from the output buffer */
while(outptr > out) {
outptr--;
if(*outptr == '/')
break;
}
*outptr = 0; /* zero-terminate where it stops */
}
else if(!strcmp("/..", clone)) {
clone[2]='/';
clone+=2;
clen-=2;
/* remove the last segment from the output buffer */
while(outptr > out) {
outptr--;
if(*outptr == '/')
break;
}
*outptr = 0; /* zero-terminate where it stops */
}
/* D. if the input buffer consists only of "." or "..", then remove
that from the input buffer; otherwise, */
else if(!strcmp(".", clone) || !strcmp("..", clone)) {
*clone=0;
}
else {
/* E. move the first path segment in the input buffer to the end of
the output buffer, including the initial "/" character (if any) and
any subsequent characters up to, but not including, the next "/"
character or the end of the input buffer. */
do {
*outptr++ = *clone++;
clen--;
} while(*clone && (*clone != '/'));
*outptr = 0;
}
} while(*clone);
if(queryp) {
size_t qlen;
/* There was a query part, append that to the output. The 'clone' string
may now have been altered so we copy from the original input string
from the correct index. */
size_t oindex = queryp - orgclone;
qlen = strlen(&input[oindex]);
memcpy(outptr, &input[oindex], qlen+1); /* include the ending zero byte */
}
free(orgclone);
return out;
}

View File

@@ -1,5 +1,5 @@
#ifndef HEADER_CURL_RAND_H
#define HEADER_CURL_RAND_H
#ifndef HEADER_CURL_DOTDOT_H
#define HEADER_CURL_DOTDOT_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -21,9 +21,5 @@
* KIND, either express or implied.
*
***************************************************************************/
void Curl_srand(void);
unsigned int Curl_rand(void);
#endif /* HEADER_CURL_RAND_H */
char *Curl_dedotdotify(char *input);
#endif

View File

@@ -50,6 +50,11 @@
#include <sys/param.h>
#endif
#if defined(HAVE_SIGNAL_H) && defined(HAVE_SIGACTION) && defined(USE_OPENSSL)
#define SIGPIPE_IGNORE 1
#include <signal.h>
#endif
#include "strequal.h"
#include "urldata.h"
#include <curl/curl.h>
@@ -69,10 +74,10 @@
#include "connect.h" /* for Curl_getconnectinfo */
#include "slist.h"
#include "amigaos.h"
#include "curl_rand.h"
#include "non-ascii.h"
#include "warnless.h"
#include "conncache.h"
#include "multiif.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -80,6 +85,56 @@
/* The last #include file should be: */
#include "memdebug.h"
#ifdef SIGPIPE_IGNORE
struct sigpipe_ignore {
struct sigaction old_pipe_act;
bool no_signal;
};
#define SIGPIPE_VARIABLE(x) struct sigpipe_ignore x
/*
* sigpipe_ignore() makes sure we ignore SIGPIPE while running libcurl
* internals, and then sigpipe_restore() will restore the situation when we
* return from libcurl again.
*/
static void sigpipe_ignore(struct SessionHandle *data,
struct sigpipe_ignore *ig)
{
/* get a local copy of no_signal because the SessionHandle might not be
around when we restore */
ig->no_signal = data->set.no_signal;
if(!data->set.no_signal) {
struct sigaction action;
/* first, extract the existing situation */
memset(&ig->old_pipe_act, 0, sizeof(struct sigaction));
sigaction(SIGPIPE, NULL, &ig->old_pipe_act);
action = ig->old_pipe_act;
/* ignore this signal */
action.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &action, NULL);
}
}
/*
* sigpipe_restore() puts back the outside world's opinion of signal handler
* and SIGPIPE handling. It MUST only be called after a corresponding
* sigpipe_ignore() was used.
*/
static void sigpipe_restore(struct sigpipe_ignore *ig)
{
if(!ig->no_signal)
/* restore the outside state */
sigaction(SIGPIPE, &ig->old_pipe_act, NULL);
}
#else
/* for systems without sigaction */
#define sigpipe_ignore(x,y) Curl_nop_stmt
#define sigpipe_restore(x) Curl_nop_stmt
#define SIGPIPE_VARIABLE(x)
#endif
/* win32_cleanup() is for win32 socket cleanup functionality, the opposite
of win32_init() */
static void win32_cleanup(void)
@@ -197,8 +252,8 @@ curl_free_callback Curl_cfree = (curl_free_callback)free;
curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc;
curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)system_strdup;
curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
#ifdef WIN32
curl_wcsdup_callback Curl_cwcsdup = (curl_wcsdup_callback)wcsdup;
#if defined(WIN32) && defined(UNICODE)
curl_wcsdup_callback Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
#endif
#else
/*
@@ -231,8 +286,8 @@ CURLcode curl_global_init(long flags)
Curl_crealloc = (curl_realloc_callback)realloc;
Curl_cstrdup = (curl_strdup_callback)system_strdup;
Curl_ccalloc = (curl_calloc_callback)calloc;
#ifdef WIN32
Curl_cwcsdup = (curl_wcsdup_callback)wcsdup;
#if defined(WIN32) && defined(UNICODE)
Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
#endif
if(flags & CURL_GLOBAL_SSL)
@@ -281,10 +336,6 @@ CURLcode curl_global_init(long flags)
init_flags = flags;
/* Preset pseudo-random number sequence. */
Curl_srand();
return CURLE_OK;
}
@@ -402,8 +453,328 @@ CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
return ret;
}
#ifdef CURLDEBUG
struct socketmonitor {
struct socketmonitor *next; /* the next node in the list or NULL */
struct pollfd socket; /* socket info of what to monitor */
};
struct events {
long ms; /* timeout, run the timeout function when reached */
bool msbump; /* set TRUE when timeout is set by callback */
int num_sockets; /* number of nodes in the monitor list */
struct socketmonitor *list; /* list of sockets to monitor */
int running_handles; /* store the returned number */
};
/* events_timer
*
* Callback that gets called with a new value when the timeout should be
* updated.
*/
static int events_timer(CURLM *multi, /* multi handle */
long timeout_ms, /* see above */
void *userp) /* private callback pointer */
{
struct events *ev = userp;
(void)multi;
if(timeout_ms == -1)
/* timeout removed */
timeout_ms = 0;
else if(timeout_ms == 0)
/* timeout is already reached! */
timeout_ms = 1; /* trigger asap */
ev->ms = timeout_ms;
ev->msbump = TRUE;
return 0;
}
/* poll2cselect
*
* convert from poll() bit definitions to libcurl's CURL_CSELECT_* ones
*/
static int poll2cselect(int pollmask)
{
int omask=0;
if(pollmask & POLLIN)
omask |= CURL_CSELECT_IN;
if(pollmask & POLLOUT)
omask |= CURL_CSELECT_OUT;
if(pollmask & POLLERR)
omask |= CURL_CSELECT_ERR;
return omask;
}
/* socketcb2poll
*
* convert from libcurl' CURL_POLL_* bit definitions to poll()'s
*/
static short socketcb2poll(int pollmask)
{
short omask=0;
if(pollmask & CURL_POLL_IN)
omask |= POLLIN;
if(pollmask & CURL_POLL_OUT)
omask |= POLLOUT;
return omask;
}
/* events_socket
*
* Callback that gets called with information about socket activity to
* monitor.
*/
static int events_socket(CURL *easy, /* easy handle */
curl_socket_t s, /* socket */
int what, /* see above */
void *userp, /* private callback
pointer */
void *socketp) /* private socket
pointer */
{
struct events *ev = userp;
struct socketmonitor *m;
struct socketmonitor *prev=NULL;
(void)socketp;
m = ev->list;
while(m) {
if(m->socket.fd == s) {
if(what == CURL_POLL_REMOVE) {
struct socketmonitor *nxt = m->next;
/* remove this node from the list of monitored sockets */
if(prev)
prev->next = nxt;
else
ev->list = nxt;
free(m);
m = nxt;
infof(easy, "socket cb: socket %d REMOVED\n", s);
}
else {
/* The socket 's' is already being monitored, update the activity
mask. Convert from libcurl bitmask to the poll one. */
m->socket.events = socketcb2poll(what);
infof(easy, "socket cb: socket %d UPDATED as %s%s\n", s,
what&CURL_POLL_IN?"IN":"",
what&CURL_POLL_OUT?"OUT":"");
}
break;
}
prev = m;
m = m->next; /* move to next node */
}
if(!m) {
if(what == CURL_POLL_REMOVE) {
/* this happens a bit too often, libcurl fix perhaps? */
/* fprintf(stderr,
"%s: socket %d asked to be REMOVED but not present!\n",
__func__, s); */
}
else {
m = malloc(sizeof(struct socketmonitor));
m->next = ev->list;
m->socket.fd = s;
m->socket.events = socketcb2poll(what);
m->socket.revents = 0;
ev->list = m;
infof(easy, "socket cb: socket %d ADDED as %s%s\n", s,
what&CURL_POLL_IN?"IN":"",
what&CURL_POLL_OUT?"OUT":"");
}
}
return 0;
}
/*
* curl_easy_perform() is the external interface that performs a blocking
* events_setup()
*
* Do the multi handle setups that only event-based transfers need.
*/
static void events_setup(CURLM *multi, struct events *ev)
{
/* timer callback */
curl_multi_setopt(multi, CURLMOPT_TIMERFUNCTION, events_timer);
curl_multi_setopt(multi, CURLMOPT_TIMERDATA, ev);
/* socket callback */
curl_multi_setopt(multi, CURLMOPT_SOCKETFUNCTION, events_socket);
curl_multi_setopt(multi, CURLMOPT_SOCKETDATA, ev);
}
/* wait_or_timeout()
*
* waits for activity on any of the given sockets, or the timeout to trigger.
*/
static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
{
bool done = FALSE;
CURLMcode mcode;
CURLcode rc = CURLE_OK;
while(!done) {
CURLMsg *msg;
struct socketmonitor *m;
struct pollfd *f;
struct pollfd fds[4];
int numfds=0;
int pollrc;
int i;
struct timeval before;
struct timeval after;
/* populate the fds[] array */
for(m = ev->list, f=&fds[0]; m; m = m->next) {
f->fd = m->socket.fd;
f->events = m->socket.events;
f->revents = 0;
/* fprintf(stderr, "poll() %d check socket %d\n", numfds, f->fd); */
f++;
numfds++;
}
/* get the time stamp to use to figure out how long poll takes */
before = curlx_tvnow();
/* wait for activity or timeout */
pollrc = Curl_poll(fds, numfds, (int)ev->ms);
after = curlx_tvnow();
ev->msbump = FALSE; /* reset here */
if(0 == pollrc) {
/* timeout! */
ev->ms = 0;
/* fprintf(stderr, "call curl_multi_socket_action( TIMEOUT )\n"); */
mcode = curl_multi_socket_action(multi, CURL_SOCKET_TIMEOUT, 0,
&ev->running_handles);
}
else if(pollrc > 0) {
/* loop over the monitored sockets to see which ones had activity */
for(i = 0; i< numfds; i++) {
if(fds[i].revents) {
/* socket activity, tell libcurl */
int act = poll2cselect(fds[i].revents); /* convert */
infof(multi->easyp, "call curl_multi_socket_action( socket %d )\n",
fds[i].fd);
mcode = curl_multi_socket_action(multi, fds[i].fd, act,
&ev->running_handles);
}
}
if(!ev->msbump)
/* If nothing updated the timeout, we decrease it by the spent time.
* If it was updated, it has the new timeout time stored already.
*/
ev->ms += curlx_tvdiff(after, before);
}
if(mcode)
return CURLE_URL_MALFORMAT; /* TODO: return a proper error! */
/* we don't really care about the "msgs_in_queue" value returned in the
second argument */
msg = curl_multi_info_read(multi, &pollrc);
if(msg) {
rc = msg->data.result;
done = TRUE;
}
}
return rc;
}
/* easy_events()
*
* Runs a transfer in a blocking manner using the events-based API
*/
static CURLcode easy_events(CURLM *multi)
{
struct events evs= {2, FALSE, 0, NULL, 0};
/* if running event-based, do some further multi inits */
events_setup(multi, &evs);
return wait_or_timeout(multi, &evs);
}
#else /* CURLDEBUG */
/* when not built with debug, this function doesn't exist */
#define easy_events(x) CURLE_NOT_BUILT_IN
#endif
static CURLcode easy_transfer(CURLM *multi)
{
bool done = FALSE;
CURLMcode mcode = CURLM_OK;
CURLcode code = CURLE_OK;
struct timeval before;
int without_fds = 0; /* count number of consecutive returns from
curl_multi_wait() without any filedescriptors */
while(!done && !mcode) {
int still_running;
int ret;
before = curlx_tvnow();
mcode = curl_multi_wait(multi, NULL, 0, 1000, &ret);
if(mcode == CURLM_OK) {
if(ret == -1) {
/* poll() failed not on EINTR, indicate a network problem */
code = CURLE_RECV_ERROR;
break;
}
else if(ret == 0) {
struct timeval after = curlx_tvnow();
/* If it returns without any filedescriptor instantly, we need to
avoid busy-looping during periods where it has nothing particular
to wait for */
if(curlx_tvdiff(after, before) <= 10) {
without_fds++;
if(without_fds > 2) {
int sleep_ms = without_fds < 10 ? (1 << (without_fds-1)): 1000;
Curl_wait_ms(sleep_ms);
}
}
else
/* it wasn't "instant", restart counter */
without_fds = 0;
}
else
/* got file descriptor, restart counter */
without_fds = 0;
mcode = curl_multi_perform(multi, &still_running);
}
/* only read 'still_running' if curl_multi_perform() return OK */
if((mcode == CURLM_OK) && !still_running) {
int rc;
CURLMsg *msg = curl_multi_info_read(multi, &rc);
if(msg) {
code = msg->data.result;
done = TRUE;
}
}
}
return code;
}
/*
* easy_perform() is the external interface that performs a blocking
* transfer as previously setup.
*
* CONCEPT: This function creates a multi handle, adds the easy handle to it,
@@ -415,18 +786,18 @@ CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
* needs to keep it around since if this easy handle is used again by this
* function, the same multi handle must be re-used so that the same pools and
* caches can be used.
*
* DEBUG: if 'events' is set TRUE, this function will use a replacement engine
* instead of curl_multi_perform() and use curl_multi_socket_action().
*/
CURLcode curl_easy_perform(CURL *easy)
static CURLcode easy_perform(struct SessionHandle *data, bool events)
{
CURLM *multi;
CURLMcode mcode;
CURLcode code = CURLE_OK;
CURLMsg *msg;
bool done = FALSE;
int rc;
struct SessionHandle *data = easy;
SIGPIPE_VARIABLE(pipe_st);
if(!easy)
if(!data)
return CURLE_BAD_FUNCTION_ARGUMENT;
if(data->multi) {
@@ -437,7 +808,9 @@ CURLcode curl_easy_perform(CURL *easy)
if(data->multi_easy)
multi = data->multi_easy;
else {
multi = curl_multi_init();
/* this multi handle will only ever have a single easy handled attached
to it, so make it use minimal hashes */
multi = Curl_multi_handle(1, 3);
if(!multi)
return CURLE_OUT_OF_MEMORY;
data->multi_easy = multi;
@@ -446,7 +819,7 @@ CURLcode curl_easy_perform(CURL *easy)
/* Copy the MAXCONNECTS option to the multi handle */
curl_multi_setopt(multi, CURLMOPT_MAXCONNECTS, data->set.maxconnects);
mcode = curl_multi_add_handle(multi, easy);
mcode = curl_multi_add_handle(multi, data);
if(mcode) {
curl_multi_cleanup(multi);
if(mcode == CURLM_OUT_OF_MEMORY)
@@ -455,44 +828,47 @@ CURLcode curl_easy_perform(CURL *easy)
return CURLE_FAILED_INIT;
}
sigpipe_ignore(data, &pipe_st);
/* assign this after curl_multi_add_handle() since that function checks for
it and rejects this handle otherwise */
data->multi = multi;
while(!done && !mcode) {
int still_running;
int ret;
mcode = curl_multi_wait(multi, NULL, 0, 1000, &ret);
if(mcode == CURLM_OK) {
if(ret == -1) {
/* poll() failed not on EINTR, indicate a network problem */
code = CURLE_RECV_ERROR;
break;
}
mcode = curl_multi_perform(multi, &still_running);
}
/* only read 'still_running' if curl_multi_perform() return OK */
if((mcode == CURLM_OK) && !still_running) {
msg = curl_multi_info_read(multi, &rc);
if(msg) {
code = msg->data.result;
done = TRUE;
}
}
}
/* run the transfer */
code = events ? easy_events(multi) : easy_transfer(multi);
/* ignoring the return code isn't nice, but atm we can't really handle
a failure here, room for future improvement! */
(void)curl_multi_remove_handle(multi, easy);
(void)curl_multi_remove_handle(multi, data);
sigpipe_restore(&pipe_st);
/* The multi handle is kept alive, owned by the easy handle */
return code;
}
/*
* curl_easy_perform() is the external interface that performs a blocking
* transfer as previously setup.
*/
CURLcode curl_easy_perform(CURL *easy)
{
return easy_perform(easy, FALSE);
}
#ifdef CURLDEBUG
/*
* curl_easy_perform_ev() is the external interface that performs a blocking
* transfer using the event-based API internally.
*/
CURLcode curl_easy_perform_ev(CURL *easy)
{
return easy_perform(easy, TRUE);
}
#endif
/*
* curl_easy_cleanup() is the external interface to cleaning/freeing the given
* easy handle.
@@ -500,27 +876,14 @@ CURLcode curl_easy_perform(CURL *easy)
void curl_easy_cleanup(CURL *curl)
{
struct SessionHandle *data = (struct SessionHandle *)curl;
SIGPIPE_VARIABLE(pipe_st);
if(!data)
return;
sigpipe_ignore(data, &pipe_st);
Curl_close(data);
}
/*
* Store a pointed to the multi handle within the easy handle's data struct.
*/
void Curl_easy_addmulti(struct SessionHandle *data,
void *multi)
{
data->multi = multi;
}
void Curl_easy_initHandleData(struct SessionHandle *data)
{
memset(&data->req, 0, sizeof(struct SingleRequest));
data->req.maxdownload = -1;
sigpipe_restore(&pipe_st);
}
/*
@@ -532,12 +895,16 @@ CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)
{
va_list arg;
void *paramp;
CURLcode ret;
struct SessionHandle *data = (struct SessionHandle *)curl;
va_start(arg, info);
paramp = va_arg(arg, void *);
return Curl_getinfo(data, info, paramp);
ret = Curl_getinfo(data, info, paramp);
va_end(arg);
return ret;
}
/*
@@ -615,8 +982,6 @@ CURL *curl_easy_duphandle(CURL *incurl)
Curl_convert_setup(outcurl);
Curl_easy_initHandleData(outcurl);
outcurl->magic = CURLEASY_MAGIC_NUMBER;
/* we reach this point and thus we are OK */
@@ -650,7 +1015,7 @@ void curl_easy_reset(CURL *curl)
data->state.path = NULL;
Curl_safefree(data->state.proto.generic);
Curl_free_request_state(data);
/* zero out UserDefined data: */
Curl_freeset(data);
@@ -660,9 +1025,6 @@ void curl_easy_reset(CURL *curl)
/* zero out Progress data: */
memset(&data->progress, 0, sizeof(struct Progress));
/* init Handle data */
Curl_easy_initHandleData(data);
data->progress.flags |= PGRS_HIDE;
data->state.current_speed = -1; /* init to negative == impossible */
}
@@ -724,7 +1086,7 @@ CURLcode curl_easy_pause(CURL *curl, int action)
do {
chunklen = (tempsize > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:tempsize;
result = Curl_client_write(data->state.current_conn,
result = Curl_client_write(data->easy_conn,
temptype, tempwrite, chunklen);
if(result)
/* failures abort the loop at once */
@@ -766,6 +1128,13 @@ CURLcode curl_easy_pause(CURL *curl, int action)
free(freewrite); /* this is unconditionally no longer used */
}
/* if there's no error and we're not pausing both directions, we want
to have this handle checked soon */
if(!result &&
((newstate&(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) !=
(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) )
Curl_expire(data, 1); /* get this handle going again */
return result;
}

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -25,9 +25,9 @@
/*
* Prototypes for library-wide functions provided by easy.c
*/
void Curl_easy_addmulti(struct SessionHandle *data, void *multi);
void Curl_easy_initHandleData(struct SessionHandle *data);
#ifdef CURLDEBUG
CURL_EXTERN CURLcode curl_easy_perform_ev(CURL *easy);
#endif
#endif /* HEADER_CURL_EASYIF_H */

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -159,7 +159,8 @@ CURLcode Curl_urldecode(struct SessionHandle *data,
while(--alloc > 0) {
in = *string;
if(('%' == in) && ISXDIGIT(string[1]) && ISXDIGIT(string[2])) {
if(('%' == in) && (alloc > 2) &&
ISXDIGIT(string[1]) && ISXDIGIT(string[2])) {
/* this is two hexadecimal digits following a '%' */
char hexstr[3];
char *ptr;

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -90,7 +90,7 @@ static CURLcode file_done(struct connectdata *conn,
static CURLcode file_connect(struct connectdata *conn, bool *done);
static CURLcode file_disconnect(struct connectdata *conn,
bool dead_connection);
static CURLcode file_setup_connection(struct connectdata *conn);
/*
* FILE scheme handler.
@@ -98,7 +98,7 @@ static CURLcode file_disconnect(struct connectdata *conn,
const struct Curl_handler Curl_handler_file = {
"FILE", /* scheme */
ZERO_NULL, /* setup_connection */
file_setup_connection, /* setup_connection */
file_do, /* do_it */
file_done, /* done */
ZERO_NULL, /* do_more */
@@ -117,6 +117,16 @@ const struct Curl_handler Curl_handler_file = {
};
static CURLcode file_setup_connection(struct connectdata *conn)
{
/* allocate the FILE specific struct */
conn->data->req.protop = calloc(1, sizeof(struct FILEPROTO));
if(!conn->data->req.protop)
return CURLE_OUT_OF_MEMORY;
return CURLE_OK;
}
/*
Check if this is a range download, and if so, set the internal variables
properly. This code is copied from the FTP implementation and might as
@@ -179,39 +189,17 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
{
struct SessionHandle *data = conn->data;
char *real_path;
struct FILEPROTO *file;
struct FILEPROTO *file = data->req.protop;
int fd;
#ifdef DOS_FILESYSTEM
int i;
char *actual_path;
#endif
/* If there already is a protocol-specific struct allocated for this
sessionhandle, deal with it */
Curl_reset_reqproto(conn);
real_path = curl_easy_unescape(data, data->state.path, 0, NULL);
if(!real_path)
return CURLE_OUT_OF_MEMORY;
if(!data->state.proto.file) {
file = calloc(1, sizeof(struct FILEPROTO));
if(!file) {
free(real_path);
return CURLE_OUT_OF_MEMORY;
}
data->state.proto.file = file;
}
else {
/* file is not a protocol that can deal with "persistancy" */
file = data->state.proto.file;
Curl_safefree(file->freepath);
file->path = NULL;
if(file->fd != -1)
close(file->fd);
file->fd = -1;
}
#ifdef DOS_FILESYSTEM
/* If the first character is a slash, and there's
something that looks like a drive at the beginning of
@@ -262,7 +250,7 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
static CURLcode file_done(struct connectdata *conn,
CURLcode status, bool premature)
{
struct FILEPROTO *file = conn->data->state.proto.file;
struct FILEPROTO *file = conn->data->req.protop;
(void)status; /* not used */
(void)premature; /* not used */
@@ -280,7 +268,7 @@ static CURLcode file_done(struct connectdata *conn,
static CURLcode file_disconnect(struct connectdata *conn,
bool dead_connection)
{
struct FILEPROTO *file = conn->data->state.proto.file;
struct FILEPROTO *file = conn->data->req.protop;
(void)dead_connection; /* not used */
if(file) {
@@ -302,7 +290,7 @@ static CURLcode file_disconnect(struct connectdata *conn,
static CURLcode file_upload(struct connectdata *conn)
{
struct FILEPROTO *file = conn->data->state.proto.file;
struct FILEPROTO *file = conn->data->req.protop;
const char *dir = strchr(file->path, DIRSEP);
int fd;
int mode;
@@ -440,6 +428,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
curl_off_t bytecount = 0;
int fd;
struct timeval now = Curl_tvnow();
struct FILEPROTO *file;
*done = TRUE; /* unconditionally */
@@ -449,8 +438,10 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
if(data->set.upload)
return file_upload(conn);
file = conn->data->req.protop;
/* get the fd from the connection phase */
fd = conn->data->state.proto.file->fd;
fd = file->fd;
/* VMS: This only works reliable for STREAMLF files */
if(-1 != fstat(fd, &statbuf)) {

View File

@@ -24,9 +24,6 @@
#include <curl/curl.h>
/* Length of the random boundary string. */
#define BOUNDARY_LENGTH 40
#if !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY)
#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
@@ -35,7 +32,7 @@
#include "urldata.h" /* for struct SessionHandle */
#include "formdata.h"
#include "curl_rand.h"
#include "sslgen.h"
#include "strequal.h"
#include "curl_memory.h"
#include "sendf.h"
@@ -56,7 +53,7 @@ static char *Curl_basename(char *path);
#endif
static size_t readfromfile(struct Form *form, char *buffer, size_t size);
static char *formboundary(void);
static char *formboundary(struct SessionHandle *data);
/* What kind of Content-Type to use on un-specified files with unrecognized
extensions. */
@@ -171,8 +168,8 @@ static FormInfo * AddFormInfo(char *value,
* Returns some valid contenttype for filename.
*
***************************************************************************/
static const char * ContentTypeForFilename (const char *filename,
const char *prevtype)
static const char *ContentTypeForFilename(const char *filename,
const char *prevtype)
{
const char *contenttype = NULL;
unsigned int i;
@@ -181,7 +178,7 @@ static const char * ContentTypeForFilename (const char *filename,
* extensions and pick the first we match!
*/
struct ContentType {
char extension[6];
const char *extension;
const char *type;
};
static const struct ContentType ctts[]={
@@ -429,7 +426,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
/* Get contents from a given file name */
case CURLFORM_FILECONTENT:
if(current_form->flags != 0)
if(current_form->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_READFILE))
return_value = CURL_FORMADD_OPTION_TWICE;
else {
const char *filename = array_state?
@@ -670,9 +667,11 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
if(((form->flags & HTTPPOST_FILENAME) ||
(form->flags & HTTPPOST_BUFFER)) &&
!form->contenttype ) {
char *f = form->flags & HTTPPOST_BUFFER?
form->showfilename : form->value;
/* our contenttype is missing */
form->contenttype
= strdup(ContentTypeForFilename(form->value, prevtype));
form->contenttype = strdup(ContentTypeForFilename(f, prevtype));
if(!form->contenttype) {
return_value = CURL_FORMADD_MEMORY;
break;
@@ -777,6 +776,70 @@ CURLFORMcode curl_formadd(struct curl_httppost **httppost,
return result;
}
#ifdef __VMS
#include <fabdef.h>
/*
* get_vms_file_size does what it takes to get the real size of the file
*
* For fixed files, find out the size of the EOF block and adjust.
*
* For all others, have to read the entire file in, discarding the contents.
* Most posted text files will be small, and binary files like zlib archives
* and CD/DVD images should be either a STREAM_LF format or a fixed format.
*
*/
curl_off_t VmsRealFileSize(const char * name,
const struct_stat * stat_buf)
{
char buffer[8192];
curl_off_t count;
int ret_stat;
FILE * file;
file = fopen(name, "r");
if(file == NULL)
return 0;
count = 0;
ret_stat = 1;
while(ret_stat > 0) {
ret_stat = fread(buffer, 1, sizeof(buffer), file);
if(ret_stat != 0)
count += ret_stat;
}
fclose(file);
return count;
}
/*
*
* VmsSpecialSize checks to see if the stat st_size can be trusted and
* if not to call a routine to get the correct size.
*
*/
static curl_off_t VmsSpecialSize(const char * name,
const struct_stat * stat_buf)
{
switch(stat_buf->st_fab_rfm) {
case FAB$C_VAR:
case FAB$C_VFC:
return VmsRealFileSize(name, stat_buf);
break;
default:
return stat_buf->st_size;
}
}
#endif
#ifndef __VMS
#define filesize(name, stat_data) (stat_data.st_size)
#else
/* Getting the expected file size needs help on VMS */
#define filesize(name, stat_data) VmsSpecialSize(name, &stat_data)
#endif
/*
* AddFormData() adds a chunk of data to the FormData linked list.
*
@@ -832,7 +895,7 @@ static CURLcode AddFormData(struct FormData **formp,
if(!strequal("-", newform->line)) {
struct_stat file;
if(!stat(newform->line, &file) && !S_ISDIR(file.st_mode))
*size += file.st_size;
*size += filesize(newform->line, file);
else
return CURLE_BAD_FUNCTION_ARGUMENT;
}
@@ -1101,7 +1164,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
if(!post)
return result; /* no input => no output! */
boundary = formboundary();
boundary = formboundary(data);
if(!boundary)
return CURLE_OUT_OF_MEMORY;
@@ -1157,7 +1220,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
the magic to include several files with the same field name */
Curl_safefree(fileboundary);
fileboundary = formboundary();
fileboundary = formboundary(data);
if(!fileboundary) {
result = CURLE_OUT_OF_MEMORY;
break;
@@ -1343,6 +1406,36 @@ int Curl_FormInit(struct Form *form, struct FormData *formdata )
return 0;
}
#ifndef __VMS
# define fopen_read fopen
#else
/*
* vmsfopenread
*
* For upload to work as expected on VMS, different optional
* parameters must be added to the fopen command based on
* record format of the file.
*
*/
# define fopen_read vmsfopenread
static FILE * vmsfopenread(const char *file, const char *mode) {
struct_stat statbuf;
int result;
result = stat(file, &statbuf);
switch (statbuf.st_fab_rfm) {
case FAB$C_VAR:
case FAB$C_VFC:
case FAB$C_STMCR:
return fopen(file, "r");
break;
default:
return fopen(file, "r", "rfm=stmlf", "ctx=stm");
}
}
#endif
/*
* readfromfile()
*
@@ -1365,7 +1458,7 @@ static size_t readfromfile(struct Form *form, char *buffer,
else {
if(!form->fp) {
/* this file hasn't yet been opened */
form->fp = fopen(form->data->line, "rb"); /* b is for binary */
form->fp = fopen_read(form->data->line, "rb"); /* b is for binary */
if(!form->fp)
return (size_t)-1; /* failure */
}
@@ -1464,28 +1557,12 @@ char *Curl_formpostheader(void *formp, size_t *len)
* formboundary() creates a suitable boundary string and returns an allocated
* one.
*/
static char *formboundary(void)
static char *formboundary(struct SessionHandle *data)
{
char *retstring;
size_t i;
static const char table16[]="0123456789abcdef";
retstring = malloc(BOUNDARY_LENGTH+1);
if(!retstring)
return NULL; /* failed */
strcpy(retstring, "----------------------------");
for(i=strlen(retstring); i<BOUNDARY_LENGTH; i++)
retstring[i] = table16[Curl_rand()%16];
/* 28 dashes and 12 hexadecimal digits makes 12^16 (184884258895036416)
/* 24 dashes and 16 hexadecimal digits makes 64 bit (18446744073709551615)
combinations */
retstring[BOUNDARY_LENGTH]=0; /* zero terminate */
return retstring;
return aprintf("------------------------%08x%08x",
Curl_rand(data), Curl_rand(data));
}
#else /* CURL_DISABLE_HTTP */

482
lib/ftp.c

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -53,8 +53,9 @@ CURLcode Curl_initinfo(struct SessionHandle *data)
pro->t_redirect = 0;
info->httpcode = 0;
info->httpversion=0;
info->filetime=-1; /* -1 is an illegal time and thus means unknown */
info->httpversion = 0;
info->filetime = -1; /* -1 is an illegal time and thus means unknown */
info->timecond = FALSE;
if(info->contenttype)
free(info->contenttype);
@@ -185,7 +186,7 @@ static CURLcode getinfo_long(struct SessionHandle *data, CURLINFO info,
break;
case CURLINFO_CONDITION_UNMET:
/* return if the condition prevented the document to get transferred */
*param_longp = data->info.timecond;
*param_longp = data->info.timecond ? 1L : 0L;
break;
case CURLINFO_RTSP_CLIENT_CSEQ:
*param_longp = data->state.rtsp_next_client_CSeq;

906
lib/gskit.c Normal file
View File

@@ -0,0 +1,906 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "curl_setup.h"
#ifdef USE_GSKIT
#include <gskssl.h>
#include <qsoasync.h>
/* Some symbols are undefined/unsupported on OS400 versions < V7R1. */
#ifndef GSK_SSL_EXTN_SERVERNAME_REQUEST
#define GSK_SSL_EXTN_SERVERNAME_REQUEST 230
#endif
#ifdef HAVE_LIMITS_H
# include <limits.h>
#endif
#include <curl/curl.h>
#include "urldata.h"
#include "sendf.h"
#include "gskit.h"
#include "sslgen.h"
#include "connect.h" /* for the connect timeout */
#include "select.h"
#include "strequal.h"
#include "x509asn1.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
#include "curl_memory.h"
/* The last #include file should be: */
#include "memdebug.h"
/* Supported ciphers. */
typedef struct {
const char * name; /* Cipher name. */
const char * gsktoken; /* Corresponding token for GSKit String. */
int sslver; /* SSL version. */
} gskit_cipher;
static const gskit_cipher ciphertable[] = {
{ "null-md5", "01", CURL_SSLVERSION_SSLv3 },
{ "null-sha", "02", CURL_SSLVERSION_SSLv3 },
{ "exp-rc4-md5", "03", CURL_SSLVERSION_SSLv3 },
{ "rc4-md5", "04", CURL_SSLVERSION_SSLv3 },
{ "rc4-sha", "05", CURL_SSLVERSION_SSLv3 },
{ "exp-rc2-cbc-md5", "06", CURL_SSLVERSION_SSLv3 },
{ "exp-des-cbc-sha", "09", CURL_SSLVERSION_SSLv3 },
{ "des-cbc3-sha", "0A", CURL_SSLVERSION_SSLv3 },
{ "aes128-sha", "2F", CURL_SSLVERSION_TLSv1 },
{ "aes256-sha", "35", CURL_SSLVERSION_TLSv1 },
{ "rc4-md5", "1", CURL_SSLVERSION_SSLv2 },
{ "exp-rc4-md5", "2", CURL_SSLVERSION_SSLv2 },
{ "rc2-md5", "3", CURL_SSLVERSION_SSLv2 },
{ "exp-rc2-md5", "4", CURL_SSLVERSION_SSLv2 },
{ "des-cbc-md5", "6", CURL_SSLVERSION_SSLv2 },
{ "des-cbc3-md5", "7", CURL_SSLVERSION_SSLv2 },
{ (const char *) NULL, (const char *) NULL, 0 }
};
static bool is_separator(char c)
{
/* Return whether character is a cipher list separator. */
switch (c) {
case ' ':
case '\t':
case ':':
case ',':
case ';':
return true;
}
return false;
}
static CURLcode gskit_status(struct SessionHandle * data, int rc,
const char * procname, CURLcode defcode)
{
CURLcode cc;
/* Process GSKit status and map it to a CURLcode. */
switch (rc) {
case GSK_OK:
case GSK_OS400_ASYNCHRONOUS_SOC_INIT:
return CURLE_OK;
case GSK_KEYRING_OPEN_ERROR:
case GSK_OS400_ERROR_NO_ACCESS:
return CURLE_SSL_CACERT_BADFILE;
case GSK_INSUFFICIENT_STORAGE:
return CURLE_OUT_OF_MEMORY;
case GSK_ERROR_BAD_V2_CIPHER:
case GSK_ERROR_BAD_V3_CIPHER:
case GSK_ERROR_NO_CIPHERS:
return CURLE_SSL_CIPHER;
case GSK_OS400_ERROR_NOT_TRUSTED_ROOT:
case GSK_ERROR_CERT_VALIDATION:
return CURLE_PEER_FAILED_VERIFICATION;
case GSK_OS400_ERROR_TIMED_OUT:
return CURLE_OPERATION_TIMEDOUT;
case GSK_WOULD_BLOCK:
return CURLE_AGAIN;
case GSK_OS400_ERROR_NOT_REGISTERED:
break;
case GSK_ERROR_IO:
switch (errno) {
case ENOMEM:
return CURLE_OUT_OF_MEMORY;
default:
failf(data, "%s I/O error: %s", procname, strerror(errno));
break;
}
break;
default:
failf(data, "%s: %s", procname, gsk_strerror(rc));
break;
}
return defcode;
}
static CURLcode set_enum(struct SessionHandle * data,
gsk_handle h, GSK_ENUM_ID id, GSK_ENUM_VALUE value)
{
int rc = gsk_attribute_set_enum(h, id, value);
switch (rc) {
case GSK_OK:
return CURLE_OK;
case GSK_ERROR_IO:
failf(data, "gsk_attribute_set_enum() I/O error: %s", strerror(errno));
break;
default:
failf(data, "gsk_attribute_set_enum(): %s", gsk_strerror(rc));
break;
}
return CURLE_SSL_CONNECT_ERROR;
}
static CURLcode set_buffer(struct SessionHandle * data,
gsk_handle h, GSK_BUF_ID id, const char * buffer)
{
int rc = gsk_attribute_set_buffer(h, id, buffer, 0);
switch (rc) {
case GSK_OK:
return CURLE_OK;
case GSK_ERROR_IO:
failf(data, "gsk_attribute_set_buffer() I/O error: %s", strerror(errno));
break;
default:
failf(data, "gsk_attribute_set_buffer(): %s", gsk_strerror(rc));
break;
}
return CURLE_SSL_CONNECT_ERROR;
}
static CURLcode set_numeric(struct SessionHandle * data,
gsk_handle h, GSK_NUM_ID id, int value)
{
int rc = gsk_attribute_set_numeric_value(h, id, value);
switch (rc) {
case GSK_OK:
return CURLE_OK;
case GSK_ERROR_IO:
failf(data, "gsk_attribute_set_numeric_value() I/O error: %s",
strerror(errno));
break;
default:
failf(data, "gsk_attribute_set_numeric_value(): %s", gsk_strerror(rc));
break;
}
return CURLE_SSL_CONNECT_ERROR;
}
static CURLcode set_callback(struct SessionHandle * data,
gsk_handle h, GSK_CALLBACK_ID id, void * info)
{
int rc = gsk_attribute_set_callback(h, id, info);
switch (rc) {
case GSK_OK:
return CURLE_OK;
case GSK_ERROR_IO:
failf(data, "gsk_attribute_set_callback() I/O error: %s", strerror(errno));
break;
default:
failf(data, "gsk_attribute_set_callback(): %s", gsk_strerror(rc));
break;
}
return CURLE_SSL_CONNECT_ERROR;
}
static CURLcode set_ciphers(struct SessionHandle * data, gsk_handle h)
{
const char * cipherlist = data->set.str[STRING_SSL_CIPHER_LIST];
char * sslv2ciphers;
char * sslv3ciphers;
const char * clp;
const gskit_cipher * ctp;
char * v2p;
char * v3p;
int i;
CURLcode cc;
/* Compile cipher list into GSKit-compatible cipher lists. */
if(!cipherlist)
return CURLE_OK;
while(is_separator(*cipherlist)) /* Skip initial separators. */
cipherlist++;
if(!*cipherlist)
return CURLE_OK;
/* We allocate GSKit buffers of the same size as the input string: since
GSKit tokens are always shorter than their cipher names, allocated buffers
will always be large enough to accomodate the result. */
i = strlen(cipherlist) + 1;
v2p = malloc(i);
if(!v2p)
return CURLE_OUT_OF_MEMORY;
v3p = malloc(i);
if(!v3p) {
free(v2p);
return CURLE_OUT_OF_MEMORY;
}
sslv2ciphers = v2p;
sslv3ciphers = v3p;
/* Process each cipher in input string. */
for(;;) {
for(clp = cipherlist; *cipherlist && !is_separator(*cipherlist);)
cipherlist++;
i = cipherlist - clp;
if(!i)
break;
/* Search the cipher in our table. */
for(ctp = ciphertable; ctp->name; ctp++)
if(strnequal(ctp->name, clp, i) && !ctp->name[i])
break;
if(!ctp->name)
failf(data, "Unknown cipher %.*s: ignored", i, clp);
else {
switch (ctp->sslver) {
case CURL_SSLVERSION_SSLv2:
strcpy(v2p, ctp->gsktoken);
v2p += strlen(v2p);
break;
default:
/* GSKit wants TLSv1 ciphers with SSLv3 ciphers. */
strcpy(v3p, ctp->gsktoken);
v3p += strlen(v3p);
break;
}
}
/* Advance to next cipher name or end of string. */
while(is_separator(*cipherlist))
cipherlist++;
}
*v2p = '\0';
*v3p = '\0';
cc = set_buffer(data, h, GSK_V2_CIPHER_SPECS, sslv2ciphers);
if(cc == CURLE_OK)
cc = set_buffer(data, h, GSK_V3_CIPHER_SPECS, sslv3ciphers);
free(sslv2ciphers);
free(sslv3ciphers);
return cc;
}
int Curl_gskit_init(void)
{
/* No initialisation needed. */
return 1;
}
void Curl_gskit_cleanup(void)
{
/* Nothing to do. */
}
static CURLcode init_environment(struct SessionHandle * data,
gsk_handle * envir, const char * appid,
const char * file, const char * label,
const char * password)
{
int rc;
CURLcode c;
gsk_handle h;
/* Creates the GSKit environment. */
rc = gsk_environment_open(&h);
switch (rc) {
case GSK_OK:
break;
case GSK_INSUFFICIENT_STORAGE:
return CURLE_OUT_OF_MEMORY;
default:
failf(data, "gsk_environment_open(): %s", gsk_strerror(rc));
return CURLE_SSL_CONNECT_ERROR;
}
c = set_enum(data, h, GSK_SESSION_TYPE, GSK_CLIENT_SESSION);
if(c == CURLE_OK && appid)
c = set_buffer(data, h, GSK_OS400_APPLICATION_ID, appid);
if(c == CURLE_OK && file)
c = set_buffer(data, h, GSK_KEYRING_FILE, file);
if(c == CURLE_OK && label)
c = set_buffer(data, h, GSK_KEYRING_LABEL, label);
if(c == CURLE_OK && password)
c = set_buffer(data, h, GSK_KEYRING_PW, password);
if(c == CURLE_OK) {
/* Locate CAs, Client certificate and key according to our settings.
Note: this call may be blocking for some tenths of seconds. */
c = gskit_status(data, gsk_environment_init(h),
"gsk_environment_init()", CURLE_SSL_CERTPROBLEM);
if(c == CURLE_OK) {
*envir = h;
return c;
}
}
/* Error: rollback. */
gsk_environment_close(&h);
return c;
}
static void cancel_async_handshake(struct connectdata * conn, int sockindex)
{
struct ssl_connect_data * connssl = &conn->ssl[sockindex];
Qso_OverlappedIO_t cstat;
if(QsoCancelOperation(conn->sock[sockindex], 0) > 0)
QsoWaitForIOCompletion(connssl->iocport, &cstat, (struct timeval *) NULL);
}
static void close_async_handshake(struct ssl_connect_data * connssl)
{
QsoDestroyIOCompletionPort(connssl->iocport);
connssl->iocport = -1;
}
static void close_one(struct ssl_connect_data * conn,
struct SessionHandle * data)
{
if(conn->handle) {
gskit_status(data, gsk_secure_soc_close(&conn->handle),
"gsk_secure_soc_close()", 0);
conn->handle = (gsk_handle) NULL;
}
if(conn->iocport >= 0)
close_async_handshake(conn);
}
static ssize_t gskit_send(struct connectdata * conn, int sockindex,
const void * mem, size_t len, CURLcode * curlcode)
{
struct SessionHandle * data = conn->data;
CURLcode cc;
int written;
cc = gskit_status(data,
gsk_secure_soc_write(conn->ssl[sockindex].handle,
(char *) mem, (int) len, &written),
"gsk_secure_soc_write()", CURLE_SEND_ERROR);
if(cc != CURLE_OK) {
*curlcode = cc;
written = -1;
}
return (ssize_t) written; /* number of bytes */
}
static ssize_t gskit_recv(struct connectdata * conn, int num, char * buf,
size_t buffersize, CURLcode * curlcode)
{
struct SessionHandle * data = conn->data;
int buffsize;
int nread;
CURLcode cc;
buffsize = buffersize > (size_t) INT_MAX? INT_MAX: (int) buffersize;
cc = gskit_status(data, gsk_secure_soc_read(conn->ssl[num].handle,
buf, buffsize, &nread),
"gsk_secure_soc_read()", CURLE_RECV_ERROR);
if(cc != CURLE_OK) {
*curlcode = cc;
nread = -1;
}
return (ssize_t) nread;
}
static CURLcode gskit_connect_step1(struct connectdata * conn, int sockindex)
{
struct SessionHandle * data = conn->data;
struct ssl_connect_data * connssl = &conn->ssl[sockindex];
gsk_handle envir;
CURLcode cc;
int rc;
char * keyringfile;
char * keyringpwd;
char * keyringlabel;
char * v2ciphers;
char * v3ciphers;
char * sni;
bool sslv2enable, sslv3enable, tlsv1enable;
long timeout;
Qso_OverlappedIO_t commarea;
/* Create SSL environment, start (preferably asynchronous) handshake. */
connssl->handle = (gsk_handle) NULL;
connssl->iocport = -1;
/* GSKit supports two ways of specifying an SSL context: either by
* application identifier (that should have been defined at the system
* level) or by keyring file, password and certificate label.
* Local certificate name (CURLOPT_SSLCERT) is used to hold either the
* application identifier of the certificate label.
* Key password (CURLOPT_KEYPASSWD) holds the keyring password.
* It is not possible to have different keyrings for the CAs and the
* local certificate. We thus use the CA file (CURLOPT_CAINFO) to identify
* the keyring file.
* If no key password is given and the keyring is the system keyring,
* application identifier mode is tried first, as recommended in IBM doc.
*/
keyringfile = data->set.str[STRING_SSL_CAFILE];
keyringpwd = data->set.str[STRING_KEY_PASSWD];
keyringlabel = data->set.str[STRING_CERT];
envir = (gsk_handle) NULL;
if(keyringlabel && *keyringlabel && !keyringpwd &&
!strcmp(keyringfile, CURL_CA_BUNDLE)) {
/* Try application identifier mode. */
init_environment(data, &envir, keyringlabel, (const char *) NULL,
(const char *) NULL, (const char *) NULL);
}
if(!envir) {
/* Use keyring mode. */
cc = init_environment(data, &envir, (const char *) NULL,
keyringfile, keyringlabel, keyringpwd);
if(cc != CURLE_OK)
return cc;
}
/* Create secure session. */
cc = gskit_status(data, gsk_secure_soc_open(envir, &connssl->handle),
"gsk_secure_soc_open()", CURLE_SSL_CONNECT_ERROR);
gsk_environment_close(&envir);
if(cc != CURLE_OK)
return cc;
/* Determine which SSL/TLS version should be enabled. */
sslv2enable = sslv3enable = tlsv1enable = false;
sni = conn->host.name;
switch (data->set.ssl.version) {
case CURL_SSLVERSION_SSLv2:
sslv2enable = true;
sni = (char *) NULL;
break;
case CURL_SSLVERSION_SSLv3:
sslv3enable = true;
sni = (char *) NULL;
break;
case CURL_SSLVERSION_TLSv1:
tlsv1enable = true;
break;
default: /* CURL_SSLVERSION_DEFAULT. */
sslv3enable = true;
tlsv1enable = true;
break;
}
/* Process SNI. Ignore if not supported (on OS400 < V7R1). */
if(sni) {
rc = gsk_attribute_set_buffer(connssl->handle,
GSK_SSL_EXTN_SERVERNAME_REQUEST, sni, 0);
switch (rc) {
case GSK_OK:
case GSK_ATTRIBUTE_INVALID_ID:
break;
case GSK_ERROR_IO:
failf(data, "gsk_attribute_set_buffer() I/O error: %s", strerror(errno));
cc = CURLE_SSL_CONNECT_ERROR;
break;
default:
failf(data, "gsk_attribute_set_buffer(): %s", gsk_strerror(rc));
cc = CURLE_SSL_CONNECT_ERROR;
break;
}
}
/* Set session parameters. */
if(cc == CURLE_OK) {
/* Compute the handshake timeout. Since GSKit granularity is 1 second,
we round up the required value. */
timeout = Curl_timeleft(data, NULL, TRUE);
if(timeout < 0)
cc = CURLE_OPERATION_TIMEDOUT;
else
cc = set_numeric(data, connssl->handle, GSK_HANDSHAKE_TIMEOUT,
(timeout + 999) / 1000);
}
if(cc == CURLE_OK)
cc = set_numeric(data, connssl->handle, GSK_FD, conn->sock[sockindex]);
if(cc == CURLE_OK)
cc = set_ciphers(data, connssl->handle);
if(cc == CURLE_OK)
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV2,
sslv2enable? GSK_PROTOCOL_SSLV2_ON:
GSK_PROTOCOL_SSLV2_OFF);
if(cc == CURLE_OK)
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV3,
sslv3enable? GSK_PROTOCOL_SSLV3_ON:
GSK_PROTOCOL_SSLV3_OFF);
if(cc == CURLE_OK)
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV1,
sslv3enable? GSK_PROTOCOL_TLSV1_ON:
GSK_PROTOCOL_TLSV1_OFF);
if(cc == CURLE_OK)
cc = set_enum(data, connssl->handle, GSK_SERVER_AUTH_TYPE,
data->set.ssl.verifypeer? GSK_SERVER_AUTH_FULL:
GSK_SERVER_AUTH_PASSTHRU);
if(cc == CURLE_OK) {
/* Start handshake. Try asynchronous first. */
memset(&commarea, 0, sizeof commarea);
connssl->iocport = QsoCreateIOCompletionPort();
if(connssl->iocport != -1) {
cc = gskit_status(data, gsk_secure_soc_startInit(connssl->handle,
connssl->iocport, &commarea),
"gsk_secure_soc_startInit()", CURLE_SSL_CONNECT_ERROR);
if(cc == CURLE_OK) {
connssl->connecting_state = ssl_connect_2;
return CURLE_OK;
}
else
close_async_handshake(connssl);
}
else if(errno != ENOBUFS)
cc = gskit_status(data, GSK_ERROR_IO, "QsoCreateIOCompletionPort()", 0);
else {
/* No more completion port available. Use synchronous IO. */
cc = gskit_status(data, gsk_secure_soc_init(connssl->handle),
"gsk_secure_soc_init()", CURLE_SSL_CONNECT_ERROR);
if(cc == CURLE_OK) {
connssl->connecting_state = ssl_connect_3;
return CURLE_OK;
}
}
}
/* Error: rollback. */
close_one(connssl, data);
return cc;
}
static CURLcode gskit_connect_step2(struct connectdata * conn, int sockindex,
bool nonblocking)
{
struct SessionHandle * data = conn->data;
struct ssl_connect_data * connssl = &conn->ssl[sockindex];
Qso_OverlappedIO_t cstat;
long timeout_ms;
struct timeval stmv;
CURLcode cc;
/* Poll or wait for end of SSL asynchronous handshake. */
for(;;) {
timeout_ms = nonblocking? 0: Curl_timeleft(data, NULL, TRUE);
if(timeout_ms < 0)
timeout_ms = 0;
stmv.tv_sec = timeout_ms / 1000;
stmv.tv_usec = (timeout_ms - stmv.tv_sec * 1000) * 1000;
switch (QsoWaitForIOCompletion(connssl->iocport, &cstat, &stmv)) {
case 1: /* Operation complete. */
break;
case -1: /* An error occurred: handshake still in progress. */
if(errno == EINTR) {
if(nonblocking)
return CURLE_OK;
continue; /* Retry. */
}
if(errno != ETIME) {
failf(data, "QsoWaitForIOCompletion() I/O error: %s", strerror(errno));
cancel_async_handshake(conn, sockindex);
close_async_handshake(connssl);
return CURLE_SSL_CONNECT_ERROR;
}
/* FALL INTO... */
case 0: /* Handshake in progress, timeout occurred. */
if(nonblocking)
return CURLE_OK;
cancel_async_handshake(conn, sockindex);
close_async_handshake(connssl);
return CURLE_OPERATION_TIMEDOUT;
}
break;
}
cc = gskit_status(data, cstat.returnValue, "SSL handshake",
CURLE_SSL_CONNECT_ERROR);
if(cc == CURLE_OK)
connssl->connecting_state = ssl_connect_3;
close_async_handshake(connssl);
return cc;
}
static CURLcode gskit_connect_step3(struct connectdata * conn, int sockindex)
{
struct SessionHandle * data = conn->data;
struct ssl_connect_data * connssl = &conn->ssl[sockindex];
const gsk_cert_data_elem * cdev;
int cdec;
const gsk_cert_data_elem * p;
const char * cert = (const char *) NULL;
const char * certend;
int i;
CURLcode cc;
/* SSL handshake done: gather certificate info and verify host. */
if(gskit_status(data, gsk_attribute_get_cert_info(connssl->handle,
GSK_PARTNER_CERT_INFO,
&cdev, &cdec),
"gsk_attribute_get_cert_info()", CURLE_SSL_CONNECT_ERROR) ==
CURLE_OK) {
infof(data, "Server certificate:\n");
p = cdev;
for(i = 0; i++ < cdec; p++)
switch (p->cert_data_id) {
case CERT_BODY_DER:
cert = p->cert_data_p;
certend = cert + cdev->cert_data_l;
break;
case CERT_DN_PRINTABLE:
infof(data, "\t subject: %.*s\n", p->cert_data_l, p->cert_data_p);
break;
case CERT_ISSUER_DN_PRINTABLE:
infof(data, "\t issuer: %.*s\n", p->cert_data_l, p->cert_data_p);
break;
case CERT_VALID_FROM:
infof(data, "\t start date: %.*s\n", p->cert_data_l, p->cert_data_p);
break;
case CERT_VALID_TO:
infof(data, "\t expire date: %.*s\n", p->cert_data_l, p->cert_data_p);
break;
}
}
/* Verify host. */
cc = Curl_verifyhost(conn, cert, certend);
if(cc != CURLE_OK)
return cc;
/* The only place GSKit can get the whole CA chain is a validation
callback where no user data pointer is available. Therefore it's not
possible to copy this chain into our structures for CAINFO.
However the server certificate may be available, thus we can return
info about it. */
if(data->set.ssl.certinfo) {
if(Curl_ssl_init_certinfo(data, 1))
return CURLE_OUT_OF_MEMORY;
if(cert) {
cc = Curl_extract_certinfo(conn, 0, cert, certend);
if(cc != CURLE_OK)
return cc;
}
}
connssl->connecting_state = ssl_connect_done;
return CURLE_OK;
}
static CURLcode gskit_connect_common(struct connectdata * conn, int sockindex,
bool nonblocking, bool * done)
{
struct SessionHandle * data = conn->data;
struct ssl_connect_data * connssl = &conn->ssl[sockindex];
long timeout_ms;
Qso_OverlappedIO_t cstat;
CURLcode cc = CURLE_OK;
*done = connssl->state == ssl_connection_complete;
if(*done)
return CURLE_OK;
/* Step 1: create session, start handshake. */
if(connssl->connecting_state == ssl_connect_1) {
/* check allowed time left */
timeout_ms = Curl_timeleft(data, NULL, TRUE);
if(timeout_ms < 0) {
/* no need to continue if time already is up */
failf(data, "SSL connection timeout");
cc = CURLE_OPERATION_TIMEDOUT;
}
else
cc = gskit_connect_step1(conn, sockindex);
}
/* Step 2: check if handshake is over. */
if(cc == CURLE_OK && connssl->connecting_state == ssl_connect_2) {
/* check allowed time left */
timeout_ms = Curl_timeleft(data, NULL, TRUE);
if(timeout_ms < 0) {
/* no need to continue if time already is up */
failf(data, "SSL connection timeout");
cc = CURLE_OPERATION_TIMEDOUT;
}
else
cc = gskit_connect_step2(conn, sockindex, nonblocking);
}
/* Step 3: gather certificate info, verify host. */
if(cc == CURLE_OK && connssl->connecting_state == ssl_connect_3)
cc = gskit_connect_step3(conn, sockindex);
if(cc != CURLE_OK)
close_one(connssl, data);
else if(connssl->connecting_state == ssl_connect_done) {
connssl->state = ssl_connection_complete;
connssl->connecting_state = ssl_connect_1;
conn->recv[sockindex] = gskit_recv;
conn->send[sockindex] = gskit_send;
*done = TRUE;
}
return cc;
}
CURLcode Curl_gskit_connect_nonblocking(struct connectdata * conn,
int sockindex,
bool * done)
{
CURLcode cc;
cc = gskit_connect_common(conn, sockindex, TRUE, done);
if(*done || cc != CURLE_OK)
conn->ssl[sockindex].connecting_state = ssl_connect_1;
return cc;
}
CURLcode Curl_gskit_connect(struct connectdata * conn, int sockindex)
{
CURLcode retcode;
bool done;
conn->ssl[sockindex].connecting_state = ssl_connect_1;
retcode = gskit_connect_common(conn, sockindex, FALSE, &done);
if(retcode)
return retcode;
DEBUGASSERT(done);
return CURLE_OK;
}
void Curl_gskit_close(struct connectdata * conn, int sockindex)
{
struct SessionHandle * data = conn->data;
struct ssl_connect_data * connssl = &conn->ssl[sockindex];
if(connssl->use)
close_one(connssl, data);
}
int Curl_gskit_close_all(struct SessionHandle * data)
{
/* Unimplemented. */
(void) data;
return 0;
}
int Curl_gskit_shutdown(struct connectdata * conn, int sockindex)
{
struct ssl_connect_data * connssl = &conn->ssl[sockindex];
struct SessionHandle * data = conn->data;
ssize_t nread;
int what;
int rc;
char buf[120];
if(!connssl->handle)
return 0;
if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
return 0;
close_one(connssl, data);
rc = 0;
what = Curl_socket_ready(conn->sock[sockindex],
CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
for(;;) {
if(what < 0) {
/* anything that gets here is fatally bad */
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
rc = -1;
break;
}
if(!what) { /* timeout */
failf(data, "SSL shutdown timeout");
break;
}
/* Something to read, let's do it and hope that it is the close
notify alert from the server. No way to gsk_secure_soc_read() now, so
use read(). */
nread = read(conn->sock[sockindex], buf, sizeof(buf));
if(nread < 0) {
failf(data, "read: %s", strerror(errno));
rc = -1;
}
if(nread <= 0)
break;
what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, 0);
}
return rc;
}
size_t Curl_gskit_version(char * buffer, size_t size)
{
strncpy(buffer, "GSKit", size);
return strlen(buffer);
}
int Curl_gskit_check_cxn(struct connectdata * cxn)
{
int err;
int errlen;
/* The only thing that can be tested here is at the socket level. */
if(!cxn->ssl[FIRSTSOCKET].handle)
return 0; /* connection has been closed */
err = 0;
errlen = sizeof err;
if(getsockopt(cxn->sock[FIRSTSOCKET], SOL_SOCKET, SO_ERROR,
(unsigned char *) &err, &errlen) ||
errlen != sizeof err || err)
return 0; /* connection has been closed */
return -1; /* connection status unknown */
}
#endif /* USE_GSKIT */

64
lib/gskit.h Normal file
View File

@@ -0,0 +1,64 @@
#ifndef HEADER_CURL_GSKIT_H
#define HEADER_CURL_GSKIT_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "curl_setup.h"
/*
* This header should only be needed to get included by sslgen.c and gskit.c
*/
#include "urldata.h"
#ifdef USE_GSKIT
int Curl_gskit_init(void);
void Curl_gskit_cleanup(void);
CURLcode Curl_gskit_connect(struct connectdata * conn, int sockindex);
CURLcode Curl_gskit_connect_nonblocking(struct connectdata * conn,
int sockindex, bool * done);
void Curl_gskit_close(struct connectdata *conn, int sockindex);
int Curl_gskit_close_all(struct SessionHandle * data);
int Curl_gskit_shutdown(struct connectdata * conn, int sockindex);
size_t Curl_gskit_version(char * buffer, size_t size);
int Curl_gskit_check_cxn(struct connectdata * cxn);
/* API setup for GSKit */
#define curlssl_init Curl_gskit_init
#define curlssl_cleanup Curl_gskit_cleanup
#define curlssl_connect Curl_gskit_connect
#define curlssl_connect_nonblocking Curl_gskit_connect_nonblocking
/* No session handling for GSKit */
#define curlssl_session_free(x) Curl_nop_stmt
#define curlssl_close_all Curl_gskit_close_all
#define curlssl_close Curl_gskit_close
#define curlssl_shutdown(x,y) Curl_gskit_shutdown(x,y)
#define curlssl_set_engine(x,y) CURLE_NOT_BUILT_IN
#define curlssl_set_engine_default(x) CURLE_NOT_BUILT_IN
#define curlssl_engines_list(x) NULL
#define curlssl_version Curl_gskit_version
#define curlssl_check_cxn(x) Curl_gskit_check_cxn(x)
#define curlssl_data_pending(x,y) 0
#endif /* USE_GSKIT */
#endif /* HEADER_CURL_GSKIT_H */

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -55,6 +55,10 @@ void Curl_gtls_md5sum(unsigned char *tmp, /* input */
unsigned char *md5sum, /* output */
size_t md5len);
/* this backend provides these functions: */
#define have_curlssl_random 1
#define have_curlssl_md5sum 1
/* API setup for GnuTLS */
#define curlssl_init Curl_gtls_init
#define curlssl_cleanup Curl_gtls_cleanup

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -391,7 +391,7 @@ void Curl_hash_print(struct curl_hash *h,
if(func)
func(he->ptr);
else
fprintf(stderr, " [%p]", he->ptr);
fprintf(stderr, " [%p]", (void *)he->ptr);
he = Curl_hash_next_element(&iter);
}

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -22,8 +22,9 @@
#include "curl_setup.h"
#if defined(USE_SSLEAY) || defined(USE_AXTLS)
/* these two backends use functions from this file */
#if defined(USE_SSLEAY) || defined(USE_AXTLS) || defined(USE_QSOSSL) || \
defined(USE_GSKIT)
/* these backends use functions from this file */
#include "hostcheck.h"
#include "rawstr.h"
@@ -93,4 +94,4 @@ int Curl_cert_hostcheck(const char *match_pattern, const char *hostname)
return 0;
}
#endif /* SSLEAY or AXTLS */
#endif /* SSLEAY or AXTLS or QSOSSL or GSKIT */

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -140,6 +140,10 @@ struct curl_hash *Curl_global_host_cache_init(void)
void Curl_global_host_cache_dtor(void)
{
if(host_cache_initialized) {
/* first make sure that any custom "CURLOPT_RESOLVE" names are
cleared off */
Curl_hostcache_clean(NULL, &hostname_cache);
/* then free the remaining hash completely */
Curl_hash_clean(&hostname_cache);
host_cache_initialized = 0;
}
@@ -681,12 +685,14 @@ clean_up:
* Curl_resolv_unlock() unlocks the given cached DNS entry. When this has been
* made, the struct may be destroyed due to pruning. It is important that only
* one unlock is made for each Curl_resolv() call.
*
* May be called with 'data' == NULL for global cache.
*/
void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns)
{
DEBUGASSERT(dns && (dns->inuse>0));
if(data->share)
if(data && data->share)
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
dns->inuse--;
@@ -697,7 +703,7 @@ void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns)
free(dns);
}
if(data->share)
if(data && data->share)
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
}
@@ -734,22 +740,23 @@ static int hostcache_inuse(void *data, void *hc)
return 1; /* free all entries */
}
void Curl_hostcache_clean(struct SessionHandle *data)
/*
* Curl_hostcache_clean()
*
* This _can_ be called with 'data' == NULL but then of course no locking
* can be done!
*/
void Curl_hostcache_clean(struct SessionHandle *data,
struct curl_hash *hash)
{
/* Entries added to the hostcache with the CURLOPT_RESOLVE function are
* still present in the cache with the inuse counter set to 1. Detect them
* and cleanup!
*/
Curl_hash_clean_with_criterium(data->dns.hostcache, data, hostcache_inuse);
Curl_hash_clean_with_criterium(hash, data, hostcache_inuse);
}
void Curl_hostcache_destroy(struct SessionHandle *data)
{
Curl_hostcache_clean(data);
Curl_hash_destroy(data->dns.hostcache);
data->dns.hostcachetype = HCACHE_NONE;
data->dns.hostcache = NULL;
}
CURLcode Curl_loadhostpairs(struct SessionHandle *data)
{

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -200,10 +200,31 @@ extern sigjmp_buf curl_jmpenv;
*/
CURLcode Curl_set_dns_servers(struct SessionHandle *data, char *servers);
/*
* Function provided by the resolver backend to set
* outgoing interface to use for DNS requests
*/
CURLcode Curl_set_dns_interface(struct SessionHandle *data,
const char *interf);
/*
* Function provided by the resolver backend to set
* local IPv4 address to use as source address for DNS requests
*/
CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
const char *local_ip4);
/*
* Function provided by the resolver backend to set
* local IPv6 address to use as source address for DNS requests
*/
CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data,
const char *local_ip6);
/*
* Clean off entries from the cache
*/
void Curl_hostcache_clean(struct SessionHandle *data);
void Curl_hostcache_clean(struct SessionHandle *data, struct curl_hash *hash);
/*
* Destroy the hostcache of this handle.

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -140,7 +140,7 @@ Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
#if defined(HAVE_GETADDRINFO_THREADSAFE)
else {
struct addrinfo hints;
char sbuf[NI_MAXSERV];
char sbuf[12];
char *sbufptr = NULL;
memset(&hints, 0, sizeof(hints));

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -168,7 +168,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
struct addrinfo hints;
Curl_addrinfo *res;
int error;
char sbuf[NI_MAXSERV];
char sbuf[12];
char *sbufptr = NULL;
char addrbuf[128];
int pf;

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -72,4 +72,40 @@ CURLcode Curl_set_dns_servers(struct SessionHandle *data,
}
/*
* Function provided by the resolver backend to set
* outgoing interface to use for DNS requests
*/
CURLcode Curl_set_dns_interface(struct SessionHandle *data,
const char *interf)
{
(void)data;
(void)interf;
return CURLE_NOT_BUILT_IN;
}
/*
* Function provided by the resolver backend to set
* local IPv4 address to use as source address for DNS requests
*/
CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
const char *local_ip4)
{
(void)data;
(void)local_ip4;
return CURLE_NOT_BUILT_IN;
}
/*
* Function provided by the resolver backend to set
* local IPv6 address to use as source address for DNS requests
*/
CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data,
const char *local_ip6)
{
(void)data;
(void)local_ip6;
return CURLE_NOT_BUILT_IN;
}
#endif /* truly sync */

View File

@@ -75,6 +75,7 @@
#include "non-ascii.h"
#include "bundles.h"
#include "pipeline.h"
#include "http2.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -105,7 +106,7 @@ static int https_getsock(struct connectdata *conn,
*/
const struct Curl_handler Curl_handler_http = {
"HTTP", /* scheme */
ZERO_NULL, /* setup_connection */
Curl_http_setup_conn, /* setup_connection */
Curl_http, /* do_it */
Curl_http_done, /* done */
ZERO_NULL, /* do_more */
@@ -129,7 +130,7 @@ const struct Curl_handler Curl_handler_http = {
*/
const struct Curl_handler Curl_handler_https = {
"HTTPS", /* scheme */
ZERO_NULL, /* setup_connection */
Curl_http_setup_conn, /* setup_connection */
Curl_http, /* do_it */
Curl_http_done, /* done */
ZERO_NULL, /* do_more */
@@ -149,6 +150,19 @@ const struct Curl_handler Curl_handler_https = {
#endif
CURLcode Curl_http_setup_conn(struct connectdata *conn)
{
/* allocate the HTTP-specific struct for the SessionHandle, only to survive
during this request */
DEBUGASSERT(conn->data->req.protop == NULL);
conn->data->req.protop = calloc(1, sizeof(struct HTTP));
if(!conn->data->req.protop)
return CURLE_OUT_OF_MEMORY;
return CURLE_OK;
}
/*
* checkheaders() checks the linked list of custom HTTP headers for a
* particular header (prefix).
@@ -330,7 +344,7 @@ static bool pickoneauth(struct auth *pick)
static CURLcode http_perhapsrewind(struct connectdata *conn)
{
struct SessionHandle *data = conn->data;
struct HTTP *http = data->state.proto.http;
struct HTTP *http = data->req.protop;
curl_off_t bytessent;
curl_off_t expectsend = -1; /* default is unknown */
@@ -948,7 +962,7 @@ static size_t readmoredata(char *buffer,
void *userp)
{
struct connectdata *conn = (struct connectdata *)userp;
struct HTTP *http = conn->data->state.proto.http;
struct HTTP *http = conn->data->req.protop;
size_t fullsize = size * nitems;
if(0 == http->postsize)
@@ -1019,7 +1033,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
CURLcode res;
char *ptr;
size_t size;
struct HTTP *http = conn->data->state.proto.http;
struct HTTP *http = conn->data->req.protop;
size_t sendsize;
curl_socket_t sockfd;
size_t headersize;
@@ -1402,7 +1416,7 @@ CURLcode Curl_http_done(struct connectdata *conn,
CURLcode status, bool premature)
{
struct SessionHandle *data = conn->data;
struct HTTP *http =data->state.proto.http;
struct HTTP *http =data->req.protop;
Curl_unencode_cleanup(conn);
@@ -1442,6 +1456,7 @@ CURLcode Curl_http_done(struct connectdata *conn,
if(!premature && /* this check is pointless when DONE is called before the
entire operation is complete */
!conn->bits.retry &&
!data->set.connect_only &&
((http->readbytecount +
data->req.headerbytecount -
data->req.deductheadercount)) <= 0) {
@@ -1456,14 +1471,19 @@ CURLcode Curl_http_done(struct connectdata *conn,
}
/* Determine if we should use HTTP 1.1 for this request. Reasons to avoid it
are if the user specifically requested HTTP 1.0, if the server we are
connected to only supports 1.0, or if any server previously contacted to
handle this request only supports 1.0. */
static bool use_http_1_1(const struct SessionHandle *data,
const struct connectdata *conn)
/*
* Determine if we should use HTTP 1.1 (OR BETTER) for this request. Reasons
* to avoid it include:
*
* - if the user specifically requested HTTP 1.0
* - if the server we are connected to only supports 1.0
* - if any server previously contacted to handle this request only supports
* 1.0.
*/
static bool use_http_1_1plus(const struct SessionHandle *data,
const struct connectdata *conn)
{
return ((data->set.httpversion == CURL_HTTP_VERSION_1_1) ||
return ((data->set.httpversion >= CURL_HTTP_VERSION_1_1) ||
((data->set.httpversion != CURL_HTTP_VERSION_1_0) &&
((conn->httpversion == 11) ||
((conn->httpversion != 10) &&
@@ -1479,7 +1499,7 @@ static CURLcode expect100(struct SessionHandle *data,
const char *ptr;
data->state.expect100header = FALSE; /* default to false unless it is set
to TRUE below */
if(use_http_1_1(data, conn)) {
if(use_http_1_1plus(data, conn)) {
/* if not doing HTTP 1.0 or disabled explicitly, we add a Expect:
100-continue to the headers which actually speeds up post operations
(as there is one packet coming back from the web server) */
@@ -1655,20 +1675,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
the rest of the request in the PERFORM phase. */
*done = TRUE;
/* If there already is a protocol-specific struct allocated for this
sessionhandle, deal with it */
Curl_reset_reqproto(conn);
if(!data->state.proto.http) {
/* Only allocate this struct if we don't already have it! */
http = calloc(1, sizeof(struct HTTP));
if(!http)
return CURLE_OUT_OF_MEMORY;
data->state.proto.http = http;
}
else
http = data->state.proto.http;
http = data->req.protop;
if(!data->state.this_is_a_follow) {
/* this is not a followed location, get the original host name */
@@ -1795,7 +1802,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
if(conn->bits.authneg)
/* don't enable chunked during auth neg */
;
else if(use_http_1_1(data, conn)) {
else if(use_http_1_1plus(data, conn)) {
/* HTTP, upload, unknown file size and not HTTP 1.0 */
data->req.upload_chunky = TRUE;
}
@@ -2095,7 +2102,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
/* Use 1.1 unless the user specifically asked for 1.0 or the server only
supports 1.0 */
httpstring= use_http_1_1(data, conn)?"1.1":"1.0";
httpstring= use_http_1_1plus(data, conn)?"1.1":"1.0";
/* initialize a dynamic send-buffer */
req_buffer = Curl_add_buffer_init();
@@ -2173,6 +2180,15 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
if(result)
return result;
if(!(conn->handler->flags&PROTOPT_SSL) &&
(data->set.httpversion == CURL_HTTP_VERSION_2_0)) {
/* append HTTP2 updrade magic stuff to the HTTP request if it isn't done
over SSL */
result = Curl_http2_request(req_buffer, conn);
if(result)
return result;
}
#if !defined(CURL_DISABLE_COOKIES)
if(data->cookies || addcookies) {
struct Cookie *co=NULL; /* no cookies from start */

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -21,8 +21,14 @@
* KIND, either express or implied.
*
***************************************************************************/
#include "curl_setup.h"
#ifndef CURL_DISABLE_HTTP
#ifdef USE_NGHTTP2
#include <nghttp2/nghttp2.h>
#endif
extern const struct Curl_handler Curl_handler_http;
#ifdef USE_SSL
@@ -66,6 +72,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
CURLcode Curl_http(struct connectdata *conn, bool *done);
CURLcode Curl_http_done(struct connectdata *, CURLcode, bool premature);
CURLcode Curl_http_connect(struct connectdata *conn, bool *done);
CURLcode Curl_http_setup_conn(struct connectdata *conn);
/* The following functions are defined in http_chunks.c */
void Curl_httpchunk_init(struct connectdata *conn);
@@ -141,6 +148,14 @@ struct HTTP {
points to an allocated send_buffer struct */
};
struct http_conn {
#ifdef USE_NGHTTP2
nghttp2_session *h2;
#else
int unused; /* prevent a compiler warning */
#endif
};
CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
struct connectdata *conn,
ssize_t *nread,

182
lib/http2.c Normal file
View File

@@ -0,0 +1,182 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "curl_setup.h"
#ifdef USE_NGHTTP2
#define _MPRINTF_REPLACE
#include <curl/mprintf.h>
#include <nghttp2/nghttp2.h>
#include "urldata.h"
#include "http2.h"
#include "http.h"
#include "sendf.h"
#include "curl_base64.h"
#include "curl_memory.h"
/* include memdebug.h last */
#include "memdebug.h"
/*
* Store nghttp2 version info in this buffer, Prefix with a space. Return
* total length written.
*/
int Curl_http2_ver(char *p, size_t len)
{
nghttp2_info *h2 = nghttp2_version(0);
return snprintf(p, len, " nghttp2/%s", h2->version_str);
}
/*
* The implementation of nghttp2_send_callback type. Here we write |data| with
* size |length| to the network and return the number of bytes actually
* written. See the documentation of nghttp2_send_callback for the details.
*/
static ssize_t send_callback(nghttp2_session *h2,
const uint8_t *data, size_t length, int flags,
void *userp)
{
struct connectdata *conn = (struct connectdata *)userp;
ssize_t written;
CURLcode rc =
Curl_write(conn, conn->sock[0], data, length, &written);
(void)h2;
(void)flags;
if(rc) {
failf(conn->data, "Failed sending HTTP2 data");
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
else if(!written)
return NGHTTP2_ERR_WOULDBLOCK;
return written;
}
/*
* The implementation of nghttp2_recv_callback type. Here we read data from
* the network and write them in |buf|. The capacity of |buf| is |length|
* bytes. Returns the number of bytes stored in |buf|. See the documentation
* of nghttp2_recv_callback for the details.
*/
static ssize_t recv_callback(nghttp2_session *h2,
uint8_t *buf, size_t length, int flags,
void *userp)
{
struct connectdata *conn = (struct connectdata *)userp;
ssize_t nread;
CURLcode rc = Curl_read(conn, conn->sock[0], (char *)buf, length, &nread);
(void)h2;
(void)flags;
if(rc) {
failf(conn->data, "Failed recving HTTP2 data");
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
if(!nread)
return NGHTTP2_ERR_WOULDBLOCK;
return nread;
}
/*
* This is all callbacks nghttp2 calls
*/
static const nghttp2_session_callbacks callbacks = {
send_callback,
recv_callback,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};
/*
* The HTTP2 settings we send in the Upgrade request
*/
static nghttp2_settings_entry settings[] = {
{ NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 100 },
{ NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, NGHTTP2_INITIAL_WINDOW_SIZE },
};
/*
* Append headers to ask for a HTTP1.1 to HTTP2 upgrade.
*/
CURLcode Curl_http2_request(Curl_send_buffer *req,
struct connectdata *conn)
{
uint8_t binsettings[80];
CURLcode result;
ssize_t binlen;
char *base64;
size_t blen;
if(!conn->proto.httpc.h2) {
/* The nghttp2 session is not yet setup, do it */
int rc = nghttp2_session_client_new(&conn->proto.httpc.h2,
&callbacks, &conn);
if(rc) {
failf(conn->data, "Couldn't initialize nghttp2!");
return CURLE_OUT_OF_MEMORY; /* most likely at least */
}
}
/* As long as we have a fixed set of settings, we don't have to dynamically
* figure out the base64 strings since it'll always be the same. However,
* the settings will likely not be fixed every time in the future.
*/
/* this returns number of bytes it wrote */
binlen = nghttp2_pack_settings_payload(binsettings,
sizeof(binsettings),
settings,
sizeof(settings)/sizeof(settings[0]));
if(!binlen) {
failf(conn->data, "nghttp2 unexpectedly failed on pack_settings_payload");
return CURLE_FAILED_INIT;
}
result = Curl_base64_encode(conn->data, (const char *)binsettings, binlen,
&base64, &blen);
if(result)
return result;
result = Curl_add_bufferf(req,
"Connection: Upgrade, HTTP2-Settings\r\n"
"Upgrade: %s\r\n"
"HTTP2-Settings: %s\r\n",
NGHTTP2_PROTO_VERSION_ID, base64);
free(base64);
return result;
}
#endif

View File

@@ -1,3 +1,5 @@
#ifndef HEADER_CURL_HTTP2_H
#define HEADER_CURL_HTTP2_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@@ -5,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -22,40 +24,19 @@
#include "curl_setup.h"
#include <curl/curl.h>
#ifdef USE_NGHTTP2
#include "http.h"
/*
* Store nghttp2 version info in this buffer, Prefix with a space. Return
* total length written.
*/
int Curl_http2_ver(char *p, size_t len);
#include "curl_rand.h"
CURLcode Curl_http2_request(Curl_send_buffer *req,
struct connectdata *conn);
#else /* USE_NGHTTP2 */
#define Curl_http2_request(x,y) CURLE_OK
#endif
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
#include "curl_memory.h"
/* The last #include file should be: */
#include "memdebug.h"
/* Private pseudo-random number seed. Unsigned integer >= 32bit. Threads
mutual exclusion is not implemented to acess it since we do not require
high quality random numbers (only used in form boudary generation). */
static unsigned int randseed;
/* Pseudo-random number support. */
unsigned int Curl_rand(void)
{
unsigned int r;
/* Return an unsigned 32-bit pseudo-random number. */
r = randseed = randseed * 1103515245 + 12345;
return (r << 16) | ((r >> 16) & 0xFFFF);
}
void Curl_srand(void)
{
/* Randomize pseudo-random number sequence. */
randseed = (unsigned int) time(NULL);
Curl_rand();
Curl_rand();
Curl_rand();
}
#endif /* HEADER_CURL_HTTP2_H */

View File

@@ -25,14 +25,13 @@
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
#include "urldata.h"
#include "sendf.h"
#include "rawstr.h"
#include "curl_base64.h"
#include "curl_md5.h"
#include "http_digest.h"
#include "strtok.h"
#include "url.h" /* for Curl_safefree() */
#include "curl_memory.h"
#include "sslgen.h" /* for Curl_rand() */
#include "non-ascii.h" /* included for Curl_convert_... prototypes */
#include "warnless.h"
@@ -267,6 +266,38 @@ static void md5_to_ascii(unsigned char *source, /* 16 bytes */
snprintf((char *)&dest[i*2], 3, "%02x", source[i]);
}
/* Perform quoted-string escaping as described in RFC2616 and its errata */
static char *string_quoted(const char *source)
{
char *dest, *d;
const char *s = source;
size_t n = 1; /* null terminator */
/* Calculate size needed */
while(*s) {
++n;
if(*s == '"' || *s == '\\') {
++n;
}
++s;
}
dest = malloc(n);
if(dest) {
s = source;
d = dest;
while(*s) {
if(*s == '"' || *s == '\\') {
*d++ = '\\';
}
*d++ = *s++;
}
*d = 0;
}
return dest;
}
CURLcode Curl_output_digest(struct connectdata *conn,
bool proxy,
const unsigned char *request,
@@ -278,17 +309,16 @@ CURLcode Curl_output_digest(struct connectdata *conn,
unsigned char md5buf[16]; /* 16 bytes/128 bits */
unsigned char request_digest[33];
unsigned char *md5this;
unsigned char *ha1;
unsigned char ha1[33];/* 32 digits and 1 zero byte */
unsigned char ha2[33];/* 32 digits and 1 zero byte */
char cnoncebuf[33];
char *cnonce = NULL;
size_t cnonce_sz = 0;
char *tmp = NULL;
struct timeval now;
char **allocuserpwd;
size_t userlen;
const char *userp;
char *userp_quoted;
const char *passwdp;
struct auth *authp;
@@ -321,10 +351,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
authp = &data->state.authhost;
}
if(*allocuserpwd) {
Curl_safefree(*allocuserpwd);
*allocuserpwd = NULL;
}
Curl_safefree(*allocuserpwd);
/* not set means empty */
if(!userp)
@@ -343,10 +370,11 @@ CURLcode Curl_output_digest(struct connectdata *conn,
d->nc = 1;
if(!d->cnonce) {
/* Generate a cnonce */
now = Curl_tvnow();
snprintf(cnoncebuf, sizeof(cnoncebuf), "%32ld",
(long)now.tv_sec + now.tv_usec);
struct timeval now = Curl_tvnow();
snprintf(cnoncebuf, sizeof(cnoncebuf), "%08x%08x%08x%08x",
Curl_rand(data), Curl_rand(data),
(unsigned int)now.tv_sec,
(unsigned int)now.tv_usec);
rc = Curl_base64_encode(data, cnoncebuf, strlen(cnoncebuf),
&cnonce, &cnonce_sz);
@@ -373,12 +401,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
Curl_md5it(md5buf, md5this);
free(md5this); /* free this again */
ha1 = malloc(33); /* 32 digits and 1 zero byte */
if(!ha1)
return CURLE_OUT_OF_MEMORY;
Curl_safefree(md5this);
md5_to_ascii(md5buf, ha1);
if(d->algo == CURLDIGESTALGO_MD5SESS) {
@@ -388,7 +411,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
return CURLE_OUT_OF_MEMORY;
CURL_OUTPUT_DIGEST_CONV(data, tmp); /* convert on non-ASCII machines */
Curl_md5it(md5buf, (unsigned char *)tmp);
free(tmp); /* free this again */
Curl_safefree(tmp);
md5_to_ascii(md5buf, ha1);
}
@@ -425,19 +448,21 @@ CURLcode Curl_output_digest(struct connectdata *conn,
else
md5this = (unsigned char *)aprintf("%s:%s", request, uripath);
if(!md5this) {
free(ha1);
return CURLE_OUT_OF_MEMORY;
if(d->qop && Curl_raw_equal(d->qop, "auth-int")) {
/* We don't support auth-int for PUT or POST at the moment.
TODO: replace md5 of empty string with entity-body for PUT/POST */
unsigned char *md5this2 = (unsigned char *)
aprintf("%s:%s", md5this, "d41d8cd98f00b204e9800998ecf8427e");
Curl_safefree(md5this);
md5this = md5this2;
}
if(d->qop && Curl_raw_equal(d->qop, "auth-int")) {
/* We don't support auth-int at the moment. I can't see a easy way to get
entity-body here */
/* TODO: Append H(entity-body)*/
}
if(!md5this)
return CURLE_OUT_OF_MEMORY;
CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
Curl_md5it(md5buf, md5this);
free(md5this); /* free this again */
Curl_safefree(md5this);
md5_to_ascii(md5buf, ha2);
if(d->qop) {
@@ -455,20 +480,30 @@ CURLcode Curl_output_digest(struct connectdata *conn,
d->nonce,
ha2);
}
free(ha1);
if(!md5this)
return CURLE_OUT_OF_MEMORY;
CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
Curl_md5it(md5buf, md5this);
free(md5this); /* free this again */
Curl_safefree(md5this);
md5_to_ascii(md5buf, request_digest);
/* for test case 64 (snooped from a Mozilla 1.3a request)
Authorization: Digest username="testuser", realm="testrealm", \
nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca"
Digest parameters are all quoted strings. Username which is provided by
the user will need double quotes and backslashes within it escaped. For
the other fields, this shouldn't be an issue. realm, nonce, and opaque
are copied as is from the server, escapes and all. cnonce is generated
with web-safe characters. uri is already percent encoded. nc is 8 hex
characters. algorithm and qop with standard values only contain web-safe
chracters.
*/
userp_quoted = string_quoted(userp);
if(!userp_quoted)
return CURLE_OUT_OF_MEMORY;
if(d->qop) {
*allocuserpwd =
@@ -482,7 +517,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
"qop=%s, "
"response=\"%s\"",
proxy?"Proxy-":"",
userp,
userp_quoted,
d->realm,
d->nonce,
uripath, /* this is the PATH part of the URL */
@@ -505,12 +540,13 @@ CURLcode Curl_output_digest(struct connectdata *conn,
"uri=\"%s\", "
"response=\"%s\"",
proxy?"Proxy-":"",
userp,
userp_quoted,
d->realm,
d->nonce,
uripath, /* this is the PATH part of the URL */
request_digest);
}
Curl_safefree(userp_quoted);
if(!*allocuserpwd)
return CURLE_OUT_OF_MEMORY;
@@ -546,29 +582,12 @@ CURLcode Curl_output_digest(struct connectdata *conn,
static void digest_cleanup_one(struct digestdata *d)
{
if(d->nonce)
free(d->nonce);
d->nonce = NULL;
if(d->cnonce)
free(d->cnonce);
d->cnonce = NULL;
if(d->realm)
free(d->realm);
d->realm = NULL;
if(d->opaque)
free(d->opaque);
d->opaque = NULL;
if(d->qop)
free(d->qop);
d->qop = NULL;
if(d->algorithm)
free(d->algorithm);
d->algorithm = NULL;
Curl_safefree(d->nonce);
Curl_safefree(d->cnonce);
Curl_safefree(d->realm);
Curl_safefree(d->opaque);
Curl_safefree(d->qop);
Curl_safefree(d->algorithm);
d->nc = 0;
d->algo = CURLDIGESTALGO_MD5; /* default algorithm */

Some files were not shown because too many files have changed in this diff Show More