Compare commits
860 Commits
curl-7_30_
...
curl-7_34_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0966b324d9 | ||
|
|
c0ef05e675 | ||
|
|
1dc43de0dc | ||
|
|
8a8f9a5d57 | ||
|
|
be28223f35 | ||
|
|
8e2d73bbde | ||
|
|
dd4d9ea542 | ||
|
|
169fedbdce | ||
|
|
32b9c30e67 | ||
|
|
75cd7fd667 | ||
|
|
7246dffff5 | ||
|
|
41d21e460f | ||
|
|
aadca7f418 | ||
|
|
3905bd637d | ||
|
|
c4f46e97ca | ||
|
|
bd3ca6630a | ||
|
|
92e607abfa | ||
|
|
ef118c13ba | ||
|
|
1cf71bd76e | ||
|
|
2c0ecac9d3 | ||
|
|
b0b5b51193 | ||
|
|
ff9b66a8d4 | ||
|
|
e221b55f67 | ||
|
|
865666afca | ||
|
|
7fc9325a52 | ||
|
|
4fb8241add | ||
|
|
30e7e7552b | ||
|
|
f58f843f66 | ||
|
|
d92de3a7e9 | ||
|
|
fe7fc61c6e | ||
|
|
ad3836448e | ||
|
|
f3ee587775 | ||
|
|
c92c30edbd | ||
|
|
4d10f48629 | ||
|
|
dc68120e63 | ||
|
|
0db811b69b | ||
|
|
d81cbbcc2c | ||
|
|
0dd6522036 | ||
|
|
889cb9c982 | ||
|
|
26ff1ea6c3 | ||
|
|
59f1209fad | ||
|
|
7b9365c65f | ||
|
|
a900d45489 | ||
|
|
e64f91feb7 | ||
|
|
b2a55c8106 | ||
|
|
030a2b8cb8 | ||
|
|
edce855943 | ||
|
|
35e476a3f6 | ||
|
|
0434a19431 | ||
|
|
2ff0c6f5f3 | ||
|
|
8a94aedbd6 | ||
|
|
95877cf8ae | ||
|
|
d3325ae40a | ||
|
|
23fabf8dea | ||
|
|
7a36b2abc0 | ||
|
|
e1c255f388 | ||
|
|
6d3c832a30 | ||
|
|
7935478397 | ||
|
|
5ee64be9c6 | ||
|
|
9f18cf15d5 | ||
|
|
bf05da183e | ||
|
|
2c04e8d80c | ||
|
|
925df53580 | ||
|
|
8191800a0c | ||
|
|
2165298fe6 | ||
|
|
e885dc85a1 | ||
|
|
df58084695 | ||
|
|
3c8c9b2779 | ||
|
|
b27dc009cf | ||
|
|
2c7a5578e1 | ||
|
|
b56d7cda74 | ||
|
|
8896b56488 | ||
|
|
0d735c29f9 | ||
|
|
3d50e91aee | ||
|
|
0cbfe5a7d5 | ||
|
|
eedca5055e | ||
|
|
5d040632ac | ||
|
|
314c3b8480 | ||
|
|
d630e1f389 | ||
|
|
0ea4a80bb2 | ||
|
|
ed4ce23c23 | ||
|
|
168aa59705 | ||
|
|
f71b1ad908 | ||
|
|
dac01ff6d7 | ||
|
|
4a9fe26837 | ||
|
|
90ec8763a5 | ||
|
|
796333bc5e | ||
|
|
f16c0de4e9 | ||
|
|
786cba1ada | ||
|
|
ed1662c374 | ||
|
|
1f0616ea1a | ||
|
|
55250d2d02 | ||
|
|
c5d73167a6 | ||
|
|
bde901ad89 | ||
|
|
79c77f7c31 | ||
|
|
986c249f2f | ||
|
|
3b8c3eb911 | ||
|
|
b29217d0d6 | ||
|
|
534f90f9bf | ||
|
|
dbe228353d | ||
|
|
bf77101e5c | ||
|
|
2ea9a125a6 | ||
|
|
58a00d6d9f | ||
|
|
57a27528e6 | ||
|
|
632c1edd06 | ||
|
|
434bc09263 | ||
|
|
f2584627c8 | ||
|
|
6901861fc9 | ||
|
|
d7d8a8f922 | ||
|
|
c19cfb79db | ||
|
|
65ce9b6d6c | ||
|
|
5f34a10445 | ||
|
|
fa1253aee1 | ||
|
|
f833f54979 | ||
|
|
e7d77fb3ef | ||
|
|
c8e63f247a | ||
|
|
7396ad6e09 | ||
|
|
6d295f8d7d | ||
|
|
5bd999d0c5 | ||
|
|
0f81fbe5da | ||
|
|
9b67960421 | ||
|
|
e10a26a9d6 | ||
|
|
7b68b58bc0 | ||
|
|
2d5455feac | ||
|
|
ac05c80f19 | ||
|
|
460adfef93 | ||
|
|
c876f6ae6d | ||
|
|
f49276bfcb | ||
|
|
d08ee3c83d | ||
|
|
cf7008670b | ||
|
|
558034ab70 | ||
|
|
27b7b1062f | ||
|
|
af82661dbd | ||
|
|
76f924131c | ||
|
|
98a5fdaf29 | ||
|
|
1ea05be46d | ||
|
|
c9d8c00a41 | ||
|
|
5aa290f0f2 | ||
|
|
f0831f7931 | ||
|
|
7fc3b2ce38 | ||
|
|
02fbc26d59 | ||
|
|
0074c9f5d1 | ||
|
|
90acbfd52e | ||
|
|
989b28fe97 | ||
|
|
aa61e14dc1 | ||
|
|
a84a09ad0b | ||
|
|
66b8557aff | ||
|
|
63cac69c2a | ||
|
|
f77d9b6584 | ||
|
|
2736b27df7 | ||
|
|
297644fa70 | ||
|
|
0177f28c51 | ||
|
|
732d10ed6c | ||
|
|
526a1c3b45 | ||
|
|
5b315a273e | ||
|
|
5094bb53f4 | ||
|
|
052f24c9b7 | ||
|
|
bce03fe144 | ||
|
|
9a1755264f | ||
|
|
3b59696a93 | ||
|
|
cdccb42267 | ||
|
|
753d44fa00 | ||
|
|
cfdfdcdd9d | ||
|
|
e232f5f3f9 | ||
|
|
43400b4086 | ||
|
|
8179354c2f | ||
|
|
f6c335d63f | ||
|
|
2bd72fa61c | ||
|
|
e17c1b25bc | ||
|
|
7d1eb66cd7 | ||
|
|
255826c40f | ||
|
|
1d0eead969 | ||
|
|
8005e58983 | ||
|
|
5d415815df | ||
|
|
f68559c086 | ||
|
|
08f97f3b1d | ||
|
|
b87ba2c942 | ||
|
|
e7a2ba41e3 | ||
|
|
6fe619be7a | ||
|
|
1e39b95682 | ||
|
|
8230af0b94 | ||
|
|
1709e5e966 | ||
|
|
7d7df83198 | ||
|
|
7de4cc35f8 | ||
|
|
aa0eaef483 | ||
|
|
9f503a254b | ||
|
|
d44b014271 | ||
|
|
469b423350 | ||
|
|
0adad07690 | ||
|
|
e4670a1029 | ||
|
|
1f0e50f2b9 | ||
|
|
2766262a68 | ||
|
|
bdb1f0e53d | ||
|
|
6e3613e6e6 | ||
|
|
1cb5150dba | ||
|
|
d24b7953c2 | ||
|
|
13db74ffc3 | ||
|
|
98905aa2c5 | ||
|
|
820ed48a00 | ||
|
|
973cc22529 | ||
|
|
2cc9246477 | ||
|
|
650036633f | ||
|
|
78aee26be6 | ||
|
|
947d431d50 | ||
|
|
58bd0148fb | ||
|
|
ca5c5be3e4 | ||
|
|
9bd37a6d27 | ||
|
|
1be69159f3 | ||
|
|
a3da0a96e3 | ||
|
|
626f8a85f0 | ||
|
|
867b52a7ac | ||
|
|
be31924f8c | ||
|
|
f70b2c77f4 | ||
|
|
ae495ffcc3 | ||
|
|
0fdfe82c6a | ||
|
|
dead10b1b8 | ||
|
|
41d820d2c3 | ||
|
|
5b31b38c27 | ||
|
|
39f4e4fafa | ||
|
|
587811c0a6 | ||
|
|
7f7fbe7fbd | ||
|
|
9b1eb2b421 | ||
|
|
1034aa6680 | ||
|
|
4be0af7f74 | ||
|
|
72f850571d | ||
|
|
e179d0eb12 | ||
|
|
ce61510127 | ||
|
|
86c64f3daf | ||
|
|
65e556d0ce | ||
|
|
6a1363128f | ||
|
|
75b9b26465 | ||
|
|
2c84ffe154 | ||
|
|
e7452415c5 | ||
|
|
87861c9b0e | ||
|
|
4d49ffe165 | ||
|
|
f63603dec4 | ||
|
|
0218a737fe | ||
|
|
18ca0aa984 | ||
|
|
c4e6c33b13 | ||
|
|
d774802eec | ||
|
|
69c0d3fbc8 | ||
|
|
076726f141 | ||
|
|
ad34a2d5c8 | ||
|
|
31e106c01c | ||
|
|
1dcc433661 | ||
|
|
a106abee62 | ||
|
|
f77e89c5d2 | ||
|
|
92cf6141ed | ||
|
|
cf12d5b62f | ||
|
|
39beaa5ffb | ||
|
|
5df04bfafd | ||
|
|
d015f4ccac | ||
|
|
143d7c13d8 | ||
|
|
9b33ecfd01 | ||
|
|
ca1b34b887 | ||
|
|
f0f95c97f7 | ||
|
|
4cd444e01a | ||
|
|
8264478490 | ||
|
|
b46491900d | ||
|
|
725288bf2f | ||
|
|
173160c0d0 | ||
|
|
3c3622b662 | ||
|
|
a22c478ed7 | ||
|
|
3d43a48781 | ||
|
|
c8b05b809e | ||
|
|
ca995010d0 | ||
|
|
25a0c96a49 | ||
|
|
a8b606b1a6 | ||
|
|
20a99a45c0 | ||
|
|
49341628b5 | ||
|
|
ab7e6afd44 | ||
|
|
4d7bf73fc3 | ||
|
|
3c34f453fa | ||
|
|
d5f687ed8f | ||
|
|
a377fab015 | ||
|
|
092f33d6bf | ||
|
|
09a13a1c01 | ||
|
|
30a09783b2 | ||
|
|
733a4419d0 | ||
|
|
77dc4ba877 | ||
|
|
14d8209adc | ||
|
|
a942d8ff5b | ||
|
|
1695c67818 | ||
|
|
f81d1e1666 | ||
|
|
b71ed1fb3d | ||
|
|
86ccfaa3fd | ||
|
|
3b69462fc0 | ||
|
|
22bccb0eda | ||
|
|
4f591b9148 | ||
|
|
52cefc8cd7 | ||
|
|
8880f84e1a | ||
|
|
9d4a8c7936 | ||
|
|
fd8dc21fd0 | ||
|
|
8ec6486d05 | ||
|
|
59c1743c78 | ||
|
|
60a2046162 | ||
|
|
6dd8bd8d2f | ||
|
|
b07709f741 | ||
|
|
9215cee4c6 | ||
|
|
34df869f99 | ||
|
|
3f04d48495 | ||
|
|
517b8e2290 | ||
|
|
af44da38d6 | ||
|
|
fcfa26a7ee | ||
|
|
18db743851 | ||
|
|
0e188e2dc3 | ||
|
|
eecb0e969f | ||
|
|
bd7d56ec71 | ||
|
|
6f78aaad6f | ||
|
|
89d320c2fd | ||
|
|
b809bafb0c | ||
|
|
3b6a1681dc | ||
|
|
9300bb826d | ||
|
|
dfe7ee1429 | ||
|
|
841103c776 | ||
|
|
8d2335ca23 | ||
|
|
04064e89c1 | ||
|
|
c873375123 | ||
|
|
62d232c131 | ||
|
|
98f7ca7e97 | ||
|
|
4cfbb201c4 | ||
|
|
dc016567ce | ||
|
|
96b68c57ce | ||
|
|
158dfe2c5c | ||
|
|
8f5336a2fa | ||
|
|
f8a9dbd391 | ||
|
|
016879d477 | ||
|
|
c03335ec68 | ||
|
|
894585784c | ||
|
|
33c1f2876b | ||
|
|
00ee5c5cf1 | ||
|
|
dadc495540 | ||
|
|
eae86ba62d | ||
|
|
e9cca79dd1 | ||
|
|
4ba3b6c05a | ||
|
|
187ac69374 | ||
|
|
84ad1569e5 | ||
|
|
45e0a661ce | ||
|
|
4d6ef6297a | ||
|
|
b68c52704b | ||
|
|
4f4dc5832d | ||
|
|
fbcefc0ce0 | ||
|
|
83f6f58834 | ||
|
|
0a691f8935 | ||
|
|
c243d45aad | ||
|
|
8a6dba520b | ||
|
|
32352ed6ad | ||
|
|
df69440d05 | ||
|
|
345955e87e | ||
|
|
6f5b46855c | ||
|
|
5f93c5d658 | ||
|
|
7fd84b14d2 | ||
|
|
f2403140f9 | ||
|
|
f3c9749a40 | ||
|
|
3f6991766f | ||
|
|
cfe5f7dbf4 | ||
|
|
5840c918d5 | ||
|
|
b0afb00000 | ||
|
|
0b5ae7c80e | ||
|
|
0d55f4e1bc | ||
|
|
86d340af27 | ||
|
|
5c14a7f068 | ||
|
|
2879ffacfa | ||
|
|
d89eb55906 | ||
|
|
4a85e60cfe | ||
|
|
bfefe2400a | ||
|
|
25c6890375 | ||
|
|
eb6314260d | ||
|
|
313c38c9de | ||
|
|
ae6096471a | ||
|
|
66ea5c415b | ||
|
|
2481ac358c | ||
|
|
c639d725a3 | ||
|
|
857f999353 | ||
|
|
6d9cddc513 | ||
|
|
e20e48cbf2 | ||
|
|
ee5e2cf6cb | ||
|
|
e8313697b6 | ||
|
|
28427b4083 | ||
|
|
131649a121 | ||
|
|
632b3d81d6 | ||
|
|
241aeadc50 | ||
|
|
669e4ca366 | ||
|
|
c9617d9f93 | ||
|
|
f8986a2b34 | ||
|
|
1b96ce04b2 | ||
|
|
f851df88fb | ||
|
|
18c595fde2 | ||
|
|
56abdd07e7 | ||
|
|
7e06c336d6 | ||
|
|
8a4069fb17 | ||
|
|
243ad539fe | ||
|
|
3d60590422 | ||
|
|
08fa4fed70 | ||
|
|
4344fa926a | ||
|
|
61672bde44 | ||
|
|
13dbb41c49 | ||
|
|
e5c2354fd5 | ||
|
|
09634f46fb | ||
|
|
0119a93b33 | ||
|
|
9fa42beddc | ||
|
|
d6cda9e8ab | ||
|
|
2a7f1425d9 | ||
|
|
900ccc26ae | ||
|
|
01d7bbbebe | ||
|
|
3dc6fc42bf | ||
|
|
d2fe616e7e | ||
|
|
316ca865e3 | ||
|
|
812d49db90 | ||
|
|
02370fff3a | ||
|
|
e9de8e78f0 | ||
|
|
2eabb7d590 | ||
|
|
d707a975f6 | ||
|
|
ac487842a1 | ||
|
|
06b6e1d0d2 | ||
|
|
b77997e6da | ||
|
|
9e8ced9890 | ||
|
|
698e3bdf82 | ||
|
|
9011fb3f0c | ||
|
|
073b03fab7 | ||
|
|
f73f052010 | ||
|
|
97ed1ac905 | ||
|
|
322f0bc2f1 | ||
|
|
af4bddf20b | ||
|
|
f19efd07e7 | ||
|
|
83f5332536 | ||
|
|
497775024c | ||
|
|
ea38a70539 | ||
|
|
5eea336d01 | ||
|
|
f3849a7b84 | ||
|
|
1ca6ed7b75 | ||
|
|
aa51d3a139 | ||
|
|
64c8909071 | ||
|
|
e848942505 | ||
|
|
7e489c42f7 | ||
|
|
75b52f9dcc | ||
|
|
221825aebf | ||
|
|
9d35ad9552 | ||
|
|
c4a7ca038e | ||
|
|
84f3b3dd44 | ||
|
|
2ef83136d4 | ||
|
|
d737aa19c8 | ||
|
|
78e6683bb0 | ||
|
|
2f9b64ac33 | ||
|
|
6a353049ac | ||
|
|
49e3d803ab | ||
|
|
b644ae68c8 | ||
|
|
4ae7b7ea69 | ||
|
|
13a2e32548 | ||
|
|
c3b513e75c | ||
|
|
a74b36af2a | ||
|
|
1b4dc10393 | ||
|
|
45b6e2dd89 | ||
|
|
6dca35c0e5 | ||
|
|
a691e04470 | ||
|
|
3d1a453d88 | ||
|
|
d7a39f8f97 | ||
|
|
3c929ff9f6 | ||
|
|
9d957294cb | ||
|
|
acf59be7f0 | ||
|
|
e7dcc454c6 | ||
|
|
84789e12fb | ||
|
|
460fb12097 | ||
|
|
63d8b3a507 | ||
|
|
90ab65c632 | ||
|
|
34122800b8 | ||
|
|
7f41eab395 | ||
|
|
0192ad65bb | ||
|
|
06c1bea72f | ||
|
|
19a05c908f | ||
|
|
bb55293313 | ||
|
|
817ceb09e0 | ||
|
|
1a911f7ec4 | ||
|
|
ea464d72e9 | ||
|
|
22adb46a32 | ||
|
|
fc99eaa5ae | ||
|
|
4bea91fc67 | ||
|
|
06d1b10cbe | ||
|
|
816b639035 | ||
|
|
8804ffd4fa | ||
|
|
19122c0768 | ||
|
|
c346c4c8f9 | ||
|
|
bc7d806e3a | ||
|
|
6cf8413e31 | ||
|
|
062e5bfd9c | ||
|
|
e4a1888bd0 | ||
|
|
2f1a0bc0bf | ||
|
|
09ddb1d61c | ||
|
|
15f76bf7bb | ||
|
|
36585b5395 | ||
|
|
11baffbff6 | ||
|
|
53333a43a1 | ||
|
|
c56f9797e7 | ||
|
|
9281be36d5 | ||
|
|
f15a88f2b2 | ||
|
|
5ca96cb844 | ||
|
|
10afe7cf10 | ||
|
|
6972335f50 | ||
|
|
d5e2d0b6bf | ||
|
|
f34b5fb4d8 | ||
|
|
f584312e81 | ||
|
|
0b4557f766 | ||
|
|
204126a5f1 | ||
|
|
2ae3d28f3d | ||
|
|
8a42c2ef8d | ||
|
|
e79535bc5e | ||
|
|
4ad8e142da | ||
|
|
e3ee73b70c | ||
|
|
70812c2f32 | ||
|
|
a64bca68c7 | ||
|
|
67633e1308 | ||
|
|
715ca7c5fe | ||
|
|
001758760b | ||
|
|
2f06265e39 | ||
|
|
432431368f | ||
|
|
4b0028f82d | ||
|
|
8c9236bb2c | ||
|
|
2af0b10c95 | ||
|
|
08adecc9a1 | ||
|
|
015556d74c | ||
|
|
4c40fe64b8 | ||
|
|
d20def2046 | ||
|
|
d2b36e466a | ||
|
|
27f8c93daf | ||
|
|
058b86e6f3 | ||
|
|
0018d6830e | ||
|
|
59224a31fd | ||
|
|
0994d737c8 | ||
|
|
96749554fd | ||
|
|
785749405f | ||
|
|
7cc00d9a83 | ||
|
|
230e16dc03 | ||
|
|
0ce410a629 | ||
|
|
5d3cbde72e | ||
|
|
8fe8fd2b17 | ||
|
|
0ddc678927 | ||
|
|
51f0b798fa | ||
|
|
6b27703b5f | ||
|
|
045ccb59a4 | ||
|
|
784336deec | ||
|
|
eb41e8eebe | ||
|
|
3cd43bbfec | ||
|
|
204e340bcd | ||
|
|
37f2ba7e57 | ||
|
|
09b9fc9009 | ||
|
|
7da3caaf95 | ||
|
|
82ab5f1b0c | ||
|
|
7ae64af368 | ||
|
|
2ad688ed7c | ||
|
|
ca786233d2 | ||
|
|
14a3139c4d | ||
|
|
5af2bfb955 | ||
|
|
1691a31cab | ||
|
|
9dedcbf9ec | ||
|
|
537ffc4c69 | ||
|
|
c3e7210548 | ||
|
|
9a5c2d8373 | ||
|
|
8693bbd8c4 | ||
|
|
251dd03b88 | ||
|
|
55ea83d622 | ||
|
|
b5478a0e03 | ||
|
|
db2deba6b4 | ||
|
|
41fb6443ce | ||
|
|
e5dfe6c282 | ||
|
|
e277e20a6d | ||
|
|
a23e56d109 | ||
|
|
ca89a0a092 | ||
|
|
50a74be125 | ||
|
|
8c1e3bb713 | ||
|
|
4fad1943a2 | ||
|
|
4d346673a2 | ||
|
|
de052ca6fc | ||
|
|
1a593191c2 | ||
|
|
2c4ef997b9 | ||
|
|
d020e2c381 | ||
|
|
48fe9226a0 | ||
|
|
a77ac42e52 | ||
|
|
5880db8abd | ||
|
|
0f4ba89ffd | ||
|
|
edeb1ae65f | ||
|
|
82232bbbaf | ||
|
|
bb2e0686ab | ||
|
|
513e587c5e | ||
|
|
6ed2bcc5f5 | ||
|
|
d529f3882b | ||
|
|
e2e92486a7 | ||
|
|
2e5b3168d6 | ||
|
|
6bcacff1a5 | ||
|
|
12d01cb6fa | ||
|
|
90695fb2c5 | ||
|
|
dd17069c9e | ||
|
|
26b0cb6ae2 | ||
|
|
6d30f8ebed | ||
|
|
11220678c4 | ||
|
|
448d55ef0a | ||
|
|
7b115cc1e1 | ||
|
|
a10d5e3851 | ||
|
|
1016637f5a | ||
|
|
2e00872c04 | ||
|
|
56ece42c81 | ||
|
|
99924f6606 | ||
|
|
0eba02fd41 | ||
|
|
464c8693d2 | ||
|
|
50af17ef24 | ||
|
|
3a24cb7bc4 | ||
|
|
e839446c2a | ||
|
|
695931cf8e | ||
|
|
964a7600b9 | ||
|
|
d4492f955d | ||
|
|
9c15325d34 | ||
|
|
d8c04909fa | ||
|
|
c0a7a98aee | ||
|
|
f5005dd8d0 | ||
|
|
d3aaa68f55 | ||
|
|
cfc907e43d | ||
|
|
2af64c6432 | ||
|
|
83f0dae129 | ||
|
|
65d53cf6ef | ||
|
|
0d9e65f79f | ||
|
|
c983aa9efc | ||
|
|
b16b7f9d3a | ||
|
|
5c6f12b9f2 | ||
|
|
2022b10e50 | ||
|
|
45339625bc | ||
|
|
20ff820ef2 | ||
|
|
39e85d99fe | ||
|
|
3a0e931fc7 | ||
|
|
fe7e3229f8 | ||
|
|
ecf042ff3c | ||
|
|
aff245b360 | ||
|
|
e01469907a | ||
|
|
b7a933154a | ||
|
|
54f18e5427 | ||
|
|
833fba265d | ||
|
|
d633052905 | ||
|
|
009d2336fe | ||
|
|
abca89aaa0 | ||
|
|
d689376cb0 | ||
|
|
98b0d66eb4 | ||
|
|
9c2853f2ae | ||
|
|
aff7562922 | ||
|
|
365c5ba395 | ||
|
|
cb1aa8b0e3 | ||
|
|
d3d5c4a40e | ||
|
|
6117d4025e | ||
|
|
d23745f7c9 | ||
|
|
ad47d8e263 | ||
|
|
8a7a277c08 | ||
|
|
0030fbd382 | ||
|
|
f3052c8a81 | ||
|
|
7d80ed64e4 | ||
|
|
a2e0ce86ba | ||
|
|
6fab0bd9f1 | ||
|
|
02964ed630 | ||
|
|
6f3e7aabdc | ||
|
|
631e3e13a9 | ||
|
|
832c195179 | ||
|
|
7877619f85 | ||
|
|
ec248b590d | ||
|
|
4846b5e9fe | ||
|
|
85c710e11e | ||
|
|
0de7249bb3 | ||
|
|
192c4f788d | ||
|
|
da0db499fd | ||
|
|
88c5c63ffc | ||
|
|
a9f5ad0e2a | ||
|
|
e305f5ec71 | ||
|
|
7ac3e9f1ba | ||
|
|
03a3dd9ee3 | ||
|
|
5fc24a5297 | ||
|
|
b1a295ac4e | ||
|
|
1826c768ab | ||
|
|
9c3e098259 | ||
|
|
0feeab7802 | ||
|
|
f24dc09d20 | ||
|
|
9e10963c20 | ||
|
|
10b6d81c64 | ||
|
|
8026bd7abd | ||
|
|
9b8df58169 | ||
|
|
529a2e9110 | ||
|
|
21091549c0 | ||
|
|
7b97f03f09 | ||
|
|
ce362e8eb9 | ||
|
|
a4decb49a6 | ||
|
|
c53fb36b0c | ||
|
|
dc19e656b5 | ||
|
|
87cf677eca | ||
|
|
5657c56f63 | ||
|
|
51b3445e84 | ||
|
|
a7452b8b8c | ||
|
|
0bf5ce77aa | ||
|
|
159d34b58e | ||
|
|
29bf0598aa | ||
|
|
239b58d34d | ||
|
|
74f1810546 | ||
|
|
f4b08b8f40 | ||
|
|
6691fdf517 | ||
|
|
7d8d2a54ba | ||
|
|
9986c6cb2b | ||
|
|
ba9a66663a | ||
|
|
ac419bf562 | ||
|
|
520833cbe1 | ||
|
|
e58d9c87f7 | ||
|
|
84f7991474 | ||
|
|
85b9dc8023 | ||
|
|
7d4d4892d8 | ||
|
|
fc4759af9d | ||
|
|
ee84c47655 | ||
|
|
ce32176db7 | ||
|
|
04f52e9b4d | ||
|
|
100a33f7ff | ||
|
|
7ed25ccf0d | ||
|
|
01eede2662 | ||
|
|
ae26ee3489 | ||
|
|
992bee504d | ||
|
|
01a2abedd7 | ||
|
|
a45e3f93e4 | ||
|
|
bdb396ef2a | ||
|
|
6add1901a1 | ||
|
|
51b0f09b5e | ||
|
|
8dac7be438 | ||
|
|
bcf1b9dec1 | ||
|
|
b045d079f8 | ||
|
|
683f2b8323 | ||
|
|
2de20dd9a1 | ||
|
|
b47cf4f688 | ||
|
|
a15b2b6c62 | ||
|
|
42e01cff9a | ||
|
|
865d4138a0 | ||
|
|
35874298e4 | ||
|
|
52d72e66c2 | ||
|
|
f3d10aa0d4 | ||
|
|
7632bc911b | ||
|
|
92ef5f19c8 | ||
|
|
99b4045183 | ||
|
|
087f9bb20a | ||
|
|
e2c7e19144 | ||
|
|
f5c3d95384 | ||
|
|
6b10f5b963 | ||
|
|
ee74b77d45 | ||
|
|
734bdb68c2 | ||
|
|
514817669e | ||
|
|
cb9c0ac7d7 | ||
|
|
1c435295b8 | ||
|
|
46d26a0e77 | ||
|
|
f4e3cae8a7 | ||
|
|
b52cf5d2cd | ||
|
|
073e83b543 | ||
|
|
c3e6d69acb | ||
|
|
b56e3d43e5 | ||
|
|
f317ffb7bb | ||
|
|
9ea5145952 | ||
|
|
1d7c38e1f0 | ||
|
|
18bfc8f2d7 | ||
|
|
945246988d | ||
|
|
a5c0e20939 | ||
|
|
128517649c | ||
|
|
219358b93d | ||
|
|
f133719f73 | ||
|
|
f4e6e201b1 | ||
|
|
790b2086d7 | ||
|
|
f9b691cdb0 | ||
|
|
4118c30261 | ||
|
|
dacbdaab94 | ||
|
|
70e30f6caa | ||
|
|
7cb6c31370 | ||
|
|
5d3a031ca7 | ||
|
|
a846fbbe2a | ||
|
|
6420672879 | ||
|
|
c4067a5678 | ||
|
|
0523152ad6 | ||
|
|
b37b5233ca | ||
|
|
c68c7e588e | ||
|
|
1498a0073e | ||
|
|
27777949a0 | ||
|
|
4dc2d965d6 | ||
|
|
70bbbccc39 | ||
|
|
0dd470fc61 | ||
|
|
89acdf50fa | ||
|
|
c0d502785f | ||
|
|
a8c92cb608 | ||
|
|
53fda844cc | ||
|
|
bbf63b0faa | ||
|
|
2af9fd4960 | ||
|
|
2c0d65785f | ||
|
|
d791179d7f | ||
|
|
c49ed0b6c0 | ||
|
|
868d8e6831 | ||
|
|
e3aca1b2ce | ||
|
|
ddac43b38e | ||
|
|
416ecc1584 | ||
|
|
455ba691a7 | ||
|
|
11332577b3 | ||
|
|
702b0dd408 | ||
|
|
e8a9f794f0 | ||
|
|
bddf3d4705 | ||
|
|
e99c81a07c | ||
|
|
fe880475ed | ||
|
|
5821d5f111 | ||
|
|
d535c4a2e1 | ||
|
|
ca8f17a303 | ||
|
|
fddb7b44a7 | ||
|
|
49184c3723 | ||
|
|
cc7f6a2ddf | ||
|
|
90fe59b829 | ||
|
|
7b074a460b | ||
|
|
993cdcd6ee | ||
|
|
8763374f0e | ||
|
|
63388fe1f3 | ||
|
|
b75a88aa72 | ||
|
|
bb20989a63 | ||
|
|
0d49e408a4 | ||
|
|
90c87f311e | ||
|
|
da06ac7f3f | ||
|
|
6d9236e805 | ||
|
|
c306d2e42f | ||
|
|
f737e3a3dd | ||
|
|
686586b0f9 | ||
|
|
e621a5f6ea | ||
|
|
8093f9541e | ||
|
|
68e7fb499d | ||
|
|
d9569720dd | ||
|
|
1c40685d32 | ||
|
|
31c6e7af6a | ||
|
|
552ba67bb1 | ||
|
|
651254dcc7 | ||
|
|
26bdafcbf9 | ||
|
|
02dc9e788f | ||
|
|
e11c6e9961 | ||
|
|
e4eaa92728 | ||
|
|
577f8e5ac6 | ||
|
|
95ba6cdd54 | ||
|
|
7ce6cb9ab4 | ||
|
|
8723cade21 | ||
|
|
d956d9db47 | ||
|
|
ecf93ac986 | ||
|
|
b3a01be2f3 | ||
|
|
00045a3009 | ||
|
|
3f7188dd94 | ||
|
|
720218fea1 | ||
|
|
73aa95592f | ||
|
|
ad3fdbc0a4 | ||
|
|
73cbd21b5e | ||
|
|
c5ba0c2f54 | ||
|
|
edddf394b8 | ||
|
|
61d259f950 | ||
|
|
c01735865f | ||
|
|
ca46c5dbe2 | ||
|
|
2da127abb5 | ||
|
|
bc33f2200d | ||
|
|
fd399cde00 | ||
|
|
00c74019f4 | ||
|
|
9d0063befa | ||
|
|
01e55ebb26 | ||
|
|
4bbad1dac7 | ||
|
|
ddbda328b3 | ||
|
|
8ffbeeda80 | ||
|
|
1d1ffaf912 | ||
|
|
e0cff02061 | ||
|
|
7fe95bb0d5 |
11
.travis.yml
Normal file
11
.travis.yml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
language: c
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- ./buildconf
|
||||||
|
|
||||||
|
compiler:
|
||||||
|
- clang
|
||||||
|
- gcc
|
||||||
|
|
||||||
|
notifications:
|
||||||
|
email: false
|
||||||
@@ -108,7 +108,11 @@ if(NOT UNIX)
|
|||||||
set(HAVE_IN_ADDR_T 0)
|
set(HAVE_IN_ADDR_T 0)
|
||||||
set(HAVE_INET_NTOA_R_DECL 0)
|
set(HAVE_INET_NTOA_R_DECL 0)
|
||||||
set(HAVE_INET_NTOA_R_DECL_REENTRANT 0)
|
set(HAVE_INET_NTOA_R_DECL_REENTRANT 0)
|
||||||
set(HAVE_GETADDRINFO 0)
|
if(ENABLE_IPV6)
|
||||||
|
set(HAVE_GETADDRINFO 1)
|
||||||
|
else()
|
||||||
|
set(HAVE_GETADDRINFO 0)
|
||||||
|
endif()
|
||||||
set(STDC_HEADERS 1)
|
set(STDC_HEADERS 1)
|
||||||
set(RETSIGTYPE_TEST 1)
|
set(RETSIGTYPE_TEST 1)
|
||||||
|
|
||||||
|
|||||||
@@ -783,6 +783,17 @@ else()
|
|||||||
set(CURL_SIZEOF_CURL_SOCKLEN_T ${SIZEOF_INT})
|
set(CURL_SIZEOF_CURL_SOCKLEN_T ${SIZEOF_INT})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# TODO test which of these headers are required for the typedefs used in curlbuild.h
|
||||||
|
if(WIN32)
|
||||||
|
set(CURL_PULL_WS2TCPIP_H ${HAVE_WS2TCPIP_H})
|
||||||
|
else()
|
||||||
|
set(CURL_PULL_SYS_TYPES_H ${HAVE_SYS_TYPES_H})
|
||||||
|
set(CURL_PULL_SYS_SOCKET_H ${HAVE_SYS_SOCKET_H})
|
||||||
|
set(CURL_PULL_SYS_POLL_H ${HAVE_SYS_POLL_H})
|
||||||
|
endif()
|
||||||
|
set(CURL_PULL_STDINT_H ${HAVE_STDINT_H})
|
||||||
|
set(CURL_PULL_INTTYPES_H ${HAVE_INTTYPES_H})
|
||||||
|
|
||||||
include(CMake/OtherTests.cmake)
|
include(CMake/OtherTests.cmake)
|
||||||
|
|
||||||
add_definitions(-DHAVE_CONFIG_H)
|
add_definitions(-DHAVE_CONFIG_H)
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ if test ! -z $SDK32; then
|
|||||||
ln -fs ${FRAMEWORK_VERSION}/Resources Resources
|
ln -fs ${FRAMEWORK_VERSION}/Resources Resources
|
||||||
ln -fs ${FRAMEWORK_VERSION}/Headers Headers
|
ln -fs ${FRAMEWORK_VERSION}/Headers Headers
|
||||||
cd Versions
|
cd Versions
|
||||||
ln -fs ${FRAMEWORK_VERSION} Current
|
ln -fs $(basename "${FRAMEWORK_VERSION}") Current
|
||||||
|
|
||||||
echo Testing for SDK64
|
echo Testing for SDK64
|
||||||
if test -d $SDK64_DIR; then
|
if test -d $SDK64_DIR; then
|
||||||
|
|||||||
@@ -148,12 +148,24 @@ vc-ssl-zlib: $(VC)
|
|||||||
cd ..\src
|
cd ..\src
|
||||||
nmake /f Makefile.$(VC) cfg=release-ssl-zlib
|
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)
|
vc-x64-ssl-zlib: $(VC)
|
||||||
cd lib
|
cd lib
|
||||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-zlib
|
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-zlib
|
||||||
cd ..\src
|
cd ..\src
|
||||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-zlib
|
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)
|
vc-ssl-dll: $(VC)
|
||||||
cd lib
|
cd lib
|
||||||
nmake /f Makefile.$(VC) cfg=release-ssl-dll
|
nmake /f Makefile.$(VC) cfg=release-ssl-dll
|
||||||
|
|||||||
202
RELEASE-NOTES
202
RELEASE-NOTES
@@ -1,88 +1,71 @@
|
|||||||
Curl and libcurl 7.30.0
|
Curl and libcurl 7.34.0
|
||||||
|
|
||||||
Public curl releases: 132
|
Public curl releases: 136
|
||||||
Command line options: 152
|
Command line options: 161
|
||||||
curl_easy_setopt() options: 199
|
curl_easy_setopt() options: 206
|
||||||
Public functions in libcurl: 58
|
Public functions in libcurl: 58
|
||||||
Known libcurl bindings: 42
|
Known libcurl bindings: 42
|
||||||
Contributors: 1005
|
Contributors: 1104
|
||||||
|
|
||||||
***
|
This release includes the following security fix:
|
||||||
krb4 support is up for removal. If you care about it at all, speak up
|
o gtls: respect *VERIFYHOST independently of *VERIFYPEER [26]
|
||||||
on the curl-library list asap!
|
|
||||||
***
|
|
||||||
|
|
||||||
This release includes the following changes:
|
This release includes the following changes:
|
||||||
|
|
||||||
o imap: Changed response tag generation to be completely unique
|
o SSL: protocol version can be specified more precisely [1]
|
||||||
o imap: Added support for SASL-IR extension
|
o imap/pop3/smtp: Added graceful cancellation of SASL authentication
|
||||||
o imap: Added support for the list command
|
o Add "Happy Eyeballs" for IPv4/IPv6 dual connect attempts
|
||||||
o imap: Added support for the append command
|
o base64: Added validation of base64 input strings when decoding [8]
|
||||||
o imap: Added custom request parsing
|
o curl_easy_setopt: Added the ability to set the login options separately
|
||||||
o imap: Added support to the fetch command for UID and SECTION properties
|
o smtp: Added support for additional SMTP commands
|
||||||
o imap: Added parsing and verification of the UIDVALIDITY mailbox attribute
|
o curl_easy_getinfo: Added CURLINFO_TLS_SESSION for accessing TLS internals
|
||||||
o darwinssl: Make certificate errors less techy
|
o nss: allow to use TLS > 1.0 if built against recent NSS [18]
|
||||||
o imap/pop3/smtp: Added support for the STARTTLS capability
|
o SECURITY: added this document to describe our security processes [22]
|
||||||
o checksrc: ban use of sprintf, vsprintf, strcat, strncat and gets
|
o parseconfig: warn if unquoted white spaces are detected
|
||||||
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]
|
|
||||||
|
|
||||||
This release includes the following bugfixes:
|
This release includes the following bugfixes:
|
||||||
|
|
||||||
o SECURITY ADVISORY: cookie tailmatching to avoid cross-domain leakage [25]
|
o darwinssl: un-break iOS build after PKCS#12 feature added
|
||||||
o darwinssl: Fix build under Leopard
|
o tool: use XFERFUNCTION to save some casts [2]
|
||||||
o DONE: consider callback-aborted transfers premature [1]
|
o usercertinmem: fix memory leaks
|
||||||
o ntlm: Fixed memory leaks
|
o ssh: Handle successful SSH_USERAUTH_NONE [3]
|
||||||
o smtp: Fixed an issue when processing EHLO failure responses
|
o NSS: acknowledge the --no-sessionid/CURLOPT_SSL_SESSIONID_CACHE option [4]
|
||||||
o pop3: Fixed incorrect return value from pop3_endofresp()
|
o test906: Fixed failing test on some platforms [5]
|
||||||
o pop3: Fixed SASL authentication capability detection
|
o sasl: initialize NSS before using NTLM crypto
|
||||||
o pop3: Fixed blocking SSL connect when connecting via POP3S
|
o sasl: Fixed memory leak in OAUTH2 message creation
|
||||||
o imap: Fixed memory leak when performing multiple selects
|
o imap/pop3/smtp: Fixed QUIT / LOGOUT being sent when SSL connect fails
|
||||||
o nss: fix misplaced code enabling non-blocking socket mode
|
o cmake: unbreak for non-Windows platforms [6]
|
||||||
o AddFormData: prevent only directories from being posted [2]
|
o ssh: initialize per-handle data in ssh_connect()
|
||||||
o darwinssl: fix infinite loop if server disconnected abruptly [3]
|
o glob: fix broken URLs
|
||||||
o metalink: fix improbable crash parsing metalink filename
|
o configure: check for long long when building with cyassl
|
||||||
o show proper host name on failed resolve
|
o CURLOPT_RESOLVE: mention they don't time-out [7]
|
||||||
o MacOSX-Framework: Make script work in Xcode 4.0 and later
|
o docs/examples/httpput.c: fix build for MSVC
|
||||||
o strlcat: remove function [4]
|
o FTP: make the data connection work when going through proxy
|
||||||
o darwinssl: Fix send glitchiness with data > 32 or so KB [5]
|
o NSS: support for CERTINFO feature
|
||||||
o polarssl: better 1.1.x and 1.2.x support
|
o curl_multi_wait: accept 0 from multi_timeout() as valid timeout
|
||||||
o various documentation improvements
|
o glob_range: pass the closing bracket for a-z ranges
|
||||||
o multi: NULL pointer reference when closing an unused multi handle [9]
|
o tool_help: Updated --list-only description to include POP3
|
||||||
o SOCKS: fix socks proxy when noproxy matched [7]
|
o Curl_ssl_push_certinfo_len: don't %.*s non-zero-terminated string [9]
|
||||||
o install-sh: updated to support multiple source files as arguments [6]
|
o cmake: fix Windows build with IPv6 support [10]
|
||||||
o PolarSSL: added human readable error strings
|
o ares: Fixed compilation under Visual Studio 2012 [11]
|
||||||
o resolver_error: remove wrong error message output
|
o curl_easy_setopt.3: clarify CURLOPT_SSL_VERIFYHOST documentation [12]
|
||||||
o docs: updates HTML index and general improvements
|
o curl.1: mention that -O does no URL decoding [13]
|
||||||
o curlbuild.h.dist: enhance non-configure GCC ABI detection logic
|
o darwinssl: PKCS#12 import feature now requires Lion or later [14]
|
||||||
o sasl: Fixed null pointer reference when decoding empty digest challenge [8]
|
o darwinssl: check for SSLSetSessionOption() presence when toggling BEAST
|
||||||
o easy: do not ignore poll() failures other than EINTR
|
o configure: Fix test with -Werror=implicit-function-declaration [15]
|
||||||
o darwinssl: disable ECC ciphers under Mountain Lion by default
|
o sigpipe: factor out sigpipe_reset from easy.c
|
||||||
o CONNECT: count received headers [11]
|
o curl_multi_cleanup: ignore SIGPIPE
|
||||||
o build: fixes for VMS
|
o globbing: curl glob counter mismatch with {} list use [16]
|
||||||
o CONNECT: clear 'rewindaftersend' on success [12]
|
o parseconfig: dash options can't specified with colon or equals [17]
|
||||||
o HTTP proxy: insert slash in URL if missing [13]
|
o digest: fix CURLAUTH_DIGEST_IE [19]
|
||||||
o hiperfifo: updated to use current libevent API [14]
|
o curl.h: <sys/select.h> for OpenBSD [20]
|
||||||
o getinmemory.c: abort the transfer nicely if not enough memory
|
o darwinssl: Fix #if 10.6.0 for SecKeychainSearch
|
||||||
o improved win32 memorytracking
|
o TFTP: fix return codes for connect timeout [21]
|
||||||
o corrected proxy header response headers count [16]
|
o login options: remove the ;[options] support from CURLOPT_USERPWD [23]
|
||||||
o FTP quote operations on re-used connection [17]
|
o imap: Fixed incorrect fallback to clear text authentication
|
||||||
o tcpkeepalive on win32 [18]
|
o parsedate: avoid integer overflow
|
||||||
o tcpkeepalive on Mac OS X [23]
|
o curl.1: document -J doesn't %-decode [25]
|
||||||
o easy: acknowledge the CURLOPT_MAXCONNECTS option properly [19]
|
o multi: add timer inaccuracy margin to timeout/connecttimeout [24]
|
||||||
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"
|
|
||||||
|
|
||||||
This release includes the following known bugs:
|
This release includes the following known bugs:
|
||||||
|
|
||||||
@@ -91,43 +74,42 @@ This release includes the following known bugs:
|
|||||||
This release would not have looked like this without help, code, reports and
|
This release would not have looked like this without help, code, reports and
|
||||||
advice from friends like these:
|
advice from friends like these:
|
||||||
|
|
||||||
Kamil Dudka, Steve Holme, Nick Zitzmann, Patricia Muscalu, Dan Fandrich,
|
Alessandro Ghedini, Andreas Rieke, Björn Stenberg, Chris Conlon,
|
||||||
Gisle Vanem, Guenter Knauf, Yang Tse, Oliver Gondža, Aki Koskinen,
|
Christian Grothoff, Christian Weisgerber, Dave Reisner, David Walser,
|
||||||
Alexander Klauer, Kim Vandry, Willem Sparreboom, Jeremy Huddleston,
|
Dima Tisnek, Fabian Keil, Felix Yan, Gergely Nagy, Gisle Vanem,
|
||||||
Bruno de Carvalho, Rainer Jung, Jeremy Huddleston, Kim Vandry, Jiri Hruska,
|
Ishan SinghLevett, James Dury, Javier Barroso, Jeff King, Kamil Dudka,
|
||||||
Alexander Klauer, Saran Neti, Alessandro Ghedini, Linus Nielsen Feltzing,
|
Kim Vandry, Marcin Gryszkalis, Melissa Mears, Michael Osipov, Nick Zitzmann,
|
||||||
Martin Jansen, John E. Malmberg, Tom Grace, Patrick Monnerat,
|
Oliver Kuckertz, Patrick Monnerat, Paul Donohue, Paul Marks, Romulo A. Ceccon,
|
||||||
Zdenek Pavlas, Myk Taylor, Cédric Deltheil, Robert Wruck, Sam Deane,
|
Rémy Léone, Sergey Tatarincev, Steve Holme, Tomas Hoger, Tyler Hall,
|
||||||
Clemens Gruber, Marc Hoersken, Tomas Mlcoch, Fredrik Thulin, Steven Gu,
|
Yaakov Selkowitz, Eric Lubin, Petr Bahula, He Qin, Marc Deslauriers
|
||||||
Andrew Kurushin, Christian Hägele, Daniel Theron, Bill Middlecamp,
|
|
||||||
Richard Michael, Yamada Yasuharu
|
|
||||||
|
|
||||||
Thanks! (and sorry if I forgot to mention someone)
|
Thanks! (and sorry if I forgot to mention someone)
|
||||||
|
|
||||||
References to bug reports and discussions on issues:
|
References to bug reports and discussions on issues:
|
||||||
|
|
||||||
[1] = http://curl.haxx.se/bug/view.cgi?id=1184
|
[1] = https://github.com/bagder/curl/pull/79
|
||||||
[2] = http://curl.haxx.se/mail/archive-2013-02/0040.html
|
[2] = http://curl.haxx.se/mail/lib-2013-10/0089.html
|
||||||
[3] = http://curl.haxx.se/mail/lib-2013-03/0014.html
|
[3] = http://curl.haxx.se/mail/lib-2013-10/0096.html
|
||||||
[4] = http://curl.haxx.se/bug/view.cgi?id=1192
|
[4] = http://curl.haxx.se/mail/lib-2013-10/0113.html
|
||||||
[5] = http://curl.haxx.se/mail/lib-2013-02/0145.html
|
[5] = http://sourceforge.net/p/curl/bugs/1291
|
||||||
[6] = http://curl.haxx.se/bug/view.cgi?id=1195
|
[6] = http://sourceforge.net/p/curl/bugs/1292
|
||||||
[7] = http://curl.haxx.se/bug/view.cgi?id=1190
|
[7] = http://curl.haxx.se/mail/lib-2013-10/0062.html
|
||||||
[8] = http://curl.haxx.se/bug/view.cgi?id=1193
|
[8] = http://curl.haxx.se/mail/lib-2013-10/0242.html
|
||||||
[9] = http://curl.haxx.se/bug/view.cgi?id=1194
|
[9] = http://curl.haxx.se/bug/view.cgi?id=1295
|
||||||
[10] = http://curl.haxx.se/bug/view.cgi?id=1168
|
[10] = http://sourceforge.net/p/curl/bugs/1064
|
||||||
[11] = http://curl.haxx.se/bug/view.cgi?id=1204
|
[11] = http://curl.haxx.se/mail/lib-2013-11/0057.html
|
||||||
[12] = https://groups.google.com/d/msg/msysgit/B31LNftR4BI/KhRTz0iuGmUJ
|
[12] = https://github.com/bagder/curl/pull/83
|
||||||
[13] = http://curl.haxx.se/bug/view.cgi?id=1206
|
[13] = http://sourceforge.net/p/curl/bugs/1299
|
||||||
[14] = http://curl.haxx.se/bug/view.cgi?id=1199
|
[14] = http://curl.haxx.se/mail/lib-2013-11/0076.html
|
||||||
[15] = http://daniel.haxx.se/blog/2013/03/26/better-pipelining-in-libcurl-7-30-0/
|
[15] = http://curl.haxx.se/bug/view.cgi?id=1304
|
||||||
[16] = http://curl.haxx.se/bug/view.cgi?id=1204
|
[16] = http://curl.haxx.se/bug/view.cgi?id=1305
|
||||||
[17] = http://curl.haxx.se/mail/lib-2013-03/0319.html
|
[17] = http://curl.haxx.se/bug/view.cgi?id=1297
|
||||||
[18] = http://curl.haxx.se/bug/view.cgi?id=1209
|
[18] = http://curl.haxx.se/mail/lib-2013-11/0162.html
|
||||||
[19] = http://curl.haxx.se/bug/view.cgi?id=1212
|
[19] = http://curl.haxx.se/bug/view.cgi?id=1308
|
||||||
[20] = http://curl.haxx.se/bug/view.cgi?id=1188
|
[20] = http://curl.haxx.se/mail/lib-2013-12/0017.html
|
||||||
[21] = http://curl.haxx.se/bug/view.cgi?id=1183
|
[21] = http://curl.haxx.se/bug/view.cgi?id=1310
|
||||||
[22] = http://curl.haxx.se/bug/view.cgi?id=1189
|
[22] = http://curl.haxx.se/dev/security.html
|
||||||
[23] = http://curl.haxx.se/bug/view.cgi?id=1214
|
[23] = http://curl.haxx.se/bug/view.cgi?id=1311
|
||||||
[24] = http://curl.haxx.se/mail/lib-2013-04/0113.html
|
[24] = http://curl.haxx.se/bug/view.cgi?id=1298
|
||||||
[25] = http://curl.haxx.se/docs/adv_20130412.html
|
[25] = http://curl.haxx.se/bug/view.cgi?id=1294
|
||||||
|
[26] = http://curl.haxx.se/docs/adv_20131217.html
|
||||||
|
|||||||
68
acinclude.m4
68
acinclude.m4
@@ -2620,46 +2620,50 @@ AC_HELP_STRING([--without-ca-path], [Don't use a default CA path]),
|
|||||||
capath="$want_capath"
|
capath="$want_capath"
|
||||||
ca="no"
|
ca="no"
|
||||||
else
|
else
|
||||||
dnl neither of --with-ca-* given
|
|
||||||
dnl first try autodetecting a CA bundle , then a CA path
|
dnl first try autodetecting a CA bundle , then a CA path
|
||||||
dnl both autodetections can be skipped by --without-ca-*
|
dnl both autodetections can be skipped by --without-ca-*
|
||||||
ca="no"
|
ca="no"
|
||||||
capath="no"
|
capath="no"
|
||||||
if test "x$want_ca" = "xunset"; then
|
if test "x$cross_compiling" != "xyes"; then
|
||||||
dnl the path we previously would have installed the curl ca bundle
|
dnl NOT cross-compiling and...
|
||||||
dnl to, and thus we now check for an already existing cert in that place
|
dnl neither of the --with-ca-* options are provided
|
||||||
dnl in case we find no other
|
if test "x$want_ca" = "xunset"; then
|
||||||
if test "x$prefix" != xNONE; then
|
dnl the path we previously would have installed the curl ca bundle
|
||||||
cac="${prefix}/share/curl/curl-ca-bundle.crt"
|
dnl to, and thus we now check for an already existing cert in that
|
||||||
else
|
dnl place in case we find no other
|
||||||
cac="$ac_default_prefix/share/curl/curl-ca-bundle.crt"
|
if test "x$prefix" != xNONE; then
|
||||||
fi
|
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 \
|
for a in /etc/ssl/certs/ca-certificates.crt \
|
||||||
/etc/pki/tls/certs/ca-bundle.crt \
|
/etc/pki/tls/certs/ca-bundle.crt \
|
||||||
/usr/share/ssl/certs/ca-bundle.crt \
|
/usr/share/ssl/certs/ca-bundle.crt \
|
||||||
/usr/local/share/certs/ca-root.crt \
|
/usr/local/share/certs/ca-root.crt \
|
||||||
/etc/ssl/cert.pem \
|
/etc/ssl/cert.pem \
|
||||||
"$cac"; do
|
"$cac"; do
|
||||||
if test -f "$a"; then
|
if test -f "$a"; then
|
||||||
ca="$a"
|
ca="$a"
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
if test "x$want_capath" = "xunset" -a "x$ca" = "xno" -a \
|
if test "x$want_capath" = "xunset" -a "x$ca" = "xno" -a \
|
||||||
"x$OPENSSL_ENABLED" = "x1"; then
|
"x$OPENSSL_ENABLED" = "x1"; then
|
||||||
for a in /etc/ssl/certs/; do
|
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
|
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"
|
capath="$a"
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
dnl no option given and cross-compiling
|
||||||
|
AC_MSG_WARN([skipped the ca-cert path detection when cross-compiling])
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if test "x$ca" != "xno"; then
|
if test "x$ca" != "xno"; then
|
||||||
CURL_CA_BUNDLE='"'$ca'"'
|
CURL_CA_BUNDLE='"'$ca'"'
|
||||||
AC_DEFINE_UNQUOTED(CURL_CA_BUNDLE, "$ca", [Location of default ca bundle])
|
AC_DEFINE_UNQUOTED(CURL_CA_BUNDLE, "$ca", [Location of default ca bundle])
|
||||||
|
|||||||
244
configure.ac
244
configure.ac
@@ -126,7 +126,7 @@ fi
|
|||||||
dnl figure out the libcurl version
|
dnl figure out the libcurl version
|
||||||
CURLVERSION=`$SED -ne 's/^#define LIBCURL_VERSION "\(.*\)"/\1/p' ${srcdir}/include/curl/curlver.h`
|
CURLVERSION=`$SED -ne 's/^#define LIBCURL_VERSION "\(.*\)"/\1/p' ${srcdir}/include/curl/curlver.h`
|
||||||
XC_CHECK_PROG_CC
|
XC_CHECK_PROG_CC
|
||||||
AM_INIT_AUTOMAKE
|
XC_AUTOMAKE
|
||||||
AC_MSG_CHECKING([curl version])
|
AC_MSG_CHECKING([curl version])
|
||||||
AC_MSG_RESULT($CURLVERSION)
|
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_ssl_msg="no (--with-{ssl,gnutls,nss,polarssl,cyassl,axtls,winssl,darwinssl} )"
|
||||||
curl_ssh_msg="no (--with-libssh2)"
|
curl_ssh_msg="no (--with-libssh2)"
|
||||||
curl_zlib_msg="no (--with-zlib)"
|
curl_zlib_msg="no (--with-zlib)"
|
||||||
curl_krb4_msg="no (--with-krb4*)"
|
|
||||||
curl_gss_msg="no (--with-gssapi)"
|
curl_gss_msg="no (--with-gssapi)"
|
||||||
curl_spnego_msg="no (--with-spnego)"
|
curl_spnego_msg="no (--with-spnego)"
|
||||||
curl_tls_srp_msg="no (--enable-tls-srp)"
|
curl_tls_srp_msg="no (--enable-tls-srp)"
|
||||||
@@ -1066,6 +1065,7 @@ AC_HELP_STRING([--disable-ipv6],[Disable ipv6 support]),
|
|||||||
AC_TRY_RUN([ /* is AF_INET6 available? */
|
AC_TRY_RUN([ /* is AF_INET6 available? */
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <stdlib.h> /* for exit() */
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
if (socket(AF_INET6, SOCK_STREAM, 0) < 0)
|
if (socket(AF_INET6, SOCK_STREAM, 0) < 0)
|
||||||
@@ -1134,101 +1134,6 @@ no)
|
|||||||
;;
|
;;
|
||||||
esac
|
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 **********************************************************************
|
||||||
dnl Check for FBopenssl(SPNEGO) libraries
|
dnl Check for FBopenssl(SPNEGO) libraries
|
||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
@@ -2079,6 +1984,9 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
|
|||||||
if test "x$USE_CYASSL" = "xyes"; then
|
if test "x$USE_CYASSL" = "xyes"; then
|
||||||
AC_MSG_NOTICE([detected CyaSSL])
|
AC_MSG_NOTICE([detected CyaSSL])
|
||||||
|
|
||||||
|
dnl cyassl/ctaocrypt/types.h needs SIZEOF_LONG_LONG defined!
|
||||||
|
AC_CHECK_SIZEOF(long long)
|
||||||
|
|
||||||
LIBS="-lcyassl -lm $LIBS"
|
LIBS="-lcyassl -lm $LIBS"
|
||||||
|
|
||||||
if test -n "$cyassllib"; then
|
if test -n "$cyassllib"; then
|
||||||
@@ -2163,8 +2071,8 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
|
|||||||
CPPFLAGS="$CPPFLAGS $addcflags"
|
CPPFLAGS="$CPPFLAGS $addcflags"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl The function PK11_CreateGenericObject is needed to load libnsspem.so
|
dnl The function SSL_VersionRangeSet() is needed to enable TLS > 1.0
|
||||||
AC_CHECK_LIB(nss3, PK11_CreateGenericObject,
|
AC_CHECK_LIB(nss3, SSL_VersionRangeSet,
|
||||||
[
|
[
|
||||||
AC_DEFINE(USE_NSS, 1, [if NSS is enabled])
|
AC_DEFINE(USE_NSS, 1, [if NSS is enabled])
|
||||||
AC_SUBST(USE_NSS, [1])
|
AC_SUBST(USE_NSS, [1])
|
||||||
@@ -2180,14 +2088,6 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
|
|||||||
if test "x$USE_NSS" = "xyes"; then
|
if test "x$USE_NSS" = "xyes"; then
|
||||||
AC_MSG_NOTICE([detected NSS version $version])
|
AC_MSG_NOTICE([detected NSS version $version])
|
||||||
|
|
||||||
dnl NSS_InitContext() was introduced in NSS 3.12.5 and helps to prevent
|
|
||||||
dnl collisions on NSS initialization/shutdown with other libraries
|
|
||||||
AC_CHECK_FUNC(NSS_InitContext,
|
|
||||||
[
|
|
||||||
AC_DEFINE(HAVE_NSS_INITCONTEXT, 1, [if you have the NSS_InitContext function])
|
|
||||||
AC_SUBST(HAVE_NSS_INITCONTEXT, [1])
|
|
||||||
])
|
|
||||||
|
|
||||||
dnl when shared libs were found in a path that the run-time
|
dnl when shared libs were found in a path that the run-time
|
||||||
dnl linker doesn't search through, we need to add it to
|
dnl linker doesn't search through, we need to add it to
|
||||||
dnl LD_LIBRARY_PATH to prevent further configure tests to fail
|
dnl LD_LIBRARY_PATH to prevent further configure tests to fail
|
||||||
@@ -2808,6 +2708,92 @@ dnl http://publibn.boulder.ibm.com/doc_link/en_US/a_doc_lib/aixprggd/ \
|
|||||||
dnl genprogc/thread_quick_ref.htm
|
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 **********************************************************************
|
||||||
dnl Back to "normal" configuring
|
dnl Back to "normal" configuring
|
||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
@@ -3158,14 +3144,26 @@ if test "$want_thres" = "yes"; then
|
|||||||
AC_CHECK_HEADER(pthread.h,
|
AC_CHECK_HEADER(pthread.h,
|
||||||
[ AC_DEFINE(HAVE_PTHREAD_H, 1, [if you have <pthread.h>])
|
[ AC_DEFINE(HAVE_PTHREAD_H, 1, [if you have <pthread.h>])
|
||||||
save_CFLAGS="$CFLAGS"
|
save_CFLAGS="$CFLAGS"
|
||||||
CFLAGS="$CFLAGS -pthread"
|
|
||||||
AC_CHECK_LIB(pthread, pthread_create,
|
dnl first check for function without lib
|
||||||
[ AC_MSG_NOTICE([using POSIX threaded DNS lookup])
|
AC_CHECK_FUNC(pthread_create, [USE_THREADS_POSIX=1] )
|
||||||
AC_DEFINE(USE_THREADS_POSIX, 1, [if you want POSIX threaded DNS lookup])
|
|
||||||
USE_THREADS_POSIX=1
|
dnl if it wasn't found without lib, search for it in pthread lib
|
||||||
curl_res_msg="threaded"
|
if test "$USE_THREADS_POSIX" != "1"
|
||||||
],
|
then
|
||||||
[ CFLAGS="$save_CFLAGS"])
|
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
|
fi
|
||||||
|
|
||||||
@@ -3338,6 +3336,11 @@ dnl yes or no
|
|||||||
ENABLE_SHARED="$enable_shared"
|
ENABLE_SHARED="$enable_shared"
|
||||||
AC_SUBST(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
|
||||||
dnl For keeping supported features and protocols also in pkg-config file
|
dnl For keeping supported features and protocols also in pkg-config file
|
||||||
dnl since it is more cross-compile friendly than curl-config
|
dnl since it is more cross-compile friendly than curl-config
|
||||||
@@ -3348,9 +3351,6 @@ if test "x$USE_SSLEAY" = "x1"; then
|
|||||||
elif test -n "$SSL_ENABLED"; then
|
elif test -n "$SSL_ENABLED"; then
|
||||||
SUPPORT_FEATURES="$SUPPORT_FEATURES SSL"
|
SUPPORT_FEATURES="$SUPPORT_FEATURES SSL"
|
||||||
fi
|
fi
|
||||||
if test "@KRB4_ENABLED@" = "x1"; then
|
|
||||||
SUPPORT_FEATURES="$SUPPORT_FEATURES KRB4"
|
|
||||||
fi
|
|
||||||
if test "x$IPV6_ENABLED" = "x1"; then
|
if test "x$IPV6_ENABLED" = "x1"; then
|
||||||
SUPPORT_FEATURES="$SUPPORT_FEATURES IPv6"
|
SUPPORT_FEATURES="$SUPPORT_FEATURES IPv6"
|
||||||
fi
|
fi
|
||||||
@@ -3380,6 +3380,10 @@ if test "x$USE_TLS_SRP" = "x1"; then
|
|||||||
SUPPORT_FEATURES="$SUPPORT_FEATURES TLS-SRP"
|
SUPPORT_FEATURES="$SUPPORT_FEATURES TLS-SRP"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test "x$USE_NGHTTP2" = "x1"; then
|
||||||
|
SUPPORT_FEATURES="$SUPPORT_FEATURES HTTP2"
|
||||||
|
fi
|
||||||
|
|
||||||
AC_SUBST(SUPPORT_FEATURES)
|
AC_SUBST(SUPPORT_FEATURES)
|
||||||
|
|
||||||
dnl For supported protocols in pkg-config file
|
dnl For supported protocols in pkg-config file
|
||||||
@@ -3514,6 +3518,8 @@ AC_OUTPUT
|
|||||||
|
|
||||||
CURL_GENERATE_CONFIGUREHELP_PM
|
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:
|
AC_MSG_NOTICE([Configured to build curl/libcurl:
|
||||||
|
|
||||||
curl version: ${CURLVERSION}
|
curl version: ${CURLVERSION}
|
||||||
@@ -3523,7 +3529,6 @@ AC_MSG_NOTICE([Configured to build curl/libcurl:
|
|||||||
SSL support: ${curl_ssl_msg}
|
SSL support: ${curl_ssl_msg}
|
||||||
SSH support: ${curl_ssh_msg}
|
SSH support: ${curl_ssh_msg}
|
||||||
zlib support: ${curl_zlib_msg}
|
zlib support: ${curl_zlib_msg}
|
||||||
krb4 support: ${curl_krb4_msg}
|
|
||||||
GSSAPI support: ${curl_gss_msg}
|
GSSAPI support: ${curl_gss_msg}
|
||||||
SPNEGO support: ${curl_spnego_msg}
|
SPNEGO support: ${curl_spnego_msg}
|
||||||
TLS-SRP support: ${curl_tls_srp_msg}
|
TLS-SRP support: ${curl_tls_srp_msg}
|
||||||
@@ -3542,6 +3547,7 @@ AC_MSG_NOTICE([Configured to build curl/libcurl:
|
|||||||
RTSP support: ${curl_rtsp_msg}
|
RTSP support: ${curl_rtsp_msg}
|
||||||
RTMP support: ${curl_rtmp_msg}
|
RTMP support: ${curl_rtmp_msg}
|
||||||
metalink support: ${curl_mtlnk_msg}
|
metalink support: ${curl_mtlnk_msg}
|
||||||
|
HTTP2 support: ${curl_h2_msg}
|
||||||
Protocols: ${SUPPORT_PROTOCOLS}
|
Protocols: ${SUPPORT_PROTOCOLS}
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|||||||
46
contributors.sh
Executable file
46
contributors.sh
Executable 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
|
||||||
@@ -155,7 +155,12 @@ while test $# -gt 0; do
|
|||||||
;;
|
;;
|
||||||
|
|
||||||
--static-libs)
|
--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)
|
--configure)
|
||||||
|
|||||||
@@ -79,9 +79,9 @@
|
|||||||
1.3 What To Read
|
1.3 What To Read
|
||||||
|
|
||||||
Source code, the man pages, the INTERNALS document, TODO, KNOWN_BUGS, the
|
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
|
most recent CHANGES. Just lurking on the curl-library mailing list is gonna
|
||||||
you a lot of insights on what's going on right now. Asking there is a good
|
give you a lot of insights on what's going on right now. Asking there is a
|
||||||
idea too.
|
good idea too.
|
||||||
|
|
||||||
2. cURL Coding Standards
|
2. cURL Coding Standards
|
||||||
|
|
||||||
@@ -98,12 +98,12 @@
|
|||||||
|
|
||||||
2.2 Indenting
|
2.2 Indenting
|
||||||
|
|
||||||
Please try using the same indenting levels and bracing method as all the
|
Use the same indenting levels and bracing method as all the other code
|
||||||
other code already does. It makes the source code a lot easier to follow if
|
already does. It makes the source code easier to follow if all of it is
|
||||||
all of it is written using the same style. We don't ask you to like it, we
|
written using the same style. We don't ask you to like it, we just ask you to
|
||||||
just ask you to follow the tradition! ;-) This mainly means: 2-level indents,
|
follow the tradition! ;-) This mainly means: 2-level indents, using spaces
|
||||||
using spaces only (no tabs) and having the opening brace ({) on the same line
|
only (no tabs) and having the opening brace ({) on the same line as the if()
|
||||||
as the if() or while().
|
or while().
|
||||||
|
|
||||||
Also note that we use if() and while() with no space before the parenthesis.
|
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
|
description exactly what they correct so that all patches can be selectively
|
||||||
applied by the maintainer or other interested parties.
|
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
|
2.9 Patch Against Recent Sources
|
||||||
|
|
||||||
Please try to get the latest available sources to make your patches
|
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
|
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!
|
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. Pushing Out Your Changes
|
||||||
|
|
||||||
3.1 Write Access to git Repository
|
3.1 Write Access to git Repository
|
||||||
|
|||||||
146
docs/FAQ
146
docs/FAQ
@@ -202,27 +202,25 @@ FAQ
|
|||||||
better. We do however believe in a few rules when it comes to the future of
|
better. We do however believe in a few rules when it comes to the future of
|
||||||
curl:
|
curl:
|
||||||
|
|
||||||
* Curl -- the command line tool -- is to remain a non-graphical command line
|
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
|
tool. If you want GUIs or fancy scripting capabilities, you should look for
|
||||||
for another tool that uses libcurl.
|
another tool that uses libcurl.
|
||||||
|
|
||||||
* We do not add things to curl that other small and available tools already
|
We do not add things to curl that other small and available tools already do
|
||||||
do very fine at the side. Curl's output is fine to pipe into another
|
very fine at the side. Curl's output is fine to pipe into another program or
|
||||||
program or redirect to another file for the next program to interpret.
|
redirect to another file for the next program to interpret.
|
||||||
|
|
||||||
* We focus on protocol related issues and improvements. If you wanna do more
|
We focus on protocol related issues and improvements. If you wanna do more
|
||||||
magic with the supported protocols than curl currently does, chances are
|
magic with the supported protocols than curl currently does, chances are big
|
||||||
big we will agree. If you wanna add more protocols, we may very well
|
we will agree. If you wanna add more protocols, we may very well agree.
|
||||||
agree.
|
|
||||||
|
|
||||||
* If you want someone else to make all the work while you wait for us to
|
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
|
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
|
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
|
get more out of us, you should consider trading in some of your time and
|
||||||
efforts in return.
|
efforts in return.
|
||||||
|
|
||||||
* If you write the code, chances are bigger that it will get into curl
|
If you write the code, chances are bigger that it will get into curl faster.
|
||||||
faster.
|
|
||||||
|
|
||||||
1.5 Who makes curl?
|
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
|
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 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
|
We recognize that we will be living in parallel with curl.com and wish them
|
||||||
every success.
|
every success.
|
||||||
@@ -620,15 +618,15 @@ FAQ
|
|||||||
|
|
||||||
Some workarounds usually suggested to overcome this Javascript dependency:
|
Some workarounds usually suggested to overcome this Javascript dependency:
|
||||||
|
|
||||||
- Depending on the Javascript complexity, write up a script that
|
Depending on the Javascript complexity, write up a script that translates it
|
||||||
translates it to another language and execute that.
|
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
|
Implement a Javascript interpreter, people have successfully used the
|
||||||
Mozilla Javascript engine in the past.
|
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?
|
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
|
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.
|
talk about using SSL-based protocols (HTTPS or FTPS) using curl or libcurl.
|
||||||
|
|
||||||
- Client certificate. The server you communicate may require that you can
|
CLIENT CERTIFICATE
|
||||||
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.
|
|
||||||
|
|
||||||
A client certificate is always used together with a private key, and the
|
The server you communicate may require that you can provide this in order to
|
||||||
private key has a pass phrase that protects it.
|
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
|
A client certificate is always used together with a private key, and the
|
||||||
certificate. You can and should verify this certificate to make sure that
|
private key has a pass phrase that protects it.
|
||||||
you are truly talking to the real server and not a server impersonating
|
|
||||||
it.
|
|
||||||
|
|
||||||
- Certificate Authority certificate ("CA cert"). You often have several CA
|
SERVER CERTIFICATE
|
||||||
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
|
The server you communicate with has a server certificate. You can and should
|
||||||
Authority certificate ("CA cert") that was used to sign the server
|
verify this certificate to make sure that you are truly talking to the real
|
||||||
certificate. Server certificate verification is enabled by default in curl
|
server and not a server impersonating it.
|
||||||
and libcurl and is often the reason for problems as explained in FAQ entry
|
|
||||||
4.12 and the SSLCERTS document
|
CERTIFICATE AUTHORITY CERTIFICATE ("CA cert")
|
||||||
(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
|
You often have several CA certs in a CA cert bundle that can be used to
|
||||||
for, cannot be verified. If the verification during a connect fails, you
|
verify a server certificate that was signed by one of the authorities in the
|
||||||
are refused access. You then need to explicitly disable the verification
|
bundle. curl does not come with a CA cert bundle but most curl installs
|
||||||
to connect to the server.
|
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?
|
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
|
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
|
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
|
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
|
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 built to only support a given set of protocols, and the rest would then
|
||||||
be disabled or not supported.
|
be disabled or not supported.
|
||||||
@@ -794,12 +796,13 @@ FAQ
|
|||||||
|
|
||||||
curl 'http://www.altavista.com/cgi-bin/query?text=yes&q=curl'
|
curl 'http://www.altavista.com/cgi-bin/query?text=yes&q=curl'
|
||||||
|
|
||||||
In Windows, the standard DOS shell treats the %-symbol specially and you
|
In Windows, the standard DOS shell treats the percent sign specially and you
|
||||||
need to use TWO %-symbols for each single one you want to use in the URL.
|
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
|
If you want a literal percent sign to be part of the data you pass in a POST
|
||||||
pass in a POST using -d/--data you must encode it as '%25' (which then also
|
using -d/--data you must encode it as '%25' (which then also needs the
|
||||||
needs the %-symbol doubled on Windows machines).
|
percent sign doubled on Windows machines).
|
||||||
|
|
||||||
4.3 How can I use {, }, [ or ] to specify multiple URLs?
|
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!
|
4.14 Redirects work in browser but not with curl!
|
||||||
|
|
||||||
curl supports HTTP redirects fine (see item 3.8). Browsers generally support
|
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
|
Meta tags. You can write a HTML tag that will cause the browser to redirect
|
||||||
redirect to another given URL after a certain time.
|
to another given URL after a certain time.
|
||||||
|
|
||||||
- Javascript. You can write a Javascript program embedded in a HTML page
|
Javascript. You can write a Javascript program embedded in a HTML page that
|
||||||
that redirects the browser to another given URL.
|
redirects the browser to another given URL.
|
||||||
|
|
||||||
There is no way to make curl follow these redirects. You must either
|
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
|
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?
|
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
|
was designed to be fault tolerant, so even though there may be a physical
|
||||||
break somewhere the connection shouldn't be affected, just possibly
|
break somewhere the connection shouldn't be affected, just possibly
|
||||||
delayed. Eventually, the physical break will be fixed or the data will be
|
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
|
In such cases, the TCP/IP stack is responsible for detecting when the
|
||||||
network connection is irrevocably lost. Since with some protocols it is
|
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
|
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.
|
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
|
5. libcurl Issues
|
||||||
|
|
||||||
@@ -1086,7 +1095,9 @@ FAQ
|
|||||||
|
|
||||||
We have written the libcurl code specifically adjusted for multi-threaded
|
We have written the libcurl code specifically adjusted for multi-threaded
|
||||||
programs. libcurl will use thread-safe functions instead of non-safe ones if
|
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
|
If you use a OpenSSL-powered libcurl in a multi-threaded environment, you
|
||||||
need to provide one or two locking functions:
|
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?
|
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
|
No. libcurl operates on a higher level. Besides, faking IP address would
|
||||||
would imply sending IP packages with a made-up source address, and then you
|
imply sending IP packet with a made-up source address, and then you normally
|
||||||
normally get a problem with intercepting the packages sent back as they
|
get a problem with receiving the packet sent back as they would then not be
|
||||||
would then not be routed to you!
|
routed to you!
|
||||||
|
|
||||||
If you use a proxy to access remote sites, the sites will not see your local
|
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.
|
IP address but instead the address of the proxy.
|
||||||
|
|
||||||
Also note that on many networks NATs or other IP-munging techniques are used
|
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
|
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?
|
5.13 How do I stop an ongoing transfer?
|
||||||
|
|
||||||
|
|||||||
14
docs/HISTORY
14
docs/HISTORY
@@ -7,19 +7,19 @@
|
|||||||
How cURL Became Like This
|
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)
|
currency-exchange calculations available to Internet Relay Chat (IRC)
|
||||||
users. All the necessary data are published on the Web; he just needed to
|
users. All the necessary data are published on the Web; he just needed to
|
||||||
automate their retrieval.
|
automate their retrieval.
|
||||||
|
|
||||||
Daniel simply adopted an existing command-line open-source tool, httpget, that
|
Daniel simply adopted an existing command-line open-source tool, httpget, that
|
||||||
Brazilian Rafael Sagula had written. After a few minor adjustments, it did
|
Brazilian Rafael Sagula had written and recently release version 0.1 of. After
|
||||||
just what he needed.
|
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,
|
We soon found and fixed support for getting currencies over GOPHER. Once FTP
|
||||||
and not before long FTP download support was added as well. The name of the
|
download support was added, the name of the project was changed and urlget 2.0
|
||||||
project was changed to urlget to better fit what it actually did now, since
|
was released in August 1997. The http-only days were already passed.
|
||||||
the http-only days were already passed.
|
|
||||||
|
|
||||||
The project slowly grew bigger. When upload capabilities were added and the
|
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,
|
name once again was misleading, a second name change was made and on March 20,
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ Win32
|
|||||||
adjust as necessary. It is also possible to override these paths with
|
adjust as necessary. It is also possible to override these paths with
|
||||||
environment variables, for example:
|
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 OPENSSL_PATH=c:\openssl-0.9.8y
|
||||||
set LIBSSH2_PATH=c:\libssh2-1.4.3
|
set LIBSSH2_PATH=c:\libssh2-1.4.3
|
||||||
|
|
||||||
@@ -323,7 +323,7 @@ Win32
|
|||||||
documentation on how to compile zlib. Define the ZLIB_PATH environment
|
documentation on how to compile zlib. Define the ZLIB_PATH environment
|
||||||
variable to the location of zlib.h and zlib.lib, for example:
|
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.
|
Then run 'nmake vc-zlib' in curl's root directory.
|
||||||
|
|
||||||
@@ -1045,7 +1045,7 @@ PORTS
|
|||||||
- Alpha OpenVMS V7.1-1H2
|
- Alpha OpenVMS V7.1-1H2
|
||||||
- Alpha Tru64 v5.0 5.1
|
- Alpha Tru64 v5.0 5.1
|
||||||
- AVR32 Linux
|
- AVR32 Linux
|
||||||
- ARM Android 1.5, 2.1
|
- ARM Android 1.5, 2.1, 2.3, 3.2, 4.x
|
||||||
- ARM INTEGRITY
|
- ARM INTEGRITY
|
||||||
- ARM iOS
|
- ARM iOS
|
||||||
- Cell Linux
|
- Cell Linux
|
||||||
@@ -1116,6 +1116,7 @@ GNU GSS http://www.gnu.org/software/gss/
|
|||||||
GnuTLS http://www.gnu.org/software/gnutls/
|
GnuTLS http://www.gnu.org/software/gnutls/
|
||||||
Heimdal http://www.pdc.kth.se/heimdal/
|
Heimdal http://www.pdc.kth.se/heimdal/
|
||||||
libidn http://www.gnu.org/software/libidn/
|
libidn http://www.gnu.org/software/libidn/
|
||||||
|
libmetalink https://launchpad.net/libmetalink/
|
||||||
libssh2 http://www.libssh2.org/
|
libssh2 http://www.libssh2.org/
|
||||||
MIT Kerberos http://web.mit.edu/kerberos/www/dist/
|
MIT Kerberos http://web.mit.edu/kerberos/www/dist/
|
||||||
NSS http://www.mozilla.org/projects/security/pki/nss/
|
NSS http://www.mozilla.org/projects/security/pki/nss/
|
||||||
|
|||||||
115
docs/INTERNALS
115
docs/INTERNALS
@@ -43,7 +43,7 @@ Portability
|
|||||||
openldap 2.0
|
openldap 2.0
|
||||||
MIT krb5 lib 1.2.4
|
MIT krb5 lib 1.2.4
|
||||||
qsossl V5R3M0
|
qsossl V5R3M0
|
||||||
NSS 3.12.x
|
NSS 3.14.x
|
||||||
axTLS 1.2.7
|
axTLS 1.2.7
|
||||||
Heimdal ?
|
Heimdal ?
|
||||||
|
|
||||||
@@ -111,6 +111,9 @@ Windows vs Unix
|
|||||||
Library
|
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
|
There are plenty of entry points to the library, namely each publicly defined
|
||||||
function that libcurl offers to applications. All of those functions are
|
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
|
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
|
options is documented in the man page. This function mainly sets things in
|
||||||
the 'SessionHandle' struct.
|
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
|
Some of the most important key functions in url.c are called from multi.c
|
||||||
work then continues in lib/url.c. The flow continues with a call to
|
when certain key steps are to be made in the transfer operation.
|
||||||
Curl_connect() to connect to the remote site.
|
|
||||||
|
|
||||||
o Curl_connect()
|
o Curl_connect()
|
||||||
|
|
||||||
... analyzes the URL, it separates the different components and connects to
|
Analyzes the URL, it separates the different components and connects to the
|
||||||
the remote host. This may involve using a proxy and/or using SSL. 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
|
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
|
(it does then use the proper underlying method, which may vary between
|
||||||
platforms and builds).
|
platforms and builds).
|
||||||
@@ -160,10 +165,7 @@ Library
|
|||||||
o Curl_do()
|
o Curl_do()
|
||||||
|
|
||||||
Curl_do() makes sure the proper protocol-specific function is called. The
|
Curl_do() makes sure the proper protocol-specific function is called. The
|
||||||
functions are named after the protocols they handle. Curl_ftp(),
|
functions are named after the protocols they handle.
|
||||||
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().
|
|
||||||
|
|
||||||
The protocol-specific functions of course deal with protocol-specific
|
The protocol-specific functions of course deal with protocol-specific
|
||||||
negotiations and setup. They have access to the Curl_sendf() (from
|
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)
|
be called with some basic info about the upcoming transfer: what socket(s)
|
||||||
to read/write and the expected file transfer sizes (if known).
|
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
|
Called during the transfer of the actual protocol payload.
|
||||||
entire file transfer.
|
|
||||||
|
|
||||||
During transfer, the progress functions in lib/progress.c are called at a
|
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
|
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
|
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
|
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
|
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
|
connections alive at the same time.
|
||||||
can be changed with the CURLOPT_MAXCONNECTS option).
|
|
||||||
|
|
||||||
This function cleans up all resources that are associated with a single
|
This function cleans up all resources that are associated with a single
|
||||||
connection.
|
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)
|
HTTP(S)
|
||||||
|
|
||||||
@@ -316,48 +295,38 @@ Persistent Connections
|
|||||||
hold connection-oriented data. It is meant to hold the root data as well as
|
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.
|
all the options etc that the library-user may choose.
|
||||||
o The 'SessionHandle' struct holds the "connection cache" (an array of
|
o The 'SessionHandle' struct holds the "connection cache" (an array of
|
||||||
pointers to 'connectdata' structs). There's one connectdata struct
|
pointers to 'connectdata' structs).
|
||||||
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.
|
|
||||||
o This enables the 'curl handle' to be reused on subsequent transfers.
|
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
|
o When libcurl is told to perform a transfer, it first checks for an already
|
||||||
check for an already existing connection in the cache that we can use,
|
existing connection in the cache that we can use. Otherwise it creates a
|
||||||
otherwise we create a new one and add to the cache. If the cache is full
|
new one and adds that the cache. If the cache is full already when a new
|
||||||
already when we add a new connection, we close one of the present ones. We
|
conncetion is added added, it will first close the oldest unused one.
|
||||||
select which one to close dependent on the close policy that may have been
|
o When the transfer operation is complete, the connection is left
|
||||||
previously set.
|
open. Particular options may tell libcurl not to, and protocols may signal
|
||||||
o When the transfer operation is complete, we try to leave the connection
|
closure on connections and then they won't be kept open of course.
|
||||||
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 curl_easy_cleanup() is called, we close all still opened connections,
|
o When curl_easy_cleanup() is called, we close all still opened connections,
|
||||||
unless of course the multi interface "owns" the 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
|
The curl handle must be re-used in order for the persistent connections to
|
||||||
persistent connections to work.
|
work.
|
||||||
|
|
||||||
multi interface/non-blocking
|
multi interface/non-blocking
|
||||||
============================
|
============================
|
||||||
|
|
||||||
We make an effort to provide a non-blocking interface to the library, the
|
The multi interface is a non-blocking interface to the library. To make that
|
||||||
multi interface. To make that interface work as good as possible, no
|
interface work as good as possible, no low-level functions within libcurl
|
||||||
low-level functions within libcurl must be written to work in a blocking
|
must be written to work in a blocking manner. (There are still a few spots
|
||||||
manner.
|
violating this rule.)
|
||||||
|
|
||||||
One of the primary reasons we introduced c-ares support was to allow the name
|
One of the primary reasons we introduced c-ares support was to allow the name
|
||||||
resolve phase to be perfectly non-blocking as well.
|
resolve phase to be perfectly non-blocking as well.
|
||||||
|
|
||||||
The ultimate goal is to provide the easy interface simply by wrapping the
|
The FTP and the SFTP/SCP protocols are examples of how we adapt and adjust
|
||||||
multi interface functions and thus treat everything internally as the multi
|
the code to allow non-blocking operations even on multi-stage command-
|
||||||
interface is the single interface we have.
|
response protocols. They are built around state machines that return when
|
||||||
|
they would otherwise block waiting for data. The DICT, LDAP and TELNET
|
||||||
The FTP and the SFTP/SCP protocols are thus perfect examples of how we adapt
|
protocols are crappy examples and they are subject for rewrite in the future
|
||||||
and adjust the code to allow non-blocking operations even on multi-stage
|
to better fit the libcurl protocol family.
|
||||||
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.
|
|
||||||
|
|
||||||
SSL libraries
|
SSL libraries
|
||||||
=============
|
=============
|
||||||
@@ -408,12 +377,12 @@ API/ABI
|
|||||||
Client
|
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
|
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
|
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
|
functions used for the URL-"globbing" support. Globbing in the sense that the
|
||||||
the {} and [] expansion stuff is there.
|
{} and [] expansion stuff is there.
|
||||||
|
|
||||||
The client mostly messes around to setup its 'config' struct properly, then
|
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
|
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
|
curl_easy_getinfo() function to extract useful information from the curl
|
||||||
session.
|
session.
|
||||||
|
|
||||||
Recent versions may loop and do all this several times if many URLs were
|
It may loop and do all this several times if many URLs were specified on the
|
||||||
specified on the command line or config file.
|
command line or config file.
|
||||||
|
|
||||||
Memory Debugging
|
Memory Debugging
|
||||||
================
|
================
|
||||||
|
|||||||
@@ -3,20 +3,61 @@ 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
|
changelog of the current development status, as one or more of these problems
|
||||||
may have been fixed since this was written!
|
may have been fixed since this was written!
|
||||||
|
|
||||||
|
87. -J/--remote-header-name doesn't decode %-encoded file names. RFC6266
|
||||||
|
details how it should be done. The can of worm is basically that we have no
|
||||||
|
charset handling in curl and ascii >=128 is a challenge for us. Not to
|
||||||
|
mention that decoding also means that we need to check for nastyness that is
|
||||||
|
attempted, like "../" sequences and the like. Probably everything to the left
|
||||||
|
of any embedded slashes should be cut off.
|
||||||
|
http://curl.haxx.se/bug/view.cgi?id=1294
|
||||||
|
|
||||||
|
86. The disconnect commands (LOGOUT and QUIT) may not be sent by IMAP, POP3
|
||||||
|
and SMTP if a failure occures during the authentication phase of a
|
||||||
|
connection.
|
||||||
|
|
||||||
|
85. Wrong STARTTRANSFER timer accounting for POST requests
|
||||||
|
Timer works fine with GET requests, but while using POST the time for
|
||||||
|
CURLINFO_STARTTRANSFER_TIME is wrong. While using POST
|
||||||
|
CURLINFO_STARTTRANSFER_TIME minus CURLINFO_PRETRANSFER_TIME is near to zero
|
||||||
|
every time.
|
||||||
|
http://curl.haxx.se/bug/view.cgi?id=1213
|
||||||
|
|
||||||
|
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
|
80. Curl doesn't recognize certificates in DER format in keychain, but it
|
||||||
works with PEM.
|
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
|
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"
|
failure if one of the recipients indicate failure (on the "RCPT TO"
|
||||||
command). Ordinary mail programs would proceed and still send to the ones
|
command). Ordinary mail programs would proceed and still send to the ones
|
||||||
that can receive data. This is subject for change in the future.
|
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"
|
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
|
zero bytes files - it makes for example the command line client not creating
|
||||||
any file at all. Like when using FTP.
|
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
|
77. CURLOPT_FORBID_REUSE on a handle prevents NTLM from working since it
|
||||||
"abuses" the underlying connection re-use system and if connections are
|
"abuses" the underlying connection re-use system and if connections are
|
||||||
@@ -31,7 +72,7 @@ may have been fixed since this was written!
|
|||||||
properly if built with UNICODE defined together with the schannel/winssl
|
properly if built with UNICODE defined together with the schannel/winssl
|
||||||
backend. The original problem was mentioned in:
|
backend. The original problem was mentioned in:
|
||||||
http://curl.haxx.se/mail/lib-2009-10/0024.html
|
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
|
The schannel version verified to work as mentioned in
|
||||||
http://curl.haxx.se/mail/lib-2012-07/0073.html
|
http://curl.haxx.se/mail/lib-2012-07/0073.html
|
||||||
@@ -41,7 +82,7 @@ may have been fixed since this was written!
|
|||||||
acknowledge the connection timeout during that phase but only the "real"
|
acknowledge the connection timeout during that phase but only the "real"
|
||||||
timeout - which may surprise users as it is probably considered to be the
|
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:
|
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."
|
72. "Pausing pipeline problems."
|
||||||
http://curl.haxx.se/mail/lib-2009-07/0214.html
|
http://curl.haxx.se/mail/lib-2009-07/0214.html
|
||||||
@@ -59,7 +100,7 @@ may have been fixed since this was written!
|
|||||||
http://tools.ietf.org/html/draft-reschke-rfc2231-in-http-02
|
http://tools.ietf.org/html/draft-reschke-rfc2231-in-http-02
|
||||||
|
|
||||||
66. When using telnet, the time limitation options don't work.
|
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
|
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
|
multi interface is used, libcurl will fail if the (passive) TCP connection
|
||||||
@@ -85,19 +126,12 @@ may have been fixed since this was written!
|
|||||||
CURLOPT_FAILONERROR with FTP to detect if a file exists or not, but it is
|
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
|
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
|
56. When libcurl sends CURLOPT_POSTQUOTE commands when connected to a SFTP
|
||||||
server using the multi interface, the commands are not being sent correctly
|
server using the multi interface, the commands are not being sent correctly
|
||||||
and instead the connection is "cancelled" (the operation is considered done)
|
and instead the connection is "cancelled" (the operation is considered done)
|
||||||
prematurely. There is a half-baked (busy-looping) patch provided in the bug
|
prematurely. There is a half-baked (busy-looping) patch provided in the bug
|
||||||
report but it cannot be accepted as-is. See
|
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
|
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
|
library header files exporting symbols/macros that should be kept private
|
||||||
@@ -121,12 +155,12 @@ may have been fixed since this was written!
|
|||||||
protocol code. This should be very rare.
|
protocol code. This should be very rare.
|
||||||
|
|
||||||
43. There seems to be a problem when connecting to the Microsoft telnet server.
|
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
|
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
|
when logging in), the operation will fail since libcurl doesn't detect this
|
||||||
and thus fails to issue the correct command:
|
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:
|
39. Steffen Rumler's Race Condition in Curl_proxyCONNECT:
|
||||||
http://curl.haxx.se/mail/lib-2007-01/0045.html
|
http://curl.haxx.se/mail/lib-2007-01/0045.html
|
||||||
@@ -139,7 +173,7 @@ may have been fixed since this was written!
|
|||||||
|
|
||||||
34. The SOCKS4 connection codes don't properly acknowledge (connect) timeouts.
|
34. The SOCKS4 connection codes don't properly acknowledge (connect) timeouts.
|
||||||
Also see #12. According to bug #1556528, even the SOCKS5 connect code does
|
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
|
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
|
run that might be needed only for building libcurl. Further, curl-config
|
||||||
@@ -154,13 +188,12 @@ may have been fixed since this was written!
|
|||||||
IDs in URLs to get around the problem of percent signs being
|
IDs in URLs to get around the problem of percent signs being
|
||||||
special. According to the reporter, Firefox deals with the URL _with_ a
|
special. According to the reporter, Firefox deals with the URL _with_ a
|
||||||
percent letter (which seems like a blatant URL spec violation).
|
percent letter (which seems like a blatant URL spec violation).
|
||||||
libcurl supports zone IDs where the percent sign is URL-escaped (i.e. %25).
|
libcurl supports zone IDs where the percent sign is URL-escaped (i.e. %25):
|
||||||
|
http://curl.haxx.se/bug/view.cgi?id=555
|
||||||
See http://curl.haxx.se/bug/view.cgi?id=1371118
|
|
||||||
|
|
||||||
26. NTLM authentication using SSPI (on Windows) when (lib)curl is running in
|
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
|
"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:
|
23. SOCKS-related problems:
|
||||||
B) libcurl doesn't support FTPS over a SOCKS proxy.
|
B) libcurl doesn't support FTPS over a SOCKS proxy.
|
||||||
@@ -169,12 +202,6 @@ may have been fixed since this was written!
|
|||||||
We probably have even more bugs and lack of features when a SOCKS proxy is
|
We probably have even more bugs and lack of features when a SOCKS proxy is
|
||||||
used.
|
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
|
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
|
accordingly (not for sending nor for receiving). RFC 959 section 3.1.1.1
|
||||||
clearly describes how this should be done:
|
clearly describes how this should be done:
|
||||||
@@ -212,7 +239,7 @@ may have been fixed since this was written!
|
|||||||
10. To get HTTP Negotiate authentication to work fine, you need to provide a
|
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
|
(fake) user name (this concerns both curl and the lib) because the code
|
||||||
wrongly only considers authentication if there's a user name provided.
|
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
|
http://curl.haxx.se/mail/lib-2004-08/0182.html
|
||||||
|
|
||||||
8. Doing resumed upload over HTTP does not work with '-C -', because curl
|
8. Doing resumed upload over HTTP does not work with '-C -', because curl
|
||||||
|
|||||||
245
docs/LIBCURL-STRUCTS
Normal file
245
docs/LIBCURL-STRUCTS
Normal 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.
|
||||||
@@ -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
|
# This software is licensed as described in the file COPYING, which
|
||||||
# you should have received as part of this distribution. The terms
|
# you should have received as part of this distribution. The terms
|
||||||
@@ -22,7 +22,8 @@
|
|||||||
|
|
||||||
AUTOMAKE_OPTIONS = foreign no-dependencies
|
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
|
GENHTMLPAGES = curl.html curl-config.html mk-ca-bundle.html
|
||||||
PDFPAGES = curl.pdf curl-config.pdf mk-ca-bundle.pdf
|
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 \
|
README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS VERSIONS \
|
||||||
KNOWN_BUGS BINDINGS $(man_MANS) $(HTMLPAGES) HISTORY INSTALL \
|
KNOWN_BUGS BINDINGS $(man_MANS) $(HTMLPAGES) HISTORY INSTALL \
|
||||||
$(PDFPAGES) LICENSE-MIXING README.netware DISTRO-DILEMMA INSTALL.devcpp \
|
$(PDFPAGES) LICENSE-MIXING README.netware DISTRO-DILEMMA INSTALL.devcpp \
|
||||||
MAIL-ETIQUETTE HTTP-COOKIES
|
MAIL-ETIQUETTE HTTP-COOKIES LIBCURL-STRUCTS SECURITY
|
||||||
|
|
||||||
MAN2HTML= roffit < $< >$@
|
MAN2HTML= roffit < $< >$@
|
||||||
|
|
||||||
|
|||||||
91
docs/SECURITY
Normal file
91
docs/SECURITY
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
_ _ ____ _
|
||||||
|
___| | | | _ \| |
|
||||||
|
/ __| | | | |_) | |
|
||||||
|
| (__| |_| | _ <| |___
|
||||||
|
\___|\___/|_| \_\_____|
|
||||||
|
|
||||||
|
CURL SECURITY FOR DEVELOPERS
|
||||||
|
|
||||||
|
This document is intended to provide guidance to curl developers on how
|
||||||
|
security vulnerabilities should be handled.
|
||||||
|
|
||||||
|
PUBLISHING INFORMATION
|
||||||
|
|
||||||
|
All known and public curl or libcurl related vulnerabilities are listed at
|
||||||
|
http://curl.haxx.se/docs/security.html
|
||||||
|
|
||||||
|
Security vulnerabilities should not be entered in the project's public bug
|
||||||
|
tracker unless the necessary configuration is in place to limit access to the
|
||||||
|
issue to only the reporter and the project's security team.
|
||||||
|
|
||||||
|
VULNERABILITY HANDLING
|
||||||
|
|
||||||
|
The typical process for handling a new security vulnerability is as follows.
|
||||||
|
|
||||||
|
No information should be made public about a vulnerability until it is
|
||||||
|
formally announced at the end of this process. That means, for example that a
|
||||||
|
bug tracker entry must NOT be created to track the issue since that will make
|
||||||
|
the issue public and it should not be discussed on any of the project's public
|
||||||
|
mailing lists. Also messages associated with any commits should not make
|
||||||
|
any reference to the security nature of the commit if done prior to the public
|
||||||
|
announcement.
|
||||||
|
|
||||||
|
- The person discovering the issue, the reporter, reports the vulnerability
|
||||||
|
privately to curl-security@haxx.se. That's an email alias that reaches a
|
||||||
|
handful of selected and trusted people.
|
||||||
|
|
||||||
|
- Messages that do not relate to the reporting or managing of an undisclosed
|
||||||
|
security vulnerability in curl or libcurl are ignored and no further action
|
||||||
|
is required.
|
||||||
|
|
||||||
|
- A person in the security team sends an e-mail to the original reporter to
|
||||||
|
acknowledge the report.
|
||||||
|
|
||||||
|
- The security team investigates the report and either rejects it or accepts
|
||||||
|
it.
|
||||||
|
|
||||||
|
- If the report is rejected, the team writes to the reporter to explain why.
|
||||||
|
|
||||||
|
- If the report is accepted, the team writes to the reporter to let him/her
|
||||||
|
know it is accepted and that they are working on a fix.
|
||||||
|
|
||||||
|
- The security team discusses the problem, works out a fix, considers the
|
||||||
|
impact of the problem and suggests a release schedule. This discussion
|
||||||
|
should involve the reporter as much as possible.
|
||||||
|
|
||||||
|
- The release of the information should be "as soon as possible" and is most
|
||||||
|
often synced with an upcoming release that contains the fix. If the
|
||||||
|
reporter, or anyone else, thinks the next planned release is too far away
|
||||||
|
then a separate earlier release for security reasons should be considered.
|
||||||
|
|
||||||
|
- Write a security advisory draft about the problem that explains what the
|
||||||
|
problem is, its impact, which versions it affects, solutions or
|
||||||
|
work-arounds, when the release is out and make sure to credit all
|
||||||
|
contributors properly.
|
||||||
|
|
||||||
|
- Request a CVE number from distros@openwall.org[1] when also informing and
|
||||||
|
preparing them for the upcoming public security vulnerability announcement -
|
||||||
|
attach the advisory draft for information. Note that 'distros' won't accept
|
||||||
|
an embargo longer than 19 days.
|
||||||
|
|
||||||
|
- Update the "security advisory" with the CVE number.
|
||||||
|
|
||||||
|
- The security team commits the fix in a private branch. The commit message
|
||||||
|
should ideally contain the CVE number. This fix is usually also distributed
|
||||||
|
to the 'distros' mailing list to allow them to use the fix prior to the
|
||||||
|
public announcement.
|
||||||
|
|
||||||
|
- At the day of the next release, the private branch is merged into the master
|
||||||
|
branch and pushed. Once pushed, the information is accessible to the public
|
||||||
|
and the actual release should follow suit immediately afterwards.
|
||||||
|
|
||||||
|
- The project team creates a release that includes the fix.
|
||||||
|
|
||||||
|
- The project team announces the release and the vulnerability to the world in
|
||||||
|
the same manner we always announce releases. It gets sent to the
|
||||||
|
curl-announce, curl-library and curl-users mailing lists.
|
||||||
|
|
||||||
|
- The security web page on the web site should get the new vulernability
|
||||||
|
mentioned.
|
||||||
|
|
||||||
|
[1] = http://oss-security.openwall.org/wiki/mailing-lists/distros
|
||||||
107
docs/THANKS
107
docs/THANKS
@@ -13,24 +13,27 @@ Adam Tkac
|
|||||||
Adrian Schuur
|
Adrian Schuur
|
||||||
Adriano Meirelles
|
Adriano Meirelles
|
||||||
Ajit Dhumale
|
Ajit Dhumale
|
||||||
|
Aki Koskinen
|
||||||
Akos Pasztory
|
Akos Pasztory
|
||||||
Alan Pinstein
|
Alan Pinstein
|
||||||
Albert Chin
|
|
||||||
Albert Chin-A-Young
|
Albert Chin-A-Young
|
||||||
Albert Choy
|
Albert Choy
|
||||||
Ale Vesely
|
Ale Vesely
|
||||||
Alejandro Alvarez
|
Alejandro Alvarez
|
||||||
Aleksandar Milivojevic
|
Aleksandar Milivojevic
|
||||||
|
Aleksey Tulinov
|
||||||
Alessandro Ghedini
|
Alessandro Ghedini
|
||||||
Alessandro Vesely
|
Alessandro Vesely
|
||||||
Alex Bligh
|
Alex Bligh
|
||||||
Alex Fishman
|
Alex Fishman
|
||||||
Alex Gruz
|
Alex Gruz
|
||||||
|
Alex McLellan
|
||||||
Alex Neblett
|
Alex Neblett
|
||||||
Alex Suykov
|
Alex Suykov
|
||||||
Alex Vinnik
|
Alex Vinnik
|
||||||
Alex aka WindEagle
|
Alex aka WindEagle
|
||||||
Alexander Beedie
|
Alexander Beedie
|
||||||
|
Alexander Klauer
|
||||||
Alexander Kourakos
|
Alexander Kourakos
|
||||||
Alexander Krasnostavsky
|
Alexander Krasnostavsky
|
||||||
Alexander Lazic
|
Alexander Lazic
|
||||||
@@ -46,11 +49,13 @@ Amol Pattekar
|
|||||||
Amr Shahin
|
Amr Shahin
|
||||||
Anatoli Tubman
|
Anatoli Tubman
|
||||||
Anders Gustafsson
|
Anders Gustafsson
|
||||||
|
Anders Havn
|
||||||
Andi Jahja
|
Andi Jahja
|
||||||
Andre Guibert de Bruet
|
Andre Guibert de Bruet
|
||||||
Andreas Damm
|
Andreas Damm
|
||||||
Andreas Faerber
|
Andreas Faerber
|
||||||
Andreas Farber
|
Andreas Farber
|
||||||
|
Andreas Malzahn
|
||||||
Andreas Ntaflos
|
Andreas Ntaflos
|
||||||
Andreas Olsson
|
Andreas Olsson
|
||||||
Andreas Rieke
|
Andreas Rieke
|
||||||
@@ -58,15 +63,18 @@ Andreas Schuldei
|
|||||||
Andreas Wurf
|
Andreas Wurf
|
||||||
Andrei Benea
|
Andrei Benea
|
||||||
Andrei Cipu
|
Andrei Cipu
|
||||||
|
Andrej E Baranov
|
||||||
Andres Garcia
|
Andres Garcia
|
||||||
Andrew Benham
|
Andrew Benham
|
||||||
Andrew Biggs
|
Andrew Biggs
|
||||||
Andrew Bushnell
|
Andrew Bushnell
|
||||||
Andrew Francis
|
Andrew Francis
|
||||||
Andrew Fuller
|
Andrew Fuller
|
||||||
|
Andrew Kurushin
|
||||||
Andrew Moise
|
Andrew Moise
|
||||||
Andrew Wansink
|
Andrew Wansink
|
||||||
Andrew de los Reyes
|
Andrew de los Reyes
|
||||||
|
Andrii Moiseiev
|
||||||
Andrés García
|
Andrés García
|
||||||
Andy Cedilnik
|
Andy Cedilnik
|
||||||
Andy Serpa
|
Andy Serpa
|
||||||
@@ -101,12 +109,16 @@ Ben Van Hof
|
|||||||
Ben Winslow
|
Ben Winslow
|
||||||
Benbuck Nason
|
Benbuck Nason
|
||||||
Benjamin Gerard
|
Benjamin Gerard
|
||||||
|
Benjamin Gilbert
|
||||||
Benjamin Johnson
|
Benjamin Johnson
|
||||||
|
Benoit Sigoure
|
||||||
Bernard Leak
|
Bernard Leak
|
||||||
Bernhard Reutner-Fischer
|
Bernhard Reutner-Fischer
|
||||||
Bertrand Demiddelaer
|
Bertrand Demiddelaer
|
||||||
|
Bill Doyle
|
||||||
Bill Egert
|
Bill Egert
|
||||||
Bill Hoffman
|
Bill Hoffman
|
||||||
|
Bill Middlecamp
|
||||||
Bjoern Sikora
|
Bjoern Sikora
|
||||||
Bjorn Augustsson
|
Bjorn Augustsson
|
||||||
Bjorn Reese
|
Bjorn Reese
|
||||||
@@ -133,6 +145,7 @@ Bruce Mitchener
|
|||||||
Bruno de Carvalho
|
Bruno de Carvalho
|
||||||
Bryan Henderson
|
Bryan Henderson
|
||||||
Bryan Kemp
|
Bryan Kemp
|
||||||
|
Byrial Jensen
|
||||||
Cameron Kaiser
|
Cameron Kaiser
|
||||||
Camille Moncelier
|
Camille Moncelier
|
||||||
Caolan McNamara
|
Caolan McNamara
|
||||||
@@ -145,6 +158,7 @@ Charles Kerr
|
|||||||
Chih-Chung Chang
|
Chih-Chung Chang
|
||||||
Chris "Bob Bob"
|
Chris "Bob Bob"
|
||||||
Chris Combes
|
Chris Combes
|
||||||
|
Chris Conlon
|
||||||
Chris Conroy
|
Chris Conroy
|
||||||
Chris Deidun
|
Chris Deidun
|
||||||
Chris Flerackers
|
Chris Flerackers
|
||||||
@@ -153,13 +167,13 @@ Chris Maltby
|
|||||||
Chris Mumford
|
Chris Mumford
|
||||||
Chris Smowton
|
Chris Smowton
|
||||||
Christian Grothoff
|
Christian Grothoff
|
||||||
Christian Hagele
|
|
||||||
Christian Hägele
|
Christian Hägele
|
||||||
Christian Krause
|
Christian Krause
|
||||||
Christian Kurz
|
Christian Kurz
|
||||||
Christian Robottom Reis
|
Christian Robottom Reis
|
||||||
Christian Schmitz
|
Christian Schmitz
|
||||||
Christian Vogt
|
Christian Vogt
|
||||||
|
Christian Weisgerber
|
||||||
Christophe Demory
|
Christophe Demory
|
||||||
Christophe Legry
|
Christophe Legry
|
||||||
Christopher Conroy
|
Christopher Conroy
|
||||||
@@ -169,8 +183,10 @@ Christopher Stone
|
|||||||
Ciprian Badescu
|
Ciprian Badescu
|
||||||
Claes Jakobsson
|
Claes Jakobsson
|
||||||
Clarence Gardner
|
Clarence Gardner
|
||||||
|
Clemens Gruber
|
||||||
Clifford Wolf
|
Clifford Wolf
|
||||||
Cody Jones
|
Cody Jones
|
||||||
|
Colby Ranger
|
||||||
Colin Hogben
|
Colin Hogben
|
||||||
Colin Watson
|
Colin Watson
|
||||||
Colm Buckley
|
Colm Buckley
|
||||||
@@ -180,10 +196,11 @@ Craig A West
|
|||||||
Craig Davison
|
Craig Davison
|
||||||
Craig Markwardt
|
Craig Markwardt
|
||||||
Cris Bailiff
|
Cris Bailiff
|
||||||
Cristian Rodriguez
|
|
||||||
Cristian Rodríguez
|
Cristian Rodríguez
|
||||||
Curt Bogmine
|
Curt Bogmine
|
||||||
Cyrill Osterwalder
|
Cyrill Osterwalder
|
||||||
|
Cédric Deltheil
|
||||||
|
D. Flinkmann
|
||||||
Dag Ekengren
|
Dag Ekengren
|
||||||
Dagobert Michelsen
|
Dagobert Michelsen
|
||||||
Damien Adant
|
Damien Adant
|
||||||
@@ -211,6 +228,7 @@ Dave Halbakken
|
|||||||
Dave Hamilton
|
Dave Hamilton
|
||||||
Dave May
|
Dave May
|
||||||
Dave Reisner
|
Dave Reisner
|
||||||
|
Dave Thompson
|
||||||
Dave Vasilevsky
|
Dave Vasilevsky
|
||||||
David Bau
|
David Bau
|
||||||
David Binderman
|
David Binderman
|
||||||
@@ -231,15 +249,19 @@ David Odin
|
|||||||
David Phillips
|
David Phillips
|
||||||
David Rosenstrauch
|
David Rosenstrauch
|
||||||
David Shaw
|
David Shaw
|
||||||
|
David Strauss
|
||||||
David Tarendash
|
David Tarendash
|
||||||
David Thiel
|
David Thiel
|
||||||
|
David Walser
|
||||||
David Wright
|
David Wright
|
||||||
David Yan
|
David Yan
|
||||||
Dengminwen
|
Dengminwen
|
||||||
|
Derek Higgins
|
||||||
Detlef Schmier
|
Detlef Schmier
|
||||||
Didier Brisebourg
|
Didier Brisebourg
|
||||||
Diego Casorran
|
Diego Casorran
|
||||||
Dima Barsky
|
Dima Barsky
|
||||||
|
Dima Tisnek
|
||||||
Dimitre Dimitrov
|
Dimitre Dimitrov
|
||||||
Dimitris Sarris
|
Dimitris Sarris
|
||||||
Dinar
|
Dinar
|
||||||
@@ -263,6 +285,7 @@ Douglas R. Horner
|
|||||||
Douglas Steinwand
|
Douglas Steinwand
|
||||||
Dov Murik
|
Dov Murik
|
||||||
Duane Cathey
|
Duane Cathey
|
||||||
|
Duncan
|
||||||
Duncan Mac-Vicar Prett
|
Duncan Mac-Vicar Prett
|
||||||
Dustin Boswell
|
Dustin Boswell
|
||||||
Dylan Ellicott
|
Dylan Ellicott
|
||||||
@@ -271,11 +294,13 @@ Early Ehlinger
|
|||||||
Ebenezer Ikonne
|
Ebenezer Ikonne
|
||||||
Edin Kadribasic
|
Edin Kadribasic
|
||||||
Eduard Bloch
|
Eduard Bloch
|
||||||
|
Edward Rudd
|
||||||
Edward Sheldrake
|
Edward Sheldrake
|
||||||
Eelco Dolstra
|
Eelco Dolstra
|
||||||
Eetu Ojanen
|
Eetu Ojanen
|
||||||
Eldar Zaitov
|
Eldar Zaitov
|
||||||
Ellis Pritchard
|
Ellis Pritchard
|
||||||
|
Elmira A Semenova
|
||||||
Emanuele Bovisio
|
Emanuele Bovisio
|
||||||
Emil Romanus
|
Emil Romanus
|
||||||
Emiliano Ida
|
Emiliano Ida
|
||||||
@@ -285,27 +310,33 @@ Eric Cooper
|
|||||||
Eric Hu
|
Eric Hu
|
||||||
Eric Landes
|
Eric Landes
|
||||||
Eric Lavigne
|
Eric Lavigne
|
||||||
|
Eric Lubin
|
||||||
Eric Melville
|
Eric Melville
|
||||||
Eric Mertens
|
Eric Mertens
|
||||||
Eric Rautman
|
Eric Rautman
|
||||||
|
Eric S. Raymond
|
||||||
Eric Thelin
|
Eric Thelin
|
||||||
Eric Vergnaud
|
Eric Vergnaud
|
||||||
Eric Wong
|
Eric Wong
|
||||||
Eric Young
|
Eric Young
|
||||||
Erick Nuwendam
|
Erick Nuwendam
|
||||||
|
Erik Johansson
|
||||||
Erwan Legrand
|
Erwan Legrand
|
||||||
Erwin Authried
|
Erwin Authried
|
||||||
Eugene Kotlyarov
|
Eugene Kotlyarov
|
||||||
Evan Jordan
|
Evan Jordan
|
||||||
|
Evgeny Turnaev
|
||||||
Eygene Ryabinkin
|
Eygene Ryabinkin
|
||||||
Fabian Hiernaux
|
Fabian Hiernaux
|
||||||
Fabian Keil
|
Fabian Keil
|
||||||
Fabrizio Ammollo
|
Fabrizio Ammollo
|
||||||
Fedor Karpelevitch
|
Fedor Karpelevitch
|
||||||
|
Felix Yan
|
||||||
Felix von Leitner
|
Felix von Leitner
|
||||||
Feng Tu
|
Feng Tu
|
||||||
Florian Schoppmann
|
Florian Schoppmann
|
||||||
Forrest Cahoon
|
Forrest Cahoon
|
||||||
|
Francois Charlier
|
||||||
Frank Hempel
|
Frank Hempel
|
||||||
Frank Keeney
|
Frank Keeney
|
||||||
Frank McGeough
|
Frank McGeough
|
||||||
@@ -317,6 +348,7 @@ Fred Machado
|
|||||||
Fred New
|
Fred New
|
||||||
Fred Noz
|
Fred Noz
|
||||||
Frederic Lepied
|
Frederic Lepied
|
||||||
|
Fredrik Thulin
|
||||||
Gabriel Kuri
|
Gabriel Kuri
|
||||||
Gabriel Sjoberg
|
Gabriel Sjoberg
|
||||||
Garrett Holmstrom
|
Garrett Holmstrom
|
||||||
@@ -325,11 +357,13 @@ Gautam Kachroo
|
|||||||
Gautam Mani
|
Gautam Mani
|
||||||
Gavrie Philipson
|
Gavrie Philipson
|
||||||
Gaz Iqbal
|
Gaz Iqbal
|
||||||
|
Geoff Beier
|
||||||
Georg Horn
|
Georg Horn
|
||||||
Georg Huettenegger
|
Georg Huettenegger
|
||||||
Georg Lippitsch
|
Georg Lippitsch
|
||||||
Georg Wicherski
|
Georg Wicherski
|
||||||
Gerd v. Egidy
|
Gerd v. Egidy
|
||||||
|
Gergely Nagy
|
||||||
Gerhard Herre
|
Gerhard Herre
|
||||||
Gerrit Bruchhäuser
|
Gerrit Bruchhäuser
|
||||||
Ghennadi Procopciuc
|
Ghennadi Procopciuc
|
||||||
@@ -345,6 +379,8 @@ Giuseppe D'Ambrosio
|
|||||||
Glen Nakamura
|
Glen Nakamura
|
||||||
Glen Scott
|
Glen Scott
|
||||||
Gokhan Sengun
|
Gokhan Sengun
|
||||||
|
Gordon Marler
|
||||||
|
Gorilla Maguila
|
||||||
Grant Erickson
|
Grant Erickson
|
||||||
Greg Hewgill
|
Greg Hewgill
|
||||||
Greg Morse
|
Greg Morse
|
||||||
@@ -360,14 +396,17 @@ Gwenole Beauchesne
|
|||||||
Götz Babin-Ebell
|
Götz Babin-Ebell
|
||||||
Hamish Mackenzie
|
Hamish Mackenzie
|
||||||
Hang Kin Lau
|
Hang Kin Lau
|
||||||
|
Hang Su
|
||||||
Hanno Kranzhoff
|
Hanno Kranzhoff
|
||||||
Hans Steegers
|
Hans Steegers
|
||||||
Hans-Jurgen May
|
Hans-Jurgen May
|
||||||
Hardeep Singh
|
Hardeep Singh
|
||||||
Harshal Pradhan
|
Harshal Pradhan
|
||||||
Hauke Duden
|
Hauke Duden
|
||||||
|
He Qin
|
||||||
Heikki Korpela
|
Heikki Korpela
|
||||||
Heinrich Ko
|
Heinrich Ko
|
||||||
|
Heinrich Schaefer
|
||||||
Hendrik Visage
|
Hendrik Visage
|
||||||
Henrik Storner
|
Henrik Storner
|
||||||
Henry Ludemann
|
Henry Ludemann
|
||||||
@@ -394,6 +433,7 @@ Immanuel Gregoire
|
|||||||
Ingmar Runge
|
Ingmar Runge
|
||||||
Ingo Ralf Blum
|
Ingo Ralf Blum
|
||||||
Ingo Wilken
|
Ingo Wilken
|
||||||
|
Ishan SinghLevett
|
||||||
Jack Zhang
|
Jack Zhang
|
||||||
Jacky Lam
|
Jacky Lam
|
||||||
Jacob Meuser
|
Jacob Meuser
|
||||||
@@ -403,6 +443,7 @@ James Bursa
|
|||||||
James Cheng
|
James Cheng
|
||||||
James Clancy
|
James Clancy
|
||||||
James Cone
|
James Cone
|
||||||
|
James Dury
|
||||||
James Gallagher
|
James Gallagher
|
||||||
James Griffiths
|
James Griffiths
|
||||||
James Housley
|
James Housley
|
||||||
@@ -415,12 +456,14 @@ Jan Koen Annot
|
|||||||
Jan Kunder
|
Jan Kunder
|
||||||
Jan Schaumann
|
Jan Schaumann
|
||||||
Jan Van Boghout
|
Jan Van Boghout
|
||||||
|
Jared Jennings
|
||||||
Jared Lundell
|
Jared Lundell
|
||||||
Jari Sundell
|
Jari Sundell
|
||||||
Jason Glasgow
|
Jason Glasgow
|
||||||
Jason Liu
|
Jason Liu
|
||||||
Jason McDonald
|
Jason McDonald
|
||||||
Jason S. Priebe
|
Jason S. Priebe
|
||||||
|
Javier Barroso
|
||||||
Jay Austin
|
Jay Austin
|
||||||
Jayesh A Shah
|
Jayesh A Shah
|
||||||
Jaz Fresh
|
Jaz Fresh
|
||||||
@@ -429,17 +472,21 @@ Jean-Claude Chauve
|
|||||||
Jean-Francois Bertrand
|
Jean-Francois Bertrand
|
||||||
Jean-Louis Lemaire
|
Jean-Louis Lemaire
|
||||||
Jean-Marc Ranger
|
Jean-Marc Ranger
|
||||||
|
Jean-Noel Rouvignac
|
||||||
Jean-Philippe Barrette-LaPierre
|
Jean-Philippe Barrette-LaPierre
|
||||||
Jeff Connelly
|
Jeff Connelly
|
||||||
Jeff Johnson
|
Jeff Johnson
|
||||||
|
Jeff King
|
||||||
Jeff Lawson
|
Jeff Lawson
|
||||||
Jeff Phillips
|
Jeff Phillips
|
||||||
Jeff Pohlmeyer
|
Jeff Pohlmeyer
|
||||||
Jeff Weber
|
Jeff Weber
|
||||||
Jeffrey Pohlmeyer
|
Jeffrey Pohlmeyer
|
||||||
Jeremy Friesner
|
Jeremy Friesner
|
||||||
|
Jeremy Huddleston
|
||||||
Jerome Muffat-Meridol
|
Jerome Muffat-Meridol
|
||||||
Jerome Vouillon
|
Jerome Vouillon
|
||||||
|
Jerry Krinock
|
||||||
Jerry Wu
|
Jerry Wu
|
||||||
Jes Badwal
|
Jes Badwal
|
||||||
Jesper Jensen
|
Jesper Jensen
|
||||||
@@ -449,8 +496,8 @@ Jim Drash
|
|||||||
Jim Freeman
|
Jim Freeman
|
||||||
Jim Hollinger
|
Jim Hollinger
|
||||||
Jim Meyering
|
Jim Meyering
|
||||||
Jiri Jaburek
|
|
||||||
Jiri Hruska
|
Jiri Hruska
|
||||||
|
Jiri Jaburek
|
||||||
Jocelyn Jaubert
|
Jocelyn Jaubert
|
||||||
Joe Halpin
|
Joe Halpin
|
||||||
Joe Malicki
|
Joe Malicki
|
||||||
@@ -464,7 +511,9 @@ Johannes Bauer
|
|||||||
John Bradshaw
|
John Bradshaw
|
||||||
John Crow
|
John Crow
|
||||||
John Dennis
|
John Dennis
|
||||||
|
John Dunn
|
||||||
John E. Malmberg
|
John E. Malmberg
|
||||||
|
John Gardiner Myers
|
||||||
John Janssen
|
John Janssen
|
||||||
John Joseph Bachir
|
John Joseph Bachir
|
||||||
John Kelly
|
John Kelly
|
||||||
@@ -506,6 +555,7 @@ Julien Royer
|
|||||||
Jun-ichiro itojun Hagino
|
Jun-ichiro itojun Hagino
|
||||||
Jurij Smakov
|
Jurij Smakov
|
||||||
Justin Fletcher
|
Justin Fletcher
|
||||||
|
Justin Karneges
|
||||||
Jörg Mueller-Tolk
|
Jörg Mueller-Tolk
|
||||||
Jörn Hartroth
|
Jörn Hartroth
|
||||||
Kai Engert
|
Kai Engert
|
||||||
@@ -534,15 +584,18 @@ Kevin Lussier
|
|||||||
Kevin Reed
|
Kevin Reed
|
||||||
Kevin Roth
|
Kevin Roth
|
||||||
Kim Rinnewitz
|
Kim Rinnewitz
|
||||||
|
Kim Vandry
|
||||||
Kimmo Kinnunen
|
Kimmo Kinnunen
|
||||||
Kjell Ericson
|
Kjell Ericson
|
||||||
Kjetil Jacobsen
|
Kjetil Jacobsen
|
||||||
Klevtsov Vadim
|
Klevtsov Vadim
|
||||||
|
Konstantin Isakov
|
||||||
Kris Kennaway
|
Kris Kennaway
|
||||||
Krishnendu Majumdar
|
Krishnendu Majumdar
|
||||||
Krister Johansen
|
Krister Johansen
|
||||||
Kristian Gunstone
|
Kristian Gunstone
|
||||||
Kristian Köhntopp
|
Kristian Köhntopp
|
||||||
|
Kyle L. Huff
|
||||||
Kyle Sallee
|
Kyle Sallee
|
||||||
Lachlan O'Dea
|
Lachlan O'Dea
|
||||||
Larry Campbell
|
Larry Campbell
|
||||||
@@ -550,6 +603,7 @@ Larry Fahnoe
|
|||||||
Lars Buitinck
|
Lars Buitinck
|
||||||
Lars Gustafsson
|
Lars Gustafsson
|
||||||
Lars J. Aas
|
Lars J. Aas
|
||||||
|
Lars Johannesen
|
||||||
Lars Nilsson
|
Lars Nilsson
|
||||||
Lars Torben Wilson
|
Lars Torben Wilson
|
||||||
Lau Hang Kin
|
Lau Hang Kin
|
||||||
@@ -572,6 +626,7 @@ Loren Kirkby
|
|||||||
Luca Altea
|
Luca Altea
|
||||||
Luca Alteas
|
Luca Alteas
|
||||||
Lucas Adamski
|
Lucas Adamski
|
||||||
|
Ludovico Cavedon
|
||||||
Lukasz Czekierda
|
Lukasz Czekierda
|
||||||
Luke Amery
|
Luke Amery
|
||||||
Luke Call
|
Luke Call
|
||||||
@@ -583,12 +638,15 @@ Mandy Wu
|
|||||||
Manfred Schwarb
|
Manfred Schwarb
|
||||||
Manuel Massing
|
Manuel Massing
|
||||||
Marc Boucher
|
Marc Boucher
|
||||||
|
Marc Deslauriers
|
||||||
|
Marc Doughty
|
||||||
Marc Hoersken
|
Marc Hoersken
|
||||||
Marc Kleine-Budde
|
Marc Kleine-Budde
|
||||||
Marcel Raad
|
Marcel Raad
|
||||||
Marcel Roelofs
|
Marcel Roelofs
|
||||||
Marcelo Juchem
|
Marcelo Juchem
|
||||||
Marcin Adamski
|
Marcin Adamski
|
||||||
|
Marcin Gryszkalis
|
||||||
Marcin Konicki
|
Marcin Konicki
|
||||||
Marco G. Salvagno
|
Marco G. Salvagno
|
||||||
Marco Maggi
|
Marco Maggi
|
||||||
@@ -614,6 +672,7 @@ Martin C. Martin
|
|||||||
Martin Drasar
|
Martin Drasar
|
||||||
Martin Hager
|
Martin Hager
|
||||||
Martin Hedenfalk
|
Martin Hedenfalk
|
||||||
|
Martin Jansen
|
||||||
Martin Lemke
|
Martin Lemke
|
||||||
Martin Skinner
|
Martin Skinner
|
||||||
Martin Storsjo
|
Martin Storsjo
|
||||||
@@ -642,6 +701,7 @@ Maxim Prohorov
|
|||||||
Maxime Larocque
|
Maxime Larocque
|
||||||
Mehmet Bozkurt
|
Mehmet Bozkurt
|
||||||
Mekonikum
|
Mekonikum
|
||||||
|
Melissa Mears
|
||||||
Mettgut Jamalla
|
Mettgut Jamalla
|
||||||
Michael Benedict
|
Michael Benedict
|
||||||
Michael Calmer
|
Michael Calmer
|
||||||
@@ -653,6 +713,7 @@ Michael Jahn
|
|||||||
Michael Jerris
|
Michael Jerris
|
||||||
Michael Mealling
|
Michael Mealling
|
||||||
Michael Mueller
|
Michael Mueller
|
||||||
|
Michael Osipov
|
||||||
Michael Smith
|
Michael Smith
|
||||||
Michael Stillwell
|
Michael Stillwell
|
||||||
Michael Wallner
|
Michael Wallner
|
||||||
@@ -661,13 +722,16 @@ Michal Gorny
|
|||||||
Michal Kowalczyk
|
Michal Kowalczyk
|
||||||
Michal Marek
|
Michal Marek
|
||||||
Michele Bini
|
Michele Bini
|
||||||
|
Miguel Angel
|
||||||
Mihai Ionescu
|
Mihai Ionescu
|
||||||
Mikael Johansson
|
Mikael Johansson
|
||||||
Mikael Sennerholm
|
Mikael Sennerholm
|
||||||
Mike Bytnar
|
Mike Bytnar
|
||||||
Mike Crowe
|
Mike Crowe
|
||||||
Mike Dobbs
|
Mike Dobbs
|
||||||
|
Mike Giancola
|
||||||
Mike Hommey
|
Mike Hommey
|
||||||
|
Mike Mio
|
||||||
Mike Power
|
Mike Power
|
||||||
Mike Protts
|
Mike Protts
|
||||||
Mike Revi
|
Mike Revi
|
||||||
@@ -676,6 +740,8 @@ Mitz Wark
|
|||||||
Mohamed Lrhazi
|
Mohamed Lrhazi
|
||||||
Mohun Biswas
|
Mohun Biswas
|
||||||
Moonesamy
|
Moonesamy
|
||||||
|
Myk Taylor
|
||||||
|
Nach M. S.
|
||||||
Nathan Coulter
|
Nathan Coulter
|
||||||
Nathan O'Sullivan
|
Nathan O'Sullivan
|
||||||
Nathanael Nerode
|
Nathanael Nerode
|
||||||
@@ -709,6 +775,8 @@ Ofer
|
|||||||
Olaf Flebbe
|
Olaf Flebbe
|
||||||
Olaf Stueben
|
Olaf Stueben
|
||||||
Olaf Stüben
|
Olaf Stüben
|
||||||
|
Oliver Gondža
|
||||||
|
Oliver Kuckertz
|
||||||
Olivier Berger
|
Olivier Berger
|
||||||
Oren Tirosh
|
Oren Tirosh
|
||||||
Ori Avtalion
|
Ori Avtalion
|
||||||
@@ -720,14 +788,17 @@ Pascal Terjan
|
|||||||
Pasha Kuznetsov
|
Pasha Kuznetsov
|
||||||
Pat Ray
|
Pat Ray
|
||||||
Patrice Guerin
|
Patrice Guerin
|
||||||
|
Patricia Muscalu
|
||||||
Patrick Bihan-Faou
|
Patrick Bihan-Faou
|
||||||
Patrick Monnerat
|
Patrick Monnerat
|
||||||
Patrick Scott
|
Patrick Scott
|
||||||
Patrick Smith
|
Patrick Smith
|
||||||
Patrik Thunstrom
|
Patrik Thunstrom
|
||||||
Pau Garcia i Quiles
|
Pau Garcia i Quiles
|
||||||
|
Paul Donohue
|
||||||
Paul Harrington
|
Paul Harrington
|
||||||
Paul Howarth
|
Paul Howarth
|
||||||
|
Paul Marks
|
||||||
Paul Marquis
|
Paul Marquis
|
||||||
Paul Moore
|
Paul Moore
|
||||||
Paul Nolan
|
Paul Nolan
|
||||||
@@ -742,6 +813,7 @@ Pedro Neves
|
|||||||
Pete Su
|
Pete Su
|
||||||
Peter Bray
|
Peter Bray
|
||||||
Peter Forret
|
Peter Forret
|
||||||
|
Peter Gal
|
||||||
Peter Heuchert
|
Peter Heuchert
|
||||||
Peter Hjalmarsson
|
Peter Hjalmarsson
|
||||||
Peter Korsgaard
|
Peter Korsgaard
|
||||||
@@ -755,6 +827,8 @@ Peter Todd
|
|||||||
Peter Verhas
|
Peter Verhas
|
||||||
Peter Wullinger
|
Peter Wullinger
|
||||||
Peteris Krumins
|
Peteris Krumins
|
||||||
|
Petr Bahula
|
||||||
|
Petr Pisar
|
||||||
Phil Blundell
|
Phil Blundell
|
||||||
Phil Karn
|
Phil Karn
|
||||||
Phil Lisiecki
|
Phil Lisiecki
|
||||||
@@ -779,6 +853,7 @@ Quinn Slack
|
|||||||
Rafa Muyo
|
Rafa Muyo
|
||||||
Rafael Sagula
|
Rafael Sagula
|
||||||
Rainer Canavan
|
Rainer Canavan
|
||||||
|
Rainer Jung
|
||||||
Rainer Koenig
|
Rainer Koenig
|
||||||
Rajesh Naganathan
|
Rajesh Naganathan
|
||||||
Ralf S. Engelschall
|
Ralf S. Engelschall
|
||||||
@@ -793,6 +868,7 @@ Reinout van Schouwen
|
|||||||
Renato Botelho
|
Renato Botelho
|
||||||
Renaud Chaillat
|
Renaud Chaillat
|
||||||
Renaud Duhaut
|
Renaud Duhaut
|
||||||
|
Renaud Guillard
|
||||||
Rene Bernhardt
|
Rene Bernhardt
|
||||||
Rene Rebe
|
Rene Rebe
|
||||||
Reuven Wachtfogel
|
Reuven Wachtfogel
|
||||||
@@ -806,6 +882,7 @@ Richard Bramante
|
|||||||
Richard Clayton
|
Richard Clayton
|
||||||
Richard Cooper
|
Richard Cooper
|
||||||
Richard Gorton
|
Richard Gorton
|
||||||
|
Richard Michael
|
||||||
Richard Prescott
|
Richard Prescott
|
||||||
Richard Silverman
|
Richard Silverman
|
||||||
Rick Jones
|
Rick Jones
|
||||||
@@ -822,6 +899,7 @@ Robert Iakobashvili
|
|||||||
Robert Olson
|
Robert Olson
|
||||||
Robert Schumann
|
Robert Schumann
|
||||||
Robert Weaver
|
Robert Weaver
|
||||||
|
Robert Wruck
|
||||||
Robin Cornelius
|
Robin Cornelius
|
||||||
Robin Johnson
|
Robin Johnson
|
||||||
Robin Kay
|
Robin Kay
|
||||||
@@ -834,6 +912,7 @@ Roland Zimmermann
|
|||||||
Rolland Dudemaine
|
Rolland Dudemaine
|
||||||
Roman Koifman
|
Roman Koifman
|
||||||
Roman Mamedov
|
Roman Mamedov
|
||||||
|
Romulo A. Ceccon
|
||||||
Ron Zapp
|
Ron Zapp
|
||||||
Rosimildo da Silva
|
Rosimildo da Silva
|
||||||
Roy Shan
|
Roy Shan
|
||||||
@@ -843,9 +922,11 @@ Rutger Hofman
|
|||||||
Ryan Chan
|
Ryan Chan
|
||||||
Ryan Nelson
|
Ryan Nelson
|
||||||
Ryan Schmidt
|
Ryan Schmidt
|
||||||
|
Rémy Léone
|
||||||
S. Moonesamy
|
S. Moonesamy
|
||||||
Salvador Dávila
|
Salvador Dávila
|
||||||
Salvatore Sorrentino
|
Salvatore Sorrentino
|
||||||
|
Sam Deane
|
||||||
Sam Listopad
|
Sam Listopad
|
||||||
Sampo Kellomaki
|
Sampo Kellomaki
|
||||||
Samuel Díaz García
|
Samuel Díaz García
|
||||||
@@ -856,6 +937,7 @@ Sandor Feldi
|
|||||||
Santhana Todatry
|
Santhana Todatry
|
||||||
Saqib Ali
|
Saqib Ali
|
||||||
Sara Golemon
|
Sara Golemon
|
||||||
|
Saran Neti
|
||||||
Saul good
|
Saul good
|
||||||
Scott Bailey
|
Scott Bailey
|
||||||
Scott Barrett
|
Scott Barrett
|
||||||
@@ -866,11 +948,13 @@ Sebastian Rasmussen
|
|||||||
Sebastien Willemijns
|
Sebastien Willemijns
|
||||||
Senthil Raja Velu
|
Senthil Raja Velu
|
||||||
Sergei Nikulov
|
Sergei Nikulov
|
||||||
|
Sergey Tatarincev
|
||||||
Sergio Ballestrero
|
Sergio Ballestrero
|
||||||
Seshubabu Pasam
|
Seshubabu Pasam
|
||||||
Sh Diao
|
Sh Diao
|
||||||
Sharad Gupta
|
Sharad Gupta
|
||||||
Shard
|
Shard
|
||||||
|
Shawn Landden
|
||||||
Shawn Poulson
|
Shawn Poulson
|
||||||
Shmulik Regev
|
Shmulik Regev
|
||||||
Siddhartha Prakash Jain
|
Siddhartha Prakash Jain
|
||||||
@@ -888,6 +972,7 @@ Stan van de Burgt
|
|||||||
Stanislav Ivochkin
|
Stanislav Ivochkin
|
||||||
Stefan Esser
|
Stefan Esser
|
||||||
Stefan Krause
|
Stefan Krause
|
||||||
|
Stefan Neis
|
||||||
Stefan Teleman
|
Stefan Teleman
|
||||||
Stefan Tomanek
|
Stefan Tomanek
|
||||||
Stefan Ulrich
|
Stefan Ulrich
|
||||||
@@ -906,6 +991,7 @@ Steve Oliphant
|
|||||||
Steve Roskowski
|
Steve Roskowski
|
||||||
Steven Bazyl
|
Steven Bazyl
|
||||||
Steven G. Johnson
|
Steven G. Johnson
|
||||||
|
Steven Gu
|
||||||
Steven M. Schweda
|
Steven M. Schweda
|
||||||
Steven Parkes
|
Steven Parkes
|
||||||
Stoned Elipot
|
Stoned Elipot
|
||||||
@@ -934,6 +1020,7 @@ Tim Harder
|
|||||||
Tim Heckman
|
Tim Heckman
|
||||||
Tim Newsome
|
Tim Newsome
|
||||||
Tim Sneddon
|
Tim Sneddon
|
||||||
|
Timo Sirainen
|
||||||
Tinus van den Berg
|
Tinus van den Berg
|
||||||
Tobias Rundström
|
Tobias Rundström
|
||||||
Toby Peterson
|
Toby Peterson
|
||||||
@@ -943,6 +1030,7 @@ Todd Ouska
|
|||||||
Todd Vierling
|
Todd Vierling
|
||||||
Tom Benoist
|
Tom Benoist
|
||||||
Tom Donovan
|
Tom Donovan
|
||||||
|
Tom Grace
|
||||||
Tom Lee
|
Tom Lee
|
||||||
Tom Mattison
|
Tom Mattison
|
||||||
Tom Moers
|
Tom Moers
|
||||||
@@ -950,6 +1038,7 @@ Tom Mueller
|
|||||||
Tom Regner
|
Tom Regner
|
||||||
Tom Wright
|
Tom Wright
|
||||||
Tom Zerucha
|
Tom Zerucha
|
||||||
|
Tomas Hoger
|
||||||
Tomas Mlcoch
|
Tomas Mlcoch
|
||||||
Tomas Pospisek
|
Tomas Pospisek
|
||||||
Tomas Szepe
|
Tomas Szepe
|
||||||
@@ -967,7 +1056,9 @@ Traian Nicolescu
|
|||||||
Troels Walsted Hansen
|
Troels Walsted Hansen
|
||||||
Troy Engel
|
Troy Engel
|
||||||
Tupone Alfredo
|
Tupone Alfredo
|
||||||
|
Tyler Hall
|
||||||
Ulf Härnhammar
|
Ulf Härnhammar
|
||||||
|
Ulf Samuelsson
|
||||||
Ulrich Doehner
|
Ulrich Doehner
|
||||||
Ulrich Zadow
|
Ulrich Zadow
|
||||||
Venkat Akella
|
Venkat Akella
|
||||||
@@ -994,16 +1085,24 @@ Wesley Laxton
|
|||||||
Wesley Miaw
|
Wesley Miaw
|
||||||
Wez Furlong
|
Wez Furlong
|
||||||
Wilfredo Sanchez
|
Wilfredo Sanchez
|
||||||
|
Will Dietz
|
||||||
|
Willem Sparreboom
|
||||||
Wojciech Zwiefka
|
Wojciech Zwiefka
|
||||||
|
Wouter Van Rooy
|
||||||
Wu Yongzheng
|
Wu Yongzheng
|
||||||
Xavier Bouchoux
|
Xavier Bouchoux
|
||||||
|
Yaakov Selkowitz
|
||||||
|
Yamada Yasuharu
|
||||||
Yang Tse
|
Yang Tse
|
||||||
Yarram Sunil
|
Yarram Sunil
|
||||||
Yehoshua Hershberg
|
Yehoshua Hershberg
|
||||||
|
Yi Huang
|
||||||
Yukihiro Kawada
|
Yukihiro Kawada
|
||||||
Yuriy Sosov
|
Yuriy Sosov
|
||||||
Yves Arrouye
|
Yves Arrouye
|
||||||
Yves Lejeune
|
Yves Lejeune
|
||||||
|
Zdenek Pavlas
|
||||||
|
Zekun Ni
|
||||||
Zmey Petroff
|
Zmey Petroff
|
||||||
Zvi Har'El
|
Zvi Har'El
|
||||||
nk
|
nk
|
||||||
|
|||||||
142
docs/TODO
142
docs/TODO
@@ -16,8 +16,7 @@
|
|||||||
1.3 struct lifreq
|
1.3 struct lifreq
|
||||||
1.4 signal-based resolver timeouts
|
1.4 signal-based resolver timeouts
|
||||||
1.5 get rid of PATH_MAX
|
1.5 get rid of PATH_MAX
|
||||||
1.6 progress callback without doubles
|
1.6 Modified buffer size approach
|
||||||
1.7 Happy Eyeball dual stack connect
|
|
||||||
|
|
||||||
2. libcurl - multi interface
|
2. libcurl - multi interface
|
||||||
2.1 More non-blocking
|
2.1 More non-blocking
|
||||||
@@ -38,6 +37,8 @@
|
|||||||
5.1 Better persistency for HTTP 1.0
|
5.1 Better persistency for HTTP 1.0
|
||||||
5.2 support FF3 sqlite cookie files
|
5.2 support FF3 sqlite cookie files
|
||||||
5.3 Rearrange request header order
|
5.3 Rearrange request header order
|
||||||
|
5.4 HTTP2/SPDY
|
||||||
|
5.5 auth= in URLs
|
||||||
|
|
||||||
6. TELNET
|
6. TELNET
|
||||||
6.1 ditch stdin
|
6.1 ditch stdin
|
||||||
@@ -46,19 +47,15 @@
|
|||||||
6.4 send data in chunks
|
6.4 send data in chunks
|
||||||
|
|
||||||
7. SMTP
|
7. SMTP
|
||||||
7.1 Specify the preferred authentication mechanism
|
7.1 Pipelining
|
||||||
7.2 Initial response
|
7.2 Enhanced capability support
|
||||||
7.3 Pipelining
|
|
||||||
7.4 Graceful base64 decoding failure
|
|
||||||
|
|
||||||
8. POP3
|
8. POP3
|
||||||
8.1 auth= in URLs
|
8.1 Pipelining
|
||||||
8.2 Initial response
|
8.2 Enhanced capability support
|
||||||
8.3 Graceful base64 decoding failure
|
|
||||||
|
|
||||||
9. IMAP
|
9. IMAP
|
||||||
9.1 auth= in URLs
|
9.1 Enhanced capability support
|
||||||
9.2 Graceful base64 decoding failure
|
|
||||||
|
|
||||||
10. LDAP
|
10. LDAP
|
||||||
10.1 SASL based authentication mechanisms
|
10.1 SASL based authentication mechanisms
|
||||||
@@ -157,26 +154,27 @@
|
|||||||
we need libssh2 to properly tell us when we pass in a too small buffer and
|
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.
|
its current API (as of libssh2 1.2.7) doesn't.
|
||||||
|
|
||||||
1.6 progress callback without doubles
|
1.6 Modified buffer size approach
|
||||||
|
|
||||||
The progress callback was introduced way back in the days and the choice to
|
Current libcurl allocates a fixed 16K size buffer for download and an
|
||||||
use doubles in the arguments was possibly good at the time. Today the doubles
|
additional 16K for upload. They are always unconditionally part of the easy
|
||||||
only confuse users and make the amounts less precise. We should introduce
|
handle. If CRLF translations are requested, an additional 32K "scratch
|
||||||
another progress callback option that take precedence over the old one and
|
buffer" is allocated. A total of 64K transfer buffers in the worst case.
|
||||||
have both co-exist for a forseeable time until we can remove the double-using
|
|
||||||
one.
|
|
||||||
|
|
||||||
1.7 Happy Eyeball dual stack connect
|
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.
|
||||||
|
|
||||||
In order to make alternative technologies not suffer when transitioning, like
|
Secondly, SFTP is a protocol that needs to handle many ~30K blocks at once
|
||||||
when introducing IPv6 as an alternative to IPv4 and there are more than one
|
since each need to be individually acked and therefore libssh2 must be
|
||||||
option existing simultaneously there are reasons to reconsider internal
|
allowed to send (or receive) many separate ones in parallel to achieve high
|
||||||
choices.
|
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.
|
||||||
|
|
||||||
To make libcurl do blazing fast IPv6 in a dual-stack configuration, this needs
|
Dynamically allocate buffer size depending on protocol in use in combination
|
||||||
to be addressed:
|
with freeing it after each individual transfer? Other suggestions?
|
||||||
|
|
||||||
http://tools.ietf.org/html/rfc6555
|
|
||||||
|
|
||||||
2. libcurl - multi interface
|
2. libcurl - multi interface
|
||||||
|
|
||||||
@@ -269,6 +267,36 @@
|
|||||||
headers use a default value so only headers that need to be moved have to be
|
headers use a default value so only headers that need to be moved have to be
|
||||||
specified.
|
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.
|
||||||
|
|
||||||
|
5.5 auth= in URLs
|
||||||
|
|
||||||
|
Add the ability to specify the preferred authentication mechanism to use by
|
||||||
|
using ;auth=<mech> in the login part of the URL.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
http://test:pass;auth=NTLM@example.com would be equivalent to specifing --user
|
||||||
|
test:pass;auth=NTLM or --user test:pass --ntlm from the command line.
|
||||||
|
|
||||||
|
Additionally this should be implemented for proxy base URLs as well.
|
||||||
|
|
||||||
6. TELNET
|
6. TELNET
|
||||||
|
|
||||||
6.1 ditch stdin
|
6.1 ditch stdin
|
||||||
@@ -295,64 +323,32 @@ to provide the data to send.
|
|||||||
|
|
||||||
7. SMTP
|
7. SMTP
|
||||||
|
|
||||||
7.1 Specify the preferred authentication mechanism
|
7.1 Pipelining
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
Add support for pipelining emails.
|
Add support for pipelining emails.
|
||||||
|
|
||||||
7.4 Graceful base64 decoding failure
|
7.2 Enhanced capability support
|
||||||
|
|
||||||
Rather than shutting down the session and returning an error when the
|
Add the ability, for an application that uses libcurl, to obtain the list of
|
||||||
decoding of a base64 encoded authentication response fails, we should
|
capabilities returned from the EHLO command.
|
||||||
gracefully shutdown the authentication process by sending a * response to the
|
|
||||||
server as per RFC4954.
|
|
||||||
|
|
||||||
8. POP3
|
8. POP3
|
||||||
|
|
||||||
8.1 auth= in URLs
|
8.1 Pipelining
|
||||||
|
|
||||||
Being able to specify the preferred authentication mechanism in the URL as
|
Add support for pipelining commands.
|
||||||
per RFC2384.
|
|
||||||
|
|
||||||
8.2 Initial response
|
8.2 Enhanced capability support
|
||||||
|
|
||||||
Add the ability for the user to specify whether the initial response is
|
Add the ability, for an application that uses libcurl, to obtain the list of
|
||||||
included in the AUTH command as per RFC5034.
|
capabilities returned from the CAPA command.
|
||||||
|
|
||||||
8.3 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.
|
|
||||||
|
|
||||||
9. IMAP
|
9. IMAP
|
||||||
|
|
||||||
9.1 auth= in URLs
|
9.1 Enhanced capability support
|
||||||
|
|
||||||
Being able to specify the preferred authentication mechanism in the URL as
|
Add the ability, for an application that uses libcurl, to obtain the list of
|
||||||
per RFC5092.
|
capabilities returned from the CAPABILITY command.
|
||||||
|
|
||||||
9.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 RFC3501.
|
|
||||||
|
|
||||||
10. LDAP
|
10. LDAP
|
||||||
|
|
||||||
@@ -429,6 +425,12 @@ to provide the data to send.
|
|||||||
keys and certs over DNS using DNSSEC as an alternative to the CA model.
|
keys and certs over DNS using DNSSEC as an alternative to the CA model.
|
||||||
http://www.rfc-editor.org/rfc/rfc6698.txt
|
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. GnuTLS
|
||||||
|
|
||||||
13.1 SSL engine stuff
|
13.1 SSL engine stuff
|
||||||
|
|||||||
264
docs/curl.1
264
docs/curl.1
@@ -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
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
.\" * you should have received as part of this distribution. The terms
|
.\" * 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
|
If you prefer a progress "bar" instead of the regular meter, \fI-#\fP is your
|
||||||
friend.
|
friend.
|
||||||
.SH OPTIONS
|
.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
|
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
|
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
|
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,
|
Make curl display progress as a simple progress bar instead of the standard,
|
||||||
more informational, meter.
|
more informational, meter.
|
||||||
.IP "-0, --http1.0"
|
.IP "-0, --http1.0"
|
||||||
(HTTP) Forces curl to issue its requests using HTTP 1.0 instead of using its
|
(HTTP) Tells curl to use HTTP version 1.0 instead of using its internally
|
||||||
internally preferred: HTTP 1.1.
|
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"
|
.IP "-1, --tlsv1"
|
||||||
(SSL)
|
(SSL)
|
||||||
Forces curl to use TLS version 1 when negotiating with a remote TLS server.
|
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>"
|
.IP "--connect-timeout <seconds>"
|
||||||
Maximum time in seconds that you allow the connection to the server to take.
|
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
|
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.
|
If this option is used several times, the last one will be used.
|
||||||
.IP "--create-dirs"
|
.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
|
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
|
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
|
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>"
|
.IP "-D, --dump-header <file>"
|
||||||
Write the protocol headers to the specified 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
|
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
|
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
|
If this option is used several times, the ones following the first will append
|
||||||
data as described in \fI-d, --data\fP.
|
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
|
Disabling EPSV only changes the passive behavior. If you want to switch to
|
||||||
active mode you need to use \fI-P, --ftp-port\fP.
|
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>"
|
.IP "-e, --referer <URL>"
|
||||||
(HTTP) Sends the "Referer Page" information to the HTTP server. This can also
|
(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
|
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]>"
|
.IP "-E, --cert <certificate[:password]>"
|
||||||
(SSL) Tells curl to use the specified client certificate file when getting a
|
(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
|
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
|
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
|
is the private key and the private certificate concatenated! See \fI--cert\fP
|
||||||
and \fI--key\fP to specify them independently.
|
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
|
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
|
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
|
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.
|
If this option is used several times, the last one will be used.
|
||||||
.IP "--engine <name>"
|
.IP "--engine <name>"
|
||||||
@@ -582,10 +646,10 @@ you can specify URLs that contain the letters {}[] without having them being
|
|||||||
interpreted by curl itself. Note that these letters are not normal legal URL
|
interpreted by curl itself. Note that these letters are not normal legal URL
|
||||||
contents but they should be encoded according to the URI standard.
|
contents but they should be encoded according to the URI standard.
|
||||||
.IP "-G, --get"
|
.IP "-G, --get"
|
||||||
When used, this option will make all data specified with \fI-d, --data\fP or
|
When used, this option will make all data specified with \fI-d, --data\fP,
|
||||||
\fI--data-binary\fP to be used in an HTTP GET request instead of the POST
|
\fI--data-binary\fP or \fI--data-urlencode\fP to be used in an HTTP GET
|
||||||
request that otherwise would be used. The data will be appended to the URL
|
request instead of the POST request that otherwise would be used. The data
|
||||||
with a '?' separator.
|
will be appended to the URL with a '?' separator.
|
||||||
|
|
||||||
If used in combination with -I, the POST data will instead be appended to the
|
If used in combination with -I, the POST data will instead be appended to the
|
||||||
URL with a HEAD request.
|
URL with a HEAD request.
|
||||||
@@ -647,6 +711,9 @@ cookies when they're closed down.
|
|||||||
(HTTP) This option tells the \fI-O, --remote-name\fP option to use the
|
(HTTP) This option tells the \fI-O, --remote-name\fP option to use the
|
||||||
server-specified Content-Disposition filename instead of extracting a filename
|
server-specified Content-Disposition filename instead of extracting a filename
|
||||||
from the URL.
|
from the URL.
|
||||||
|
|
||||||
|
There's no attempt to decode %-sequences (yet) in the provided file name, so
|
||||||
|
this option may provide you with rather unexpected file names.
|
||||||
.IP "-k, --insecure"
|
.IP "-k, --insecure"
|
||||||
(SSL) This option explicitly allows curl to perform "insecure" SSL connections
|
(SSL) This option explicitly allows curl to perform "insecure" SSL connections
|
||||||
and transfers. All SSL connections are attempted to be made secure by using
|
and transfers. All SSL connections are attempted to be made secure by using
|
||||||
@@ -658,16 +725,21 @@ See this online resource for further details:
|
|||||||
.IP "-K, --config <config file>"
|
.IP "-K, --config <config file>"
|
||||||
Specify which config file to read curl arguments from. The config file is a
|
Specify which config file to read curl arguments from. The config file is a
|
||||||
text file in which command line arguments can be written which then will be
|
text file in which command line arguments can be written which then will be
|
||||||
used as if they were written on the actual command line. Options and their
|
used as if they were written on the actual command line.
|
||||||
parameters must be specified on the same config file line, separated by
|
|
||||||
whitespace, colon, the equals sign or any combination thereof (however,
|
Options and their parameters must be specified on the same config file line,
|
||||||
the preferred separator is the equals sign). If the parameter is to contain
|
separated by whitespace, colon, or the equals sign. Long option names can
|
||||||
whitespace, the parameter must be enclosed within quotes. Within double
|
optionally be given in the config file without the initial double dashes and
|
||||||
quotes, the following escape sequences are available: \\\\, \\", \\t, \\n,
|
if so, the colon or equals characters can be used as separators. If the option
|
||||||
\\r and \\v. A backslash preceding any other letter is ignored. If the
|
is specified with one or two dashes, there can be no colon or equals character
|
||||||
first column of a config line is a '#' character, the rest of the line will be
|
between the option and its parameter.
|
||||||
treated as a comment. Only write one option per physical line in the config
|
|
||||||
file.
|
If the parameter is to contain whitespace, the parameter must be enclosed
|
||||||
|
within quotes. Within double quotes, the following escape sequences are
|
||||||
|
available: \\\\, \\", \\t, \\n, \\r and \\v. A backslash preceding any other
|
||||||
|
letter is ignored. If the first column of a config line is a '#' character,
|
||||||
|
the rest of the line will be treated as a comment. Only write one option per
|
||||||
|
physical line in the config file.
|
||||||
|
|
||||||
Specify the filename to -K, --config as '-' to make curl read the file from
|
Specify the filename to -K, --config as '-' to make curl read the file from
|
||||||
stdin.
|
stdin.
|
||||||
@@ -678,9 +750,6 @@ line. So, it could look similar to this:
|
|||||||
|
|
||||||
url = "http://curl.haxx.se/docs/"
|
url = "http://curl.haxx.se/docs/"
|
||||||
|
|
||||||
Long option names can optionally be given in the config file without the
|
|
||||||
initial double dashes.
|
|
||||||
|
|
||||||
When curl is invoked, it always (unless \fI-q\fP is used) checks for a default
|
When curl is invoked, it always (unless \fI-q\fP is used) checks for a default
|
||||||
config file and uses it if found. The default config file is checked for in
|
config file and uses it if found. The default config file is checked for in
|
||||||
the following places in this order:
|
the following places in this order:
|
||||||
@@ -742,15 +811,23 @@ see if your curl supports it.
|
|||||||
If this option is used several times, the last one will be used.
|
If this option is used several times, the last one will be used.
|
||||||
.IP "-l, --list-only"
|
.IP "-l, --list-only"
|
||||||
(FTP)
|
(FTP)
|
||||||
When listing an FTP directory, this switch forces a name-only view.
|
When listing an FTP directory, this switch forces a name-only view. This is
|
||||||
Especially useful if you want to machine-parse the contents of an FTP
|
especially useful if the user wants to machine-parse the contents of an FTP
|
||||||
directory since the normal directory view doesn't use a standard look
|
directory since the normal directory view doesn't use a standard look or
|
||||||
or format.
|
format. When used like this, the option causes a NLST command to be sent to
|
||||||
|
the server instead of LIST.
|
||||||
|
|
||||||
This option causes an FTP NLST command to be sent. Some FTP servers
|
Note: Some FTP servers list only files in their response to NLST; they do not
|
||||||
list only files in their response to NLST; they do not include
|
include sub-directories and symbolic links.
|
||||||
subdirectories and symbolic links.
|
|
||||||
|
|
||||||
|
(POP3)
|
||||||
|
When retrieving a specific email from POP3, this switch forces a LIST command
|
||||||
|
to be performed instead of RETR. This is particularly useful if the user wants
|
||||||
|
to see if a specific message id exists on the server and what size it is.
|
||||||
|
|
||||||
|
Note: When combined with \fI-X, --request <command>\fP, this option can be used
|
||||||
|
to send an UIDL command instead, so the user may use the email's unique
|
||||||
|
identifier rather than it's message id to make the request. (Added in 7.21.5)
|
||||||
.IP "-L, --location"
|
.IP "-L, --location"
|
||||||
(HTTP/HTTPS) If the server reports that the requested page has moved to a
|
(HTTP/HTTPS) If the server reports that the requested page has moved to a
|
||||||
different location (indicated with a Location: header and a 3XX response code),
|
different location (indicated with a Location: header and a 3XX response code),
|
||||||
@@ -805,7 +882,10 @@ Basic authentication).
|
|||||||
.IP "-m, --max-time <seconds>"
|
.IP "-m, --max-time <seconds>"
|
||||||
Maximum time in seconds that you allow the whole operation to take. This is
|
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
|
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.
|
If this option is used several times, the last one will be used.
|
||||||
.IP "--mail-auth <address>"
|
.IP "--mail-auth <address>"
|
||||||
@@ -827,10 +907,18 @@ return with exit code 63.
|
|||||||
files this option has no effect even if the file transfer ends up being larger
|
files this option has no effect even if the file transfer ends up being larger
|
||||||
than this given limit. This concerns both FTP and HTTP transfers.
|
than this given limit. This concerns both FTP and HTTP transfers.
|
||||||
.IP "--mail-rcpt <address>"
|
.IP "--mail-rcpt <address>"
|
||||||
(SMTP) Specify a single address that the given mail should get sent to. This
|
(SMTP) Specify a single address, user name or mailing list name.
|
||||||
option can be used multiple times to specify many recipients.
|
|
||||||
|
|
||||||
(Added in 7.20.0)
|
When performing a mail transfer, the recipient should specify a valid email
|
||||||
|
address to send the mail to. (Added in 7.20.0)
|
||||||
|
|
||||||
|
When performing an address verification (VRFY command), the recipient should be
|
||||||
|
specified as the user name or user name and domain (as per Section 3.5 of
|
||||||
|
RFC5321). (Added in 7.34.0)
|
||||||
|
|
||||||
|
When performing a mailing list expand (EXPN command), the recipient should be
|
||||||
|
specified using the mailing list name, such as "Friends" or "London-Office".
|
||||||
|
(Added in 7.34.0)
|
||||||
.IP "--max-redirs <num>"
|
.IP "--max-redirs <num>"
|
||||||
Set maximum number of redirection-followings allowed. If \fI-L, --location\fP
|
Set maximum number of redirection-followings allowed. If \fI-L, --location\fP
|
||||||
is used, this option can be used to prevent curl from following redirections
|
is used, this option can be used to prevent curl from following redirections
|
||||||
@@ -986,7 +1074,19 @@ Consequentially, the file will be saved in the current working directory. If
|
|||||||
you want the file saved in a different directory, make sure you change current
|
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!
|
working directory before you invoke curl with the \fB-O, --remote-name\fP flag!
|
||||||
|
|
||||||
|
There is no URL decoding done on the file name. If it has %20 or other URL
|
||||||
|
encoded parts of the name, they will end up as-is as file name.
|
||||||
|
|
||||||
You may use this option as many times as the number of URLs you have.
|
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 conjunction 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"
|
.IP "-p, --proxytunnel"
|
||||||
When an HTTP proxy is used (\fI-x, --proxy\fP), this option will cause non-HTTP
|
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
|
protocols to attempt to tunnel through the proxy instead of merely using it to
|
||||||
@@ -1038,6 +1138,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
|
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
|
a redirection. This option is meaningful only when using \fI-L, --location\fP
|
||||||
(Added in 7.19.1)
|
(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>"
|
.IP "--proto <protocols>"
|
||||||
Tells curl to use the listed protocols for its initial retrieval. 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
|
are evaluated left to right, are comma separated, and are each a protocol
|
||||||
@@ -1272,8 +1379,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.
|
If this option is used several times, the last one will be used.
|
||||||
.IP "-s, --silent"
|
.IP "-s, --silent"
|
||||||
Silent or quiet mode. Don't show progress meter or error messages. Makes
|
Silent or quiet mode. Don't show progress meter or error messages. Makes Curl
|
||||||
Curl mute.
|
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"
|
.IP "-S, --show-error"
|
||||||
When used with \fI-s\fP it makes curl show an error message if it fails.
|
When used with \fI-s\fP it makes curl show an error message if it fails.
|
||||||
.IP "--ssl"
|
.IP "--ssl"
|
||||||
@@ -1412,14 +1523,26 @@ Set TLS authentication type. Currently, the only supported option is "SRP",
|
|||||||
for TLS-SRP (RFC 5054). If \fI--tlsuser\fP and \fI--tlspassword\fP are
|
for TLS-SRP (RFC 5054). If \fI--tlsuser\fP and \fI--tlspassword\fP are
|
||||||
specified but \fI--tlsauthtype\fP is not, then this option defaults to "SRP".
|
specified but \fI--tlsauthtype\fP is not, then this option defaults to "SRP".
|
||||||
(Added in 7.21.4)
|
(Added in 7.21.4)
|
||||||
.IP "--tlsuser <user>"
|
|
||||||
Set username for use with the TLS authentication method specified with
|
|
||||||
\fI--tlsauthtype\fP. Requires that \fI--tlspassword\fP also be set. (Added in
|
|
||||||
7.21.4)
|
|
||||||
.IP "--tlspassword <password>"
|
.IP "--tlspassword <password>"
|
||||||
Set password for use with the TLS authentication method specified with
|
Set password for use with the TLS authentication method specified with
|
||||||
\fI--tlsauthtype\fP. Requires that \fI--tlsuser\fP also be set. (Added in
|
\fI--tlsauthtype\fP. Requires that \fI--tlsuser\fP also be set. (Added in
|
||||||
7.21.4)
|
7.21.4)
|
||||||
|
.IP "--tlsuser <user>"
|
||||||
|
Set username for use with the TLS authentication method specified with
|
||||||
|
\fI--tlsauthtype\fP. Requires that \fI--tlspassword\fP also be set. (Added in
|
||||||
|
7.21.4)
|
||||||
|
.IP "--tlsv1.0"
|
||||||
|
(SSL)
|
||||||
|
Forces curl to use TLS version 1.0 when negotiating with a remote TLS server.
|
||||||
|
(Added in 7.34.0)
|
||||||
|
.IP "--tlsv1.1"
|
||||||
|
(SSL)
|
||||||
|
Forces curl to use TLS version 1.1 when negotiating with a remote TLS server.
|
||||||
|
(Added in 7.34.0)
|
||||||
|
.IP "--tlsv1.2"
|
||||||
|
(SSL)
|
||||||
|
Forces curl to use TLS version 1.2 when negotiating with a remote TLS server.
|
||||||
|
(Added in 7.34.0)
|
||||||
.IP "--tr-encoding"
|
.IP "--tr-encoding"
|
||||||
(HTTP) Request a compressed Transfer-Encoding response using one of the
|
(HTTP) Request a compressed Transfer-Encoding response using one of the
|
||||||
algorithms curl supports, and uncompress the data while receiving it.
|
algorithms curl supports, and uncompress the data while receiving it.
|
||||||
@@ -1449,16 +1572,23 @@ If this option is used several times, the last one will be used.
|
|||||||
.IP "--trace-time"
|
.IP "--trace-time"
|
||||||
Prepends a time stamp to each trace or verbose line that curl displays.
|
Prepends a time stamp to each trace or verbose line that curl displays.
|
||||||
(Added in 7.14.0)
|
(Added in 7.14.0)
|
||||||
.IP "-u, --user <user:password>"
|
.IP "-u, --user <user:password;options>"
|
||||||
Specify the user name and password to use for server authentication. Overrides
|
Specify the user name, password and optional login options to use for server
|
||||||
\fI-n, --netrc\fP and \fI--netrc-optional\fP.
|
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
|
If you simply specify the user name, with or without the login options, curl
|
||||||
a password.
|
will prompt for a password.
|
||||||
|
|
||||||
If you use an SSPI-enabled curl binary and do NTLM authentication, you can
|
If you use an SSPI-enabled curl binary and perform NTLM authentication, you
|
||||||
force curl to pick up the user name and password from your environment by
|
can force curl to select the user name and password from your environment by
|
||||||
simply specifying a single colon with this option: "-u :".
|
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.
|
If this option is used several times, the last one will be used.
|
||||||
.IP "-U, --proxy-user <user:password>"
|
.IP "-U, --proxy-user <user:password>"
|
||||||
@@ -1619,8 +1749,16 @@ to follow location: headers.
|
|||||||
|
|
||||||
If this option is used several times, the last one will be used.
|
If this option is used several times, the last one will be used.
|
||||||
.IP "-x, --proxy <[protocol://][user:password@]proxyhost[:port]>"
|
.IP "-x, --proxy <[protocol://][user:password@]proxyhost[:port]>"
|
||||||
Use the specified HTTP proxy. If the port number is not specified, it is
|
Use the specified proxy.
|
||||||
assumed at port 1080.
|
|
||||||
|
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
|
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
|
use. If there's an environment variable setting a proxy, you can set proxy to
|
||||||
@@ -1639,11 +1777,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 +
|
variables, including the protocol prefix (http://) and the embedded user +
|
||||||
password.
|
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.
|
If this option is used several times, the last one will be used.
|
||||||
.IP "-X, --request <command>"
|
.IP "-X, --request <command>"
|
||||||
(HTTP) Specifies a custom request method to use when communicating with the
|
(HTTP) Specifies a custom request method to use when communicating with the
|
||||||
@@ -1665,11 +1798,20 @@ option.
|
|||||||
Specifies a custom FTP command to use instead of LIST when doing file lists
|
Specifies a custom FTP command to use instead of LIST when doing file lists
|
||||||
with FTP.
|
with FTP.
|
||||||
|
|
||||||
If this option is used several times, the last one will be used.
|
(POP3)
|
||||||
|
Specifies a custom POP3 command to use instead of LIST or RETR. (Added in
|
||||||
|
7.26.0)
|
||||||
|
|
||||||
|
(IMAP)
|
||||||
|
Specifies a custom IMAP command to use insead of LIST. (Added in 7.30.0)
|
||||||
|
|
||||||
|
(SMTP)
|
||||||
|
Specifies a custom SMTP command to use instead of HELP or VRFY. (Added in 7.34.0)
|
||||||
|
|
||||||
|
If this option is used several times, the last one will be used.
|
||||||
.IP "--xattr"
|
.IP "--xattr"
|
||||||
When saving output to a file, this option tells curl to store certain file
|
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
|
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
|
the mime_type attribute. If the file system does not support extended
|
||||||
attributes, a warning is issued.
|
attributes, a warning is issued.
|
||||||
@@ -1689,7 +1831,7 @@ speed-time seconds it gets aborted. speed-time is set with \fI-y\fP and is 30
|
|||||||
if not set.
|
if not set.
|
||||||
|
|
||||||
If this option is used several times, the last one will be used.
|
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
|
(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>
|
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
|
can be all sorts of date strings or if it doesn't match any internal ones, it
|
||||||
@@ -1959,6 +2101,8 @@ RTSP: mismatch of Session Identifiers
|
|||||||
unable to parse FTP file list
|
unable to parse FTP file list
|
||||||
.IP 88
|
.IP 88
|
||||||
FTP chunk callback reported error
|
FTP chunk callback reported error
|
||||||
|
.IP 89
|
||||||
|
No connection available, the session will be queued
|
||||||
.IP XX
|
.IP XX
|
||||||
More error codes will appear here in future releases. The existing ones
|
More error codes will appear here in future releases. The existing ones
|
||||||
are meant to never change.
|
are meant to never change.
|
||||||
|
|||||||
2
docs/examples/.gitignore
vendored
2
docs/examples/.gitignore
vendored
@@ -43,3 +43,5 @@ simplessl
|
|||||||
smtp-multi
|
smtp-multi
|
||||||
smtp-tls
|
smtp-tls
|
||||||
url2file
|
url2file
|
||||||
|
usercertinmem
|
||||||
|
xmlstream
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ check_PROGRAMS = 10-at-a-time anyauthput cookie_interface debug fileupload \
|
|||||||
persistant post-callback postit2 sepheaders simple simplepost simplessl \
|
persistant post-callback postit2 sepheaders simple simplepost simplessl \
|
||||||
sendrecv httpcustomheader certinfo chkspeed ftpgetinfo ftp-wildcard \
|
sendrecv httpcustomheader certinfo chkspeed ftpgetinfo ftp-wildcard \
|
||||||
smtp-multi simplesmtp smtp-tls rtsp externalsocket resolve \
|
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
|
# These examples require external dependencies that may not be commonly
|
||||||
# available on POSIX systems, so don't bother attempting to compile them here.
|
# 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 \
|
ftpuploadresume.c ghiper.c hiperfifo.c htmltidy.c multithread.c \
|
||||||
opensslthreadlock.c sampleconv.c synctime.c threaded-ssl.c evhiperfifo.c \
|
opensslthreadlock.c sampleconv.c synctime.c threaded-ssl.c evhiperfifo.c \
|
||||||
smooth-gtk-thread.c version-check.pl href_extractor.c asiohiper.cpp \
|
smooth-gtk-thread.c version-check.pl href_extractor.c asiohiper.cpp \
|
||||||
multi-uv.c
|
multi-uv.c xmlstream.c usercertinmem.c sessioninfo.c
|
||||||
|
|||||||
@@ -27,14 +27,14 @@
|
|||||||
## Example: mingw32-make -f Makefile.m32 CFG=-zlib-ssl-spi-winidn
|
## Example: mingw32-make -f Makefile.m32 CFG=-zlib-ssl-spi-winidn
|
||||||
##
|
##
|
||||||
## Hint: you can also set environment vars to control the build, f.e.:
|
## 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
|
## set ZLIB=1
|
||||||
#
|
#
|
||||||
###########################################################################
|
###########################################################################
|
||||||
|
|
||||||
# Edit the path below to point to the base of your Zlib sources.
|
# Edit the path below to point to the base of your Zlib sources.
|
||||||
ifndef ZLIB_PATH
|
ifndef ZLIB_PATH
|
||||||
ZLIB_PATH = ../../../zlib-1.2.7
|
ZLIB_PATH = ../../../zlib-1.2.8
|
||||||
endif
|
endif
|
||||||
# Edit the path below to point to the base of your OpenSSL package.
|
# Edit the path below to point to the base of your OpenSSL package.
|
||||||
ifndef OPENSSL_PATH
|
ifndef OPENSSL_PATH
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ endif
|
|||||||
|
|
||||||
# Edit the path below to point to the base of your Zlib sources.
|
# Edit the path below to point to the base of your Zlib sources.
|
||||||
ifndef ZLIB_PATH
|
ifndef ZLIB_PATH
|
||||||
ZLIB_PATH = ../../../zlib-1.2.7
|
ZLIB_PATH = ../../../zlib-1.2.8
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Edit the path below to point to the base of your OpenSSL package.
|
# Edit the path below to point to the base of your OpenSSL package.
|
||||||
|
|||||||
@@ -78,4 +78,5 @@ simplepost.c - HTTP POST
|
|||||||
simplessl.c - HTTPS example with certificates many options set
|
simplessl.c - HTTPS example with certificates many options set
|
||||||
synctime.c - Sync local time by extracting date from remote HTTP servers
|
synctime.c - Sync local time by extracting date from remote HTTP servers
|
||||||
url2file.c - download a document and store it in a file
|
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.
|
10-at-a-time.c - Download many files simultaneously, 10 at a time.
|
||||||
|
|||||||
@@ -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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* 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.
|
* bytes big and contains the remote file.
|
||||||
*
|
*
|
||||||
* Do something nice with it!
|
* 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);
|
printf("%lu bytes retrieved\n", (long)chunk.size);
|
||||||
|
|||||||
@@ -22,8 +22,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -59,7 +57,6 @@ int main(int argc, char **argv)
|
|||||||
CURL *curl;
|
CURL *curl;
|
||||||
CURLcode res;
|
CURLcode res;
|
||||||
FILE * hd_src ;
|
FILE * hd_src ;
|
||||||
int hd ;
|
|
||||||
struct stat file_info;
|
struct stat file_info;
|
||||||
|
|
||||||
char *file;
|
char *file;
|
||||||
@@ -72,9 +69,7 @@ int main(int argc, char **argv)
|
|||||||
url = argv[2];
|
url = argv[2];
|
||||||
|
|
||||||
/* get the file size of the local file */
|
/* get the file size of the local file */
|
||||||
hd = open(file, O_RDONLY) ;
|
stat(file, &file_info);
|
||||||
fstat(hd, &file_info);
|
|
||||||
close(hd) ;
|
|
||||||
|
|
||||||
/* get a FILE * of the same file, could also be made with
|
/* get a FILE * of the same file, could also be made with
|
||||||
fdopen() from the previous descriptor, but hey this is just
|
fdopen() from the previous descriptor, but hey this is just
|
||||||
|
|||||||
111
docs/examples/postinmemory.c
Normal file
111
docs/examples/postinmemory.c
Normal 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;
|
||||||
|
}
|
||||||
@@ -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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -30,9 +30,10 @@ struct myprogress {
|
|||||||
CURL *curl;
|
CURL *curl;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int progress(void *p,
|
/* this is how the CURLOPT_XFERINFOFUNCTION callback works */
|
||||||
double dltotal, double dlnow,
|
static int xferinfo(void *p,
|
||||||
double ultotal, double ulnow)
|
curl_off_t dltotal, curl_off_t dlnow,
|
||||||
|
curl_off_t ultotal, curl_off_t ulnow)
|
||||||
{
|
{
|
||||||
struct myprogress *myp = (struct myprogress *)p;
|
struct myprogress *myp = (struct myprogress *)p;
|
||||||
CURL *curl = myp->curl;
|
CURL *curl = myp->curl;
|
||||||
@@ -48,7 +49,9 @@ static int progress(void *p,
|
|||||||
fprintf(stderr, "TOTAL TIME: %f \r\n", curtime);
|
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);
|
ulnow, ultotal, dlnow, dltotal);
|
||||||
|
|
||||||
if(dlnow > STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES)
|
if(dlnow > STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES)
|
||||||
@@ -56,6 +59,19 @@ static int progress(void *p,
|
|||||||
return 0;
|
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)
|
int main(void)
|
||||||
{
|
{
|
||||||
CURL *curl;
|
CURL *curl;
|
||||||
@@ -68,9 +84,28 @@ int main(void)
|
|||||||
prog.curl = curl;
|
prog.curl = curl;
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/");
|
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 */
|
/* pass the struct pointer into the progress function */
|
||||||
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &prog);
|
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);
|
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
|
||||||
res = curl_easy_perform(curl);
|
res = curl_easy_perform(curl);
|
||||||
|
|
||||||
|
|||||||
@@ -54,23 +54,22 @@ int main(void)
|
|||||||
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);
|
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);
|
||||||
|
|
||||||
/* open the files */
|
/* open the files */
|
||||||
headerfile = fopen(headerfilename,"w");
|
headerfile = fopen(headerfilename,"wb");
|
||||||
if (headerfile == NULL) {
|
if (headerfile == NULL) {
|
||||||
curl_easy_cleanup(curl_handle);
|
curl_easy_cleanup(curl_handle);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
bodyfile = fopen(bodyfilename,"w");
|
bodyfile = fopen(bodyfilename,"wb");
|
||||||
if (bodyfile == NULL) {
|
if (bodyfile == NULL) {
|
||||||
curl_easy_cleanup(curl_handle);
|
curl_easy_cleanup(curl_handle);
|
||||||
return -1;
|
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);
|
curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER, headerfile);
|
||||||
|
|
||||||
/*
|
/* we want the body be written to this file handle instead of stdout */
|
||||||
* Notice here that if you want the actual data sent anywhere else but
|
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, bodyfile);
|
||||||
* stdout, you should consider using the CURLOPT_WRITEDATA option. */
|
|
||||||
|
|
||||||
/* get it! */
|
/* get it! */
|
||||||
curl_easy_perform(curl_handle);
|
curl_easy_perform(curl_handle);
|
||||||
@@ -78,6 +77,9 @@ int main(void)
|
|||||||
/* close the header file */
|
/* close the header file */
|
||||||
fclose(headerfile);
|
fclose(headerfile);
|
||||||
|
|
||||||
|
/* close the body file */
|
||||||
|
fclose(bodyfile);
|
||||||
|
|
||||||
/* cleanup curl stuff */
|
/* cleanup curl stuff */
|
||||||
curl_easy_cleanup(curl_handle);
|
curl_easy_cleanup(curl_handle);
|
||||||
|
|
||||||
|
|||||||
105
docs/examples/sessioninfo.c
Normal file
105
docs/examples/sessioninfo.c
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/* Note that this example currently requires cURL to be linked against
|
||||||
|
GnuTLS (and this program must also be linked against -lgnutls). */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <curl/curl.h>
|
||||||
|
#include <gnutls/gnutls.h>
|
||||||
|
|
||||||
|
static CURL *curl;
|
||||||
|
|
||||||
|
static size_t wrfu(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||||
|
{
|
||||||
|
const struct curl_tlssessioninfo *info;
|
||||||
|
unsigned int cert_list_size;
|
||||||
|
const gnutls_datum_t *chainp;
|
||||||
|
CURLcode res;
|
||||||
|
|
||||||
|
(void)stream;
|
||||||
|
(void)ptr;
|
||||||
|
|
||||||
|
res = curl_easy_getinfo(curl, CURLINFO_TLS_SESSION, &info);
|
||||||
|
|
||||||
|
if(!res) {
|
||||||
|
switch(info->backend) {
|
||||||
|
case CURLSSLBACKEND_GNUTLS:
|
||||||
|
/* info->internals is now the gnutls_session_t */
|
||||||
|
chainp = gnutls_certificate_get_peers(info->internals, &cert_list_size);
|
||||||
|
if((chainp) && (cert_list_size)) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < cert_list_size; i++) {
|
||||||
|
gnutls_x509_crt_t cert;
|
||||||
|
gnutls_datum_t dn;
|
||||||
|
|
||||||
|
if(GNUTLS_E_SUCCESS == gnutls_x509_crt_init(&cert)) {
|
||||||
|
if(GNUTLS_E_SUCCESS ==
|
||||||
|
gnutls_x509_crt_import(cert, &chainp[i], GNUTLS_X509_FMT_DER)) {
|
||||||
|
if(GNUTLS_E_SUCCESS ==
|
||||||
|
gnutls_x509_crt_print(cert, GNUTLS_CRT_PRINT_FULL, &dn)) {
|
||||||
|
fprintf(stderr, "Certificate #%d: %.*s", i, dn.size, dn.data);
|
||||||
|
|
||||||
|
gnutls_free(dn.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gnutls_x509_crt_deinit(cert);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CURLSSLBACKEND_NONE:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return size * nmemb;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||||
|
|
||||||
|
curl = curl_easy_init();
|
||||||
|
if(curl) {
|
||||||
|
curl_easy_setopt(curl, CURLOPT_URL, "https://www.example.com/");
|
||||||
|
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, wrfu);
|
||||||
|
|
||||||
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||||
|
|
||||||
|
curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
|
||||||
|
|
||||||
|
(void) curl_easy_perform(curl);
|
||||||
|
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_global_cleanup();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
224
docs/examples/usercertinmem.c
Normal file
224
docs/examples/usercertinmem.c
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* 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 that to maintain simplicity this example does not use a CA certificate
|
||||||
|
* for peer verification. However, some form of peer verification
|
||||||
|
* must be used in real circumstances when a secure connection is required.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free resources that have been allocated by openssl functions */
|
||||||
|
if (bio)
|
||||||
|
BIO_free(bio);
|
||||||
|
|
||||||
|
if (kbio)
|
||||||
|
BIO_free(kbio);
|
||||||
|
|
||||||
|
if (rsa)
|
||||||
|
RSA_free(rsa);
|
||||||
|
|
||||||
|
if (cert)
|
||||||
|
X509_free(cert);
|
||||||
|
|
||||||
|
/* 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
158
docs/examples/xmlstream.c
Normal 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;
|
||||||
|
}
|
||||||
@@ -79,9 +79,12 @@ PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf \
|
|||||||
curl_multi_assign.pdf curl_easy_pause.pdf curl_easy_recv.pdf \
|
curl_multi_assign.pdf curl_easy_pause.pdf curl_easy_recv.pdf \
|
||||||
curl_easy_send.pdf curl_multi_socket_action.pdf curl_multi_wait.pdf
|
curl_easy_send.pdf curl_multi_socket_action.pdf curl_multi_wait.pdf
|
||||||
|
|
||||||
|
m4macrodir = $(datadir)/aclocal
|
||||||
|
dist_m4macro_DATA = libcurl.m4
|
||||||
|
|
||||||
CLEANFILES = $(HTMLPAGES) $(PDFPAGES)
|
CLEANFILES = $(HTMLPAGES) $(PDFPAGES)
|
||||||
|
|
||||||
EXTRA_DIST = $(man_MANS) $(HTMLPAGES) index.html $(PDFPAGES) libcurl.m4 ABI \
|
EXTRA_DIST = $(man_MANS) $(HTMLPAGES) index.html $(PDFPAGES) ABI \
|
||||||
symbols-in-versions symbols.pl
|
symbols-in-versions symbols.pl
|
||||||
MAN2HTML= roffit --mandir=. < $< >$@
|
MAN2HTML= roffit --mandir=. < $< >$@
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
.\" * you should have received as part of this distribution. The terms
|
.\" * you should have received as part of this distribution. The terms
|
||||||
@@ -219,8 +219,20 @@ done. The struct reports how many certs it found and then you can extract info
|
|||||||
for each of those certs by following the linked lists. The info chain is
|
for each of those certs by following the linked lists. The info chain is
|
||||||
provided in a series of data in the format "name:content" where the content is
|
provided in a series of data in the format "name:content" where the content is
|
||||||
for the specific named data. See also the certinfo.c example. NOTE: this
|
for the specific named data. See also the certinfo.c example. NOTE: this
|
||||||
option is only available in libcurl built with OpenSSL support. (Added in
|
option is only available in libcurl built with OpenSSL, NSS, GSKit or QsoSSL
|
||||||
7.19.1)
|
support. (Added in 7.19.1)
|
||||||
|
.IP CURLINFO_TLS_SESSION
|
||||||
|
Pass a pointer to a 'struct curl_tlsinfo *'. The pointer will be initialized
|
||||||
|
to refer to a 'struct curl_tlsinfo *' that will contain an enum indicating the
|
||||||
|
SSL library used for the handshake and the respective internal TLS session
|
||||||
|
structure of this underlying SSL library.
|
||||||
|
|
||||||
|
This may then be used to extract certificate information in a format
|
||||||
|
convenient for further processing, such as manual validation. NOTE: this
|
||||||
|
option may not be available for all SSL backends; unsupported SSL backends
|
||||||
|
will return 'CURLSSLBACKEND_NONE' to indicate that they are not supported;
|
||||||
|
this does not mean that no SSL backend was used. (Added in 7.34.0)
|
||||||
|
|
||||||
.IP CURLINFO_CONDITION_UNMET
|
.IP CURLINFO_CONDITION_UNMET
|
||||||
Pass a pointer to a long to receive the number 1 if the condition provided in
|
Pass a pointer to a long to receive the number 1 if the condition provided in
|
||||||
the previous request didn't match (see \fICURLOPT_TIMECONDITION\fP). Alas, if
|
the previous request didn't match (see \fICURLOPT_TIMECONDITION\fP). Alas, if
|
||||||
@@ -232,7 +244,7 @@ Pass a pointer to a char pointer to receive a pointer to a string holding the
|
|||||||
most recent RTSP Session ID.
|
most recent RTSP Session ID.
|
||||||
|
|
||||||
Applications wishing to resume an RTSP session on another connection should
|
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
|
.IP CURLINFO_RTSP_CLIENT_CSEQ
|
||||||
Pass a pointer to a long to receive the next CSeq that will be used by the
|
Pass a pointer to a long to receive the next CSeq that will be used by the
|
||||||
application.
|
application.
|
||||||
@@ -244,7 +256,7 @@ by the application.
|
|||||||
unimplemented).\fP
|
unimplemented).\fP
|
||||||
|
|
||||||
Applications wishing to resume an RTSP session on another connection should
|
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
|
.IP CURLINFO_RTSP_CSEQ_RECV
|
||||||
Pass a pointer to a long to receive the most recently received CSeq from the
|
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
|
server. If your application encounters a \fICURLE_RTSP_CSEQ_ERROR\fP then you
|
||||||
|
|||||||
@@ -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
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
.\" * you should have received as part of this distribution. The terms
|
.\" * 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
|
data at all, and that data will then be delivered again to the callback when
|
||||||
the writing is later unpaused.
|
the writing is later unpaused.
|
||||||
|
|
||||||
NOTE: while it may feel tempting, take care and notice that you cannot call
|
While it may feel tempting, take care and notice that you cannot call this
|
||||||
this function from another thread.
|
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
|
When this function is called to unpause reading, the chance is high that you
|
||||||
will get your write callback called before this function returns.
|
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
|
.SH AVAILABILITY
|
||||||
This function was added in libcurl 7.18.0. Before this version, there was no
|
This function was added in libcurl 7.18.0. Before this version, there was no
|
||||||
explicit support for pausing transfers.
|
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"
|
.SH "MEMORY USE"
|
||||||
When pausing a read by returning the magic return code from a write callback,
|
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
|
the read data is already in libcurl's internal buffers so it'll have to keep
|
||||||
|
|||||||
@@ -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
|
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
|
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,
|
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
|
SEEK_CUR and SEEK_END as argument for origin, although libcurl currently only
|
||||||
only passes SEEK_SET. The callback must return 0 (CURL_SEEKFUNC_OK) on
|
passes SEEK_SET. The callback must return 0 (CURL_SEEKFUNC_OK) on success, 1
|
||||||
success, 1 (CURL_SEEKFUNC_FAIL) to cause the upload operation to fail or 2
|
(CURL_SEEKFUNC_FAIL) to cause the upload operation to fail or 2
|
||||||
(CURL_SEEKFUNC_CANTSEEK) to indicate that while the seek failed, libcurl is
|
(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
|
free to work around the problem if possible. The latter can sometimes be done
|
||||||
by instead reading from the input or similar.
|
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.
|
The default value of this parameter is unspecified.
|
||||||
(Option added in 7.21.7)
|
(Option added in 7.21.7)
|
||||||
.IP CURLOPT_PROGRESSFUNCTION
|
.IP CURLOPT_PROGRESSFUNCTION
|
||||||
Pass a pointer to a function that matches the following prototype: \fBint
|
Pass a pointer to a function that matches the following prototype:
|
||||||
function(void *clientp, double dltotal, double dlnow, double ultotal, double
|
|
||||||
ulnow); \fP. This function gets called by libcurl instead of its internal
|
\fBint function(void *clientp, double dltotal, double dlnow, double ultotal,
|
||||||
equivalent with a frequent interval during operation (roughly once per second
|
double ulnow);\fP
|
||||||
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
|
This function gets called by libcurl instead of its internal equivalent with a
|
||||||
download data, the upload size will remain 0). Returning a non-zero value from
|
frequent interval. While data is being transferred it will be called very
|
||||||
this callback will cause libcurl to abort the transfer and return
|
frequently, and during slow periods like when nothing is being transferred it
|
||||||
\fICURLE_ABORTED_BY_CALLBACK\fP.
|
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
|
If you transfer data with the multi interface, this function will not be
|
||||||
called during periods of idleness unless you call the appropriate libcurl
|
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
|
\fICURLOPT_NOPROGRESS\fP must be set to 0 to make this function actually
|
||||||
get called.
|
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
|
.IP CURLOPT_PROGRESSDATA
|
||||||
Pass a pointer that will be untouched by libcurl and passed as the first
|
Pass a pointer that will be untouched by libcurl and passed as the first
|
||||||
argument in the progress callback set with \fICURLOPT_PROGRESSFUNCTION\fP.
|
argument in the progress callback set with \fICURLOPT_PROGRESSFUNCTION\fP.
|
||||||
The default value of this parameter is unspecified.
|
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
|
.IP CURLOPT_HEADERFUNCTION
|
||||||
Pass a pointer to a function that matches the following prototype:
|
Pass a pointer to a function that matches the following prototype:
|
||||||
\fBsize_t function( void *ptr, size_t size, size_t nmemb, void
|
\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.
|
For a greater explanation of the format please see RFC3986.
|
||||||
|
|
||||||
If the given URL lacks the scheme, or protocol, part ("http://" or "ftp://"
|
If the given URL lacks the scheme (such as "http://" or "ftp://" etc) then
|
||||||
etc), libcurl will attempt to resolve which protocol to use based on the
|
libcurl will attempt to resolve the protocol based on one of the following
|
||||||
given host mame. If the protocol is not supported, libcurl will return
|
given host names:
|
||||||
(\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
|
HTTP, FTP, DICT, LDAP, IMAP, POP3 or SMTP
|
||||||
information on which protocols are supported.
|
|
||||||
|
(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
|
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
|
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]/
|
http://[2001:1890:1112:1::20]/
|
||||||
|
|
||||||
It is also possible to specify the user name and password as part of the
|
It is also possible to specify the user name, password and any supported login
|
||||||
host, for some protocols, when connecting to servers that require
|
options as part of the host, for the following protocols, when connecting to
|
||||||
authentication.
|
servers that require authentication:
|
||||||
|
|
||||||
For example the following types of authentication support this:
|
|
||||||
|
|
||||||
http://user:password@www.example.com
|
http://user:password@www.example.com
|
||||||
|
|
||||||
ftp://user:password@ftp.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
|
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
|
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
|
For more information about the individual components of a LDAP URL please
|
||||||
see RFC4516.
|
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
|
.B NOTES
|
||||||
|
|
||||||
Starting with version 7.20.0, the fragment part of the URI will not be sent as
|
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
|
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)
|
find a .netrc file in the current user's home directory. (Added in 7.10.9)
|
||||||
.IP CURLOPT_USERPWD
|
.IP CURLOPT_USERPWD
|
||||||
Pass a char * as parameter, which should be [user name]:[password] to use for
|
Pass a char * as parameter, pointing to a zero terminated login details string
|
||||||
the connection. Use \fICURLOPT_HTTPAUTH\fP to decide the authentication method.
|
for the connection. The format of which is: [user name]:[password].
|
||||||
|
|
||||||
When using NTLM, you can set the domain by prepending it to the user name and
|
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
|
separating the domain and name with a forward (/) or backward slash (\\). Like
|
||||||
@@ -1054,10 +1144,21 @@ and password information to hosts using the initial host name (unless
|
|||||||
\fICURLOPT_UNRESTRICTED_AUTH\fP is set), so if libcurl follows locations to
|
\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
|
other hosts it will not send the user and password to those. This is enforced
|
||||||
to prevent accidental information leakage.
|
to prevent accidental information leakage.
|
||||||
|
|
||||||
|
Use \fICURLOPT_HTTPAUTH\fP to specify the authentication method for HTTP based
|
||||||
|
connections or \fICURLOPT_LOGIN_OPTIONS\fP to control IMAP, POP3 and SMTP
|
||||||
|
options.
|
||||||
|
|
||||||
|
The user and password strings are not URL decoded, so there's no way to send
|
||||||
|
in a user name containing a colon using this option. Use \fCURLOPT_USERNAME\fP
|
||||||
|
for that, or include it in the URL.
|
||||||
.IP CURLOPT_PROXYUSERPWD
|
.IP CURLOPT_PROXYUSERPWD
|
||||||
Pass a char * as parameter, which should be [user name]:[password] to use for
|
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 connection to the HTTP proxy. Both the name and the password will be URL
|
||||||
the authentication method.
|
decoded before use, so to include for example a colon in the user name you
|
||||||
|
should encode it as %3A.
|
||||||
|
|
||||||
|
Use \fICURLOPT_PROXYAUTH\fP to specify the authentication method.
|
||||||
.IP CURLOPT_USERNAME
|
.IP CURLOPT_USERNAME
|
||||||
Pass a char * as parameter, which should be pointing to the zero terminated
|
Pass a char * as parameter, which should be pointing to the zero terminated
|
||||||
user name to use for the transfer.
|
user name to use for the transfer.
|
||||||
@@ -1066,14 +1167,26 @@ user name to use for the transfer.
|
|||||||
authentication. You should not use this option together with the (older)
|
authentication. You should not use this option together with the (older)
|
||||||
CURLOPT_USERPWD option.
|
CURLOPT_USERPWD option.
|
||||||
|
|
||||||
In order to specify the password to be used in conjunction with the user name
|
To specify the password and login options, along with the user name, use the
|
||||||
use the \fICURLOPT_PASSWORD\fP option. (Added in 7.19.1)
|
\fICURLOPT_PASSWORD\fP and \fICURLOPT_LOGIN_OPTIONS\fP options. (Added in
|
||||||
|
7.19.1)
|
||||||
.IP CURLOPT_PASSWORD
|
.IP CURLOPT_PASSWORD
|
||||||
Pass a char * as parameter, which should be pointing to the zero terminated
|
Pass a char * as parameter, which should be pointing to the zero terminated
|
||||||
password to use for the transfer.
|
password to use for the transfer.
|
||||||
|
|
||||||
The CURLOPT_PASSWORD option should be used in conjunction with
|
The CURLOPT_PASSWORD option should be used in conjunction with the
|
||||||
the \fICURLOPT_USERNAME\fP option. (Added in 7.19.1)
|
\fICURLOPT_USERNAME\fP option. (Added in 7.19.1)
|
||||||
|
.IP CURLOPT_LOGIN_OPTIONS
|
||||||
|
(Added in 7.34.0) Pass a char * as parameter, which should be pointing to the
|
||||||
|
zero terminated options string to use for the transfer.
|
||||||
|
|
||||||
|
At present only IMAP, POP3 and SMTP support login options. For more
|
||||||
|
information about the login options please see RFC2384, RFC5092 and IETF draft
|
||||||
|
draft-earhart-url-smtp-00.txt
|
||||||
|
|
||||||
|
\CURLOPT_LOGIN_OPTIONS\fP can be used to set protocol specific login options,
|
||||||
|
such as the preferred authentication mechanism via "AUTH=NTLM" or "AUTH=*",
|
||||||
|
and should be used in conjunction with the \fICURLOPT_USERNAME\fP option.
|
||||||
.IP CURLOPT_PROXYUSERNAME
|
.IP CURLOPT_PROXYUSERNAME
|
||||||
Pass a char * as parameter, which should be pointing to the zero terminated
|
Pass a char * as parameter, which should be pointing to the zero terminated
|
||||||
user name to use for the transfer while connecting to Proxy.
|
user name to use for the transfer while connecting to Proxy.
|
||||||
@@ -1134,7 +1247,7 @@ Microsoft. It uses a challenge-response and hash concept similar to Digest, to
|
|||||||
prevent the password from being eavesdropped.
|
prevent the password from being eavesdropped.
|
||||||
|
|
||||||
You need to build libcurl with either OpenSSL, GnuTLS or NSS support for this
|
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
|
.IP CURLAUTH_NTLM_WB
|
||||||
NTLM delegating to winbind helper. Authentication is performed by a separate
|
NTLM delegating to winbind helper. Authentication is performed by a separate
|
||||||
binary application that is executed when needed. The name of the application
|
binary application that is executed when needed. The name of the application
|
||||||
@@ -1195,6 +1308,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
|
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
|
\fICURLOPT_HTTPAUTH\fP option. As of this writing, only Basic, Digest and NTLM
|
||||||
work. (Added in 7.10.7)
|
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
|
.SH HTTP OPTIONS
|
||||||
.IP CURLOPT_AUTOREFERER
|
.IP CURLOPT_AUTOREFERER
|
||||||
Pass a parameter set to 1 to enable this. When enabled, libcurl will
|
Pass a parameter set to 1 to enable this. When enabled, libcurl will
|
||||||
@@ -1392,10 +1521,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
|
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
|
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
|
new headers, replace internal headers and remove internal headers. To add a
|
||||||
header with no content, make the content be two quotes: \&"". The headers
|
header with no content (nothing to the right side of the colon), use the
|
||||||
included in the linked list must not be CRLF-terminated, because curl adds
|
form 'MyHeader;' (note the ending semicolon).
|
||||||
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
|
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.
|
you specified.
|
||||||
|
|
||||||
The first line in a request (containing the method, usually a GET or POST) is
|
The first line in a request (containing the method, usually a GET or POST) is
|
||||||
@@ -1535,12 +1666,18 @@ SMTP mail request. The linked list should be a fully valid list of \fBstruct
|
|||||||
curl_slist\fP structs properly filled in. Use \fIcurl_slist_append(3)\fP to
|
curl_slist\fP structs properly filled in. Use \fIcurl_slist_append(3)\fP to
|
||||||
create the list and \fIcurl_slist_free_all(3)\fP to clean up an entire list.
|
create the list and \fIcurl_slist_free_all(3)\fP to clean up an entire list.
|
||||||
|
|
||||||
Each recipient should be specified within a pair of angled brackets (<>),
|
When performing a mail transfer, each recipient should be specified within a
|
||||||
however, should you not use an angled bracket as the first character libcurl
|
pair of angled brackets (<>), however, should you not use an angled bracket as
|
||||||
will assume you provided a single email address and enclose that address
|
the first character libcurl will assume you provided a single email address and
|
||||||
within brackets for you.
|
enclose that address within brackets for you. (Added in 7.20.0)
|
||||||
|
|
||||||
(Added in 7.20.0)
|
When performing an address verification (VRFY command), each recipient should
|
||||||
|
be specified as the user name or user name and domain (as per Section 3.5 of
|
||||||
|
RFC5321). (Added in 7.34.0)
|
||||||
|
|
||||||
|
When performing a mailing list expand (EXPN command), each recipient should be
|
||||||
|
specified using the mailing list name, such as "Friends" or "London-Office".
|
||||||
|
(Added in 7.34.0)
|
||||||
.IP CURLOPT_MAIL_AUTH
|
.IP CURLOPT_MAIL_AUTH
|
||||||
Pass a pointer to a zero terminated string as parameter. This will be used
|
Pass a pointer to a zero terminated string as parameter. This will be used
|
||||||
to specify the authentication address (identity) of a submitted message that
|
to specify the authentication address (identity) of a submitted message that
|
||||||
@@ -1912,35 +2049,32 @@ source file to the remote target file.
|
|||||||
Pass a curl_off_t as parameter. It contains the offset in number of bytes that
|
Pass a curl_off_t as parameter. It contains the offset in number of bytes that
|
||||||
you want the transfer to start from. (Added in 7.11.0)
|
you want the transfer to start from. (Added in 7.11.0)
|
||||||
.IP CURLOPT_CUSTOMREQUEST
|
.IP CURLOPT_CUSTOMREQUEST
|
||||||
Pass a pointer to a zero terminated string as parameter. It can be used to
|
Pass a pointer to a zero terminated string as parameter.
|
||||||
specify the request instead of GET or HEAD when performing HTTP based
|
|
||||||
requests, instead of LIST and NLST when performing FTP directory listings and
|
|
||||||
instead of LIST and RETR when issuing POP3 based commands. This is
|
|
||||||
particularly useful, for example, for performing a HTTP DELETE request or a
|
|
||||||
POP3 DELE command.
|
|
||||||
|
|
||||||
Please don't perform this at will, on HTTP based requests, by making sure
|
|
||||||
your server supports the command you are sending first.
|
|
||||||
|
|
||||||
When you change the request method by setting \fBCURLOPT_CUSTOMREQUEST\fP to
|
When you change the request method by setting \fBCURLOPT_CUSTOMREQUEST\fP to
|
||||||
something, you don't actually change how libcurl behaves or acts in regards
|
something, you don't actually change how libcurl behaves or acts in regards
|
||||||
to the particular request method, it will only change the actual string sent
|
to the particular request method, it will only change the actual string sent
|
||||||
in the request.
|
in the request.
|
||||||
|
|
||||||
|
Restore to the internal default by setting this to NULL.
|
||||||
|
|
||||||
|
This option can be used to specify the request:
|
||||||
|
|
||||||
|
.B HTTP
|
||||||
|
|
||||||
|
Instead of GET or HEAD when performing HTTP based requests. This is
|
||||||
|
particularly useful, for example, for performing a HTTP DELETE request.
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
With the HTTP protocol when you tell libcurl to do a HEAD request, but then
|
When you tell libcurl to do a HEAD request, but then specify a GET though a
|
||||||
specify a GET though a custom request libcurl will still act as if it sent a
|
custom request libcurl will still act as if it sent a HEAD. To switch to a
|
||||||
HEAD. To switch to a proper HEAD use \fICURLOPT_NOBODY\fP, to switch to a
|
proper HEAD use \fICURLOPT_NOBODY\fP, to switch to a proper POST use
|
||||||
proper POST use \fICURLOPT_POST\fP or \fICURLOPT_POSTFIELDS\fP and to switch
|
\fICURLOPT_POST\fP or \fICURLOPT_POSTFIELDS\fP and to switch to a proper GET
|
||||||
to a proper GET use CURLOPT_HTTPGET.
|
use CURLOPT_HTTPGET.
|
||||||
|
|
||||||
With the POP3 protocol when you tell libcurl to use a custom request it will
|
Please don't perform this at will, on HTTP based requests, by making sure
|
||||||
behave like a LIST or RETR command was sent where it expects data to be
|
your server supports the command you are sending first.
|
||||||
returned by the server. As such \fICURLOPT_NOBODY\fP should be used when
|
|
||||||
specifying commands such as DELE and NOOP for example.
|
|
||||||
|
|
||||||
Restore to the internal default by setting this to NULL.
|
|
||||||
|
|
||||||
Many people have wrongly used this option to replace the entire request with
|
Many people have wrongly used this option to replace the entire request with
|
||||||
their own, including multiple headers and POST contents. While that might
|
their own, including multiple headers and POST contents. While that might
|
||||||
@@ -1950,7 +2084,35 @@ could possibly confuse the remote server badly. Use \fICURLOPT_POST\fP and
|
|||||||
replace or extend the set of headers sent by libcurl. Use
|
replace or extend the set of headers sent by libcurl. Use
|
||||||
\fICURLOPT_HTTP_VERSION\fP to change HTTP version.
|
\fICURLOPT_HTTP_VERSION\fP to change HTTP version.
|
||||||
|
|
||||||
(Support for POP3 added in 7.26.0)
|
.B FTP
|
||||||
|
|
||||||
|
Instead of LIST and NLST when performing FTP directory listings.
|
||||||
|
|
||||||
|
.B IMAP
|
||||||
|
|
||||||
|
Instead of LIST when issuing IMAP based requests. (Added in 7.30.0)
|
||||||
|
|
||||||
|
.B POP3
|
||||||
|
|
||||||
|
Instead of LIST and RETR when issuing POP3 based requests. (Added in 7.26.0)
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
When you tell libcurl to use a custom request it will behave like a LIST or
|
||||||
|
RETR command was sent where it expects data to be returned by the server. As
|
||||||
|
such \fICURLOPT_NOBODY\fP should be used when specifying commands such as
|
||||||
|
DELE and NOOP for example.
|
||||||
|
|
||||||
|
.B SMTP
|
||||||
|
|
||||||
|
Instead of a HELP or VRFY when issuing SMTP based requests. (Added in 7.34.0)
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
Normally a multiline response is returned which can be used, in conjuection with
|
||||||
|
\fICURLOPT_MAIL_RCPT\fP, to specify an EXPN request. If the \fICURLOPT_NOBODY\fP
|
||||||
|
option is specified then the request can be used to issue NOOP and RSET
|
||||||
|
commands.
|
||||||
.IP CURLOPT_FILETIME
|
.IP CURLOPT_FILETIME
|
||||||
Pass a long. If it is 1, libcurl will attempt to get the modification date of
|
Pass a long. If it is 1, libcurl will attempt to get the modification date of
|
||||||
the remote document in this operation. This requires that the remote server
|
the remote document in this operation. This requires that the remote server
|
||||||
@@ -2046,10 +2208,14 @@ In unix-like systems, this might cause signals to be used unless
|
|||||||
|
|
||||||
Default timeout is 0 (zero) which means it never times out.
|
Default timeout is 0 (zero) which means it never times out.
|
||||||
.IP CURLOPT_TIMEOUT_MS
|
.IP CURLOPT_TIMEOUT_MS
|
||||||
Like \fICURLOPT_TIMEOUT\fP but takes number of milliseconds instead. If
|
An alternative to \fICURLOPT_TIMEOUT\fP but takes number of milliseconds
|
||||||
libcurl is built to use the standard system name resolver, that portion
|
instead. If libcurl is built to use the standard system name resolver, that
|
||||||
of the transfer will still use full-second resolution for timeouts with
|
portion of the transfer will still use full-second resolution for timeouts
|
||||||
a minimum timeout allowed of one second.
|
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)
|
(Added in 7.16.2)
|
||||||
.IP CURLOPT_LOW_SPEED_LIMIT
|
.IP CURLOPT_LOW_SPEED_LIMIT
|
||||||
Pass a long as parameter. It contains the transfer speed in bytes per second
|
Pass a long as parameter. It contains the transfer speed in bytes per second
|
||||||
@@ -2173,7 +2339,9 @@ ADDRESS can of course be either IPv4 or IPv6 style addressing.
|
|||||||
|
|
||||||
This option effectively pre-populates the DNS cache with entries for the
|
This option effectively pre-populates the DNS cache with entries for the
|
||||||
host+port pair so redirects and everything that operations against the
|
host+port pair so redirects and everything that operations against the
|
||||||
HOST+PORT will instead use your provided ADDRESS.
|
HOST+PORT will instead use your provided ADDRESS. Addresses to set with
|
||||||
|
\fICURL_RESOLVE\fP will not time-out from the DNS cache like ordindary
|
||||||
|
entries.
|
||||||
|
|
||||||
You can remove names from the DNS cache again, to stop providing these fake
|
You can remove names from the DNS cache again, to stop providing these fake
|
||||||
resolves, by including a string in the linked list that uses the format
|
resolves, by including a string in the linked list that uses the format
|
||||||
@@ -2195,6 +2363,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.
|
supports this operation. The c-ares backend is the only such one.
|
||||||
|
|
||||||
(Added in 7.24.0)
|
(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
|
.IP CURLOPT_ACCEPTTIMEOUT_MS
|
||||||
Pass a long telling libcurl the maximum number of milliseconds to wait for a
|
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
|
server to connect back to libcurl when an active FTP connection is used. If no
|
||||||
@@ -2202,20 +2400,28 @@ timeout is set, the internal default of 60000 will be used. (Added in 7.24.0)
|
|||||||
.SH SSL and SECURITY OPTIONS
|
.SH SSL and SECURITY OPTIONS
|
||||||
.IP CURLOPT_SSLCERT
|
.IP CURLOPT_SSLCERT
|
||||||
Pass a pointer to a zero terminated string as parameter. The string should be
|
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
|
the file name of your certificate. The default format is "P12" on Secure
|
||||||
changed with \fICURLOPT_SSLCERTTYPE\fP.
|
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
|
With NSS or Secure Transport, this can also be the nickname of the certificate
|
||||||
authenticate with. If you want to use a file from the current directory, please
|
you wish to authenticate with as it is named in the security database. If you
|
||||||
precede it with "./" prefix, in order to avoid confusion with a nickname.
|
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
|
.IP CURLOPT_SSLCERTTYPE
|
||||||
Pass a pointer to a zero terminated string as parameter. The string should be
|
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
|
the format of your certificate. Supported formats are "PEM" and "DER", except
|
||||||
in 7.9.3)
|
with Secure Transport. OpenSSL (versions 0.9.3 and later) and Secure Transport
|
||||||
|
(on iOS 5 or later, or OS X 10.7 or later) also support "P12" for
|
||||||
|
PKCS#12-encoded files. (Added in 7.9.3)
|
||||||
.IP CURLOPT_SSLKEY
|
.IP CURLOPT_SSLKEY
|
||||||
Pass a pointer to a zero terminated string as parameter. The string should be
|
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
|
the file name of your private key. The default format is "PEM" and can be
|
||||||
changed with \fICURLOPT_SSLKEYTYPE\fP.
|
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
|
.IP CURLOPT_SSLKEYTYPE
|
||||||
Pass a pointer to a zero terminated string as parameter. The string should be
|
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".
|
the format of your private key. Supported formats are "PEM", "DER" and "ENG".
|
||||||
@@ -2252,6 +2458,8 @@ Even though this option doesn't need any parameter, in some configurations
|
|||||||
arguments. Therefore, it's recommended to pass 1 as parameter to this option.
|
arguments. Therefore, it's recommended to pass 1 as parameter to this option.
|
||||||
.IP CURLOPT_SSLVERSION
|
.IP CURLOPT_SSLVERSION
|
||||||
Pass a long as parameter to control what version of SSL/TLS to attempt to use.
|
Pass a long as parameter to control what version of SSL/TLS to attempt to use.
|
||||||
|
(Added in 7.9.2)
|
||||||
|
|
||||||
The available options are:
|
The available options are:
|
||||||
.RS
|
.RS
|
||||||
.IP CURL_SSLVERSION_DEFAULT
|
.IP CURL_SSLVERSION_DEFAULT
|
||||||
@@ -2259,11 +2467,17 @@ The default action. This will attempt to figure out the remote SSL protocol
|
|||||||
version, i.e. either SSLv3 or TLSv1 (but not SSLv2, which became disabled
|
version, i.e. either SSLv3 or TLSv1 (but not SSLv2, which became disabled
|
||||||
by default with 7.18.1).
|
by default with 7.18.1).
|
||||||
.IP CURL_SSLVERSION_TLSv1
|
.IP CURL_SSLVERSION_TLSv1
|
||||||
Force TLSv1
|
Force TLSv1.x
|
||||||
.IP CURL_SSLVERSION_SSLv2
|
.IP CURL_SSLVERSION_SSLv2
|
||||||
Force SSLv2
|
Force SSLv2
|
||||||
.IP CURL_SSLVERSION_SSLv3
|
.IP CURL_SSLVERSION_SSLv3
|
||||||
Force SSLv3
|
Force SSLv3
|
||||||
|
.IP CURL_SSLVERSION_TLSv1_0
|
||||||
|
Force TLSv1.0 (Added in 7.34.0)
|
||||||
|
.IP CURL_SSLVERSION_TLSv1_1
|
||||||
|
Force TLSv1.1 (Added in 7.34.0)
|
||||||
|
.IP CURL_SSLVERSION_TLSv1_2
|
||||||
|
Force TLSv1.2 (Added in 7.34.0)
|
||||||
.RE
|
.RE
|
||||||
.IP CURLOPT_SSL_VERIFYPEER
|
.IP CURLOPT_SSL_VERIFYPEER
|
||||||
Pass a long as parameter. By default, curl assumes a value of 1.
|
Pass a long as parameter. By default, curl assumes a value of 1.
|
||||||
@@ -2364,9 +2578,10 @@ Curl considers the server the intended one when the Common Name field or a
|
|||||||
Subject Alternate Name field in the certificate matches the host name in the
|
Subject Alternate Name field in the certificate matches the host name in the
|
||||||
URL to which you told Curl to connect.
|
URL to which you told Curl to connect.
|
||||||
|
|
||||||
When the value is 1, libcurl will return a failure. It was previously (in
|
When the value is 1, \fIcurl_easy_setopt\fP will return an error and the option
|
||||||
7.28.0 and earlier) a debug option of some sorts, but it is no longer
|
value will not be changed. It was previously (in 7.28.0 and earlier) a debug
|
||||||
supported due to frequently leading to programmer mistakes.
|
option of some sorts, but it is no longer supported due to frequently leading
|
||||||
|
to programmer mistakes.
|
||||||
|
|
||||||
When the value is 0, the connection succeeds regardless of the names in the
|
When the value is 0, the connection succeeds regardless of the names in the
|
||||||
certificate.
|
certificate.
|
||||||
@@ -2376,14 +2591,14 @@ The default value for this option is 2.
|
|||||||
This option controls checking the server's certificate's claimed identity.
|
This option controls checking the server's certificate's claimed identity.
|
||||||
The server could be lying. To control lying, see
|
The server could be lying. To control lying, see
|
||||||
\fICURLOPT_SSL_VERIFYPEER\fP. If libcurl is built against NSS and
|
\fICURLOPT_SSL_VERIFYPEER\fP. If libcurl is built against NSS and
|
||||||
\fICURLOPT_SSL_VERIFYPEER\fP is zero, \fICURLOPT_SSL_VERIFYHOST\fP
|
\fICURLOPT_SSL_VERIFYPEER\fP is zero, \fICURLOPT_SSL_VERIFYHOST\fP is also set
|
||||||
is ignored.
|
to zero and cannot be overridden.
|
||||||
|
|
||||||
.IP CURLOPT_CERTINFO
|
.IP CURLOPT_CERTINFO
|
||||||
Pass a long set to 1 to enable libcurl's certificate chain info gatherer. With
|
Pass a long set to 1 to enable libcurl's certificate chain info gatherer. With
|
||||||
this enabled, libcurl (if built with OpenSSL) will extract lots of information
|
this enabled, libcurl (if built with OpenSSL, NSS, GSKit or QsoSSL) will
|
||||||
|
extract lots of information
|
||||||
and data about the certificates in the certificate chain used in the SSL
|
and data about the certificates in the certificate chain used in the SSL
|
||||||
connection. This data is then possible to extract after a transfer using
|
connection. This data may then be retrieved after a transfer using
|
||||||
\fIcurl_easy_getinfo(3)\fP and its option \fICURLINFO_CERTINFO\fP. (Added in
|
\fIcurl_easy_getinfo(3)\fP and its option \fICURLINFO_CERTINFO\fP. (Added in
|
||||||
7.19.1)
|
7.19.1)
|
||||||
.IP CURLOPT_RANDOM_FILE
|
.IP CURLOPT_RANDOM_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
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
.\" * you should have received as part of this distribution. The terms
|
.\" * 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
|
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
|
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
|
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.
|
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.
|
You can disable this header with \fICURLOPT_HTTPHEADER\fP as usual.
|
||||||
|
|||||||
@@ -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
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
.\" * you should have received as part of this distribution. The terms
|
.\" * 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
|
.ad
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
Adds a standard easy handle to the multi stack. This function call will make
|
Adds a standard easy handle to the multi stack. This function call will make
|
||||||
this \fImulti_handle\fP control the specified \fIeasy_handle\fP.
|
this \fImulti_handle\fP control the specified \fIeasy_handle\fP. Furthermore,
|
||||||
Furthermore, libcurl now initiates the connection associated with the
|
libcurl now initiates the connection associated with the specified
|
||||||
specified \fIeasy_handle\fP.
|
\fIeasy_handle\fP.
|
||||||
|
|
||||||
When an easy handle has been added to a multi stack, you can not and you must
|
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!
|
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
|
that is shared between all easy handles within the multi handle when
|
||||||
\fIcurl_multi_add_handle(3)\fP is called.
|
\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
|
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
|
\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
|
multi stack before you terminate first the easy handle and then the multi
|
||||||
|
|||||||
@@ -74,9 +74,9 @@ The socket \fBcallback\fP function uses a prototype like this
|
|||||||
int action, /* see values below */
|
int action, /* see values below */
|
||||||
void *userp, /* private callback pointer */
|
void *userp, /* private callback pointer */
|
||||||
void *socketp); /* private socket pointer,
|
void *socketp); /* private socket pointer,
|
||||||
\fBNULL\fI if not
|
\fBNULL\fP if not
|
||||||
previously assigned with
|
previously assigned with
|
||||||
\fIcurl_multi_assign(3)\fP */
|
\fBcurl_multi_assign(3)\fP */
|
||||||
|
|
||||||
.fi
|
.fi
|
||||||
The callback MUST return 0.
|
The callback MUST return 0.
|
||||||
|
|||||||
@@ -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
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
.\" * you should have received as part of this distribution. The terms
|
.\" * 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
|
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
|
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.
|
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
|
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.
|
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
|
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
|
If no extra file descriptors are provided and libcurl has no file descriptor
|
||||||
to offer to wait for, this function will return immediately.
|
to offer to wait for, this function will return immediately.
|
||||||
|
|||||||
@@ -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
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
.\" * you should have received as part of this distribution. The terms
|
.\" * 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)"
|
.IP "CURLM_UNKNOWN_OPTION (6)"
|
||||||
curl_multi_setopt() with unsupported option
|
curl_multi_setopt() with unsupported option
|
||||||
(Added in 7.15.4)
|
(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"
|
.SH "CURLSHcode"
|
||||||
The "share" interface will return a CURLSHcode to indicate when an error has
|
The "share" interface will return a CURLSHcode to indicate when an error has
|
||||||
occurred. Also consider \fIcurl_share_strerror(3)\fP.
|
occurred. Also consider \fIcurl_share_strerror(3)\fP.
|
||||||
|
|||||||
@@ -34,8 +34,10 @@ The share interface was added to enable sharing of data between curl
|
|||||||
\&"handles".
|
\&"handles".
|
||||||
.SH "ONE SET OF DATA - MANY TRANSFERS"
|
.SH "ONE SET OF DATA - MANY TRANSFERS"
|
||||||
You can have multiple easy handles share data between them. Have them update
|
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
|
and use the \fBsame\fP cookie database, DNS cache, TLS session cache! This
|
||||||
transfer will take advantage from data updates made by the other transfer(s).
|
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"
|
.SH "SHARE OBJECT"
|
||||||
You create a shared object with \fIcurl_share_init(3)\fP. It returns a handle
|
You create a shared object with \fIcurl_share_init(3)\fP. It returns a handle
|
||||||
for a newly created one.
|
for a newly created one.
|
||||||
|
|||||||
@@ -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
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
.\" * you should have received as part of this distribution. The terms
|
.\" * 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.
|
are sanitized before use.
|
||||||
|
|
||||||
.IP "Private Resources"
|
.IP "Private Resources"
|
||||||
A user who can control the DNS server of a domain being passed in within
|
A user who can control the DNS server of a domain being passed in within a URL
|
||||||
a URL can change the address of the host to a local, private address
|
can change the address of the host to a local, private address which a
|
||||||
which the libcurl application will then use. e.g. The innocuous URL
|
server-side libcurl-using application could then use. e.g. the innocuous URL
|
||||||
http://fuzzybunnies.example.com/ could actually resolve to the IP address
|
http://fuzzybunnies.example.com/ could actually resolve to the IP address of a
|
||||||
of a server behind a firewall, such as 127.0.0.1 or 10.1.2.3
|
server behind a firewall, such as 127.0.0.1 or 10.1.2.3. Apps can mitigate
|
||||||
Apps can mitigate against this by setting a CURLOPT_OPENSOCKETFUNCTION
|
against this by setting a CURLOPT_OPENSOCKETFUNCTION and checking the address
|
||||||
and checking the address before a connection.
|
before a connection.
|
||||||
|
|
||||||
All the malicious scenarios regarding redirected URLs apply just as well
|
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
|
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
|
but behind a firewall. Apps can mitigate against this by using the
|
||||||
CURLOPT_FTP_SKIP_PASV_IP option or CURLOPT_FTPPORT.
|
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
|
.IP Uploads
|
||||||
When uploading, a redirect can cause a local (or remote) file to be
|
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
|
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
|
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
|
server-supplied redirect URL. Special care must be taken to sanitize such
|
||||||
names to avoid the possibility of a malicious server supplying one like
|
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"
|
.IP "Server Certificates"
|
||||||
A secure application should never use the CURLOPT_SSL_VERIFYPEER option to
|
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
|
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
|
problems with libcurl and ask someone for help, everything you reveal in order
|
||||||
to get best possible help might also impose certain security related
|
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
|
mention passwords of course) may in fact be used by intruders to gain
|
||||||
additional information of a potential target.
|
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
|
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
|
can just edit out the sensitive data or just search/replace your true
|
||||||
information with faked data.
|
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.
|
per-easy handle basis when the easy interface is used.
|
||||||
|
|
||||||
The DNS cache is shared between handles within a multi handle, making
|
The DNS cache is shared between handles within a multi handle, making
|
||||||
subsequent name resolvings faster and the connection pool that is kept to
|
subsequent name resolving faster, and the connection pool that is kept to
|
||||||
better allow persistent connections and connection re-use is shared. If you're
|
better allow persistent connections and connection re-use is also shared. If
|
||||||
using the easy interface, you can still share these between specific easy
|
you're using the easy interface, you can still share these between specific
|
||||||
handles by using the share interface, see \fIlibcurl-share(3)\fP.
|
easy handles by using the share interface, see \fIlibcurl-share(3)\fP.
|
||||||
|
|
||||||
Some things are never shared automatically, not within multi handles, like for
|
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.
|
example cookies so the only way to share that is with the share interface.
|
||||||
|
|||||||
@@ -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
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
.\" * you should have received as part of this distribution. The terms
|
.\" * 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.
|
for details.
|
||||||
|
|
||||||
To transfer files, you always set up an "easy handle" using
|
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
|
\fIcurl_easy_init(3)\fP for a single specific transfer (in either
|
||||||
the option of using the "easy" interface, or the "multi" interface.
|
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
|
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
|
\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
|
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
|
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
|
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
|
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
|
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.
|
several transfers, if the conditions are right.
|
||||||
|
|
||||||
libcurl will \fBalways\fP attempt to use persistent connections. Whenever you
|
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
|
use \fIcurl_easy_perform(3)\fP or \fIcurl_multi_perform(3)\fP etc, libcurl
|
||||||
attempt to use an existing connection to do the transfer, and if none exists
|
will attempt to use an existing connection to do the transfer, and if none
|
||||||
it'll open a new one that will be subject for re-use on a possible following
|
exists it'll open a new one that will be subject for re-use on a possible
|
||||||
call to \fIcurl_easy_perform(3)\fP or \fIcurl_multi_perform(3)\fP.
|
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
|
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
|
do as many of your file transfers as possible using the same handle.
|
||||||
you call \fIcurl_easy_cleanup(3)\fP, all the possibly open connections held by
|
|
||||||
libcurl will be closed and forgotten.
|
|
||||||
|
|
||||||
Note that the options set with \fIcurl_easy_setopt(3)\fP will be used on
|
If you use the easy interface, and you call \fIcurl_easy_cleanup(3)\fP, all
|
||||||
every repeated \fIcurl_easy_perform(3)\fP call.
|
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"
|
.SH "GLOBAL CONSTANTS"
|
||||||
There are a variety of constants that libcurl uses, mainly through its
|
There are a variety of constants that libcurl uses, mainly through its
|
||||||
internal use of other libraries, which are too complicated for the
|
internal use of other libraries, which are too complicated for the
|
||||||
|
|||||||
@@ -85,8 +85,8 @@ CURLE_LDAP_SEARCH_FAILED 7.1
|
|||||||
CURLE_LIBRARY_NOT_FOUND 7.1 7.17.0
|
CURLE_LIBRARY_NOT_FOUND 7.1 7.17.0
|
||||||
CURLE_LOGIN_DENIED 7.13.1
|
CURLE_LOGIN_DENIED 7.13.1
|
||||||
CURLE_MALFORMAT_USER 7.1 7.17.0
|
CURLE_MALFORMAT_USER 7.1 7.17.0
|
||||||
CURLE_NO_CONNECTION_AVAILABLE 7.30.0
|
|
||||||
CURLE_NOT_BUILT_IN 7.21.5
|
CURLE_NOT_BUILT_IN 7.21.5
|
||||||
|
CURLE_NO_CONNECTION_AVAILABLE 7.30.0
|
||||||
CURLE_OK 7.1
|
CURLE_OK 7.1
|
||||||
CURLE_OPERATION_TIMEDOUT 7.10.2
|
CURLE_OPERATION_TIMEDOUT 7.10.2
|
||||||
CURLE_OPERATION_TIMEOUTED 7.1 7.17.0
|
CURLE_OPERATION_TIMEOUTED 7.1 7.17.0
|
||||||
@@ -250,6 +250,7 @@ CURLINFO_SSL_VERIFYRESULT 7.5
|
|||||||
CURLINFO_STARTTRANSFER_TIME 7.9.2
|
CURLINFO_STARTTRANSFER_TIME 7.9.2
|
||||||
CURLINFO_STRING 7.4.1
|
CURLINFO_STRING 7.4.1
|
||||||
CURLINFO_TEXT 7.9.6
|
CURLINFO_TEXT 7.9.6
|
||||||
|
CURLINFO_TLS_SESSION 7.34.0
|
||||||
CURLINFO_TOTAL_TIME 7.4.1
|
CURLINFO_TOTAL_TIME 7.4.1
|
||||||
CURLINFO_TYPEMASK 7.4.1
|
CURLINFO_TYPEMASK 7.4.1
|
||||||
CURLIOCMD_NOP 7.12.3
|
CURLIOCMD_NOP 7.12.3
|
||||||
@@ -270,10 +271,10 @@ CURLKHTYPE_RSA1 7.19.6
|
|||||||
CURLKHTYPE_UNKNOWN 7.19.6
|
CURLKHTYPE_UNKNOWN 7.19.6
|
||||||
CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE 7.30.0
|
CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE 7.30.0
|
||||||
CURLMOPT_CONTENT_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_HOST_CONNECTIONS 7.30.0
|
||||||
CURLMOPT_MAX_PIPELINE_LENGTH 7.30.0
|
CURLMOPT_MAX_PIPELINE_LENGTH 7.30.0
|
||||||
CURLMOPT_MAX_TOTAL_CONNECTIONS 7.30.0
|
CURLMOPT_MAX_TOTAL_CONNECTIONS 7.30.0
|
||||||
CURLMOPT_MAXCONNECTS 7.16.3
|
|
||||||
CURLMOPT_PIPELINING 7.16.0
|
CURLMOPT_PIPELINING 7.16.0
|
||||||
CURLMOPT_PIPELINING_SERVER_BL 7.30.0
|
CURLMOPT_PIPELINING_SERVER_BL 7.30.0
|
||||||
CURLMOPT_PIPELINING_SITE_BL 7.30.0
|
CURLMOPT_PIPELINING_SITE_BL 7.30.0
|
||||||
@@ -283,6 +284,7 @@ CURLMOPT_TIMERDATA 7.16.0
|
|||||||
CURLMOPT_TIMERFUNCTION 7.16.0
|
CURLMOPT_TIMERFUNCTION 7.16.0
|
||||||
CURLMSG_DONE 7.9.6
|
CURLMSG_DONE 7.9.6
|
||||||
CURLMSG_NONE 7.9.6
|
CURLMSG_NONE 7.9.6
|
||||||
|
CURLM_ADDED_ALREADY 7.32.1
|
||||||
CURLM_BAD_EASY_HANDLE 7.9.6
|
CURLM_BAD_EASY_HANDLE 7.9.6
|
||||||
CURLM_BAD_HANDLE 7.9.6
|
CURLM_BAD_HANDLE 7.9.6
|
||||||
CURLM_BAD_SOCKET 7.15.4
|
CURLM_BAD_SOCKET 7.15.4
|
||||||
@@ -331,6 +333,9 @@ CURLOPT_DEBUGDATA 7.9.6
|
|||||||
CURLOPT_DEBUGFUNCTION 7.9.6
|
CURLOPT_DEBUGFUNCTION 7.9.6
|
||||||
CURLOPT_DIRLISTONLY 7.17.0
|
CURLOPT_DIRLISTONLY 7.17.0
|
||||||
CURLOPT_DNS_CACHE_TIMEOUT 7.9.3
|
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_SERVERS 7.24.0
|
||||||
CURLOPT_DNS_USE_GLOBAL_CACHE 7.9.3 7.11.1
|
CURLOPT_DNS_USE_GLOBAL_CACHE 7.9.3 7.11.1
|
||||||
CURLOPT_EGDSOCKET 7.7
|
CURLOPT_EGDSOCKET 7.7
|
||||||
@@ -390,6 +395,7 @@ CURLOPT_KRB4LEVEL 7.3 7.17.0
|
|||||||
CURLOPT_KRBLEVEL 7.16.4
|
CURLOPT_KRBLEVEL 7.16.4
|
||||||
CURLOPT_LOCALPORT 7.15.2
|
CURLOPT_LOCALPORT 7.15.2
|
||||||
CURLOPT_LOCALPORTRANGE 7.15.2
|
CURLOPT_LOCALPORTRANGE 7.15.2
|
||||||
|
CURLOPT_LOGIN_OPTIONS 7.34.0
|
||||||
CURLOPT_LOW_SPEED_LIMIT 7.1
|
CURLOPT_LOW_SPEED_LIMIT 7.1
|
||||||
CURLOPT_LOW_SPEED_TIME 7.1
|
CURLOPT_LOW_SPEED_TIME 7.1
|
||||||
CURLOPT_MAIL_AUTH 7.25.0
|
CURLOPT_MAIL_AUTH 7.25.0
|
||||||
@@ -428,7 +434,7 @@ CURLOPT_POSTREDIR 7.19.1
|
|||||||
CURLOPT_PREQUOTE 7.9.5
|
CURLOPT_PREQUOTE 7.9.5
|
||||||
CURLOPT_PRIVATE 7.10.3
|
CURLOPT_PRIVATE 7.10.3
|
||||||
CURLOPT_PROGRESSDATA 7.1
|
CURLOPT_PROGRESSDATA 7.1
|
||||||
CURLOPT_PROGRESSFUNCTION 7.1
|
CURLOPT_PROGRESSFUNCTION 7.1 7.32.0
|
||||||
CURLOPT_PROTOCOLS 7.19.4
|
CURLOPT_PROTOCOLS 7.19.4
|
||||||
CURLOPT_PROXY 7.1
|
CURLOPT_PROXY 7.1
|
||||||
CURLOPT_PROXYAUTH 7.10.7
|
CURLOPT_PROXYAUTH 7.10.7
|
||||||
@@ -456,6 +462,7 @@ CURLOPT_RTSP_SERVER_CSEQ 7.20.0
|
|||||||
CURLOPT_RTSP_SESSION_ID 7.20.0
|
CURLOPT_RTSP_SESSION_ID 7.20.0
|
||||||
CURLOPT_RTSP_STREAM_URI 7.20.0
|
CURLOPT_RTSP_STREAM_URI 7.20.0
|
||||||
CURLOPT_RTSP_TRANSPORT 7.20.0
|
CURLOPT_RTSP_TRANSPORT 7.20.0
|
||||||
|
CURLOPT_SASL_IR 7.31.0
|
||||||
CURLOPT_SEEKDATA 7.18.0
|
CURLOPT_SEEKDATA 7.18.0
|
||||||
CURLOPT_SEEKFUNCTION 7.18.0
|
CURLOPT_SEEKFUNCTION 7.18.0
|
||||||
CURLOPT_SERVER_RESPONSE_TIMEOUT 7.20.0
|
CURLOPT_SERVER_RESPONSE_TIMEOUT 7.20.0
|
||||||
@@ -524,6 +531,9 @@ CURLOPT_WRITEDATA 7.9.7
|
|||||||
CURLOPT_WRITEFUNCTION 7.1
|
CURLOPT_WRITEFUNCTION 7.1
|
||||||
CURLOPT_WRITEHEADER 7.1
|
CURLOPT_WRITEHEADER 7.1
|
||||||
CURLOPT_WRITEINFO 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_ALL 7.18.0
|
||||||
CURLPAUSE_CONT 7.18.0
|
CURLPAUSE_CONT 7.18.0
|
||||||
CURLPAUSE_RECV 7.18.0
|
CURLPAUSE_RECV 7.18.0
|
||||||
@@ -585,6 +595,16 @@ CURLSSH_AUTH_KEYBOARD 7.16.1
|
|||||||
CURLSSH_AUTH_NONE 7.16.1
|
CURLSSH_AUTH_NONE 7.16.1
|
||||||
CURLSSH_AUTH_PASSWORD 7.16.1
|
CURLSSH_AUTH_PASSWORD 7.16.1
|
||||||
CURLSSH_AUTH_PUBLICKEY 7.16.1
|
CURLSSH_AUTH_PUBLICKEY 7.16.1
|
||||||
|
CURLSSLBACKEND_CYASSL 7.34.0
|
||||||
|
CURLSSLBACKEND_DARWINSSL 7.34.0
|
||||||
|
CURLSSLBACKEND_GNUTLS 7.34.0
|
||||||
|
CURLSSLBACKEND_GSKIT 7.34.0
|
||||||
|
CURLSSLBACKEND_NONE 7.34.0
|
||||||
|
CURLSSLBACKEND_NSS 7.34.0
|
||||||
|
CURLSSLBACKEND_OPENSSL 7.34.0
|
||||||
|
CURLSSLBACKEND_POLARSSL 7.34.0
|
||||||
|
CURLSSLBACKEND_QSOSSL 7.34.0
|
||||||
|
CURLSSLBACKEND_SCHANNEL 7.34.0
|
||||||
CURLSSLOPT_ALLOW_BEAST 7.25.0
|
CURLSSLOPT_ALLOW_BEAST 7.25.0
|
||||||
CURLUSESSL_ALL 7.17.0
|
CURLUSESSL_ALL 7.17.0
|
||||||
CURLUSESSL_CONTROL 7.17.0
|
CURLUSESSL_CONTROL 7.17.0
|
||||||
@@ -617,14 +637,15 @@ CURL_FORMADD_NULL 7.9.8
|
|||||||
CURL_FORMADD_OK 7.9.8
|
CURL_FORMADD_OK 7.9.8
|
||||||
CURL_FORMADD_OPTION_TWICE 7.9.8
|
CURL_FORMADD_OPTION_TWICE 7.9.8
|
||||||
CURL_FORMADD_UNKNOWN_OPTION 7.9.8
|
CURL_FORMADD_UNKNOWN_OPTION 7.9.8
|
||||||
|
CURL_GLOBAL_ACK_EINTR 7.30.0
|
||||||
CURL_GLOBAL_ALL 7.8
|
CURL_GLOBAL_ALL 7.8
|
||||||
CURL_GLOBAL_DEFAULT 7.8
|
CURL_GLOBAL_DEFAULT 7.8
|
||||||
CURL_GLOBAL_NOTHING 7.8
|
CURL_GLOBAL_NOTHING 7.8
|
||||||
CURL_GLOBAL_SSL 7.8
|
CURL_GLOBAL_SSL 7.8
|
||||||
CURL_GLOBAL_WIN32 7.8.1
|
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_0 7.9.1
|
||||||
CURL_HTTP_VERSION_1_1 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_HTTP_VERSION_NONE 7.9.1
|
||||||
CURL_IPRESOLVE_V4 7.10.8
|
CURL_IPRESOLVE_V4 7.10.8
|
||||||
CURL_IPRESOLVE_V6 7.10.8
|
CURL_IPRESOLVE_V6 7.10.8
|
||||||
@@ -686,6 +707,9 @@ CURL_SSLVERSION_DEFAULT 7.9.2
|
|||||||
CURL_SSLVERSION_SSLv2 7.9.2
|
CURL_SSLVERSION_SSLv2 7.9.2
|
||||||
CURL_SSLVERSION_SSLv3 7.9.2
|
CURL_SSLVERSION_SSLv3 7.9.2
|
||||||
CURL_SSLVERSION_TLSv1 7.9.2
|
CURL_SSLVERSION_TLSv1 7.9.2
|
||||||
|
CURL_SSLVERSION_TLSv1_0 7.34.0
|
||||||
|
CURL_SSLVERSION_TLSv1_1 7.34.0
|
||||||
|
CURL_SSLVERSION_TLSv1_2 7.34.0
|
||||||
CURL_TIMECOND_IFMODSINCE 7.9.7
|
CURL_TIMECOND_IFMODSINCE 7.9.7
|
||||||
CURL_TIMECOND_IFUNMODSINCE 7.9.7
|
CURL_TIMECOND_IFUNMODSINCE 7.9.7
|
||||||
CURL_TIMECOND_LASTMOD 7.9.7
|
CURL_TIMECOND_LASTMOD 7.9.7
|
||||||
@@ -697,6 +721,7 @@ CURL_VERSION_CONV 7.15.4
|
|||||||
CURL_VERSION_CURLDEBUG 7.19.6
|
CURL_VERSION_CURLDEBUG 7.19.6
|
||||||
CURL_VERSION_DEBUG 7.10.6
|
CURL_VERSION_DEBUG 7.10.6
|
||||||
CURL_VERSION_GSSNEGOTIATE 7.10.6
|
CURL_VERSION_GSSNEGOTIATE 7.10.6
|
||||||
|
CURL_VERSION_HTTP2 7.33.0
|
||||||
CURL_VERSION_IDN 7.12.0
|
CURL_VERSION_IDN 7.12.0
|
||||||
CURL_VERSION_IPV6 7.10
|
CURL_VERSION_IPV6 7.10
|
||||||
CURL_VERSION_KERBEROS4 7.10
|
CURL_VERSION_KERBEROS4 7.10
|
||||||
|
|||||||
@@ -60,11 +60,16 @@ unlink (remove) certdata.txt after processing
|
|||||||
be verbose and print out processed CAs
|
be verbose and print out processed CAs
|
||||||
.SH EXIT STATUS
|
.SH EXIT STATUS
|
||||||
Returns 0 on success. Returns 1 if it fails to download data.
|
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
|
.SH SEE ALSO
|
||||||
.BR curl (1)
|
.BR curl (1)
|
||||||
.SH HISTORY
|
.SH HISTORY
|
||||||
\fBmk-ca-bundle\fP is a command line tool that is shipped as part of every
|
\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
|
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
|
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
|
improved by Guenter Knauf. This manual page was initially written by Jan
|
||||||
\&<jschauma@netmeister.org>.
|
Schaumann \&<jschauma@netmeister.org>.
|
||||||
|
|||||||
@@ -69,7 +69,7 @@
|
|||||||
require it! */
|
require it! */
|
||||||
#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
|
#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
|
||||||
defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \
|
defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \
|
||||||
defined(ANDROID) || defined(__ANDROID__) || \
|
defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \
|
||||||
(defined(__FreeBSD_version) && (__FreeBSD_version < 800000))
|
(defined(__FreeBSD_version) && (__FreeBSD_version < 800000))
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -156,12 +156,22 @@ struct curl_httppost {
|
|||||||
HTTPPOST_CALLBACK posts */
|
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,
|
typedef int (*curl_progress_callback)(void *clientp,
|
||||||
double dltotal,
|
double dltotal,
|
||||||
double dlnow,
|
double dlnow,
|
||||||
double ultotal,
|
double ultotal,
|
||||||
double ulnow);
|
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
|
#ifndef CURL_MAX_WRITE_SIZE
|
||||||
/* Tests have proven that 20K is a very bad buffer size for uploads on
|
/* 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.
|
Windows, while 16K for some odd reason performed a lot better.
|
||||||
@@ -635,16 +645,18 @@ typedef enum {
|
|||||||
|
|
||||||
#define CURL_ERROR_SIZE 256
|
#define CURL_ERROR_SIZE 256
|
||||||
|
|
||||||
|
enum curl_khtype {
|
||||||
|
CURLKHTYPE_UNKNOWN,
|
||||||
|
CURLKHTYPE_RSA1,
|
||||||
|
CURLKHTYPE_RSA,
|
||||||
|
CURLKHTYPE_DSS
|
||||||
|
};
|
||||||
|
|
||||||
struct curl_khkey {
|
struct curl_khkey {
|
||||||
const char *key; /* points to a zero-terminated string encoded with base64
|
const char *key; /* points to a zero-terminated string encoded with base64
|
||||||
if len is zero, otherwise to the "raw" data */
|
if len is zero, otherwise to the "raw" data */
|
||||||
size_t len;
|
size_t len;
|
||||||
enum type {
|
enum curl_khtype keytype;
|
||||||
CURLKHTYPE_UNKNOWN,
|
|
||||||
CURLKHTYPE_RSA1,
|
|
||||||
CURLKHTYPE_RSA,
|
|
||||||
CURLKHTYPE_DSS
|
|
||||||
} keytype;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* this is the set of return values expected from the curl_sshkeycallback
|
/* this is the set of return values expected from the curl_sshkeycallback
|
||||||
@@ -815,10 +827,10 @@ typedef enum {
|
|||||||
/* Name of proxy to use. */
|
/* Name of proxy to use. */
|
||||||
CINIT(PROXY, OBJECTPOINT, 4),
|
CINIT(PROXY, OBJECTPOINT, 4),
|
||||||
|
|
||||||
/* "name:password" to use when fetching. */
|
/* "user:password;options" to use when fetching. */
|
||||||
CINIT(USERPWD, OBJECTPOINT, 5),
|
CINIT(USERPWD, OBJECTPOINT, 5),
|
||||||
|
|
||||||
/* "name:password" to use with proxy. */
|
/* "user:password" to use with proxy. */
|
||||||
CINIT(PROXYUSERPWD, OBJECTPOINT, 6),
|
CINIT(PROXYUSERPWD, OBJECTPOINT, 6),
|
||||||
|
|
||||||
/* Range to get, specified as an ASCII string. */
|
/* Range to get, specified as an ASCII string. */
|
||||||
@@ -968,13 +980,16 @@ typedef enum {
|
|||||||
|
|
||||||
/* 55 = OBSOLETE */
|
/* 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
|
* function. This function should be defined as the curl_progress_callback
|
||||||
* prototype defines. */
|
* prototype defines. */
|
||||||
CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56),
|
CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56),
|
||||||
|
|
||||||
/* Data passed to the progress callback */
|
/* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION
|
||||||
|
callbacks */
|
||||||
CINIT(PROGRESSDATA, OBJECTPOINT, 57),
|
CINIT(PROGRESSDATA, OBJECTPOINT, 57),
|
||||||
|
#define CURLOPT_XFERINFODATA CURLOPT_PROGRESSDATA
|
||||||
|
|
||||||
/* We want the referrer field set automatically when following locations */
|
/* We want the referrer field set automatically when following locations */
|
||||||
CINIT(AUTOREFERER, LONG, 58),
|
CINIT(AUTOREFERER, LONG, 58),
|
||||||
@@ -1373,8 +1388,7 @@ typedef enum {
|
|||||||
CINIT(ADDRESS_SCOPE, LONG, 171),
|
CINIT(ADDRESS_SCOPE, LONG, 171),
|
||||||
|
|
||||||
/* Collect certificate chain info and allow it to get retrievable with
|
/* Collect certificate chain info and allow it to get retrievable with
|
||||||
CURLINFO_CERTINFO after the transfer is complete. (Unfortunately) only
|
CURLINFO_CERTINFO after the transfer is complete. */
|
||||||
working with OpenSSL-powered builds. */
|
|
||||||
CINIT(CERTINFO, LONG, 172),
|
CINIT(CERTINFO, LONG, 172),
|
||||||
|
|
||||||
/* "name" and "pwd" to use when fetching. */
|
/* "name" and "pwd" to use when fetching. */
|
||||||
@@ -1527,9 +1541,36 @@ typedef enum {
|
|||||||
/* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */
|
/* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */
|
||||||
CINIT(SSL_OPTIONS, LONG, 216),
|
CINIT(SSL_OPTIONS, LONG, 216),
|
||||||
|
|
||||||
/* set the SMTP auth originator */
|
/* Set the SMTP auth originator */
|
||||||
CINIT(MAIL_AUTH, OBJECTPOINT, 217),
|
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),
|
||||||
|
|
||||||
|
/* Set authentication options directly */
|
||||||
|
CINIT(LOGIN_OPTIONS, OBJECTPOINT, 224),
|
||||||
|
|
||||||
CURLOPT_LASTENTRY /* the last unused */
|
CURLOPT_LASTENTRY /* the last unused */
|
||||||
} CURLoption;
|
} CURLoption;
|
||||||
|
|
||||||
@@ -1582,6 +1623,7 @@ enum {
|
|||||||
for us! */
|
for us! */
|
||||||
CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */
|
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_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 */
|
CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */
|
||||||
};
|
};
|
||||||
@@ -1619,9 +1661,12 @@ enum CURL_NETRC_OPTION {
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
CURL_SSLVERSION_DEFAULT,
|
CURL_SSLVERSION_DEFAULT,
|
||||||
CURL_SSLVERSION_TLSv1,
|
CURL_SSLVERSION_TLSv1, /* TLS 1.x */
|
||||||
CURL_SSLVERSION_SSLv2,
|
CURL_SSLVERSION_SSLv2,
|
||||||
CURL_SSLVERSION_SSLv3,
|
CURL_SSLVERSION_SSLv3,
|
||||||
|
CURL_SSLVERSION_TLSv1_0,
|
||||||
|
CURL_SSLVERSION_TLSv1_1,
|
||||||
|
CURL_SSLVERSION_TLSv1_2,
|
||||||
|
|
||||||
CURL_SSLVERSION_LAST /* never use, keep last */
|
CURL_SSLVERSION_LAST /* never use, keep last */
|
||||||
};
|
};
|
||||||
@@ -1940,6 +1985,28 @@ struct curl_certinfo {
|
|||||||
format "name: value" */
|
format "name: value" */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* enum for the different supported SSL backends */
|
||||||
|
typedef enum {
|
||||||
|
CURLSSLBACKEND_NONE = 0,
|
||||||
|
CURLSSLBACKEND_OPENSSL = 1,
|
||||||
|
CURLSSLBACKEND_GNUTLS = 2,
|
||||||
|
CURLSSLBACKEND_NSS = 3,
|
||||||
|
CURLSSLBACKEND_QSOSSL = 4,
|
||||||
|
CURLSSLBACKEND_GSKIT = 5,
|
||||||
|
CURLSSLBACKEND_POLARSSL = 6,
|
||||||
|
CURLSSLBACKEND_CYASSL = 7,
|
||||||
|
CURLSSLBACKEND_SCHANNEL = 8,
|
||||||
|
CURLSSLBACKEND_DARWINSSL = 9
|
||||||
|
} curl_sslbackend;
|
||||||
|
|
||||||
|
/* Information about the SSL library used and the respective internal SSL
|
||||||
|
handle, which can be used to obtain further information regarding the
|
||||||
|
connection. Asked for with CURLINFO_TLS_SESSION. */
|
||||||
|
struct curl_tlssessioninfo {
|
||||||
|
curl_sslbackend backend;
|
||||||
|
void *internals;
|
||||||
|
};
|
||||||
|
|
||||||
#define CURLINFO_STRING 0x100000
|
#define CURLINFO_STRING 0x100000
|
||||||
#define CURLINFO_LONG 0x200000
|
#define CURLINFO_LONG 0x200000
|
||||||
#define CURLINFO_DOUBLE 0x300000
|
#define CURLINFO_DOUBLE 0x300000
|
||||||
@@ -1991,9 +2058,10 @@ typedef enum {
|
|||||||
CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40,
|
CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40,
|
||||||
CURLINFO_LOCAL_IP = CURLINFO_STRING + 41,
|
CURLINFO_LOCAL_IP = CURLINFO_STRING + 41,
|
||||||
CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42,
|
CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42,
|
||||||
|
CURLINFO_TLS_SESSION = CURLINFO_SLIST + 43,
|
||||||
/* Fill in new entries below here! */
|
/* Fill in new entries below here! */
|
||||||
|
|
||||||
CURLINFO_LASTONE = 42
|
CURLINFO_LASTONE = 43
|
||||||
} CURLINFO;
|
} CURLINFO;
|
||||||
|
|
||||||
/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
|
/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
|
||||||
@@ -2145,6 +2213,7 @@ typedef struct {
|
|||||||
#define CURL_VERSION_CURLDEBUG (1<<13) /* debug memory tracking supported */
|
#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_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */
|
||||||
#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegating to winbind helper */
|
#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()
|
* NAME curl_version_info()
|
||||||
|
|||||||
@@ -58,51 +58,52 @@
|
|||||||
/* ================================================================ */
|
/* ================================================================ */
|
||||||
|
|
||||||
#ifdef CURL_SIZEOF_LONG
|
#ifdef CURL_SIZEOF_LONG
|
||||||
# error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h"
|
#error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h"
|
||||||
Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined
|
Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
|
#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
|
||||||
# error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
|
#error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
|
||||||
Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined
|
Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURL_SIZEOF_CURL_SOCKLEN_T
|
#ifdef CURL_SIZEOF_CURL_SOCKLEN_T
|
||||||
# error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
|
#error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
|
||||||
Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined
|
Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURL_TYPEOF_CURL_OFF_T
|
#ifdef CURL_TYPEOF_CURL_OFF_T
|
||||||
# error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
|
#error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
|
||||||
Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined
|
Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURL_FORMAT_CURL_OFF_T
|
#ifdef CURL_FORMAT_CURL_OFF_T
|
||||||
# error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h"
|
#error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h"
|
||||||
Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined
|
Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURL_FORMAT_CURL_OFF_TU
|
#ifdef CURL_FORMAT_CURL_OFF_TU
|
||||||
# error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h"
|
#error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h"
|
||||||
Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined
|
Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURL_FORMAT_OFF_T
|
#ifdef CURL_FORMAT_OFF_T
|
||||||
# error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h"
|
#error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h"
|
||||||
Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined
|
Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURL_SIZEOF_CURL_OFF_T
|
#ifdef CURL_SIZEOF_CURL_OFF_T
|
||||||
# error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
|
#error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
|
||||||
Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined
|
Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURL_SUFFIX_CURL_OFF_T
|
#ifdef CURL_SUFFIX_CURL_OFF_T
|
||||||
# error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h"
|
#error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h"
|
||||||
Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined
|
Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURL_SUFFIX_CURL_OFF_TU
|
#ifdef CURL_SUFFIX_CURL_OFF_TU
|
||||||
# error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h"
|
#error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h"
|
||||||
Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined
|
Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -110,71 +111,87 @@
|
|||||||
/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */
|
/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */
|
||||||
/* ================================================================ */
|
/* ================================================================ */
|
||||||
|
|
||||||
|
/* Configure process defines this to 1 when it finds out that system */
|
||||||
|
/* header file ws2tcpip.h must be included by the external interface. */
|
||||||
|
#cmakedefine CURL_PULL_WS2TCPIP_H
|
||||||
|
#ifdef CURL_PULL_WS2TCPIP_H
|
||||||
|
# ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
# define WIN32_LEAN_AND_MEAN
|
||||||
|
# endif
|
||||||
|
# include <windows.h>
|
||||||
|
# include <winsock2.h>
|
||||||
|
# include <ws2tcpip.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Configure process defines this to 1 when it finds out that system */
|
/* Configure process defines this to 1 when it finds out that system */
|
||||||
/* header file sys/types.h must be included by the external interface. */
|
/* header file sys/types.h must be included by the external interface. */
|
||||||
#cmakedefine CURL_PULL_SYS_TYPES_H ${CURL_PULL_SYS_TYPES_H}
|
#cmakedefine CURL_PULL_SYS_TYPES_H
|
||||||
#ifdef CURL_PULL_SYS_TYPES_H
|
#ifdef CURL_PULL_SYS_TYPES_H
|
||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Configure process defines this to 1 when it finds out that system */
|
/* Configure process defines this to 1 when it finds out that system */
|
||||||
/* header file stdint.h must be included by the external interface. */
|
/* header file stdint.h must be included by the external interface. */
|
||||||
#cmakedefine CURL_PULL_STDINT_H ${CURL_PULL_STDINT_H}
|
#cmakedefine CURL_PULL_STDINT_H
|
||||||
#ifdef CURL_PULL_STDINT_H
|
#ifdef CURL_PULL_STDINT_H
|
||||||
# include <stdint.h>
|
# include <stdint.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Configure process defines this to 1 when it finds out that system */
|
/* Configure process defines this to 1 when it finds out that system */
|
||||||
/* header file inttypes.h must be included by the external interface. */
|
/* header file inttypes.h must be included by the external interface. */
|
||||||
#cmakedefine CURL_PULL_INTTYPES_H ${CURL_PULL_INTTYPES_H}
|
#cmakedefine CURL_PULL_INTTYPES_H
|
||||||
#ifdef CURL_PULL_INTTYPES_H
|
#ifdef CURL_PULL_INTTYPES_H
|
||||||
# include <inttypes.h>
|
# include <inttypes.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The size of `long', as computed by sizeof. */
|
/* Configure process defines this to 1 when it finds out that system */
|
||||||
#cmakedefine CURL_SIZEOF_LONG ${CURL_SIZEOF_LONG}
|
/* header file sys/socket.h must be included by the external interface. */
|
||||||
|
#cmakedefine CURL_PULL_SYS_SOCKET_H
|
||||||
/* Integral data type used for curl_socklen_t. */
|
#ifdef CURL_PULL_SYS_SOCKET_H
|
||||||
#cmakedefine CURL_TYPEOF_CURL_SOCKLEN_T ${CURL_TYPEOF_CURL_SOCKLEN_T}
|
|
||||||
|
|
||||||
/* on windows socklen_t is in here */
|
|
||||||
#ifdef _WIN32
|
|
||||||
# include <winsock2.h>
|
|
||||||
# include <ws2tcpip.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Configure process defines this to 1 when it finds out that system */
|
||||||
|
/* header file sys/poll.h must be included by the external interface. */
|
||||||
|
#cmakedefine CURL_PULL_SYS_POLL_H
|
||||||
|
#ifdef CURL_PULL_SYS_POLL_H
|
||||||
|
# include <sys/poll.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The size of `long', as computed by sizeof. */
|
||||||
|
#define CURL_SIZEOF_LONG ${CURL_SIZEOF_LONG}
|
||||||
|
|
||||||
|
/* Integral data type used for curl_socklen_t. */
|
||||||
|
#define CURL_TYPEOF_CURL_SOCKLEN_T ${CURL_TYPEOF_CURL_SOCKLEN_T}
|
||||||
|
|
||||||
|
/* The size of `curl_socklen_t', as computed by sizeof. */
|
||||||
|
#define CURL_SIZEOF_CURL_SOCKLEN_T ${CURL_SIZEOF_CURL_SOCKLEN_T}
|
||||||
|
|
||||||
/* Data type definition of curl_socklen_t. */
|
/* Data type definition of curl_socklen_t. */
|
||||||
typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t;
|
typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t;
|
||||||
|
|
||||||
/* The size of `curl_socklen_t', as computed by sizeof. */
|
|
||||||
#cmakedefine CURL_SIZEOF_CURL_SOCKLEN_T ${CURL_SIZEOF_CURL_SOCKLEN_T}
|
|
||||||
|
|
||||||
/* Signed integral data type used for curl_off_t. */
|
/* Signed integral data type used for curl_off_t. */
|
||||||
#cmakedefine CURL_TYPEOF_CURL_OFF_T ${CURL_TYPEOF_CURL_OFF_T}
|
#define CURL_TYPEOF_CURL_OFF_T ${CURL_TYPEOF_CURL_OFF_T}
|
||||||
|
|
||||||
/* Data type definition of curl_off_t. */
|
/* Data type definition of curl_off_t. */
|
||||||
typedef CURL_TYPEOF_CURL_OFF_T curl_off_t;
|
typedef CURL_TYPEOF_CURL_OFF_T curl_off_t;
|
||||||
|
|
||||||
/* curl_off_t formatting string directive without "%" conversion specifier. */
|
/* curl_off_t formatting string directive without "%" conversion specifier. */
|
||||||
#cmakedefine CURL_FORMAT_CURL_OFF_T "${CURL_FORMAT_CURL_OFF_T}"
|
#define CURL_FORMAT_CURL_OFF_T "${CURL_FORMAT_CURL_OFF_T}"
|
||||||
|
|
||||||
/* unsigned curl_off_t formatting string without "%" conversion specifier. */
|
/* unsigned curl_off_t formatting string without "%" conversion specifier. */
|
||||||
#cmakedefine CURL_FORMAT_CURL_OFF_TU "${CURL_FORMAT_CURL_OFF_TU}"
|
#define CURL_FORMAT_CURL_OFF_TU "${CURL_FORMAT_CURL_OFF_TU}"
|
||||||
|
|
||||||
/* curl_off_t formatting string directive with "%" conversion specifier. */
|
/* curl_off_t formatting string directive with "%" conversion specifier. */
|
||||||
#cmakedefine CURL_FORMAT_OFF_T "${CURL_FORMAT_OFF_T}"
|
#define CURL_FORMAT_OFF_T "${CURL_FORMAT_OFF_T}"
|
||||||
|
|
||||||
/* The size of `curl_off_t', as computed by sizeof. */
|
/* The size of `curl_off_t', as computed by sizeof. */
|
||||||
#cmakedefine CURL_SIZEOF_CURL_OFF_T ${CURL_SIZEOF_CURL_OFF_T}
|
#define CURL_SIZEOF_CURL_OFF_T ${CURL_SIZEOF_CURL_OFF_T}
|
||||||
|
|
||||||
/* curl_off_t constant suffix. */
|
/* curl_off_t constant suffix. */
|
||||||
#cmakedefine CURL_SUFFIX_CURL_OFF_T ${CURL_SUFFIX_CURL_OFF_T}
|
#define CURL_SUFFIX_CURL_OFF_T ${CURL_SUFFIX_CURL_OFF_T}
|
||||||
|
|
||||||
/* unsigned curl_off_t constant suffix. */
|
/* unsigned curl_off_t constant suffix. */
|
||||||
#cmakedefine CURL_SUFFIX_CURL_OFF_TU ${CURL_SUFFIX_CURL_OFF_TU}
|
#define CURL_SUFFIX_CURL_OFF_TU ${CURL_SUFFIX_CURL_OFF_TU}
|
||||||
|
|
||||||
#endif /* __CURL_CURLBUILD_H */
|
#endif /* __CURL_CURLBUILD_H */
|
||||||
|
|||||||
@@ -30,12 +30,12 @@
|
|||||||
|
|
||||||
/* This is the version number of the libcurl package from which this header
|
/* This is the version number of the libcurl package from which this header
|
||||||
file origins: */
|
file origins: */
|
||||||
#define LIBCURL_VERSION "7.30.0-DEV"
|
#define LIBCURL_VERSION "7.34.0-DEV"
|
||||||
|
|
||||||
/* The numeric version number is also available "in parts" by using these
|
/* The numeric version number is also available "in parts" by using these
|
||||||
defines: */
|
defines: */
|
||||||
#define LIBCURL_VERSION_MAJOR 7
|
#define LIBCURL_VERSION_MAJOR 7
|
||||||
#define LIBCURL_VERSION_MINOR 30
|
#define LIBCURL_VERSION_MINOR 34
|
||||||
#define LIBCURL_VERSION_PATCH 0
|
#define LIBCURL_VERSION_PATCH 0
|
||||||
|
|
||||||
/* This is the numeric version of the libcurl version number, meant for easier
|
/* 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
|
and it is always a greater number in a more recent release. It makes
|
||||||
comparisons with greater than and less than work.
|
comparisons with greater than and less than work.
|
||||||
*/
|
*/
|
||||||
#define LIBCURL_VERSION_NUM 0x071e00
|
#define LIBCURL_VERSION_NUM 0x072200
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the date and time when the full source package was created. The
|
* This is the date and time when the full source package was created. The
|
||||||
|
|||||||
@@ -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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* 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_INTERNAL_ERROR, /* this is a libcurl bug */
|
||||||
CURLM_BAD_SOCKET, /* the passed in socket argument did not match */
|
CURLM_BAD_SOCKET, /* the passed in socket argument did not match */
|
||||||
CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */
|
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
|
CURLM_LAST
|
||||||
} CURLMcode;
|
} CURLMcode;
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -264,6 +264,12 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
|
|||||||
(option) == CURLOPT_RTSP_SESSION_ID || \
|
(option) == CURLOPT_RTSP_SESSION_ID || \
|
||||||
(option) == CURLOPT_RTSP_STREAM_URI || \
|
(option) == CURLOPT_RTSP_STREAM_URI || \
|
||||||
(option) == CURLOPT_RTSP_TRANSPORT || \
|
(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 || \
|
||||||
|
(option) == CURLOPT_LOGIN_OPTIONS || \
|
||||||
0)
|
0)
|
||||||
|
|
||||||
/* evaluates to true if option takes a curl_write_callback argument */
|
/* evaluates to true if option takes a curl_write_callback argument */
|
||||||
|
|||||||
@@ -94,6 +94,10 @@ add_library(
|
|||||||
${HHEADERS} ${CSOURCES}
|
${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})
|
target_link_libraries(${LIB_NAME} ${CURL_LIBS})
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
@@ -108,14 +112,6 @@ setup_curl_dependencies(${LIB_NAME})
|
|||||||
set_target_properties(${LIB_NAME} PROPERTIES PREFIX "")
|
set_target_properties(${LIB_NAME} PROPERTIES PREFIX "")
|
||||||
set_target_properties(${LIB_NAME} PROPERTIES IMPORT_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(WIN32)
|
||||||
if(NOT CURL_STATICLIB)
|
if(NOT CURL_STATICLIB)
|
||||||
# Add "_imp" as a suffix before the extension to avoid conflicting with the statically linked "libcurl.lib"
|
# Add "_imp" as a suffix before the extension to avoid conflicting with the statically linked "libcurl.lib"
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ CFLAGS += -dWANT_IDN_PROTOTYPES
|
|||||||
!ifdef %zlib_root
|
!ifdef %zlib_root
|
||||||
ZLIB_ROOT = $(%zlib_root)
|
ZLIB_ROOT = $(%zlib_root)
|
||||||
!else
|
!else
|
||||||
ZLIB_ROOT = ..$(DS)..$(DS)zlib-1.2.7
|
ZLIB_ROOT = ..$(DS)..$(DS)zlib-1.2.8
|
||||||
!endif
|
!endif
|
||||||
|
|
||||||
!ifdef %libssh2_root
|
!ifdef %libssh2_root
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ libcurl_la_CFLAGS_EXTRA += $(CFLAG_CURL_SYMBOL_HIDING)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
libcurl_la_CPPFLAGS = $(AM_CPPFLAGS) $(libcurl_la_CPPFLAGS_EXTRA)
|
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)
|
libcurl_la_CFLAGS = $(AM_CFLAGS) $(libcurl_la_CFLAGS_EXTRA)
|
||||||
|
|
||||||
libcurlu_la_CPPFLAGS = $(AM_CPPFLAGS) -DCURL_STATICLIB -DUNITTESTS
|
libcurlu_la_CPPFLAGS = $(AM_CPPFLAGS) -DCURL_STATICLIB -DUNITTESTS
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ BCCDIR = $(MAKEDIR)\..
|
|||||||
|
|
||||||
# Edit the path below to point to the base of your Zlib sources.
|
# Edit the path below to point to the base of your Zlib sources.
|
||||||
!ifndef ZLIB_PATH
|
!ifndef ZLIB_PATH
|
||||||
ZLIB_PATH = ..\..\zlib-1.2.7
|
ZLIB_PATH = ..\..\zlib-1.2.8
|
||||||
!endif
|
!endif
|
||||||
|
|
||||||
# Edit the path below to point to the base of your OpenSSL package.
|
# Edit the path below to point to the base of your OpenSSL package.
|
||||||
@@ -52,7 +52,7 @@ LDFLAGS = -q -lq -laa -tWD
|
|||||||
SRCDIR = .
|
SRCDIR = .
|
||||||
OBJDIR = .\BCC_objs
|
OBJDIR = .\BCC_objs
|
||||||
INCDIRS = -I.;..\include
|
INCDIRS = -I.;..\include
|
||||||
LINKLIB = $(BCCDIR)\lib\cw32mt.lib
|
LINKLIB = $(BCCDIR)\lib\cw32mt.lib $(BCCDIR)\lib\ws2_32.lib
|
||||||
DEFINES = -DNDEBUG -DWIN32 -DBUILDING_LIBCURL
|
DEFINES = -DNDEBUG -DWIN32 -DBUILDING_LIBCURL
|
||||||
|
|
||||||
# By default SSPI support is enabled for BCC
|
# 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
|
# Makefile.inc provides the CSOURCES and HHEADERS defines
|
||||||
!include Makefile.inc
|
!include Makefile.inc
|
||||||
|
|
||||||
OBJECTS = $(CSOURCES:.c=.obj)
|
# Borland's command line librarian program TLIB version 4.5 is not capable
|
||||||
PREPROCESSED = $(CSOURCES:.c=.int)
|
# 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:
|
.c.obj:
|
||||||
@-$(RM) $(@R).int
|
@-$(RM) $(@R).int
|
||||||
@@ -98,6 +114,21 @@ PREPROCESSED = $(CSOURCES:.c=.int)
|
|||||||
|
|
||||||
all: $(OBJDIR) $(LIBCURL_LIB) $(LIBCURL_DLL)
|
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:
|
clean:
|
||||||
cd $(OBJDIR)
|
cd $(OBJDIR)
|
||||||
@-$(RM) $(OBJECTS)
|
@-$(RM) $(OBJECTS)
|
||||||
@@ -122,7 +153,10 @@ $(LIBCURL_LIB): $(OBJECTS)
|
|||||||
$(LIBCURL_DLL) $(LIBCURL_IMPLIB): $(OBJECTS) $(LINKLIB)
|
$(LIBCURL_DLL) $(LIBCURL_IMPLIB): $(OBJECTS) $(LINKLIB)
|
||||||
@-$(RM) $(LIBCURL_DLL)
|
@-$(RM) $(LIBCURL_DLL)
|
||||||
@-$(RM) $(LIBCURL_IMPLIB)
|
@-$(RM) $(LIBCURL_IMPLIB)
|
||||||
$(LD) $(LDFLAGS) -e$(LIBCURL_DLL) $**
|
$(LD) $(LDFLAGS) -e$(LIBCURL_DLL) @&&!
|
||||||
|
$(**: = ^
|
||||||
|
)
|
||||||
|
!
|
||||||
$(IMPLIB) $(LIBCURL_IMPLIB) $(LIBCURL_DLL)
|
$(IMPLIB) $(LIBCURL_IMPLIB) $(LIBCURL_DLL)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,10 +10,10 @@
|
|||||||
CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
|
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 \
|
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 \
|
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 \
|
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 \
|
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 \
|
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 \
|
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 \
|
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 \
|
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_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 \
|
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 \
|
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 \
|
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 \
|
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 \
|
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 \
|
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 \
|
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 \
|
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_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 \
|
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 sigpipe.h
|
||||||
|
|||||||
@@ -7,14 +7,14 @@
|
|||||||
## Example: mingw32-make -f Makefile.m32 CFG=-zlib-ssl-sspi-winidn
|
## Example: mingw32-make -f Makefile.m32 CFG=-zlib-ssl-sspi-winidn
|
||||||
##
|
##
|
||||||
## Hint: you can also set environment vars to control the build, f.e.:
|
## 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
|
## set ZLIB=1
|
||||||
#
|
#
|
||||||
###########################################################################
|
###########################################################################
|
||||||
|
|
||||||
# Edit the path below to point to the base of your Zlib sources.
|
# Edit the path below to point to the base of your Zlib sources.
|
||||||
ifndef ZLIB_PATH
|
ifndef ZLIB_PATH
|
||||||
ZLIB_PATH = ../../zlib-1.2.7
|
ZLIB_PATH = ../../zlib-1.2.8
|
||||||
endif
|
endif
|
||||||
# Edit the path below to point to the base of your OpenSSL package.
|
# Edit the path below to point to the base of your OpenSSL package.
|
||||||
ifndef OPENSSL_PATH
|
ifndef OPENSSL_PATH
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ endif
|
|||||||
|
|
||||||
# Edit the path below to point to the base of your Zlib sources.
|
# Edit the path below to point to the base of your Zlib sources.
|
||||||
ifndef ZLIB_PATH
|
ifndef ZLIB_PATH
|
||||||
ZLIB_PATH = ../../zlib-1.2.7
|
ZLIB_PATH = ../../zlib-1.2.8
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Edit the path below to point to the base of your OpenSSL package.
|
# Edit the path below to point to the base of your OpenSSL package.
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ LIBSSH2_PATH = ../../libssh2-1.4.3
|
|||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
!IFNDEF ZLIB_PATH
|
!IFNDEF ZLIB_PATH
|
||||||
ZLIB_PATH = ../../zlib-1.2.7
|
ZLIB_PATH = ../../zlib-1.2.8
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
!IFNDEF MACHINE
|
!IFNDEF MACHINE
|
||||||
@@ -103,23 +103,24 @@ WINDOWS_SDK_PATH = "$(PROGRAMFILES)\Microsoft SDK"
|
|||||||
#############################################################
|
#############################################################
|
||||||
## Nothing more to do below this line!
|
## Nothing more to do below this line!
|
||||||
|
|
||||||
CCNODBG = cl.exe /O2 /DNDEBUG
|
CCNODBG = cl.exe /O2 /DNDEBUG
|
||||||
CCDEBUG = cl.exe /Od /Gm /Zi /D_DEBUG /GZ
|
CCDEBUG = cl.exe /Od /Gm /Zi /D_DEBUG /GZ
|
||||||
CFLAGSSSL = /DUSE_SSLEAY /DUSE_OPENSSL /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
|
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"
|
CFLAGSWINSSL = /DUSE_SCHANNEL
|
||||||
CFLAGSZLIB = /DHAVE_ZLIB_H /DHAVE_ZLIB /DHAVE_LIBZ /I "$(ZLIB_PATH)"
|
CFLAGSSSH2 = /DUSE_LIBSSH2 /DCURL_DISABLE_LDAP /DHAVE_LIBSSH2 /DHAVE_LIBSSH2_H /DLIBSSH2_WIN32 /DLIBSSH2_LIBRARY /I "$(LIBSSH2_PATH)/include"
|
||||||
CFLAGS = /I. /I../include /nologo /W3 /GX /DWIN32 /YX /FD /c /DBUILDING_LIBCURL /D_BIND_TO_CURRENT_VCLIBS_VERSION=1
|
CFLAGSZLIB = /DHAVE_ZLIB_H /DHAVE_ZLIB /DHAVE_LIBZ /I "$(ZLIB_PATH)"
|
||||||
CFLAGSLIB = /DCURL_STATICLIB
|
CFLAGS = /I. /I../include /nologo /W3 /GX /DWIN32 /YX /FD /c /DBUILDING_LIBCURL /D_BIND_TO_CURRENT_VCLIBS_VERSION=1
|
||||||
LNKDLL = link.exe /DLL
|
CFLAGSLIB = /DCURL_STATICLIB
|
||||||
LNKLIB = link.exe /lib
|
LNKDLL = link.exe /DLL
|
||||||
LFLAGS = /nologo /machine:$(MACHINE)
|
LNKLIB = link.exe /lib
|
||||||
SSLLIBS = libeay32.lib ssleay32.lib
|
LFLAGS = /nologo /machine:$(MACHINE)
|
||||||
ZLIBLIBSDLL= zdll.lib
|
SSLLIBS = libeay32.lib ssleay32.lib
|
||||||
ZLIBLIBS = zlib.lib
|
ZLIBLIBSDLL = zdll.lib
|
||||||
WINLIBS = ws2_32.lib wldap32.lib advapi32.lib
|
ZLIBLIBS = zlib.lib
|
||||||
CFLAGS = $(CFLAGS)
|
WINLIBS = ws2_32.lib wldap32.lib advapi32.lib
|
||||||
|
CFLAGS = $(CFLAGS)
|
||||||
|
|
||||||
CFGSET = FALSE
|
CFGSET = FALSE
|
||||||
|
|
||||||
!IFDEF WINDOWS_SSPI
|
!IFDEF WINDOWS_SSPI
|
||||||
CFLAGS = $(CFLAGS) /DUSE_WINDOWS_SSPI /I$(WINDOWS_SDK_PATH)\include
|
CFLAGS = $(CFLAGS) /DUSE_WINDOWS_SSPI /I$(WINDOWS_SDK_PATH)\include
|
||||||
@@ -189,6 +190,18 @@ CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
|||||||
CFGSET = TRUE
|
CFGSET = TRUE
|
||||||
!ENDIF
|
!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
|
# release-ssl-ssh2-zlib
|
||||||
|
|
||||||
@@ -515,7 +528,6 @@ X_OBJS= \
|
|||||||
$(DIROBJ)\curl_ntlm_core.obj \
|
$(DIROBJ)\curl_ntlm_core.obj \
|
||||||
$(DIROBJ)\curl_ntlm_msgs.obj \
|
$(DIROBJ)\curl_ntlm_msgs.obj \
|
||||||
$(DIROBJ)\curl_ntlm_wb.obj \
|
$(DIROBJ)\curl_ntlm_wb.obj \
|
||||||
$(DIROBJ)\curl_rand.obj \
|
|
||||||
$(DIROBJ)\curl_rtmp.obj \
|
$(DIROBJ)\curl_rtmp.obj \
|
||||||
$(DIROBJ)\curl_sasl.obj \
|
$(DIROBJ)\curl_sasl.obj \
|
||||||
$(DIROBJ)\curl_schannel.obj \
|
$(DIROBJ)\curl_schannel.obj \
|
||||||
@@ -523,6 +535,7 @@ X_OBJS= \
|
|||||||
$(DIROBJ)\curl_threads.obj \
|
$(DIROBJ)\curl_threads.obj \
|
||||||
$(DIROBJ)\cyassl.obj \
|
$(DIROBJ)\cyassl.obj \
|
||||||
$(DIROBJ)\dict.obj \
|
$(DIROBJ)\dict.obj \
|
||||||
|
$(DIROBJ)\dotdot.obj \
|
||||||
$(DIROBJ)\easy.obj \
|
$(DIROBJ)\easy.obj \
|
||||||
$(DIROBJ)\escape.obj \
|
$(DIROBJ)\escape.obj \
|
||||||
$(DIROBJ)\file.obj \
|
$(DIROBJ)\file.obj \
|
||||||
@@ -553,7 +566,6 @@ X_OBJS= \
|
|||||||
$(DIROBJ)\imap.obj \
|
$(DIROBJ)\imap.obj \
|
||||||
$(DIROBJ)\inet_ntop.obj \
|
$(DIROBJ)\inet_ntop.obj \
|
||||||
$(DIROBJ)\inet_pton.obj \
|
$(DIROBJ)\inet_pton.obj \
|
||||||
$(DIROBJ)\krb4.obj \
|
|
||||||
$(DIROBJ)\krb5.obj \
|
$(DIROBJ)\krb5.obj \
|
||||||
$(DIROBJ)\ldap.obj \
|
$(DIROBJ)\ldap.obj \
|
||||||
$(DIROBJ)\llist.obj \
|
$(DIROBJ)\llist.obj \
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ USER_CFLAGS:=
|
|||||||
# directories where to seek for includes and libraries
|
# directories where to seek for includes and libraries
|
||||||
OPENSSL_INC := D:/libraries/openssl/openssl-0.9.8y-vxWorks6.3/include
|
OPENSSL_INC := D:/libraries/openssl/openssl-0.9.8y-vxWorks6.3/include
|
||||||
OPENSSL_LIB := D:/libraries/openssl/openssl-0.9.8y-vxWorks6.3
|
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_INC := D:/libraries/zlib/zlib-1.2.8-VxWorks6.3/zlib-1.2.8
|
||||||
ZLIB_LIB := D:/libraries/zlib/zlib-1.2.7-VxWorks6.3/binaries/vxworks_3.1_gnu/Debug/lib
|
ZLIB_LIB := D:/libraries/zlib/zlib-1.2.8-VxWorks6.3/binaries/vxworks_3.1_gnu/Debug/lib
|
||||||
ARES_INC :=
|
ARES_INC :=
|
||||||
ARES_LIB :=
|
ARES_LIB :=
|
||||||
|
|
||||||
|
|||||||
31
lib/README.http2
Normal file
31
lib/README.http2
Normal 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?
|
||||||
133
lib/asyn-ares.c
133
lib/asyn-ares.c
@@ -315,6 +315,7 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
|||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
struct ResolverResults *res = (struct ResolverResults *)
|
struct ResolverResults *res = (struct ResolverResults *)
|
||||||
conn->async.os_specific;
|
conn->async.os_specific;
|
||||||
|
CURLcode rc = CURLE_OK;
|
||||||
|
|
||||||
*dns = NULL;
|
*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
|
/* temp_ai ownership is moved to the connection, so we need not free-up
|
||||||
them */
|
them */
|
||||||
res->temp_ai = NULL;
|
res->temp_ai = NULL;
|
||||||
destroy_async_data(&conn->async);
|
|
||||||
if(!conn->async.dns) {
|
if(!conn->async.dns) {
|
||||||
failf(data, "Could not resolve %s: %s (%s)",
|
failf(data, "Could not resolve: %s (%s)",
|
||||||
conn->bits.proxy?"proxy":"host",
|
conn->async.hostname, ares_strerror(conn->async.status));
|
||||||
conn->host.dispname,
|
rc = conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
|
||||||
ares_strerror(conn->async.status));
|
|
||||||
return conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
|
|
||||||
CURLE_COULDNT_RESOLVE_HOST;
|
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)
|
if(entry)
|
||||||
*entry = conn->async.dns;
|
*entry = conn->async.dns;
|
||||||
|
|
||||||
if(!conn->async.dns) {
|
if(rc)
|
||||||
/* 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;
|
|
||||||
|
|
||||||
/* close the connection, since we can't return failure here without
|
/* 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;
|
conn->bits.close = TRUE;
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -614,8 +590,19 @@ CURLcode Curl_set_dns_servers(struct SessionHandle *data,
|
|||||||
char *servers)
|
char *servers)
|
||||||
{
|
{
|
||||||
CURLcode result = CURLE_NOT_BUILT_IN;
|
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)
|
#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) {
|
switch(ares_result) {
|
||||||
case ARES_SUCCESS:
|
case ARES_SUCCESS:
|
||||||
result = CURLE_OK;
|
result = CURLE_OK;
|
||||||
@@ -632,8 +619,76 @@ CURLcode Curl_set_dns_servers(struct SessionHandle *data,
|
|||||||
}
|
}
|
||||||
#else /* too old c-ares version! */
|
#else /* too old c-ares version! */
|
||||||
(void)data;
|
(void)data;
|
||||||
(void)servers;
|
(void)(ares_result);
|
||||||
#endif
|
#endif
|
||||||
return result;
|
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)
|
||||||
|
struct in_addr a4;
|
||||||
|
|
||||||
|
if((!local_ip4) || (local_ip4[0] == 0)) {
|
||||||
|
a4.s_addr = 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.s_addr));
|
||||||
|
|
||||||
|
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 */
|
#endif /* CURLRES_ARES */
|
||||||
|
|||||||
@@ -265,7 +265,7 @@ static int getaddrinfo_complete(struct connectdata *conn)
|
|||||||
static unsigned int CURL_STDCALL getaddrinfo_thread (void *arg)
|
static unsigned int CURL_STDCALL getaddrinfo_thread (void *arg)
|
||||||
{
|
{
|
||||||
struct thread_sync_data *tsd = (struct thread_sync_data*)arg;
|
struct thread_sync_data *tsd = (struct thread_sync_data*)arg;
|
||||||
char service [NI_MAXSERV];
|
char service[12];
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
snprintf(service, sizeof(service), "%d", tsd->port);
|
snprintf(service, sizeof(service), "%d", tsd->port);
|
||||||
@@ -559,7 +559,7 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
|||||||
struct in_addr in;
|
struct in_addr in;
|
||||||
Curl_addrinfo *res;
|
Curl_addrinfo *res;
|
||||||
int error;
|
int error;
|
||||||
char sbuf[NI_MAXSERV];
|
char sbuf[12];
|
||||||
int pf = PF_INET;
|
int pf = PF_INET;
|
||||||
#ifdef CURLRES_IPV6
|
#ifdef CURLRES_IPV6
|
||||||
struct in6_addr in6;
|
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 */
|
#endif /* CURLRES_THREADED */
|
||||||
|
|||||||
275
lib/axtls.c
275
lib/axtls.c
@@ -41,26 +41,12 @@
|
|||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
#include "curl_memory.h"
|
#include "curl_memory.h"
|
||||||
|
#include <unistd.h>
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#include "hostcheck.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() */
|
/* Global axTLS init, called from Curl_ssl_init() */
|
||||||
int Curl_axtls_init(void)
|
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_recv axtls_recv;
|
||||||
static Curl_send axtls_send;
|
static Curl_send axtls_send;
|
||||||
|
|
||||||
/*
|
static void free_ssl_structs(struct ssl_connect_data *connssl)
|
||||||
* This function is called after the TCP connect has completed. Setup the TLS
|
{
|
||||||
* layer and do all necessary magic.
|
if(connssl->ssl) {
|
||||||
*/
|
ssl_free (connssl->ssl);
|
||||||
CURLcode
|
connssl->ssl = NULL;
|
||||||
Curl_axtls_connect(struct connectdata *conn,
|
}
|
||||||
int sockindex)
|
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;
|
struct SessionHandle *data = conn->data;
|
||||||
SSL_CTX *ssl_ctx;
|
SSL_CTX *ssl_ctx;
|
||||||
SSL *ssl;
|
SSL *ssl = NULL;
|
||||||
int cert_types[] = {SSL_OBJ_X509_CERT, SSL_OBJ_PKCS12, 0};
|
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 key_types[] = {SSL_OBJ_RSA_KEY, SSL_OBJ_PKCS8, SSL_OBJ_PKCS12, 0};
|
||||||
int i, ssl_fcn_return;
|
int i, ssl_fcn_return;
|
||||||
const uint8_t *ssl_sessionid;
|
const uint8_t *ssl_sessionid;
|
||||||
size_t ssl_idsize;
|
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 */
|
/* Assuming users will not compile in custom key/cert to axTLS.
|
||||||
uint32_t client_option = SSL_NO_DEFAULT_KEY|SSL_SERVER_VERIFY_LATER;
|
* 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)
|
if(conn->ssl[sockindex].state == ssl_connection_complete)
|
||||||
/* to make us tolerant against being called more than once for the
|
/* to make us tolerant against being called more than once for the
|
||||||
@@ -169,7 +164,8 @@ Curl_axtls_connect(struct connectdata *conn,
|
|||||||
case CURL_SSLVERSION_TLSv1:
|
case CURL_SSLVERSION_TLSv1:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
failf(data, "axTLS only supports TLSv1");
|
failf(data, "axTLS only supports TLS 1.0 and 1.1, "
|
||||||
|
"and it cannot be specified which one to use");
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,6 +180,9 @@ Curl_axtls_connect(struct connectdata *conn,
|
|||||||
return CURLE_SSL_CONNECT_ERROR;
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
conn->ssl[sockindex].ssl_ctx = ssl_ctx;
|
||||||
|
conn->ssl[sockindex].ssl = NULL;
|
||||||
|
|
||||||
/* Load the trusted CA cert bundle file */
|
/* Load the trusted CA cert bundle file */
|
||||||
if(data->set.ssl.CAfile) {
|
if(data->set.ssl.CAfile) {
|
||||||
if(ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT, data->set.ssl.CAfile, NULL)
|
if(ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT, data->set.ssl.CAfile, NULL)
|
||||||
@@ -191,7 +190,6 @@ Curl_axtls_connect(struct connectdata *conn,
|
|||||||
infof(data, "error reading ca cert file %s \n",
|
infof(data, "error reading ca cert file %s \n",
|
||||||
data->set.ssl.CAfile);
|
data->set.ssl.CAfile);
|
||||||
if(data->set.ssl.verifypeer) {
|
if(data->set.ssl.verifypeer) {
|
||||||
Curl_axtls_close(conn, sockindex);
|
|
||||||
return CURLE_SSL_CACERT_BADFILE;
|
return CURLE_SSL_CACERT_BADFILE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -225,7 +223,6 @@ Curl_axtls_connect(struct connectdata *conn,
|
|||||||
if(cert_types[i] == 0) {
|
if(cert_types[i] == 0) {
|
||||||
failf(data, "%s is not x509 or pkcs12 format",
|
failf(data, "%s is not x509 or pkcs12 format",
|
||||||
data->set.str[STRING_CERT]);
|
data->set.str[STRING_CERT]);
|
||||||
Curl_axtls_close(conn, sockindex);
|
|
||||||
return CURLE_SSL_CERTPROBLEM;
|
return CURLE_SSL_CERTPROBLEM;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -250,7 +247,6 @@ Curl_axtls_connect(struct connectdata *conn,
|
|||||||
if(key_types[i] == 0) {
|
if(key_types[i] == 0) {
|
||||||
failf(data, "Failure: %s is not a supported key file",
|
failf(data, "Failure: %s is not a supported key file",
|
||||||
data->set.str[STRING_KEY]);
|
data->set.str[STRING_KEY]);
|
||||||
Curl_axtls_close(conn, sockindex);
|
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -271,14 +267,25 @@ Curl_axtls_connect(struct connectdata *conn,
|
|||||||
else
|
else
|
||||||
ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex], NULL, 0);
|
ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex], NULL, 0);
|
||||||
|
|
||||||
/* Check to make sure handshake was ok. */
|
conn->ssl[sockindex].ssl = ssl;
|
||||||
ssl_fcn_return = ssl_handshake_status(ssl);
|
return CURLE_OK;
|
||||||
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);
|
* For both blocking and non-blocking connects, this function finalizes the
|
||||||
}
|
* SSL connection.
|
||||||
infof (data, "handshake completed successfully\n");
|
*/
|
||||||
|
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
|
/* 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?
|
* settings in "data." axTLS api doesn't have get cert chain fcn, so omit?
|
||||||
@@ -289,7 +296,7 @@ Curl_axtls_connect(struct connectdata *conn,
|
|||||||
if(ssl_verify_cert(ssl) != SSL_OK) {
|
if(ssl_verify_cert(ssl) != SSL_OK) {
|
||||||
Curl_axtls_close(conn, sockindex);
|
Curl_axtls_close(conn, sockindex);
|
||||||
failf(data, "server cert verify failed");
|
failf(data, "server cert verify failed");
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
return CURLE_PEER_FAILED_VERIFICATION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -306,7 +313,6 @@ Curl_axtls_connect(struct connectdata *conn,
|
|||||||
* this, but a couple fields are available.
|
* this, but a couple fields are available.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* There is no (DNS) Altnames count in the version 1.4.8 API. There is a
|
/* There is no (DNS) Altnames count in the version 1.4.8 API. There is a
|
||||||
risk of an inifite loop */
|
risk of an inifite loop */
|
||||||
for(dns_altname_index = 0; ; dns_altname_index++) {
|
for(dns_altname_index = 0; ; dns_altname_index++) {
|
||||||
@@ -326,20 +332,29 @@ Curl_axtls_connect(struct connectdata *conn,
|
|||||||
|
|
||||||
/* RFC2818 checks */
|
/* RFC2818 checks */
|
||||||
if(found_subject_alt_names && !found_subject_alt_name_matching_conn) {
|
if(found_subject_alt_names && !found_subject_alt_name_matching_conn) {
|
||||||
/* Break connection ! */
|
if(data->set.ssl.verifyhost) {
|
||||||
Curl_axtls_close(conn, sockindex);
|
/* Break connection ! */
|
||||||
failf(data, "\tsubjectAltName(s) do not match %s\n", conn->host.dispname);
|
Curl_axtls_close(conn, sockindex);
|
||||||
return CURLE_PEER_FAILED_VERIFICATION;
|
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) {
|
else if(found_subject_alt_names == 0) {
|
||||||
/* Per RFC2818, when no Subject Alt Names were available, examine the peer
|
/* Per RFC2818, when no Subject Alt Names were available, examine the peer
|
||||||
CN as a legacy fallback */
|
CN as a legacy fallback */
|
||||||
peer_CN = ssl_get_cert_dn(ssl, SSL_X509_CERT_COMMON_NAME);
|
peer_CN = ssl_get_cert_dn(ssl, SSL_X509_CERT_COMMON_NAME);
|
||||||
if(peer_CN == NULL) {
|
if(peer_CN == NULL) {
|
||||||
/* Similar behaviour to the OpenSSL interface */
|
if(data->set.ssl.verifyhost) {
|
||||||
Curl_axtls_close(conn, sockindex);
|
Curl_axtls_close(conn, sockindex);
|
||||||
failf(data, "unable to obtain common name from peer certificate");
|
failf(data, "unable to obtain common name from peer certificate");
|
||||||
return CURLE_PEER_FAILED_VERIFICATION;
|
return CURLE_PEER_FAILED_VERIFICATION;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
infof(data, "unable to obtain common name from peer certificate");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(!Curl_cert_hostcheck((const char *)peer_CN, conn->host.name)) {
|
if(!Curl_cert_hostcheck((const char *)peer_CN, conn->host.name)) {
|
||||||
@@ -359,8 +374,6 @@ Curl_axtls_connect(struct connectdata *conn,
|
|||||||
|
|
||||||
/* General housekeeping */
|
/* General housekeeping */
|
||||||
conn->ssl[sockindex].state = ssl_connection_complete;
|
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->recv[sockindex] = axtls_recv;
|
||||||
conn->send[sockindex] = axtls_send;
|
conn->send[sockindex] = axtls_send;
|
||||||
|
|
||||||
@@ -374,6 +387,107 @@ Curl_axtls_connect(struct connectdata *conn,
|
|||||||
return CURLE_OK;
|
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 */
|
/* return number of sent (non-SSL) bytes */
|
||||||
static ssize_t axtls_send(struct connectdata *conn,
|
static ssize_t axtls_send(struct connectdata *conn,
|
||||||
@@ -407,7 +521,7 @@ void Curl_axtls_close(struct connectdata *conn, int sockindex)
|
|||||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||||
|
|
||||||
infof(conn->data, " Curl_axtls_close\n");
|
infof(conn->data, " Curl_axtls_close\n");
|
||||||
if(connssl->ssl) {
|
|
||||||
/* line from ssluse.c: (void)SSL_shutdown(connssl->ssl);
|
/* line from ssluse.c: (void)SSL_shutdown(connssl->ssl);
|
||||||
axTLS compat layer does nothing for SSL_shutdown */
|
axTLS compat layer does nothing for SSL_shutdown */
|
||||||
|
|
||||||
@@ -415,13 +529,7 @@ void Curl_axtls_close(struct connectdata *conn, int sockindex)
|
|||||||
equivalent. ssl_free and ssl_ctx_free close things.
|
equivalent. ssl_free and ssl_ctx_free close things.
|
||||||
SSL_set_connect_state(connssl->handle); */
|
SSL_set_connect_state(connssl->handle); */
|
||||||
|
|
||||||
ssl_free (connssl->ssl);
|
free_ssl_structs(connssl);
|
||||||
connssl->ssl = NULL;
|
|
||||||
}
|
|
||||||
if(connssl->ssl_ctx) {
|
|
||||||
ssl_ctx_free (connssl->ssl_ctx);
|
|
||||||
connssl->ssl_ctx = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -436,8 +544,7 @@ int Curl_axtls_shutdown(struct connectdata *conn, int sockindex)
|
|||||||
int retval = 0;
|
int retval = 0;
|
||||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
char buf[120]; /* We will use this for the OpenSSL error buffer, so it has
|
uint8_t *buf;
|
||||||
to be at least 120 bytes long. */
|
|
||||||
ssize_t nread;
|
ssize_t nread;
|
||||||
|
|
||||||
infof(conn->data, " Curl_axtls_shutdown\n");
|
infof(conn->data, " Curl_axtls_shutdown\n");
|
||||||
@@ -457,9 +564,10 @@ int Curl_axtls_shutdown(struct connectdata *conn, int sockindex)
|
|||||||
CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
|
CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
|
||||||
if(what > 0) {
|
if(what > 0) {
|
||||||
/* Something to read, let's do it and hope that it is the close
|
/* Something to read, let's do it and hope that it is the close
|
||||||
notify alert from the server */
|
notify alert from the server. buf is managed internally by
|
||||||
nread = (ssize_t)SSL_read(conn->ssl[sockindex].ssl, buf,
|
axTLS and will be released upon calling ssl_free via
|
||||||
sizeof(buf));
|
free_ssl_structs. */
|
||||||
|
nread = (ssize_t)ssl_read(connssl->ssl, &buf);
|
||||||
|
|
||||||
if(nread < SSL_OK) {
|
if(nread < SSL_OK) {
|
||||||
failf(data, "close notify alert not received during shutdown");
|
failf(data, "close notify alert not received during shutdown");
|
||||||
@@ -476,8 +584,7 @@ int Curl_axtls_shutdown(struct connectdata *conn, int sockindex)
|
|||||||
retval = -1;
|
retval = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssl_free (connssl->ssl);
|
free_ssl_structs(connssl);
|
||||||
connssl->ssl = NULL;
|
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@@ -490,26 +597,36 @@ static ssize_t axtls_recv(struct connectdata *conn, /* connection data */
|
|||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = &conn->ssl[num];
|
struct ssl_connect_data *connssl = &conn->ssl[num];
|
||||||
ssize_t ret = 0;
|
ssize_t ret = 0;
|
||||||
|
uint8_t *read_buf;
|
||||||
|
|
||||||
infof(conn->data, " axtls_recv\n");
|
infof(conn->data, " axtls_recv\n");
|
||||||
|
|
||||||
|
*err = CURLE_OK;
|
||||||
if(connssl) {
|
if(connssl) {
|
||||||
ret = (ssize_t)SSL_read(conn->ssl[num].ssl, buf, (int)buffersize);
|
ret = ssl_read(connssl->ssl, &read_buf);
|
||||||
|
if(ret > SSL_OK) {
|
||||||
/* axTLS isn't terribly generous about error reporting */
|
/* ssl_read returns SSL_OK if there is more data to read, so if it is
|
||||||
/* With patched axTLS, SSL_CLOSE_NOTIFY=-3. Hard-coding until axTLS
|
larger, then all data has been read already. */
|
||||||
team approves proposed fix. */
|
memcpy(buf, read_buf,
|
||||||
if(ret == -3 ) {
|
(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);
|
Curl_axtls_close(conn, num);
|
||||||
}
|
}
|
||||||
else if(ret < 0) {
|
else {
|
||||||
failf(conn->data, "axTLS recv error (%d)", (int)ret);
|
failf(conn->data, "axTLS recv error (%d)", ret);
|
||||||
*err = map_error_to_curl(ret);
|
*err = map_error_to_curl(ret);
|
||||||
return -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*err = CURLE_OK;
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,10 @@
|
|||||||
int Curl_axtls_init(void);
|
int Curl_axtls_init(void);
|
||||||
int Curl_axtls_cleanup(void);
|
int Curl_axtls_cleanup(void);
|
||||||
CURLcode Curl_axtls_connect(struct connectdata *conn, int sockindex);
|
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
|
/* tell axTLS to close down all open information regarding connections (and
|
||||||
thus session ID caching etc) */
|
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_init Curl_axtls_init
|
||||||
#define curlssl_cleanup Curl_axtls_cleanup
|
#define curlssl_cleanup Curl_axtls_cleanup
|
||||||
#define curlssl_connect Curl_axtls_connect
|
#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_session_free(x) Curl_axtls_session_free(x)
|
||||||
#define curlssl_close_all Curl_axtls_close_all
|
#define curlssl_close_all Curl_axtls_close_all
|
||||||
#define curlssl_close Curl_axtls_close
|
#define curlssl_close Curl_axtls_close
|
||||||
|
|||||||
109
lib/base64.c
109
lib/base64.c
@@ -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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -40,29 +40,45 @@
|
|||||||
static const char table64[]=
|
static const char table64[]=
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
|
||||||
static void decodeQuantum(unsigned char *dest, const char *src)
|
static size_t decodeQuantum(unsigned char *dest, const char *src)
|
||||||
{
|
{
|
||||||
|
size_t padding = 0;
|
||||||
const char *s, *p;
|
const char *s, *p;
|
||||||
unsigned long i, v, x = 0;
|
unsigned long i, v, x = 0;
|
||||||
|
|
||||||
for(i = 0, s = src; i < 4; i++, s++) {
|
for(i = 0, s = src; i < 4; i++, s++) {
|
||||||
v = 0;
|
v = 0;
|
||||||
p = table64;
|
|
||||||
while(*p && (*p != *s)) {
|
if(*s == '=') {
|
||||||
v++;
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
if(*p == *s)
|
|
||||||
x = (x << 6) + v;
|
|
||||||
else if(*s == '=')
|
|
||||||
x = (x << 6);
|
x = (x << 6);
|
||||||
|
padding++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
p = table64;
|
||||||
|
|
||||||
|
while(*p && (*p != *s)) {
|
||||||
|
v++;
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(*p == *s)
|
||||||
|
x = (x << 6) + v;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dest[2] = curlx_ultouc(x & 0xFFUL);
|
if(padding < 1)
|
||||||
|
dest[2] = curlx_ultouc(x & 0xFFUL);
|
||||||
|
|
||||||
x >>= 8;
|
x >>= 8;
|
||||||
dest[1] = curlx_ultouc(x & 0xFFUL);
|
if(padding < 2)
|
||||||
|
dest[1] = curlx_ultouc(x & 0xFFUL);
|
||||||
|
|
||||||
x >>= 8;
|
x >>= 8;
|
||||||
dest[0] = curlx_ultouc(x & 0xFFUL);
|
dest[0] = curlx_ultouc(x & 0xFFUL);
|
||||||
|
|
||||||
|
return 3 - padding;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -82,58 +98,71 @@ static void decodeQuantum(unsigned char *dest, const char *src)
|
|||||||
CURLcode Curl_base64_decode(const char *src,
|
CURLcode Curl_base64_decode(const char *src,
|
||||||
unsigned char **outptr, size_t *outlen)
|
unsigned char **outptr, size_t *outlen)
|
||||||
{
|
{
|
||||||
|
size_t srclen = 0;
|
||||||
size_t length = 0;
|
size_t length = 0;
|
||||||
size_t equalsTerm = 0;
|
size_t padding = 0;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
size_t result;
|
||||||
size_t numQuantums;
|
size_t numQuantums;
|
||||||
unsigned char lastQuantum[3];
|
|
||||||
size_t rawlen = 0;
|
size_t rawlen = 0;
|
||||||
|
unsigned char *pos;
|
||||||
unsigned char *newstr;
|
unsigned char *newstr;
|
||||||
|
|
||||||
*outptr = NULL;
|
*outptr = NULL;
|
||||||
*outlen = 0;
|
*outlen = 0;
|
||||||
|
srclen = strlen(src);
|
||||||
|
|
||||||
|
/* Check the length of the input string is valid */
|
||||||
|
if(!srclen || srclen % 4)
|
||||||
|
return CURLE_BAD_CONTENT_ENCODING;
|
||||||
|
|
||||||
|
/* Find the position of any = padding characters */
|
||||||
while((src[length] != '=') && src[length])
|
while((src[length] != '=') && src[length])
|
||||||
length++;
|
length++;
|
||||||
|
|
||||||
/* A maximum of two = padding characters is allowed */
|
/* A maximum of two = padding characters is allowed */
|
||||||
if(src[length] == '=') {
|
if(src[length] == '=') {
|
||||||
equalsTerm++;
|
padding++;
|
||||||
if(src[length+equalsTerm] == '=')
|
if(src[length + 1] == '=')
|
||||||
equalsTerm++;
|
padding++;
|
||||||
}
|
}
|
||||||
numQuantums = (length + equalsTerm) / 4;
|
|
||||||
|
|
||||||
/* Don't allocate a buffer if the decoded length is 0 */
|
/* Check the = padding characters weren't part way through the input */
|
||||||
if(numQuantums == 0)
|
if(length + padding != srclen)
|
||||||
return CURLE_OK;
|
return CURLE_BAD_CONTENT_ENCODING;
|
||||||
|
|
||||||
rawlen = (numQuantums * 3) - equalsTerm;
|
/* Calculate the number of quantums */
|
||||||
|
numQuantums = srclen / 4;
|
||||||
|
|
||||||
/* The buffer must be large enough to make room for the last quantum
|
/* Calculate the size of the decoded string */
|
||||||
(which may be partially thrown out) and the zero terminator. */
|
rawlen = (numQuantums * 3) - padding;
|
||||||
newstr = malloc(rawlen+4);
|
|
||||||
|
/* Allocate our buffer including room for a zero terminator */
|
||||||
|
newstr = malloc(rawlen + 1);
|
||||||
if(!newstr)
|
if(!newstr)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
*outptr = newstr;
|
pos = newstr;
|
||||||
|
|
||||||
/* Decode all but the last quantum (which may not decode to a
|
/* Decode the quantums */
|
||||||
multiple of 3 bytes) */
|
for(i = 0; i < numQuantums; i++) {
|
||||||
for(i = 0; i < numQuantums - 1; i++) {
|
result = decodeQuantum(pos, src);
|
||||||
decodeQuantum(newstr, src);
|
if(!result) {
|
||||||
newstr += 3; src += 4;
|
Curl_safefree(newstr);
|
||||||
|
|
||||||
|
return CURLE_BAD_CONTENT_ENCODING;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += result;
|
||||||
|
src += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This final decode may actually read slightly past the end of the buffer
|
/* Zero terminate */
|
||||||
if the input string is missing pad bytes. This will almost always be
|
*pos = '\0';
|
||||||
harmless. */
|
|
||||||
decodeQuantum(lastQuantum, src);
|
|
||||||
for(i = 0; i < 3 - equalsTerm; i++)
|
|
||||||
newstr[i] = lastQuantum[i];
|
|
||||||
|
|
||||||
newstr[i] = '\0'; /* zero terminate */
|
/* Return the decoded data */
|
||||||
|
*outptr = newstr;
|
||||||
*outlen = rawlen; /* return size of decoded data */
|
*outlen = rawlen;
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -277,21 +277,27 @@
|
|||||||
/* Define if you have the <stdlib.h> header file. */
|
/* Define if you have the <stdlib.h> header file. */
|
||||||
#define HAVE_STDLIB_H
|
#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. */
|
/* Define if you have the `strcasecmp' function. */
|
||||||
#undef HAVE_STRCASECMP
|
#undef HAVE_STRCASECMP
|
||||||
|
|
||||||
/* Define if you have the `strcmpi' function. */
|
/* 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. */
|
/* Define if you have the `strdup' function. */
|
||||||
#undef HAVE_STRDUP
|
#define HAVE_STRDUP
|
||||||
|
|
||||||
|
|
||||||
/* Define if you have the `strftime' function. */
|
/* Define if you have the `strftime' function. */
|
||||||
#define HAVE_STRFTIME
|
#define HAVE_STRFTIME
|
||||||
|
|
||||||
/* Define if you have the `stricmp' function. */
|
|
||||||
#undef HAVE_STRICMP
|
|
||||||
|
|
||||||
/* Define if you have the <strings.h> header file. */
|
/* Define if you have the <strings.h> header file. */
|
||||||
#define HAVE_STRINGS_H
|
#define HAVE_STRINGS_H
|
||||||
|
|
||||||
@@ -523,7 +529,10 @@
|
|||||||
#define SEND_TYPE_RETV int
|
#define SEND_TYPE_RETV int
|
||||||
|
|
||||||
/* Define to use the QsoSSL package. */
|
/* Define to use the QsoSSL package. */
|
||||||
#define USE_QSOSSL
|
#undef USE_QSOSSL
|
||||||
|
|
||||||
|
/* Define to use the GSKit package. */
|
||||||
|
#define USE_GSKIT
|
||||||
|
|
||||||
/* Use the system keyring as the default CA bundle. */
|
/* Use the system keyring as the default CA bundle. */
|
||||||
#define CURL_CA_BUNDLE "/QIBM/UserData/ICSS/Cert/Server/DEFAULT.KDB"
|
#define CURL_CA_BUNDLE "/QIBM/UserData/ICSS/Cert/Server/DEFAULT.KDB"
|
||||||
|
|||||||
@@ -390,21 +390,6 @@
|
|||||||
# define SIZEOF_SIZE_T 4
|
# define SIZEOF_SIZE_T 4
|
||||||
#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
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
/* BSD-style lwIP TCP/IP stack SPECIFIC */
|
/* BSD-style lwIP TCP/IP stack SPECIFIC */
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
@@ -572,6 +557,25 @@
|
|||||||
# endif
|
# endif
|
||||||
#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 */
|
/* LARGE FILE SUPPORT */
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
|
|||||||
@@ -38,8 +38,6 @@
|
|||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
#define CONNECTION_HASH_SIZE 97
|
|
||||||
|
|
||||||
static void free_bundle_hash_entry(void *freethis)
|
static void free_bundle_hash_entry(void *freethis)
|
||||||
{
|
{
|
||||||
struct connectbundle *b = (struct connectbundle *) freethis;
|
struct connectbundle *b = (struct connectbundle *) freethis;
|
||||||
@@ -47,7 +45,7 @@ static void free_bundle_hash_entry(void *freethis)
|
|||||||
Curl_bundle_destroy(b);
|
Curl_bundle_destroy(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct conncache *Curl_conncache_init(void)
|
struct conncache *Curl_conncache_init(int size)
|
||||||
{
|
{
|
||||||
struct conncache *connc;
|
struct conncache *connc;
|
||||||
|
|
||||||
@@ -55,7 +53,7 @@ struct conncache *Curl_conncache_init(void)
|
|||||||
if(!connc)
|
if(!connc)
|
||||||
return NULL;
|
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);
|
Curl_str_key_compare, free_bundle_hash_entry);
|
||||||
|
|
||||||
if(!connc->hash) {
|
if(!connc->hash) {
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ struct conncache {
|
|||||||
size_t num_connections;
|
size_t num_connections;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct conncache *Curl_conncache_init(void);
|
struct conncache *Curl_conncache_init(int size);
|
||||||
|
|
||||||
void Curl_conncache_destroy(struct conncache *connc);
|
void Curl_conncache_destroy(struct conncache *connc);
|
||||||
|
|
||||||
|
|||||||
397
lib/connect.c
397
lib/connect.c
@@ -164,8 +164,7 @@ tcpkeepalive(struct SessionHandle *data,
|
|||||||
static CURLcode
|
static CURLcode
|
||||||
singleipconnect(struct connectdata *conn,
|
singleipconnect(struct connectdata *conn,
|
||||||
const Curl_addrinfo *ai, /* start connecting to this */
|
const Curl_addrinfo *ai, /* start connecting to this */
|
||||||
curl_socket_t *sock,
|
curl_socket_t *sock);
|
||||||
bool *connected);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Curl_timeleft() returns the amount of milliseconds left allowed for the
|
* Curl_timeleft() returns the amount of milliseconds left allowed for the
|
||||||
@@ -233,45 +232,6 @@ long Curl_timeleft(struct SessionHandle *data,
|
|||||||
return timeout_ms;
|
return timeout_ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* checkconnect() checks for a TCP connect on the given socket.
|
|
||||||
* It returns:
|
|
||||||
*/
|
|
||||||
|
|
||||||
enum chkconn_t {
|
|
||||||
CHKCONN_SELECT_ERROR = -1,
|
|
||||||
CHKCONN_CONNECTED = 0,
|
|
||||||
CHKCONN_IDLE = 1,
|
|
||||||
CHKCONN_FDSET_ERROR = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
static enum chkconn_t
|
|
||||||
checkconnect(curl_socket_t sockfd)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
#ifdef mpeix
|
|
||||||
/* Call this function once now, and ignore the results. We do this to
|
|
||||||
"clear" the error state on the socket so that we can later read it
|
|
||||||
reliably. This is reported necessary on the MPE/iX operating system. */
|
|
||||||
(void)verifyconnect(sockfd, NULL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
rc = Curl_socket_ready(CURL_SOCKET_BAD, sockfd, 0);
|
|
||||||
|
|
||||||
if(-1 == rc)
|
|
||||||
/* error, no connect here, try next */
|
|
||||||
return CHKCONN_SELECT_ERROR;
|
|
||||||
|
|
||||||
else if(rc & CURL_CSELECT_ERR)
|
|
||||||
/* error condition caught */
|
|
||||||
return CHKCONN_FDSET_ERROR;
|
|
||||||
|
|
||||||
else if(rc)
|
|
||||||
return CHKCONN_CONNECTED;
|
|
||||||
|
|
||||||
return CHKCONN_IDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CURLcode bindlocal(struct connectdata *conn,
|
static CURLcode bindlocal(struct connectdata *conn,
|
||||||
curl_socket_t sockfd, int af)
|
curl_socket_t sockfd, int af)
|
||||||
{
|
{
|
||||||
@@ -413,23 +373,22 @@ static CURLcode bindlocal(struct connectdata *conn,
|
|||||||
if(af == AF_INET6) {
|
if(af == AF_INET6) {
|
||||||
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
|
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
|
||||||
char *scope_ptr = strchr(myhost, '%');
|
char *scope_ptr = strchr(myhost, '%');
|
||||||
|
if(scope_ptr)
|
||||||
if(scope_ptr) *(scope_ptr++) = 0;
|
*(scope_ptr++) = 0;
|
||||||
#endif
|
#endif
|
||||||
if(Curl_inet_pton(AF_INET6, myhost, &si6->sin6_addr) > 0) {
|
if(Curl_inet_pton(AF_INET6, myhost, &si6->sin6_addr) > 0) {
|
||||||
si6->sin6_family = AF_INET6;
|
si6->sin6_family = AF_INET6;
|
||||||
si6->sin6_port = htons(port);
|
si6->sin6_port = htons(port);
|
||||||
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
|
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
|
||||||
if(scope_ptr) {
|
if(scope_ptr)
|
||||||
/* The "myhost" string either comes from Curl_if2ip or
|
/* The "myhost" string either comes from Curl_if2ip or from
|
||||||
from Curl_printable_address. The latter returns only
|
Curl_printable_address. The latter returns only numeric scope
|
||||||
numeric scope IDs and the former returns none at all.
|
IDs and the former returns none at all. So the scope ID, if
|
||||||
So the scope ID, if present, is known to be numeric */
|
present, is known to be numeric */
|
||||||
si6->sin6_scope_id = atoi(scope_ptr);
|
si6->sin6_scope_id = atoi(scope_ptr);
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
sizeof_sa = sizeof(struct sockaddr_in6);
|
}
|
||||||
|
sizeof_sa = sizeof(struct sockaddr_in6);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@@ -574,42 +533,53 @@ static bool verifyconnect(curl_socket_t sockfd, int *error)
|
|||||||
more address exists or error */
|
more address exists or error */
|
||||||
static CURLcode trynextip(struct connectdata *conn,
|
static CURLcode trynextip(struct connectdata *conn,
|
||||||
int sockindex,
|
int sockindex,
|
||||||
bool *connected)
|
int tempindex)
|
||||||
{
|
{
|
||||||
curl_socket_t sockfd;
|
CURLcode rc = CURLE_COULDNT_CONNECT;
|
||||||
Curl_addrinfo *ai;
|
|
||||||
|
|
||||||
/* First clean up after the failed socket.
|
/* First clean up after the failed socket.
|
||||||
Don't close it yet to ensure that the next IP's socket gets a different
|
Don't close it yet to ensure that the next IP's socket gets a different
|
||||||
file descriptor, which can prevent bugs when the curl_multi_socket_action
|
file descriptor, which can prevent bugs when the curl_multi_socket_action
|
||||||
interface is used with certain select() replacements such as kqueue. */
|
interface is used with certain select() replacements such as kqueue. */
|
||||||
curl_socket_t fd_to_close = conn->sock[sockindex];
|
curl_socket_t fd_to_close = conn->tempsock[tempindex];
|
||||||
conn->sock[sockindex] = CURL_SOCKET_BAD;
|
conn->tempsock[tempindex] = CURL_SOCKET_BAD;
|
||||||
*connected = FALSE;
|
|
||||||
|
|
||||||
if(sockindex != FIRSTSOCKET) {
|
if(sockindex == FIRSTSOCKET) {
|
||||||
Curl_closesocket(conn, fd_to_close);
|
Curl_addrinfo *ai;
|
||||||
return CURLE_COULDNT_CONNECT; /* no next */
|
int family;
|
||||||
}
|
|
||||||
|
|
||||||
/* try the next address */
|
if(conn->tempaddr[tempindex]) {
|
||||||
ai = conn->ip_addr->ai_next;
|
/* find next address in the same protocol family */
|
||||||
|
family = conn->tempaddr[tempindex]->ai_family;
|
||||||
while(ai) {
|
ai = conn->tempaddr[tempindex]->ai_next;
|
||||||
CURLcode res = singleipconnect(conn, ai, &sockfd, connected);
|
}
|
||||||
if(res)
|
else {
|
||||||
return res;
|
/* happy eyeballs - try the other protocol family */
|
||||||
if(sockfd != CURL_SOCKET_BAD) {
|
int firstfamily = conn->tempaddr[0]->ai_family;
|
||||||
/* store the new socket descriptor */
|
family = (firstfamily == AF_INET) ? AF_INET6 : AF_INET;
|
||||||
conn->sock[sockindex] = sockfd;
|
ai = conn->tempaddr[0]->ai_next;
|
||||||
conn->ip_addr = ai;
|
}
|
||||||
Curl_closesocket(conn, fd_to_close);
|
|
||||||
return CURLE_OK;
|
while(ai) {
|
||||||
|
while(ai && ai->ai_family != family)
|
||||||
|
ai = ai->ai_next;
|
||||||
|
|
||||||
|
if(ai) {
|
||||||
|
rc = singleipconnect(conn, ai, &conn->tempsock[tempindex]);
|
||||||
|
conn->tempaddr[tempindex] = ai;
|
||||||
|
if(rc == CURLE_COULDNT_CONNECT) {
|
||||||
|
ai = ai->ai_next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
ai = ai->ai_next;
|
|
||||||
}
|
}
|
||||||
Curl_closesocket(conn, fd_to_close);
|
|
||||||
return CURLE_COULDNT_CONNECT;
|
if(fd_to_close != CURL_SOCKET_BAD)
|
||||||
|
Curl_closesocket(conn, fd_to_close);
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copies connection info into the session handle to make it available
|
/* Copies connection info into the session handle to make it available
|
||||||
@@ -708,6 +678,7 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
|
|||||||
error, Curl_strerror(conn, error));
|
error, Curl_strerror(conn, error));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
|
||||||
|
|
||||||
if(!getaddressinfo((struct sockaddr*)&ssloc,
|
if(!getaddressinfo((struct sockaddr*)&ssloc,
|
||||||
conn->local_ip, &conn->local_port)) {
|
conn->local_ip, &conn->local_port)) {
|
||||||
@@ -733,11 +704,11 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
|||||||
{
|
{
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
CURLcode code = CURLE_OK;
|
CURLcode code = CURLE_OK;
|
||||||
curl_socket_t sockfd = conn->sock[sockindex];
|
long allow;
|
||||||
long allow = DEFAULT_CONNECT_TIMEOUT;
|
|
||||||
int error = 0;
|
int error = 0;
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
enum chkconn_t chk;
|
int result;
|
||||||
|
int i;
|
||||||
|
|
||||||
DEBUGASSERT(sockindex >= FIRSTSOCKET && sockindex <= SECONDARYSOCKET);
|
DEBUGASSERT(sockindex >= FIRSTSOCKET && sockindex <= SECONDARYSOCKET);
|
||||||
|
|
||||||
@@ -760,69 +731,104 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
|||||||
return CURLE_OPERATION_TIMEDOUT;
|
return CURLE_OPERATION_TIMEDOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check socket for connect */
|
for(i=0; i<2; i++) {
|
||||||
chk = checkconnect(sockfd);
|
if(conn->tempsock[i] == CURL_SOCKET_BAD)
|
||||||
if(CHKCONN_IDLE == chk) {
|
continue;
|
||||||
if(curlx_tvdiff(now, conn->connecttime) >= conn->timeoutms_per_addr) {
|
|
||||||
infof(data, "After %ldms connect time, move on!\n",
|
#ifdef mpeix
|
||||||
conn->timeoutms_per_addr);
|
/* Call this function once now, and ignore the results. We do this to
|
||||||
goto next;
|
"clear" the error state on the socket so that we can later read it
|
||||||
|
reliably. This is reported necessary on the MPE/iX operating system. */
|
||||||
|
(void)verifyconnect(conn->tempsock[i], NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* check socket for connect */
|
||||||
|
result = Curl_socket_ready(CURL_SOCKET_BAD, conn->tempsock[i], 0);
|
||||||
|
|
||||||
|
if(result == 0) { /* no connection yet */
|
||||||
|
if(curlx_tvdiff(now, conn->connecttime) >= conn->timeoutms_per_addr) {
|
||||||
|
infof(data, "After %ldms connect time, move on!\n",
|
||||||
|
conn->timeoutms_per_addr);
|
||||||
|
error = ETIMEDOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* should we try another protocol family? */
|
||||||
|
if(i == 0 && conn->tempaddr[1] == NULL &&
|
||||||
|
curlx_tvdiff(now, conn->connecttime) >= HAPPY_EYEBALLS_TIMEOUT) {
|
||||||
|
trynextip(conn, sockindex, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else if(result == CURL_CSELECT_OUT) {
|
||||||
|
if(verifyconnect(conn->tempsock[i], &error)) {
|
||||||
|
/* we are connected with TCP, awesome! */
|
||||||
|
int other = i ^ 1;
|
||||||
|
|
||||||
/* not an error, but also no connection yet */
|
/* use this socket from now on */
|
||||||
return code;
|
conn->sock[sockindex] = conn->tempsock[i];
|
||||||
}
|
conn->ip_addr = conn->tempaddr[i];
|
||||||
|
conn->tempsock[i] = CURL_SOCKET_BAD;
|
||||||
|
|
||||||
if(CHKCONN_CONNECTED == chk) {
|
/* close the other socket, if open */
|
||||||
if(verifyconnect(sockfd, &error)) {
|
if(conn->tempsock[other] != CURL_SOCKET_BAD) {
|
||||||
/* we are connected with TCP, awesome! */
|
Curl_closesocket(conn, conn->tempsock[other]);
|
||||||
|
conn->tempsock[other] = CURL_SOCKET_BAD;
|
||||||
|
}
|
||||||
|
|
||||||
/* see if we need to do any proxy magic first once we connected */
|
/* see if we need to do any proxy magic first once we connected */
|
||||||
code = Curl_connected_proxy(conn);
|
code = Curl_connected_proxy(conn, sockindex);
|
||||||
if(code)
|
if(code)
|
||||||
return code;
|
return code;
|
||||||
|
|
||||||
conn->bits.tcpconnect[sockindex] = TRUE;
|
conn->bits.tcpconnect[sockindex] = TRUE;
|
||||||
|
|
||||||
*connected = TRUE;
|
*connected = TRUE;
|
||||||
if(sockindex == FIRSTSOCKET)
|
if(sockindex == FIRSTSOCKET)
|
||||||
Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
|
Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
|
||||||
Curl_verboseconnect(conn);
|
Curl_updateconninfo(conn, conn->sock[sockindex]);
|
||||||
Curl_updateconninfo(conn, sockfd);
|
Curl_verboseconnect(conn);
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
infof(data, "Connection failed\n");
|
||||||
}
|
}
|
||||||
/* nope, not connected for real */
|
else if(result & CURL_CSELECT_ERR)
|
||||||
}
|
(void)verifyconnect(conn->tempsock[i], &error);
|
||||||
else {
|
|
||||||
/* nope, not connected */
|
/*
|
||||||
if(CHKCONN_FDSET_ERROR == chk) {
|
* The connection failed here, we should attempt to connect to the "next
|
||||||
(void)verifyconnect(sockfd, &error);
|
* address" for the given host. But first remember the latest error.
|
||||||
infof(data, "%s\n",Curl_strerror(conn, error));
|
*/
|
||||||
|
if(error) {
|
||||||
|
char ipaddress[MAX_IPADR_LEN];
|
||||||
|
data->state.os_errno = error;
|
||||||
|
SET_SOCKERRNO(error);
|
||||||
|
Curl_printable_address(conn->tempaddr[i], ipaddress, MAX_IPADR_LEN);
|
||||||
|
infof(data, "connect to %s port %ld failed: %s\n",
|
||||||
|
ipaddress, conn->port, Curl_strerror(conn, error));
|
||||||
|
|
||||||
|
conn->timeoutms_per_addr = conn->tempaddr[i]->ai_next == NULL ?
|
||||||
|
allow : allow / 2;
|
||||||
|
|
||||||
|
code = trynextip(conn, sockindex, i);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
infof(data, "Connection failed\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* The connection failed here, we should attempt to connect to the "next
|
|
||||||
* address" for the given host. But first remember the latest error.
|
|
||||||
*/
|
|
||||||
if(error) {
|
|
||||||
data->state.os_errno = error;
|
|
||||||
SET_SOCKERRNO(error);
|
|
||||||
}
|
|
||||||
next:
|
|
||||||
|
|
||||||
conn->timeoutms_per_addr = conn->ip_addr->ai_next == NULL ?
|
|
||||||
allow : allow / 2;
|
|
||||||
code = trynextip(conn, sockindex, connected);
|
|
||||||
|
|
||||||
if(code) {
|
if(code) {
|
||||||
error = SOCKERRNO;
|
/* no more addresses to try */
|
||||||
data->state.os_errno = error;
|
|
||||||
failf(data, "Failed connect to %s:%ld; %s",
|
/* if the first address family runs out of addresses to try before
|
||||||
conn->host.name, conn->port, Curl_strerror(conn, error));
|
the happy eyeball timeout, go ahead and try the next family now */
|
||||||
|
if(conn->tempaddr[1] == NULL) {
|
||||||
|
int rc;
|
||||||
|
rc = trynextip(conn, sockindex, 1);
|
||||||
|
if(rc == CURLE_OK)
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
failf(data, "Failed to connect to %s port %ld: %s",
|
||||||
|
conn->bits.proxy?conn->proxy.name:conn->host.name,
|
||||||
|
conn->port, Curl_strerror(conn, error));
|
||||||
}
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
@@ -939,8 +945,7 @@ void Curl_sndbufset(curl_socket_t sockfd)
|
|||||||
static CURLcode
|
static CURLcode
|
||||||
singleipconnect(struct connectdata *conn,
|
singleipconnect(struct connectdata *conn,
|
||||||
const Curl_addrinfo *ai,
|
const Curl_addrinfo *ai,
|
||||||
curl_socket_t *sockp,
|
curl_socket_t *sockp)
|
||||||
bool *connected)
|
|
||||||
{
|
{
|
||||||
struct Curl_sockaddr_ex addr;
|
struct Curl_sockaddr_ex addr;
|
||||||
int rc;
|
int rc;
|
||||||
@@ -949,9 +954,10 @@ singleipconnect(struct connectdata *conn,
|
|||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
curl_socket_t sockfd;
|
curl_socket_t sockfd;
|
||||||
CURLcode res = CURLE_OK;
|
CURLcode res = CURLE_OK;
|
||||||
|
char ipaddress[MAX_IPADR_LEN];
|
||||||
|
long port;
|
||||||
|
|
||||||
*sockp = CURL_SOCKET_BAD;
|
*sockp = CURL_SOCKET_BAD;
|
||||||
*connected = FALSE; /* default is not connected */
|
|
||||||
|
|
||||||
res = Curl_socket(conn, ai, &addr, &sockfd);
|
res = Curl_socket(conn, ai, &addr, &sockfd);
|
||||||
if(res)
|
if(res)
|
||||||
@@ -962,7 +968,7 @@ singleipconnect(struct connectdata *conn,
|
|||||||
|
|
||||||
/* store remote address and port used in this connection attempt */
|
/* store remote address and port used in this connection attempt */
|
||||||
if(!getaddressinfo((struct sockaddr*)&addr.sa_addr,
|
if(!getaddressinfo((struct sockaddr*)&addr.sa_addr,
|
||||||
conn->primary_ip, &conn->primary_port)) {
|
ipaddress, &port)) {
|
||||||
/* malformed address or bug in inet_ntop, try next address */
|
/* malformed address or bug in inet_ntop, try next address */
|
||||||
error = ERRNO;
|
error = ERRNO;
|
||||||
failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
|
failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
|
||||||
@@ -970,10 +976,7 @@ singleipconnect(struct connectdata *conn,
|
|||||||
Curl_closesocket(conn, sockfd);
|
Curl_closesocket(conn, sockfd);
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
|
infof(data, " Trying %s...\n", ipaddress);
|
||||||
infof(data, " Trying %s...\n", conn->ip_addr_str);
|
|
||||||
|
|
||||||
Curl_persistconninfo(conn);
|
|
||||||
|
|
||||||
if(data->set.tcp_nodelay)
|
if(data->set.tcp_nodelay)
|
||||||
tcpnodelay(conn, sockfd);
|
tcpnodelay(conn, sockfd);
|
||||||
@@ -1034,7 +1037,7 @@ singleipconnect(struct connectdata *conn,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(-1 == rc) {
|
if(-1 == rc) {
|
||||||
switch (error) {
|
switch(error) {
|
||||||
case EINPROGRESS:
|
case EINPROGRESS:
|
||||||
case EWOULDBLOCK:
|
case EWOULDBLOCK:
|
||||||
#if defined(EAGAIN)
|
#if defined(EAGAIN)
|
||||||
@@ -1046,25 +1049,25 @@ singleipconnect(struct connectdata *conn,
|
|||||||
case EAGAIN:
|
case EAGAIN:
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
*sockp = sockfd;
|
res = CURLE_OK;
|
||||||
return CURLE_OK;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* unknown error, fallthrough and try another address! */
|
/* unknown error, fallthrough and try another address! */
|
||||||
failf(data, "Failed to connect to %s: %s",
|
infof(data, "Immediate connect fail for %s: %s\n",
|
||||||
conn->ip_addr_str, Curl_strerror(conn,error));
|
ipaddress, Curl_strerror(conn,error));
|
||||||
data->state.os_errno = error;
|
data->state.os_errno = error;
|
||||||
|
|
||||||
/* connect failed */
|
/* connect failed */
|
||||||
Curl_closesocket(conn, sockfd);
|
Curl_closesocket(conn, sockfd);
|
||||||
|
res = CURLE_COULDNT_CONNECT;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if(!res)
|
||||||
*sockp = sockfd;
|
*sockp = sockfd;
|
||||||
|
|
||||||
return CURLE_OK;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1074,29 +1077,13 @@ singleipconnect(struct connectdata *conn,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||||
const struct Curl_dns_entry *remotehost,
|
const struct Curl_dns_entry *remotehost)
|
||||||
curl_socket_t *sockconn, /* the connected socket */
|
|
||||||
Curl_addrinfo **addr, /* the one we used */
|
|
||||||
bool *connected) /* really connected? */
|
|
||||||
{
|
{
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
curl_socket_t sockfd = CURL_SOCKET_BAD;
|
|
||||||
Curl_addrinfo *ai;
|
|
||||||
Curl_addrinfo *curr_addr;
|
|
||||||
|
|
||||||
struct timeval after;
|
|
||||||
struct timeval before = Curl_tvnow();
|
struct timeval before = Curl_tvnow();
|
||||||
|
CURLcode res;
|
||||||
|
|
||||||
/*************************************************************
|
long timeout_ms = Curl_timeleft(data, &before, TRUE);
|
||||||
* Figure out what maximum time we have left
|
|
||||||
*************************************************************/
|
|
||||||
long timeout_ms;
|
|
||||||
|
|
||||||
DEBUGASSERT(sockconn);
|
|
||||||
*connected = FALSE; /* default to not connected */
|
|
||||||
|
|
||||||
/* get the timeout left */
|
|
||||||
timeout_ms = Curl_timeleft(data, &before, TRUE);
|
|
||||||
|
|
||||||
if(timeout_ms < 0) {
|
if(timeout_ms < 0) {
|
||||||
/* a precaution, no need to continue if time already is up */
|
/* a precaution, no need to continue if time already is up */
|
||||||
@@ -1105,57 +1092,27 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
|||||||
}
|
}
|
||||||
|
|
||||||
conn->num_addr = Curl_num_addresses(remotehost->addr);
|
conn->num_addr = Curl_num_addresses(remotehost->addr);
|
||||||
|
conn->tempaddr[0] = remotehost->addr;
|
||||||
|
conn->tempaddr[1] = NULL;
|
||||||
|
conn->tempsock[0] = CURL_SOCKET_BAD;
|
||||||
|
conn->tempsock[1] = CURL_SOCKET_BAD;
|
||||||
|
Curl_expire(conn->data,
|
||||||
|
HAPPY_EYEBALLS_TIMEOUT + (MULTI_TIMEOUT_INACCURACY/1000));
|
||||||
|
|
||||||
ai = remotehost->addr;
|
/* Max time for the next connection attempt */
|
||||||
|
conn->timeoutms_per_addr =
|
||||||
|
conn->tempaddr[0]->ai_next == NULL ? timeout_ms : timeout_ms / 2;
|
||||||
|
|
||||||
/* Below is the loop that attempts to connect to all IP-addresses we
|
/* start connecting to first IP */
|
||||||
* know for the given host. One by one until one IP succeeds.
|
res = singleipconnect(conn, conn->tempaddr[0], &(conn->tempsock[0]));
|
||||||
*/
|
while(res != CURLE_OK &&
|
||||||
|
conn->tempaddr[0] &&
|
||||||
|
conn->tempaddr[0]->ai_next &&
|
||||||
|
conn->tempsock[0] == CURL_SOCKET_BAD)
|
||||||
|
res = trynextip(conn, FIRSTSOCKET, 0);
|
||||||
|
|
||||||
/*
|
if(conn->tempsock[0] == CURL_SOCKET_BAD)
|
||||||
* Connecting with a Curl_addrinfo chain
|
return res;
|
||||||
*/
|
|
||||||
for(curr_addr = ai; curr_addr; curr_addr = curr_addr->ai_next) {
|
|
||||||
CURLcode res;
|
|
||||||
|
|
||||||
/* Max time for the next address */
|
|
||||||
conn->timeoutms_per_addr = curr_addr->ai_next == NULL ?
|
|
||||||
timeout_ms : timeout_ms / 2;
|
|
||||||
|
|
||||||
/* start connecting to the IP curr_addr points to */
|
|
||||||
res = singleipconnect(conn, curr_addr,
|
|
||||||
&sockfd, connected);
|
|
||||||
if(res)
|
|
||||||
return res;
|
|
||||||
|
|
||||||
if(sockfd != CURL_SOCKET_BAD)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* get a new timeout for next attempt */
|
|
||||||
after = Curl_tvnow();
|
|
||||||
timeout_ms -= Curl_tvdiff(after, before);
|
|
||||||
if(timeout_ms < 0) {
|
|
||||||
failf(data, "connect() timed out!");
|
|
||||||
return CURLE_OPERATION_TIMEDOUT;
|
|
||||||
}
|
|
||||||
before = after;
|
|
||||||
} /* end of connect-to-each-address loop */
|
|
||||||
|
|
||||||
*sockconn = sockfd; /* the socket descriptor we've connected */
|
|
||||||
|
|
||||||
if(sockfd == CURL_SOCKET_BAD) {
|
|
||||||
/* no good connect was made */
|
|
||||||
failf(data, "couldn't connect to %s at %s:%d",
|
|
||||||
conn->bits.proxy?"proxy":"host",
|
|
||||||
conn->bits.proxy?conn->proxy.name:conn->host.name, conn->port);
|
|
||||||
return CURLE_COULDNT_CONNECT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* leave the socket in non-blocking mode */
|
|
||||||
|
|
||||||
/* store the address we use */
|
|
||||||
if(addr)
|
|
||||||
*addr = curr_addr;
|
|
||||||
|
|
||||||
data->info.numconnects++; /* to track the number of connections made */
|
data->info.numconnects++; /* to track the number of connections made */
|
||||||
|
|
||||||
@@ -1240,7 +1197,7 @@ curl_socket_t Curl_getconnectinfo(struct SessionHandle *data,
|
|||||||
* 'conn' can be NULL, beware!
|
* 'conn' can be NULL, beware!
|
||||||
*/
|
*/
|
||||||
int Curl_closesocket(struct connectdata *conn,
|
int Curl_closesocket(struct connectdata *conn,
|
||||||
curl_socket_t sock)
|
curl_socket_t sock)
|
||||||
{
|
{
|
||||||
if(conn && conn->fclosesocket) {
|
if(conn && conn->fclosesocket) {
|
||||||
if((sock == conn->sock[SECONDARYSOCKET]) &&
|
if((sock == conn->sock[SECONDARYSOCKET]) &&
|
||||||
@@ -1252,7 +1209,13 @@ int Curl_closesocket(struct connectdata *conn,
|
|||||||
else
|
else
|
||||||
return conn->fclosesocket(conn->closesocket_client, sock);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -31,11 +31,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
|||||||
bool *connected);
|
bool *connected);
|
||||||
|
|
||||||
CURLcode Curl_connecthost(struct connectdata *conn,
|
CURLcode Curl_connecthost(struct connectdata *conn,
|
||||||
const struct Curl_dns_entry *host, /* connect to
|
const struct Curl_dns_entry *host);
|
||||||
this */
|
|
||||||
curl_socket_t *sockconn, /* not set if error */
|
|
||||||
Curl_addrinfo **addr, /* the one we used */
|
|
||||||
bool *connected); /* truly connected? */
|
|
||||||
|
|
||||||
/* generic function that returns how much time there's left to run, according
|
/* generic function that returns how much time there's left to run, according
|
||||||
to the timeouts set */
|
to the timeouts set */
|
||||||
@@ -44,6 +40,8 @@ long Curl_timeleft(struct SessionHandle *data,
|
|||||||
bool duringconnect);
|
bool duringconnect);
|
||||||
|
|
||||||
#define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */
|
#define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */
|
||||||
|
#define HAPPY_EYEBALLS_TIMEOUT 200 /* milliseconds to wait between
|
||||||
|
ipv4/ipv6 connection attempts */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Used to extract socket and connectdata struct for the most recent
|
* Used to extract socket and connectdata struct for the most recent
|
||||||
|
|||||||
271
lib/cookie.c
271
lib/cookie.c
@@ -89,6 +89,7 @@ Example set of cookies:
|
|||||||
#include "strequal.h"
|
#include "strequal.h"
|
||||||
#include "strtok.h"
|
#include "strtok.h"
|
||||||
#include "sendf.h"
|
#include "sendf.h"
|
||||||
|
#include "slist.h"
|
||||||
#include "curl_memory.h"
|
#include "curl_memory.h"
|
||||||
#include "share.h"
|
#include "share.h"
|
||||||
#include "strtoofft.h"
|
#include "strtoofft.h"
|
||||||
@@ -106,6 +107,8 @@ static void freecookie(struct Cookie *co)
|
|||||||
free(co->domain);
|
free(co->domain);
|
||||||
if(co->path)
|
if(co->path)
|
||||||
free(co->path);
|
free(co->path);
|
||||||
|
if(co->spath)
|
||||||
|
free(co->spath);
|
||||||
if(co->name)
|
if(co->name)
|
||||||
free(co->name);
|
free(co->name);
|
||||||
if(co->value)
|
if(co->value)
|
||||||
@@ -143,6 +146,116 @@ static bool tailmatch(const char *cooke_domain, const char *hostname)
|
|||||||
return FALSE;
|
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).
|
* Load cookies from all given cookie files (CURLOPT_COOKIEFILE).
|
||||||
*/
|
*/
|
||||||
@@ -177,6 +290,34 @@ static void strstore(char **str, const char *newstr)
|
|||||||
*str = strdup(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.
|
* 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 *
|
struct Cookie *
|
||||||
@@ -288,72 +432,39 @@ Curl_cookie_add(struct SessionHandle *data,
|
|||||||
badcookie = TRUE; /* out of memory bad */
|
badcookie = TRUE; /* out of memory bad */
|
||||||
break;
|
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)) {
|
else if(Curl_raw_equal("domain", name)) {
|
||||||
/* note that this name may or may not have a preceding dot, but
|
/* Now, we make sure that our host is within the given domain,
|
||||||
we don't care about that, we treat the names the same anyway */
|
or the given domain is not valid and thus cannot be set. */
|
||||||
|
|
||||||
const char *domptr=whatptr;
|
|
||||||
const char *nextptr;
|
|
||||||
int dotcount=1;
|
|
||||||
|
|
||||||
/* Count the dots, we need to make sure that there are enough
|
|
||||||
of them. */
|
|
||||||
|
|
||||||
if('.' == whatptr[0])
|
if('.' == whatptr[0])
|
||||||
/* don't count the initial dot, assume it */
|
whatptr++; /* ignore preceding dot */
|
||||||
domptr++;
|
|
||||||
|
|
||||||
do {
|
if(!domain || tailmatch(whatptr, domain)) {
|
||||||
nextptr = strchr(domptr, '.');
|
const char *tailptr=whatptr;
|
||||||
if(nextptr) {
|
if(tailptr[0] == '.')
|
||||||
if(domptr != nextptr)
|
tailptr++;
|
||||||
dotcount++;
|
strstore(&co->domain, tailptr); /* don't prefix w/dots
|
||||||
domptr = nextptr+1;
|
internally */
|
||||||
|
if(!co->domain) {
|
||||||
|
badcookie = TRUE;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} while(nextptr);
|
co->tailmatch=TRUE; /* we always do that if the domain name was
|
||||||
|
given */
|
||||||
/* 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);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Now, we make sure that our host is within the given domain,
|
/* we did not get a tailmatch and then the attempted set domain
|
||||||
or the given domain is not valid and thus cannot be set. */
|
is not a domain to which the current host belongs. Mark as
|
||||||
|
bad. */
|
||||||
if('.' == whatptr[0])
|
badcookie=TRUE;
|
||||||
whatptr++; /* ignore preceding dot */
|
infof(data, "skipped cookie with bad tailmatch domain: %s\n",
|
||||||
|
whatptr);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(Curl_raw_equal("version", name)) {
|
else if(Curl_raw_equal("version", name)) {
|
||||||
@@ -461,6 +572,9 @@ Curl_cookie_add(struct SessionHandle *data,
|
|||||||
if(co->path) {
|
if(co->path) {
|
||||||
memcpy(co->path, path, pathlen);
|
memcpy(co->path, path, pathlen);
|
||||||
co->path[pathlen]=0; /* zero terminate */
|
co->path[pathlen]=0; /* zero terminate */
|
||||||
|
co->spath = sanitize_cookie_path(co->path);
|
||||||
|
if(!co->spath)
|
||||||
|
badcookie = TRUE; /* out of memory bad */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
badcookie = TRUE;
|
badcookie = TRUE;
|
||||||
@@ -512,12 +626,6 @@ Curl_cookie_add(struct SessionHandle *data,
|
|||||||
|
|
||||||
firstptr=strtok_r(lineptr, "\t", &tok_buf); /* tokenize it on the TAB */
|
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
|
/* Now loop through the fields and init the struct we already have
|
||||||
allocated */
|
allocated */
|
||||||
for(ptr=firstptr, fields=0; ptr && !badcookie;
|
for(ptr=firstptr, fields=0; ptr && !badcookie;
|
||||||
@@ -552,12 +660,21 @@ Curl_cookie_add(struct SessionHandle *data,
|
|||||||
co->path = strdup(ptr);
|
co->path = strdup(ptr);
|
||||||
if(!co->path)
|
if(!co->path)
|
||||||
badcookie = TRUE;
|
badcookie = TRUE;
|
||||||
|
else {
|
||||||
|
co->spath = sanitize_cookie_path(co->path);
|
||||||
|
if(!co->spath) {
|
||||||
|
badcookie = TRUE; /* out of memory bad */
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* this doesn't look like a path, make one up! */
|
/* this doesn't look like a path, make one up! */
|
||||||
co->path = strdup("/");
|
co->path = strdup("/");
|
||||||
if(!co->path)
|
if(!co->path)
|
||||||
badcookie = TRUE;
|
badcookie = TRUE;
|
||||||
|
co->spath = strdup("/");
|
||||||
|
if(!co->spath)
|
||||||
|
badcookie = TRUE;
|
||||||
fields++; /* add a field and fall down to secure */
|
fields++; /* add a field and fall down to secure */
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case 3:
|
case 3:
|
||||||
@@ -611,6 +728,9 @@ Curl_cookie_add(struct SessionHandle *data,
|
|||||||
superceeds an already existing cookie, which it may if the previous have
|
superceeds an already existing cookie, which it may if the previous have
|
||||||
the same domain and path as this */
|
the same domain and path as this */
|
||||||
|
|
||||||
|
/* at first, remove expired cookies */
|
||||||
|
remove_expired(c);
|
||||||
|
|
||||||
clist = c->cookies;
|
clist = c->cookies;
|
||||||
replace_old = FALSE;
|
replace_old = FALSE;
|
||||||
while(clist) {
|
while(clist) {
|
||||||
@@ -628,14 +748,14 @@ Curl_cookie_add(struct SessionHandle *data,
|
|||||||
if(replace_old) {
|
if(replace_old) {
|
||||||
/* the domains were identical */
|
/* the domains were identical */
|
||||||
|
|
||||||
if(clist->path && co->path) {
|
if(clist->spath && co->spath) {
|
||||||
if(Curl_raw_equal(clist->path, co->path)) {
|
if(Curl_raw_equal(clist->spath, co->spath)) {
|
||||||
replace_old = TRUE;
|
replace_old = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
replace_old = FALSE;
|
replace_old = FALSE;
|
||||||
}
|
}
|
||||||
else if(!clist->path && !co->path)
|
else if(!clist->spath && !co->spath)
|
||||||
replace_old = TRUE;
|
replace_old = TRUE;
|
||||||
else
|
else
|
||||||
replace_old = FALSE;
|
replace_old = FALSE;
|
||||||
@@ -664,6 +784,8 @@ Curl_cookie_add(struct SessionHandle *data,
|
|||||||
free(clist->domain);
|
free(clist->domain);
|
||||||
if(clist->path)
|
if(clist->path)
|
||||||
free(clist->path);
|
free(clist->path);
|
||||||
|
if(clist->spath)
|
||||||
|
free(clist->spath);
|
||||||
if(clist->expirestr)
|
if(clist->expirestr)
|
||||||
free(clist->expirestr);
|
free(clist->expirestr);
|
||||||
|
|
||||||
@@ -840,6 +962,9 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
|||||||
if(!c || !c->cookies)
|
if(!c || !c->cookies)
|
||||||
return NULL; /* no cookie struct or no cookies in the struct */
|
return NULL; /* no cookie struct or no cookies in the struct */
|
||||||
|
|
||||||
|
/* at first, remove expired cookies */
|
||||||
|
remove_expired(c);
|
||||||
|
|
||||||
co = c->cookies;
|
co = c->cookies;
|
||||||
|
|
||||||
while(co) {
|
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
|
/* now check the left part of the path with the cookies path
|
||||||
requirement */
|
requirement */
|
||||||
if(!co->path ||
|
if(!co->spath || pathmatch(co->spath, path) ) {
|
||||||
/* not using checkprefix() because matching should be
|
|
||||||
case-sensitive */
|
|
||||||
!strncmp(co->path, path, strlen(co->path)) ) {
|
|
||||||
|
|
||||||
/* and now, we know this is a match and we should create an
|
/* and now, we know this is a match and we should create an
|
||||||
entry for the return-linked-list */
|
entry for the return-linked-list */
|
||||||
@@ -1085,6 +1207,9 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
|
|||||||
destination file */
|
destination file */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/* at first, remove expired cookies */
|
||||||
|
remove_expired(c);
|
||||||
|
|
||||||
if(strequal("-", dumphere)) {
|
if(strequal("-", dumphere)) {
|
||||||
/* use stdout */
|
/* use stdout */
|
||||||
out = stdout;
|
out = stdout;
|
||||||
@@ -1145,9 +1270,9 @@ struct curl_slist *Curl_cookie_list(struct SessionHandle *data)
|
|||||||
curl_slist_free_all(list);
|
curl_slist_free_all(list);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
beg = curl_slist_append(list, line);
|
beg = Curl_slist_append_nodup(list, line);
|
||||||
free(line);
|
|
||||||
if(!beg) {
|
if(!beg) {
|
||||||
|
free(line);
|
||||||
curl_slist_free_all(list);
|
curl_slist_free_all(list);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,8 @@ struct Cookie {
|
|||||||
struct Cookie *next; /* next in the chain */
|
struct Cookie *next; /* next in the chain */
|
||||||
char *name; /* <this> = value */
|
char *name; /* <this> = value */
|
||||||
char *value; /* name = <this> */
|
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> */
|
char *domain; /* domain = <this> */
|
||||||
curl_off_t expires; /* expires = <this> */
|
curl_off_t expires; /* expires = <this> */
|
||||||
char *expirestr; /* the plain text version */
|
char *expirestr; /* the plain text version */
|
||||||
|
|||||||
@@ -38,9 +38,58 @@
|
|||||||
#include <Security/SecureTransport.h>
|
#include <Security/SecureTransport.h>
|
||||||
#include <CoreFoundation/CoreFoundation.h>
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
#include <CommonCrypto/CommonDigest.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 (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>
|
#include <sys/sysctl.h>
|
||||||
#endif
|
#endif /* CURL_BUILD_MAC */
|
||||||
|
|
||||||
#include "urldata.h"
|
#include "urldata.h"
|
||||||
#include "sendf.h"
|
#include "sendf.h"
|
||||||
@@ -61,16 +110,6 @@
|
|||||||
#define ioErr -36
|
#define ioErr -36
|
||||||
#define paramErr -50
|
#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,
|
/* The following two functions were ripped from Apple sample code,
|
||||||
* with some modifications: */
|
* with some modifications: */
|
||||||
static OSStatus SocketRead(SSLConnectionRef connection,
|
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:
|
case TLS_DH_anon_WITH_AES_256_CBC_SHA:
|
||||||
return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
|
return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
|
||||||
break;
|
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) */
|
/* TLS 1.0 with ECDSA (RFC 4492) */
|
||||||
case TLS_ECDH_ECDSA_WITH_NULL_SHA:
|
case TLS_ECDH_ECDSA_WITH_NULL_SHA:
|
||||||
return "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:
|
case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
|
||||||
return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA";
|
return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA";
|
||||||
break;
|
break;
|
||||||
#endif /* defined(__MAC_10_6) || defined(__IPHONE_5_0) */
|
#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
|
||||||
#if defined(__MAC_10_8) || defined(__IPHONE_5_0)
|
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
|
||||||
/* TLS 1.2 (RFC 5246) */
|
/* TLS 1.2 (RFC 5246) */
|
||||||
case TLS_RSA_WITH_NULL_MD5:
|
case TLS_RSA_WITH_NULL_MD5:
|
||||||
return "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:
|
case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
|
||||||
return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
|
return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
|
||||||
break;
|
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";
|
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)
|
CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
|
||||||
{
|
{
|
||||||
int mib[2];
|
int mib[2];
|
||||||
@@ -658,7 +801,7 @@ CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
|
|||||||
*minor = atoi(os_version_minor);
|
*minor = atoi(os_version_minor);
|
||||||
free(os_version);
|
free(os_version);
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* CURL_BUILD_MAC */
|
||||||
|
|
||||||
/* Apple provides a myriad of ways of getting information about a certificate
|
/* 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
|
into a string. Some aren't available under iOS or newer cats. So here's
|
||||||
@@ -668,29 +811,186 @@ CF_INLINE CFStringRef CopyCertSubject(SecCertificateRef cert)
|
|||||||
{
|
{
|
||||||
CFStringRef server_cert_summary = CFSTR("(null)");
|
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. */
|
/* iOS: There's only one way to do this. */
|
||||||
server_cert_summary = SecCertificateCopySubjectSummary(cert);
|
server_cert_summary = SecCertificateCopySubjectSummary(cert);
|
||||||
#else
|
#else
|
||||||
#if defined(__MAC_10_7)
|
#if CURL_BUILD_MAC_10_7
|
||||||
/* Lion & later: Get the long description if we can. */
|
/* Lion & later: Get the long description if we can. */
|
||||||
if(SecCertificateCopyLongDescription != NULL)
|
if(SecCertificateCopyLongDescription != NULL)
|
||||||
server_cert_summary =
|
server_cert_summary =
|
||||||
SecCertificateCopyLongDescription(NULL, cert, NULL);
|
SecCertificateCopyLongDescription(NULL, cert, NULL);
|
||||||
else
|
else
|
||||||
#endif /* defined(__MAC_10_7) */
|
#endif /* CURL_BUILD_MAC_10_7 */
|
||||||
#if defined(__MAC_10_6)
|
#if CURL_BUILD_MAC_10_6
|
||||||
/* Snow Leopard: Get the certificate summary. */
|
/* Snow Leopard: Get the certificate summary. */
|
||||||
if(SecCertificateCopySubjectSummary != NULL)
|
if(SecCertificateCopySubjectSummary != NULL)
|
||||||
server_cert_summary = SecCertificateCopySubjectSummary(cert);
|
server_cert_summary = SecCertificateCopySubjectSummary(cert);
|
||||||
else
|
else
|
||||||
#endif /* defined(__MAC_10_6) */
|
#endif /* CURL_BUILD_MAC_10_6 */
|
||||||
/* Leopard is as far back as we go... */
|
/* Leopard is as far back as we go... */
|
||||||
(void)SecCertificateCopyCommonName(cert, &server_cert_summary);
|
(void)SecCertificateCopyCommonName(cert, &server_cert_summary);
|
||||||
#endif /* (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) */
|
#endif /* CURL_BUILD_IOS */
|
||||||
return server_cert_summary;
|
return server_cert_summary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CURL_SUPPORT_MAC_10_6
|
||||||
|
/* 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_6 */
|
||||||
|
|
||||||
|
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_6
|
||||||
|
/* 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_6
|
||||||
|
/* 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.7 or later: */
|
||||||
|
/* These constants are documented as having first appeared in 10.6 but they
|
||||||
|
raise linker errors when used on that cat for some reason. */
|
||||||
|
#if CURL_BUILD_MAC_10_7 || 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_7 || 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,
|
static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||||
int sockindex)
|
int sockindex)
|
||||||
{
|
{
|
||||||
@@ -701,17 +1001,19 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
struct in6_addr addr;
|
struct in6_addr addr;
|
||||||
#else
|
#else
|
||||||
struct in_addr addr;
|
struct in_addr addr;
|
||||||
#endif
|
#endif /* ENABLE_IPV6 */
|
||||||
size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
|
size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
|
||||||
SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL;
|
SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL;
|
||||||
|
char *ssl_sessionid;
|
||||||
|
size_t ssl_sessionid_len;
|
||||||
OSStatus err = noErr;
|
OSStatus err = noErr;
|
||||||
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
|
#if CURL_BUILD_MAC
|
||||||
int darwinver_maj = 0, darwinver_min = 0;
|
int darwinver_maj = 0, darwinver_min = 0;
|
||||||
|
|
||||||
GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
|
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(SSLCreateContext != NULL) { /* use the newer API if avaialble */
|
||||||
if(connssl->ssl_ctx)
|
if(connssl->ssl_ctx)
|
||||||
CFRelease(connssl->ssl_ctx);
|
CFRelease(connssl->ssl_ctx);
|
||||||
@@ -723,7 +1025,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* The old ST API does not exist under iOS, so don't compile it: */
|
/* 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)
|
if(connssl->ssl_ctx)
|
||||||
(void)SSLDisposeContext(connssl->ssl_ctx);
|
(void)SSLDisposeContext(connssl->ssl_ctx);
|
||||||
err = SSLNewContext(false, &(connssl->ssl_ctx));
|
err = SSLNewContext(false, &(connssl->ssl_ctx));
|
||||||
@@ -731,7 +1033,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
failf(data, "SSL: couldn't create a context: OSStatus %d", err);
|
failf(data, "SSL: couldn't create a context: OSStatus %d", err);
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
|
#endif /* CURL_SUPPORT_MAC_10_8 */
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if(connssl->ssl_ctx)
|
if(connssl->ssl_ctx)
|
||||||
@@ -741,11 +1043,11 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
failf(data, "SSL: couldn't create a context: OSStatus %d", err);
|
failf(data, "SSL: couldn't create a context: OSStatus %d", err);
|
||||||
return CURLE_OUT_OF_MEMORY;
|
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 */
|
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 */
|
/* 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) {
|
if(SSLSetProtocolVersionMax != NULL) {
|
||||||
switch(data->set.ssl.version) {
|
switch(data->set.ssl.version) {
|
||||||
case CURL_SSLVERSION_DEFAULT: default:
|
case CURL_SSLVERSION_DEFAULT: default:
|
||||||
@@ -756,17 +1058,33 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
|
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
|
||||||
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
|
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
|
||||||
break;
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
|
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
|
||||||
|
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol1);
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
|
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol11);
|
||||||
|
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol11);
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
|
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol12);
|
||||||
|
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
|
||||||
|
break;
|
||||||
case CURL_SSLVERSION_SSLv3:
|
case CURL_SSLVERSION_SSLv3:
|
||||||
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
|
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
|
||||||
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
|
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
|
||||||
break;
|
break;
|
||||||
case CURL_SSLVERSION_SSLv2:
|
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);
|
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
|
#if CURL_SUPPORT_MAC_10_8
|
||||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||||
kSSLProtocolAll,
|
kSSLProtocolAll,
|
||||||
false);
|
false);
|
||||||
@@ -796,18 +1114,37 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
kTLSProtocol12,
|
kTLSProtocol12,
|
||||||
true);
|
true);
|
||||||
break;
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
|
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||||
|
kTLSProtocol1,
|
||||||
|
true);
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
|
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||||
|
kTLSProtocol11,
|
||||||
|
true);
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
|
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||||
|
kTLSProtocol12,
|
||||||
|
true);
|
||||||
|
break;
|
||||||
case CURL_SSLVERSION_SSLv3:
|
case CURL_SSLVERSION_SSLv3:
|
||||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||||
kSSLProtocol3,
|
kSSLProtocol3,
|
||||||
true);
|
true);
|
||||||
break;
|
break;
|
||||||
case CURL_SSLVERSION_SSLv2:
|
case CURL_SSLVERSION_SSLv2:
|
||||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||||
kSSLProtocol2,
|
kSSLProtocol2,
|
||||||
true);
|
true);
|
||||||
|
if(err != noErr) {
|
||||||
|
failf(data, "Your version of the OS does not support SSLv2");
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
|
#endif /* CURL_SUPPORT_MAC_10_8 */
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
|
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
|
||||||
@@ -822,14 +1159,25 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
true);
|
true);
|
||||||
break;
|
break;
|
||||||
case CURL_SSLVERSION_TLSv1:
|
case CURL_SSLVERSION_TLSv1:
|
||||||
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||||
kTLSProtocol1,
|
kTLSProtocol1,
|
||||||
true);
|
true);
|
||||||
break;
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
|
failf(data, "Your version of the OS does not support TLSv1.1");
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
|
failf(data, "Your version of the OS does not support TLSv1.2");
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
case CURL_SSLVERSION_SSLv2:
|
case CURL_SSLVERSION_SSLv2:
|
||||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||||
kSSLProtocol2,
|
kSSLProtocol2,
|
||||||
true);
|
true);
|
||||||
|
if(err != noErr) {
|
||||||
|
failf(data, "Your version of the OS does not support SSLv2");
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case CURL_SSLVERSION_SSLv3:
|
case CURL_SSLVERSION_SSLv3:
|
||||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||||
@@ -837,16 +1185,104 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
true);
|
true);
|
||||||
break;
|
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
|
if(data->set.str[STRING_KEY]) {
|
||||||
* (which is also part of the Security framework) to evaluate trust. */
|
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 errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
|
||||||
|
failf(data, "SSL: Incorrect password for the certificate \"%s\" "
|
||||||
|
"and its private key.", data->set.str[STRING_CERT]);
|
||||||
|
break;
|
||||||
|
case errSecDecode: case -25257: /* 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 -25260: /* 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
|
/* 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
|
* 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
|
* anyway. In the latter case the result of the verification is checked with
|
||||||
* SSL_get_verify_result() below. */
|
* 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
|
/* Snow Leopard introduced the SSLSetSessionOption() function, but due to
|
||||||
a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag
|
a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag
|
||||||
works, it doesn't work as expected under Snow Leopard or Lion.
|
works, it doesn't work as expected under Snow Leopard or Lion.
|
||||||
@@ -855,11 +1291,11 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
(SecureTransport will always validate the certificate chain by
|
(SecureTransport will always validate the certificate chain by
|
||||||
default.) */
|
default.) */
|
||||||
/* (Note: Darwin 12.x.x is Mountain Lion.) */
|
/* (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) {
|
if(SSLSetSessionOption != NULL && darwinver_maj >= 12) {
|
||||||
#else
|
#else
|
||||||
if(SSLSetSessionOption != NULL) {
|
if(SSLSetSessionOption != NULL) {
|
||||||
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
|
#endif /* CURL_BUILD_MAC */
|
||||||
err = SSLSetSessionOption(connssl->ssl_ctx,
|
err = SSLSetSessionOption(connssl->ssl_ctx,
|
||||||
kSSLSessionOptionBreakOnServerAuth,
|
kSSLSessionOptionBreakOnServerAuth,
|
||||||
data->set.ssl.verifypeer?false:true);
|
data->set.ssl.verifypeer?false:true);
|
||||||
@@ -869,14 +1305,14 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
|
#if CURL_SUPPORT_MAC_10_8
|
||||||
err = SSLSetEnableCertVerify(connssl->ssl_ctx,
|
err = SSLSetEnableCertVerify(connssl->ssl_ctx,
|
||||||
data->set.ssl.verifypeer?true:false);
|
data->set.ssl.verifypeer?true:false);
|
||||||
if(err != noErr) {
|
if(err != noErr) {
|
||||||
failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
|
failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
}
|
}
|
||||||
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
|
#endif /* CURL_SUPPORT_MAC_10_8 */
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
err = SSLSetEnableCertVerify(connssl->ssl_ctx,
|
err = SSLSetEnableCertVerify(connssl->ssl_ctx,
|
||||||
@@ -885,7 +1321,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
|
failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
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.
|
/* If this is a domain name and not an IP address, then configure SNI.
|
||||||
* Also: the verifyhost setting influences SNI usage */
|
* Also: the verifyhost setting influences SNI usage */
|
||||||
@@ -898,7 +1334,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
err = SSLSetPeerDomainName(connssl->ssl_ctx, conn->host.name,
|
err = SSLSetPeerDomainName(connssl->ssl_ctx, conn->host.name,
|
||||||
strlen(conn->host.name));
|
strlen(conn->host.name));
|
||||||
if(err != noErr) {
|
if(err != noErr) {
|
||||||
infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d",
|
infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n",
|
||||||
err);
|
err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -915,7 +1351,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
SSLGetSupportedCiphers(connssl->ssl_ctx, all_ciphers,
|
SSLGetSupportedCiphers(connssl->ssl_ctx, all_ciphers,
|
||||||
&all_ciphers_count) == noErr) {
|
&all_ciphers_count) == noErr) {
|
||||||
for(i = 0UL ; i < all_ciphers_count ; i++) {
|
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
|
/* 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.
|
ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
|
||||||
Work around the problem here by disabling those ciphers if we are
|
Work around the problem here by disabling those ciphers if we are
|
||||||
@@ -924,17 +1360,27 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
|
all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* CURL_BUILD_MAC */
|
||||||
switch(all_ciphers[i]) {
|
switch(all_ciphers[i]) {
|
||||||
/* Disable NULL ciphersuites: */
|
/* Disable NULL ciphersuites: */
|
||||||
case SSL_NULL_WITH_NULL_NULL:
|
case SSL_NULL_WITH_NULL_NULL:
|
||||||
case SSL_RSA_WITH_NULL_MD5:
|
case SSL_RSA_WITH_NULL_MD5:
|
||||||
case SSL_RSA_WITH_NULL_SHA:
|
case SSL_RSA_WITH_NULL_SHA:
|
||||||
|
case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */
|
||||||
case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
|
case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
|
||||||
case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
|
case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
|
||||||
case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
|
case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
|
||||||
case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */
|
case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */
|
||||||
case 0xC010: /* TLS_ECDHE_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: */
|
/* Disable anonymous ciphersuites: */
|
||||||
case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
|
case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
|
||||||
case SSL_DH_anon_WITH_RC4_128_MD5:
|
case SSL_DH_anon_WITH_RC4_128_MD5:
|
||||||
@@ -990,6 +1436,46 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
Curl_safefree(all_ciphers);
|
Curl_safefree(all_ciphers);
|
||||||
Curl_safefree(allowed_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: */
|
||||||
|
if(SSLSetSessionOption != NULL)
|
||||||
|
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);
|
err = SSLSetIOFuncs(connssl->ssl_ctx, SocketRead, SocketWrite);
|
||||||
if(err != noErr) {
|
if(err != noErr) {
|
||||||
failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
|
failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
|
||||||
@@ -1059,6 +1545,20 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
|
|||||||
"certificate format");
|
"certificate format");
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
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
|
/* This error is raised if the server's cert didn't match the server's
|
||||||
host name: */
|
host name: */
|
||||||
case errSSLHostNameMismatch:
|
case errSSLHostNameMismatch:
|
||||||
@@ -1111,7 +1611,7 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
|
|||||||
infof(data, "TLS 1.0 connection using %s\n",
|
infof(data, "TLS 1.0 connection using %s\n",
|
||||||
TLSCipherNameForNumber(cipher));
|
TLSCipherNameForNumber(cipher));
|
||||||
break;
|
break;
|
||||||
#if defined(__MAC_10_8) || defined(__IPHONE_5_0)
|
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
|
||||||
case kTLSProtocol11:
|
case kTLSProtocol11:
|
||||||
infof(data, "TLS 1.1 connection using %s\n",
|
infof(data, "TLS 1.1 connection using %s\n",
|
||||||
TLSCipherNameForNumber(cipher));
|
TLSCipherNameForNumber(cipher));
|
||||||
@@ -1138,20 +1638,22 @@ darwinssl_connect_step3(struct connectdata *conn,
|
|||||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||||
CFStringRef server_cert_summary;
|
CFStringRef server_cert_summary;
|
||||||
char server_cert_summary_c[128];
|
char server_cert_summary_c[128];
|
||||||
CFArrayRef server_certs;
|
CFArrayRef server_certs = NULL;
|
||||||
SecCertificateRef server_cert;
|
SecCertificateRef server_cert;
|
||||||
OSStatus err;
|
OSStatus err;
|
||||||
CFIndex i, count;
|
CFIndex i, count;
|
||||||
SecTrustRef trust;
|
SecTrustRef trust = NULL;
|
||||||
|
|
||||||
/* There is no step 3!
|
/* There is no step 3!
|
||||||
* Well, okay, if verbose mode is on, let's print the details of the
|
* Well, okay, if verbose mode is on, let's print the details of the
|
||||||
* server certificates. */
|
* server certificates. */
|
||||||
#if defined(__MAC_10_7) || defined(__IPHONE_5_0)
|
#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
|
||||||
#if (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)
|
#if CURL_BUILD_IOS
|
||||||
#pragma unused(server_certs)
|
#pragma unused(server_certs)
|
||||||
err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
|
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);
|
count = SecTrustGetCertificateCount(trust);
|
||||||
for(i = 0L ; i < count ; i++) {
|
for(i = 0L ; i < count ; i++) {
|
||||||
server_cert = SecTrustGetCertificateAtIndex(trust, i);
|
server_cert = SecTrustGetCertificateAtIndex(trust, i);
|
||||||
@@ -1177,7 +1679,9 @@ darwinssl_connect_step3(struct connectdata *conn,
|
|||||||
if(SecTrustEvaluateAsync != NULL) {
|
if(SecTrustEvaluateAsync != NULL) {
|
||||||
#pragma unused(server_certs)
|
#pragma unused(server_certs)
|
||||||
err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
|
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);
|
count = SecTrustGetCertificateCount(trust);
|
||||||
for(i = 0L ; i < count ; i++) {
|
for(i = 0L ; i < count ; i++) {
|
||||||
server_cert = SecTrustGetCertificateAtIndex(trust, i);
|
server_cert = SecTrustGetCertificateAtIndex(trust, i);
|
||||||
@@ -1195,8 +1699,10 @@ darwinssl_connect_step3(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
#if CURL_SUPPORT_MAC_10_8
|
||||||
err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
|
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);
|
count = CFArrayGetCount(server_certs);
|
||||||
for(i = 0L ; i < count ; i++) {
|
for(i = 0L ; i < count ; i++) {
|
||||||
server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
|
server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
|
||||||
@@ -1214,8 +1720,9 @@ darwinssl_connect_step3(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
CFRelease(server_certs);
|
CFRelease(server_certs);
|
||||||
}
|
}
|
||||||
|
#endif /* CURL_SUPPORT_MAC_10_8 */
|
||||||
}
|
}
|
||||||
#endif /* (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) */
|
#endif /* CURL_BUILD_IOS */
|
||||||
#else
|
#else
|
||||||
#pragma unused(trust)
|
#pragma unused(trust)
|
||||||
err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
|
err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
|
||||||
@@ -1235,7 +1742,7 @@ darwinssl_connect_step3(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
CFRelease(server_certs);
|
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;
|
connssl->connecting_state = ssl_connect_done;
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
@@ -1387,16 +1894,16 @@ void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
|
|||||||
|
|
||||||
if(connssl->ssl_ctx) {
|
if(connssl->ssl_ctx) {
|
||||||
(void)SSLClose(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)
|
if(SSLCreateContext != NULL)
|
||||||
CFRelease(connssl->ssl_ctx);
|
CFRelease(connssl->ssl_ctx);
|
||||||
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
|
#if CURL_SUPPORT_MAC_10_8
|
||||||
else
|
else
|
||||||
(void)SSLDisposeContext(connssl->ssl_ctx);
|
(void)SSLDisposeContext(connssl->ssl_ctx);
|
||||||
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
|
#endif /* CURL_SUPPORT_MAC_10_8 */
|
||||||
#else
|
#else
|
||||||
(void)SSLDisposeContext(connssl->ssl_ctx);
|
(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_ctx = NULL;
|
||||||
}
|
}
|
||||||
connssl->ssl_sockfd = 0;
|
connssl->ssl_sockfd = 0;
|
||||||
@@ -1462,6 +1969,17 @@ int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
|
|||||||
return rc;
|
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)
|
size_t Curl_darwinssl_version(char *buffer, size_t size)
|
||||||
{
|
{
|
||||||
return snprintf(buffer, size, "SecureTransport");
|
return snprintf(buffer, size, "SecureTransport");
|
||||||
|
|||||||
@@ -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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* 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 */
|
/* close a SSL connection */
|
||||||
void Curl_darwinssl_close(struct connectdata *conn, int sockindex);
|
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);
|
size_t Curl_darwinssl_version(char *buffer, size_t size);
|
||||||
int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex);
|
int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex);
|
||||||
int Curl_darwinssl_check_cxn(struct connectdata *conn);
|
int Curl_darwinssl_check_cxn(struct connectdata *conn);
|
||||||
@@ -51,12 +52,16 @@ void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
|
|||||||
unsigned char *md5sum, /* output */
|
unsigned char *md5sum, /* output */
|
||||||
size_t md5len);
|
size_t md5len);
|
||||||
|
|
||||||
|
/* this backend provides these functions: */
|
||||||
|
#define have_curlssl_random 1
|
||||||
|
#define have_curlssl_md5sum 1
|
||||||
|
|
||||||
/* API setup for SecureTransport */
|
/* API setup for SecureTransport */
|
||||||
#define curlssl_init() (1)
|
#define curlssl_init() (1)
|
||||||
#define curlssl_cleanup() Curl_nop_stmt
|
#define curlssl_cleanup() Curl_nop_stmt
|
||||||
#define curlssl_connect Curl_darwinssl_connect
|
#define curlssl_connect Curl_darwinssl_connect
|
||||||
#define curlssl_connect_nonblocking Curl_darwinssl_connect_nonblocking
|
#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_all Curl_darwinssl_close_all
|
||||||
#define curlssl_close Curl_darwinssl_close
|
#define curlssl_close Curl_darwinssl_close
|
||||||
#define curlssl_shutdown(x,y) 0
|
#define curlssl_shutdown(x,y) 0
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ extern curl_free_callback Curl_cfree;
|
|||||||
extern curl_realloc_callback Curl_crealloc;
|
extern curl_realloc_callback Curl_crealloc;
|
||||||
extern curl_strdup_callback Curl_cstrdup;
|
extern curl_strdup_callback Curl_cstrdup;
|
||||||
extern curl_calloc_callback Curl_ccalloc;
|
extern curl_calloc_callback Curl_ccalloc;
|
||||||
#ifdef WIN32
|
#if defined(WIN32) && defined(UNICODE)
|
||||||
extern curl_wcsdup_callback Curl_cwcsdup;
|
extern curl_wcsdup_callback Curl_cwcsdup;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -114,14 +114,15 @@ extern curl_wcsdup_callback Curl_cwcsdup;
|
|||||||
#define free(ptr) Curl_cfree(ptr)
|
#define free(ptr) Curl_cfree(ptr)
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
# undef wcsdup
|
|
||||||
# define wcsdup(ptr) Curl_cwcsdup(ptr)
|
|
||||||
# undef _wcsdup
|
|
||||||
# define _wcsdup(ptr) Curl_cwcsdup(ptr)
|
|
||||||
# undef _tcsdup
|
|
||||||
# ifdef UNICODE
|
# 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)
|
# define _tcsdup(ptr) Curl_cwcsdup(ptr)
|
||||||
# else
|
# else
|
||||||
|
# undef _tcsdup
|
||||||
# define _tcsdup(ptr) Curl_cstrdup(ptr)
|
# define _tcsdup(ptr) Curl_cstrdup(ptr)
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -77,10 +77,6 @@ CURLcode Curl_input_ntlm(struct connectdata *conn,
|
|||||||
|
|
||||||
ntlm = proxy ? &conn->proxyntlm : &conn->ntlm;
|
ntlm = proxy ? &conn->proxyntlm : &conn->ntlm;
|
||||||
|
|
||||||
/* skip initial whitespaces */
|
|
||||||
while(*header && ISSPACE(*header))
|
|
||||||
header++;
|
|
||||||
|
|
||||||
if(checkprefix("NTLM", header)) {
|
if(checkprefix("NTLM", header)) {
|
||||||
header += strlen("NTLM");
|
header += strlen("NTLM");
|
||||||
|
|
||||||
|
|||||||
@@ -356,7 +356,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
|
|||||||
conn->response_header = NULL;
|
conn->response_header = NULL;
|
||||||
break;
|
break;
|
||||||
case NTLMSTATE_TYPE2:
|
case NTLMSTATE_TYPE2:
|
||||||
input = aprintf("TT %s", conn->challenge_header);
|
input = aprintf("TT %s\n", conn->challenge_header);
|
||||||
if(!input)
|
if(!input)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
res = ntlm_wb_response(conn, input, ntlm->state);
|
res = ntlm_wb_response(conn, input, ntlm->state);
|
||||||
|
|||||||
312
lib/curl_sasl.c
312
lib/curl_sasl.c
@@ -22,6 +22,8 @@
|
|||||||
* RFC2831 DIGEST-MD5 authentication
|
* RFC2831 DIGEST-MD5 authentication
|
||||||
* RFC4422 Simple Authentication and Security Layer (SASL)
|
* RFC4422 Simple Authentication and Security Layer (SASL)
|
||||||
* RFC4616 PLAIN authentication
|
* RFC4616 PLAIN authentication
|
||||||
|
* RFC6749 OAuth 2.0 Authorization Framework
|
||||||
|
* Draft LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
|
||||||
*
|
*
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
@@ -32,13 +34,17 @@
|
|||||||
|
|
||||||
#include "curl_base64.h"
|
#include "curl_base64.h"
|
||||||
#include "curl_md5.h"
|
#include "curl_md5.h"
|
||||||
#include "curl_rand.h"
|
#include "sslgen.h"
|
||||||
#include "curl_hmac.h"
|
#include "curl_hmac.h"
|
||||||
#include "curl_ntlm_msgs.h"
|
#include "curl_ntlm_msgs.h"
|
||||||
#include "curl_sasl.h"
|
#include "curl_sasl.h"
|
||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
#include "curl_memory.h"
|
#include "curl_memory.h"
|
||||||
|
|
||||||
|
#ifdef USE_NSS
|
||||||
|
#include "nssg.h" /* for Curl_nss_force_init() */
|
||||||
|
#endif
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
|
|
||||||
@@ -49,7 +55,7 @@
|
|||||||
/* Retrieves the value for a corresponding key from the challenge string
|
/* Retrieves the value for a corresponding key from the challenge string
|
||||||
* returns TRUE if the key could be found, FALSE if it does not exists
|
* returns TRUE if the key could be found, FALSE if it does not exists
|
||||||
*/
|
*/
|
||||||
static bool sasl_digest_get_key_value(const unsigned char *chlg,
|
static bool sasl_digest_get_key_value(const char *chlg,
|
||||||
const char *key,
|
const char *key,
|
||||||
char *value,
|
char *value,
|
||||||
size_t max_val_len,
|
size_t max_val_len,
|
||||||
@@ -58,7 +64,7 @@ static bool sasl_digest_get_key_value(const unsigned char *chlg,
|
|||||||
char *find_pos;
|
char *find_pos;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
find_pos = strstr((const char *) chlg, key);
|
find_pos = strstr(chlg, key);
|
||||||
if(!find_pos)
|
if(!find_pos)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
@@ -94,18 +100,18 @@ CURLcode Curl_sasl_create_plain_message(struct SessionHandle *data,
|
|||||||
const char *passwdp,
|
const char *passwdp,
|
||||||
char **outptr, size_t *outlen)
|
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 ulen;
|
||||||
size_t plen;
|
size_t plen;
|
||||||
|
|
||||||
ulen = strlen(userp);
|
ulen = strlen(userp);
|
||||||
plen = strlen(passwdp);
|
plen = strlen(passwdp);
|
||||||
|
|
||||||
if(2 * ulen + plen + 2 > sizeof(plainauth)) {
|
plainauth = malloc(2 * ulen + plen + 2);
|
||||||
|
if(!plainauth) {
|
||||||
*outlen = 0;
|
*outlen = 0;
|
||||||
*outptr = NULL;
|
*outptr = NULL;
|
||||||
|
|
||||||
/* Plainauth too small */
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,8 +123,10 @@ CURLcode Curl_sasl_create_plain_message(struct SessionHandle *data,
|
|||||||
memcpy(plainauth + 2 * ulen + 2, passwdp, plen);
|
memcpy(plainauth + 2 * ulen + 2, passwdp, plen);
|
||||||
|
|
||||||
/* Base64 encode the reply */
|
/* Base64 encode the reply */
|
||||||
return Curl_base64_encode(data, plainauth, 2 * ulen + plen + 2, outptr,
|
result = Curl_base64_encode(data, plainauth, 2 * ulen + plen + 2, outptr,
|
||||||
outlen);
|
outlen);
|
||||||
|
Curl_safefree(plainauth);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -160,7 +168,37 @@ CURLcode Curl_sasl_create_login_message(struct SessionHandle *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||||
/*
|
/*
|
||||||
|
* Curl_sasl_decode_cram_md5_message()
|
||||||
|
*
|
||||||
|
* This is used to decode an already encoded CRAM-MD5 challenge message.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* chlg64 [in] - Pointer to the base64 encoded challenge message.
|
||||||
|
* 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_decode_cram_md5_message(const char *chlg64, char **outptr,
|
||||||
|
size_t *outlen)
|
||||||
|
{
|
||||||
|
CURLcode result = CURLE_OK;
|
||||||
|
size_t chlg64len = strlen(chlg64);
|
||||||
|
|
||||||
|
*outptr = NULL;
|
||||||
|
*outlen = 0;
|
||||||
|
|
||||||
|
/* Decode the challenge if necessary */
|
||||||
|
if(chlg64len && *chlg64 != '=')
|
||||||
|
result = Curl_base64_decode(chlg64, (unsigned char **) outptr, outlen);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
* Curl_sasl_create_cram_md5_message()
|
* Curl_sasl_create_cram_md5_message()
|
||||||
*
|
*
|
||||||
* This is used to generate an already encoded CRAM-MD5 response message ready
|
* This is used to generate an already encoded CRAM-MD5 response message ready
|
||||||
@@ -169,7 +207,7 @@ CURLcode Curl_sasl_create_login_message(struct SessionHandle *data,
|
|||||||
* Parameters:
|
* Parameters:
|
||||||
*
|
*
|
||||||
* data [in] - The session handle.
|
* data [in] - The session handle.
|
||||||
* chlg64 [in] - Pointer to the base64 encoded challenge buffer.
|
* chlg [in] - The challenge.
|
||||||
* userp [in] - The user name.
|
* userp [in] - The user name.
|
||||||
* passdwp [in] - The user's password.
|
* passdwp [in] - The user's password.
|
||||||
* outptr [in/out] - The address where a pointer to newly allocated memory
|
* outptr [in/out] - The address where a pointer to newly allocated memory
|
||||||
@@ -179,55 +217,110 @@ CURLcode Curl_sasl_create_login_message(struct SessionHandle *data,
|
|||||||
* Returns CURLE_OK on success.
|
* Returns CURLE_OK on success.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
|
CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
|
||||||
const char *chlg64,
|
const char *chlg,
|
||||||
const char *userp,
|
const char *userp,
|
||||||
const char *passwdp,
|
const char *passwdp,
|
||||||
char **outptr, size_t *outlen)
|
char **outptr, size_t *outlen)
|
||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
size_t chlg64len = strlen(chlg64);
|
|
||||||
unsigned char *chlg = (unsigned char *) NULL;
|
|
||||||
size_t chlglen = 0;
|
size_t chlglen = 0;
|
||||||
HMAC_context *ctxt;
|
HMAC_context *ctxt;
|
||||||
unsigned char digest[MD5_DIGEST_LEN];
|
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(chlg)
|
||||||
if(chlg64len && *chlg64 != '=') {
|
chlglen = strlen(chlg);
|
||||||
result = Curl_base64_decode(chlg64, &chlg, &chlglen);
|
|
||||||
|
|
||||||
if(result)
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compute the digest using the password as the key */
|
/* Compute the digest using the password as the key */
|
||||||
ctxt = Curl_HMAC_init(Curl_HMAC_MD5,
|
ctxt = Curl_HMAC_init(Curl_HMAC_MD5,
|
||||||
(const unsigned char *) passwdp,
|
(const unsigned char *) passwdp,
|
||||||
curlx_uztoui(strlen(passwdp)));
|
curlx_uztoui(strlen(passwdp)));
|
||||||
|
if(!ctxt)
|
||||||
if(!ctxt) {
|
|
||||||
Curl_safefree(chlg);
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
|
||||||
|
|
||||||
/* Update the digest with the given challenge */
|
/* Update the digest with the given challenge */
|
||||||
if(chlglen > 0)
|
if(chlglen > 0)
|
||||||
Curl_HMAC_update(ctxt, chlg, curlx_uztoui(chlglen));
|
Curl_HMAC_update(ctxt, (const unsigned char *) chlg,
|
||||||
|
curlx_uztoui(chlglen));
|
||||||
Curl_safefree(chlg);
|
|
||||||
|
|
||||||
/* Finalise the digest */
|
/* Finalise the digest */
|
||||||
Curl_HMAC_final(ctxt, digest);
|
Curl_HMAC_final(ctxt, digest);
|
||||||
|
|
||||||
/* Prepare the response */
|
/* Generate 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",
|
"%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],
|
userp, digest[0], digest[1], digest[2], digest[3], digest[4],
|
||||||
digest[5], digest[6], digest[7], digest[8], digest[9], digest[10],
|
digest[5], digest[6], digest[7], digest[8], digest[9], digest[10],
|
||||||
digest[11], digest[12], digest[13], digest[14], digest[15]);
|
digest[11], digest[12], digest[13], digest[14], digest[15]);
|
||||||
|
if(!response)
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
/* Base64 encode the reply */
|
/* Base64 encode the response */
|
||||||
return Curl_base64_encode(data, response, 0, outptr, outlen);
|
result = Curl_base64_encode(data, response, 0, outptr, outlen);
|
||||||
|
|
||||||
|
Curl_safefree(response);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Curl_sasl_decode_digest_md5_message()
|
||||||
|
*
|
||||||
|
* This is used to decode an already encoded DIGEST-MD5 challenge message.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* chlg64 [in] - Pointer to the base64 encoded challenge message.
|
||||||
|
* nonce [in/out] - The buffer where the nonce will be stored.
|
||||||
|
* nlen [in] - The length of the nonce buffer.
|
||||||
|
* realm [in/out] - The buffer where the realm will be stored.
|
||||||
|
* rlen [in] - The length of the realm buffer.
|
||||||
|
* alg [in/out] - The buffer where the algorithm will be stored.
|
||||||
|
* alen [in] - The length of the algorithm buffer.
|
||||||
|
*
|
||||||
|
* Returns CURLE_OK on success.
|
||||||
|
*/
|
||||||
|
CURLcode Curl_sasl_decode_digest_md5_message(const char *chlg64,
|
||||||
|
char *nonce, size_t nlen,
|
||||||
|
char *realm, size_t rlen,
|
||||||
|
char *alg, size_t alen)
|
||||||
|
{
|
||||||
|
CURLcode result = CURLE_OK;
|
||||||
|
unsigned char *chlg = NULL;
|
||||||
|
size_t chlglen = 0;
|
||||||
|
size_t chlg64len = strlen(chlg64);
|
||||||
|
|
||||||
|
if(chlg64len && *chlg64 != '=') {
|
||||||
|
result = Curl_base64_decode(chlg64, &chlg, &chlglen);
|
||||||
|
if(result)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure we have a valid challenge message */
|
||||||
|
if(!chlg)
|
||||||
|
return CURLE_BAD_CONTENT_ENCODING;
|
||||||
|
|
||||||
|
/* Retrieve nonce string from the challenge */
|
||||||
|
if(!sasl_digest_get_key_value((char *)chlg, "nonce=\"", nonce, nlen, '\"')) {
|
||||||
|
Curl_safefree(chlg);
|
||||||
|
return CURLE_BAD_CONTENT_ENCODING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Retrieve realm string from the challenge */
|
||||||
|
if(!sasl_digest_get_key_value((char *)chlg, "realm=\"", realm, rlen, '\"')) {
|
||||||
|
/* Challenge does not have a realm, set empty string [RFC2831] page 6 */
|
||||||
|
strcpy(realm, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Retrieve algorithm string from the challenge */
|
||||||
|
if(!sasl_digest_get_key_value((char *)chlg, "algorithm=", alg, alen, ',')) {
|
||||||
|
Curl_safefree(chlg);
|
||||||
|
return CURLE_BAD_CONTENT_ENCODING;
|
||||||
|
}
|
||||||
|
|
||||||
|
Curl_safefree(chlg);
|
||||||
|
|
||||||
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -239,10 +332,11 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
|
|||||||
* Parameters:
|
* Parameters:
|
||||||
*
|
*
|
||||||
* data [in] - The session handle.
|
* data [in] - The session handle.
|
||||||
* chlg64 [in] - Pointer to the base64 encoded challenge buffer.
|
* nonce [in] - The nonce.
|
||||||
|
* realm [in] - The realm.
|
||||||
* userp [in] - The user name.
|
* userp [in] - The user name.
|
||||||
* passdwp [in] - The user's password.
|
* passdwp [in] - The user's password.
|
||||||
* service [in] - The service type such as www, smtp or pop
|
* service [in] - The service type such as www, smtp, pop or imap.
|
||||||
* outptr [in/out] - The address where a pointer to newly allocated memory
|
* outptr [in/out] - The address where a pointer to newly allocated memory
|
||||||
* holding the result will be stored upon completion.
|
* holding the result will be stored upon completion.
|
||||||
* outlen [out] - The length of the output message.
|
* outlen [out] - The length of the output message.
|
||||||
@@ -250,71 +344,36 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
|
|||||||
* Returns CURLE_OK on success.
|
* Returns CURLE_OK on success.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
|
CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
|
||||||
const char *chlg64,
|
const char *nonce,
|
||||||
|
const char *realm,
|
||||||
const char *userp,
|
const char *userp,
|
||||||
const char *passwdp,
|
const char *passwdp,
|
||||||
const char *service,
|
const char *service,
|
||||||
char **outptr, size_t *outlen)
|
char **outptr, size_t *outlen)
|
||||||
{
|
{
|
||||||
|
#ifndef DEBUGBUILD
|
||||||
static const char table16[] = "0123456789abcdef";
|
static const char table16[] = "0123456789abcdef";
|
||||||
|
#endif
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
unsigned char *chlg = (unsigned char *) NULL;
|
|
||||||
size_t chlglen = 0;
|
|
||||||
size_t i;
|
size_t i;
|
||||||
MD5_context *ctxt;
|
MD5_context *ctxt;
|
||||||
|
char *response = NULL;
|
||||||
unsigned char digest[MD5_DIGEST_LEN];
|
unsigned char digest[MD5_DIGEST_LEN];
|
||||||
char HA1_hex[2 * MD5_DIGEST_LEN + 1];
|
char HA1_hex[2 * MD5_DIGEST_LEN + 1];
|
||||||
char HA2_hex[2 * MD5_DIGEST_LEN + 1];
|
char HA2_hex[2 * MD5_DIGEST_LEN + 1];
|
||||||
char resp_hash_hex[2 * MD5_DIGEST_LEN + 1];
|
char resp_hash_hex[2 * MD5_DIGEST_LEN + 1];
|
||||||
|
|
||||||
char nonce[64];
|
|
||||||
char realm[128];
|
|
||||||
char alg[64];
|
|
||||||
char nonceCount[] = "00000001";
|
char nonceCount[] = "00000001";
|
||||||
char cnonce[] = "12345678"; /* will be changed */
|
char cnonce[] = "12345678"; /* will be changed */
|
||||||
char method[] = "AUTHENTICATE";
|
char method[] = "AUTHENTICATE";
|
||||||
char qop[] = "auth";
|
char qop[] = "auth";
|
||||||
char uri[128];
|
char uri[128];
|
||||||
char response[512];
|
|
||||||
|
|
||||||
result = Curl_base64_decode(chlg64, &chlg, &chlglen);
|
|
||||||
|
|
||||||
if(result)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
if(!chlg)
|
|
||||||
return CURLE_LOGIN_DENIED;
|
|
||||||
|
|
||||||
/* Retrieve nonce string from the challenge */
|
|
||||||
if(!sasl_digest_get_key_value(chlg, "nonce=\"", nonce,
|
|
||||||
sizeof(nonce), '\"')) {
|
|
||||||
Curl_safefree(chlg);
|
|
||||||
return CURLE_LOGIN_DENIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Retrieve realm string from the challenge */
|
|
||||||
if(!sasl_digest_get_key_value(chlg, "realm=\"", realm,
|
|
||||||
sizeof(realm), '\"')) {
|
|
||||||
/* Challenge does not have a realm, set empty string [RFC2831] page 6 */
|
|
||||||
strcpy(realm, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Retrieve algorithm string from the challenge */
|
|
||||||
if(!sasl_digest_get_key_value(chlg, "algorithm=", alg, sizeof(alg), ',')) {
|
|
||||||
Curl_safefree(chlg);
|
|
||||||
return CURLE_LOGIN_DENIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
Curl_safefree(chlg);
|
|
||||||
|
|
||||||
/* We do not support other algorithms */
|
|
||||||
if(strcmp(alg, "md5-sess") != 0)
|
|
||||||
return CURLE_LOGIN_DENIED;
|
|
||||||
|
|
||||||
|
#ifndef DEBUGBUILD
|
||||||
/* Generate 64 bits of random data */
|
/* Generate 64 bits of random data */
|
||||||
for(i = 0; i < 8; i++)
|
for(i = 0; i < 8; i++)
|
||||||
cnonce[i] = table16[Curl_rand()%16];
|
cnonce[i] = table16[Curl_rand(data)%16];
|
||||||
|
#endif
|
||||||
|
|
||||||
/* So far so good, now calculate A1 and H(A1) according to RFC 2831 */
|
/* So far so good, now calculate A1 and H(A1) according to RFC 2831 */
|
||||||
ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
|
ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
|
||||||
@@ -393,14 +452,20 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
|
|||||||
for(i = 0; i < MD5_DIGEST_LEN; i++)
|
for(i = 0; i < MD5_DIGEST_LEN; i++)
|
||||||
snprintf(&resp_hash_hex[2 * i], 3, "%02x", digest[i]);
|
snprintf(&resp_hash_hex[2 * i], 3, "%02x", digest[i]);
|
||||||
|
|
||||||
snprintf(response, sizeof(response),
|
/* Generate the response */
|
||||||
"username=\"%s\",realm=\"%s\",nonce=\"%s\","
|
response = aprintf("username=\"%s\",realm=\"%s\",nonce=\"%s\","
|
||||||
"cnonce=\"%s\",nc=\"%s\",digest-uri=\"%s\",response=%s",
|
"cnonce=\"%s\",nc=\"%s\",digest-uri=\"%s\",response=%s",
|
||||||
userp, realm, nonce,
|
userp, realm, nonce,
|
||||||
cnonce, nonceCount, uri, resp_hash_hex);
|
cnonce, nonceCount, uri, resp_hash_hex);
|
||||||
|
if(!response)
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
/* Base64 encode the reply */
|
/* Base64 encode the response */
|
||||||
return Curl_base64_encode(data, response, 0, outptr, outlen);
|
result = Curl_base64_encode(data, response, 0, outptr, outlen);
|
||||||
|
|
||||||
|
Curl_safefree(response);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -430,8 +495,36 @@ CURLcode Curl_sasl_create_ntlm_type1_message(const char *userp,
|
|||||||
struct ntlmdata *ntlm,
|
struct ntlmdata *ntlm,
|
||||||
char **outptr, size_t *outlen)
|
char **outptr, size_t *outlen)
|
||||||
{
|
{
|
||||||
return Curl_ntlm_create_type1_message(userp, passwdp, ntlm, outptr,
|
return Curl_ntlm_create_type1_message(userp, passwdp, ntlm, outptr, outlen);
|
||||||
outlen);
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Curl_sasl_decode_ntlm_type2_message()
|
||||||
|
*
|
||||||
|
* This is used to decode an already encoded NTLM type-2 message.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* data [in] - Pointer to session handle.
|
||||||
|
* type2msg [in] - Pointer to the base64 encoded type-2 message.
|
||||||
|
* ntlm [in/out] - The ntlm data struct being used and modified.
|
||||||
|
*
|
||||||
|
* Returns CURLE_OK on success.
|
||||||
|
*/
|
||||||
|
CURLcode Curl_sasl_decode_ntlm_type2_message(struct SessionHandle *data,
|
||||||
|
const char *type2msg,
|
||||||
|
struct ntlmdata *ntlm)
|
||||||
|
{
|
||||||
|
#ifdef USE_NSS
|
||||||
|
CURLcode result;
|
||||||
|
|
||||||
|
/* make sure the crypto backend is initialized */
|
||||||
|
result = Curl_nss_force_init(data);
|
||||||
|
if(result)
|
||||||
|
return result;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return Curl_ntlm_decode_type2_message(data, type2msg, ntlm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -443,7 +536,6 @@ CURLcode Curl_sasl_create_ntlm_type1_message(const char *userp,
|
|||||||
* Parameters:
|
* Parameters:
|
||||||
*
|
*
|
||||||
* data [in] - Pointer to session handle.
|
* data [in] - Pointer to session handle.
|
||||||
* header [in] - Pointer to the base64 encoded type-2 message buffer.
|
|
||||||
* userp [in] - The user name in the format User or Domain\User.
|
* userp [in] - The user name in the format User or Domain\User.
|
||||||
* passdwp [in] - The user's password.
|
* passdwp [in] - The user's password.
|
||||||
* ntlm [in/out] - The ntlm data struct being used and modified.
|
* ntlm [in/out] - The ntlm data struct being used and modified.
|
||||||
@@ -454,21 +546,53 @@ CURLcode Curl_sasl_create_ntlm_type1_message(const char *userp,
|
|||||||
* Returns CURLE_OK on success.
|
* Returns CURLE_OK on success.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data,
|
CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data,
|
||||||
const char *header,
|
|
||||||
const char *userp,
|
const char *userp,
|
||||||
const char *passwdp,
|
const char *passwdp,
|
||||||
struct ntlmdata *ntlm,
|
struct ntlmdata *ntlm,
|
||||||
char **outptr, size_t *outlen)
|
char **outptr, size_t *outlen)
|
||||||
{
|
{
|
||||||
CURLcode result = Curl_ntlm_decode_type2_message(data, header, ntlm);
|
return Curl_ntlm_create_type3_message(data, userp, passwdp, ntlm, outptr,
|
||||||
|
outlen);
|
||||||
|
}
|
||||||
|
#endif /* USE_NTLM */
|
||||||
|
|
||||||
if(!result)
|
/*
|
||||||
result = Curl_ntlm_create_type3_message(data, userp, passwdp, ntlm,
|
* Curl_sasl_create_xoauth2_message()
|
||||||
outptr, outlen);
|
*
|
||||||
|
* This is used to generate an already encoded OAuth 2.0 message ready for
|
||||||
|
* sending to the recipient.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* data [in] - The session handle.
|
||||||
|
* user [in] - The user name.
|
||||||
|
* bearer [in] - The 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)
|
||||||
|
{
|
||||||
|
CURLcode result = CURLE_OK;
|
||||||
|
char *xoauth = NULL;
|
||||||
|
|
||||||
|
/* Generate the message */
|
||||||
|
xoauth = aprintf("user=%s\1auth=Bearer %s\1\1", user, bearer);
|
||||||
|
if(!xoauth)
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
/* Base64 encode the reply */
|
||||||
|
result = Curl_base64_encode(data, xoauth, strlen(xoauth), outptr, outlen);
|
||||||
|
|
||||||
|
Curl_safefree(xoauth);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif /* USE_NTLM */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Curl_sasl_cleanup()
|
* Curl_sasl_cleanup()
|
||||||
|
|||||||
@@ -24,14 +24,34 @@
|
|||||||
|
|
||||||
#include "pingpong.h"
|
#include "pingpong.h"
|
||||||
|
|
||||||
|
/* Authentication mechanism values */
|
||||||
|
#define SASL_AUTH_NONE 0
|
||||||
|
#define SASL_AUTH_ANY ~0U
|
||||||
|
|
||||||
/* Authentication mechanism flags */
|
/* Authentication mechanism flags */
|
||||||
#define SASL_MECH_LOGIN 0x0001
|
#define SASL_MECH_LOGIN (1 << 0)
|
||||||
#define SASL_MECH_PLAIN 0x0002
|
#define SASL_MECH_PLAIN (1 << 1)
|
||||||
#define SASL_MECH_CRAM_MD5 0x0004
|
#define SASL_MECH_CRAM_MD5 (1 << 2)
|
||||||
#define SASL_MECH_DIGEST_MD5 0x0008
|
#define SASL_MECH_DIGEST_MD5 (1 << 3)
|
||||||
#define SASL_MECH_GSSAPI 0x0010
|
#define SASL_MECH_GSSAPI (1 << 4)
|
||||||
#define SASL_MECH_EXTERNAL 0x0020
|
#define SASL_MECH_EXTERNAL (1 << 5)
|
||||||
#define SASL_MECH_NTLM 0x0040
|
#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 */
|
/* This is used to generate a base64 encoded PLAIN authentication message */
|
||||||
CURLcode Curl_sasl_create_plain_message(struct SessionHandle *data,
|
CURLcode Curl_sasl_create_plain_message(struct SessionHandle *data,
|
||||||
@@ -46,16 +66,27 @@ CURLcode Curl_sasl_create_login_message(struct SessionHandle *data,
|
|||||||
size_t *outlen);
|
size_t *outlen);
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||||
|
/* This is used to decode a base64 encoded CRAM-MD5 challange message */
|
||||||
|
CURLcode Curl_sasl_decode_cram_md5_message(const char *chlg64, char **outptr,
|
||||||
|
size_t *outlen);
|
||||||
|
|
||||||
/* This is used to generate a base64 encoded CRAM-MD5 response message */
|
/* This is used to generate a base64 encoded CRAM-MD5 response message */
|
||||||
CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
|
CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
|
||||||
const char *chlg64,
|
const char *chlg,
|
||||||
const char *user,
|
const char *user,
|
||||||
const char *passwdp,
|
const char *passwdp,
|
||||||
char **outptr, size_t *outlen);
|
char **outptr, size_t *outlen);
|
||||||
|
|
||||||
|
/* This is used to decode a base64 encoded DIGEST-MD5 challange message */
|
||||||
|
CURLcode Curl_sasl_decode_digest_md5_message(const char *chlg64,
|
||||||
|
char *nonce, size_t nlen,
|
||||||
|
char *realm, size_t rlen,
|
||||||
|
char *alg, size_t alen);
|
||||||
|
|
||||||
/* This is used to generate a base64 encoded DIGEST-MD5 response message */
|
/* This is used to generate a base64 encoded DIGEST-MD5 response message */
|
||||||
CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
|
CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
|
||||||
const char *chlg64,
|
const char *nonce,
|
||||||
|
const char *realm,
|
||||||
const char *user,
|
const char *user,
|
||||||
const char *passwdp,
|
const char *passwdp,
|
||||||
const char *service,
|
const char *service,
|
||||||
@@ -70,10 +101,13 @@ CURLcode Curl_sasl_create_ntlm_type1_message(const char *userp,
|
|||||||
char **outptr,
|
char **outptr,
|
||||||
size_t *outlen);
|
size_t *outlen);
|
||||||
|
|
||||||
/* This is used to decode an incoming NTLM type-2 message and generate a
|
/* This is used to decode a base64 encoded NTLM type-2 message */
|
||||||
base64 encoded type-3 response */
|
CURLcode Curl_sasl_decode_ntlm_type2_message(struct SessionHandle *data,
|
||||||
|
const char *type2msg,
|
||||||
|
struct ntlmdata *ntlm);
|
||||||
|
|
||||||
|
/* This is used to generate a base64 encoded NTLM type-3 message */
|
||||||
CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data,
|
CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data,
|
||||||
const char *header,
|
|
||||||
const char *userp,
|
const char *userp,
|
||||||
const char *passwdp,
|
const char *passwdp,
|
||||||
struct ntlmdata *ntlm,
|
struct ntlmdata *ntlm,
|
||||||
@@ -81,6 +115,13 @@ CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data,
|
|||||||
|
|
||||||
#endif /* USE_NTLM */
|
#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
|
/* This is used to cleanup any libraries or curl modules used by the sasl
|
||||||
functions */
|
functions */
|
||||||
void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused);
|
void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused);
|
||||||
|
|||||||
@@ -180,6 +180,15 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
|
|||||||
SP_PROT_TLS1_1_CLIENT |
|
SP_PROT_TLS1_1_CLIENT |
|
||||||
SP_PROT_TLS1_2_CLIENT;
|
SP_PROT_TLS1_2_CLIENT;
|
||||||
break;
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
|
schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_0_CLIENT;
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
|
schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_1_CLIENT;
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
|
schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT;
|
||||||
|
break;
|
||||||
case CURL_SSLVERSION_SSLv3:
|
case CURL_SSLVERSION_SSLv3:
|
||||||
schannel_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT;
|
schannel_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT;
|
||||||
break;
|
break;
|
||||||
@@ -534,6 +543,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
|
|||||||
return retcode;
|
return retcode;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
connssl->cred->cached = TRUE;
|
||||||
infof(data, "schannel: stored credential handle in session cache\n");
|
infof(data, "schannel: stored credential handle in session cache\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1063,7 +1073,6 @@ int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
|
|||||||
*/
|
*/
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
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",
|
infof(data, "schannel: shutting down SSL/TLS connection with %s port %hu\n",
|
||||||
conn->host.name, conn->remote_port);
|
conn->host.name, conn->remote_port);
|
||||||
@@ -1141,17 +1150,11 @@ int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
|
|||||||
connssl->cred->refcount);
|
connssl->cred->refcount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if the handle refcount is zero, check if we have not cached it */
|
/* if the handle was not cached and the refcount is zero */
|
||||||
if(connssl->cred->refcount == 0) {
|
if(!connssl->cred->cached && connssl->cred->refcount == 0) {
|
||||||
if(Curl_ssl_getsessionid(conn, (void**)&cached_cred, NULL)) {
|
infof(data, "schannel: clear credential handle\n");
|
||||||
cached_cred = NULL;
|
s_pSecFn->FreeCredentialsHandle(&connssl->cred->cred_handle);
|
||||||
}
|
Curl_safefree(connssl->cred);
|
||||||
/* 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1177,7 +1180,7 @@ void Curl_schannel_session_free(void *ptr)
|
|||||||
{
|
{
|
||||||
struct curl_schannel_cred *cred = 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);
|
s_pSecFn->FreeCredentialsHandle(&cred->cred_handle);
|
||||||
Curl_safefree(cred);
|
Curl_safefree(cred);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#ifndef HEADER_CURL_KRB4_H
|
#ifndef HEADER_CURL_SECURITY_H
|
||||||
#define HEADER_CURL_KRB4_H
|
#define HEADER_CURL_SECURITY_H
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* _ _ ____ _
|
* _ _ ____ _
|
||||||
* Project ___| | | | _ \| |
|
* 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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* 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 *);
|
int (*decode)(void *, void*, int, int, struct connectdata *);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#define AUTH_OK 0
|
#define AUTH_OK 0
|
||||||
#define AUTH_CONTINUE 1
|
#define AUTH_CONTINUE 1
|
||||||
#define AUTH_ERROR 2
|
#define AUTH_ERROR 2
|
||||||
|
|
||||||
#ifdef HAVE_KRB4
|
|
||||||
extern struct Curl_sec_client_mech Curl_krb4_client_mech;
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_GSSAPI
|
#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 *,
|
int Curl_sec_read_msg (struct connectdata *conn, char *,
|
||||||
enum protection_level);
|
enum protection_level);
|
||||||
void Curl_sec_end (struct connectdata *);
|
void Curl_sec_end (struct connectdata *);
|
||||||
CURLcode Curl_sec_login (struct connectdata *);
|
CURLcode Curl_sec_login (struct connectdata *);
|
||||||
int Curl_sec_request_prot (struct connectdata *conn, const char *level);
|
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 */
|
||||||
@@ -270,7 +270,9 @@
|
|||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
# include <tchar.h>
|
# 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
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -369,7 +371,9 @@
|
|||||||
# include <sys/stat.h>
|
# include <sys/stat.h>
|
||||||
# undef lseek
|
# undef lseek
|
||||||
# define lseek(fdes,offset,whence) _lseeki64(fdes, offset, whence)
|
# define lseek(fdes,offset,whence) _lseeki64(fdes, offset, whence)
|
||||||
|
# undef fstat
|
||||||
# define fstat(fdes,stp) _fstati64(fdes, stp)
|
# define fstat(fdes,stp) _fstati64(fdes, stp)
|
||||||
|
# undef stat
|
||||||
# define stat(fname,stp) _stati64(fname, stp)
|
# define stat(fname,stp) _stati64(fname, stp)
|
||||||
# define struct_stat struct _stati64
|
# define struct_stat struct _stati64
|
||||||
# define LSEEK_ERROR (__int64)-1
|
# define LSEEK_ERROR (__int64)-1
|
||||||
@@ -616,7 +620,7 @@ int netware_init(void);
|
|||||||
#if defined(USE_GNUTLS) || defined(USE_SSLEAY) || defined(USE_NSS) || \
|
#if defined(USE_GNUTLS) || defined(USE_SSLEAY) || defined(USE_NSS) || \
|
||||||
defined(USE_QSOSSL) || defined(USE_POLARSSL) || defined(USE_AXTLS) || \
|
defined(USE_QSOSSL) || defined(USE_POLARSSL) || defined(USE_AXTLS) || \
|
||||||
defined(USE_CYASSL) || defined(USE_SCHANNEL) || \
|
defined(USE_CYASSL) || defined(USE_SCHANNEL) || \
|
||||||
defined(USE_DARWINSSL)
|
defined(USE_DARWINSSL) || defined(USE_GSKIT)
|
||||||
#define USE_SSL /* SSL support has been enabled */
|
#define USE_SSL /* SSL support has been enabled */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -440,7 +440,7 @@ typedef int sig_atomic_t;
|
|||||||
* (or equivalent) on this platform to hide platform details to code using it.
|
* (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 ERRNO ((int)GetLastError())
|
||||||
#define SET_ERRNO(x) (SetLastError((DWORD)(x)))
|
#define SET_ERRNO(x) (SetLastError((DWORD)(x)))
|
||||||
#else
|
#else
|
||||||
|
|||||||
13
lib/cyassl.c
13
lib/cyassl.c
@@ -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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -98,8 +98,19 @@ cyassl_connect_step1(struct connectdata *conn,
|
|||||||
req_method = SSLv23_client_method();
|
req_method = SSLv23_client_method();
|
||||||
break;
|
break;
|
||||||
case CURL_SSLVERSION_TLSv1:
|
case CURL_SSLVERSION_TLSv1:
|
||||||
|
infof(data, "CyaSSL cannot be configured to use TLS 1.0-1.2, "
|
||||||
|
"TLS 1.0 is used exclusively\n");
|
||||||
req_method = TLSv1_client_method();
|
req_method = TLSv1_client_method();
|
||||||
break;
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
|
req_method = TLSv1_client_method();
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
|
req_method = TLSv1_1_client_method();
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
|
req_method = TLSv1_2_client_method();
|
||||||
|
break;
|
||||||
case CURL_SSLVERSION_SSLv3:
|
case CURL_SSLVERSION_SSLv3:
|
||||||
req_method = SSLv3_client_method();
|
req_method = SSLv3_client_method();
|
||||||
break;
|
break;
|
||||||
|
|||||||
170
lib/dotdot.c
Normal file
170
lib/dotdot.c
Normal 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;
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#ifndef HEADER_CURL_RAND_H
|
#ifndef HEADER_CURL_DOTDOT_H
|
||||||
#define HEADER_CURL_RAND_H
|
#define HEADER_CURL_DOTDOT_H
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* _ _ ____ _
|
* _ _ ____ _
|
||||||
* Project ___| | | | _ \| |
|
* 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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -21,9 +21,5 @@
|
|||||||
* KIND, either express or implied.
|
* KIND, either express or implied.
|
||||||
*
|
*
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
char *Curl_dedotdotify(char *input);
|
||||||
void Curl_srand(void);
|
#endif
|
||||||
|
|
||||||
unsigned int Curl_rand(void);
|
|
||||||
|
|
||||||
#endif /* HEADER_CURL_RAND_H */
|
|
||||||
451
lib/easy.c
451
lib/easy.c
@@ -69,10 +69,11 @@
|
|||||||
#include "connect.h" /* for Curl_getconnectinfo */
|
#include "connect.h" /* for Curl_getconnectinfo */
|
||||||
#include "slist.h"
|
#include "slist.h"
|
||||||
#include "amigaos.h"
|
#include "amigaos.h"
|
||||||
#include "curl_rand.h"
|
|
||||||
#include "non-ascii.h"
|
#include "non-ascii.h"
|
||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
#include "conncache.h"
|
#include "conncache.h"
|
||||||
|
#include "multiif.h"
|
||||||
|
#include "sigpipe.h"
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
@@ -197,8 +198,8 @@ curl_free_callback Curl_cfree = (curl_free_callback)free;
|
|||||||
curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc;
|
curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc;
|
||||||
curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)system_strdup;
|
curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)system_strdup;
|
||||||
curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
|
curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
|
||||||
#ifdef WIN32
|
#if defined(WIN32) && defined(UNICODE)
|
||||||
curl_wcsdup_callback Curl_cwcsdup = (curl_wcsdup_callback)wcsdup;
|
curl_wcsdup_callback Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
/*
|
/*
|
||||||
@@ -231,8 +232,8 @@ CURLcode curl_global_init(long flags)
|
|||||||
Curl_crealloc = (curl_realloc_callback)realloc;
|
Curl_crealloc = (curl_realloc_callback)realloc;
|
||||||
Curl_cstrdup = (curl_strdup_callback)system_strdup;
|
Curl_cstrdup = (curl_strdup_callback)system_strdup;
|
||||||
Curl_ccalloc = (curl_calloc_callback)calloc;
|
Curl_ccalloc = (curl_calloc_callback)calloc;
|
||||||
#ifdef WIN32
|
#if defined(WIN32) && defined(UNICODE)
|
||||||
Curl_cwcsdup = (curl_wcsdup_callback)wcsdup;
|
Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(flags & CURL_GLOBAL_SSL)
|
if(flags & CURL_GLOBAL_SSL)
|
||||||
@@ -281,10 +282,6 @@ CURLcode curl_global_init(long flags)
|
|||||||
|
|
||||||
init_flags = flags;
|
init_flags = flags;
|
||||||
|
|
||||||
/* Preset pseudo-random number sequence. */
|
|
||||||
|
|
||||||
Curl_srand();
|
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,8 +399,328 @@ CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
|
|||||||
return ret;
|
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.
|
* transfer as previously setup.
|
||||||
*
|
*
|
||||||
* CONCEPT: This function creates a multi handle, adds the easy handle to it,
|
* CONCEPT: This function creates a multi handle, adds the easy handle to it,
|
||||||
@@ -415,18 +732,18 @@ CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
|
|||||||
* needs to keep it around since if this easy handle is used again by this
|
* 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
|
* function, the same multi handle must be re-used so that the same pools and
|
||||||
* caches can be used.
|
* 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;
|
CURLM *multi;
|
||||||
CURLMcode mcode;
|
CURLMcode mcode;
|
||||||
CURLcode code = CURLE_OK;
|
CURLcode code = CURLE_OK;
|
||||||
CURLMsg *msg;
|
SIGPIPE_VARIABLE(pipe_st);
|
||||||
bool done = FALSE;
|
|
||||||
int rc;
|
|
||||||
struct SessionHandle *data = easy;
|
|
||||||
|
|
||||||
if(!easy)
|
if(!data)
|
||||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||||
|
|
||||||
if(data->multi) {
|
if(data->multi) {
|
||||||
@@ -437,7 +754,9 @@ CURLcode curl_easy_perform(CURL *easy)
|
|||||||
if(data->multi_easy)
|
if(data->multi_easy)
|
||||||
multi = data->multi_easy;
|
multi = data->multi_easy;
|
||||||
else {
|
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)
|
if(!multi)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
data->multi_easy = multi;
|
data->multi_easy = multi;
|
||||||
@@ -446,7 +765,7 @@ CURLcode curl_easy_perform(CURL *easy)
|
|||||||
/* Copy the MAXCONNECTS option to the multi handle */
|
/* Copy the MAXCONNECTS option to the multi handle */
|
||||||
curl_multi_setopt(multi, CURLMOPT_MAXCONNECTS, data->set.maxconnects);
|
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) {
|
if(mcode) {
|
||||||
curl_multi_cleanup(multi);
|
curl_multi_cleanup(multi);
|
||||||
if(mcode == CURLM_OUT_OF_MEMORY)
|
if(mcode == CURLM_OUT_OF_MEMORY)
|
||||||
@@ -455,44 +774,47 @@ CURLcode curl_easy_perform(CURL *easy)
|
|||||||
return CURLE_FAILED_INIT;
|
return CURLE_FAILED_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sigpipe_ignore(data, &pipe_st);
|
||||||
|
|
||||||
/* assign this after curl_multi_add_handle() since that function checks for
|
/* assign this after curl_multi_add_handle() since that function checks for
|
||||||
it and rejects this handle otherwise */
|
it and rejects this handle otherwise */
|
||||||
data->multi = multi;
|
data->multi = multi;
|
||||||
|
|
||||||
while(!done && !mcode) {
|
/* run the transfer */
|
||||||
int still_running;
|
code = events ? easy_events(multi) : easy_transfer(multi);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ignoring the return code isn't nice, but atm we can't really handle
|
/* ignoring the return code isn't nice, but atm we can't really handle
|
||||||
a failure here, room for future improvement! */
|
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 */
|
/* The multi handle is kept alive, owned by the easy handle */
|
||||||
return code;
|
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
|
* curl_easy_cleanup() is the external interface to cleaning/freeing the given
|
||||||
* easy handle.
|
* easy handle.
|
||||||
@@ -500,27 +822,14 @@ CURLcode curl_easy_perform(CURL *easy)
|
|||||||
void curl_easy_cleanup(CURL *curl)
|
void curl_easy_cleanup(CURL *curl)
|
||||||
{
|
{
|
||||||
struct SessionHandle *data = (struct SessionHandle *)curl;
|
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||||
|
SIGPIPE_VARIABLE(pipe_st);
|
||||||
|
|
||||||
if(!data)
|
if(!data)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
sigpipe_ignore(data, &pipe_st);
|
||||||
Curl_close(data);
|
Curl_close(data);
|
||||||
}
|
sigpipe_restore(&pipe_st);
|
||||||
|
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -532,12 +841,16 @@ CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)
|
|||||||
{
|
{
|
||||||
va_list arg;
|
va_list arg;
|
||||||
void *paramp;
|
void *paramp;
|
||||||
|
CURLcode ret;
|
||||||
struct SessionHandle *data = (struct SessionHandle *)curl;
|
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||||
|
|
||||||
va_start(arg, info);
|
va_start(arg, info);
|
||||||
paramp = va_arg(arg, void *);
|
paramp = va_arg(arg, void *);
|
||||||
|
|
||||||
return Curl_getinfo(data, info, paramp);
|
ret = Curl_getinfo(data, info, paramp);
|
||||||
|
|
||||||
|
va_end(arg);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -615,8 +928,6 @@ CURL *curl_easy_duphandle(CURL *incurl)
|
|||||||
|
|
||||||
Curl_convert_setup(outcurl);
|
Curl_convert_setup(outcurl);
|
||||||
|
|
||||||
Curl_easy_initHandleData(outcurl);
|
|
||||||
|
|
||||||
outcurl->magic = CURLEASY_MAGIC_NUMBER;
|
outcurl->magic = CURLEASY_MAGIC_NUMBER;
|
||||||
|
|
||||||
/* we reach this point and thus we are OK */
|
/* we reach this point and thus we are OK */
|
||||||
@@ -650,7 +961,7 @@ void curl_easy_reset(CURL *curl)
|
|||||||
|
|
||||||
data->state.path = NULL;
|
data->state.path = NULL;
|
||||||
|
|
||||||
Curl_safefree(data->state.proto.generic);
|
Curl_free_request_state(data);
|
||||||
|
|
||||||
/* zero out UserDefined data: */
|
/* zero out UserDefined data: */
|
||||||
Curl_freeset(data);
|
Curl_freeset(data);
|
||||||
@@ -660,9 +971,6 @@ void curl_easy_reset(CURL *curl)
|
|||||||
/* zero out Progress data: */
|
/* zero out Progress data: */
|
||||||
memset(&data->progress, 0, sizeof(struct Progress));
|
memset(&data->progress, 0, sizeof(struct Progress));
|
||||||
|
|
||||||
/* init Handle data */
|
|
||||||
Curl_easy_initHandleData(data);
|
|
||||||
|
|
||||||
data->progress.flags |= PGRS_HIDE;
|
data->progress.flags |= PGRS_HIDE;
|
||||||
data->state.current_speed = -1; /* init to negative == impossible */
|
data->state.current_speed = -1; /* init to negative == impossible */
|
||||||
}
|
}
|
||||||
@@ -724,7 +1032,7 @@ CURLcode curl_easy_pause(CURL *curl, int action)
|
|||||||
do {
|
do {
|
||||||
chunklen = (tempsize > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:tempsize;
|
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);
|
temptype, tempwrite, chunklen);
|
||||||
if(result)
|
if(result)
|
||||||
/* failures abort the loop at once */
|
/* failures abort the loop at once */
|
||||||
@@ -766,6 +1074,13 @@ CURLcode curl_easy_pause(CURL *curl, int action)
|
|||||||
free(freewrite); /* this is unconditionally no longer used */
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -25,9 +25,9 @@
|
|||||||
/*
|
/*
|
||||||
* Prototypes for library-wide functions provided by easy.c
|
* Prototypes for library-wide functions provided by easy.c
|
||||||
*/
|
*/
|
||||||
void Curl_easy_addmulti(struct SessionHandle *data, void *multi);
|
#ifdef CURLDEBUG
|
||||||
|
CURL_EXTERN CURLcode curl_easy_perform_ev(CURL *easy);
|
||||||
void Curl_easy_initHandleData(struct SessionHandle *data);
|
#endif
|
||||||
|
|
||||||
#endif /* HEADER_CURL_EASYIF_H */
|
#endif /* HEADER_CURL_EASYIF_H */
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -159,7 +159,8 @@ CURLcode Curl_urldecode(struct SessionHandle *data,
|
|||||||
|
|
||||||
while(--alloc > 0) {
|
while(--alloc > 0) {
|
||||||
in = *string;
|
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 '%' */
|
/* this is two hexadecimal digits following a '%' */
|
||||||
char hexstr[3];
|
char hexstr[3];
|
||||||
char *ptr;
|
char *ptr;
|
||||||
|
|||||||
51
lib/file.c
51
lib/file.c
@@ -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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* 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_connect(struct connectdata *conn, bool *done);
|
||||||
static CURLcode file_disconnect(struct connectdata *conn,
|
static CURLcode file_disconnect(struct connectdata *conn,
|
||||||
bool dead_connection);
|
bool dead_connection);
|
||||||
|
static CURLcode file_setup_connection(struct connectdata *conn);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FILE scheme handler.
|
* FILE scheme handler.
|
||||||
@@ -98,7 +98,7 @@ static CURLcode file_disconnect(struct connectdata *conn,
|
|||||||
|
|
||||||
const struct Curl_handler Curl_handler_file = {
|
const struct Curl_handler Curl_handler_file = {
|
||||||
"FILE", /* scheme */
|
"FILE", /* scheme */
|
||||||
ZERO_NULL, /* setup_connection */
|
file_setup_connection, /* setup_connection */
|
||||||
file_do, /* do_it */
|
file_do, /* do_it */
|
||||||
file_done, /* done */
|
file_done, /* done */
|
||||||
ZERO_NULL, /* do_more */
|
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
|
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
|
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;
|
struct SessionHandle *data = conn->data;
|
||||||
char *real_path;
|
char *real_path;
|
||||||
struct FILEPROTO *file;
|
struct FILEPROTO *file = data->req.protop;
|
||||||
int fd;
|
int fd;
|
||||||
#ifdef DOS_FILESYSTEM
|
#ifdef DOS_FILESYSTEM
|
||||||
int i;
|
int i;
|
||||||
char *actual_path;
|
char *actual_path;
|
||||||
#endif
|
#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);
|
real_path = curl_easy_unescape(data, data->state.path, 0, NULL);
|
||||||
if(!real_path)
|
if(!real_path)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
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
|
#ifdef DOS_FILESYSTEM
|
||||||
/* If the first character is a slash, and there's
|
/* If the first character is a slash, and there's
|
||||||
something that looks like a drive at the beginning of
|
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,
|
static CURLcode file_done(struct connectdata *conn,
|
||||||
CURLcode status, bool premature)
|
CURLcode status, bool premature)
|
||||||
{
|
{
|
||||||
struct FILEPROTO *file = conn->data->state.proto.file;
|
struct FILEPROTO *file = conn->data->req.protop;
|
||||||
(void)status; /* not used */
|
(void)status; /* not used */
|
||||||
(void)premature; /* not used */
|
(void)premature; /* not used */
|
||||||
|
|
||||||
@@ -280,7 +268,7 @@ static CURLcode file_done(struct connectdata *conn,
|
|||||||
static CURLcode file_disconnect(struct connectdata *conn,
|
static CURLcode file_disconnect(struct connectdata *conn,
|
||||||
bool dead_connection)
|
bool dead_connection)
|
||||||
{
|
{
|
||||||
struct FILEPROTO *file = conn->data->state.proto.file;
|
struct FILEPROTO *file = conn->data->req.protop;
|
||||||
(void)dead_connection; /* not used */
|
(void)dead_connection; /* not used */
|
||||||
|
|
||||||
if(file) {
|
if(file) {
|
||||||
@@ -302,7 +290,7 @@ static CURLcode file_disconnect(struct connectdata *conn,
|
|||||||
|
|
||||||
static CURLcode file_upload(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);
|
const char *dir = strchr(file->path, DIRSEP);
|
||||||
int fd;
|
int fd;
|
||||||
int mode;
|
int mode;
|
||||||
@@ -440,6 +428,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
|||||||
curl_off_t bytecount = 0;
|
curl_off_t bytecount = 0;
|
||||||
int fd;
|
int fd;
|
||||||
struct timeval now = Curl_tvnow();
|
struct timeval now = Curl_tvnow();
|
||||||
|
struct FILEPROTO *file;
|
||||||
|
|
||||||
*done = TRUE; /* unconditionally */
|
*done = TRUE; /* unconditionally */
|
||||||
|
|
||||||
@@ -449,8 +438,10 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
|||||||
if(data->set.upload)
|
if(data->set.upload)
|
||||||
return file_upload(conn);
|
return file_upload(conn);
|
||||||
|
|
||||||
|
file = conn->data->req.protop;
|
||||||
|
|
||||||
/* get the fd from the connection phase */
|
/* 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 */
|
/* VMS: This only works reliable for STREAMLF files */
|
||||||
if(-1 != fstat(fd, &statbuf)) {
|
if(-1 != fstat(fd, &statbuf)) {
|
||||||
|
|||||||
147
lib/formdata.c
147
lib/formdata.c
@@ -24,9 +24,6 @@
|
|||||||
|
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
/* Length of the random boundary string. */
|
|
||||||
#define BOUNDARY_LENGTH 40
|
|
||||||
|
|
||||||
#if !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY)
|
#if !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY)
|
||||||
|
|
||||||
#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
|
#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
|
||||||
@@ -35,7 +32,7 @@
|
|||||||
|
|
||||||
#include "urldata.h" /* for struct SessionHandle */
|
#include "urldata.h" /* for struct SessionHandle */
|
||||||
#include "formdata.h"
|
#include "formdata.h"
|
||||||
#include "curl_rand.h"
|
#include "sslgen.h"
|
||||||
#include "strequal.h"
|
#include "strequal.h"
|
||||||
#include "curl_memory.h"
|
#include "curl_memory.h"
|
||||||
#include "sendf.h"
|
#include "sendf.h"
|
||||||
@@ -56,7 +53,7 @@ static char *Curl_basename(char *path);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static size_t readfromfile(struct Form *form, char *buffer, size_t size);
|
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
|
/* What kind of Content-Type to use on un-specified files with unrecognized
|
||||||
extensions. */
|
extensions. */
|
||||||
@@ -171,8 +168,8 @@ static FormInfo * AddFormInfo(char *value,
|
|||||||
* Returns some valid contenttype for filename.
|
* Returns some valid contenttype for filename.
|
||||||
*
|
*
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static const char * ContentTypeForFilename (const char *filename,
|
static const char *ContentTypeForFilename(const char *filename,
|
||||||
const char *prevtype)
|
const char *prevtype)
|
||||||
{
|
{
|
||||||
const char *contenttype = NULL;
|
const char *contenttype = NULL;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
@@ -181,7 +178,7 @@ static const char * ContentTypeForFilename (const char *filename,
|
|||||||
* extensions and pick the first we match!
|
* extensions and pick the first we match!
|
||||||
*/
|
*/
|
||||||
struct ContentType {
|
struct ContentType {
|
||||||
char extension[6];
|
const char *extension;
|
||||||
const char *type;
|
const char *type;
|
||||||
};
|
};
|
||||||
static const struct ContentType ctts[]={
|
static const struct ContentType ctts[]={
|
||||||
@@ -429,7 +426,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||||||
|
|
||||||
/* Get contents from a given file name */
|
/* Get contents from a given file name */
|
||||||
case CURLFORM_FILECONTENT:
|
case CURLFORM_FILECONTENT:
|
||||||
if(current_form->flags != 0)
|
if(current_form->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_READFILE))
|
||||||
return_value = CURL_FORMADD_OPTION_TWICE;
|
return_value = CURL_FORMADD_OPTION_TWICE;
|
||||||
else {
|
else {
|
||||||
const char *filename = array_state?
|
const char *filename = array_state?
|
||||||
@@ -670,9 +667,11 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||||||
if(((form->flags & HTTPPOST_FILENAME) ||
|
if(((form->flags & HTTPPOST_FILENAME) ||
|
||||||
(form->flags & HTTPPOST_BUFFER)) &&
|
(form->flags & HTTPPOST_BUFFER)) &&
|
||||||
!form->contenttype ) {
|
!form->contenttype ) {
|
||||||
|
char *f = form->flags & HTTPPOST_BUFFER?
|
||||||
|
form->showfilename : form->value;
|
||||||
|
|
||||||
/* our contenttype is missing */
|
/* our contenttype is missing */
|
||||||
form->contenttype
|
form->contenttype = strdup(ContentTypeForFilename(f, prevtype));
|
||||||
= strdup(ContentTypeForFilename(form->value, prevtype));
|
|
||||||
if(!form->contenttype) {
|
if(!form->contenttype) {
|
||||||
return_value = CURL_FORMADD_MEMORY;
|
return_value = CURL_FORMADD_MEMORY;
|
||||||
break;
|
break;
|
||||||
@@ -777,6 +776,70 @@ CURLFORMcode curl_formadd(struct curl_httppost **httppost,
|
|||||||
return result;
|
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.
|
* 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)) {
|
if(!strequal("-", newform->line)) {
|
||||||
struct_stat file;
|
struct_stat file;
|
||||||
if(!stat(newform->line, &file) && !S_ISDIR(file.st_mode))
|
if(!stat(newform->line, &file) && !S_ISDIR(file.st_mode))
|
||||||
*size += file.st_size;
|
*size += filesize(newform->line, file);
|
||||||
else
|
else
|
||||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||||
}
|
}
|
||||||
@@ -1101,7 +1164,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
|
|||||||
if(!post)
|
if(!post)
|
||||||
return result; /* no input => no output! */
|
return result; /* no input => no output! */
|
||||||
|
|
||||||
boundary = formboundary();
|
boundary = formboundary(data);
|
||||||
if(!boundary)
|
if(!boundary)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
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 */
|
the magic to include several files with the same field name */
|
||||||
|
|
||||||
Curl_safefree(fileboundary);
|
Curl_safefree(fileboundary);
|
||||||
fileboundary = formboundary();
|
fileboundary = formboundary(data);
|
||||||
if(!fileboundary) {
|
if(!fileboundary) {
|
||||||
result = CURLE_OUT_OF_MEMORY;
|
result = CURLE_OUT_OF_MEMORY;
|
||||||
break;
|
break;
|
||||||
@@ -1343,6 +1406,36 @@ int Curl_FormInit(struct Form *form, struct FormData *formdata )
|
|||||||
return 0;
|
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()
|
* readfromfile()
|
||||||
*
|
*
|
||||||
@@ -1365,7 +1458,7 @@ static size_t readfromfile(struct Form *form, char *buffer,
|
|||||||
else {
|
else {
|
||||||
if(!form->fp) {
|
if(!form->fp) {
|
||||||
/* this file hasn't yet been opened */
|
/* 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)
|
if(!form->fp)
|
||||||
return (size_t)-1; /* failure */
|
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
|
* formboundary() creates a suitable boundary string and returns an allocated
|
||||||
* one.
|
* one.
|
||||||
*/
|
*/
|
||||||
static char *formboundary(void)
|
static char *formboundary(struct SessionHandle *data)
|
||||||
{
|
{
|
||||||
char *retstring;
|
/* 24 dashes and 16 hexadecimal digits makes 64 bit (18446744073709551615)
|
||||||
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)
|
|
||||||
combinations */
|
combinations */
|
||||||
retstring[BOUNDARY_LENGTH]=0; /* zero terminate */
|
return aprintf("------------------------%08x%08x",
|
||||||
|
Curl_rand(data), Curl_rand(data));
|
||||||
return retstring;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* CURL_DISABLE_HTTP */
|
#else /* CURL_DISABLE_HTTP */
|
||||||
|
|||||||
@@ -147,6 +147,12 @@ struct ftp_conn {
|
|||||||
curl_off_t known_filesize; /* file size is different from -1, if wildcard
|
curl_off_t known_filesize; /* file size is different from -1, if wildcard
|
||||||
LIST parsing was done and wc_statemach set
|
LIST parsing was done and wc_statemach set
|
||||||
it */
|
it */
|
||||||
|
/* newhost must be able to hold a full IP-style address in ASCII, which
|
||||||
|
in the IPv6 case means 5*8-1 = 39 letters */
|
||||||
|
#define NEWHOST_BUFSIZE 48
|
||||||
|
char newhost[NEWHOST_BUFSIZE]; /* this is the pair to connect the DATA... */
|
||||||
|
unsigned short newport; /* connection to */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEFAULT_ACCEPT_TIMEOUT 60000 /* milliseconds == one minute */
|
#define DEFAULT_ACCEPT_TIMEOUT 60000 /* milliseconds == one minute */
|
||||||
|
|||||||
@@ -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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* 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;
|
pro->t_redirect = 0;
|
||||||
|
|
||||||
info->httpcode = 0;
|
info->httpcode = 0;
|
||||||
info->httpversion=0;
|
info->httpversion = 0;
|
||||||
info->filetime=-1; /* -1 is an illegal time and thus means unknown */
|
info->filetime = -1; /* -1 is an illegal time and thus means unknown */
|
||||||
|
info->timecond = FALSE;
|
||||||
|
|
||||||
if(info->contenttype)
|
if(info->contenttype)
|
||||||
free(info->contenttype);
|
free(info->contenttype);
|
||||||
@@ -185,7 +186,7 @@ static CURLcode getinfo_long(struct SessionHandle *data, CURLINFO info,
|
|||||||
break;
|
break;
|
||||||
case CURLINFO_CONDITION_UNMET:
|
case CURLINFO_CONDITION_UNMET:
|
||||||
/* return if the condition prevented the document to get transferred */
|
/* return if the condition prevented the document to get transferred */
|
||||||
*param_longp = data->info.timecond;
|
*param_longp = data->info.timecond ? 1L : 0L;
|
||||||
break;
|
break;
|
||||||
case CURLINFO_RTSP_CLIENT_CSEQ:
|
case CURLINFO_RTSP_CLIENT_CSEQ:
|
||||||
*param_longp = data->state.rtsp_next_client_CSeq;
|
*param_longp = data->state.rtsp_next_client_CSeq;
|
||||||
@@ -276,7 +277,57 @@ static CURLcode getinfo_slist(struct SessionHandle *data, CURLINFO info,
|
|||||||
ptr.to_certinfo = &data->info.certs;
|
ptr.to_certinfo = &data->info.certs;
|
||||||
*param_slistp = ptr.to_slist;
|
*param_slistp = ptr.to_slist;
|
||||||
break;
|
break;
|
||||||
|
case CURLINFO_TLS_SESSION:
|
||||||
|
{
|
||||||
|
struct curl_tlssessioninfo **tsip = (struct curl_tlssessioninfo **)
|
||||||
|
param_slistp;
|
||||||
|
struct curl_tlssessioninfo *tsi = &data->tsi;
|
||||||
|
struct connectdata *conn = data->easy_conn;
|
||||||
|
unsigned int sockindex = 0;
|
||||||
|
|
||||||
|
*tsip = tsi;
|
||||||
|
tsi->backend = CURLSSLBACKEND_NONE;
|
||||||
|
tsi->internals = NULL;
|
||||||
|
|
||||||
|
if(!conn)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Find the active ("in use") SSL connection, if any */
|
||||||
|
while((sockindex < sizeof(conn->ssl) / sizeof(conn->ssl[0])) &&
|
||||||
|
(!conn->ssl[sockindex].use))
|
||||||
|
sockindex++;
|
||||||
|
|
||||||
|
if(sockindex == sizeof(conn->ssl) / sizeof(conn->ssl[0]))
|
||||||
|
break; /* no SSL session found */
|
||||||
|
|
||||||
|
/* Return the TLS session information from the relevant backend */
|
||||||
|
#ifdef USE_SSLEAY
|
||||||
|
tsi->backend = CURLSSLBACKEND_OPENSSL;
|
||||||
|
tsi->internals = conn->ssl[sockindex].ctx;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_GNUTLS
|
||||||
|
tsi->backend = CURLSSLBACKEND_GNUTLS;
|
||||||
|
tsi->internals = conn->ssl[sockindex].session;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_NSS
|
||||||
|
tsi->backend = CURLSSLBACKEND_NSS;
|
||||||
|
tsi->internals = conn->ssl[sockindex].handle;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_QSOSSL
|
||||||
|
tsi->backend = CURLSSLBACKEND_QSOSSL;
|
||||||
|
tsi->internals = conn->ssl[sockindex].handle;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_GSKIT
|
||||||
|
tsi->backend = CURLSSLBACKEND_GSKIT;
|
||||||
|
tsi->internals = conn->ssl[sockindex].handle;
|
||||||
|
#endif
|
||||||
|
/* NOTE: For other SSL backends, it is not immediately clear what data
|
||||||
|
to return from 'struct ssl_connect_data'; thus, for now we keep the
|
||||||
|
backend as CURLSSLBACKEND_NONE in those cases, which should be
|
||||||
|
interpreted as "not supported" */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|||||||
1053
lib/gskit.c
Normal file
1053
lib/gskit.c
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user