third-party libs
This commit is contained in:
parent
f836927d3a
commit
b154ee9266
3667 changed files with 854591 additions and 0 deletions
2
third-party/curl-7.21.4/docs/.gitignore
vendored
Normal file
2
third-party/curl-7.21.4/docs/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
*.html
|
||||
*.pdf
|
||||
228
third-party/curl-7.21.4/docs/BINDINGS
vendored
Normal file
228
third-party/curl-7.21.4/docs/BINDINGS
vendored
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
libcurl bindings
|
||||
|
||||
Creative people have written bindings or interfaces for various environments
|
||||
and programming languages. Using one of these allows you to take advantage of
|
||||
curl powers from within your favourite language or system.
|
||||
|
||||
This is a list of all known interfaces as of this writing.
|
||||
|
||||
The bindings listed below are not part of the curl/libcurl distribution
|
||||
archives, but must be downloaded and installed separately.
|
||||
|
||||
Ada95
|
||||
|
||||
Writtten by Andreas Almroth
|
||||
http://www.almroth.com/adacurl/index.html
|
||||
|
||||
Basic
|
||||
|
||||
ScriptBasic bindings to libcurl. Writtten by Peter Verhas
|
||||
http://scriptbasic.com/
|
||||
|
||||
C
|
||||
libcurl is a C library in itself!
|
||||
http://curl.haxx.se/libcurl/
|
||||
|
||||
C++
|
||||
|
||||
Written by Jean-Philippe Barrette-LaPierre
|
||||
http://curlpp.org/
|
||||
|
||||
Ch
|
||||
|
||||
Written by Stephen Nestinger and Jonathan Rogado
|
||||
http://chcurl.sourceforge.net/
|
||||
|
||||
Cocoa
|
||||
|
||||
Written by Dan Wood
|
||||
http://curlhandle.sourceforge.net/
|
||||
|
||||
D
|
||||
|
||||
Written by Kenneth Bogert
|
||||
http://curl.haxx.se/libcurl/d/
|
||||
|
||||
Dylan
|
||||
|
||||
Written by Chris Double
|
||||
http://dylanlibs.sourceforge.net/
|
||||
|
||||
Eiffel
|
||||
Written by Eiffel Software
|
||||
http://curl.haxx.se/libcurl/eiffel/
|
||||
|
||||
Euphoria
|
||||
|
||||
Written by Ray Smith
|
||||
http://rays-web.com/eulibcurl.htm
|
||||
|
||||
Falcon
|
||||
|
||||
http://www.falconpl.org/index.ftd?page_id=prjs&prj_id=curl
|
||||
|
||||
Ferite
|
||||
|
||||
Written by Paul Querna
|
||||
http://www.ferite.org/
|
||||
|
||||
Gambas
|
||||
|
||||
http://gambas.sourceforge.net
|
||||
|
||||
glib/GTK+
|
||||
|
||||
Written by Richard Atterer
|
||||
http://atterer.net/glibcurl/
|
||||
|
||||
Haskell
|
||||
|
||||
Written by Galois, Inc
|
||||
http://hackage.haskell.org/cgi-bin/hackage-scripts/package/curl
|
||||
|
||||
Java
|
||||
|
||||
Maintained by [blank]
|
||||
http://curl.haxx.se/libcurl/java/
|
||||
|
||||
Lisp
|
||||
|
||||
Written by Liam Healy
|
||||
http://common-lisp.net/project/cl-curl/
|
||||
|
||||
Lua
|
||||
|
||||
luacurl by Alexander Marinov
|
||||
http://luacurl.luaforge.net/
|
||||
|
||||
Lua-cURL by Jürgen Hötzel
|
||||
http://luaforge.net/projects/lua-curl/
|
||||
|
||||
Mono
|
||||
|
||||
Written by Jeffrey Phillips
|
||||
http://forge.novell.com/modules/xfmod/project/?libcurl-mono
|
||||
|
||||
.NET
|
||||
|
||||
libcurl-net by Jeffrey Phillips
|
||||
http://sourceforge.net/projects/libcurl-net/
|
||||
|
||||
Object-Pascal
|
||||
|
||||
Free Pascal, Delphi and Kylix binding written by Christophe Espern.
|
||||
http://www.tekool.com/opcurl
|
||||
|
||||
O'Caml
|
||||
|
||||
Written by Lars Nilsson
|
||||
http://sourceforge.net/projects/ocurl/
|
||||
|
||||
Pascal
|
||||
|
||||
Free Pascal, Delphi and Kylix binding written by Jeffrey Pohlmeyer.
|
||||
http://houston.quik.com/jkp/curlpas/
|
||||
|
||||
Perl
|
||||
|
||||
Maintained by Cris Bailiff
|
||||
http://curl.haxx.se/libcurl/perl/
|
||||
|
||||
PHP
|
||||
|
||||
Written by Sterling Hughes
|
||||
http://curl.haxx.se/libcurl/php/
|
||||
|
||||
PostgreSQL
|
||||
|
||||
Written by Gian Paolo Ciceri
|
||||
http://gborg.postgresql.org/project/pgcurl/projdisplay.php
|
||||
|
||||
Python
|
||||
|
||||
PycURL by Kjetil Jacobsen
|
||||
http://pycurl.sourceforge.net/
|
||||
|
||||
R
|
||||
|
||||
RCurl by Duncan Temple Lang
|
||||
http://www.omegahat.org/RCurl/
|
||||
|
||||
Rexx
|
||||
|
||||
Written Mark Hessling
|
||||
http://rexxcurl.sourceforge.net/
|
||||
|
||||
RPG
|
||||
|
||||
Support for ILE/RPG on OS/400 is included in source distribution
|
||||
http://curl.haxx.se/libcurl/
|
||||
See packages/OS400/README.OS400 and packages/OS400/curl.inc.in
|
||||
|
||||
Ruby
|
||||
|
||||
curb - written by Ross Bamford
|
||||
http://curb.rubyforge.org/
|
||||
|
||||
ruby-curl-multi - written by Kristjan Petursson and Keith Rarick
|
||||
http://curl-multi.rubyforge.org/
|
||||
|
||||
Scheme
|
||||
|
||||
Bigloo binding by Kirill Lisovsky
|
||||
http://curl.haxx.se/libcurl/scheme/
|
||||
|
||||
S-Lang
|
||||
|
||||
S-Lang binding by John E Davis
|
||||
http://www.jedsoft.org/slang/modules/curl.html
|
||||
|
||||
Smalltalk
|
||||
|
||||
Smalltalk binding by Danil Osipchuk
|
||||
http://www.squeaksource.com/CurlPlugin/
|
||||
|
||||
SP-Forth
|
||||
|
||||
SP-Forth binding by ygrek
|
||||
http://www.forth.org.ru/~ac/lib/lin/curl/
|
||||
|
||||
SPL
|
||||
|
||||
SPL binding by Clifford Wolf
|
||||
http://www.clifford.at/spl/
|
||||
|
||||
Tcl
|
||||
|
||||
Tclcurl by Andrés García
|
||||
http://personal1.iddeo.es/andresgarci/tclcurl/english/docs.html
|
||||
|
||||
Visual Basic
|
||||
|
||||
libcurl-vb by Jeffrey Phillips
|
||||
http://sourceforge.net/projects/libcurl-vb/
|
||||
|
||||
Visual Foxpro
|
||||
|
||||
by Carlos Alloatti
|
||||
http://www.ctl32.com.ar/libcurl.asp
|
||||
|
||||
Q
|
||||
The libcurl module is part of the default install
|
||||
http://q-lang.sourceforge.net/
|
||||
|
||||
wxWidgets
|
||||
|
||||
Written by Casey O'Donnell
|
||||
http://wxcode.sourceforge.net/components/wxcurl/
|
||||
|
||||
XBLite
|
||||
|
||||
Written by David Szafranski
|
||||
http://perso.wanadoo.fr/xblite/libraries.html
|
||||
81
third-party/curl-7.21.4/docs/BUGS
vendored
Normal file
81
third-party/curl-7.21.4/docs/BUGS
vendored
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
BUGS
|
||||
|
||||
Curl and libcurl have grown substantially since the beginning. At the time
|
||||
of writing (July 2007), there are about 47000 lines of source code, and by
|
||||
the time you read this it has probably grown even more.
|
||||
|
||||
Of course there are lots of bugs left. And lots of misfeatures.
|
||||
|
||||
To help us make curl the stable and solid product we want it to be, we need
|
||||
bug reports and bug fixes.
|
||||
|
||||
WHERE TO REPORT
|
||||
|
||||
If you can't fix a bug yourself and submit a fix for it, try to report an as
|
||||
detailed report as possible to a curl mailing list to allow one of us to
|
||||
have a go at a solution. You should also post your bug/problem at curl's bug
|
||||
tracking system over at
|
||||
|
||||
http://sourceforge.net/bugs/?group_id=976
|
||||
|
||||
(but please read the sections below first before doing that)
|
||||
|
||||
If you feel you need to ask around first, find a suitable mailing list and
|
||||
post there. The lists are available on http://curl.haxx.se/mail/
|
||||
|
||||
WHAT TO REPORT
|
||||
|
||||
When reporting a bug, you should include all information that will help us
|
||||
understand what's wrong, what you expected to happen and how to repeat the
|
||||
bad behavior. You therefore need to tell us:
|
||||
|
||||
- your operating system's name and version number (uname -a under a unix
|
||||
is fine)
|
||||
- what version of curl you're using (curl -V is fine)
|
||||
- versions of the used libraries that libcurl is built to use
|
||||
- what URL you were working with (if possible), at least which protocol
|
||||
|
||||
and anything and everything else you think matters. Tell us what you
|
||||
expected to happen, tell use what did happen, tell us how you could make it
|
||||
work another way. Dig around, try out, test. Then include all the tiny bits
|
||||
and pieces in your report. You will benefit from this yourself, as it will
|
||||
enable us to help you quicker and more accurately.
|
||||
|
||||
Since curl deals with networks, it often helps us if you include a protocol
|
||||
debug dump with your bug report. The output you get by using the -v or
|
||||
--trace options.
|
||||
|
||||
If curl crashed, causing a core dump (in unix), there is hardly any use to
|
||||
send that huge file to anyone of us. Unless we have an exact same system
|
||||
setup as you, we can't do much with it. Instead we ask you to get a stack
|
||||
trace and send that (much smaller) output to us instead!
|
||||
|
||||
The address and how to subscribe to the mailing lists are detailed in the
|
||||
MANUAL file.
|
||||
|
||||
HOW TO GET A STACK TRACE
|
||||
|
||||
First, you must make sure that you compile all sources with -g and that you
|
||||
don't 'strip' the final executable. Try to avoid optimizing the code as
|
||||
well, remove -O, -O2 etc from the compiler options.
|
||||
|
||||
Run the program until it cores.
|
||||
|
||||
Run your debugger on the core file, like '<debugger> curl core'. <debugger>
|
||||
should be replaced with the name of your debugger, in most cases that will
|
||||
be 'gdb', but 'dbx' and others also occur.
|
||||
|
||||
When the debugger has finished loading the core file and presents you a
|
||||
prompt, enter 'where' (without the quotes) and press return.
|
||||
|
||||
The list that is presented is the stack trace. If everything worked, it is
|
||||
supposed to contain the chain of functions that were called when curl
|
||||
crashed. Include the stack trace with your detailed bug report. It'll help a
|
||||
lot.
|
||||
|
||||
279
third-party/curl-7.21.4/docs/CONTRIBUTE
vendored
Normal file
279
third-party/curl-7.21.4/docs/CONTRIBUTE
vendored
Normal file
|
|
@ -0,0 +1,279 @@
|
|||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
When Contributing Source Code
|
||||
|
||||
This document is intended to offer guidelines that can be useful to keep in
|
||||
mind when you decide to contribute to the project. This concerns new features
|
||||
as well as corrections to existing flaws or bugs.
|
||||
|
||||
1. Learning cURL
|
||||
1.1 Join the Community
|
||||
1.2 License
|
||||
1.3 What To Read
|
||||
|
||||
2. cURL Coding Standards
|
||||
2.1 Naming
|
||||
2.2 Indenting
|
||||
2.3 Commenting
|
||||
2.4 Line Lengths
|
||||
2.5 General Style
|
||||
2.6 Non-clobbering All Over
|
||||
2.7 Platform Dependent Code
|
||||
2.8 Write Separate Patches
|
||||
2.9 Patch Against Recent Sources
|
||||
2.10 Document
|
||||
2.11 Test Cases
|
||||
|
||||
3. Pushing Out Your Changes
|
||||
3.1 Write Access to git Repository
|
||||
3.2 How To Make a Patch with git
|
||||
3.3 How To Make a Patch without git
|
||||
3.4 How to get your changes into the main sources
|
||||
3.5 Write good commit messages
|
||||
|
||||
==============================================================================
|
||||
|
||||
1. Learning cURL
|
||||
|
||||
1.1 Join the Community
|
||||
|
||||
Skip over to http://curl.haxx.se/mail/ and join the appropriate mailing
|
||||
list(s). Read up on details before you post questions. Read this file before
|
||||
you start sending patches! We prefer patches and discussions being held on
|
||||
the mailing list(s), not sent to individuals.
|
||||
|
||||
Before posting to one of the curl mailing lists, please read up on the mailing
|
||||
list etiquette: http://curl.haxx.se/mail/etiquette.html
|
||||
|
||||
We also hang out on IRC in #curl on irc.freenode.net
|
||||
|
||||
1.2. License
|
||||
|
||||
When contributing with code, you agree to put your changes and new code under
|
||||
the same license curl and libcurl is already using unless stated and agreed
|
||||
otherwise.
|
||||
|
||||
If you add a larger piece of code, you can opt to make that file or set of
|
||||
files to use a different license as long as they don't enforce any changes to
|
||||
the rest of the package and they make sense. Such "separate parts" can not be
|
||||
GPL licensed (as we don't want copyleft to affect users of libcurl) but they
|
||||
must use "GPL compatible" licenses (as we want to allow users to use libcurl
|
||||
properly in GPL licensed environments).
|
||||
|
||||
When changing existing source code, you do not alter the copyright of the
|
||||
original file(s). The copyright will still be owned by the original
|
||||
creator(s) or those who have been assigned copyright by the original
|
||||
author(s).
|
||||
|
||||
By submitting a patch to the curl project, you are assumed to have the right
|
||||
to the code and to be allowed by your employer or whatever to hand over that
|
||||
patch/code to us. We will credit you for your changes as far as possible, to
|
||||
give credit but also to keep a trace back to who made what changes. Please
|
||||
always provide us with your full real name when contributing!
|
||||
|
||||
1.3 What To Read
|
||||
|
||||
Source code, the man pages, the INTERNALS document, TODO, KNOWN_BUGS, the
|
||||
most recent CHANGES. Just lurking on the libcurl mailing list is gonna give
|
||||
you a lot of insights on what's going on right now. Asking there is a good
|
||||
idea too.
|
||||
|
||||
2. cURL Coding Standards
|
||||
|
||||
2.1 Naming
|
||||
|
||||
Try using a non-confusing naming scheme for your new functions and variable
|
||||
names. It doesn't necessarily have to mean that you should use the same as in
|
||||
other places of the code, just that the names should be logical,
|
||||
understandable and be named according to what they're used for. File-local
|
||||
functions should be made static. We like lower case names.
|
||||
|
||||
See the INTERNALS document on how we name non-exported library-global
|
||||
symbols.
|
||||
|
||||
2.2 Indenting
|
||||
|
||||
Please try using the same indenting levels and bracing method as all the
|
||||
other code already does. It makes the source code a lot easier to follow if
|
||||
all of it is written using the same style. We don't ask you to like it, we
|
||||
just ask you to follow the tradition! ;-) This mainly means: 2-level indents,
|
||||
using spaces only (no tabs) and having the opening brace ({) on the same line
|
||||
as the if() or while().
|
||||
|
||||
Also note that we use if() and while() with no space before the parenthesis.
|
||||
|
||||
2.3 Commenting
|
||||
|
||||
Comment your source code extensively using C comments (/* comment */), DO NOT
|
||||
use C++ comments (// this style). Commented code is quality code and enables
|
||||
future modifications much more. Uncommented code risk having to be completely
|
||||
replaced when someone wants to extend things, since other persons' source
|
||||
code can get quite hard to read.
|
||||
|
||||
2.4 Line Lengths
|
||||
|
||||
We write source lines shorter than 80 columns.
|
||||
|
||||
2.5 General Style
|
||||
|
||||
Keep your functions small. If they're small you avoid a lot of mistakes and
|
||||
you don't accidentally mix up variables etc.
|
||||
|
||||
2.6 Non-clobbering All Over
|
||||
|
||||
When you write new functionality or fix bugs, it is important that you don't
|
||||
fiddle all over the source files and functions. Remember that it is likely
|
||||
that other people have done changes in the same source files as you have and
|
||||
possibly even in the same functions. If you bring completely new
|
||||
functionality, try writing it in a new source file. If you fix bugs, try to
|
||||
fix one bug at a time and send them as separate patches.
|
||||
|
||||
2.7 Platform Dependent Code
|
||||
|
||||
Use #ifdef HAVE_FEATURE to do conditional code. We avoid checking for
|
||||
particular operating systems or hardware in the #ifdef lines. The
|
||||
HAVE_FEATURE shall be generated by the configure script for unix-like systems
|
||||
and they are hard-coded in the config-[system].h files for the others.
|
||||
|
||||
2.8 Write Separate Patches
|
||||
|
||||
It is annoying when you get a huge patch from someone that is said to fix 511
|
||||
odd problems, but discussions and opinions don't agree with 510 of them - or
|
||||
509 of them were already fixed in a different way. Then the patcher needs to
|
||||
extract the single interesting patch from somewhere within the huge pile of
|
||||
source, and that gives a lot of extra work. Preferably, all fixes that
|
||||
correct different problems should be in their own patch with an attached
|
||||
description exactly what they correct so that all patches can be selectively
|
||||
applied by the maintainer or other interested parties.
|
||||
|
||||
2.9 Patch Against Recent Sources
|
||||
|
||||
Please try to get the latest available sources to make your patches
|
||||
against. It makes the life of the developers so much easier. The very best is
|
||||
if you get the most up-to-date sources from the git repository, but the
|
||||
latest release archive is quite OK as well!
|
||||
|
||||
2.10 Document
|
||||
|
||||
Writing docs is dead boring and one of the big problems with many open source
|
||||
projects. Someone's gotta do it. It makes it a lot easier if you submit a
|
||||
small description of your fix or your new features with every contribution so
|
||||
that it can be swiftly added to the package documentation.
|
||||
|
||||
The documentation is always made in man pages (nroff formatted) or plain
|
||||
ASCII files. All HTML files on the web site and in the release archives are
|
||||
generated from the nroff/ASCII versions.
|
||||
|
||||
2.11 Test Cases
|
||||
|
||||
Since the introduction of the test suite, we can quickly verify that the main
|
||||
features are working as they're supposed to. To maintain this situation and
|
||||
improve it, all new features and functions that are added need to be tested
|
||||
in the test suite. Every feature that is added should get at least one valid
|
||||
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!
|
||||
|
||||
3. Pushing Out Your Changes
|
||||
|
||||
3.1 Write Access to git Repository
|
||||
|
||||
If you are a frequent contributor, or have another good reason, you can of
|
||||
course get write access to the git repository and then you'll be able to push
|
||||
your changes straight into the git repo instead of sending changes by mail as
|
||||
patches. Just ask if this is what you'd want. You will be required to have
|
||||
posted a few quality patches first, before you can be granted push access.
|
||||
|
||||
3.2 How To Make a Patch with git
|
||||
|
||||
You need to first checkout the repository:
|
||||
|
||||
git clone git://github.com/bagder/curl.git
|
||||
|
||||
You then proceed and edit all the files you like and you commit them to your
|
||||
local repository:
|
||||
|
||||
git commit [file]
|
||||
|
||||
As usual, group your commits so that you commit all changes that at once that
|
||||
constitutes a logical change. See also section "3.5 Write good commit
|
||||
messages".
|
||||
|
||||
Once you have done all your commits and you're happy with what you see, you
|
||||
can make patches out of your changes that are suitable for mailing:
|
||||
|
||||
git format-patch remotes/origin/master
|
||||
|
||||
This creates files in your local directory named NNNN-[name].patch for each
|
||||
commit.
|
||||
|
||||
Now send those patches off to the curl-library list. You can of course opt to
|
||||
do that with the 'get send-email' command.
|
||||
|
||||
3.3 How To Make a Patch without git
|
||||
|
||||
Keep a copy of the unmodified curl sources. Make your changes in a separate
|
||||
source tree. When you think you have something that you want to offer the
|
||||
curl community, use GNU diff to generate patches.
|
||||
|
||||
If you have modified a single file, try something like:
|
||||
|
||||
diff -u unmodified-file.c my-changed-one.c > my-fixes.diff
|
||||
|
||||
If you have modified several files, possibly in different directories, you
|
||||
can use diff recursively:
|
||||
|
||||
diff -ur curl-original-dir curl-modified-sources-dir > my-fixes.diff
|
||||
|
||||
The GNU diff and GNU patch tools exist for virtually all platforms, including
|
||||
all kinds of Unixes and Windows:
|
||||
|
||||
For unix-like operating systems:
|
||||
|
||||
http://www.gnu.org/software/patch/patch.html
|
||||
http://www.gnu.org/directory/diffutils.html
|
||||
|
||||
For Windows:
|
||||
|
||||
http://gnuwin32.sourceforge.net/packages/patch.htm
|
||||
http://gnuwin32.sourceforge.net/packages/diffutils.htm
|
||||
|
||||
3.4 How to get your changes into the main sources
|
||||
|
||||
1. Submit your patch to the curl-library mailing list
|
||||
|
||||
2. Make the patch against as recent sources as possible.
|
||||
|
||||
3. Make sure your patch adheres to the source indent and coding style of
|
||||
already existing source code. Failing to do so just adds more work for me.
|
||||
|
||||
4. Respond to replies on the list about the patch and answer questions and/or
|
||||
fix nits/flaws. This is very important. I will take lack of replies as a
|
||||
sign that you're not very anxious to get your patch accepted and I tend to
|
||||
simply drop such patches from my TODO list.
|
||||
|
||||
5. If you've followed the above mentioned paragraphs and your patch still
|
||||
hasn't been incorporated after some weeks, consider resubmitting it to the
|
||||
list.
|
||||
|
||||
3.5 Write good commit messages
|
||||
|
||||
A short guide to how to do fine commit messages in the curl project.
|
||||
|
||||
---- start ----
|
||||
[area]: [short line describing the main effect]
|
||||
|
||||
[separate the above single line from the rest with an empty line]
|
||||
|
||||
[full description, no wider than 72 columns that describe as much as
|
||||
possible as to why this change is made, and possibly what things
|
||||
it fixes and everything else that is related]
|
||||
---- stop ----
|
||||
|
||||
Don't forget to use commit --author="" if you commit someone else's work,
|
||||
and make sure that you have your own user and email setup correctly in git
|
||||
before you commit
|
||||
|
||||
176
third-party/curl-7.21.4/docs/DISTRO-DILEMMA
vendored
Normal file
176
third-party/curl-7.21.4/docs/DISTRO-DILEMMA
vendored
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
Date: February 11, 2007
|
||||
Author: Daniel Stenberg <daniel@haxx.se>
|
||||
URL: http://curl.haxx.se/legal/distro-dilemma.html
|
||||
|
||||
Condition
|
||||
|
||||
This document is written to describe the situation as it is right now.
|
||||
libcurl 7.16.1 is currently the latest version available. Things may of
|
||||
course change in the future.
|
||||
|
||||
This document reflects my view and understanding of these things. Please tell
|
||||
me where and how you think I'm wrong, and I'll try to correct my mistakes.
|
||||
|
||||
Background
|
||||
|
||||
The Free Software Foundation has deemed the Original BSD license[1] to be
|
||||
"incompatible"[2] with GPL[3]. I'd rather say it is the other way around, but
|
||||
the point is the same: if you distribute a binary version of a GPL program,
|
||||
it MUST NOT be linked with any Original BSD-licensed parts or libraries.
|
||||
Doing so will violate the GPL license. For a long time, very many GPL
|
||||
licensed programs have avoided this license mess by adding an exception[8] to
|
||||
their license. And many others have just closed their eyes for this problem.
|
||||
|
||||
libcurl is MIT-style[4] licensed - how on earth did this dilemma fall onto
|
||||
our plates?
|
||||
|
||||
libcurl is only a little library. libcurl can be built to use OpenSSL for its
|
||||
SSL/TLS capabilities. OpenSSL is basically Original BSD licensed[5].
|
||||
|
||||
If libcurl built to use OpenSSL is used by a GPL-licensed application and you
|
||||
decide to distribute a binary version of it (Linux distros - for example -
|
||||
tend to), you have a clash. GPL vs Original BSD.
|
||||
|
||||
This dilemma is not libcurl-specific nor is it specific to any particular
|
||||
Linux distro. (This article mentions and refers to Debian several times, but
|
||||
only because Debian seems to be the only Linux distro to have faced this
|
||||
issue yet since no other distro is shipping libcurl built with two SSL
|
||||
libraries.)
|
||||
|
||||
Part of the Operating System
|
||||
|
||||
This would not be a problem if the used lib would be considered part of the
|
||||
underlying operating system, as then the GPL license has an exception
|
||||
clause[6] that allows applications to use such libs without having to be
|
||||
allowed to distribute it or its sources. Possibly some distros will claim
|
||||
that OpenSSL is part of their operating system.
|
||||
|
||||
Debian does however not take this stance and has officially(?) claimed that
|
||||
OpenSSL is not a required part of the Debian operating system
|
||||
|
||||
Some people claim that this paragraph cannot be exploited this way by a Linux
|
||||
distro, but I am not a lawyer and that is a discussion left outside of this
|
||||
document.
|
||||
|
||||
GnuTLS
|
||||
|
||||
Since May 2005 libcurl can get built to use GnuTLS instead of OpenSSL. GnuTLS
|
||||
is an LGPL[7] licensed library that offers a matching set of features as
|
||||
OpenSSL does. Now, you can build and distribute an TLS/SSL capable libcurl
|
||||
without including any Original BSD licensed code.
|
||||
|
||||
I believe Debian is the first (only?) distro that provides libcurl/GnutTLS
|
||||
packages.
|
||||
|
||||
yassl
|
||||
|
||||
libcurl can get also get built to use yassl for the TLS/SSL layer. yassl is a
|
||||
GPL[3] licensed library.
|
||||
|
||||
|
||||
GnuTLS vs OpenSSL vs yassl
|
||||
|
||||
While these three libraries offer similar features, they are not equal.
|
||||
libcurl does not (yet) offer a standardized stable ABI if you decide to
|
||||
switch from using libcurl-openssl to libcurl-gnutls or vice versa. The GnuTLS
|
||||
and yassl support is very recent in libcurl and it has not been tested nor
|
||||
used very extensively, while the OpenSSL equivalent code has been used and
|
||||
thus matured since 1999.
|
||||
|
||||
GnuTLS
|
||||
- LGPL licensened
|
||||
- supports SRP
|
||||
- lacks SSLv2 support
|
||||
- lacks MD2 support (used by at least some CA certs)
|
||||
- lacks the crypto functions libcurl uses for NTLM
|
||||
|
||||
OpenSSL
|
||||
- Original BSD licensened
|
||||
- lacks SRP
|
||||
- supports SSLv2
|
||||
- older and more widely used
|
||||
- provides crypto functions libcurl uses for NTLM
|
||||
- libcurl can do non-blocking connects with it in 7.15.4 and later
|
||||
|
||||
yassl
|
||||
- GPL licensed
|
||||
- much untested and unproven in the real work by (lib)curl users so we don't
|
||||
know a lot about restrictions or benefits from using this
|
||||
|
||||
The Better License, Original BSD, GPL or LGPL?
|
||||
|
||||
It isn't obvious or without debate to any objective interested party that
|
||||
either of these licenses are the "better" or even the "preferred" one in a
|
||||
generic situation.
|
||||
|
||||
Instead, I think we should accept the fact that the SSL/TLS libraries and
|
||||
their different licenses will fit different applications and their authors
|
||||
differently depending on the applications' licenses and their general usage
|
||||
pattern (considering how GPL and LGPL libraries for example can be burdensome
|
||||
for embedded systems usage).
|
||||
|
||||
In Debian land, there seems to be a common opinion that LGPL is "maximally
|
||||
compatible" with apps while Original BSD is not. Like this:
|
||||
|
||||
http://lists.debian.org/debian-devel/2005/09/msg01417.html
|
||||
|
||||
More SSL Libraries
|
||||
|
||||
In libcurl, there's no stopping us here. There are more Open Source/Free
|
||||
SSL/TLS libraries out there and we would very much like to support them as
|
||||
well, to offer application authors an even wider scope of choice.
|
||||
|
||||
Application Angle of this Problem
|
||||
|
||||
libcurl is built to use one SSL/TLS library. It uses a single fixed name (by
|
||||
default) on the built/created lib file, and applications are built/linked to
|
||||
use that single lib. Replacing one libcurl instance with another one that
|
||||
uses the other SSL/TLS library might break one or more applications (due to
|
||||
ABI differences and/or different feature set). You want your application to
|
||||
use the libcurl it was built for.
|
||||
|
||||
Project cURL Angle of this Problem
|
||||
|
||||
We distribute libcurl and everyone may build libcurl with either library at
|
||||
their choice. This problem is not directly a problem of ours. It merely
|
||||
affects users - GPL application authors only - of our lib as it comes
|
||||
included and delivered on some distros.
|
||||
|
||||
libcurl has different ABI when built with different SSL/TLS libraries due to
|
||||
these reasons:
|
||||
|
||||
1. No one has worked on fixing this. The mutex/lock callbacks should be set
|
||||
with a generic libcurl function that should use the proper underlying
|
||||
functions.
|
||||
|
||||
2. The CURLOPT_SSL_CTX_FUNCTION option is not possible to "emulate" on GnuTLS
|
||||
but simply requires OpenSSL.
|
||||
|
||||
3. There might be some other subtle differences just because nobody has yet
|
||||
tried to make a fixed ABI like this.
|
||||
|
||||
Distro Angle of this Problem
|
||||
|
||||
To my knowledge there is only one distro that ships libcurl built with either
|
||||
OpenSSL or GnuTLS.
|
||||
|
||||
Debian Linux is now (since mid September 2005) providing two different
|
||||
libcurl packages, one for libcurl built with OpenSSL and one built with
|
||||
GnuTLS. They use different .so names and can this both be installed in a
|
||||
single system simultaneously. This has been said to be a transitional system
|
||||
not desired to keep in the long run.
|
||||
|
||||
Footnotes
|
||||
|
||||
[1] = http://www.xfree86.org/3.3.6/COPYRIGHT2.html#6
|
||||
[2] = http://www.fsf.org/licensing/essays/bsd.html
|
||||
[3] = http://www.fsf.org/licensing/licenses/gpl.html
|
||||
[4] = http://curl.haxx.se/docs/copyright.html
|
||||
[5] = http://www.openssl.org/source/license.html
|
||||
[6] = http://www.fsf.org/licensing/licenses/gpl.html end of section 3
|
||||
[7] = http://www.fsf.org/licensing/licenses/lgpl.html
|
||||
[8] = http://en.wikipedia.org/wiki/OpenSSL_exception
|
||||
|
||||
Feedback/Updates provided by
|
||||
|
||||
Eric Cooper
|
||||
1388
third-party/curl-7.21.4/docs/FAQ
vendored
Normal file
1388
third-party/curl-7.21.4/docs/FAQ
vendored
Normal file
File diff suppressed because it is too large
Load diff
136
third-party/curl-7.21.4/docs/FEATURES
vendored
Normal file
136
third-party/curl-7.21.4/docs/FEATURES
vendored
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
FEATURES
|
||||
|
||||
curl tool
|
||||
- config file support
|
||||
- multiple URLs in a single command line
|
||||
- range "globbing" support: [0-13], {one,two,three}
|
||||
- multiple file upload on a single command line
|
||||
- custom maximum transfer rate
|
||||
- redirectable stderr
|
||||
|
||||
libcurl supports
|
||||
- full URL syntax with no length limit
|
||||
- custom maximum download time
|
||||
- custom least download speed acceptable
|
||||
- custom output result after completion
|
||||
- guesses protocol from host name unless specified
|
||||
- uses .netrc
|
||||
- progress bar/time specs while downloading
|
||||
- "standard" proxy environment variables support
|
||||
- compiles on win32 (reported builds on 40+ operating systems)
|
||||
- selectable network interface for outgoing traffic
|
||||
- IPv6 support on unix and Windows
|
||||
- persistant connections
|
||||
- socks5 support
|
||||
- supports user name + password in proxy environment variables
|
||||
- operations through proxy "tunnel" (using CONNECT)
|
||||
- supports large files (>2GB and >4GB) both upload/download
|
||||
- replacable memory functions (malloc, free, realloc, etc)
|
||||
- asynchronous name resolving (*6)
|
||||
- both a push and a pull style interface
|
||||
|
||||
HTTP
|
||||
- HTTP/1.1 compliant (optionally uses 1.0)
|
||||
- GET
|
||||
- PUT
|
||||
- HEAD
|
||||
- POST
|
||||
- Pipelining
|
||||
- multipart formpost (RFC1867-style)
|
||||
- authentication: Basic, Digest, NTLM(*9), GSS-Negotiate/Negotiate(*3) and
|
||||
SPNEGO (*4) to server and proxy
|
||||
- resume (both GET and PUT)
|
||||
- follow redirects
|
||||
- maximum amount of redirects to follow
|
||||
- custom HTTP request
|
||||
- cookie get/send fully parsed
|
||||
- reads/writes the netscape cookie file format
|
||||
- custom headers (replace/remove internally generated headers)
|
||||
- custom user-agent string
|
||||
- custom referer string
|
||||
- range
|
||||
- proxy authentication
|
||||
- time conditions
|
||||
- via http-proxy
|
||||
- retrieve file modification date
|
||||
- Content-Encoding support for deflate and gzip
|
||||
- "Transfer-Encoding: chunked" support for "uploads"
|
||||
|
||||
HTTPS (*1)
|
||||
- (all the HTTP features)
|
||||
- using client certificates
|
||||
- verify server certificate
|
||||
- via http-proxy
|
||||
- select desired encryption
|
||||
- force usage of a specific SSL version (SSLv2(*7), SSLv3 or TLSv1)
|
||||
|
||||
FTP
|
||||
- download
|
||||
- authentication
|
||||
- kerberos4 (*5), kerberos5 (*3)
|
||||
- active/passive using PORT, EPRT, PASV or EPSV
|
||||
- single file size information (compare to HTTP HEAD)
|
||||
- 'type=' URL support
|
||||
- dir listing
|
||||
- dir listing names-only
|
||||
- upload
|
||||
- upload append
|
||||
- upload via http-proxy as HTTP PUT
|
||||
- download resume
|
||||
- upload resume
|
||||
- custom ftp commands (before and/or after the transfer)
|
||||
- simple "range" support
|
||||
- via http-proxy
|
||||
- all operations can be tunneled through a http-proxy
|
||||
- customizable to retrieve file modification date
|
||||
- no dir depth limit
|
||||
|
||||
FTPS (*1)
|
||||
- implicit ftps:// support that use SSL on both connections
|
||||
- explicit "AUTH TSL" and "AUTH SSL" usage to "upgrade" plain ftp://
|
||||
connection to use SSL for both or one of the connections
|
||||
|
||||
SCP (*8)
|
||||
- both password and public key auth
|
||||
|
||||
SFTP (*8)
|
||||
- both password and public key auth
|
||||
- with custom commands sent before/after the transfer
|
||||
|
||||
TFTP
|
||||
- download / upload
|
||||
|
||||
TELNET
|
||||
- connection negotiation
|
||||
- custom telnet options
|
||||
- stdin/stdout I/O
|
||||
|
||||
LDAP (*2)
|
||||
- full LDAP URL support
|
||||
|
||||
DICT
|
||||
- extended DICT URL support
|
||||
|
||||
FILE
|
||||
- URL support
|
||||
- "uploads"
|
||||
- resume
|
||||
|
||||
FOOTNOTES
|
||||
=========
|
||||
|
||||
*1 = requires OpenSSL, GnuTLS, NSS, yassl, axTLS or PolarSSL
|
||||
*2 = requires OpenLDAP
|
||||
*3 = requires a GSSAPI-compliant library, such as Heimdal or similar.
|
||||
*4 = requires FBopenssl
|
||||
*5 = requires a krb4 library, such as the MIT one or similar.
|
||||
*6 = requires c-ares
|
||||
*7 = requires OpenSSL or NSS, as GnuTLS only supports SSLv3 and TLSv1
|
||||
*8 = requires libssh2
|
||||
*9 = requires OpenSSL, GnuTLS, NSS or yassl
|
||||
244
third-party/curl-7.21.4/docs/HISTORY
vendored
Normal file
244
third-party/curl-7.21.4/docs/HISTORY
vendored
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
How cURL Became Like This
|
||||
|
||||
|
||||
In the second half of 1997, Daniel Stenberg came up with the idea to make
|
||||
currency-exchange calculations available to Internet Relay Chat (IRC)
|
||||
users. All the necessary data are published on the Web; he just needed to
|
||||
automate their retrieval.
|
||||
|
||||
Daniel simply adopted an existing command-line open-source tool, httpget, that
|
||||
Brazilian Rafael Sagula had written. After a few minor adjustments, it did
|
||||
just what he needed.
|
||||
|
||||
Soon, he found currencies on a GOPHER site, so support for that had to go in,
|
||||
and not before long FTP download support was added as well. The name of the
|
||||
project was changed to urlget to better fit what it actually did now, since
|
||||
the http-only days were already passed.
|
||||
|
||||
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,
|
||||
1998 curl 4 was released. (The version numbering from the previous names was
|
||||
kept.)
|
||||
|
||||
(Unrelated to this project a company called Curl Corporation registered a US
|
||||
trademark on the name "CURL" on May 18 1998. That company had then already
|
||||
registered the curl.com domain back in November of the previous year. All this
|
||||
was revealed to us much later.)
|
||||
|
||||
SSL support was added, powered by the SSLeay library.
|
||||
|
||||
August 1998, first announcement of curl on freshmeat.net.
|
||||
|
||||
October 1998, with the curl 4.9 release and the introduction of cookie
|
||||
support, curl was no longer released under the GPL license. Now we're at 4000
|
||||
lines of code, we switched over to the MPL license to restrict the effects of
|
||||
"copyleft".
|
||||
|
||||
November 1998, configure script and reported successful compiles on several
|
||||
major operating systems. The never-quite-understood -F option was added and
|
||||
curl could now simulate quite a lot of a browser. TELNET support was added.
|
||||
|
||||
Curl 5 was released in December 1998 and introduced the first ever curl man
|
||||
page. People started making Linux RPM packages out of it.
|
||||
|
||||
January 1999, DICT support added.
|
||||
|
||||
OpenSSL took over where SSLeay was abandoned.
|
||||
|
||||
May 1999, first Debian package.
|
||||
|
||||
August 1999, LDAP:// and FILE:// support added. The curl web site gets 1300
|
||||
visits weekly.
|
||||
|
||||
Released curl 6.0 in September. 15000 lines of code.
|
||||
|
||||
December 28 1999, added the project on Sourceforge and started using its
|
||||
services for managing the project.
|
||||
|
||||
Spring 2000, major internal overhaul to provide a suitable library interface.
|
||||
The first non-beta release was named 7.1 and arrived in August. This offered
|
||||
the easy interface and turned out to be the beginning of actually getting
|
||||
other software and programs to get based on and powered by libcurl. Almost
|
||||
20000 lines of code.
|
||||
|
||||
August 2000, the curl web site gets 4000 visits weekly.
|
||||
|
||||
The PHP guys adopted libcurl already the same month, when the first ever third
|
||||
party libcurl binding showed up. CURL has been a supported module in PHP since
|
||||
the release of PHP 4.0.2. This would soon get followers. More than 16
|
||||
different bindings exist at the time of this writing.
|
||||
|
||||
September 2000, kerberos4 support was added.
|
||||
|
||||
In November 2000 started the work on a test suite for curl. It was later
|
||||
re-written from scratch again. The libcurl major SONAME number was set to 1.
|
||||
|
||||
January 2001, Daniel released curl 7.5.2 under a new license again: MIT (or
|
||||
MPL). The MIT license is extremely liberal and can be used combined with GPL
|
||||
in other projects. This would finally put an end to the "complaints" from
|
||||
people involved in GPLed projects that previously were prohibited from using
|
||||
libcurl while it was released under MPL only. (Due to the fact that MPL is
|
||||
deemed "GPL incompatible".)
|
||||
|
||||
curl supports HTTP 1.1 starting with the release of 7.7, March 22 2001. This
|
||||
also introduced libcurl's ability to do persistent connections. 24000 lines of
|
||||
code. The libcurl major SONAME number was bumped to 2 due to this overhaul.
|
||||
|
||||
The first experimental ftps:// support was added in March 2001.
|
||||
|
||||
August 2001. curl is bundled in Mac OS X, 10.1. It was already becoming more
|
||||
and more of a standard utility of Linux distributions and a regular in the BSD
|
||||
ports collections. The curl web site gets 8000 visits weekly. Curl Corporation
|
||||
contacted Daniel to discuss "the name issue". After Daniel's reply, they have
|
||||
never since got in touch again.
|
||||
|
||||
September 2001, libcurl 7.9 introduces cookie jar and curl_formadd(). During
|
||||
the forthcoming 7.9.x releases, we introduced the multi interface slowly and
|
||||
without much whistles.
|
||||
|
||||
June 2002, the curl web site gets 13000 visits weekly. curl and libcurl is
|
||||
35000 lines of code. Reported successful compiles on more than 40 combinations
|
||||
of CPUs and operating systems.
|
||||
|
||||
To estimate number of users of the curl tool or libcurl library is next to
|
||||
impossible. Around 5000 downloaded packages each week from the main site gives
|
||||
a hint, but the packages are mirrored extensively, bundled with numerous OS
|
||||
distributions and otherwise retrieved as part of other software.
|
||||
|
||||
September 2002, with the release of curl 7.10 it is released under the MIT
|
||||
license only.
|
||||
|
||||
January 2003. Started working on the distributed curl tests. The autobuilds.
|
||||
|
||||
February 2003, the curl site averages at 20000 visits weekly. At any given
|
||||
moment, there's an average of 3 people browsing the curl.haxx.se site.
|
||||
|
||||
Multiple new authentication schemes are supported: Digest (May), NTLM (June)
|
||||
and Negotiate (June).
|
||||
|
||||
November 2003: curl 7.10.8 is released. 45000 lines of code. ~55000 unique
|
||||
visitors to the curl.haxx.se site. Five official web mirrors.
|
||||
|
||||
December 2003, full-fledged SSL for FTP is supported.
|
||||
|
||||
January 2004: curl 7.11.0 introduced large file support.
|
||||
|
||||
June 2004:
|
||||
|
||||
curl 7.12.0 introduced IDN support. 10 official web mirrors.
|
||||
|
||||
This release bumped the major SONAME to 3 due to the removal of the
|
||||
curl_formparse() function
|
||||
|
||||
August 2004:
|
||||
Curl and libcurl 7.12.1
|
||||
|
||||
Public curl release number: 82
|
||||
Releases counted from the very beginning: 109
|
||||
Available command line options: 96
|
||||
Available curl_easy_setopt() options: 120
|
||||
Number of public functions in libcurl: 36
|
||||
Amount of public web site mirrors: 12
|
||||
Number of known libcurl bindings: 26
|
||||
|
||||
April 2005:
|
||||
|
||||
GnuTLS can now optionally be used for the secure layer when curl is built.
|
||||
|
||||
September 2005:
|
||||
|
||||
TFTP support was added.
|
||||
|
||||
More than 100,000 unique visitors of the curl web site. 25 mirrors.
|
||||
|
||||
December 2005:
|
||||
|
||||
security vulnerability: libcurl URL Buffer Overflow
|
||||
|
||||
January 2006:
|
||||
|
||||
We dropped support for Gopher. We found bugs in the implementation that
|
||||
turned out having been introduced years ago, so with the conclusion that
|
||||
nobody had found out in all this time we removed it instead of fixing it.
|
||||
|
||||
March 2006:
|
||||
|
||||
security vulnerability: libcurl TFTP Packet Buffer Overflow
|
||||
|
||||
April 2006:
|
||||
|
||||
Added the multi_socket() API
|
||||
|
||||
September 2006:
|
||||
|
||||
The major SONAME number for libcurl was bumped to 4 due to the removal of
|
||||
ftp third party transfer support.
|
||||
|
||||
November 2006:
|
||||
|
||||
Added SCP and SFTP support
|
||||
|
||||
February 2007:
|
||||
|
||||
Added support for the Mozilla NSS library to do the SSL/TLS stuff
|
||||
|
||||
July 2007:
|
||||
|
||||
security vulnerability: libcurl GnuTLS insufficient cert verification
|
||||
|
||||
November 2008:
|
||||
|
||||
Command line options: 128
|
||||
curl_easy_setopt() options: 158
|
||||
Public functions in libcurl: 58
|
||||
Known libcurl bindings: 37
|
||||
Contributors: 683
|
||||
|
||||
145,000 unique visitors. >100 GB downloaded.
|
||||
|
||||
March 2009:
|
||||
|
||||
security vulnerability: libcurl Arbitrary File Access
|
||||
|
||||
August 2009:
|
||||
|
||||
security vulnerability: libcurl embedded zero in cert name
|
||||
|
||||
December 2009:
|
||||
|
||||
Added support for IMAP, POP3 and SMTP
|
||||
|
||||
January 2010:
|
||||
|
||||
Added support for RTSP
|
||||
|
||||
February 2010:
|
||||
|
||||
security vulnerability: libcurl data callback excessive length
|
||||
|
||||
March 2010:
|
||||
|
||||
The project switched over to use git instead of CVS for source code control
|
||||
|
||||
May 2010:
|
||||
|
||||
Added support for RTMP
|
||||
|
||||
Added support for PolarSSL to do the SSL/TLS stuff
|
||||
|
||||
August 2010:
|
||||
|
||||
Public curl releases: 117
|
||||
Command line options: 138
|
||||
curl_easy_setopt() options: 180
|
||||
Public functions in libcurl: 58
|
||||
Known libcurl bindings: 39
|
||||
Contributors: 808
|
||||
|
||||
Gopher support added (re-added actually)
|
||||
65
third-party/curl-7.21.4/docs/INSTALL.cmake
vendored
Executable file
65
third-party/curl-7.21.4/docs/INSTALL.cmake
vendored
Executable file
|
|
@ -0,0 +1,65 @@
|
|||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
How To Compile with CMake
|
||||
|
||||
Building with CMake
|
||||
==========================
|
||||
This document describes how to compile, build and install curl and libcurl
|
||||
from source code using the CMake build tool. To build with CMake, you will
|
||||
of course have to first install CMake. The minimum required version of
|
||||
CMake is specifed in the file CMakeLists.txt found in the top of the curl
|
||||
source tree. Once the correct version of CMake is installed you can follow
|
||||
the instructions below for the platform you are building on.
|
||||
|
||||
CMake builds can be configured either from the command line, or from one
|
||||
of CMake's GUI's.
|
||||
|
||||
Command Line CMake
|
||||
==================
|
||||
A command line build of Curl is similar to the autotools build of Curl. It
|
||||
consists of the following steps after you have unpacked the source.
|
||||
# 1st create an out of source build tree parallel to the curl source
|
||||
# tree and change into that directory
|
||||
mkdir curl-build
|
||||
cd curl-build
|
||||
# now run CMake from the build tree, giving it the path to the top of
|
||||
# the Curl source tree. CMake will pick a compiler for you. If you
|
||||
# want to specifiy the compile, you can set the CC environment
|
||||
# variable prior to running CMake.
|
||||
cmake ../curl
|
||||
make
|
||||
# currently make test and make install are not implemented
|
||||
#make test
|
||||
#make install
|
||||
|
||||
ccmake
|
||||
=========
|
||||
CMake comes with a curses based interface called ccmake. To run ccmake on
|
||||
a curl use the instructions for the command line cmake, but substitue
|
||||
ccmake ../curl for cmake ../curl. This will bring up a curses interface
|
||||
with instructions on the bottom of the screen. You can press the "c" key
|
||||
to configure the project, and the "g" key to generate the project. After
|
||||
the project is generated, you can run make.
|
||||
|
||||
cmake-gui
|
||||
=========
|
||||
CMake also comes with a Qt based GUI called cmake-gui. To configure with
|
||||
cmake-gui, you run cmake-gui and follow these steps:
|
||||
1. Fill in the "Where is the source code" combo box with the path to
|
||||
the curl source tree.
|
||||
2. Fill in the "Where to build the binaries" combo box with the path
|
||||
to the directory for your build tree, ideally this should not be the
|
||||
same as the source tree, but a parallel diretory called curl-build or
|
||||
something similar.
|
||||
3. Once the source and binary directories are specified, press the
|
||||
"Configure" button.
|
||||
4. Select the native build tool that you want to use.
|
||||
5. At this point you can change any of the options presented in the
|
||||
GUI. Once you have selected all the options you want, click the
|
||||
"Generate" button.
|
||||
6. Run the native build tool that you used CMake to genratate.
|
||||
|
||||
302
third-party/curl-7.21.4/docs/INSTALL.devcpp
vendored
Normal file
302
third-party/curl-7.21.4/docs/INSTALL.devcpp
vendored
Normal file
|
|
@ -0,0 +1,302 @@
|
|||
DevCpp-Mingw Install & Compilation Sept 2005
|
||||
==================================
|
||||
|
||||
Reference Emails available at curl@haxx.se:
|
||||
|
||||
Libcurl Install and Use Issues
|
||||
Awaiting an Answer for Win 32 Install
|
||||
res = curl_easy_perform(curl); Error
|
||||
Makefile Issues
|
||||
|
||||
|
||||
Having previously done a thorough review of what was available that met my
|
||||
requirements under GPL, I settled for Libcurl as the software of choice for
|
||||
many reasons not the least of which was the support.
|
||||
|
||||
Background
|
||||
----------
|
||||
|
||||
This quest started when I innocently tried to incorporate the libcurl library
|
||||
into my simple source code. I figured that a few easy steps would accomplish
|
||||
this without major headaches. I had no idea that I would be facing an almost
|
||||
insurmountable challenge.
|
||||
|
||||
The main problem lies in two areas. First the bulk of support for libcurl
|
||||
exists for a Unix/linux command line environments. This is of little help when
|
||||
it comes to Windows O/S.
|
||||
|
||||
Secondly the help that does exist for the Windows O/S focused around mingw
|
||||
thru a command line argument environment.
|
||||
|
||||
You may ask "Why is this a problem?"
|
||||
|
||||
I'm using a Windows O/S with DevCpp. For those of you who are unfamiliar with
|
||||
DevCpp, it is a window shell GUI that replaces the command line environment
|
||||
for gcc. A definite improvement that I am unwilling to give up. However using
|
||||
DevCpp presented its own set of issues. Inadvertently I also made some
|
||||
careless errors such as compiling the 7.14 version of Makefile with an older
|
||||
version of source code. Thanks to Dan Fandrich for picking this up.
|
||||
|
||||
I did eventually with the help of Daniel, Phillipe and others manage to
|
||||
implement successfully (the only mingw available version)
|
||||
curl-7.13.0-win32-ssl-devel-mingw32 into the DevCpp environment. Only the
|
||||
dynamic libcurl.dll libcurldll.a libraries worked. The static library which I
|
||||
was interested in did not. Furthermore when I tried to implement one of the
|
||||
examples included with the curl package (get info.c) it caused the executable
|
||||
to crash. Tracing the bug I found it in the code and function res =
|
||||
curl_easy_perform(curl);.
|
||||
|
||||
At this point I had to make a choice as to whether invest my limited
|
||||
time-energy resource to fixing the bug or to compile the new version
|
||||
available. After searching the archives I found a very similar or the same bug
|
||||
reported from version 7.12x on. Daniel did inform me that he thought that this
|
||||
bug had been fixed with the latest version. So I proceeded to compile the
|
||||
latest SSL version where I faced other challenges.
|
||||
|
||||
In order to make this process unremarkable for others using the same
|
||||
environment I decided to document the process so that others will find it
|
||||
routine. It would be a shame if newbies could not implement this excellent
|
||||
package for their use.
|
||||
|
||||
I would like to thank the many others in this forum and in the DevCpp forum
|
||||
for their help. Without your help I may either have given up or it would have
|
||||
taken me many times longer to achieve success.
|
||||
|
||||
The Cookbook Approach
|
||||
---------------------
|
||||
|
||||
This discussion will be confined to a SSL static library compilation and
|
||||
installation. Limited mention and comments will be inserted where appropriate
|
||||
to help with non-SSL, dynamic libraries and executables.
|
||||
|
||||
|
||||
Using Makefile from DevCpp to compile Libcurl libraries
|
||||
|
||||
Preamble
|
||||
--------
|
||||
|
||||
Using the latest version release - curl-7.14.0.tar.gz. Curl source code is
|
||||
platform independent. This simply means that the source code can be compiled
|
||||
for any Operating System (Linux/Unix Windows etc. and variations of thereof).
|
||||
|
||||
The first thing to note is that inside curl-7.14.0 you will find two folders
|
||||
lib and src. Both contain Makefile.m32 (required for win mingw library or exe
|
||||
compilation) files which are different. The main difference between these two
|
||||
folders and the makefiles is that the src folder contents are used to compile
|
||||
an executable file(curl.exe) while the lib folder contents are used to compile
|
||||
a static (libcurl.a) and dynamic (libcurl.dll & libcurldll.a) file that can be
|
||||
used to compile libcurl with your own source code so that one can use and
|
||||
access all libcurl functions.
|
||||
|
||||
Before we start please make sure that DevCpp is installed properly. In
|
||||
particular make sure you have no spaces in the name of any of the directories
|
||||
and subdirectories where DevCpp is installed. Failure to comply with the
|
||||
install instructions may produce erratic behaviour in DevCpp. For further info
|
||||
check the following sites
|
||||
|
||||
http://aditsu.freeunixhost.com/dev-cpp-faq.html
|
||||
http://sourceforge.net/forum/message.php?msg_id=3252213
|
||||
|
||||
As I have mentioned before I will confine this to the SSL Library compilations
|
||||
but the process is very similar for compilation of the executable - curl.exe;
|
||||
just substitute the src folder makefile in its stead.
|
||||
|
||||
First use a text processor Notepad, or your own favourite text processor. To
|
||||
engage your favourite text processor, select Makefile.m32 click once with your
|
||||
mouse on file icon; icon turns blue, press the shift key and right-click on
|
||||
mouse, menu appears select "Open with", select your favourite text processor.
|
||||
|
||||
Next read the contents of Makefile.m32. It includes instructions on its use.
|
||||
|
||||
Method I - DOS Command Line
|
||||
---------------------------
|
||||
|
||||
Note - The only reason I have included this method is that Method II which is
|
||||
the preferred method for compiling does not allow for the setting of option
|
||||
switches (e.g. SSL = 1 or SSL =0). At least that's what they tell me at the
|
||||
Dev-Cpp forum.
|
||||
|
||||
1 - Make a copy of (D:\Dev-Cpp\bin) bin folder and name it "bin Original"
|
||||
place it in the Dev-Cpp installed directory (D:\Dev-Cpp\ for this example)
|
||||
|
||||
2 - Copy the entire contents of the LIB folder of curl-7.14.0.tar.gz or zip
|
||||
version into the bin folder above (D:\Dev-Cpp\bin). The reason being is that
|
||||
the make.exe file resides in this folder. Make.exe will use - Makefile.m32,
|
||||
Makefile.inc, and the source code included in the lib folder to compile the
|
||||
source code. There is a PATH issue with make.exe that remains unresolved at
|
||||
least for me. Unless the entire source code to be compiled is placed entirely
|
||||
within the directory of make.exe an error message will be generated - "file
|
||||
xxxx.yyy not available".
|
||||
|
||||
3- Go to Dev-Cpp\bin and double click on make .exe. You will see a DOS window
|
||||
quickly pop up and close very quickly. Not to worry! Please do not skip this
|
||||
step.
|
||||
|
||||
4- Click on the start button\Programs\MS-DOS Prompt.Once the DOS Window is up
|
||||
Type the disk drive letter (e.g. E: ) engage the enter button. The path should
|
||||
automatically take you to the directory of the make.exe file.
|
||||
|
||||
5- To compile the source code simply type at the DOS prompt make -f
|
||||
Makefile.m32 as per instructions contained in the Makefile.m32 file (use any
|
||||
text processor to read instructions). I don't believe that this makefile
|
||||
allows for the option of non SSL. Ignore any warnings.
|
||||
|
||||
6- Collect and make copies of libcurl.a, libcurl.dll, libcurldll.a and any *.o
|
||||
compilations you might need in another directory outside of the bin directory
|
||||
as you will need this files shortly to set up libcurl for use with
|
||||
Dev-cpp. For most apps *.o is not required. Later on we will show what to do
|
||||
with these files.
|
||||
|
||||
7- You are finished but before closing we need to do cleanup - erase the bin
|
||||
folder and rename the "bin Original" folder created in step 1 to bin.
|
||||
|
||||
Note to compile a curl executable the process is probably similar but instead
|
||||
of using the LIB folder contents use the SRC folder contents and Makefiles in
|
||||
curl-7.14.0.tar.gz. File directories relative placements must be respected for
|
||||
compiling to take place successfully. This may not be possible with the PATH
|
||||
problem that make.exe experiences. If anyone has solved this PATH issue and
|
||||
please make sure it actually works on Win 9x/2000/XP before letting me
|
||||
know. Then please let me or Daniel in on the solution so that it can be
|
||||
included with these instructions. Thanks.
|
||||
|
||||
or
|
||||
|
||||
Method II - Dev-Cpp GUI
|
||||
-----------------------
|
||||
|
||||
1- Copy the entire contents of the LIB folder of curl-7.14.0.tar.gz or zip
|
||||
version into any folder outside of (Dev-Cpp\bin).
|
||||
|
||||
2- Drop the File/New/click on Project.
|
||||
|
||||
3- New Project Dialogue box appears. Double click on the Static Library.
|
||||
|
||||
4- Create Project Dialogue box appears. Select the LIB folder location to
|
||||
place and locate your Project File Name. Placing the Project File Name
|
||||
elsewhere may cause problems (PATH issue problem again).
|
||||
|
||||
5- Drop down the Project/Project Options. Project Options Dialogue box
|
||||
appears.
|
||||
|
||||
6- Select the Makefile tab in the Project Options Dialogue Box. Check Box -
|
||||
Use Custom Makefile. Click on the Folder icon at the extreme right of the
|
||||
Check Box. Select Makefile.m32 in the folder wherever you have placed the
|
||||
contents of the LIB Folder. Press OK and close the Dialogue Box.
|
||||
|
||||
7- Drop the Menu Project/Click on Add to Project. Open File Dialogue Box
|
||||
appears. The Dialogue Box should open in the folder wherever you have placed
|
||||
the contents of the LIB Folder. If not go there.
|
||||
|
||||
8- Select Crtl-A to select all files in the LIB folder. Click on open to add
|
||||
files and close box. Wait till all files are added. This may take 30 seconds
|
||||
or longer.
|
||||
|
||||
9- Drop the Menu Execute/Click on Compile.
|
||||
|
||||
10- That's it.
|
||||
|
||||
|
||||
The following steps must be completed if Curl is to work properly
|
||||
=================================================================
|
||||
|
||||
LIB folder inclusions (*.a placement)
|
||||
-------------------------------------
|
||||
|
||||
1- Refer to Method I - DOS Command Line point # 6 Take libcurl.a, libcurldll.a
|
||||
and install it in the directory C( or whichever drive Dev is installed)
|
||||
:\Dev-Cpp\lib.
|
||||
|
||||
|
||||
Include Folder
|
||||
--------------
|
||||
|
||||
1- Create a new folder by the name of curl (do not change the name curl to
|
||||
some other name as it will cause major issues) in the directory
|
||||
C:\Dev-Cpp\include.
|
||||
|
||||
2- Copy the entire contents of the curl folder of curl-7.14.0.tar.gz or zip
|
||||
version into the newly created curl directory - C:\Dev-Cpp\include\curl.
|
||||
|
||||
Links To Include And Lib Folder
|
||||
-------------------------------
|
||||
|
||||
1- Drop the Menu - Tools\Compiler Options\Directories\Libraries. Make sure
|
||||
that C( or whichever drive Dev is installed):\DEV-CPP\lib is included.
|
||||
|
||||
2- Next select the Menu - Tools\Compiler Options\Directories\C Includes. Make
|
||||
sure that C:\DEV-CPP\include and C:\Dev-Cpp\include\curl are included.
|
||||
|
||||
3- Next select the Menu - Tools\Compiler Options\Directories\C++
|
||||
Includes. Make sure that C:\DEV-CPP\include and C:\Dev-Cpp\include\curl are
|
||||
included.
|
||||
|
||||
Linker Links
|
||||
------------
|
||||
|
||||
1- Drop the Menu - Tools\Compiler Options\Directories\Compiler.
|
||||
|
||||
2- Make sure that the box "Add these commands to the linker command line" is
|
||||
checked.
|
||||
|
||||
3- Include in the white space immediately below the box referred in 2 -lcurl
|
||||
-lws2_32.
|
||||
|
||||
SSL Files
|
||||
---------
|
||||
|
||||
1- Get the latest openSSL (as of time of this writing)
|
||||
openssl-0.9.7e-win32-bin.zip for the minimalist package of the openssl-0.9.7e
|
||||
binaries ported to MS Windows 95/98/NT/XP using the MingW32/GCC-3.1
|
||||
development environment. The file may be downloaded at
|
||||
http://curl.haxx.se/download/.
|
||||
|
||||
2- Open the above zip file. You will find two files - SDL.dll,
|
||||
SDL_mixer.dll. Install them in the directory C:\WINDOWS\SYSTEM32 for Win 9x
|
||||
users and c:\winnt\system32 for NT-family users.
|
||||
|
||||
Multithreading Files
|
||||
--------------------
|
||||
|
||||
To be completed
|
||||
|
||||
#define
|
||||
-------
|
||||
|
||||
1- Make sure that your program includes the following - #define CURL_STATICLIB
|
||||
must be declared FIRST before any other define functions may be
|
||||
added. Otherwise you may experience link errors.
|
||||
|
||||
2- Don't forget to include #include "curl/curl.h".
|
||||
|
||||
e.g.
|
||||
#define CURL_STATICLIB
|
||||
#include <windows.h>
|
||||
#include "curl/curl.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
etc...
|
||||
|
||||
|
||||
Static or Dynamic Library
|
||||
-------------------------
|
||||
|
||||
The above steps apply for the use by a static library. Should you choose to
|
||||
use a dynamic library you will be required to perform these additional steps.
|
||||
|
||||
1- Refer to Method I - DOS Command Line point # 6. Install libcurl.dll in the
|
||||
directory C:\WINDOWS\SYSTEM32 for Win 9x users and c:\winnt\system32 for
|
||||
NT-family users.
|
||||
|
||||
2- Refer to Linker Links point 3 - Replace -lcurl with -lcurldll.
|
||||
|
||||
Voila you're done.
|
||||
|
||||
The non-SSL static Library build may not be possible to use at least as of the
|
||||
time of this writing - v7.14. Check reference emails - Phillipe and I found it
|
||||
impossible to fully compile as certain files were missing for linking. No big
|
||||
loss as SSL is a major plus.
|
||||
|
||||
Hope this Helps
|
||||
|
||||
Tom
|
||||
493
third-party/curl-7.21.4/docs/INTERNALS
vendored
Normal file
493
third-party/curl-7.21.4/docs/INTERNALS
vendored
Normal file
|
|
@ -0,0 +1,493 @@
|
|||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
INTERNALS
|
||||
|
||||
The project is split in two. The library and the client. The client part uses
|
||||
the library, but the library is designed to allow other applications to use
|
||||
it.
|
||||
|
||||
The largest amount of code and complexity is in the library part.
|
||||
|
||||
GIT
|
||||
===
|
||||
All changes to the sources are committed to the git repository as soon as
|
||||
they're somewhat verified to work. Changes shall be committed as independently
|
||||
as possible so that individual changes can be easier spotted and tracked
|
||||
afterwards.
|
||||
|
||||
Tagging shall be used extensively, and by the time we release new archives we
|
||||
should tag the sources with a name similar to the released version number.
|
||||
|
||||
Portability
|
||||
===========
|
||||
|
||||
We write curl and libcurl to compile with C89 compilers. On 32bit and up
|
||||
machines. Most of libcurl assumes more or less POSIX compliance but that's
|
||||
not a requirement.
|
||||
|
||||
We write libcurl to build and work with lots of third party tools, and we
|
||||
want it to remain functional and buildable with these and later versions
|
||||
(older versions may still work but is not what we work hard to maintain):
|
||||
|
||||
OpenSSL 0.9.6
|
||||
GnuTLS 1.2
|
||||
zlib 1.1.4
|
||||
libssh2 0.16
|
||||
c-ares 1.6.0
|
||||
libidn 0.4.1
|
||||
*yassl 1.4.0 (http://curl.haxx.se/mail/lib-2008-02/0093.html)
|
||||
openldap 2.0
|
||||
MIT krb5 lib 1.2.4
|
||||
qsossl V5R2M0
|
||||
NSS 3.11.x
|
||||
axTLS 1.2.7
|
||||
Heimdal ?
|
||||
|
||||
* = only partly functional, but that's due to bugs in the third party lib, not
|
||||
because of libcurl code
|
||||
|
||||
On systems where configure runs, we aim at working on them all - if they have
|
||||
a suitable C compiler. On systems that don't run configure, we strive to keep
|
||||
curl running fine on:
|
||||
|
||||
Windows 98
|
||||
AS/400 V5R2M0
|
||||
Symbian 9.1
|
||||
Windows CE ?
|
||||
TPF ?
|
||||
|
||||
When writing code (mostly for generating stuff included in release tarballs)
|
||||
we use a few "build tools" and we make sure that we remain functional with
|
||||
these versions:
|
||||
|
||||
GNU Libtool 1.4.2
|
||||
GNU Autoconf 2.57
|
||||
GNU Automake 1.7 (we currently avoid 1.10 due to Solaris-related bugs)
|
||||
GNU M4 1.4
|
||||
perl 4
|
||||
roffit 0.5
|
||||
groff ? (any version that supports "groff -Tps -man [in] [out]")
|
||||
ps2pdf (gs) ?
|
||||
|
||||
Windows vs Unix
|
||||
===============
|
||||
|
||||
There are a few differences in how to program curl the unix way compared to
|
||||
the Windows way. The four perhaps most notable details are:
|
||||
|
||||
1. Different function names for socket operations.
|
||||
|
||||
In curl, this is solved with defines and macros, so that the source looks
|
||||
the same at all places except for the header file that defines them. The
|
||||
macros in use are sclose(), sread() and swrite().
|
||||
|
||||
2. Windows requires a couple of init calls for the socket stuff.
|
||||
|
||||
That's taken care of by the curl_global_init() call, but if other libs also
|
||||
do it etc there might be reasons for applications to alter that behaviour.
|
||||
|
||||
3. The file descriptors for network communication and file operations are
|
||||
not easily interchangeable as in unix.
|
||||
|
||||
We avoid this by not trying any funny tricks on file descriptors.
|
||||
|
||||
4. When writing data to stdout, Windows makes end-of-lines the DOS way, thus
|
||||
destroying binary data, although you do want that conversion if it is
|
||||
text coming through... (sigh)
|
||||
|
||||
We set stdout to binary under windows
|
||||
|
||||
Inside the source code, We make an effort to avoid '#ifdef [Your OS]'. All
|
||||
conditionals that deal with features *should* instead be in the format
|
||||
'#ifdef HAVE_THAT_WEIRD_FUNCTION'. Since Windows can't run configure scripts,
|
||||
we maintain two curl_config-win32.h files (one in lib/ and one in src/) that
|
||||
are supposed to look exactly as a curl_config.h file would have looked like on
|
||||
a Windows machine!
|
||||
|
||||
Generally speaking: always remember that this will be compiled on dozens of
|
||||
operating systems. Don't walk on the edge.
|
||||
|
||||
Library
|
||||
=======
|
||||
|
||||
There are plenty of entry points to the library, namely each publicly defined
|
||||
function that libcurl offers to applications. All of those functions are
|
||||
rather small and easy-to-follow. All the ones prefixed with 'curl_easy' are
|
||||
put in the lib/easy.c file.
|
||||
|
||||
curl_global_init_() and curl_global_cleanup() should be called by the
|
||||
application to initialize and clean up global stuff in the library. As of
|
||||
today, it can handle the global SSL initing if SSL is enabled and it can init
|
||||
the socket layer on windows machines. libcurl itself has no "global" scope.
|
||||
|
||||
All printf()-style functions use the supplied clones in lib/mprintf.c. This
|
||||
makes sure we stay absolutely platform independent.
|
||||
|
||||
curl_easy_init() allocates an internal struct and makes some initializations.
|
||||
The returned handle does not reveal internals. This is the 'SessionHandle'
|
||||
struct which works as an "anchor" struct for all curl_easy functions. All
|
||||
connections performed will get connect-specific data allocated that should be
|
||||
used for things related to particular connections/requests.
|
||||
|
||||
curl_easy_setopt() takes three arguments, where the option stuff must be
|
||||
passed in pairs: the parameter-ID and the parameter-value. The list of
|
||||
options is documented in the man page. This function mainly sets things in
|
||||
the 'SessionHandle' struct.
|
||||
|
||||
curl_easy_perform() does a whole lot of things:
|
||||
|
||||
It starts off in the lib/easy.c file by calling Curl_perform() and the main
|
||||
work then continues in lib/url.c. The flow continues with a call to
|
||||
Curl_connect() to connect to the remote site.
|
||||
|
||||
o Curl_connect()
|
||||
|
||||
... analyzes the URL, it separates the different components and connects to
|
||||
the remote host. This may involve using a proxy and/or using SSL. The
|
||||
Curl_resolv() function in lib/hostip.c is used for looking up host names
|
||||
(it does then use the proper underlying method, which may vary between
|
||||
platforms and builds).
|
||||
|
||||
When Curl_connect is done, we are connected to the remote site. Then it is
|
||||
time to tell the server to get a document/file. Curl_do() arranges this.
|
||||
|
||||
This function makes sure there's an allocated and initiated 'connectdata'
|
||||
struct that is used for this particular connection only (although there may
|
||||
be several requests performed on the same connect). A bunch of things are
|
||||
inited/inherited from the SessionHandle struct.
|
||||
|
||||
o Curl_do()
|
||||
|
||||
Curl_do() makes sure the proper protocol-specific function is called. The
|
||||
functions are named after the protocols they handle. Curl_ftp(),
|
||||
Curl_http(), Curl_dict(), etc. They all reside in their respective files
|
||||
(ftp.c, http.c and dict.c). HTTPS is handled by Curl_http() and FTPS by
|
||||
Curl_ftp().
|
||||
|
||||
The protocol-specific functions of course deal with protocol-specific
|
||||
negotiations and setup. They have access to the Curl_sendf() (from
|
||||
lib/sendf.c) function to send printf-style formatted data to the remote
|
||||
host and when they're ready to make the actual file transfer they call the
|
||||
Curl_Transfer() function (in lib/transfer.c) to setup the transfer and
|
||||
returns.
|
||||
|
||||
If this DO function fails and the connection is being re-used, libcurl will
|
||||
then close this connection, setup a new connection and re-issue the DO
|
||||
request on that. This is because there is no way to be perfectly sure that
|
||||
we have discovered a dead connection before the DO function and thus we
|
||||
might wrongly be re-using a connection that was closed by the remote peer.
|
||||
|
||||
Some time during the DO function, the Curl_setup_transfer() function must
|
||||
be called with some basic info about the upcoming transfer: what socket(s)
|
||||
to read/write and the expected file transfer sizes (if known).
|
||||
|
||||
o Transfer()
|
||||
|
||||
Curl_perform() then calls Transfer() in lib/transfer.c that performs the
|
||||
entire file transfer.
|
||||
|
||||
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
|
||||
called). The speedcheck functions in lib/speedcheck.c are also used to
|
||||
verify that the transfer is as fast as required.
|
||||
|
||||
o Curl_done()
|
||||
|
||||
Called after a transfer is done. This function takes care of everything
|
||||
that has to be done after a transfer. This function attempts to leave
|
||||
matters in a state so that Curl_do() should be possible to call again on
|
||||
the same connection (in a persistent connection case). It might also soon
|
||||
be closed with Curl_disconnect().
|
||||
|
||||
o Curl_disconnect()
|
||||
|
||||
When doing normal connections and transfers, no one ever tries to close any
|
||||
connections so this is not normally called when curl_easy_perform() is
|
||||
used. This function is only used when we are certain that no more transfers
|
||||
is going to be made on the connection. It can be also closed by force, or
|
||||
it can be called to make sure that libcurl doesn't keep too many
|
||||
connections alive at the same time (there's a default amount of 5 but that
|
||||
can be changed with the CURLOPT_MAXCONNECTS option).
|
||||
|
||||
This function cleans up all resources that are associated with a single
|
||||
connection.
|
||||
|
||||
Curl_perform() is the function that does the main "connect - do - transfer -
|
||||
done" loop. It loops if there's a Location: to follow.
|
||||
|
||||
When completed, the curl_easy_cleanup() should be called to free up used
|
||||
resources. It runs Curl_disconnect() on all open connectons.
|
||||
|
||||
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 offers a lot and is the protocol in curl that uses the most lines of
|
||||
code. There is a special file (lib/formdata.c) that offers all the multipart
|
||||
post functions.
|
||||
|
||||
base64-functions for user+password stuff (and more) is in (lib/base64.c) and
|
||||
all functions for parsing and sending cookies are found in (lib/cookie.c).
|
||||
|
||||
HTTPS uses in almost every means the same procedure as HTTP, with only two
|
||||
exceptions: the connect procedure is different and the function used to read
|
||||
or write from the socket is different, although the latter fact is hidden in
|
||||
the source by the use of Curl_read() for reading and Curl_write() for writing
|
||||
data to the remote server.
|
||||
|
||||
http_chunks.c contains functions that understands HTTP 1.1 chunked transfer
|
||||
encoding.
|
||||
|
||||
An interesting detail with the HTTP(S) request, is the Curl_add_buffer() series of
|
||||
functions we use. They append data to one single buffer, and when the
|
||||
building is done the entire request is sent off in one single write. This is
|
||||
done this way to overcome problems with flawed firewalls and lame servers.
|
||||
|
||||
FTP
|
||||
|
||||
The Curl_if2ip() function can be used for getting the IP number of a
|
||||
specified network interface, and it resides in lib/if2ip.c.
|
||||
|
||||
Curl_ftpsendf() is used for sending FTP commands to the remote server. It was
|
||||
made a separate function to prevent us programmers from forgetting that they
|
||||
must be CRLF terminated. They must also be sent in one single write() to make
|
||||
firewalls and similar happy.
|
||||
|
||||
Kerberos
|
||||
|
||||
The kerberos support is mainly in lib/krb4.c and lib/security.c.
|
||||
|
||||
TELNET
|
||||
|
||||
Telnet is implemented in lib/telnet.c.
|
||||
|
||||
FILE
|
||||
|
||||
The file:// protocol is dealt with in lib/file.c.
|
||||
|
||||
LDAP
|
||||
|
||||
Everything LDAP is in lib/ldap.c.
|
||||
|
||||
GENERAL
|
||||
|
||||
URL encoding and decoding, called escaping and unescaping in the source code,
|
||||
is found in lib/escape.c.
|
||||
|
||||
While transferring data in Transfer() a few functions might get used.
|
||||
curl_getdate() in lib/parsedate.c is for HTTP date comparisons (and more).
|
||||
|
||||
lib/getenv.c offers curl_getenv() which is for reading environment variables
|
||||
in a neat platform independent way. That's used in the client, but also in
|
||||
lib/url.c when checking the proxy environment variables. Note that contrary
|
||||
to the normal unix getenv(), this returns an allocated buffer that must be
|
||||
free()ed after use.
|
||||
|
||||
lib/netrc.c holds the .netrc parser
|
||||
|
||||
lib/timeval.c features replacement functions for systems that don't have
|
||||
gettimeofday() and a few support functions for timeval conversions.
|
||||
|
||||
A function named curl_version() that returns the full curl version string is
|
||||
found in lib/version.c.
|
||||
|
||||
Persistent Connections
|
||||
======================
|
||||
|
||||
The persistent connection support in libcurl requires some considerations on
|
||||
how to do things inside of the library.
|
||||
|
||||
o The 'SessionHandle' struct returned in the curl_easy_init() call must never
|
||||
hold connection-oriented data. It is meant to hold the root data as well as
|
||||
all the options etc that the library-user may choose.
|
||||
o The 'SessionHandle' struct holds the "connection cache" (an array of
|
||||
pointers to 'connectdata' structs). There's one connectdata struct
|
||||
allocated for each connection that libcurl knows about. Note that when you
|
||||
use the multi interface, the multi handle will hold the connection cache
|
||||
and not the particular easy handle. This of course to allow all easy handles
|
||||
in a multi stack to be able to share and re-use connections.
|
||||
o This enables the 'curl handle' to be reused on subsequent transfers.
|
||||
o When we are about to perform a transfer with curl_easy_perform(), we first
|
||||
check for an already existing connection in the cache that we can use,
|
||||
otherwise we create a new one and add to the cache. If the cache is full
|
||||
already when we add a new connection, we close one of the present ones. We
|
||||
select which one to close dependent on the close policy that may have been
|
||||
previously set.
|
||||
o When the transfer operation is complete, we try to leave the connection
|
||||
open. Particular options may tell us not to, and protocols may signal
|
||||
closure on connections and then we don't keep it open of course.
|
||||
o When curl_easy_cleanup() is called, we close all still opened connections,
|
||||
unless of course the multi interface "owns" the connections.
|
||||
|
||||
You do realize that the curl handle must be re-used in order for the
|
||||
persistent connections to work.
|
||||
|
||||
multi interface/non-blocking
|
||||
============================
|
||||
|
||||
We make an effort to provide a non-blocking interface to the library, the
|
||||
multi interface. To make that interface work as good as possible, no
|
||||
low-level functions within libcurl must be written to work in a blocking
|
||||
manner.
|
||||
|
||||
One of the primary reasons we introduced c-ares support was to allow the name
|
||||
resolve phase to be perfectly non-blocking as well.
|
||||
|
||||
The ultimate goal is to provide the easy interface simply by wrapping the
|
||||
multi interface functions and thus treat everything internally as the multi
|
||||
interface is the single interface we have.
|
||||
|
||||
The FTP and the SFTP/SCP protocols are thus perfect examples of how we adapt
|
||||
and adjust the code to allow non-blocking operations even on multi-stage
|
||||
protocols. They are built around state machines that return when they could
|
||||
block waiting for data. The DICT, LDAP and TELNET protocols are crappy
|
||||
examples and they are subject for rewrite in the future to better fit the
|
||||
libcurl protocol family.
|
||||
|
||||
SSL libraries
|
||||
=============
|
||||
|
||||
Originally libcurl supported SSLeay for SSL/TLS transports, but that was then
|
||||
extended to its successor OpenSSL but has since also been extended to several
|
||||
other SSL/TLS libraries and we expect and hope to further extend the support
|
||||
in future libcurl versions.
|
||||
|
||||
To deal with this internally in the best way possible, we have a generic SSL
|
||||
function API as provided by the sslgen.[ch] system, and they are the only SSL
|
||||
functions we must use from within libcurl. sslgen is then crafted to use the
|
||||
appropriate lower-level function calls to whatever SSL library that is in
|
||||
use.
|
||||
|
||||
Library Symbols
|
||||
===============
|
||||
|
||||
All symbols used internally in libcurl must use a 'Curl_' prefix if they're
|
||||
used in more than a single file. Single-file symbols must be made static.
|
||||
Public ("exported") symbols must use a 'curl_' prefix. (There are exceptions,
|
||||
but they are to be changed to follow this pattern in future versions.) Public
|
||||
API functions are marked with CURL_EXTERN in the public header files so that
|
||||
all others can be hidden on platforms where this is possible.
|
||||
|
||||
Return Codes and Informationals
|
||||
===============================
|
||||
|
||||
I've made things simple. Almost every function in libcurl returns a CURLcode,
|
||||
that must be CURLE_OK if everything is OK or otherwise a suitable error code
|
||||
as the curl/curl.h include file defines. The very spot that detects an error
|
||||
must use the Curl_failf() function to set the human-readable error
|
||||
description.
|
||||
|
||||
In aiding the user to understand what's happening and to debug curl usage, we
|
||||
must supply a fair amount of informational messages by using the Curl_infof()
|
||||
function. Those messages are only displayed when the user explicitly asks for
|
||||
them. They are best used when revealing information that isn't otherwise
|
||||
obvious.
|
||||
|
||||
API/ABI
|
||||
=======
|
||||
|
||||
We make an effort to not export or show internals or how internals work, as
|
||||
that makes it easier to keep a solid API/ABI over time. See docs/libcurl/ABI
|
||||
for our promise to users.
|
||||
|
||||
Client
|
||||
======
|
||||
|
||||
main() resides in src/main.c together with most of the client code.
|
||||
|
||||
src/hugehelp.c is automatically generated by the mkhelp.pl perl script to
|
||||
display the complete "manual" and the src/urlglob.c file holds the functions
|
||||
used for the URL-"globbing" support. Globbing in the sense that the {} and []
|
||||
expansion stuff is there.
|
||||
|
||||
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
|
||||
control after the curl_easy_perform() it cleans up the library, checks status
|
||||
and exits.
|
||||
|
||||
When the operation is done, the ourWriteOut() function in src/writeout.c may
|
||||
be called to report about the operation. That function is using the
|
||||
curl_easy_getinfo() function to extract useful information from the curl
|
||||
session.
|
||||
|
||||
Recent versions may loop and do all this several times if many URLs were
|
||||
specified on the command line or config file.
|
||||
|
||||
Memory Debugging
|
||||
================
|
||||
|
||||
The file lib/memdebug.c contains debug-versions of a few functions. Functions
|
||||
such as malloc, free, fopen, fclose, etc that somehow deal with resources
|
||||
that might give us problems if we "leak" them. The functions in the memdebug
|
||||
system do nothing fancy, they do their normal function and then log
|
||||
information about what they just did. The logged data can then be analyzed
|
||||
after a complete session,
|
||||
|
||||
memanalyze.pl is the perl script present in tests/ that analyzes a log file
|
||||
generated by the memory tracking system. It detects if resources are
|
||||
allocated but never freed and other kinds of errors related to resource
|
||||
management.
|
||||
|
||||
Internally, definition of preprocessor symbol DEBUGBUILD restricts code which
|
||||
is only compiled for debug enabled builds. And symbol CURLDEBUG is used to
|
||||
differentiate code which is _only_ used for memory tracking/debugging.
|
||||
|
||||
Use -DCURLDEBUG when compiling to enable memory debugging, this is also
|
||||
switched on by running configure with --enable-curldebug. Use -DDEBUGBUILD
|
||||
when compiling to enable a debug build or run configure with --enable-debug.
|
||||
|
||||
curl --version will list 'Debug' feature for debug enabled builds, and
|
||||
will list 'TrackMemory' feature for curl debug memory tracking capable
|
||||
builds. These features are independent and can be controlled when running
|
||||
the configure script. When --enable-debug is given both features will be
|
||||
enabled, unless some restriction prevents memory tracking from being used.
|
||||
|
||||
Test Suite
|
||||
==========
|
||||
|
||||
Since November 2000, a test suite has evolved. It is placed in its own
|
||||
subdirectory directly off the root in the curl archive tree, and it contains
|
||||
a bunch of scripts and a lot of test case data.
|
||||
|
||||
The main test script is runtests.pl that will invoke test servers like
|
||||
httpserver.pl and ftpserver.pl before all the test cases are performed. The
|
||||
test suite currently only runs on unix-like platforms.
|
||||
|
||||
You'll find a description of the test suite in the tests/README file, and the
|
||||
test case data files in the tests/FILEFORMAT file.
|
||||
|
||||
The test suite automatically detects if curl was built with the memory
|
||||
debugging enabled, and if it was it will detect memory leaks, too.
|
||||
|
||||
Building Releases
|
||||
=================
|
||||
|
||||
There's no magic to this. When you consider everything stable enough to be
|
||||
released, run the 'maketgz' script (using 'make distcheck' will give you a
|
||||
pretty good view on the status of the current sources). maketgz prompts for
|
||||
version number of the client and the library before it creates a release
|
||||
archive. maketgz uses 'make dist' for the actual archive building, why you
|
||||
need to fill in the Makefile.am files properly for which files that should
|
||||
be included in the release archives.
|
||||
|
||||
NOTE: you need to have curl checked out from git to be able to do a proper
|
||||
release build. The release tarballs do not have everything setup in order to
|
||||
do releases properly.
|
||||
232
third-party/curl-7.21.4/docs/KNOWN_BUGS
vendored
Normal file
232
third-party/curl-7.21.4/docs/KNOWN_BUGS
vendored
Normal file
|
|
@ -0,0 +1,232 @@
|
|||
These are problems known to exist at the time of this release. Feel free to
|
||||
join in and help us correct one or more of these! Also be sure to check the
|
||||
changelog of the current development status, as one or more of these problems
|
||||
may have been fixed since this was written!
|
||||
|
||||
76. The SOCKET type in Win64 is 64 bits large (and thus so is curl_socket_t on
|
||||
that platform), and long is only 32 bits. It makes it impossible for
|
||||
curl_easy_getinfo() to return a socket properly with the CURLINFO_LASTSOCKET
|
||||
option as for all other operating systems.
|
||||
|
||||
75. NTLM authentication involving unicode user name or password.
|
||||
http://curl.haxx.se/mail/lib-2009-10/0024.html
|
||||
http://curl.haxx.se/bug/view.cgi?id=2944325
|
||||
|
||||
74. The HTTP spec allows headers to be merged and become comma-separated
|
||||
instead of being repeated several times. This also include Authenticate: and
|
||||
Proxy-Authenticate: headers and while this hardly every happens in real life
|
||||
it will confuse libcurl which does not properly support it for all headers -
|
||||
like those Authenticate headers.
|
||||
|
||||
73. if a connection is made to a FTP server but the server then just never
|
||||
sends the 220 response or otherwise is dead slow, libcurl will not
|
||||
acknowledge the connection timeout during that phase but only the "real"
|
||||
timeout - which may surprise users as it is probably considered to be the
|
||||
connect phase to most people. Brought up (and is being misunderstood) in:
|
||||
http://curl.haxx.se/bug/view.cgi?id=2844077
|
||||
|
||||
72. "Pausing pipeline problems."
|
||||
http://curl.haxx.se/mail/lib-2009-07/0214.html
|
||||
|
||||
70. Problem re-using easy handle after call to curl_multi_remove_handle
|
||||
http://curl.haxx.se/mail/lib-2009-07/0249.html
|
||||
|
||||
68. "More questions about ares behavior".
|
||||
http://curl.haxx.se/mail/lib-2009-08/0012.html
|
||||
|
||||
67. When creating multipart formposts. The file name part can be encoded with
|
||||
something beyond ascii but currently libcurl will only pass in the verbatim
|
||||
string the app provides. There are several browsers that already do this
|
||||
encoding. The key seems to be the updated draft to RFC2231:
|
||||
http://tools.ietf.org/html/draft-reschke-rfc2231-in-http-02
|
||||
|
||||
66. When using telnet, the time limitation options don't work.
|
||||
http://curl.haxx.se/bug/view.cgi?id=2818950
|
||||
|
||||
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
|
||||
for the data transfer isn't more or less instant as the code does not
|
||||
properly wait for the connect to be confirmed. See test case 564 for a first
|
||||
shot at a test case.
|
||||
|
||||
63. When CURLOPT_CONNECT_ONLY is used, the handle cannot reliably be re-used
|
||||
for any further requests or transfers. The work-around is then to close that
|
||||
handle with curl_easy_cleanup() and create a new. Some more details:
|
||||
http://curl.haxx.se/mail/lib-2009-04/0300.html
|
||||
|
||||
61. If an upload using Expect: 100-continue receives an HTTP 417 response,
|
||||
it ought to be automatically resent without the Expect:. A workaround is
|
||||
for the client application to redo the transfer after disabling Expect:.
|
||||
http://curl.haxx.se/mail/archive-2008-02/0043.html
|
||||
|
||||
60. libcurl closes the connection if an HTTP 401 reply is received while it
|
||||
is waiting for the the 100-continue response.
|
||||
http://curl.haxx.se/mail/lib-2008-08/0462.html
|
||||
|
||||
58. It seems sensible to be able to use CURLOPT_NOBODY and
|
||||
CURLOPT_FAILONERROR with FTP to detect if a file exists or not, but it is
|
||||
not working: http://curl.haxx.se/mail/lib-2008-07/0295.html
|
||||
|
||||
57. On VMS-Alpha: When using an http-file-upload the file is not sent to the
|
||||
Server with the correct content-length. Sending a file with 511 or less
|
||||
bytes, content-length 512 is used. Sending a file with 513 - 1023 bytes,
|
||||
content-length 1024 is used. Files with a length of a multiple of 512 Bytes
|
||||
show the correct content-length. Only these files work for upload.
|
||||
http://curl.haxx.se/bug/view.cgi?id=2057858
|
||||
|
||||
56. When libcurl sends CURLOPT_POSTQUOTE commands when connected to a SFTP
|
||||
server using the multi interface, the commands are not being sent correctly
|
||||
and instead the connection is "cancelled" (the operation is considered done)
|
||||
prematurely. There is a half-baked (busy-looping) patch provided in the bug
|
||||
report but it cannot be accepted as-is. See
|
||||
http://curl.haxx.se/bug/view.cgi?id=2006544
|
||||
|
||||
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
|
||||
to the KfW library. See ticket #5601 at http://krbdev.mit.edu/rt/
|
||||
|
||||
52. Gautam Kachroo's issue that identifies a problem with the multi interface
|
||||
where a connection can be re-used without actually being properly
|
||||
SSL-negotiated:
|
||||
http://curl.haxx.se/mail/lib-2008-01/0277.html
|
||||
|
||||
49. If using --retry and the transfer timeouts (possibly due to using -m or
|
||||
-y/-Y) the next attempt doesn't resume the transfer properly from what was
|
||||
downloaded in the previous attempt but will truncate and restart at the
|
||||
original position where it was at before the previous failed attempt. See
|
||||
http://curl.haxx.se/mail/lib-2008-01/0080.html and Mandriva bug report
|
||||
https://qa.mandriva.com/show_bug.cgi?id=22565
|
||||
|
||||
48. If a CONNECT response-headers are larger than BUFSIZE (16KB) when the
|
||||
connection is meant to be kept alive (like for NTLM proxy auth), the
|
||||
function will return prematurely and will confuse the rest of the HTTP
|
||||
protocol code. This should be very rare.
|
||||
|
||||
43. There seems to be a problem when connecting to the Microsoft telnet server.
|
||||
http://curl.haxx.se/bug/view.cgi?id=1720605
|
||||
|
||||
41. When doing an operation over FTP that requires the ACCT command (but not
|
||||
when logging in), the operation will fail since libcurl doesn't detect this
|
||||
and thus fails to issue the correct command:
|
||||
http://curl.haxx.se/bug/view.cgi?id=1693337
|
||||
|
||||
39. Steffen Rumler's Race Condition in Curl_proxyCONNECT:
|
||||
http://curl.haxx.se/mail/lib-2007-01/0045.html
|
||||
|
||||
38. Kumar Swamy Bhatt's problem in ftp/ssl "LIST" operation:
|
||||
http://curl.haxx.se/mail/lib-2007-01/0103.html
|
||||
|
||||
37. Having more than one connection to the same host when doing NTLM
|
||||
authentication (with performs multiple "passes" and authenticates a
|
||||
connection rather than a HTTP request), and particularly when using the
|
||||
multi interface, there's a risk that libcurl will re-use a wrong connection
|
||||
when doing the different passes in the NTLM negotiation and thus fail to
|
||||
negotiate (in seemingly mysterious ways).
|
||||
|
||||
35. Both SOCKS5 and SOCKS4 proxy connections are done blocking, which is very
|
||||
bad when used with the multi interface.
|
||||
|
||||
34. The SOCKS4 connection codes don't properly acknowledge (connect) timeouts.
|
||||
Also see #12. According to bug #1556528, even the SOCKS5 connect code does
|
||||
not do it right: http://curl.haxx.se/bug/view.cgi?id=1556528,
|
||||
|
||||
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
|
||||
--cflags suffers from the same effects with CFLAGS/CPPFLAGS.
|
||||
|
||||
30. You need to use -g to the command line tool in order to use RFC2732-style
|
||||
IPv6 numerical addresses in URLs.
|
||||
|
||||
29. IPv6 URLs with zone ID is not nicely supported.
|
||||
http://www.ietf.org/internet-drafts/draft-fenner-literal-zone-02.txt (expired)
|
||||
specifies the use of a plus sign instead of a percent when specifying zone
|
||||
IDs in URLs to get around the problem of percent signs being
|
||||
special. According to the reporter, Firefox deals with the URL _with_ a
|
||||
percent letter (which seems like a blatant URL spec violation).
|
||||
libcurl supports zone IDs where the percent sign is URL-escaped (i.e. %25).
|
||||
|
||||
See http://curl.haxx.se/bug/view.cgi?id=1371118
|
||||
|
||||
26. NTLM authentication using SSPI (on Windows) when (lib)curl is running in
|
||||
"system context" will make it use wrong(?) user name - at least when compared
|
||||
to what winhttp does. See http://curl.haxx.se/bug/view.cgi?id=1281867
|
||||
|
||||
23. SOCKS-related problems:
|
||||
A) libcurl doesn't support SOCKS for IPv6.
|
||||
B) libcurl doesn't support FTPS over a SOCKS proxy.
|
||||
E) libcurl doesn't support active FTP over a SOCKS proxy
|
||||
|
||||
We probably have even more bugs and lack of features when a SOCKS proxy is
|
||||
used.
|
||||
|
||||
22. Sending files to a FTP server using curl on VMS, might lead to curl
|
||||
complaining on "unaligned file size" on completion. The problem is related
|
||||
to VMS file structures and the perceived file sizes stat() returns. A
|
||||
possible fix would involve sending a "STRU VMS" command.
|
||||
http://curl.haxx.se/bug/view.cgi?id=1156287
|
||||
|
||||
21. FTP ASCII transfers do not follow RFC959. They don't convert the data
|
||||
accordingly (not for sending nor for receiving). RFC 959 section 3.1.1.1
|
||||
clearly describes how this should be done:
|
||||
|
||||
The sender converts the data from an internal character representation to
|
||||
the standard 8-bit NVT-ASCII representation (see the Telnet
|
||||
specification). The receiver will convert the data from the standard
|
||||
form to his own internal form.
|
||||
|
||||
Since 7.15.4 at least line endings are converted.
|
||||
|
||||
16. FTP URLs passed to curl may contain NUL (0x00) in the RFC 1738 <user>,
|
||||
<password>, and <fpath> components, encoded as "%00". The problem is that
|
||||
curl_unescape does not detect this, but instead returns a shortened C
|
||||
string. From a strict FTP protocol standpoint, NUL is a valid character
|
||||
within RFC 959 <string>, so the way to handle this correctly in curl would
|
||||
be to use a data structure other than a plain C string, one that can handle
|
||||
embedded NUL characters. From a practical standpoint, most FTP servers
|
||||
would not meaningfully support NUL characters within RFC 959 <string>,
|
||||
anyway (e.g., UNIX pathnames may not contain NUL).
|
||||
|
||||
14. Test case 165 might fail on a system which has libidn present, but with an
|
||||
old iconv version (2.1.3 is a known bad version), since it doesn't recognize
|
||||
the charset when named ISO8859-1. Changing the name to ISO-8859-1 makes the
|
||||
test pass, but instead makes it fail on Solaris hosts that use its native
|
||||
iconv.
|
||||
|
||||
13. curl version 7.12.2 fails on AIX if compiled with --enable-ares.
|
||||
The workaround is to combine --enable-ares with --disable-shared
|
||||
|
||||
12. When connecting to a SOCKS proxy, the (connect) timeout is not properly
|
||||
acknowledged after the actual TCP connect (during the SOCKS "negotiate"
|
||||
phase).
|
||||
|
||||
10. To get HTTP Negotiate authentication to work fine, you need to provide a
|
||||
(fake) user name (this concerns both curl and the lib) because the code
|
||||
wrongly only considers authentication if there's a user name provided.
|
||||
http://curl.haxx.se/bug/view.cgi?id=1004841. How?
|
||||
http://curl.haxx.se/mail/lib-2004-08/0182.html
|
||||
|
||||
8. Doing resumed upload over HTTP does not work with '-C -', because curl
|
||||
doesn't do a HEAD first to get the initial size. This needs to be done
|
||||
manually for HTTP PUT resume to work, and then '-C [index]'.
|
||||
|
||||
6. libcurl ignores empty path parts in FTP URLs, whereas RFC1738 states that
|
||||
such parts should be sent to the server as 'CWD ' (without an argument).
|
||||
The only exception to this rule, is that we knowingly break this if the
|
||||
empty part is first in the path, as then we use the double slashes to
|
||||
indicate that the user wants to reach the root dir (this exception SHALL
|
||||
remain even when this bug is fixed).
|
||||
|
||||
5. libcurl doesn't treat the content-length of compressed data properly, as
|
||||
it seems HTTP servers send the *uncompressed* length in that header and
|
||||
libcurl thinks of it as the *compressed* length. Some explanations are here:
|
||||
http://curl.haxx.se/mail/lib-2003-06/0146.html
|
||||
|
||||
2. If a HTTP server responds to a HEAD request and includes a body (thus
|
||||
violating the RFC2616), curl won't wait to read the response but just stop
|
||||
reading and return back. If a second request (let's assume a GET) is then
|
||||
immediately made to the same server again, the connection will be re-used
|
||||
fine of course, and the second request will be sent off but when the
|
||||
response is to get read, the previous response-body is what curl will read
|
||||
and havoc is what happens.
|
||||
More details on this is found in this libcurl mailing list thread:
|
||||
http://curl.haxx.se/mail/lib-2002-08/0000.html
|
||||
130
third-party/curl-7.21.4/docs/LICENSE-MIXING
vendored
Normal file
130
third-party/curl-7.21.4/docs/LICENSE-MIXING
vendored
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
License Mixing with apps, libcurl and Third Party Libraries
|
||||
===========================================================
|
||||
|
||||
libcurl can be built to use a fair amount of various third party libraries,
|
||||
libraries that are written and provided by other parties that are distributed
|
||||
using their own licenses. Even libcurl itself contains code that may cause
|
||||
problems to some. This document attempts to describe what licenses libcurl and
|
||||
the other libraries use and what possible dilemmas linking and mixing them all
|
||||
can lead to for end users.
|
||||
|
||||
I am not a lawyer and this is not legal advice!
|
||||
|
||||
One common dilemma is that GPL[1]-licensed code is not allowed to be linked
|
||||
with code licensed under the Original BSD license (with the announcement
|
||||
clause). You may still build your own copies that use them all, but
|
||||
distributing them as binaries would be to violate the GPL license - unless you
|
||||
accompany your license with an exception[2]. This particular problem was
|
||||
addressed when the Modified BSD license was created, which does not have the
|
||||
announcement clause that collides with GPL.
|
||||
|
||||
libcurl http://curl.haxx.se/docs/copyright.html
|
||||
|
||||
Uses an MIT (or Modified BSD)-style license that is as liberal as
|
||||
possible. Some of the source files that deal with KRB4 have Original
|
||||
BSD-style announce-clause licenses. You may not distribute binaries
|
||||
with krb4-enabled libcurl that also link with GPL-licensed code!
|
||||
|
||||
OpenSSL http://www.openssl.org/source/license.html
|
||||
|
||||
(May be used for SSL/TLS support) Uses an Original BSD-style license
|
||||
with an announcement clause that makes it "incompatible" with GPL. You
|
||||
are not allowed to ship binaries that link with OpenSSL that includes
|
||||
GPL code (unless that specific GPL code includes an exception for
|
||||
OpenSSL - a habit that is growing more and more common). If OpenSSL's
|
||||
licensing is a problem for you, consider using GnuTLS or yassl
|
||||
instead.
|
||||
|
||||
GnuTLS http://www.gnutls.org/
|
||||
|
||||
(May be used for SSL/TLS support) Uses the LGPL[3] license. If this is
|
||||
a problem for you, consider using OpenSSL instead. Also note that
|
||||
GnuTLS itself depends on and uses other libs (libgcrypt and
|
||||
libgpg-error) and they too are LGPL- or GPL-licensed.
|
||||
|
||||
yassl http://www.yassl.com/
|
||||
|
||||
(May be used for SSL/TLS support) Uses the GPL[1] license. If this is
|
||||
a problem for you, consider using OpenSSL or GnuTLS instead.
|
||||
|
||||
NSS http://www.mozilla.org/projects/security/pki/nss/
|
||||
|
||||
(May be used for SSL/TLS support) Is covered by the MPL[4] license,
|
||||
the GPL[1] license and the LGPL[3] license. You may choose to license
|
||||
the code under MPL terms, GPL terms, or LGPL terms. These licenses
|
||||
grant you different permissions and impose different obligations. You
|
||||
should select the license that best meets your needs.
|
||||
|
||||
axTLS http://axtls.sourceforge.net/
|
||||
|
||||
(May be used for SSL/TLS support) Uses a Modified BSD-style license.
|
||||
|
||||
c-ares http://daniel.haxx.se/projects/c-ares/license.html
|
||||
|
||||
(Used for asynchronous name resolves) Uses an MIT license that is very
|
||||
liberal and imposes no restrictions on any other library or part you
|
||||
may link with.
|
||||
|
||||
zlib http://www.gzip.org/zlib/zlib_license.html
|
||||
|
||||
(Used for compressed Transfer-Encoding support) Uses an MIT-style
|
||||
license that shouldn't collide with any other library.
|
||||
|
||||
krb4
|
||||
|
||||
While nothing in particular says that a Kerberos4 library must use any
|
||||
particular license, the one I've tried and used successfully so far
|
||||
(kth-krb4) is partly Original BSD-licensed with the announcement
|
||||
clause. Some of the code in libcurl that is written to deal with
|
||||
Kerberos4 is Modified BSD-licensed.
|
||||
|
||||
MIT Kerberos http://web.mit.edu/kerberos/www/dist/
|
||||
|
||||
(May be used for GSS support) MIT licensed, that shouldn't collide
|
||||
with any other parts.
|
||||
|
||||
Heimdal http://www.pdc.kth.se/heimdal/
|
||||
|
||||
(May be used for GSS support) Heimdal is Original BSD licensed with
|
||||
the announcement clause.
|
||||
|
||||
GNU GSS http://www.gnu.org/software/gss/
|
||||
|
||||
(May be used for GSS support) GNU GSS is GPL licensed. Note that you
|
||||
may not distribute binary curl packages that uses this if you build
|
||||
curl to also link and use any Original BSD licensed libraries!
|
||||
|
||||
fbopenssl
|
||||
|
||||
(Used for SPNEGO support) Unclear license. Based on its name, I assume
|
||||
that it uses the OpenSSL license and thus shares the same issues as
|
||||
described for OpenSSL above.
|
||||
|
||||
libidn http://josefsson.org/libidn/
|
||||
|
||||
(Used for IDNA support) Uses the GNU Lesser General Public
|
||||
License [3]. LGPL is a variation of GPL with slightly less aggressive
|
||||
"copyleft". This license requires more requirements to be met when
|
||||
distributing binaries, see the license for details. Also note that if
|
||||
you distribute a binary that includes this library, you must also
|
||||
include the full LGPL license text. Please properly point out what
|
||||
parts of the distributed package that the license addresses.
|
||||
|
||||
OpenLDAP http://www.openldap.org/software/release/license.html
|
||||
|
||||
(Used for LDAP support) Uses a Modified BSD-style license. Since
|
||||
libcurl uses OpenLDAP as a shared library only, I have not heard of
|
||||
anyone that ships OpenLDAP linked with libcurl in an app.
|
||||
|
||||
libssh2 http://www.libssh2.org/
|
||||
|
||||
(Used for scp and sftp support) libssh2 uses a Modified BSD-style
|
||||
license.
|
||||
|
||||
[1] = GPL - GNU General Public License: http://www.gnu.org/licenses/gpl.html
|
||||
[2] = http://www.fsf.org/licenses/gpl-faq.html#GPLIncompatibleLibs details on
|
||||
how to write such an exception to the GPL
|
||||
[3] = LGPL - GNU Lesser General Public License:
|
||||
http://www.gnu.org/licenses/lgpl.html
|
||||
[4] = MPL - Mozilla Public License:
|
||||
http://www.mozilla.org/MPL/
|
||||
971
third-party/curl-7.21.4/docs/MANUAL
vendored
Normal file
971
third-party/curl-7.21.4/docs/MANUAL
vendored
Normal file
|
|
@ -0,0 +1,971 @@
|
|||
LATEST VERSION
|
||||
|
||||
You always find news about what's going on as well as the latest versions
|
||||
from the curl web pages, located at:
|
||||
|
||||
http://curl.haxx.se
|
||||
|
||||
SIMPLE USAGE
|
||||
|
||||
Get the main page from Netscape's web-server:
|
||||
|
||||
curl http://www.netscape.com/
|
||||
|
||||
Get the README file the user's home directory at funet's ftp-server:
|
||||
|
||||
curl ftp://ftp.funet.fi/README
|
||||
|
||||
Get a web page from a server using port 8000:
|
||||
|
||||
curl http://www.weirdserver.com:8000/
|
||||
|
||||
Get a list of a directory of an FTP site:
|
||||
|
||||
curl ftp://cool.haxx.se/
|
||||
|
||||
Get the definition of curl from a dictionary:
|
||||
|
||||
curl dict://dict.org/m:curl
|
||||
|
||||
Fetch two documents at once:
|
||||
|
||||
curl ftp://cool.haxx.se/ http://www.weirdserver.com:8000/
|
||||
|
||||
Get a file off an FTPS server:
|
||||
|
||||
curl ftps://files.are.secure.com/secrets.txt
|
||||
|
||||
or use the more appropriate FTPS way to get the same file:
|
||||
|
||||
curl --ftp-ssl ftp://files.are.secure.com/secrets.txt
|
||||
|
||||
Get a file from an SSH server using SFTP:
|
||||
|
||||
curl -u username sftp://shell.example.com/etc/issue
|
||||
|
||||
Get a file from an SSH server using SCP using a private key to authenticate:
|
||||
|
||||
curl -u username: --key ~/.ssh/id_dsa --pubkey ~/.ssh/id_dsa.pub \
|
||||
scp://shell.example.com/~/personal.txt
|
||||
|
||||
Get the main page from an IPv6 web server:
|
||||
|
||||
curl -g "http://[2001:1890:1112:1::20]/"
|
||||
|
||||
DOWNLOAD TO A FILE
|
||||
|
||||
Get a web page and store in a local file:
|
||||
|
||||
curl -o thatpage.html http://www.netscape.com/
|
||||
|
||||
Get a web page and store in a local file, make the local file get the name
|
||||
of the remote document (if no file name part is specified in the URL, this
|
||||
will fail):
|
||||
|
||||
curl -O http://www.netscape.com/index.html
|
||||
|
||||
Fetch two files and store them with their remote names:
|
||||
|
||||
curl -O www.haxx.se/index.html -O curl.haxx.se/download.html
|
||||
|
||||
USING PASSWORDS
|
||||
|
||||
FTP
|
||||
|
||||
To ftp files using name+passwd, include them in the URL like:
|
||||
|
||||
curl ftp://name:passwd@machine.domain:port/full/path/to/file
|
||||
|
||||
or specify them with the -u flag like
|
||||
|
||||
curl -u name:passwd ftp://machine.domain:port/full/path/to/file
|
||||
|
||||
FTPS
|
||||
|
||||
It is just like for FTP, but you may also want to specify and use
|
||||
SSL-specific options for certificates etc.
|
||||
|
||||
Note that using FTPS:// as prefix is the "implicit" way as described in the
|
||||
standards while the recommended "explicit" way is done by using FTP:// and
|
||||
the --ftp-ssl option.
|
||||
|
||||
SFTP / SCP
|
||||
|
||||
This is similar to FTP, but you can specify a private key to use instead of
|
||||
a password. Note that the private key may itself be protected by a password
|
||||
that is unrelated to the login password of the remote system. If you
|
||||
provide a private key file you must also provide a public key file.
|
||||
|
||||
HTTP
|
||||
|
||||
Curl also supports user and password in HTTP URLs, thus you can pick a file
|
||||
like:
|
||||
|
||||
curl http://name:passwd@machine.domain/full/path/to/file
|
||||
|
||||
or specify user and password separately like in
|
||||
|
||||
curl -u name:passwd http://machine.domain/full/path/to/file
|
||||
|
||||
HTTP offers many different methods of authentication and curl supports
|
||||
several: Basic, Digest, NTLM and Negotiate. Without telling which method to
|
||||
use, curl defaults to Basic. You can also ask curl to pick the most secure
|
||||
ones out of the ones that the server accepts for the given URL, by using
|
||||
--anyauth.
|
||||
|
||||
NOTE! Since HTTP URLs don't support user and password, you can't use that
|
||||
style when using Curl via a proxy. You _must_ use the -u style fetch
|
||||
during such circumstances.
|
||||
|
||||
HTTPS
|
||||
|
||||
Probably most commonly used with private certificates, as explained below.
|
||||
|
||||
PROXY
|
||||
|
||||
Get an ftp file using a proxy named my-proxy that uses port 888:
|
||||
|
||||
curl -x my-proxy:888 ftp://ftp.leachsite.com/README
|
||||
|
||||
Get a file from a HTTP server that requires user and password, using the
|
||||
same proxy as above:
|
||||
|
||||
curl -u user:passwd -x my-proxy:888 http://www.get.this/
|
||||
|
||||
Some proxies require special authentication. Specify by using -U as above:
|
||||
|
||||
curl -U user:passwd -x my-proxy:888 http://www.get.this/
|
||||
|
||||
A comma-separated list of hosts and domains which do not use the proxy can
|
||||
be specified as:
|
||||
|
||||
curl --noproxy localhost,get.this -x my-proxy:888 http://www.get.this/
|
||||
|
||||
If the proxy is specified with --proxy1.0 instead of --proxy or -x, then
|
||||
curl will use HTTP/1.0 instead of HTTP/1.1 for any CONNECT attempts.
|
||||
|
||||
curl also supports SOCKS4 and SOCKS5 proxies with --socks4 and --socks5.
|
||||
|
||||
See also the environment variables Curl support that offer further proxy
|
||||
control.
|
||||
|
||||
RANGES
|
||||
|
||||
With HTTP 1.1 byte-ranges were introduced. Using this, a client can request
|
||||
to get only one or more subparts of a specified document. Curl supports
|
||||
this with the -r flag.
|
||||
|
||||
Get the first 100 bytes of a document:
|
||||
|
||||
curl -r 0-99 http://www.get.this/
|
||||
|
||||
Get the last 500 bytes of a document:
|
||||
|
||||
curl -r -500 http://www.get.this/
|
||||
|
||||
Curl also supports simple ranges for FTP files as well. Then you can only
|
||||
specify start and stop position.
|
||||
|
||||
Get the first 100 bytes of a document using FTP:
|
||||
|
||||
curl -r 0-99 ftp://www.get.this/README
|
||||
|
||||
UPLOADING
|
||||
|
||||
FTP / FTPS / SFTP / SCP
|
||||
|
||||
Upload all data on stdin to a specified server:
|
||||
|
||||
curl -T - ftp://ftp.upload.com/myfile
|
||||
|
||||
Upload data from a specified file, login with user and password:
|
||||
|
||||
curl -T uploadfile -u user:passwd ftp://ftp.upload.com/myfile
|
||||
|
||||
Upload a local file to the remote site, and use the local file name remote
|
||||
too:
|
||||
|
||||
curl -T uploadfile -u user:passwd ftp://ftp.upload.com/
|
||||
|
||||
Upload a local file to get appended to the remote file:
|
||||
|
||||
curl -T localfile -a ftp://ftp.upload.com/remotefile
|
||||
|
||||
Curl also supports ftp upload through a proxy, but only if the proxy is
|
||||
configured to allow that kind of tunneling. If it does, you can run curl in
|
||||
a fashion similar to:
|
||||
|
||||
curl --proxytunnel -x proxy:port -T localfile ftp.upload.com
|
||||
|
||||
HTTP
|
||||
|
||||
Upload all data on stdin to a specified http site:
|
||||
|
||||
curl -T - http://www.upload.com/myfile
|
||||
|
||||
Note that the http server must have been configured to accept PUT before
|
||||
this can be done successfully.
|
||||
|
||||
For other ways to do http data upload, see the POST section below.
|
||||
|
||||
VERBOSE / DEBUG
|
||||
|
||||
If curl fails where it isn't supposed to, if the servers don't let you in,
|
||||
if you can't understand the responses: use the -v flag to get verbose
|
||||
fetching. Curl will output lots of info and what it sends and receives in
|
||||
order to let the user see all client-server interaction (but it won't show
|
||||
you the actual data).
|
||||
|
||||
curl -v ftp://ftp.upload.com/
|
||||
|
||||
To get even more details and information on what curl does, try using the
|
||||
--trace or --trace-ascii options with a given file name to log to, like
|
||||
this:
|
||||
|
||||
curl --trace trace.txt www.haxx.se
|
||||
|
||||
|
||||
DETAILED INFORMATION
|
||||
|
||||
Different protocols provide different ways of getting detailed information
|
||||
about specific files/documents. To get curl to show detailed information
|
||||
about a single file, you should use -I/--head option. It displays all
|
||||
available info on a single file for HTTP and FTP. The HTTP information is a
|
||||
lot more extensive.
|
||||
|
||||
For HTTP, you can get the header information (the same as -I would show)
|
||||
shown before the data by using -i/--include. Curl understands the
|
||||
-D/--dump-header option when getting files from both FTP and HTTP, and it
|
||||
will then store the headers in the specified file.
|
||||
|
||||
Store the HTTP headers in a separate file (headers.txt in the example):
|
||||
|
||||
curl --dump-header headers.txt curl.haxx.se
|
||||
|
||||
Note that headers stored in a separate file can be very useful at a later
|
||||
time if you want curl to use cookies sent by the server. More about that in
|
||||
the cookies section.
|
||||
|
||||
POST (HTTP)
|
||||
|
||||
It's easy to post data using curl. This is done using the -d <data>
|
||||
option. The post data must be urlencoded.
|
||||
|
||||
Post a simple "name" and "phone" guestbook.
|
||||
|
||||
curl -d "name=Rafael%20Sagula&phone=3320780" \
|
||||
http://www.where.com/guest.cgi
|
||||
|
||||
How to post a form with curl, lesson #1:
|
||||
|
||||
Dig out all the <input> tags in the form that you want to fill in. (There's
|
||||
a perl program called formfind.pl on the curl site that helps with this).
|
||||
|
||||
If there's a "normal" post, you use -d to post. -d takes a full "post
|
||||
string", which is in the format
|
||||
|
||||
<variable1>=<data1>&<variable2>=<data2>&...
|
||||
|
||||
The 'variable' names are the names set with "name=" in the <input> tags, and
|
||||
the data is the contents you want to fill in for the inputs. The data *must*
|
||||
be properly URL encoded. That means you replace space with + and that you
|
||||
write weird letters with %XX where XX is the hexadecimal representation of
|
||||
the letter's ASCII code.
|
||||
|
||||
Example:
|
||||
|
||||
(page located at http://www.formpost.com/getthis/
|
||||
|
||||
<form action="post.cgi" method="post">
|
||||
<input name=user size=10>
|
||||
<input name=pass type=password size=10>
|
||||
<input name=id type=hidden value="blablabla">
|
||||
<input name=ding value="submit">
|
||||
</form>
|
||||
|
||||
We want to enter user 'foobar' with password '12345'.
|
||||
|
||||
To post to this, you enter a curl command line like:
|
||||
|
||||
curl -d "user=foobar&pass=12345&id=blablabla&ding=submit" (continues)
|
||||
http://www.formpost.com/getthis/post.cgi
|
||||
|
||||
|
||||
While -d uses the application/x-www-form-urlencoded mime-type, generally
|
||||
understood by CGI's and similar, curl also supports the more capable
|
||||
multipart/form-data type. This latter type supports things like file upload.
|
||||
|
||||
-F accepts parameters like -F "name=contents". If you want the contents to
|
||||
be read from a file, use <@filename> as contents. When specifying a file,
|
||||
you can also specify the file content type by appending ';type=<mime type>'
|
||||
to the file name. You can also post the contents of several files in one
|
||||
field. For example, the field name 'coolfiles' is used to send three files,
|
||||
with different content types using the following syntax:
|
||||
|
||||
curl -F "coolfiles=@fil1.gif;type=image/gif,fil2.txt,fil3.html" \
|
||||
http://www.post.com/postit.cgi
|
||||
|
||||
If the content-type is not specified, curl will try to guess from the file
|
||||
extension (it only knows a few), or use the previously specified type (from
|
||||
an earlier file if several files are specified in a list) or else it will
|
||||
using the default type 'text/plain'.
|
||||
|
||||
Emulate a fill-in form with -F. Let's say you fill in three fields in a
|
||||
form. One field is a file name which to post, one field is your name and one
|
||||
field is a file description. We want to post the file we have written named
|
||||
"cooltext.txt". To let curl do the posting of this data instead of your
|
||||
favourite browser, you have to read the HTML source of the form page and
|
||||
find the names of the input fields. In our example, the input field names
|
||||
are 'file', 'yourname' and 'filedescription'.
|
||||
|
||||
curl -F "file=@cooltext.txt" -F "yourname=Daniel" \
|
||||
-F "filedescription=Cool text file with cool text inside" \
|
||||
http://www.post.com/postit.cgi
|
||||
|
||||
To send two files in one post you can do it in two ways:
|
||||
|
||||
1. Send multiple files in a single "field" with a single field name:
|
||||
|
||||
curl -F "pictures=@dog.gif,cat.gif"
|
||||
|
||||
2. Send two fields with two field names:
|
||||
|
||||
curl -F "docpicture=@dog.gif" -F "catpicture=@cat.gif"
|
||||
|
||||
To send a field value literally without interpreting a leading '@'
|
||||
or '<', or an embedded ';type=', use --form-string instead of
|
||||
-F. This is recommended when the value is obtained from a user or
|
||||
some other unpredictable source. Under these circumstances, using
|
||||
-F instead of --form-string would allow a user to trick curl into
|
||||
uploading a file.
|
||||
|
||||
REFERRER
|
||||
|
||||
A HTTP request has the option to include information about which address
|
||||
that referred to actual page. Curl allows you to specify the
|
||||
referrer to be used on the command line. It is especially useful to
|
||||
fool or trick stupid servers or CGI scripts that rely on that information
|
||||
being available or contain certain data.
|
||||
|
||||
curl -e www.coolsite.com http://www.showme.com/
|
||||
|
||||
NOTE: The Referer: [sic] field is defined in the HTTP spec to be a full URL.
|
||||
|
||||
USER AGENT
|
||||
|
||||
A HTTP request has the option to include information about the browser
|
||||
that generated the request. Curl allows it to be specified on the command
|
||||
line. It is especially useful to fool or trick stupid servers or CGI
|
||||
scripts that only accept certain browsers.
|
||||
|
||||
Example:
|
||||
|
||||
curl -A 'Mozilla/3.0 (Win95; I)' http://www.nationsbank.com/
|
||||
|
||||
Other common strings:
|
||||
'Mozilla/3.0 (Win95; I)' Netscape Version 3 for Windows 95
|
||||
'Mozilla/3.04 (Win95; U)' Netscape Version 3 for Windows 95
|
||||
'Mozilla/2.02 (OS/2; U)' Netscape Version 2 for OS/2
|
||||
'Mozilla/4.04 [en] (X11; U; AIX 4.2; Nav)' NS for AIX
|
||||
'Mozilla/4.05 [en] (X11; U; Linux 2.0.32 i586)' NS for Linux
|
||||
|
||||
Note that Internet Explorer tries hard to be compatible in every way:
|
||||
'Mozilla/4.0 (compatible; MSIE 4.01; Windows 95)' MSIE for W95
|
||||
|
||||
Mozilla is not the only possible User-Agent name:
|
||||
'Konqueror/1.0' KDE File Manager desktop client
|
||||
'Lynx/2.7.1 libwww-FM/2.14' Lynx command line browser
|
||||
|
||||
COOKIES
|
||||
|
||||
Cookies are generally used by web servers to keep state information at the
|
||||
client's side. The server sets cookies by sending a response line in the
|
||||
headers that looks like 'Set-Cookie: <data>' where the data part then
|
||||
typically contains a set of NAME=VALUE pairs (separated by semicolons ';'
|
||||
like "NAME1=VALUE1; NAME2=VALUE2;"). The server can also specify for what
|
||||
path the "cookie" should be used for (by specifying "path=value"), when the
|
||||
cookie should expire ("expire=DATE"), for what domain to use it
|
||||
("domain=NAME") and if it should be used on secure connections only
|
||||
("secure").
|
||||
|
||||
If you've received a page from a server that contains a header like:
|
||||
Set-Cookie: sessionid=boo123; path="/foo";
|
||||
|
||||
it means the server wants that first pair passed on when we get anything in
|
||||
a path beginning with "/foo".
|
||||
|
||||
Example, get a page that wants my name passed in a cookie:
|
||||
|
||||
curl -b "name=Daniel" www.sillypage.com
|
||||
|
||||
Curl also has the ability to use previously received cookies in following
|
||||
sessions. If you get cookies from a server and store them in a file in a
|
||||
manner similar to:
|
||||
|
||||
curl --dump-header headers www.example.com
|
||||
|
||||
... you can then in a second connect to that (or another) site, use the
|
||||
cookies from the 'headers' file like:
|
||||
|
||||
curl -b headers www.example.com
|
||||
|
||||
While saving headers to a file is a working way to store cookies, it is
|
||||
however error-prone and not the preferred way to do this. Instead, make curl
|
||||
save the incoming cookies using the well-known netscape cookie format like
|
||||
this:
|
||||
|
||||
curl -c cookies.txt www.example.com
|
||||
|
||||
Note that by specifying -b you enable the "cookie awareness" and with -L
|
||||
you can make curl follow a location: (which often is used in combination
|
||||
with cookies). So that if a site sends cookies and a location, you can
|
||||
use a non-existing file to trigger the cookie awareness like:
|
||||
|
||||
curl -L -b empty.txt www.example.com
|
||||
|
||||
The file to read cookies from must be formatted using plain HTTP headers OR
|
||||
as netscape's cookie file. Curl will determine what kind it is based on the
|
||||
file contents. In the above command, curl will parse the header and store
|
||||
the cookies received from www.example.com. curl will send to the server the
|
||||
stored cookies which match the request as it follows the location. The
|
||||
file "empty.txt" may be a nonexistent file.
|
||||
|
||||
Alas, to both read and write cookies from a netscape cookie file, you can
|
||||
set both -b and -c to use the same file:
|
||||
|
||||
curl -b cookies.txt -c cookies.txt www.example.com
|
||||
|
||||
PROGRESS METER
|
||||
|
||||
The progress meter exists to show a user that something actually is
|
||||
happening. The different fields in the output have the following meaning:
|
||||
|
||||
% Total % Received % Xferd Average Speed Time Curr.
|
||||
Dload Upload Total Current Left Speed
|
||||
0 151M 0 38608 0 0 9406 0 4:41:43 0:00:04 4:41:39 9287
|
||||
|
||||
From left-to-right:
|
||||
% - percentage completed of the whole transfer
|
||||
Total - total size of the whole expected transfer
|
||||
% - percentage completed of the download
|
||||
Received - currently downloaded amount of bytes
|
||||
% - percentage completed of the upload
|
||||
Xferd - currently uploaded amount of bytes
|
||||
Average Speed
|
||||
Dload - the average transfer speed of the download
|
||||
Average Speed
|
||||
Upload - the average transfer speed of the upload
|
||||
Time Total - expected time to complete the operation
|
||||
Time Current - time passed since the invoke
|
||||
Time Left - expected time left to completion
|
||||
Curr.Speed - the average transfer speed the last 5 seconds (the first
|
||||
5 seconds of a transfer is based on less time of course.)
|
||||
|
||||
The -# option will display a totally different progress bar that doesn't
|
||||
need much explanation!
|
||||
|
||||
SPEED LIMIT
|
||||
|
||||
Curl allows the user to set the transfer speed conditions that must be met
|
||||
to let the transfer keep going. By using the switch -y and -Y you
|
||||
can make curl abort transfers if the transfer speed is below the specified
|
||||
lowest limit for a specified time.
|
||||
|
||||
To have curl abort the download if the speed is slower than 3000 bytes per
|
||||
second for 1 minute, run:
|
||||
|
||||
curl -Y 3000 -y 60 www.far-away-site.com
|
||||
|
||||
This can very well be used in combination with the overall time limit, so
|
||||
that the above operation must be completed in whole within 30 minutes:
|
||||
|
||||
curl -m 1800 -Y 3000 -y 60 www.far-away-site.com
|
||||
|
||||
Forcing curl not to transfer data faster than a given rate is also possible,
|
||||
which might be useful if you're using a limited bandwidth connection and you
|
||||
don't want your transfer to use all of it (sometimes referred to as
|
||||
"bandwidth throttle").
|
||||
|
||||
Make curl transfer data no faster than 10 kilobytes per second:
|
||||
|
||||
curl --limit-rate 10K www.far-away-site.com
|
||||
|
||||
or
|
||||
|
||||
curl --limit-rate 10240 www.far-away-site.com
|
||||
|
||||
Or prevent curl from uploading data faster than 1 megabyte per second:
|
||||
|
||||
curl -T upload --limit-rate 1M ftp://uploadshereplease.com
|
||||
|
||||
When using the --limit-rate option, the transfer rate is regulated on a
|
||||
per-second basis, which will cause the total transfer speed to become lower
|
||||
than the given number. Sometimes of course substantially lower, if your
|
||||
transfer stalls during periods.
|
||||
|
||||
CONFIG FILE
|
||||
|
||||
Curl automatically tries to read the .curlrc file (or _curlrc file on win32
|
||||
systems) from the user's home dir on startup.
|
||||
|
||||
The config file could be made up with normal command line switches, but you
|
||||
can also specify the long options without the dashes to make it more
|
||||
readable. You can separate the options and the parameter with spaces, or
|
||||
with = or :. Comments can be used within the file. If the first letter on a
|
||||
line is a '#'-symbol the rest of the line is treated as a comment.
|
||||
|
||||
If you want the parameter to contain spaces, you must enclose the entire
|
||||
parameter within double quotes ("). Within those quotes, you specify a
|
||||
quote as \".
|
||||
|
||||
NOTE: You must specify options and their arguments on the same line.
|
||||
|
||||
Example, set default time out and proxy in a config file:
|
||||
|
||||
# We want a 30 minute timeout:
|
||||
-m 1800
|
||||
# ... and we use a proxy for all accesses:
|
||||
proxy = proxy.our.domain.com:8080
|
||||
|
||||
White spaces ARE significant at the end of lines, but all white spaces
|
||||
leading up to the first characters of each line are ignored.
|
||||
|
||||
Prevent curl from reading the default file by using -q as the first command
|
||||
line parameter, like:
|
||||
|
||||
curl -q www.thatsite.com
|
||||
|
||||
Force curl to get and display a local help page in case it is invoked
|
||||
without URL by making a config file similar to:
|
||||
|
||||
# default url to get
|
||||
url = "http://help.with.curl.com/curlhelp.html"
|
||||
|
||||
You can specify another config file to be read by using the -K/--config
|
||||
flag. If you set config file name to "-" it'll read the config from stdin,
|
||||
which can be handy if you want to hide options from being visible in process
|
||||
tables etc:
|
||||
|
||||
echo "user = user:passwd" | curl -K - http://that.secret.site.com
|
||||
|
||||
EXTRA HEADERS
|
||||
|
||||
When using curl in your own very special programs, you may end up needing
|
||||
to pass on your own custom headers when getting a web page. You can do
|
||||
this by using the -H flag.
|
||||
|
||||
Example, send the header "X-you-and-me: yes" to the server when getting a
|
||||
page:
|
||||
|
||||
curl -H "X-you-and-me: yes" www.love.com
|
||||
|
||||
This can also be useful in case you want curl to send a different text in a
|
||||
header than it normally does. The -H header you specify then replaces the
|
||||
header curl would normally send. If you replace an internal header with an
|
||||
empty one, you prevent that header from being sent. To prevent the Host:
|
||||
header from being used:
|
||||
|
||||
curl -H "Host:" www.server.com
|
||||
|
||||
FTP and PATH NAMES
|
||||
|
||||
Do note that when getting files with the ftp:// URL, the given path is
|
||||
relative the directory you enter. To get the file 'README' from your home
|
||||
directory at your ftp site, do:
|
||||
|
||||
curl ftp://user:passwd@my.site.com/README
|
||||
|
||||
But if you want the README file from the root directory of that very same
|
||||
site, you need to specify the absolute file name:
|
||||
|
||||
curl ftp://user:passwd@my.site.com//README
|
||||
|
||||
(I.e with an extra slash in front of the file name.)
|
||||
|
||||
SFTP and SCP and PATH NAMES
|
||||
|
||||
With sftp: and scp: URLs, the path name given is the absolute name on the
|
||||
server. To access a file relative to the remote user's home directory,
|
||||
prefix the file with /~/ , such as:
|
||||
|
||||
curl -u $USER sftp://home.example.com/~/.bashrc
|
||||
|
||||
FTP and firewalls
|
||||
|
||||
The FTP protocol requires one of the involved parties to open a second
|
||||
connection as soon as data is about to get transfered. There are two ways to
|
||||
do this.
|
||||
|
||||
The default way for curl is to issue the PASV command which causes the
|
||||
server to open another port and await another connection performed by the
|
||||
client. This is good if the client is behind a firewall that don't allow
|
||||
incoming connections.
|
||||
|
||||
curl ftp.download.com
|
||||
|
||||
If the server for example, is behind a firewall that don't allow connections
|
||||
on other ports than 21 (or if it just doesn't support the PASV command), the
|
||||
other way to do it is to use the PORT command and instruct the server to
|
||||
connect to the client on the given (as parameters to the PORT command) IP
|
||||
number and port.
|
||||
|
||||
The -P flag to curl supports a few different options. Your machine may have
|
||||
several IP-addresses and/or network interfaces and curl allows you to select
|
||||
which of them to use. Default address can also be used:
|
||||
|
||||
curl -P - ftp.download.com
|
||||
|
||||
Download with PORT but use the IP address of our 'le0' interface (this does
|
||||
not work on windows):
|
||||
|
||||
curl -P le0 ftp.download.com
|
||||
|
||||
Download with PORT but use 192.168.0.10 as our IP address to use:
|
||||
|
||||
curl -P 192.168.0.10 ftp.download.com
|
||||
|
||||
NETWORK INTERFACE
|
||||
|
||||
Get a web page from a server using a specified port for the interface:
|
||||
|
||||
curl --interface eth0:1 http://www.netscape.com/
|
||||
|
||||
or
|
||||
|
||||
curl --interface 192.168.1.10 http://www.netscape.com/
|
||||
|
||||
HTTPS
|
||||
|
||||
Secure HTTP requires SSL libraries to be installed and used when curl is
|
||||
built. If that is done, curl is capable of retrieving and posting documents
|
||||
using the HTTPS protocol.
|
||||
|
||||
Example:
|
||||
|
||||
curl https://www.secure-site.com
|
||||
|
||||
Curl is also capable of using your personal certificates to get/post files
|
||||
from sites that require valid certificates. The only drawback is that the
|
||||
certificate needs to be in PEM-format. PEM is a standard and open format to
|
||||
store certificates with, but it is not used by the most commonly used
|
||||
browsers (Netscape and MSIE both use the so called PKCS#12 format). If you
|
||||
want curl to use the certificates you use with your (favourite) browser, you
|
||||
may need to download/compile a converter that can convert your browser's
|
||||
formatted certificates to PEM formatted ones. This kind of converter is
|
||||
included in recent versions of OpenSSL, and for older versions Dr Stephen
|
||||
N. Henson has written a patch for SSLeay that adds this functionality. You
|
||||
can get his patch (that requires an SSLeay installation) from his site at:
|
||||
http://www.drh-consultancy.demon.co.uk/
|
||||
|
||||
Example on how to automatically retrieve a document using a certificate with
|
||||
a personal password:
|
||||
|
||||
curl -E /path/to/cert.pem:password https://secure.site.com/
|
||||
|
||||
If you neglect to specify the password on the command line, you will be
|
||||
prompted for the correct password before any data can be received.
|
||||
|
||||
Many older SSL-servers have problems with SSLv3 or TLS, that newer versions
|
||||
of OpenSSL etc is using, therefore it is sometimes useful to specify what
|
||||
SSL-version curl should use. Use -3, -2 or -1 to specify that exact SSL
|
||||
version to use (for SSLv3, SSLv2 or TLSv1 respectively):
|
||||
|
||||
curl -2 https://secure.site.com/
|
||||
|
||||
Otherwise, curl will first attempt to use v3 and then v2.
|
||||
|
||||
To use OpenSSL to convert your favourite browser's certificate into a PEM
|
||||
formatted one that curl can use, do something like this (assuming netscape,
|
||||
but IE is likely to work similarly):
|
||||
|
||||
You start with hitting the 'security' menu button in netscape.
|
||||
|
||||
Select 'certificates->yours' and then pick a certificate in the list
|
||||
|
||||
Press the 'export' button
|
||||
|
||||
enter your PIN code for the certs
|
||||
|
||||
select a proper place to save it
|
||||
|
||||
Run the 'openssl' application to convert the certificate. If you cd to the
|
||||
openssl installation, you can do it like:
|
||||
|
||||
# ./apps/openssl pkcs12 -in [file you saved] -clcerts -out [PEMfile]
|
||||
|
||||
|
||||
RESUMING FILE TRANSFERS
|
||||
|
||||
To continue a file transfer where it was previously aborted, curl supports
|
||||
resume on http(s) downloads as well as ftp uploads and downloads.
|
||||
|
||||
Continue downloading a document:
|
||||
|
||||
curl -C - -o file ftp://ftp.server.com/path/file
|
||||
|
||||
Continue uploading a document(*1):
|
||||
|
||||
curl -C - -T file ftp://ftp.server.com/path/file
|
||||
|
||||
Continue downloading a document from a web server(*2):
|
||||
|
||||
curl -C - -o file http://www.server.com/
|
||||
|
||||
(*1) = This requires that the ftp server supports the non-standard command
|
||||
SIZE. If it doesn't, curl will say so.
|
||||
|
||||
(*2) = This requires that the web server supports at least HTTP/1.1. If it
|
||||
doesn't, curl will say so.
|
||||
|
||||
TIME CONDITIONS
|
||||
|
||||
HTTP allows a client to specify a time condition for the document it
|
||||
requests. It is If-Modified-Since or If-Unmodified-Since. Curl allow you to
|
||||
specify them with the -z/--time-cond flag.
|
||||
|
||||
For example, you can easily make a download that only gets performed if the
|
||||
remote file is newer than a local copy. It would be made like:
|
||||
|
||||
curl -z local.html http://remote.server.com/remote.html
|
||||
|
||||
Or you can download a file only if the local file is newer than the remote
|
||||
one. Do this by prepending the date string with a '-', as in:
|
||||
|
||||
curl -z -local.html http://remote.server.com/remote.html
|
||||
|
||||
You can specify a "free text" date as condition. Tell curl to only download
|
||||
the file if it was updated since January 12, 2012:
|
||||
|
||||
curl -z "Jan 12 2012" http://remote.server.com/remote.html
|
||||
|
||||
Curl will then accept a wide range of date formats. You always make the date
|
||||
check the other way around by prepending it with a dash '-'.
|
||||
|
||||
DICT
|
||||
|
||||
For fun try
|
||||
|
||||
curl dict://dict.org/m:curl
|
||||
curl dict://dict.org/d:heisenbug:jargon
|
||||
curl dict://dict.org/d:daniel:web1913
|
||||
|
||||
Aliases for 'm' are 'match' and 'find', and aliases for 'd' are 'define'
|
||||
and 'lookup'. For example,
|
||||
|
||||
curl dict://dict.org/find:curl
|
||||
|
||||
Commands that break the URL description of the RFC (but not the DICT
|
||||
protocol) are
|
||||
|
||||
curl dict://dict.org/show:db
|
||||
curl dict://dict.org/show:strat
|
||||
|
||||
Authentication is still missing (but this is not required by the RFC)
|
||||
|
||||
LDAP
|
||||
|
||||
If you have installed the OpenLDAP library, curl can take advantage of it
|
||||
and offer ldap:// support.
|
||||
|
||||
LDAP is a complex thing and writing an LDAP query is not an easy task. I do
|
||||
advice you to dig up the syntax description for that elsewhere. Two places
|
||||
that might suit you are:
|
||||
|
||||
Netscape's "Netscape Directory SDK 3.0 for C Programmer's Guide Chapter 10:
|
||||
Working with LDAP URLs":
|
||||
http://developer.netscape.com/docs/manuals/dirsdk/csdk30/url.htm
|
||||
|
||||
RFC 2255, "The LDAP URL Format" http://curl.haxx.se/rfc/rfc2255.txt
|
||||
|
||||
To show you an example, this is now I can get all people from my local LDAP
|
||||
server that has a certain sub-domain in their email address:
|
||||
|
||||
curl -B "ldap://ldap.frontec.se/o=frontec??sub?mail=*sth.frontec.se"
|
||||
|
||||
If I want the same info in HTML format, I can get it by not using the -B
|
||||
(enforce ASCII) flag.
|
||||
|
||||
ENVIRONMENT VARIABLES
|
||||
|
||||
Curl reads and understands the following environment variables:
|
||||
|
||||
http_proxy, HTTPS_PROXY, FTP_PROXY
|
||||
|
||||
They should be set for protocol-specific proxies. General proxy should be
|
||||
set with
|
||||
|
||||
ALL_PROXY
|
||||
|
||||
A comma-separated list of host names that shouldn't go through any proxy is
|
||||
set in (only an asterisk, '*' matches all hosts)
|
||||
|
||||
NO_PROXY
|
||||
|
||||
If the host name matches one of these strings, or the host is within the
|
||||
domain of one of these strings, transactions with that node will not be
|
||||
proxied.
|
||||
|
||||
|
||||
The usage of the -x/--proxy flag overrides the environment variables.
|
||||
|
||||
NETRC
|
||||
|
||||
Unix introduced the .netrc concept a long time ago. It is a way for a user
|
||||
to specify name and password for commonly visited ftp sites in a file so
|
||||
that you don't have to type them in each time you visit those sites. You
|
||||
realize this is a big security risk if someone else gets hold of your
|
||||
passwords, so therefore most unix programs won't read this file unless it is
|
||||
only readable by yourself (curl doesn't care though).
|
||||
|
||||
Curl supports .netrc files if told so (using the -n/--netrc and
|
||||
--netrc-optional options). This is not restricted to only ftp,
|
||||
but curl can use it for all protocols where authentication is used.
|
||||
|
||||
A very simple .netrc file could look something like:
|
||||
|
||||
machine curl.haxx.se login iamdaniel password mysecret
|
||||
|
||||
CUSTOM OUTPUT
|
||||
|
||||
To better allow script programmers to get to know about the progress of
|
||||
curl, the -w/--write-out option was introduced. Using this, you can specify
|
||||
what information from the previous transfer you want to extract.
|
||||
|
||||
To display the amount of bytes downloaded together with some text and an
|
||||
ending newline:
|
||||
|
||||
curl -w 'We downloaded %{size_download} bytes\n' www.download.com
|
||||
|
||||
KERBEROS FTP TRANSFER
|
||||
|
||||
Curl supports kerberos4 and kerberos5/GSSAPI for FTP transfers. You need
|
||||
the kerberos package installed and used at curl build time for it to be
|
||||
used.
|
||||
|
||||
First, get the krb-ticket the normal way, like with the kinit/kauth tool.
|
||||
Then use curl in way similar to:
|
||||
|
||||
curl --krb private ftp://krb4site.com -u username:fakepwd
|
||||
|
||||
There's no use for a password on the -u switch, but a blank one will make
|
||||
curl ask for one and you already entered the real password to kinit/kauth.
|
||||
|
||||
TELNET
|
||||
|
||||
The curl telnet support is basic and very easy to use. Curl passes all data
|
||||
passed to it on stdin to the remote server. Connect to a remote telnet
|
||||
server using a command line similar to:
|
||||
|
||||
curl telnet://remote.server.com
|
||||
|
||||
And enter the data to pass to the server on stdin. The result will be sent
|
||||
to stdout or to the file you specify with -o.
|
||||
|
||||
You might want the -N/--no-buffer option to switch off the buffered output
|
||||
for slow connections or similar.
|
||||
|
||||
Pass options to the telnet protocol negotiation, by using the -t option. To
|
||||
tell the server we use a vt100 terminal, try something like:
|
||||
|
||||
curl -tTTYPE=vt100 telnet://remote.server.com
|
||||
|
||||
Other interesting options for it -t include:
|
||||
|
||||
- XDISPLOC=<X display> Sets the X display location.
|
||||
|
||||
- NEW_ENV=<var,val> Sets an environment variable.
|
||||
|
||||
NOTE: the telnet protocol does not specify any way to login with a specified
|
||||
user and password so curl can't do that automatically. To do that, you need
|
||||
to track when the login prompt is received and send the username and
|
||||
password accordingly.
|
||||
|
||||
PERSISTENT CONNECTIONS
|
||||
|
||||
Specifying multiple files on a single command line will make curl transfer
|
||||
all of them, one after the other in the specified order.
|
||||
|
||||
libcurl will attempt to use persistent connections for the transfers so that
|
||||
the second transfer to the same host can use the same connection that was
|
||||
already initiated and was left open in the previous transfer. This greatly
|
||||
decreases connection time for all but the first transfer and it makes a far
|
||||
better use of the network.
|
||||
|
||||
Note that curl cannot use persistent connections for transfers that are used
|
||||
in subsequence curl invokes. Try to stuff as many URLs as possible on the
|
||||
same command line if they are using the same host, as that'll make the
|
||||
transfers faster. If you use a http proxy for file transfers, practically
|
||||
all transfers will be persistent.
|
||||
|
||||
MULTIPLE TRANSFERS WITH A SINGLE COMMAND LINE
|
||||
|
||||
As is mentioned above, you can download multiple files with one command line
|
||||
by simply adding more URLs. If you want those to get saved to a local file
|
||||
instead of just printed to stdout, you need to add one save option for each
|
||||
URL you specify. Note that this also goes for the -O option (but not
|
||||
--remote-name-all).
|
||||
|
||||
For example: get two files and use -O for the first and a custom file
|
||||
name for the second:
|
||||
|
||||
curl -O http://url.com/file.txt ftp://ftp.com/moo.exe -o moo.jpg
|
||||
|
||||
You can also upload multiple files in a similar fashion:
|
||||
|
||||
curl -T local1 ftp://ftp.com/moo.exe -T local2 ftp://ftp.com/moo2.txt
|
||||
|
||||
IPv6
|
||||
|
||||
curl will connect to a server with IPv6 when a host lookup returns an IPv6
|
||||
address and fall back to IPv4 if the connection fails. The --ipv4 and --ipv6
|
||||
options can specify which address to use when both are available. IPv6
|
||||
addresses can also be specified directly in URLs using the syntax:
|
||||
|
||||
http://[2001:1890:1112:1::20]/overview.html
|
||||
|
||||
When this style is used, the -g option must be given to stop curl from
|
||||
interpreting the square brackets as special globbing characters. Link local
|
||||
and site local addresses including a scope identifier, such as fe80::1234%1,
|
||||
may also be used, but the scope portion must be numeric and the percent
|
||||
character must be URL escaped. The previous example in an SFTP URL might
|
||||
look like:
|
||||
|
||||
sftp://[fe80::1234%251]/
|
||||
|
||||
IPv6 addresses provided other than in URLs (e.g. to the --proxy, --interface
|
||||
or --ftp-port options) should not be URL encoded.
|
||||
|
||||
|
||||
MAILING LISTS
|
||||
|
||||
For your convenience, we have several open mailing lists to discuss curl,
|
||||
its development and things relevant to this. Get all info at
|
||||
http://curl.haxx.se/mail/. Some of the lists available are:
|
||||
|
||||
curl-users
|
||||
|
||||
Users of the command line tool. How to use it, what doesn't work, new
|
||||
features, related tools, questions, news, installations, compilations,
|
||||
running, porting etc.
|
||||
|
||||
curl-library
|
||||
|
||||
Developers using or developing libcurl. Bugs, extensions, improvements.
|
||||
|
||||
curl-announce
|
||||
|
||||
Low-traffic. Only receives announcements of new public versions. At worst,
|
||||
that makes something like one or two mails per month, but usually only one
|
||||
mail every second month.
|
||||
|
||||
curl-and-php
|
||||
|
||||
Using the curl functions in PHP. Everything curl with a PHP angle. Or PHP
|
||||
with a curl angle.
|
||||
|
||||
curl-and-python
|
||||
|
||||
Python hackers using curl with or without the python binding pycurl.
|
||||
|
||||
Please direct curl questions, feature requests and trouble reports to one of
|
||||
these mailing lists instead of mailing any individual.
|
||||
40
third-party/curl-7.21.4/docs/Makefile.am
vendored
Normal file
40
third-party/curl-7.21.4/docs/Makefile.am
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#
|
||||
#
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign no-dependencies
|
||||
|
||||
man_MANS = curl.1 curl-config.1
|
||||
GENHTMLPAGES = curl.html curl-config.html
|
||||
PDFPAGES = curl.pdf curl-config.pdf
|
||||
|
||||
HTMLPAGES = $(GENHTMLPAGES) index.html
|
||||
|
||||
SUBDIRS = examples libcurl
|
||||
|
||||
CLEANFILES = $(GENHTMLPAGES) $(PDFPAGES)
|
||||
|
||||
EXTRA_DIST = MANUAL BUGS CONTRIBUTE FAQ FEATURES INTERNALS SSLCERTS \
|
||||
README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS VERSIONS \
|
||||
KNOWN_BUGS BINDINGS $(man_MANS) $(HTMLPAGES) HISTORY INSTALL \
|
||||
$(PDFPAGES) LICENSE-MIXING README.netware DISTRO-DILEMMA INSTALL.devcpp
|
||||
|
||||
MAN2HTML= roffit < $< >$@
|
||||
|
||||
SUFFIXES = .1 .html .pdf
|
||||
|
||||
html: $(HTMLPAGES)
|
||||
cd libcurl; make html
|
||||
|
||||
pdf: $(PDFPAGES)
|
||||
cd libcurl; make pdf
|
||||
|
||||
.1.html:
|
||||
$(MAN2HTML)
|
||||
|
||||
.1.pdf:
|
||||
@(foo=`echo $@ | sed -e 's/\.[0-9]$$//g'`; \
|
||||
groff -Tps -man $< >$$foo.ps; \
|
||||
ps2pdf $$foo.ps $@; \
|
||||
rm $$foo.ps; \
|
||||
echo "converted $< to $@")
|
||||
|
||||
16
third-party/curl-7.21.4/docs/README.cmake
vendored
Executable file
16
third-party/curl-7.21.4/docs/README.cmake
vendored
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
README.cmake
|
||||
Read the README file first.
|
||||
|
||||
Curl contains CMake build files that provide a way to build Curl with the
|
||||
CMake build tool (www.cmake.org). CMake is a cross platform meta build tool
|
||||
that generates native makefiles and IDE project files. The CMake build
|
||||
system can be used to build Curl on any of its supported platforms.
|
||||
|
||||
Read the INSTALL.cmake file for instructions on how to compile curl with
|
||||
CMake.
|
||||
27
third-party/curl-7.21.4/docs/README.netware
vendored
Normal file
27
third-party/curl-7.21.4/docs/README.netware
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
README.netware
|
||||
|
||||
Read the README file first.
|
||||
|
||||
Curl has been successfully compiled with gcc / nlmconv on different flavours
|
||||
of Linux as well as with the official Metrowerks CodeWarrior compiler.
|
||||
While not being the main development target, a continously growing share of
|
||||
curl users are NetWare-based, specially also consuming the lib from PHP.
|
||||
|
||||
The unix-style man pages are tricky to read on windows, so therefore are all
|
||||
those pages converted to HTML as well as pdf, and included in the release
|
||||
archives.
|
||||
|
||||
The main curl.1 man page is also "built-in" in the command line tool. Use a
|
||||
command line similar to this in order to extract a separate text file:
|
||||
|
||||
curl -M >manual.txt
|
||||
|
||||
Read the INSTALL file for instructions how to compile curl self.
|
||||
|
||||
|
||||
26
third-party/curl-7.21.4/docs/README.win32
vendored
Normal file
26
third-party/curl-7.21.4/docs/README.win32
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
README.win32
|
||||
|
||||
Read the README file first.
|
||||
|
||||
Curl has been compiled, built and run on all sorts of Windows and win32
|
||||
systems. While not being the main develop target, a fair share of curl users
|
||||
are win32-based.
|
||||
|
||||
The unix-style man pages are tricky to read on windows, so therefore are all
|
||||
those pages converted to HTML as well as pdf, and included in the release
|
||||
archives.
|
||||
|
||||
The main curl.1 man page is also "built-in" in the command line tool. Use a
|
||||
command line similar to this in order to extract a separate text file:
|
||||
|
||||
curl -M >manual.txt
|
||||
|
||||
Read the INSTALL file for instructions how to compile curl self.
|
||||
|
||||
|
||||
83
third-party/curl-7.21.4/docs/RESOURCES
vendored
Normal file
83
third-party/curl-7.21.4/docs/RESOURCES
vendored
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
_ _ ____ _
|
||||
Project ___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
|
||||
This document lists documents and standards used by curl.
|
||||
|
||||
RFC 959 - The FTP protocol
|
||||
|
||||
RFC 1635 - How to Use Anonymous FTP
|
||||
|
||||
RFC 1738 - Uniform Resource Locators
|
||||
|
||||
RFC 1777 - defines the LDAP protocol
|
||||
|
||||
RFC 1808 - Relative Uniform Resource Locators
|
||||
|
||||
RFC 1867 - Form-based File Upload in HTML
|
||||
|
||||
RFC 1950 - ZLIB Compressed Data Format Specification
|
||||
|
||||
RFC 1951 - DEFLATE Compressed Data Format Specification
|
||||
|
||||
RFC 1952 - gzip compression format
|
||||
|
||||
RFC 1959 - LDAP URL syntax
|
||||
|
||||
RFC 2045-2049 - Everything you need to know about MIME! (needed for form
|
||||
based upload)
|
||||
|
||||
RFC 2068 - HTTP 1.1 (obsoleted by RFC 2616)
|
||||
|
||||
RFC 2104 - Keyed-Hashing for Message Authentication
|
||||
|
||||
RFC 2109 - HTTP State Management Mechanism (cookie stuff)
|
||||
- Also, read Netscape's specification at
|
||||
http://curl.haxx.se/rfc/cookie_spec.html
|
||||
|
||||
RFC 2183 - The Content-Disposition Header Field
|
||||
|
||||
RFC 2195 - CRAM-MD5 authentication
|
||||
|
||||
RFC 2229 - A Dictionary Server Protocol
|
||||
|
||||
RFC 2255 - Newer LDAP URL syntax document.
|
||||
|
||||
RFC 2231 - MIME Parameter Value and Encoded Word Extensions:
|
||||
Character Sets, Languages, and Continuations
|
||||
|
||||
RFC 2388 - "Returning Values from Forms: multipart/form-data"
|
||||
Use this as an addition to the RFC1867
|
||||
|
||||
RFC 2396 - "Uniform Resource Identifiers: Generic Syntax and Semantics" This
|
||||
one obsoletes RFC 1738, but since RFC 1738 is often mentioned
|
||||
I've left it in this list.
|
||||
|
||||
RFC 2428 - FTP Extensions for IPv6 and NATs
|
||||
|
||||
RFC 2577 - FTP Security Considerations
|
||||
|
||||
RFC 2616 - HTTP 1.1, the latest
|
||||
|
||||
RFC 2617 - HTTP Authentication
|
||||
|
||||
RFC 2718 - Guidelines for new URL Schemes
|
||||
|
||||
RFC 2732 - Format for Literal IPv6 Addresses in URL's
|
||||
|
||||
RFC 2818 - HTTP Over TLS (TLS is the successor to SSL)
|
||||
|
||||
RFC 2821 - SMTP protocol
|
||||
|
||||
RFC 2964 - Use of HTTP State Management
|
||||
|
||||
RFC 2965 - HTTP State Management Mechanism. Cookies. Obsoletes RFC2109
|
||||
|
||||
RFC 3207 - SMTP over TLS
|
||||
|
||||
RFC 4616 - PLAIN authentication
|
||||
|
||||
RFC 4954 - SMTP Authentication
|
||||
116
third-party/curl-7.21.4/docs/SSLCERTS
vendored
Normal file
116
third-party/curl-7.21.4/docs/SSLCERTS
vendored
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
Peer SSL Certificate Verification
|
||||
=================================
|
||||
|
||||
libcurl performs peer SSL certificate verification by default. This is done
|
||||
by using CA cert bundle that the SSL library can use to make sure the peer's
|
||||
server certificate is valid.
|
||||
|
||||
If you communicate with HTTPS or FTPS servers using certificates that are
|
||||
signed by CAs present in the bundle, you can be sure that the remote server
|
||||
really is the one it claims to be.
|
||||
|
||||
Until 7.18.0, curl bundled a severely outdated ca bundle file that was
|
||||
installed by default. These days, the curl archives include no ca certs at
|
||||
all. You need to get them elsewhere. See below for example.
|
||||
|
||||
If the remote server uses a self-signed certificate, if you don't install a CA
|
||||
cert bundle, if the server uses a certificate signed by a CA that isn't
|
||||
included in the bundle you use or if the remote host is an impostor
|
||||
impersonating your favorite site, and you want to transfer files from this
|
||||
server, do one of the following:
|
||||
|
||||
1. Tell libcurl to *not* verify the peer. With libcurl you disable this with
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);
|
||||
|
||||
With the curl command line tool, you disable this with -k/--insecure.
|
||||
|
||||
2. Get a CA certificate that can verify the remote server and use the proper
|
||||
option to point out this CA cert for verification when connecting. For
|
||||
libcurl hackers: curl_easy_setopt(curl, CURLOPT_CAPATH, capath);
|
||||
|
||||
With the curl command line tool: --cacert [file]
|
||||
|
||||
3. Add the CA cert for your server to the existing default CA cert bundle.
|
||||
The default path of the CA bundle used can be changed by running configure
|
||||
with the --with-ca-bundle option pointing out the path of your choice.
|
||||
|
||||
To do this, you need to get the CA cert for your server in PEM format and
|
||||
then append that to your CA cert bundle.
|
||||
|
||||
If you use Internet Explorer, this is one way to get extract the CA cert
|
||||
for a particular server:
|
||||
|
||||
o View the certificate by double-clicking the padlock
|
||||
o Find out where the CA certificate is kept (Certificate>
|
||||
Authority Information Access>URL)
|
||||
o Get a copy of the crt file using curl
|
||||
o Convert it from crt to PEM using the openssl tool:
|
||||
openssl x509 -inform DES -in yourdownloaded.crt \
|
||||
-out outcert.pem -text
|
||||
o Append the 'outcert.pem' to the CA cert bundle or use it stand-alone
|
||||
as described below.
|
||||
|
||||
If you use the 'openssl' tool, this is one way to get extract the CA cert
|
||||
for a particular server:
|
||||
|
||||
o openssl s_client -connect xxxxx.com:443 |tee logfile
|
||||
o type "QUIT", followed by the "ENTER" key
|
||||
o The certificate will have "BEGIN CERTIFICATE" and "END CERTIFICATE"
|
||||
markers.
|
||||
o If you want to see the data in the certificate, you can do: "openssl
|
||||
x509 -inform PEM -in certfile -text -out certdata" where certfile is
|
||||
the cert you extracted from logfile. Look in certdata.
|
||||
o If you want to trust the certificate, you can append it to your
|
||||
cert_bundle or use it stand-alone as described. Just remember that the
|
||||
security is no better than the way you obtained the certificate.
|
||||
|
||||
4. If you're using the curl command line tool, you can specify your own CA
|
||||
cert path by setting the environment variable CURL_CA_BUNDLE to the path
|
||||
of your choice.
|
||||
|
||||
If you're using the curl command line tool on Windows, curl will search
|
||||
for a CA cert file named "curl-ca-bundle.crt" in these directories and in
|
||||
this order:
|
||||
1. application's directory
|
||||
2. current working directory
|
||||
3. Windows System directory (e.g. C:\windows\system32)
|
||||
4. Windows Directory (e.g. C:\windows)
|
||||
5. all directories along %PATH%
|
||||
|
||||
5. Get a better/different/newer CA cert bundle! One option is to extract the
|
||||
one a recent Firefox browser uses by running 'make ca-bundle' in the curl
|
||||
build tree root, or possibly download a version that was generated this
|
||||
way for you:
|
||||
|
||||
http://curl.haxx.se/docs/caextract.html
|
||||
|
||||
Neglecting to use one of the above methods when dealing with a server using a
|
||||
certificate that isn't signed by one of the certificates in the installed CA
|
||||
cert bundle, will cause SSL to report an error ("certificate verify failed")
|
||||
during the handshake and SSL will then refuse further communication with that
|
||||
server.
|
||||
|
||||
Peer SSL Certificate Verification with NSS
|
||||
==========================================
|
||||
|
||||
If libcurl is build with NSS support then depending on the OS distribution it
|
||||
is probably required to take some additional steps to use the system-wide CA
|
||||
cert db. RedHat ships with an additional module libnsspem.so which enables NSS
|
||||
to read the OpenSSL PEM CA bundle. With OpenSuSE this lib is missing, and NSS
|
||||
can only work with its own internal formats. Also NSS got a new database
|
||||
format:
|
||||
https://wiki.mozilla.org/NSS_Shared_DB
|
||||
Starting with version 7.19.7 libcurl will check for the NSS version it runs,
|
||||
and add automatically the 'sql:' prefix to the certdb directory (either the
|
||||
hardcoded default /etc/pki/nssdb or the directory configured with SSL_DIR
|
||||
environment variable) if a version 3.12.0 or later is detected.
|
||||
To check which certdb format your distribution provides examine the default
|
||||
certdb location /etc/pki/nssdb; the new certdb format can be identified by
|
||||
the filenames cert9.db, key4.db, pkcs11.txt; filenames of older versions are
|
||||
cert8.db, key3.db, modsec.db.
|
||||
Usually these cert databases are empty; but NSS also has built-in CAs which are
|
||||
provided through a shared library libnssckbi.so; if you want to use these
|
||||
built-in CAs then create a symlink to libnssckbi.so in /etc/pki/nssdb:
|
||||
ln -s /usr/lib[64]/libnssckbi.so /etc/pki/nssdb/libnssckbi.so
|
||||
|
||||
|
||||
840
third-party/curl-7.21.4/docs/THANKS
vendored
Normal file
840
third-party/curl-7.21.4/docs/THANKS
vendored
Normal file
|
|
@ -0,0 +1,840 @@
|
|||
This project has been alive for many years. Countless people have provided
|
||||
feedback that have improved curl. Here follows a list of people that have
|
||||
contributed (a-z order).
|
||||
|
||||
If you have contributed but are missing here, please let us know!
|
||||
|
||||
Aaron Oneal
|
||||
Adam D. Moss
|
||||
Adam Light
|
||||
Adam Piggott
|
||||
Adrian Schuur
|
||||
Akos Pasztory
|
||||
Alan Pinstein
|
||||
Albert Chin-A-Young
|
||||
Albert Choy
|
||||
Ale Vesely
|
||||
Aleksandar Milivojevic
|
||||
Alessandro Vesely
|
||||
Alex Bligh
|
||||
Alex Fishman
|
||||
Alex Neblett
|
||||
Alex Suykov
|
||||
Alex aka WindEagle
|
||||
Alexander Beedie
|
||||
Alexander Kourakos
|
||||
Alexander Krasnostavsky
|
||||
Alexander Lazic
|
||||
Alexander Zhuravlev
|
||||
Alexey Borzov
|
||||
Alexey Pesternikov
|
||||
Alexey Simak
|
||||
Alexis Carvalho
|
||||
Alfred Gebert
|
||||
Allen Pulsifer
|
||||
Amol Pattekar
|
||||
Anatoli Tubman
|
||||
Anders Gustafsson
|
||||
Andi Jahja
|
||||
Andre Guibert de Bruet
|
||||
Andreas Damm
|
||||
Andreas Faerber
|
||||
Andreas Farber
|
||||
Andreas Ntaflos
|
||||
Andreas Olsson
|
||||
Andreas Rieke
|
||||
Andreas Schuldei
|
||||
Andreas Wurf
|
||||
Andrei Benea
|
||||
Andres Garcia
|
||||
Andrew Benham
|
||||
Andrew Biggs
|
||||
Andrew Bushnell
|
||||
Andrew Francis
|
||||
Andrew Fuller
|
||||
Andrew Moise
|
||||
Andrew Wansink
|
||||
Andrew de los Reyes
|
||||
Andrés García
|
||||
Andy Cedilnik
|
||||
Andy Serpa
|
||||
Andy Tsouladze
|
||||
Angus Mackay
|
||||
Anthony Bryan
|
||||
Antoine Calando
|
||||
Anton Kalmykov
|
||||
Arkadiusz Miskiewicz
|
||||
Armel Asselin
|
||||
Arnaud Ebalard
|
||||
Arve Knudsen
|
||||
Ates Goral
|
||||
Augustus Saunders
|
||||
Avery Fay
|
||||
Axel Tillequin
|
||||
Balint Szilakszi
|
||||
Bart Whiteley
|
||||
Bas Mevissen
|
||||
Ben Darnell
|
||||
Ben Greear
|
||||
Ben Madsen
|
||||
Ben Van Hof
|
||||
Benbuck Nason
|
||||
Benjamin Gerard
|
||||
Bernard Leak
|
||||
Bertrand Demiddelaer
|
||||
Bill Egert
|
||||
Bill Hoffman
|
||||
Bjorn Augustsson
|
||||
Bjorn Reese
|
||||
Björn Stenberg
|
||||
Bob Richmond
|
||||
Bob Schader
|
||||
Bogdan Nicula
|
||||
Brad Burdick
|
||||
Bradford Bruce
|
||||
Brendan Jurd
|
||||
Brent Beardsley
|
||||
Brian Akins
|
||||
Brian Dessent
|
||||
Brian J. Murrell
|
||||
Brian R Duffy
|
||||
Brian Ulm
|
||||
Brock Noland
|
||||
Bruce Mitchener
|
||||
Bryan Henderson
|
||||
Bryan Kemp
|
||||
Cameron Kaiser
|
||||
Camille Moncelier
|
||||
Caolan McNamara
|
||||
Carsten Lange
|
||||
Casey O'Donnell
|
||||
Chad Monroe
|
||||
Charles Kerr
|
||||
Chih-Chung Chang
|
||||
Chris "Bob Bob"
|
||||
Chris Combes
|
||||
Chris Conroy
|
||||
Chris Deidun
|
||||
Chris Flerackers
|
||||
Chris Gaukroger
|
||||
Chris Maltby
|
||||
Chris Mumford
|
||||
Christian Krause
|
||||
Christian Kurz
|
||||
Christian Robottom Reis
|
||||
Christian Schmitz
|
||||
Christian Vogt
|
||||
Christophe Demory
|
||||
Christophe Legry
|
||||
Christopher Conroy
|
||||
Christopher Palow
|
||||
Christopher R. Palmer
|
||||
Ciprian Badescu
|
||||
Claes Jakobsson
|
||||
Clarence Gardner
|
||||
Clifford Wolf
|
||||
Cody Jones
|
||||
Colin Hogben
|
||||
Colin Watson
|
||||
Colm Buckley
|
||||
Constantine Sapuntzakis
|
||||
Cory Nelson
|
||||
Craig A West
|
||||
Craig Davison
|
||||
Craig Markwardt
|
||||
Cris Bailiff
|
||||
Curt Bogmine
|
||||
Cyrill Osterwalder
|
||||
Damien Adant
|
||||
Dan Becker
|
||||
Dan C
|
||||
Dan Fandrich
|
||||
Dan Locks
|
||||
Dan Nelson
|
||||
Dan Petitt
|
||||
Dan Torop
|
||||
Dan Zitter
|
||||
Daniel Black
|
||||
Daniel Cater
|
||||
Daniel Egger
|
||||
Daniel Fandrich
|
||||
Daniel Johnson
|
||||
Daniel Steinberg
|
||||
Daniel Stenberg
|
||||
Daniel at touchtunes
|
||||
Darryl House
|
||||
Dave Dribin
|
||||
Dave Halbakken
|
||||
Dave Hamilton
|
||||
Dave May
|
||||
Dave Vasilevsky
|
||||
David Bau
|
||||
David Binderman
|
||||
David Byron
|
||||
David Cohen
|
||||
David Eriksson
|
||||
David Houlder
|
||||
David Hull
|
||||
David J Meyer
|
||||
David James
|
||||
David Kierznowski
|
||||
David Kimdon
|
||||
David Lang
|
||||
David LeBlanc
|
||||
David McCreedy
|
||||
David Odin
|
||||
David Phillips
|
||||
David Rosenstrauch
|
||||
David Shaw
|
||||
David Tarendash
|
||||
David Thiel
|
||||
David Wright
|
||||
David Yan
|
||||
Dengminwen
|
||||
Detlef Schmier
|
||||
Didier Brisebourg
|
||||
Diego Casorran
|
||||
Dima Barsky
|
||||
Dimitre Dimitrov
|
||||
Dimitris Sarris
|
||||
Dinar
|
||||
Dirk Eddelbuettel
|
||||
Dirk Manske
|
||||
Dmitri Shubin
|
||||
Dmitriy Sergeyev
|
||||
Dmitry Bartsevich
|
||||
Dmitry Kurochkin
|
||||
Dmitry Popov
|
||||
Dmitry Rechkin
|
||||
Dolbneff A.V
|
||||
Domenico Andreoli
|
||||
Dominick Meglio
|
||||
Doug Kaufman
|
||||
Doug Porter
|
||||
Douglas E. Wegscheid
|
||||
Douglas Kilpatrick
|
||||
Douglas R. Horner
|
||||
Douglas Steinwand
|
||||
Dov Murik
|
||||
Duane Cathey
|
||||
Duncan Mac-Vicar Prett
|
||||
Dustin Boswell
|
||||
Dylan Ellicott
|
||||
Dylan Salisbury
|
||||
Early Ehlinger
|
||||
Ebenezer Ikonne
|
||||
Edin Kadribasic
|
||||
Eduard Bloch
|
||||
Eetu Ojanen
|
||||
Ellis Pritchard
|
||||
Emanuele Bovisio
|
||||
Emil Romanus
|
||||
Emiliano Ida
|
||||
Enrico Scholz
|
||||
Enrik Berkhan
|
||||
Eric Cooper
|
||||
Eric Landes
|
||||
Eric Lavigne
|
||||
Eric Melville
|
||||
Eric Mertens
|
||||
Eric Rautman
|
||||
Eric Thelin
|
||||
Eric Vergnaud
|
||||
Eric Wong
|
||||
Eric Young
|
||||
Erick Nuwendam
|
||||
Erwan Legrand
|
||||
Erwin Authried
|
||||
Eugene Kotlyarov
|
||||
Evan Jordan
|
||||
Eygene Ryabinkin
|
||||
Fabian Keil
|
||||
Fabrizio Ammollo
|
||||
Fedor Karpelevitch
|
||||
Felix von Leitner
|
||||
Feng Tu
|
||||
Florian Schoppmann
|
||||
Forrest Cahoon
|
||||
Frank Hempel
|
||||
Frank Keeney
|
||||
Frank McGeough
|
||||
Frank Meier
|
||||
Frank Ticheler
|
||||
Fred Machado
|
||||
Fred New
|
||||
Fred Noz
|
||||
Frederic Lepied
|
||||
Gabriel Kuri
|
||||
Gary Maxwell
|
||||
Gautam Kachroo
|
||||
Gautam Mani
|
||||
Gavrie Philipson
|
||||
Gaz Iqbal
|
||||
Georg Horn
|
||||
Georg Huettenegger
|
||||
Georg Lippitsch
|
||||
Georg Wicherski
|
||||
Gerd v. Egidy
|
||||
Gerhard Herre
|
||||
Gerrit Bruchhäuser
|
||||
Giancarlo Formicuccia
|
||||
Giaslas Georgios
|
||||
Gil Weber
|
||||
Gilad
|
||||
Gilbert Ramirez Jr.
|
||||
Gilles Blanc
|
||||
Gisle Vanem
|
||||
Giuseppe Attardi
|
||||
Giuseppe D'Ambrosio
|
||||
Glen Nakamura
|
||||
Glen Scott
|
||||
Grant Erickson
|
||||
Greg Hewgill
|
||||
Greg Morse
|
||||
Greg Onufer
|
||||
Greg Zavertnik
|
||||
Grigory Entin
|
||||
Guenole Bescon
|
||||
Guenter Knauf
|
||||
Guillaume Arluison
|
||||
Gustaf Hui
|
||||
Gwenole Beauchesne
|
||||
Götz Babin-Ebell
|
||||
Hamish Mackenzie
|
||||
Hang Kin Lau
|
||||
Hanno Kranzhoff
|
||||
Hans Steegers
|
||||
Hans-Jurgen May
|
||||
Hardeep Singh
|
||||
Harshal Pradhan
|
||||
Hauke Duden
|
||||
Heikki Korpela
|
||||
Heinrich Ko
|
||||
Hendrik Visage
|
||||
Henrik Storner
|
||||
Hidemoto Nakada
|
||||
Hoi-Ho Chan
|
||||
Hongli Lai
|
||||
Howard Chu
|
||||
Hzhijun
|
||||
Ian Ford
|
||||
Ian Gulliver
|
||||
Ian Lynagh
|
||||
Ian Turner
|
||||
Ian Wilkes
|
||||
Ignacio Vazquez-Abrams
|
||||
Igor Franchuk
|
||||
Igor Novoseltsev
|
||||
Igor Polyakov
|
||||
Ilguiz Latypov
|
||||
Ilja van Sprundel
|
||||
Immanuel Gregoire
|
||||
Ingmar Runge
|
||||
Ingo Ralf Blum
|
||||
Ingo Wilken
|
||||
Jack Zhang
|
||||
Jacky Lam
|
||||
Jacob Meuser
|
||||
Jacob Moshenko
|
||||
Jad Chamcham
|
||||
James Bursa
|
||||
James Cheng
|
||||
James Clancy
|
||||
James Cone
|
||||
James Gallagher
|
||||
James Griffiths
|
||||
James Housley
|
||||
James MacMillan
|
||||
Jamie Lokier
|
||||
Jamie Newton
|
||||
Jamie Wilkinson
|
||||
Jan Kunder
|
||||
Jan Van Boghout
|
||||
Jared Lundell
|
||||
Jari Sundell
|
||||
Jason McDonald
|
||||
Jason S. Priebe
|
||||
Jay Austin
|
||||
Jayesh A Shah
|
||||
Jaz Fresh
|
||||
Jean Jacques Drouin
|
||||
Jean-Claude Chauve
|
||||
Jean-Francois Bertrand
|
||||
Jean-Louis Lemaire
|
||||
Jean-Marc Ranger
|
||||
Jean-Philippe Barrette-LaPierre
|
||||
Jeff Johnson
|
||||
Jeff Lawson
|
||||
Jeff Phillips
|
||||
Jeff Pohlmeyer
|
||||
Jeff Weber
|
||||
Jeffrey Pohlmeyer
|
||||
Jeremy Friesner
|
||||
Jerome Muffat-Meridol
|
||||
Jerome Vouillon
|
||||
Jes Badwal
|
||||
Jesper Jensen
|
||||
Jesse Noller
|
||||
Jim Drash
|
||||
Jim Freeman
|
||||
Jim Meyering
|
||||
Jocelyn Jaubert
|
||||
Joe Halpin
|
||||
Joe Malicki
|
||||
Joel Chen
|
||||
Jofell Gallardo
|
||||
Johan Anderson
|
||||
Johan Nilsson
|
||||
Johan van Selst
|
||||
John Crow
|
||||
John Dennis
|
||||
John E. Malmberg
|
||||
John Janssen
|
||||
John Kelly
|
||||
John Lask
|
||||
John Lightsey
|
||||
John McGowan
|
||||
John P. McCaskey
|
||||
John Wilkinson
|
||||
John-Mark Bell
|
||||
Johnny Luong
|
||||
Jon Grubbs
|
||||
Jon Nelson
|
||||
Jon Sargeant
|
||||
Jon Travis
|
||||
Jon Turner
|
||||
Jonas Forsman
|
||||
Jonatan Lander
|
||||
Jonathan Hseu
|
||||
Jongki Suwandi
|
||||
Jose Kahan
|
||||
Josef Wolf
|
||||
Josh Kapell
|
||||
Joshua Kwan
|
||||
Juan F. Codagnone
|
||||
Juan Ignacio Hervás
|
||||
Judson Bishop
|
||||
Juergen Wilke
|
||||
Jukka Pihl
|
||||
Julian Noble
|
||||
Julien Chaffraix
|
||||
Jun-ichiro itojun Hagino
|
||||
Jurij Smakov
|
||||
Justin Fletcher
|
||||
Jörg Mueller-Tolk
|
||||
Jörn Hartroth
|
||||
Kai Sommerfeld
|
||||
Kai-Uwe Rommel
|
||||
Kalle Vahlman
|
||||
Kamil Dudka
|
||||
Kang-Jin Lee
|
||||
Karl Moerder
|
||||
Karol Pietrzak
|
||||
Kaspar Brand
|
||||
Katie Wang
|
||||
Kees Cook
|
||||
Keith MacDonald
|
||||
Keith McGuigan
|
||||
Keith Mok
|
||||
Ken Hirsch
|
||||
Ken Rastatter
|
||||
Kenny To
|
||||
Kent Boortz
|
||||
Keshav Krity
|
||||
Kevin Baughman
|
||||
Kevin Fisk
|
||||
Kevin Lussier
|
||||
Kevin Reed
|
||||
Kevin Roth
|
||||
Kim Rinnewitz
|
||||
Kimmo Kinnunen
|
||||
Kjell Ericson
|
||||
Kjetil Jacobsen
|
||||
Klevtsov Vadim
|
||||
Kris Kennaway
|
||||
Krishnendu Majumdar
|
||||
Krister Johansen
|
||||
Kristian Gunstone
|
||||
Kristian Köhntopp
|
||||
Kyle Sallee
|
||||
Lachlan O'Dea
|
||||
Larry Campbell
|
||||
Larry Fahnoe
|
||||
Lars Gustafsson
|
||||
Lars J. Aas
|
||||
Lars Nilsson
|
||||
Lars Torben Wilson
|
||||
Lau Hang Kin
|
||||
Laurent Rabret
|
||||
Legoff Vincent
|
||||
Lehel Bernadt
|
||||
Len Krause
|
||||
Lenaic Lefever
|
||||
Lenny Rachitsky
|
||||
Liam Healy
|
||||
Linas Vepstas
|
||||
Ling Thio
|
||||
Linus Nielsen Feltzing
|
||||
Lisa Xu
|
||||
Liza Alenchery
|
||||
Loic Dachary
|
||||
Loren Kirkby
|
||||
Luca Altea
|
||||
Luca Alteas
|
||||
Lucas Adamski
|
||||
Lukasz Czekierda
|
||||
Luke Call
|
||||
Luong Dinh Dung
|
||||
Maciej Karpiuk
|
||||
Maciej W. Rozycki
|
||||
Manfred Schwarb
|
||||
Marc Boucher
|
||||
Marc Kleine-Budde
|
||||
Marcelo Juchem
|
||||
Marcin Konicki
|
||||
Marco G. Salvagno
|
||||
Marco Maggi
|
||||
Marcus Webster
|
||||
Mario Schroeder
|
||||
Mark Butler
|
||||
Mark Davies
|
||||
Mark Eichin
|
||||
Mark Incley
|
||||
Mark Karpeles
|
||||
Mark Lentczner
|
||||
Markus Duft
|
||||
Markus Koetter
|
||||
Markus Moeller
|
||||
Markus Oberhumer
|
||||
Martijn Koster
|
||||
Martin C. Martin
|
||||
Martin Drasar
|
||||
Martin Hager
|
||||
Martin Hedenfalk
|
||||
Martin Skinner
|
||||
Martin Storsjo
|
||||
Marty Kuhrt
|
||||
Maruko
|
||||
Massimiliano Ziccardi
|
||||
Massimo Callegari
|
||||
Mateusz Loskot
|
||||
Mathias Axelsson
|
||||
Mats Lidell
|
||||
Matt Kraai
|
||||
Matt Veenstra
|
||||
Matt Witherspoon
|
||||
Matt Wixson
|
||||
Matthew Blain
|
||||
Matthew Clarke
|
||||
Matthias Bolte
|
||||
Maurice Barnum
|
||||
Mauro Iorio
|
||||
Max Katsev
|
||||
Maxim Ivanov
|
||||
Maxim Perenesenko
|
||||
Mekonikum
|
||||
Mettgut Jamalla
|
||||
Michael Benedict
|
||||
Michael Calmer
|
||||
Michael Cronenworth
|
||||
Michael Curtis
|
||||
Michael Goffioul
|
||||
Michael Jahn
|
||||
Michael Jerris
|
||||
Michael Mealling
|
||||
Michael Smith
|
||||
Michael Stillwell
|
||||
Michael Wallner
|
||||
Michal Bonino
|
||||
Michal Gorny
|
||||
Michal Marek
|
||||
Michele Bini
|
||||
Mihai Ionescu
|
||||
Mikael Johansson
|
||||
Mikael Sennerholm
|
||||
Mike Bytnar
|
||||
Mike Crowe
|
||||
Mike Dobbs
|
||||
Mike Hommey
|
||||
Mike Power
|
||||
Mike Protts
|
||||
Mike Revi
|
||||
Miklos Nemeth
|
||||
Mitz Wark
|
||||
Mohamed Lrhazi
|
||||
Mohun Biswas
|
||||
Moonesamy
|
||||
Nathan Coulter
|
||||
Nathan O'Sullivan
|
||||
Nathanael Nerode
|
||||
Naveen Noel
|
||||
Neil Dunbar
|
||||
Neil Spring
|
||||
Nic Roets
|
||||
Nick Gimbrone
|
||||
Nick Humfrey
|
||||
Nick Zitzmann
|
||||
Nico Baggus
|
||||
Nicolas Berloquin
|
||||
Nicolas Croiset
|
||||
Nicolas François
|
||||
Niels van Tongeren
|
||||
Nikita Schmidt
|
||||
Nikitinskit Dmitriy
|
||||
Niklas Angebrand
|
||||
Nikolai Kondrashov
|
||||
Ning Dong
|
||||
Nir Soffer
|
||||
Nis Jorgensen
|
||||
Nodak Sodak
|
||||
Norbert Frese
|
||||
Norbert Novotny
|
||||
Ofer
|
||||
Olaf Stueben
|
||||
Olaf Stüben
|
||||
Oren Tirosh
|
||||
P R Schaffner
|
||||
Pascal Terjan
|
||||
Pat Ray
|
||||
Patrick Bihan-Faou
|
||||
Patrick Monnerat
|
||||
Patrick Scott
|
||||
Patrick Smith
|
||||
Patrik Thunstrom
|
||||
Paul Harrington
|
||||
Paul Howarth
|
||||
Paul Marquis
|
||||
Paul Moore
|
||||
Paul Nolan
|
||||
Paul Querna
|
||||
Pavel Cenek
|
||||
Pavel Orehov
|
||||
Pavel Raiskup
|
||||
Pawel A. Gajda
|
||||
Pawel Kierski
|
||||
Pedro Neves
|
||||
Pete Su
|
||||
Peter Bray
|
||||
Peter Forret
|
||||
Peter Heuchert
|
||||
Peter Korsgaard
|
||||
Peter Lamberg
|
||||
Peter O'Gorman
|
||||
Peter Pentchev
|
||||
Peter Silva
|
||||
Peter Su
|
||||
Peter Sylvester
|
||||
Peter Todd
|
||||
Peter Verhas
|
||||
Peter Wullinger
|
||||
Peteris Krumins
|
||||
Phil Blundell
|
||||
Phil Karn
|
||||
Phil Lisiecki
|
||||
Phil Pellouchoud
|
||||
Philip Gladstone
|
||||
Philip Langdale
|
||||
Philippe Hameau
|
||||
Philippe Raoult
|
||||
Philippe Vaucher
|
||||
Pierre
|
||||
Pierre Brico
|
||||
Pierre Joye
|
||||
Pooyan McSporran
|
||||
Pramod Sharma
|
||||
Puneet Pawaia
|
||||
Quagmire
|
||||
Quanah Gibson-Mount
|
||||
Rafa Muyo
|
||||
Rafael Sagula
|
||||
Rainer Canavan
|
||||
Rainer Koenig
|
||||
Ralf S. Engelschall
|
||||
Ralph Beckmann
|
||||
Ralph Mitchell
|
||||
Ramana Mokkapati
|
||||
Randy McMurchy
|
||||
Ravi Pratap
|
||||
Ray Dassen
|
||||
Ray Pekowski
|
||||
Reinout van Schouwen
|
||||
Renato Botelho
|
||||
Renaud Chaillat
|
||||
Renaud Duhaut
|
||||
Rene Bernhardt
|
||||
Rene Rebe
|
||||
Reuven Wachtfogel
|
||||
Ricardo Cadime
|
||||
Rich Gray
|
||||
Rich Rauenzahn
|
||||
Richard Archer
|
||||
Richard Atterer
|
||||
Richard Bramante
|
||||
Richard Clayton
|
||||
Richard Cooper
|
||||
Richard Gorton
|
||||
Richard Prescott
|
||||
Rick Jones
|
||||
Rick Richardson
|
||||
Rob Crittenden
|
||||
Rob Jones
|
||||
Rob Stanzel
|
||||
Robert A. Monat
|
||||
Robert D. Young
|
||||
Robert Foreman
|
||||
Robert Iakobashvili
|
||||
Robert Olson
|
||||
Robert Weaver
|
||||
Robin Cornelius
|
||||
Robin Johnson
|
||||
Robin Kay
|
||||
Robson Braga Araujo
|
||||
Rodney Simmons
|
||||
Roland Blom
|
||||
Roland Krikava
|
||||
Roland Zimmermann
|
||||
Rolland Dudemaine
|
||||
Roman Koifman
|
||||
Ron Zapp
|
||||
Rosimildo da Silva
|
||||
Roy Shan
|
||||
Rune Kleveland
|
||||
Ruslan Gazizov
|
||||
Rutger Hofman
|
||||
Ryan Chan
|
||||
Ryan Nelson
|
||||
S. Moonesamy
|
||||
Salvador Dávila
|
||||
Salvatore Sorrentino
|
||||
Sam Listopad
|
||||
Sampo Kellomaki
|
||||
Samuel Díaz García
|
||||
Samuel Listopad
|
||||
Sander Gates
|
||||
Sandor Feldi
|
||||
Saul good
|
||||
Scott Barrett
|
||||
Scott Cantor
|
||||
Scott Davis
|
||||
Scott McCreary
|
||||
Sebastien Willemijns
|
||||
Senthil Raja Velu
|
||||
Sergio Ballestrero
|
||||
Seshubabu Pasam
|
||||
Sh Diao
|
||||
Sharad Gupta
|
||||
Shard
|
||||
Shawn Poulson
|
||||
Shmulik Regev
|
||||
Siddhartha Prakash Jain
|
||||
Sidney San Martin
|
||||
Siegfried Gyuricsko
|
||||
Simon Dick
|
||||
Simon Josefsson
|
||||
Simon Liu
|
||||
Song Ma
|
||||
Sonia Subramanian
|
||||
Spacen Jasset
|
||||
Spiridonoff A.V
|
||||
Stadler Stephan
|
||||
Stan van de Burgt
|
||||
Stefan Esser
|
||||
Stefan Krause
|
||||
Stefan Teleman
|
||||
Stefan Tomanek
|
||||
Stefan Ulrich
|
||||
Stephan Bergmann
|
||||
Stephen Collyer
|
||||
Stephen Kick
|
||||
Stephen More
|
||||
Sterling Hughes
|
||||
Steve Green
|
||||
Steve Lhomme
|
||||
Steve Little
|
||||
Steve Marx
|
||||
Steve Oliphant
|
||||
Steve Roskowski
|
||||
Steven Bazyl
|
||||
Steven G. Johnson
|
||||
Steven M. Schweda
|
||||
Stoned Elipot
|
||||
Sven Anders
|
||||
Sven Neuhaus
|
||||
Sven Wegener
|
||||
Sébastien Willemijns
|
||||
T. Bharath
|
||||
T. Yamada
|
||||
Tanguy Fautre
|
||||
Temprimus
|
||||
Thomas J. Moore
|
||||
Thomas Klausner
|
||||
Thomas Lopatic
|
||||
Thomas Schwinge
|
||||
Thomas Tonino
|
||||
Tim Ansell
|
||||
Tim Baker
|
||||
Tim Bartley
|
||||
Tim Chen
|
||||
Tim Costello
|
||||
Tim Newsome
|
||||
Tim Sneddon
|
||||
Tobias Rundström
|
||||
Toby Peterson
|
||||
Todd Kulesza
|
||||
Todd Vierling
|
||||
Tom Benoist
|
||||
Tom Donovan
|
||||
Tom Lee
|
||||
Tom Mattison
|
||||
Tom Moers
|
||||
Tom Mueller
|
||||
Tom Regner
|
||||
Tom Zerucha
|
||||
Tomas Pospisek
|
||||
Tomas Szepe
|
||||
Tomasz Lacki
|
||||
Tommy Tam
|
||||
Ton Voon
|
||||
Toon Verwaest
|
||||
Tor Arntsen
|
||||
Torsten Foertsch
|
||||
Toshio Kuratomi
|
||||
Toshiyuki Maezawa
|
||||
Traian Nicolescu
|
||||
Troels Walsted Hansen
|
||||
Troy Engel
|
||||
Tupone Alfredo
|
||||
Ulf Härnhammar
|
||||
Ulrich Zadow
|
||||
Venkat Akella
|
||||
Victor Snezhko
|
||||
Vikram Saxena
|
||||
Vilmos Nebehaj
|
||||
Vincent Bronner
|
||||
Vincent Le Normand
|
||||
Vincent Penquerc'h
|
||||
Vincent Sanders
|
||||
Vlad Grachov
|
||||
Vlad Ureche
|
||||
Vladimir Lazarenko
|
||||
Vojtech Janota
|
||||
Vojtech Minarik
|
||||
Walter J. Mack
|
||||
Wayne Haigh
|
||||
Werner Koch
|
||||
Wesley Laxton
|
||||
Wesley Miaw
|
||||
Wez Furlong
|
||||
Wilfredo Sanchez
|
||||
Wojciech Zwiefka
|
||||
Xavier Bouchoux
|
||||
Yang Tse
|
||||
Yarram Sunil
|
||||
Yehoshua Hershberg
|
||||
Yuriy Sosov
|
||||
Yves Lejeune
|
||||
Zmey Petroff
|
||||
Zvi Har'El
|
||||
nk
|
||||
swalkaus at yahoo.com
|
||||
tommink[at]post.pl
|
||||
571
third-party/curl-7.21.4/docs/TODO
vendored
Normal file
571
third-party/curl-7.21.4/docs/TODO
vendored
Normal file
|
|
@ -0,0 +1,571 @@
|
|||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
Things that could be nice to do in the future
|
||||
|
||||
Things to do in project cURL. Please tell us what you think, contribute and
|
||||
send us patches that improve things!
|
||||
|
||||
All bugs documented in the KNOWN_BUGS document are subject for fixing!
|
||||
|
||||
1. libcurl
|
||||
1.1 Zero-copy interface
|
||||
1.2 More data sharing
|
||||
1.3 struct lifreq
|
||||
1.4 signal-based resolver timeouts
|
||||
1.5 get rid of PATH_MAX
|
||||
|
||||
2. libcurl - multi interface
|
||||
2.1 More non-blocking
|
||||
2.2 Remove easy interface internally
|
||||
2.3 Avoid having to remove/readd handles
|
||||
2.4 Fix HTTP Pipelining for PUT
|
||||
|
||||
3. Documentation
|
||||
3.1 More and better
|
||||
|
||||
4. FTP
|
||||
4.1 HOST
|
||||
4.2 Alter passive/active on failure and retry
|
||||
4.3 Earlier bad letter detection
|
||||
4.4 REST for large files
|
||||
4.5 FTP proxy support
|
||||
4.6 ASCII support
|
||||
|
||||
5. HTTP
|
||||
5.1 Better persistency for HTTP 1.0
|
||||
5.2 support FF3 sqlite cookie files
|
||||
5.3 Rearrange request header order
|
||||
|
||||
6. TELNET
|
||||
6.1 ditch stdin
|
||||
6.2 ditch telnet-specific select
|
||||
6.3 feature negotiation debug data
|
||||
6.4 send data in chunks
|
||||
|
||||
7. SSL
|
||||
7.1 Disable specific versions
|
||||
7.2 Provide mutex locking API
|
||||
7.3 Evaluate SSL patches
|
||||
7.4 Cache OpenSSL contexts
|
||||
7.5 Export session ids
|
||||
7.6 Provide callback for cert verification
|
||||
7.7 Support other SSL libraries
|
||||
7.8 Support SRP on the TLS layer
|
||||
7.9 improve configure --with-ssl
|
||||
|
||||
8. GnuTLS
|
||||
8.1 SSL engine stuff
|
||||
8.2 SRP
|
||||
8.3 check connection
|
||||
8.4 non-gcrypt
|
||||
|
||||
9. Other protocols
|
||||
|
||||
10. New protocols
|
||||
10.1 RSYNC
|
||||
|
||||
11. Client
|
||||
11.1 sync
|
||||
11.2 glob posts
|
||||
11.3 prevent file overwriting
|
||||
11.4 simultaneous parallel transfers
|
||||
11.5 provide formpost headers
|
||||
11.6 url-specific options
|
||||
11.7 metalink support
|
||||
11.8 warning when setting an option
|
||||
|
||||
12. Build
|
||||
12.1 roffit
|
||||
|
||||
13. Test suite
|
||||
13.1 SSL tunnel
|
||||
13.2 nicer lacking perl message
|
||||
13.3 more protocols supported
|
||||
13.4 more platforms supported
|
||||
|
||||
14. Next SONAME bump
|
||||
14.1 http-style HEAD output for ftp
|
||||
14.2 combine error codes
|
||||
14.3 extend CURLOPT_SOCKOPTFUNCTION prototype
|
||||
|
||||
15. Next major release
|
||||
15.1 cleanup return codes
|
||||
15.2 remove obsolete defines
|
||||
15.3 size_t
|
||||
15.4 remove several functions
|
||||
15.5 remove CURLOPT_FAILONERROR
|
||||
15.6 remove CURLOPT_DNS_USE_GLOBAL_CACHE
|
||||
15.7 remove progress meter from libcurl
|
||||
|
||||
==============================================================================
|
||||
|
||||
1. libcurl
|
||||
|
||||
1.1 Zero-copy interface
|
||||
|
||||
Introduce another callback interface for upload/download that makes one less
|
||||
copy of data and thus a faster operation.
|
||||
[http://curl.haxx.se/dev/no_copy_callbacks.txt]
|
||||
|
||||
1.2 More data sharing
|
||||
|
||||
curl_share_* functions already exist and work, and they can be extended to
|
||||
share more. For example, enable sharing of the ares channel and the
|
||||
connection cache.
|
||||
|
||||
1.3 struct lifreq
|
||||
|
||||
Use 'struct lifreq' and SIOCGLIFADDR instead of 'struct ifreq' and
|
||||
SIOCGIFADDR on newer Solaris versions as they claim the latter is obsolete.
|
||||
To support ipv6 interface addresses for network interfaces properly.
|
||||
|
||||
1.4 signal-based resolver timeouts
|
||||
|
||||
libcurl built without an asynchronous resolver library uses alarm() to time
|
||||
out DNS lookups. When a timeout occurs, this causes libcurl to jump from the
|
||||
signal handler back into the library with a sigsetjmp, which effectively
|
||||
causes libcurl to continue running within the signal handler. This is
|
||||
non-portable and could cause problems on some platforms. A discussion on the
|
||||
problem is available at http://curl.haxx.se/mail/lib-2008-09/0197.html
|
||||
|
||||
Also, alarm() provides timeout resolution only to the nearest second. alarm
|
||||
ought to be replaced by setitimer on systems that support it.
|
||||
|
||||
1.5 get rid of PATH_MAX
|
||||
|
||||
Having code use and rely on PATH_MAX is not nice:
|
||||
http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
|
||||
|
||||
Currently the SSH based code uses it a bit, but to remove PATH_MAX from there
|
||||
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.
|
||||
|
||||
2. libcurl - multi interface
|
||||
|
||||
2.1 More non-blocking
|
||||
|
||||
Make sure we don't ever loop because of non-blocking sockets returning
|
||||
EWOULDBLOCK or similar. Blocking cases include:
|
||||
|
||||
- Name resolves on non-windows unless c-ares is used
|
||||
- NSS SSL connections
|
||||
- Active FTP connections
|
||||
- HTTP proxy CONNECT operations
|
||||
- SOCKS proxy handshakes
|
||||
- file:// transfers
|
||||
- TELNET transfers
|
||||
- The "DONE" operation (post transfer protocol-specific actions) for the
|
||||
protocols SFTP, SMTP, FTP. Fixing Curl_done() for this is a worthy task.
|
||||
|
||||
2.2 Remove easy interface internally
|
||||
|
||||
Make curl_easy_perform() a wrapper-function that simply creates a multi
|
||||
handle, adds the easy handle to it, runs curl_multi_perform() until the
|
||||
transfer is done, then detach the easy handle, destroy the multi handle and
|
||||
return the easy handle's return code. This will thus make everything
|
||||
internally use and assume the multi interface. The select()-loop should use
|
||||
curl_multi_socket().
|
||||
|
||||
2.3 Avoid having to remove/readd handles
|
||||
|
||||
curl_multi_handle_control() - this can control the easy handle (while) added
|
||||
to a multi handle in various ways:
|
||||
|
||||
o RESTART, unconditionally restart this easy handle's transfer from the
|
||||
start, re-init the state
|
||||
|
||||
o RESTART_COMPLETED, restart this easy handle's transfer but only if the
|
||||
existing transfer has already completed and it is in a "finished state".
|
||||
|
||||
o STOP, just stop this transfer and consider it completed
|
||||
|
||||
o PAUSE?
|
||||
|
||||
o RESUME?
|
||||
|
||||
2.4 Fix HTTP Pipelining for PUT
|
||||
|
||||
HTTP Pipelining can be a way to greatly enhance performance for multiple
|
||||
serial requests and currently libcurl only supports that for HEAD and GET
|
||||
requests but it should also be possible for PUT.
|
||||
|
||||
3. Documentation
|
||||
|
||||
3.1 More and better
|
||||
|
||||
Exactly
|
||||
|
||||
4. FTP
|
||||
|
||||
4.1 HOST
|
||||
|
||||
HOST is a suggested command in the works for a client to tell which host name
|
||||
to use, to offer FTP servers named-based virtual hosting:
|
||||
|
||||
http://tools.ietf.org/html/draft-hethmon-mcmurray-ftp-hosts-11
|
||||
|
||||
4.2 Alter passive/active on failure and retry
|
||||
|
||||
When trying to connect passively to a server which only supports active
|
||||
connections, libcurl returns CURLE_FTP_WEIRD_PASV_REPLY and closes the
|
||||
connection. There could be a way to fallback to an active connection (and
|
||||
vice versa). http://curl.haxx.se/bug/feature.cgi?id=1754793
|
||||
|
||||
4.3 Earlier bad letter detection
|
||||
|
||||
Make the detection of (bad) %0d and %0a codes in FTP url parts earlier in the
|
||||
process to avoid doing a resolve and connect in vain.
|
||||
|
||||
4.4 REST for large files
|
||||
|
||||
REST fix for servers not behaving well on >2GB requests. This should fail if
|
||||
the server doesn't set the pointer to the requested index. The tricky
|
||||
(impossible?) part is to figure out if the server did the right thing or not.
|
||||
|
||||
4.5 FTP proxy support
|
||||
|
||||
Support the most common FTP proxies, Philip Newton provided a list allegedly
|
||||
from ncftp. This is not a subject without debate, and is probably not really
|
||||
suitable for libcurl. http://curl.haxx.se/mail/archive-2003-04/0126.html
|
||||
|
||||
4.6 ASCII support
|
||||
|
||||
FTP ASCII transfers do not follow RFC959. They don't convert the data
|
||||
accordingly.
|
||||
|
||||
5. HTTP
|
||||
|
||||
5.1 Better persistency for HTTP 1.0
|
||||
|
||||
"Better" support for persistent connections over HTTP 1.0
|
||||
http://curl.haxx.se/bug/feature.cgi?id=1089001
|
||||
|
||||
5.2 support FF3 sqlite cookie files
|
||||
|
||||
Firefox 3 is changing from its former format to a a sqlite database instead.
|
||||
We should consider how (lib)curl can/should support this.
|
||||
http://curl.haxx.se/bug/feature.cgi?id=1871388
|
||||
|
||||
5.3 Rearrange request header order
|
||||
|
||||
Server implementors often make an effort to detect browser and to reject
|
||||
clients it can detect to not match. One of the last details we cannot yet
|
||||
control in libcurl's HTTP requests, which also can be exploited to detect
|
||||
that libcurl is in fact used even when it tries to impersonate a browser, is
|
||||
the order of the request headers. I propose that we introduce a new option in
|
||||
which you give headers a value, and then when the HTTP request is built it
|
||||
sorts the headers based on that number. We could then have internally created
|
||||
headers use a default value so only headers that need to be moved have to be
|
||||
specified.
|
||||
|
||||
|
||||
6. TELNET
|
||||
|
||||
6.1 ditch stdin
|
||||
|
||||
Reading input (to send to the remote server) on stdin is a crappy solution for
|
||||
library purposes. We need to invent a good way for the application to be able
|
||||
to provide the data to send.
|
||||
|
||||
6.2 ditch telnet-specific select
|
||||
|
||||
Move the telnet support's network select() loop go away and merge the code
|
||||
into the main transfer loop. Until this is done, the multi interface won't
|
||||
work for telnet.
|
||||
|
||||
6.3 feature negotiation debug data
|
||||
|
||||
Add telnet feature negotiation data to the debug callback as header data.
|
||||
|
||||
6.4 send data in chunks
|
||||
|
||||
Currently, telnet sends data one byte at a time. This is fine for interactive
|
||||
use, but inefficient for any other. Sent data should be sent in larger
|
||||
chunks.
|
||||
|
||||
7. SSL
|
||||
|
||||
7.1 Disable specific versions
|
||||
|
||||
Provide an option that allows for disabling specific SSL versions, such as
|
||||
SSLv2 http://curl.haxx.se/bug/feature.cgi?id=1767276
|
||||
|
||||
7.2 Provide mutex locking API
|
||||
|
||||
Provide a libcurl API for setting mutex callbacks in the underlying SSL
|
||||
library, so that the same application code can use mutex-locking
|
||||
independently of OpenSSL or GnutTLS being used.
|
||||
|
||||
7.3 Evaluate SSL patches
|
||||
|
||||
Evaluate/apply Gertjan van Wingerde's SSL patches:
|
||||
http://curl.haxx.se/mail/lib-2004-03/0087.html
|
||||
|
||||
7.4 Cache OpenSSL contexts
|
||||
|
||||
"Look at SSL cafile - quick traces look to me like these are done on every
|
||||
request as well, when they should only be necessary once per ssl context (or
|
||||
once per handle)". The major improvement we can rather easily do is to make
|
||||
sure we don't create and kill a new SSL "context" for every request, but
|
||||
instead make one for every connection and re-use that SSL context in the same
|
||||
style connections are re-used. It will make us use slightly more memory but
|
||||
it will libcurl do less creations and deletions of SSL contexts.
|
||||
|
||||
7.5 Export session ids
|
||||
|
||||
Add an interface to libcurl that enables "session IDs" to get
|
||||
exported/imported. Cris Bailiff said: "OpenSSL has functions which can
|
||||
serialise the current SSL state to a buffer of your choice, and recover/reset
|
||||
the state from such a buffer at a later date - this is used by mod_ssl for
|
||||
apache to implement and SSL session ID cache".
|
||||
|
||||
7.6 Provide callback for cert verification
|
||||
|
||||
OpenSSL supports a callback for customised verification of the peer
|
||||
certificate, but this doesn't seem to be exposed in the libcurl APIs. Could
|
||||
it be? There's so much that could be done if it were!
|
||||
|
||||
7.7 Support other SSL libraries
|
||||
|
||||
Make curl's SSL layer capable of using other free SSL libraries. Such as
|
||||
MatrixSSL (http://www.matrixssl.org/).
|
||||
|
||||
7.8 Support SRP on the TLS layer
|
||||
|
||||
Peter Sylvester's patch for SRP on the TLS layer. Awaits OpenSSL support for
|
||||
this, no need to support this in libcurl before there's an OpenSSL release
|
||||
that does it.
|
||||
|
||||
7.9 improve configure --with-ssl
|
||||
|
||||
make the configure --with-ssl option first check for OpenSSL, then GnuTLS,
|
||||
then NSS...
|
||||
|
||||
8. GnuTLS
|
||||
|
||||
8.1 SSL engine stuff
|
||||
|
||||
Is this even possible?
|
||||
|
||||
8.2 SRP
|
||||
|
||||
Work out a common method with Peter Sylvester's OpenSSL-patch for SRP on the
|
||||
TLS to provide name and password. GnuTLS already supports it...
|
||||
|
||||
8.3 check connection
|
||||
|
||||
Add a way to check if the connection seems to be alive, to correspond to the
|
||||
SSL_peak() way we use with OpenSSL.
|
||||
|
||||
8.4 non-gcrypt
|
||||
|
||||
libcurl assumes that there are gcrypt functions available when
|
||||
GnuTLS is.
|
||||
|
||||
GnuTLS can be built to use libnettle instead as crypto library,
|
||||
which breaks the previously mentioned assumption
|
||||
|
||||
The correct fix would be to detect which crypto layer that is in use and
|
||||
adapt our code to use that instead of blindly assuming gcrypt.
|
||||
|
||||
9. Other protocols
|
||||
|
||||
10. New protocols
|
||||
|
||||
10.1 RSYNC
|
||||
|
||||
There's no RFC for protocol nor URI/URL format. An implementation should
|
||||
most probably use an existing rsync library, such as librsync.
|
||||
|
||||
11. Client
|
||||
|
||||
11.1 sync
|
||||
|
||||
"curl --sync http://example.com/feed[1-100].rss" or
|
||||
"curl --sync http://example.net/{index,calendar,history}.html"
|
||||
|
||||
Downloads a range or set of URLs using the remote name, but only if the
|
||||
remote file is newer than the local file. A Last-Modified HTTP date header
|
||||
should also be used to set the mod date on the downloaded file.
|
||||
|
||||
11.2 glob posts
|
||||
|
||||
Globbing support for -d and -F, as in 'curl -d "name=foo[0-9]" URL'.
|
||||
This is easily scripted though.
|
||||
|
||||
11.3 prevent file overwriting
|
||||
|
||||
Add an option that prevents cURL from overwriting existing local files. When
|
||||
used, and there already is an existing file with the target file name
|
||||
(either -O or -o), a number should be appended (and increased if already
|
||||
existing). So that index.html becomes first index.html.1 and then
|
||||
index.html.2 etc.
|
||||
|
||||
11.4 simultaneous parallel transfers
|
||||
|
||||
The client could be told to use maximum N simultaneous parallel transfers and
|
||||
then just make sure that happens. It should of course not make more than one
|
||||
connection to the same remote host. This would require the client to use the
|
||||
multi interface. http://curl.haxx.se/bug/feature.cgi?id=1558595
|
||||
|
||||
11.5 provide formpost headers
|
||||
|
||||
Extending the capabilities of the multipart formposting. How about leaving
|
||||
the ';type=foo' syntax as it is and adding an extra tag (headers) which
|
||||
works like this: curl -F "coolfiles=@fil1.txt;headers=@fil1.hdr" where
|
||||
fil1.hdr contains extra headers like
|
||||
|
||||
Content-Type: text/plain; charset=KOI8-R"
|
||||
Content-Transfer-Encoding: base64
|
||||
X-User-Comment: Please don't use browser specific HTML code
|
||||
|
||||
which should overwrite the program reasonable defaults (plain/text,
|
||||
8bit...)
|
||||
|
||||
11.6 url-specific options
|
||||
|
||||
Provide a way to make options bound to a specific URL among several on the
|
||||
command line. Possibly by letting ':' separate options between URLs,
|
||||
similar to this:
|
||||
|
||||
curl --data foo --url url.com : \
|
||||
--url url2.com : \
|
||||
--url url3.com --data foo3
|
||||
|
||||
(More details: http://curl.haxx.se/mail/archive-2004-07/0133.html)
|
||||
|
||||
The example would do a POST-GET-POST combination on a single command line.
|
||||
|
||||
11.7 metalink support
|
||||
|
||||
Add metalink support to curl (http://www.metalinker.org/). This is most useful
|
||||
with simultaneous parallel transfers (11.6) but not necessary.
|
||||
|
||||
11.8 warning when setting an option
|
||||
|
||||
Display a warning when libcurl returns an error when setting an option.
|
||||
This can be useful to tell when support for a particular feature hasn't been
|
||||
compiled into the library.
|
||||
|
||||
12. Build
|
||||
|
||||
12.1 roffit
|
||||
|
||||
Consider extending 'roffit' to produce decent ASCII output, and use that
|
||||
instead of (g)nroff when building src/hugehelp.c
|
||||
|
||||
13. Test suite
|
||||
|
||||
13.1 SSL tunnel
|
||||
|
||||
Make our own version of stunnel for simple port forwarding to enable HTTPS
|
||||
and FTP-SSL tests without the stunnel dependency, and it could allow us to
|
||||
provide test tools built with either OpenSSL or GnuTLS
|
||||
|
||||
13.2 nicer lacking perl message
|
||||
|
||||
If perl wasn't found by the configure script, don't attempt to run the tests
|
||||
but explain something nice why it doesn't.
|
||||
|
||||
13.3 more protocols supported
|
||||
|
||||
Extend the test suite to include more protocols. The telnet could just do ftp
|
||||
or http operations (for which we have test servers).
|
||||
|
||||
13.4 more platforms supported
|
||||
|
||||
Make the test suite work on more platforms. OpenBSD and Mac OS. Remove
|
||||
fork()s and it should become even more portable.
|
||||
|
||||
14. Next SONAME bump
|
||||
|
||||
14.1 http-style HEAD output for ftp
|
||||
|
||||
#undef CURL_FTP_HTTPSTYLE_HEAD in lib/ftp.c to remove the HTTP-style headers
|
||||
from being output in NOBODY requests over ftp
|
||||
|
||||
14.2 combine error codes
|
||||
|
||||
Combine some of the error codes to remove duplicates. The original
|
||||
numbering should not be changed, and the old identifiers would be
|
||||
macroed to the new ones in an CURL_NO_OLDIES section to help with
|
||||
backward compatibility.
|
||||
|
||||
Candidates for removal and their replacements:
|
||||
|
||||
CURLE_FILE_COULDNT_READ_FILE => CURLE_REMOTE_FILE_NOT_FOUND
|
||||
CURLE_FTP_COULDNT_RETR_FILE => CURLE_REMOTE_FILE_NOT_FOUND
|
||||
CURLE_FTP_COULDNT_USE_REST => CURLE_RANGE_ERROR
|
||||
CURLE_FUNCTION_NOT_FOUND => CURLE_FAILED_INIT
|
||||
CURLE_LDAP_INVALID_URL => CURLE_URL_MALFORMAT
|
||||
CURLE_TFTP_NOSUCHUSER => CURLE_TFTP_ILLEGAL
|
||||
CURLE_TFTP_NOTFOUND => CURLE_REMOTE_FILE_NOT_FOUND
|
||||
CURLE_TFTP_PERM => CURLE_REMOTE_ACCESS_DENIED
|
||||
|
||||
14.3 extend CURLOPT_SOCKOPTFUNCTION prototype
|
||||
|
||||
The current prototype only provides 'purpose' that tells what the
|
||||
connection/socket is for, but not any protocol or similar. It makes it hard
|
||||
for applications to differentiate on TCP vs UDP and even HTTP vs FTP and
|
||||
similar.
|
||||
|
||||
15. Next major release
|
||||
|
||||
15.1 cleanup return codes
|
||||
|
||||
curl_easy_cleanup() returns void, but curl_multi_cleanup() returns a
|
||||
CURLMcode. These should be changed to be the same.
|
||||
|
||||
15.2 remove obsolete defines
|
||||
|
||||
remove obsolete defines from curl/curl.h
|
||||
|
||||
15.3 size_t
|
||||
|
||||
make several functions use size_t instead of int in their APIs
|
||||
|
||||
15.4 remove several functions
|
||||
|
||||
remove the following functions from the public API:
|
||||
|
||||
curl_getenv
|
||||
|
||||
curl_mprintf (and variations)
|
||||
|
||||
curl_strequal
|
||||
|
||||
curl_strnequal
|
||||
|
||||
They will instead become curlx_ - alternatives. That makes the curl app
|
||||
still capable of using them, by building with them from source.
|
||||
|
||||
These functions have no purpose anymore:
|
||||
|
||||
curl_multi_socket
|
||||
|
||||
curl_multi_socket_all
|
||||
|
||||
15.5 remove CURLOPT_FAILONERROR
|
||||
|
||||
Remove support for CURLOPT_FAILONERROR, it has gotten too kludgy and weird
|
||||
internally. Let the app judge success or not for itself.
|
||||
|
||||
15.6 remove CURLOPT_DNS_USE_GLOBAL_CACHE
|
||||
|
||||
Remove support for a global DNS cache. Anything global is silly, and we
|
||||
already offer the share interface for the same functionality but done
|
||||
"right".
|
||||
|
||||
15.7 remove progress meter from libcurl
|
||||
|
||||
The internally provided progress meter output doesn't belong in the library.
|
||||
Basically no application wants it (apart from curl) but instead applications
|
||||
can and should do their own progress meters using the progress callback.
|
||||
|
||||
The progress callback should then be bumped as well to get proper 64bit
|
||||
variable types passed to it instead of doubles so that big files work
|
||||
correctly.
|
||||
507
third-party/curl-7.21.4/docs/TheArtOfHttpScripting
vendored
Normal file
507
third-party/curl-7.21.4/docs/TheArtOfHttpScripting
vendored
Normal file
|
|
@ -0,0 +1,507 @@
|
|||
Online: http://curl.haxx.se/docs/httpscripting.html
|
||||
Date: Jan 19, 2011
|
||||
|
||||
The Art Of Scripting HTTP Requests Using Curl
|
||||
=============================================
|
||||
|
||||
This document will assume that you're familiar with HTML and general
|
||||
networking.
|
||||
|
||||
The possibility to write scripts is essential to make a good computer
|
||||
system. Unix' capability to be extended by shell scripts and various tools to
|
||||
run various automated commands and scripts is one reason why it has succeeded
|
||||
so well.
|
||||
|
||||
The increasing amount of applications moving to the web has made "HTTP
|
||||
Scripting" more frequently requested and wanted. To be able to automatically
|
||||
extract information from the web, to fake users, to post or upload data to
|
||||
web servers are all important tasks today.
|
||||
|
||||
Curl is a command line tool for doing all sorts of URL manipulations and
|
||||
transfers, but this particular document will focus on how to use it when
|
||||
doing HTTP requests for fun and profit. I'll assume that you know how to
|
||||
invoke 'curl --help' or 'curl --manual' to get basic information about it.
|
||||
|
||||
Curl is not written to do everything for you. It makes the requests, it gets
|
||||
the data, it sends data and it retrieves the information. You probably need
|
||||
to glue everything together using some kind of script language or repeated
|
||||
manual invokes.
|
||||
|
||||
1. The HTTP Protocol
|
||||
|
||||
HTTP is the protocol used to fetch data from web servers. It is a very simple
|
||||
protocol that is built upon TCP/IP. The protocol also allows information to
|
||||
get sent to the server from the client using a few different methods, as will
|
||||
be shown here.
|
||||
|
||||
HTTP is plain ASCII text lines being sent by the client to a server to
|
||||
request a particular action, and then the server replies a few text lines
|
||||
before the actual requested content is sent to the client.
|
||||
|
||||
The client, curl, sends a HTTP request. The request contains a method (like
|
||||
GET, POST, HEAD etc), a number of request headers and sometimes a request
|
||||
body. The HTTP server responds with a status line (indicating if things went
|
||||
well), response headers and most often also a response body. The "body" part
|
||||
is the plain data you requested, like the actual HTML or the image etc.
|
||||
|
||||
1.1 See the Protocol
|
||||
|
||||
Using curl's option --verbose (-v as a short option) will display what kind
|
||||
of commands curl sends to the server, as well as a few other informational
|
||||
texts.
|
||||
|
||||
--verbose is the single most useful option when it comes to debug or even
|
||||
understand the curl<->server interaction.
|
||||
|
||||
Sometimes even --verbose is not enough. Then --trace and --trace-ascii offer
|
||||
even more details as they show EVERYTHING curl sends and receives. Use it
|
||||
like this:
|
||||
|
||||
curl --trace-ascii debugdump.txt http://www.example.com/
|
||||
|
||||
2. URL
|
||||
|
||||
The Uniform Resource Locator format is how you specify the address of a
|
||||
particular resource on the Internet. You know these, you've seen URLs like
|
||||
http://curl.haxx.se or https://yourbank.com a million times.
|
||||
|
||||
3. GET a page
|
||||
|
||||
The simplest and most common request/operation made using HTTP is to get a
|
||||
URL. The URL could itself refer to a web page, an image or a file. The client
|
||||
issues a GET request to the server and receives the document it asked for.
|
||||
If you issue the command line
|
||||
|
||||
curl http://curl.haxx.se
|
||||
|
||||
you get a web page returned in your terminal window. The entire HTML document
|
||||
that that URL holds.
|
||||
|
||||
All HTTP replies contain a set of response headers that are normally hidden,
|
||||
use curl's --include (-i) option to display them as well as the rest of the
|
||||
document. You can also ask the remote server for ONLY the headers by using
|
||||
the --head (-I) option (which will make curl issue a HEAD request).
|
||||
|
||||
4. Forms
|
||||
|
||||
Forms are the general way a web site can present a HTML page with fields for
|
||||
the user to enter data in, and then press some kind of 'OK' or 'submit'
|
||||
button to get that data sent to the server. The server then typically uses
|
||||
the posted data to decide how to act. Like using the entered words to search
|
||||
in a database, or to add the info in a bug track system, display the entered
|
||||
address on a map or using the info as a login-prompt verifying that the user
|
||||
is allowed to see what it is about to see.
|
||||
|
||||
Of course there has to be some kind of program in the server end to receive
|
||||
the data you send. You cannot just invent something out of the air.
|
||||
|
||||
4.1 GET
|
||||
|
||||
A GET-form uses the method GET, as specified in HTML like:
|
||||
|
||||
<form method="GET" action="junk.cgi">
|
||||
<input type=text name="birthyear">
|
||||
<input type=submit name=press value="OK">
|
||||
</form>
|
||||
|
||||
In your favorite browser, this form will appear with a text box to fill in
|
||||
and a press-button labeled "OK". If you fill in '1905' and press the OK
|
||||
button, your browser will then create a new URL to get for you. The URL will
|
||||
get "junk.cgi?birthyear=1905&press=OK" appended to the path part of the
|
||||
previous URL.
|
||||
|
||||
If the original form was seen on the page "www.hotmail.com/when/birth.html",
|
||||
the second page you'll get will become
|
||||
"www.hotmail.com/when/junk.cgi?birthyear=1905&press=OK".
|
||||
|
||||
Most search engines work this way.
|
||||
|
||||
To make curl do the GET form post for you, just enter the expected created
|
||||
URL:
|
||||
|
||||
curl "http://www.hotmail.com/when/junk.cgi?birthyear=1905&press=OK"
|
||||
|
||||
4.2 POST
|
||||
|
||||
The GET method makes all input field names get displayed in the URL field of
|
||||
your browser. That's generally a good thing when you want to be able to
|
||||
bookmark that page with your given data, but it is an obvious disadvantage
|
||||
if you entered secret information in one of the fields or if there are a
|
||||
large amount of fields creating a very long and unreadable URL.
|
||||
|
||||
The HTTP protocol then offers the POST method. This way the client sends the
|
||||
data separated from the URL and thus you won't see any of it in the URL
|
||||
address field.
|
||||
|
||||
The form would look very similar to the previous one:
|
||||
|
||||
<form method="POST" action="junk.cgi">
|
||||
<input type=text name="birthyear">
|
||||
<input type=submit name=press value=" OK ">
|
||||
</form>
|
||||
|
||||
And to use curl to post this form with the same data filled in as before, we
|
||||
could do it like:
|
||||
|
||||
curl --data "birthyear=1905&press=%20OK%20" \
|
||||
http://www.example.com/when.cgi
|
||||
|
||||
This kind of POST will use the Content-Type
|
||||
application/x-www-form-urlencoded and is the most widely used POST kind.
|
||||
|
||||
The data you send to the server MUST already be properly encoded, curl will
|
||||
not do that for you. For example, if you want the data to contain a space,
|
||||
you need to replace that space with %20 etc. Failing to comply with this
|
||||
will most likely cause your data to be received wrongly and messed up.
|
||||
|
||||
Recent curl versions can in fact url-encode POST data for you, like this:
|
||||
|
||||
curl --data-urlencode "name=I am Daniel" http://www.example.com
|
||||
|
||||
4.3 File Upload POST
|
||||
|
||||
Back in late 1995 they defined an additional way to post data over HTTP. It
|
||||
is documented in the RFC 1867, why this method sometimes is referred to as
|
||||
RFC1867-posting.
|
||||
|
||||
This method is mainly designed to better support file uploads. A form that
|
||||
allows a user to upload a file could be written like this in HTML:
|
||||
|
||||
<form method="POST" enctype='multipart/form-data' action="upload.cgi">
|
||||
<input type=file name=upload>
|
||||
<input type=submit name=press value="OK">
|
||||
</form>
|
||||
|
||||
This clearly shows that the Content-Type about to be sent is
|
||||
multipart/form-data.
|
||||
|
||||
To post to a form like this with curl, you enter a command line like:
|
||||
|
||||
curl --form upload=@localfilename --form press=OK [URL]
|
||||
|
||||
4.4 Hidden Fields
|
||||
|
||||
A very common way for HTML based application to pass state information
|
||||
between pages is to add hidden fields to the forms. Hidden fields are
|
||||
already filled in, they aren't displayed to the user and they get passed
|
||||
along just as all the other fields.
|
||||
|
||||
A similar example form with one visible field, one hidden field and one
|
||||
submit button could look like:
|
||||
|
||||
<form method="POST" action="foobar.cgi">
|
||||
<input type=text name="birthyear">
|
||||
<input type=hidden name="person" value="daniel">
|
||||
<input type=submit name="press" value="OK">
|
||||
</form>
|
||||
|
||||
To post this with curl, you won't have to think about if the fields are
|
||||
hidden or not. To curl they're all the same:
|
||||
|
||||
curl --data "birthyear=1905&press=OK&person=daniel" [URL]
|
||||
|
||||
4.5 Figure Out What A POST Looks Like
|
||||
|
||||
When you're about fill in a form and send to a server by using curl instead
|
||||
of a browser, you're of course very interested in sending a POST exactly the
|
||||
way your browser does.
|
||||
|
||||
An easy way to get to see this, is to save the HTML page with the form on
|
||||
your local disk, modify the 'method' to a GET, and press the submit button
|
||||
(you could also change the action URL if you want to).
|
||||
|
||||
You will then clearly see the data get appended to the URL, separated with a
|
||||
'?'-letter as GET forms are supposed to.
|
||||
|
||||
5. PUT
|
||||
|
||||
The perhaps best way to upload data to a HTTP server is to use PUT. Then
|
||||
again, this of course requires that someone put a program or script on the
|
||||
server end that knows how to receive a HTTP PUT stream.
|
||||
|
||||
Put a file to a HTTP server with curl:
|
||||
|
||||
curl --upload-file uploadfile http://www.example.com/receive.cgi
|
||||
|
||||
6. HTTP Authentication
|
||||
|
||||
HTTP Authentication is the ability to tell the server your username and
|
||||
password so that it can verify that you're allowed to do the request you're
|
||||
doing. The Basic authentication used in HTTP (which is the type curl uses by
|
||||
default) is *plain* *text* based, which means it sends username and password
|
||||
only slightly obfuscated, but still fully readable by anyone that sniffs on
|
||||
the network between you and the remote server.
|
||||
|
||||
To tell curl to use a user and password for authentication:
|
||||
|
||||
curl --user name:password http://www.example.com
|
||||
|
||||
The site might require a different authentication method (check the headers
|
||||
returned by the server), and then --ntlm, --digest, --negotiate or even
|
||||
--anyauth might be options that suit you.
|
||||
|
||||
Sometimes your HTTP access is only available through the use of a HTTP
|
||||
proxy. This seems to be especially common at various companies. A HTTP proxy
|
||||
may require its own user and password to allow the client to get through to
|
||||
the Internet. To specify those with curl, run something like:
|
||||
|
||||
curl --proxy-user proxyuser:proxypassword curl.haxx.se
|
||||
|
||||
If your proxy requires the authentication to be done using the NTLM method,
|
||||
use --proxy-ntlm, if it requires Digest use --proxy-digest.
|
||||
|
||||
If you use any one these user+password options but leave out the password
|
||||
part, curl will prompt for the password interactively.
|
||||
|
||||
Do note that when a program is run, its parameters might be possible to see
|
||||
when listing the running processes of the system. Thus, other users may be
|
||||
able to watch your passwords if you pass them as plain command line
|
||||
options. There are ways to circumvent this.
|
||||
|
||||
It is worth noting that while this is how HTTP Authentication works, very
|
||||
many web sites will not use this concept when they provide logins etc. See
|
||||
the Web Login chapter further below for more details on that.
|
||||
|
||||
7. Referer
|
||||
|
||||
A HTTP request may include a 'referer' field (yes it is misspelled), which
|
||||
can be used to tell from which URL the client got to this particular
|
||||
resource. Some programs/scripts check the referer field of requests to verify
|
||||
that this wasn't arriving from an external site or an unknown page. While
|
||||
this is a stupid way to check something so easily forged, many scripts still
|
||||
do it. Using curl, you can put anything you want in the referer-field and
|
||||
thus more easily be able to fool the server into serving your request.
|
||||
|
||||
Use curl to set the referer field with:
|
||||
|
||||
curl --referer http://www.example.come http://www.example.com
|
||||
|
||||
8. User Agent
|
||||
|
||||
Very similar to the referer field, all HTTP requests may set the User-Agent
|
||||
field. It names what user agent (client) that is being used. Many
|
||||
applications use this information to decide how to display pages. Silly web
|
||||
programmers try to make different pages for users of different browsers to
|
||||
make them look the best possible for their particular browsers. They usually
|
||||
also do different kinds of javascript, vbscript etc.
|
||||
|
||||
At times, you will see that getting a page with curl will not return the same
|
||||
page that you see when getting the page with your browser. Then you know it
|
||||
is time to set the User Agent field to fool the server into thinking you're
|
||||
one of those browsers.
|
||||
|
||||
To make curl look like Internet Explorer 5 on a Windows 2000 box:
|
||||
|
||||
curl --user-agent "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)" [URL]
|
||||
|
||||
Or why not look like you're using Netscape 4.73 on an old Linux box:
|
||||
|
||||
curl --user-agent "Mozilla/4.73 [en] (X11; U; Linux 2.2.15 i686)" [URL]
|
||||
|
||||
9. Redirects
|
||||
|
||||
When a resource is requested from a server, the reply from the server may
|
||||
include a hint about where the browser should go next to find this page, or a
|
||||
new page keeping newly generated output. The header that tells the browser
|
||||
to redirect is Location:.
|
||||
|
||||
Curl does not follow Location: headers by default, but will simply display
|
||||
such pages in the same manner it display all HTTP replies. It does however
|
||||
feature an option that will make it attempt to follow the Location: pointers.
|
||||
|
||||
To tell curl to follow a Location:
|
||||
|
||||
curl --location http://www.example.com
|
||||
|
||||
If you use curl to POST to a site that immediately redirects you to another
|
||||
page, you can safely use --location (-L) and --data/--form together. Curl will
|
||||
only use POST in the first request, and then revert to GET in the following
|
||||
operations.
|
||||
|
||||
10. Cookies
|
||||
|
||||
The way the web browsers do "client side state control" is by using
|
||||
cookies. Cookies are just names with associated contents. The cookies are
|
||||
sent to the client by the server. The server tells the client for what path
|
||||
and host name it wants the cookie sent back, and it also sends an expiration
|
||||
date and a few more properties.
|
||||
|
||||
When a client communicates with a server with a name and path as previously
|
||||
specified in a received cookie, the client sends back the cookies and their
|
||||
contents to the server, unless of course they are expired.
|
||||
|
||||
Many applications and servers use this method to connect a series of requests
|
||||
into a single logical session. To be able to use curl in such occasions, we
|
||||
must be able to record and send back cookies the way the web application
|
||||
expects them. The same way browsers deal with them.
|
||||
|
||||
The simplest way to send a few cookies to the server when getting a page with
|
||||
curl is to add them on the command line like:
|
||||
|
||||
curl --cookie "name=Daniel" http://www.example.com
|
||||
|
||||
Cookies are sent as common HTTP headers. This is practical as it allows curl
|
||||
to record cookies simply by recording headers. Record cookies with curl by
|
||||
using the --dump-header (-D) option like:
|
||||
|
||||
curl --dump-header headers_and_cookies http://www.example.com
|
||||
|
||||
(Take note that the --cookie-jar option described below is a better way to
|
||||
store cookies.)
|
||||
|
||||
Curl has a full blown cookie parsing engine built-in that comes to use if you
|
||||
want to reconnect to a server and use cookies that were stored from a
|
||||
previous connection (or handicrafted manually to fool the server into
|
||||
believing you had a previous connection). To use previously stored cookies,
|
||||
you run curl like:
|
||||
|
||||
curl --cookie stored_cookies_in_file http://www.example.com
|
||||
|
||||
Curl's "cookie engine" gets enabled when you use the --cookie option. If you
|
||||
only want curl to understand received cookies, use --cookie with a file that
|
||||
doesn't exist. Example, if you want to let curl understand cookies from a
|
||||
page and follow a location (and thus possibly send back cookies it received),
|
||||
you can invoke it like:
|
||||
|
||||
curl --cookie nada --location http://www.example.com
|
||||
|
||||
Curl has the ability to read and write cookie files that use the same file
|
||||
format that Netscape and Mozilla do. It is a convenient way to share cookies
|
||||
between browsers and automatic scripts. The --cookie (-b) switch
|
||||
automatically detects if a given file is such a cookie file and parses it,
|
||||
and by using the --cookie-jar (-c) option you'll make curl write a new cookie
|
||||
file at the end of an operation:
|
||||
|
||||
curl --cookie cookies.txt --cookie-jar newcookies.txt \
|
||||
http://www.example.com
|
||||
|
||||
11. HTTPS
|
||||
|
||||
There are a few ways to do secure HTTP transfers. The by far most common
|
||||
protocol for doing this is what is generally known as HTTPS, HTTP over
|
||||
SSL. SSL encrypts all the data that is sent and received over the network and
|
||||
thus makes it harder for attackers to spy on sensitive information.
|
||||
|
||||
SSL (or TLS as the latest version of the standard is called) offers a
|
||||
truckload of advanced features to allow all those encryptions and key
|
||||
infrastructure mechanisms encrypted HTTP requires.
|
||||
|
||||
Curl supports encrypted fetches thanks to the freely available OpenSSL
|
||||
libraries. To get a page from a HTTPS server, simply run curl like:
|
||||
|
||||
curl https://secure.example.com
|
||||
|
||||
11.1 Certificates
|
||||
|
||||
In the HTTPS world, you use certificates to validate that you are the one
|
||||
you claim to be, as an addition to normal passwords. Curl supports client-
|
||||
side certificates. All certificates are locked with a pass phrase, which you
|
||||
need to enter before the certificate can be used by curl. The pass phrase
|
||||
can be specified on the command line or if not, entered interactively when
|
||||
curl queries for it. Use a certificate with curl on a HTTPS server like:
|
||||
|
||||
curl --cert mycert.pem https://secure.example.com
|
||||
|
||||
curl also tries to verify that the server is who it claims to be, by
|
||||
verifying the server's certificate against a locally stored CA cert
|
||||
bundle. Failing the verification will cause curl to deny the connection. You
|
||||
must then use --insecure (-k) in case you want to tell curl to ignore that
|
||||
the server can't be verified.
|
||||
|
||||
More about server certificate verification and ca cert bundles can be read
|
||||
in the SSLCERTS document, available online here:
|
||||
|
||||
http://curl.haxx.se/docs/sslcerts.html
|
||||
|
||||
12. Custom Request Elements
|
||||
|
||||
Doing fancy stuff, you may need to add or change elements of a single curl
|
||||
request.
|
||||
|
||||
For example, you can change the POST request to a PROPFIND and send the data
|
||||
as "Content-Type: text/xml" (instead of the default Content-Type) like this:
|
||||
|
||||
curl --data "<xml>" --header "Content-Type: text/xml" \
|
||||
--request PROPFIND url.com
|
||||
|
||||
You can delete a default header by providing one without content. Like you
|
||||
can ruin the request by chopping off the Host: header:
|
||||
|
||||
curl --header "Host:" http://www.example.com
|
||||
|
||||
You can add headers the same way. Your server may want a "Destination:"
|
||||
header, and you can add it:
|
||||
|
||||
curl --header "Destination: http://nowhere" http://example.com
|
||||
|
||||
13. Web Login
|
||||
|
||||
While not strictly just HTTP related, it still cause a lot of people problems
|
||||
so here's the executive run-down of how the vast majority of all login forms
|
||||
work and how to login to them using curl.
|
||||
|
||||
It can also be noted that to do this properly in an automated fashion, you
|
||||
will most certainly need to script things and do multiple curl invokes etc.
|
||||
|
||||
First, servers mostly use cookies to track the logged-in status of the
|
||||
client, so you will need to capture the cookies you receive in the
|
||||
responses. Then, many sites also set a special cookie on the login page (to
|
||||
make sure you got there through their login page) so you should make a habit
|
||||
of first getting the login-form page to capture the cookies set there.
|
||||
|
||||
Some web-based login systems features various amounts of javascript, and
|
||||
sometimes they use such code to set or modify cookie contents. Possibly they
|
||||
do that to prevent programmed logins, like this manual describes how to...
|
||||
Anyway, if reading the code isn't enough to let you repeat the behavior
|
||||
manually, capturing the HTTP requests done by your browers and analyzing the
|
||||
sent cookies is usually a working method to work out how to shortcut the
|
||||
javascript need.
|
||||
|
||||
In the actual <form> tag for the login, lots of sites fill-in random/session
|
||||
or otherwise secretly generated hidden tags and you may need to first capture
|
||||
the HTML code for the login form and extract all the hidden fields to be able
|
||||
to do a proper login POST. Remember that the contents need to be URL encoded
|
||||
when sent in a normal POST.
|
||||
|
||||
14. Debug
|
||||
|
||||
Many times when you run curl on a site, you'll notice that the site doesn't
|
||||
seem to respond the same way to your curl requests as it does to your
|
||||
browser's.
|
||||
|
||||
Then you need to start making your curl requests more similar to your
|
||||
browser's requests:
|
||||
|
||||
* Use the --trace-ascii option to store fully detailed logs of the requests
|
||||
for easier analyzing and better understanding
|
||||
|
||||
* Make sure you check for and use cookies when needed (both reading with
|
||||
--cookie and writing with --cookie-jar)
|
||||
|
||||
* Set user-agent to one like a recent popular browser does
|
||||
|
||||
* Set referer like it is set by the browser
|
||||
|
||||
* If you use POST, make sure you send all the fields and in the same order as
|
||||
the browser does it. (See chapter 4.5 above)
|
||||
|
||||
A very good helper to make sure you do this right, is the LiveHTTPHeader tool
|
||||
that lets you view all headers you send and receive with Mozilla/Firefox
|
||||
(even when using HTTPS).
|
||||
|
||||
A more raw approach is to capture the HTTP traffic on the network with tools
|
||||
such as ethereal or tcpdump and check what headers that were sent and
|
||||
received by the browser. (HTTPS makes this technique inefficient.)
|
||||
|
||||
15. References
|
||||
|
||||
RFC 2616 is a must to read if you want in-depth understanding of the HTTP
|
||||
protocol.
|
||||
|
||||
RFC 3986 explains the URL syntax.
|
||||
|
||||
RFC 2109 defines how cookies are supposed to work.
|
||||
|
||||
RFC 1867 defines the HTTP post upload format.
|
||||
|
||||
http://curl.haxx.se is the home of the cURL project
|
||||
67
third-party/curl-7.21.4/docs/VERSIONS
vendored
Normal file
67
third-party/curl-7.21.4/docs/VERSIONS
vendored
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
Version Numbers and Releases
|
||||
|
||||
Curl is not only curl. Curl is also libcurl. They're actually individually
|
||||
versioned, but they mostly follow each other rather closely.
|
||||
|
||||
The version numbering is always built up using the same system:
|
||||
|
||||
X.Y[.Z][-preN]
|
||||
|
||||
Where
|
||||
X is main version number
|
||||
Y is release number
|
||||
Z is patch number
|
||||
N is pre-release number
|
||||
|
||||
One of these numbers will get bumped in each new release. The numbers to the
|
||||
right of a bumped number will be reset to zero. If Z is zero, it may not be
|
||||
included in the version number. The pre release number is only included in
|
||||
pre releases (they're never used in public, official, releases).
|
||||
|
||||
The main version number will get bumped when *really* big, world colliding
|
||||
changes are made. The release number is bumped when big changes are
|
||||
performed. The patch number is bumped when the changes are mere bugfixes and
|
||||
only minor feature changes. The pre-release is a counter, to identify which
|
||||
pre-release a certain release is.
|
||||
|
||||
When reaching the end of a pre-release period, the version without the
|
||||
pre-release part will be released as a public release.
|
||||
|
||||
It means that after release 1.2.3, we can release 2.0 if something really big
|
||||
has been made, 1.3 if not that big changes were made or 1.2.4 if mostly bugs
|
||||
were fixed. Before 1.2.4 is released, we might release a 1.2.4-pre1 release
|
||||
for the brave people to try before the actual release.
|
||||
|
||||
Bumping, as in increasing the number with 1, is unconditionally only
|
||||
affecting one of the numbers (except the ones to the right of it, that may be
|
||||
set to zero). 1 becomes 2, 3 becomes 4, 9 becomes 10, 88 becomes 89 and 99
|
||||
becomes 100. So, after 1.2.9 comes 1.2.10. After 3.99.3, 3.100 might come.
|
||||
|
||||
All original curl source release archives are named according to the libcurl
|
||||
version (not according to the curl client version that, as said before, might
|
||||
differ).
|
||||
|
||||
As a service to any application that might want to support new libcurl
|
||||
features while still being able to build with older versions, all releases
|
||||
have the libcurl version stored in the curl/curlver.h file using a static
|
||||
numbering scheme that can be used for comparison. The version number is
|
||||
defined as:
|
||||
|
||||
#define LIBCURL_VERSION_NUM 0xXXYYZZ
|
||||
|
||||
Where XX, YY and ZZ are the main version, release and patch numbers in
|
||||
hexadecimal. All three numbers are always represented using two digits. 1.2
|
||||
would appear as "0x010200" while version 9.11.7 appears as "0x090b07".
|
||||
|
||||
This 6-digit hexadecimal number does not show pre-release number, and it is
|
||||
always a greater number in a more recent release. It makes comparisons with
|
||||
greater than and less than work.
|
||||
|
||||
This number is also available as three separate defines:
|
||||
LIBCURL_VERSION_MAJOR, LIBCURL_VERSION_MINOR and LIBCURL_VERSION_PATCH.
|
||||
99
third-party/curl-7.21.4/docs/curl-config.1
vendored
Normal file
99
third-party/curl-7.21.4/docs/curl-config.1
vendored
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
.\" **************************************************************************
|
||||
.\" * _ _ ____ _
|
||||
.\" * Project ___| | | | _ \| |
|
||||
.\" * / __| | | | |_) | |
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * Copyright (C) 1998 - 2010, 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.
|
||||
.\" *
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH curl-config 1 "25 Oct 2007" "Curl 7.17.1" "curl-config manual"
|
||||
.SH NAME
|
||||
curl-config \- Get information about a libcurl installation
|
||||
.SH SYNOPSIS
|
||||
.B curl-config [options]
|
||||
.SH DESCRIPTION
|
||||
.B curl-config
|
||||
displays information about the curl and libcurl installation.
|
||||
.SH OPTIONS
|
||||
.IP "--ca"
|
||||
Displays the built-in path to the CA cert bundle this libcurl uses.
|
||||
.IP "--cc"
|
||||
Displays the compiler used to build libcurl.
|
||||
.IP "--cflags"
|
||||
Set of compiler options (CFLAGS) to use when compiling files that use
|
||||
libcurl. Currently that is only the include path to the curl include files.
|
||||
.IP "--checkfor [version]"
|
||||
Specify the oldest possible libcurl version string you want, and this
|
||||
script will return 0 if the current installation is new enough or it
|
||||
returns 1 and outputs a text saying that the current version is not new
|
||||
enough. (Added in 7.15.4)
|
||||
.IP "--configure"
|
||||
Displays the arguments given to configure when building curl.
|
||||
.IP "--feature"
|
||||
Lists what particular main features the installed libcurl was built with. At
|
||||
the time of writing, this list may include SSL, KRB4 or IPv6. Do not assume
|
||||
any particular order. The keywords will be separated by newlines. There may be
|
||||
none, one, or several keywords in the list.
|
||||
.IP "--help"
|
||||
Displays the available options.
|
||||
.IP "--libs"
|
||||
Shows the complete set of libs and other linker options you will need in order
|
||||
to link your application with libcurl.
|
||||
.IP "--prefix"
|
||||
This is the prefix used when libcurl was installed. Libcurl is then installed
|
||||
in $prefix/lib and its header files are installed in $prefix/include and so
|
||||
on. The prefix is set with "configure --prefix".
|
||||
.IP "--protocols"
|
||||
Lists what particular protocols the installed libcurl was built to support. At
|
||||
the time of writing, this list may include HTTP, HTTPS, FTP, FTPS, FILE,
|
||||
TELNET, LDAP, DICT. Do not assume any particular order. The protocols will
|
||||
be listed using uppercase and are separated by newlines. There may be none,
|
||||
one, or several protocols in the list. (Added in 7.13.0)
|
||||
.IP "--static-libs"
|
||||
Shows the complete set of libs and other linker options you will need in order
|
||||
to link your application with libcurl statically. (Added in 7.17.1)
|
||||
.IP "--version"
|
||||
Outputs version information about the installed libcurl.
|
||||
.IP "--vernum"
|
||||
Outputs version information about the installed libcurl, in numerical mode.
|
||||
This outputs the version number, in hexadecimal, with 8 bits for each part;
|
||||
major, minor, patch. So that libcurl 7.7.4 would appear as 070704 and libcurl
|
||||
12.13.14 would appear as 0c0d0e... Note that the initial zero might be
|
||||
omitted. (This option was broken in the 7.15.0 release.)
|
||||
.SH "EXAMPLES"
|
||||
What linker options do I need when I link with libcurl?
|
||||
|
||||
$ curl-config --libs
|
||||
|
||||
What compiler options do I need when I compile using libcurl functions?
|
||||
|
||||
$ curl-config --cflags
|
||||
|
||||
How do I know if libcurl was built with SSL support?
|
||||
|
||||
$ curl-config --feature | grep SSL
|
||||
|
||||
What's the installed libcurl version?
|
||||
|
||||
$ curl-config --version
|
||||
|
||||
How do I build a single file with a one-line command?
|
||||
|
||||
$ `curl-config --cc --cflags --libs` -o example example.c
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.BR curl (1)
|
||||
1804
third-party/curl-7.21.4/docs/curl.1
vendored
Normal file
1804
third-party/curl-7.21.4/docs/curl.1
vendored
Normal file
File diff suppressed because it is too large
Load diff
35
third-party/curl-7.21.4/docs/examples/.gitignore
vendored
Normal file
35
third-party/curl-7.21.4/docs/examples/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
10-at-a-time
|
||||
anyauthput
|
||||
certinfo
|
||||
chkspeed
|
||||
cookie_interface
|
||||
debug
|
||||
fileupload
|
||||
fopen
|
||||
ftp-wildcard
|
||||
ftpget
|
||||
ftpgetinfo
|
||||
ftpgetresp
|
||||
ftpupload
|
||||
getinfo
|
||||
getinmemory
|
||||
http-post
|
||||
httpcustomheader
|
||||
httpput
|
||||
https
|
||||
multi-app
|
||||
multi-debugcallback
|
||||
multi-double
|
||||
multi-post
|
||||
multi-single
|
||||
persistant
|
||||
post-callback
|
||||
postit2
|
||||
sendrecv
|
||||
sepheaders
|
||||
simple
|
||||
simplepost
|
||||
simplesmtp
|
||||
simplessl
|
||||
smtp-multi
|
||||
smtp-tls
|
||||
184
third-party/curl-7.21.4/docs/examples/10-at-a-time.c
vendored
Normal file
184
third-party/curl-7.21.4/docs/examples/10-at-a-time.c
vendored
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*
|
||||
* Example application source code using the multi interface to download many
|
||||
* files, but with a capped maximum amount of simultaneous transfers.
|
||||
*
|
||||
* Written by Michael Wallner
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifndef WIN32
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include <curl/multi.h>
|
||||
|
||||
static const char *urls[] = {
|
||||
"http://www.microsoft.com",
|
||||
"http://www.opensource.org",
|
||||
"http://www.google.com",
|
||||
"http://www.yahoo.com",
|
||||
"http://www.ibm.com",
|
||||
"http://www.mysql.com",
|
||||
"http://www.oracle.com",
|
||||
"http://www.ripe.net",
|
||||
"http://www.iana.org",
|
||||
"http://www.amazon.com",
|
||||
"http://www.netcraft.com",
|
||||
"http://www.heise.de",
|
||||
"http://www.chip.de",
|
||||
"http://www.ca.com",
|
||||
"http://www.cnet.com",
|
||||
"http://www.news.com",
|
||||
"http://www.cnn.com",
|
||||
"http://www.wikipedia.org",
|
||||
"http://www.dell.com",
|
||||
"http://www.hp.com",
|
||||
"http://www.cert.org",
|
||||
"http://www.mit.edu",
|
||||
"http://www.nist.gov",
|
||||
"http://www.ebay.com",
|
||||
"http://www.playstation.com",
|
||||
"http://www.uefa.com",
|
||||
"http://www.ieee.org",
|
||||
"http://www.apple.com",
|
||||
"http://www.sony.com",
|
||||
"http://www.symantec.com",
|
||||
"http://www.zdnet.com",
|
||||
"http://www.fujitsu.com",
|
||||
"http://www.supermicro.com",
|
||||
"http://www.hotmail.com",
|
||||
"http://www.ecma.com",
|
||||
"http://www.bbc.co.uk",
|
||||
"http://news.google.com",
|
||||
"http://www.foxnews.com",
|
||||
"http://www.msn.com",
|
||||
"http://www.wired.com",
|
||||
"http://www.sky.com",
|
||||
"http://www.usatoday.com",
|
||||
"http://www.cbs.com",
|
||||
"http://www.nbc.com",
|
||||
"http://slashdot.org",
|
||||
"http://www.bloglines.com",
|
||||
"http://www.techweb.com",
|
||||
"http://www.newslink.org",
|
||||
"http://www.un.org",
|
||||
};
|
||||
|
||||
#define MAX 10 /* number of simultaneous transfers */
|
||||
#define CNT sizeof(urls)/sizeof(char*) /* total number of transfers to do */
|
||||
|
||||
static size_t cb(char *d, size_t n, size_t l, void *p)
|
||||
{
|
||||
/* take care of the data here, ignored in this example */
|
||||
(void)d;
|
||||
(void)p;
|
||||
return n*l;
|
||||
}
|
||||
|
||||
static void init(CURLM *cm, int i)
|
||||
{
|
||||
CURL *eh = curl_easy_init();
|
||||
|
||||
curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, cb);
|
||||
curl_easy_setopt(eh, CURLOPT_HEADER, 0L);
|
||||
curl_easy_setopt(eh, CURLOPT_URL, urls[i]);
|
||||
curl_easy_setopt(eh, CURLOPT_PRIVATE, urls[i]);
|
||||
curl_easy_setopt(eh, CURLOPT_VERBOSE, 0L);
|
||||
|
||||
curl_multi_add_handle(cm, eh);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURLM *cm;
|
||||
CURLMsg *msg;
|
||||
long L;
|
||||
unsigned int C=0;
|
||||
int M, Q, U = -1;
|
||||
fd_set R, W, E;
|
||||
struct timeval T;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
cm = curl_multi_init();
|
||||
|
||||
/* we can optionally limit the total amount of connections this multi handle
|
||||
uses */
|
||||
curl_multi_setopt(cm, CURLMOPT_MAXCONNECTS, (long)MAX);
|
||||
|
||||
for (C = 0; C < MAX; ++C) {
|
||||
init(cm, C);
|
||||
}
|
||||
|
||||
while (U) {
|
||||
curl_multi_perform(cm, &U);
|
||||
|
||||
if (U) {
|
||||
FD_ZERO(&R);
|
||||
FD_ZERO(&W);
|
||||
FD_ZERO(&E);
|
||||
|
||||
if (curl_multi_fdset(cm, &R, &W, &E, &M)) {
|
||||
fprintf(stderr, "E: curl_multi_fdset\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (curl_multi_timeout(cm, &L)) {
|
||||
fprintf(stderr, "E: curl_multi_timeout\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (L == -1)
|
||||
L = 100;
|
||||
|
||||
if (M == -1) {
|
||||
#ifdef WIN32
|
||||
Sleep(L);
|
||||
#else
|
||||
sleep(L / 1000);
|
||||
#endif
|
||||
} else {
|
||||
T.tv_sec = L/1000;
|
||||
T.tv_usec = (L%1000)*1000;
|
||||
|
||||
if (0 > select(M+1, &R, &W, &E, &T)) {
|
||||
fprintf(stderr, "E: select(%i,,,,%li): %i: %s\n",
|
||||
M+1, L, errno, strerror(errno));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while ((msg = curl_multi_info_read(cm, &Q))) {
|
||||
if (msg->msg == CURLMSG_DONE) {
|
||||
char *url;
|
||||
CURL *e = msg->easy_handle;
|
||||
curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &url);
|
||||
fprintf(stderr, "R: %d - %s <%s>\n",
|
||||
msg->data.result, curl_easy_strerror(msg->data.result), url);
|
||||
curl_multi_remove_handle(cm, e);
|
||||
curl_easy_cleanup(e);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "E: CURLMsg (%d)\n", msg->msg);
|
||||
}
|
||||
if (C < CNT) {
|
||||
init(cm, C++);
|
||||
U++; /* just to prevent it from remaining at 0 if there are more
|
||||
URLs to get */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
curl_multi_cleanup(cm);
|
||||
curl_global_cleanup();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
37
third-party/curl-7.21.4/docs/examples/Makefile.am
vendored
Normal file
37
third-party/curl-7.21.4/docs/examples/Makefile.am
vendored
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#
|
||||
#
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign nostdinc
|
||||
|
||||
EXTRA_DIST = README Makefile.example Makefile.inc Makefile.m32 \
|
||||
makefile.dj $(COMPLICATED_EXAMPLES)
|
||||
|
||||
# Specify our include paths here, and do it relative to $(top_srcdir) and
|
||||
# $(top_builddir), to ensure that these paths which belong to the library
|
||||
# being currently built and tested are searched before the library which
|
||||
# might possibly already be installed in the system.
|
||||
#
|
||||
# $(top_builddir)/include/curl for generated curlbuild.h included from curl.h
|
||||
# $(top_builddir)/include for generated curlbuild.h included from lib/setup.h
|
||||
# $(top_srcdir)/include is for libcurl's external include files
|
||||
|
||||
INCLUDES = -I$(top_builddir)/include/curl \
|
||||
-I$(top_builddir)/include \
|
||||
-I$(top_srcdir)/include
|
||||
|
||||
LIBDIR = $(top_builddir)/lib
|
||||
|
||||
if STATICLIB
|
||||
# we need this define when building with a static lib on Windows
|
||||
STATICCPPFLAGS = -DCURL_STATICLIB
|
||||
endif
|
||||
|
||||
CPPFLAGS = -DCURL_NO_OLDIES $(STATICCPPFLAGS)
|
||||
|
||||
# Dependencies
|
||||
LDADD = $(LIBDIR)/libcurl.la
|
||||
|
||||
# Makefile.inc provides the check_PROGRAMS and COMPLICATED_EXAMPLES defines
|
||||
include Makefile.inc
|
||||
|
||||
all: $(check_PROGRAMS)
|
||||
40
third-party/curl-7.21.4/docs/examples/Makefile.example
vendored
Normal file
40
third-party/curl-7.21.4/docs/examples/Makefile.example
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#############################################################################
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
#
|
||||
|
||||
# What to call the final executable
|
||||
TARGET = example
|
||||
|
||||
# Which object files that the executable consists of
|
||||
OBJS= ftpget.o
|
||||
|
||||
# What compiler to use
|
||||
CC = gcc
|
||||
|
||||
# Compiler flags, -g for debug, -c to make an object file
|
||||
CFLAGS = -c -g
|
||||
|
||||
# This should point to a directory that holds libcurl, if it isn't
|
||||
# in the system's standard lib dir
|
||||
# We also set a -L to include the directory where we have the openssl
|
||||
# libraries
|
||||
LDFLAGS = -L/home/dast/lib -L/usr/local/ssl/lib
|
||||
|
||||
# We need -lcurl for the curl stuff
|
||||
# We need -lsocket and -lnsl when on Solaris
|
||||
# We need -lssl and -lcrypto when using libcurl with SSL support
|
||||
# We need -lpthread for the pthread example
|
||||
LIBS = -lcurl -lsocket -lnsl -lssl -lcrypto
|
||||
|
||||
# Link the target with all objects and libraries
|
||||
$(TARGET) : $(OBJS)
|
||||
$(CC) -o $(TARGET) $(OBJS) $(LDFLAGS) $(LIBS)
|
||||
|
||||
# Compile the source files into object files
|
||||
ftpget.o : ftpget.c
|
||||
$(CC) $(CFLAGS) $<
|
||||
14
third-party/curl-7.21.4/docs/examples/Makefile.inc
vendored
Normal file
14
third-party/curl-7.21.4/docs/examples/Makefile.inc
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# These are all libcurl example programs to be test compiled
|
||||
check_PROGRAMS = 10-at-a-time anyauthput cookie_interface debug fileupload \
|
||||
fopen ftpget ftpgetresp ftpupload getinfo getinmemory http-post httpput \
|
||||
https multi-app multi-debugcallback multi-double multi-post multi-single \
|
||||
persistant post-callback postit2 sepheaders simple simplepost simplessl \
|
||||
sendrecv httpcustomheader certinfo chkspeed ftpgetinfo ftp-wildcard \
|
||||
smtp-multi simplesmtp smtp-tls
|
||||
|
||||
# These examples require external dependencies that may not be commonly
|
||||
# available on POSIX systems, so don't bother attempting to compile them here.
|
||||
COMPLICATED_EXAMPLES = curlgtk.c curlx.c htmltitle.cc cacertinmem.c \
|
||||
ftpuploadresume.c ghiper.c hiperfifo.c htmltidy.c multithread.c \
|
||||
opensslthreadlock.c sampleconv.c synctime.c threaded-ssl.c evhiperfifo.c \
|
||||
smooth-gtk-thread.c version-check.pl
|
||||
133
third-party/curl-7.21.4/docs/examples/Makefile.m32
vendored
Normal file
133
third-party/curl-7.21.4/docs/examples/Makefile.m32
vendored
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
#########################################################################
|
||||
#
|
||||
## Makefile for building curl examples with MingW32
|
||||
## and optionally OpenSSL (0.9.8), libssh2 (0.18), zlib (1.2.3)
|
||||
##
|
||||
## Usage:
|
||||
## mingw32-make -f Makefile.m32 [SSL=1] [SSH2=1] [ZLIB=1] [SSPI=1] [IPV6=1] [DYN=1]
|
||||
##
|
||||
## Hint: you can also set environment vars to control the build, f.e.:
|
||||
## set ZLIB_PATH=c:/zlib-1.2.3
|
||||
## set ZLIB=1
|
||||
##
|
||||
#########################################################################
|
||||
|
||||
# Edit the path below to point to the base of your Zlib sources.
|
||||
ifndef ZLIB_PATH
|
||||
ZLIB_PATH = ../../zlib-1.2.3
|
||||
endif
|
||||
# Edit the path below to point to the base of your OpenSSL package.
|
||||
ifndef OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../openssl-0.9.8k
|
||||
endif
|
||||
# Edit the path below to point to the base of your LibSSH2 package.
|
||||
ifndef LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../libssh2-1.2
|
||||
endif
|
||||
# Edit the path below to point to the base of your Novell LDAP NDK.
|
||||
ifndef LDAP_SDK
|
||||
LDAP_SDK = c:/novell/ndk/cldapsdk/win32
|
||||
endif
|
||||
|
||||
PROOT = ../..
|
||||
ARES_LIB = $(PROOT)/ares
|
||||
|
||||
SSL = 1
|
||||
ZLIB = 1
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -g -O2 -Wall
|
||||
# comment LDFLAGS below to keep debug info
|
||||
LDFLAGS = -s
|
||||
RC = windres
|
||||
RCFLAGS = --include-dir=$(PROOT)/include -O COFF -i
|
||||
RM = del /q /f > NUL 2>&1
|
||||
CP = copy
|
||||
|
||||
########################################################
|
||||
## Nothing more to do below this line!
|
||||
|
||||
INCLUDES = -I. -I$(PROOT) -I$(PROOT)/include -I$(PROOT)/lib
|
||||
LINK = $(CC) $(LDFLAGS) -o $@
|
||||
|
||||
ifdef DYN
|
||||
curl_DEPENDENCIES = $(PROOT)/lib/libcurldll.a $(PROOT)/lib/libcurl.dll
|
||||
curl_LDADD = -L$(PROOT)/lib -lcurldll
|
||||
else
|
||||
curl_DEPENDENCIES = $(PROOT)/lib/libcurl.a
|
||||
curl_LDADD = -L$(PROOT)/lib -lcurl
|
||||
CFLAGS += -DCURL_STATICLIB
|
||||
endif
|
||||
ifdef ARES
|
||||
ifndef DYN
|
||||
curl_DEPENDENCIES += $(ARES_LIB)/libcares.a
|
||||
endif
|
||||
CFLAGS += -DUSE_ARES
|
||||
curl_LDADD += -L$(ARES_LIB) -lcares
|
||||
endif
|
||||
ifdef SSH2
|
||||
CFLAGS += -DUSE_LIBSSH2 -DHAVE_LIBSSH2_H
|
||||
curl_LDADD += -L$(LIBSSH2_PATH)/win32 -lssh2
|
||||
endif
|
||||
ifdef SSL
|
||||
INCLUDES += -I"$(OPENSSL_PATH)/outinc"
|
||||
CFLAGS += -DUSE_SSLEAY -DHAVE_OPENSSL_ENGINE_H
|
||||
ifdef DYN
|
||||
curl_LDADD += -L$(OPENSSL_PATH)/out -leay32 -lssl32
|
||||
else
|
||||
curl_LDADD += -L$(OPENSSL_PATH)/out -lssl -lcrypto -lgdi32
|
||||
endif
|
||||
endif
|
||||
ifdef ZLIB
|
||||
INCLUDES += -I"$(ZLIB_PATH)"
|
||||
CFLAGS += -DHAVE_LIBZ -DHAVE_ZLIB_H
|
||||
curl_LDADD += -L$(ZLIB_PATH) -lz
|
||||
endif
|
||||
ifdef SSPI
|
||||
CFLAGS += -DUSE_WINDOWS_SSPI
|
||||
endif
|
||||
ifdef IPV6
|
||||
CFLAGS += -DENABLE_IPV6
|
||||
endif
|
||||
ifdef LDAPS
|
||||
CFLAGS += -DHAVE_LDAP_SSL
|
||||
endif
|
||||
ifdef USE_LDAP_NOVELL
|
||||
CFLAGS += -DCURL_HAS_NOVELL_LDAPSDK
|
||||
curl_LDADD += -L"$(LDAP_SDK)/lib/mscvc" -lldapsdk -lldapssl -lldapx
|
||||
endif
|
||||
ifdef USE_LDAP_OPENLDAP
|
||||
CFLAGS += -DCURL_HAS_OPENLDAP_LDAPSDK
|
||||
curl_LDADD += -L"$(LDAP_SDK)/lib" -lldap -llber
|
||||
endif
|
||||
ifndef USE_LDAP_NOVELL
|
||||
ifndef USE_LDAP_OPENLDAP
|
||||
curl_LDADD += -lwldap32
|
||||
endif
|
||||
endif
|
||||
curl_LDADD += -lws2_32
|
||||
COMPILE = $(CC) $(INCLUDES) $(CFLAGS)
|
||||
|
||||
# Makefile.inc provides the check_PROGRAMS and COMPLICATED_EXAMPLES defines
|
||||
include Makefile.inc
|
||||
|
||||
example_PROGRAMS := $(patsubst %,%.exe,$(strip $(check_PROGRAMS)))
|
||||
|
||||
.SUFFIXES: .rc .res .o .exe
|
||||
|
||||
|
||||
all: $(example_PROGRAMS)
|
||||
|
||||
.o.exe: $(curl_DEPENDENCIES)
|
||||
$(LINK) $< $(curl_LDADD)
|
||||
|
||||
.c.o:
|
||||
$(COMPILE) -c $<
|
||||
|
||||
.rc.res:
|
||||
$(RC) $(RCFLAGS) $< -o $@
|
||||
|
||||
clean:
|
||||
$(RM) $(example_PROGRAMS)
|
||||
|
||||
|
||||
76
third-party/curl-7.21.4/docs/examples/README
vendored
Normal file
76
third-party/curl-7.21.4/docs/examples/README
vendored
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
This directory is for libcurl programming examples. They are meant to show
|
||||
some simple steps on how you can build your own application to take full
|
||||
advantage of libcurl.
|
||||
|
||||
If you end up with other small but still useful example sources, please mail
|
||||
them for submission in future packages and on the web site.
|
||||
|
||||
BUILDING
|
||||
|
||||
The Makefile.example is an example makefile that could be used to build these
|
||||
examples. Just edit the file according to your system and requirements first.
|
||||
|
||||
Most examples should build fine using a command line like this:
|
||||
|
||||
$ `curl-config --cc --cflags --libs` -o example example.c
|
||||
|
||||
Some compilers don't like having the arguments in this order but instead
|
||||
want you do reorganize them like:
|
||||
|
||||
$ `curl-config --cc` -o example example.c `curl-config --cflags --libs`
|
||||
|
||||
*PLEASE* do not use the curl.haxx.se site as a test target for your libcurl
|
||||
applications/experiments. Even if some of the examples use that site as a URL
|
||||
at some places, it doesn't mean that the URLs work or that we expect you to
|
||||
actually torture our web site with your tests! Thanks.
|
||||
|
||||
EXAMPLES
|
||||
|
||||
anyauthput.c - HTTP PUT using "any" authentication method
|
||||
cacertinmem.c - Use a built-in PEM certificate to retrieve a https page
|
||||
cookie_interface.c - shows usage of simple cookie interface
|
||||
curlgtk.c - download using a GTK progress bar
|
||||
curlx.c - getting file info from the remote cert data
|
||||
debug.c - showing how to use the debug callback
|
||||
fileupload.c - uploading to a file:// URL
|
||||
fopen.c - fopen() layer that supports opening URLs and files
|
||||
ftpget.c - simple getting a file from FTP
|
||||
ftpgetresp.c - get the response strings from the FTP server
|
||||
ftpupload.c - upload a file to an FTP server
|
||||
ftpuploadresume.c - resume an upload to an FTP server
|
||||
getinfo.c - get the Content-Type from the recent transfer
|
||||
getinmemory.c - download a file to memory only
|
||||
ghiper.c - curl_multi_socket() using code with glib-2
|
||||
hiperfifo.c - downloads all URLs written to the fifo, using
|
||||
curl_multi_socket() and libevent
|
||||
htmltidy.c - download a document and use libtidy to parse the HTML
|
||||
htmltitle.cc - download a HTML file and extract the <title> tag from a HTML
|
||||
page using libxml
|
||||
http-post.c - HTTP POST
|
||||
httpput.c - HTTP PUT a local file
|
||||
https.c - simple HTTPS transfer
|
||||
multi-app.c - a multi-interface app
|
||||
multi-debugcallback.c - a multi-interface app using the debug callback
|
||||
multi-double.c - a multi-interface app doing two simultaneous transfers
|
||||
multi-post.c - a multi-interface app doing a multipart formpost
|
||||
multi-single.c - a multi-interface app getting a single file
|
||||
multithread.c - an example using multi-treading transferring multiple files
|
||||
opensslthreadlock.c - show how to do locking when using OpenSSL multi-threaded
|
||||
persistant.c - request two URLs with a persistent connection
|
||||
post-callback.c - send a HTTP POST using a callback
|
||||
postit2.c - send a HTTP multipart formpost
|
||||
sampleconv.c - showing how a program on a non-ASCII platform would invoke
|
||||
callbacks to do its own codeset conversions instead of using
|
||||
the built-in iconv functions in libcurl
|
||||
sepheaders.c - download headers to a separate file
|
||||
simple.c - the most simple download a URL source
|
||||
simplepost.c - HTTP POST
|
||||
simplessl.c - HTTPS example with certificates many options set
|
||||
synctime.c - Sync local time by extracting date from remote HTTP servers
|
||||
10-at-a-time.c - Download many files simultaneously, 10 at a time.
|
||||
35
third-party/curl-7.21.4/docs/examples/adddocsref.pl
vendored
Executable file
35
third-party/curl-7.21.4/docs/examples/adddocsref.pl
vendored
Executable file
|
|
@ -0,0 +1,35 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# pass files as argument(s)
|
||||
|
||||
my $docroot="http://curl.haxx.se/libcurl/c";
|
||||
|
||||
for $f (@ARGV) {
|
||||
open(NEW, ">$f.new");
|
||||
open(F, "<$f");
|
||||
while(<F>) {
|
||||
my $l = $_;
|
||||
if($l =~ /\/* $docroot/) {
|
||||
# just ignore preciously added refs
|
||||
}
|
||||
elsif($l =~ /^( *).*curl_easy_setopt\([^,]*, *([^ ,]*) *,/) {
|
||||
my ($prefix, $anc) = ($1, $2);
|
||||
$anc =~ s/_//g;
|
||||
print NEW "$prefix/* $docroot/curl_easy_setopt.html#$anc */\n";
|
||||
print NEW $l;
|
||||
}
|
||||
elsif($l =~ /^( *).*(curl_([^\(]*))\(/) {
|
||||
my ($prefix, $func) = ($1, $2);
|
||||
print NEW "$prefix/* $docroot/$func.html */\n";
|
||||
print NEW $l;
|
||||
}
|
||||
else {
|
||||
print NEW $l;
|
||||
}
|
||||
}
|
||||
close(F);
|
||||
close(NEW);
|
||||
|
||||
system("mv $f $f.org");
|
||||
system("mv $f.new $f");
|
||||
}
|
||||
158
third-party/curl-7.21.4/docs/examples/anyauthput.c
vendored
Normal file
158
third-party/curl-7.21.4/docs/examples/anyauthput.c
vendored
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef WIN32
|
||||
# include <io.h>
|
||||
#else
|
||||
# ifdef __VMS
|
||||
typedef int intptr_t;
|
||||
# else
|
||||
# include <stdint.h>
|
||||
# endif
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# ifdef _WIN64
|
||||
typedef __int64 intptr_t;
|
||||
# else
|
||||
typedef int intptr_t;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#if LIBCURL_VERSION_NUM < 0x070c03
|
||||
#error "upgrade your libcurl to no less than 7.12.3"
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This example shows a HTTP PUT operation with authentiction using "any"
|
||||
* type. It PUTs a file given as a command line argument to the URL also given
|
||||
* on the command line.
|
||||
*
|
||||
* Since libcurl 7.12.3, using "any" auth and POST/PUT requires a set ioctl
|
||||
* function.
|
||||
*
|
||||
* This example also uses its own read callback.
|
||||
*/
|
||||
|
||||
/* ioctl callback function */
|
||||
static curlioerr my_ioctl(CURL *handle, curliocmd cmd, void *userp)
|
||||
{
|
||||
intptr_t fd = (intptr_t)userp;
|
||||
|
||||
(void)handle; /* not used in here */
|
||||
|
||||
switch(cmd) {
|
||||
case CURLIOCMD_RESTARTREAD:
|
||||
/* mr libcurl kindly asks as to rewind the read data stream to start */
|
||||
if(-1 == lseek(fd, 0, SEEK_SET))
|
||||
/* couldn't rewind */
|
||||
return CURLIOE_FAILRESTART;
|
||||
|
||||
break;
|
||||
|
||||
default: /* ignore unknown commands */
|
||||
return CURLIOE_UNKNOWNCMD;
|
||||
}
|
||||
return CURLIOE_OK; /* success! */
|
||||
}
|
||||
|
||||
/* read callback function, fread() look alike */
|
||||
static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
size_t retcode;
|
||||
|
||||
intptr_t fd = (intptr_t)stream;
|
||||
|
||||
retcode = read(fd, ptr, size * nmemb);
|
||||
|
||||
fprintf(stderr, "*** We read %d bytes from file\n", retcode);
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
intptr_t hd ;
|
||||
struct stat file_info;
|
||||
|
||||
char *file;
|
||||
char *url;
|
||||
|
||||
if(argc < 3)
|
||||
return 1;
|
||||
|
||||
file= argv[1];
|
||||
url = argv[2];
|
||||
|
||||
/* get the file size of the local file */
|
||||
hd = open(file, O_RDONLY) ;
|
||||
fstat(hd, &file_info);
|
||||
|
||||
/* In windows, this will init the winsock stuff */
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
/* get a curl handle */
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* we want to use our own read function */
|
||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
|
||||
|
||||
/* which file to upload */
|
||||
curl_easy_setopt(curl, CURLOPT_READDATA, (void*)hd);
|
||||
|
||||
/* set the ioctl function */
|
||||
curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, my_ioctl);
|
||||
|
||||
/* pass the file descriptor to the ioctl callback as well */
|
||||
curl_easy_setopt(curl, CURLOPT_IOCTLDATA, (void*)hd);
|
||||
|
||||
/* enable "uploading" (which means PUT when doing HTTP) */
|
||||
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L) ;
|
||||
|
||||
/* specify target URL, and note that this URL should also include a file
|
||||
name, not only a directory (as you can do with GTP uploads) */
|
||||
curl_easy_setopt(curl,CURLOPT_URL, url);
|
||||
|
||||
/* and give the size of the upload, this supports large file sizes
|
||||
on systems that have general support for it */
|
||||
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
|
||||
(curl_off_t)file_info.st_size);
|
||||
|
||||
/* tell libcurl we can use "any" auth, which lets the lib pick one, but it
|
||||
also costs one extra round-trip and possibly sending of all the PUT
|
||||
data twice!!! */
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_ANY);
|
||||
|
||||
/* set user name and password for the authentication */
|
||||
curl_easy_setopt(curl, CURLOPT_USERPWD, "user:password");
|
||||
|
||||
/* Now run off and do what you've been told! */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
close(hd); /* close the local file */
|
||||
|
||||
curl_global_cleanup();
|
||||
return 0;
|
||||
}
|
||||
138
third-party/curl-7.21.4/docs/examples/cacertinmem.c
vendored
Normal file
138
third-party/curl-7.21.4/docs/examples/cacertinmem.c
vendored
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*
|
||||
* Example using a "in core" PEM certificate to retrieve a https page.
|
||||
* Written by Theo Borm
|
||||
*/
|
||||
|
||||
/* on a netBSD system with OPENSSL& LIBCURL installed from
|
||||
* pkgsrc (using default paths) this program can be compiled using:
|
||||
* gcc -I/usr/pkg/include -L/usr/pkg/lib -lcurl -Wl,-R/usr/pkg/lib -lssl
|
||||
* -lcrypto -lz -o curlcacerttest curlcacerttest.c
|
||||
* on other operating systems you may want to change paths to headers
|
||||
* and libraries
|
||||
*/
|
||||
#include <openssl/ssl.h>
|
||||
#include <curl/curl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
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_STORE * store;
|
||||
X509 * cert=NULL;
|
||||
BIO * bio;
|
||||
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";
|
||||
/* get a BIO */
|
||||
bio=BIO_new_mem_buf(mypem, -1);
|
||||
/* use it to read the PEM formatted certificate from memory into an X509
|
||||
* structure that SSL can use
|
||||
*/
|
||||
PEM_read_bio_X509(bio, &cert, 0, NULL);
|
||||
if (cert == NULL)
|
||||
printf("PEM_read_bio_X509 failed...\n");
|
||||
|
||||
/* get a pointer to the X509 certificate store (which may be empty!) */
|
||||
store=SSL_CTX_get_cert_store((SSL_CTX *)sslctx);
|
||||
|
||||
/* add our certificate to this store */
|
||||
if (X509_STORE_add_cert(store, cert)==0)
|
||||
printf("error adding certificate\n");
|
||||
|
||||
/* all set to go */
|
||||
return CURLE_OK ;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL * ch;
|
||||
CURLcode rv;
|
||||
|
||||
rv=curl_global_init(CURL_GLOBAL_ALL);
|
||||
ch=curl_easy_init();
|
||||
rv=curl_easy_setopt(ch,CURLOPT_VERBOSE, 0L);
|
||||
rv=curl_easy_setopt(ch,CURLOPT_HEADER, 0L);
|
||||
rv=curl_easy_setopt(ch,CURLOPT_NOPROGRESS, 1L);
|
||||
rv=curl_easy_setopt(ch,CURLOPT_NOSIGNAL, 1L);
|
||||
rv=curl_easy_setopt(ch,CURLOPT_WRITEFUNCTION, *writefunction);
|
||||
rv=curl_easy_setopt(ch,CURLOPT_WRITEDATA, stdout);
|
||||
rv=curl_easy_setopt(ch,CURLOPT_HEADERFUNCTION, *writefunction);
|
||||
rv=curl_easy_setopt(ch,CURLOPT_WRITEHEADER, stderr);
|
||||
rv=curl_easy_setopt(ch,CURLOPT_SSLCERTTYPE,"PEM");
|
||||
rv=curl_easy_setopt(ch,CURLOPT_SSL_VERIFYPEER,1L);
|
||||
rv=curl_easy_setopt(ch, CURLOPT_URL, "https://www.example.com/");
|
||||
|
||||
/* first try: retrieve page without cacerts' certificate -> 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 cacerts' certificate -> will succeed
|
||||
* load the certificate by installing a function doing the nescessary
|
||||
* "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;
|
||||
}
|
||||
65
third-party/curl-7.21.4/docs/examples/certinfo.c
vendored
Normal file
65
third-party/curl-7.21.4/docs/examples/certinfo.c
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/*****************************************************************************
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h>
|
||||
#include <curl/easy.h>
|
||||
|
||||
static size_t wrfu(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
(void)stream;
|
||||
(void)ptr;
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
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);
|
||||
curl_easy_setopt(curl, CURLOPT_CERTINFO, 1L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
if(!res) {
|
||||
struct curl_certinfo *ci = NULL;
|
||||
|
||||
res = curl_easy_getinfo(curl, CURLINFO_CERTINFO, &ci);
|
||||
|
||||
if(!res && ci) {
|
||||
int i;
|
||||
printf("%d certs!\n", ci->num_of_certs);
|
||||
|
||||
for(i=0; i<ci->num_of_certs; i++) {
|
||||
struct curl_slist *slist;
|
||||
|
||||
for(slist = ci->certinfo[i]; slist; slist = slist->next)
|
||||
printf("%s\n", slist->data);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
165
third-party/curl-7.21.4/docs/examples/chkspeed.c
vendored
Normal file
165
third-party/curl-7.21.4/docs/examples/chkspeed.c
vendored
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*
|
||||
* Example source code to show how the callback function can be used to
|
||||
* download data into a chunk of memory instead of storing it in a file.
|
||||
* After successful download we use curl_easy_getinfo() calls to get the
|
||||
* amount of downloaded bytes, the time used for the whole download, and
|
||||
* the average download speed.
|
||||
* On Linux you can create the download test files with:
|
||||
* dd if=/dev/urandom of=file_1M.bin bs=1M count=1
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h>
|
||||
#include <curl/easy.h>
|
||||
|
||||
#define URL_BASE "http://speedtest.your.domain/"
|
||||
#define URL_1M URL_BASE "file_1M.bin"
|
||||
#define URL_2M URL_BASE "file_2M.bin"
|
||||
#define URL_5M URL_BASE "file_5M.bin"
|
||||
#define URL_10M URL_BASE "file_10M.bin"
|
||||
#define URL_20M URL_BASE "file_20M.bin"
|
||||
#define URL_50M URL_BASE "file_50M.bin"
|
||||
#define URL_100M URL_BASE "file_100M.bin"
|
||||
|
||||
#define CHKSPEED_VERSION "1.0"
|
||||
|
||||
static size_t WriteCallback(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
/* we are not interested in the downloaded bytes itself,
|
||||
so we only return the size we would have saved ... */
|
||||
(void)ptr; /* unused */
|
||||
(void)data; /* unused */
|
||||
return (size_t)(size * nmemb);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
CURL *curl_handle;
|
||||
CURLcode res;
|
||||
int prtsep = 0, prttime = 0;
|
||||
const char *url = URL_1M;
|
||||
char *appname = argv[0];
|
||||
|
||||
if (argc > 1) {
|
||||
/* parse input parameters */
|
||||
for (argc--, argv++; *argv; argc--, argv++) {
|
||||
if (strncasecmp(*argv, "-", 1) == 0) {
|
||||
if (strncasecmp(*argv, "-H", 2) == 0) {
|
||||
fprintf(stderr,
|
||||
"\rUsage: %s [-m=1|2|5|10|20|50|100] [-t] [-x] [url]\n",
|
||||
appname);
|
||||
exit(1);
|
||||
} else if (strncasecmp(*argv, "-V", 2) == 0) {
|
||||
fprintf(stderr, "\r%s %s - %s\n",
|
||||
appname, CHKSPEED_VERSION, curl_version());
|
||||
exit(1);
|
||||
} else if (strncasecmp(*argv, "-X", 2) == 0) {
|
||||
prtsep = 1;
|
||||
} else if (strncasecmp(*argv, "-T", 2) == 0) {
|
||||
prttime = 1;
|
||||
} else if (strncasecmp(*argv, "-M=", 3) == 0) {
|
||||
long m = strtol((*argv)+3, NULL, 10);
|
||||
switch(m) {
|
||||
case 1: url = URL_1M;
|
||||
break;
|
||||
case 2: url = URL_2M;
|
||||
break;
|
||||
case 5: url = URL_5M;
|
||||
break;
|
||||
case 10: url = URL_10M;
|
||||
break;
|
||||
case 20: url = URL_20M;
|
||||
break;
|
||||
case 50: url = URL_50M;
|
||||
break;
|
||||
case 100: url = URL_100M;
|
||||
break;
|
||||
default: fprintf(stderr, "\r%s: invalid parameter %s\n",
|
||||
appname, *argv + 3);
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "\r%s: invalid or unknown option %s\n",
|
||||
appname, *argv);
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
url = *argv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* print separator line */
|
||||
if (prtsep) {
|
||||
printf("-------------------------------------------------\n");
|
||||
}
|
||||
/* print localtime */
|
||||
if (prttime) {
|
||||
time_t t = time(NULL);
|
||||
printf("Localtime: %s", ctime(&t));
|
||||
}
|
||||
|
||||
/* init libcurl */
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
/* init the curl session */
|
||||
curl_handle = curl_easy_init();
|
||||
|
||||
/* specify URL to get */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_URL, url);
|
||||
|
||||
/* send all data to this function */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteCallback);
|
||||
|
||||
/* some servers don't like requests that are made without a user-agent
|
||||
field, so we provide one */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT,
|
||||
"libcurl-speedchecker/" CHKSPEED_VERSION);
|
||||
|
||||
/* get it! */
|
||||
res = curl_easy_perform(curl_handle);
|
||||
|
||||
if(CURLE_OK == res) {
|
||||
double val;
|
||||
|
||||
/* check for bytes downloaded */
|
||||
res = curl_easy_getinfo(curl_handle, CURLINFO_SIZE_DOWNLOAD, &val);
|
||||
if((CURLE_OK == res) && (val>0))
|
||||
printf("Data downloaded: %0.0f bytes.\n", val);
|
||||
|
||||
/* check for total download time */
|
||||
res = curl_easy_getinfo(curl_handle, CURLINFO_TOTAL_TIME, &val);
|
||||
if((CURLE_OK == res) && (val>0))
|
||||
printf("Total download time: %0.3f sec.\n", val);
|
||||
|
||||
/* check for average download speed */
|
||||
res = curl_easy_getinfo(curl_handle, CURLINFO_SPEED_DOWNLOAD, &val);
|
||||
if((CURLE_OK == res) && (val>0))
|
||||
printf("Average download speed: %0.3f kbyte/sec.\n", val / 1024);
|
||||
|
||||
} else {
|
||||
fprintf(stderr, "Error while fetching '%s' : %s\n",
|
||||
url, curl_easy_strerror(res));
|
||||
}
|
||||
|
||||
/* cleanup curl stuff */
|
||||
curl_easy_cleanup(curl_handle);
|
||||
|
||||
/* we're done with libcurl, so clean it up */
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
111
third-party/curl-7.21.4/docs/examples/cookie_interface.c
vendored
Normal file
111
third-party/curl-7.21.4/docs/examples/cookie_interface.c
vendored
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* This example shows usage of simple cookie interface.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
static void
|
||||
print_cookies(CURL *curl)
|
||||
{
|
||||
CURLcode res;
|
||||
struct curl_slist *cookies;
|
||||
struct curl_slist *nc;
|
||||
int i;
|
||||
|
||||
printf("Cookies, curl knows:\n");
|
||||
res = curl_easy_getinfo(curl, CURLINFO_COOKIELIST, &cookies);
|
||||
if (res != CURLE_OK) {
|
||||
fprintf(stderr, "Curl curl_easy_getinfo failed: %s\n", curl_easy_strerror(res));
|
||||
exit(1);
|
||||
}
|
||||
nc = cookies, i = 1;
|
||||
while (nc) {
|
||||
printf("[%d]: %s\n", i, nc->data);
|
||||
nc = nc->next;
|
||||
i++;
|
||||
}
|
||||
if (i == 1) {
|
||||
printf("(none)\n");
|
||||
}
|
||||
curl_slist_free_all(cookies);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
curl = curl_easy_init();
|
||||
if (curl) {
|
||||
char nline[256];
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "http://www.example.com/");
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, ""); /* just to start the cookie engine */
|
||||
res = curl_easy_perform(curl);
|
||||
if (res != CURLE_OK) {
|
||||
fprintf(stderr, "Curl perform failed: %s\n", curl_easy_strerror(res));
|
||||
return 1;
|
||||
}
|
||||
|
||||
print_cookies(curl);
|
||||
|
||||
printf("Erasing curl's knowledge of cookies!\n");
|
||||
curl_easy_setopt(curl, CURLOPT_COOKIELIST, "ALL");
|
||||
|
||||
print_cookies(curl);
|
||||
|
||||
printf("-----------------------------------------------\n"
|
||||
"Setting a cookie \"PREF\" via cookie interface:\n");
|
||||
#ifdef WIN32
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
/* Netscape format cookie */
|
||||
snprintf(nline, sizeof(nline), "%s\t%s\t%s\t%s\t%lu\t%s\t%s",
|
||||
".google.com", "TRUE", "/", "FALSE", time(NULL) + 31337, "PREF", "hello google, i like you very much!");
|
||||
res = curl_easy_setopt(curl, CURLOPT_COOKIELIST, nline);
|
||||
if (res != CURLE_OK) {
|
||||
fprintf(stderr, "Curl curl_easy_setopt failed: %s\n", curl_easy_strerror(res));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* HTTP-header style cookie */
|
||||
snprintf(nline, sizeof(nline),
|
||||
"Set-Cookie: OLD_PREF=3d141414bf4209321; "
|
||||
"expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com");
|
||||
res = curl_easy_setopt(curl, CURLOPT_COOKIELIST, nline);
|
||||
if (res != CURLE_OK) {
|
||||
fprintf(stderr, "Curl curl_easy_setopt failed: %s\n", curl_easy_strerror(res));
|
||||
return 1;
|
||||
}
|
||||
|
||||
print_cookies(curl);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
if (res != CURLE_OK) {
|
||||
fprintf(stderr, "Curl perform failed: %s\n", curl_easy_strerror(res));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Curl init failed!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
curl_global_cleanup();
|
||||
return 0;
|
||||
}
|
||||
108
third-party/curl-7.21.4/docs/examples/curlgtk.c
vendored
Normal file
108
third-party/curl-7.21.4/docs/examples/curlgtk.c
vendored
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*/
|
||||
/* Copyright (c) 2000 David Odin (aka DindinX) for MandrakeSoft */
|
||||
/* an attempt to use the curl library in concert with a gtk-threaded application */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h> /* new for v7 */
|
||||
#include <curl/easy.h> /* new for v7 */
|
||||
|
||||
GtkWidget *Bar;
|
||||
|
||||
size_t my_write_func(void *ptr, size_t size, size_t nmemb, FILE *stream)
|
||||
{
|
||||
return fwrite(ptr, size, nmemb, stream);
|
||||
}
|
||||
|
||||
size_t my_read_func(void *ptr, size_t size, size_t nmemb, FILE *stream)
|
||||
{
|
||||
return fread(ptr, size, nmemb, stream);
|
||||
}
|
||||
|
||||
int my_progress_func(GtkWidget *bar,
|
||||
double t, /* dltotal */
|
||||
double d, /* dlnow */
|
||||
double ultotal,
|
||||
double ulnow)
|
||||
{
|
||||
/* printf("%d / %d (%g %%)\n", d, t, d*100.0/t);*/
|
||||
gdk_threads_enter();
|
||||
gtk_progress_set_value(GTK_PROGRESS(bar), d*100.0/t);
|
||||
gdk_threads_leave();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *my_thread(void *ptr)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
FILE *outfile;
|
||||
gchar *url = ptr;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl)
|
||||
{
|
||||
outfile = fopen("test.curl", "w");
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_write_func);
|
||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, my_read_func);
|
||||
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
|
||||
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, my_progress_func);
|
||||
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, Bar);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
fclose(outfile);
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
GtkWidget *Window, *Frame, *Frame2;
|
||||
GtkAdjustment *adj;
|
||||
|
||||
/* Must initialize libcurl before any threads are started */
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
/* Init thread */
|
||||
g_thread_init(NULL);
|
||||
|
||||
gtk_init(&argc, &argv);
|
||||
Window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
Frame = gtk_frame_new(NULL);
|
||||
gtk_frame_set_shadow_type(GTK_FRAME(Frame), GTK_SHADOW_OUT);
|
||||
gtk_container_add(GTK_CONTAINER(Window), Frame);
|
||||
Frame2 = gtk_frame_new(NULL);
|
||||
gtk_frame_set_shadow_type(GTK_FRAME(Frame2), GTK_SHADOW_IN);
|
||||
gtk_container_add(GTK_CONTAINER(Frame), Frame2);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(Frame2), 5);
|
||||
adj = (GtkAdjustment*)gtk_adjustment_new(0, 0, 100, 0, 0, 0);
|
||||
Bar = gtk_progress_bar_new_with_adjustment(adj);
|
||||
gtk_container_add(GTK_CONTAINER(Frame2), Bar);
|
||||
gtk_widget_show_all(Window);
|
||||
|
||||
if (!g_thread_create(&my_thread, argv[1], FALSE, NULL) != 0)
|
||||
g_warning("can't create the thread");
|
||||
|
||||
|
||||
gdk_threads_enter();
|
||||
gtk_main();
|
||||
gdk_threads_leave();
|
||||
return 0;
|
||||
}
|
||||
|
||||
514
third-party/curl-7.21.4/docs/examples/curlx.c
vendored
Normal file
514
third-party/curl-7.21.4/docs/examples/curlx.c
vendored
Normal file
|
|
@ -0,0 +1,514 @@
|
|||
/*
|
||||
curlx.c Authors: Peter Sylvester, Jean-Paul Merlin
|
||||
|
||||
This is a little program to demonstrate the usage of
|
||||
|
||||
- an ssl initialisation callback setting a user key and trustbases
|
||||
coming from a pkcs12 file
|
||||
- using an ssl application callback to find a URI in the
|
||||
certificate presented during ssl session establishment.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 The OpenEvidence Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, the following disclaimer,
|
||||
* and the original OpenSSL and SSLeay Licences below.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions, the following disclaimer
|
||||
* and the original OpenSSL and SSLeay Licences below in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgments:
|
||||
* "This product includes software developed by the Openevidence Project
|
||||
* for use in the OpenEvidence Toolkit. (http://www.openevidence.org/)"
|
||||
* This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com)."
|
||||
*
|
||||
* 4. The names "OpenEvidence Toolkit" and "OpenEvidence Project" must not be
|
||||
* used to endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openevidence-core@openevidence.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenEvidence"
|
||||
* nor may "OpenEvidence" appear in their names without prior written
|
||||
* permission of the OpenEvidence Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgments:
|
||||
* "This product includes software developed by the OpenEvidence Project
|
||||
* for use in the OpenEvidence Toolkit (http://www.openevidence.org/)
|
||||
* This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com)."
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenEvidence PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenEvidence PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include <openssl/x509_vfy.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/lhash.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/pkcs12.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
static const char *curlx_usage[]={
|
||||
"usage: curlx args\n",
|
||||
" -p12 arg - tia file ",
|
||||
" -envpass arg - environement variable which content the tia private key password",
|
||||
" -out arg - output file (response)- default stdout",
|
||||
" -in arg - input file (request)- default stdin",
|
||||
" -connect arg - URL of the server for the connection ex: www.openevidence.org",
|
||||
" -mimetype arg - MIME type for data in ex : application/timestamp-query or application/dvcs -default application/timestamp-query",
|
||||
" -acceptmime arg - MIME type acceptable for the response ex : application/timestamp-response or application/dvcs -default none",
|
||||
" -accesstype arg - an Object identifier in an AIA/SIA method, e.g. AD_DVCS or ad_timestamping",
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
./curlx -p12 psy.p12 -envpass XX -in request -verbose -accesstype AD_DVCS
|
||||
-mimetype application/dvcs -acceptmime application/dvcs -out response
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* We use this ZERO_NULL to avoid picky compiler warnings,
|
||||
* when assigning a NULL pointer to a function pointer var.
|
||||
*/
|
||||
|
||||
#define ZERO_NULL 0
|
||||
|
||||
/* This is a context that we pass to all callbacks */
|
||||
|
||||
typedef struct sslctxparm_st {
|
||||
unsigned char * p12file ;
|
||||
const char * pst ;
|
||||
PKCS12 * p12 ;
|
||||
EVP_PKEY * pkey ;
|
||||
X509 * usercert ;
|
||||
STACK_OF(X509) * ca ;
|
||||
CURL * curl;
|
||||
BIO * errorbio;
|
||||
int accesstype ;
|
||||
int verbose;
|
||||
|
||||
} sslctxparm;
|
||||
|
||||
/* some helper function. */
|
||||
|
||||
static char *i2s_ASN1_IA5STRING( ASN1_IA5STRING *ia5)
|
||||
{
|
||||
char *tmp;
|
||||
if(!ia5 || !ia5->length)
|
||||
return NULL;
|
||||
tmp = OPENSSL_malloc(ia5->length + 1);
|
||||
memcpy(tmp, ia5->data, ia5->length);
|
||||
tmp[ia5->length] = 0;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/* A conveniance routine to get an access URI. */
|
||||
|
||||
static unsigned char *my_get_ext(X509 * cert, const int type, int extensiontype) {
|
||||
|
||||
int i;
|
||||
STACK_OF(ACCESS_DESCRIPTION) * accessinfo ;
|
||||
accessinfo = X509_get_ext_d2i(cert, extensiontype, NULL, NULL) ;
|
||||
|
||||
if (!sk_ACCESS_DESCRIPTION_num(accessinfo))
|
||||
return NULL;
|
||||
for (i = 0; i < sk_ACCESS_DESCRIPTION_num(accessinfo); i++) {
|
||||
ACCESS_DESCRIPTION * ad = sk_ACCESS_DESCRIPTION_value(accessinfo, i);
|
||||
if (OBJ_obj2nid(ad->method) == type) {
|
||||
if (ad->location->type == GEN_URI) {
|
||||
return i2s_ASN1_IA5STRING(ad->location->d.ia5);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This is an application verification call back, it does not
|
||||
perform any addition verification but tries to find a URL
|
||||
in the presented certificat. If found, this will become
|
||||
the URL to be used in the POST.
|
||||
*/
|
||||
|
||||
static int ssl_app_verify_callback(X509_STORE_CTX *ctx, void *arg)
|
||||
{
|
||||
sslctxparm * p = (sslctxparm *) arg;
|
||||
int ok;
|
||||
|
||||
if (p->verbose > 2)
|
||||
BIO_printf(p->errorbio,"entering ssl_app_verify_callback\n");
|
||||
|
||||
if ((ok= X509_verify_cert(ctx)) && ctx->cert) {
|
||||
unsigned char * accessinfo ;
|
||||
if (p->verbose > 1)
|
||||
X509_print_ex(p->errorbio,ctx->cert,0,0);
|
||||
|
||||
if (accessinfo = my_get_ext(ctx->cert,p->accesstype ,NID_sinfo_access)) {
|
||||
if (p->verbose)
|
||||
BIO_printf(p->errorbio,"Setting URL from SIA to: %s\n", accessinfo);
|
||||
|
||||
curl_easy_setopt(p->curl, CURLOPT_URL,accessinfo);
|
||||
}
|
||||
else if (accessinfo = my_get_ext(ctx->cert,p->accesstype,
|
||||
NID_info_access)) {
|
||||
if (p->verbose)
|
||||
BIO_printf(p->errorbio,"Setting URL from AIA to: %s\n", accessinfo);
|
||||
|
||||
curl_easy_setopt(p->curl, CURLOPT_URL,accessinfo);
|
||||
}
|
||||
}
|
||||
if (p->verbose > 2)
|
||||
BIO_printf(p->errorbio,"leaving ssl_app_verify_callback with %d\n", ok);
|
||||
return(ok);
|
||||
}
|
||||
|
||||
|
||||
/* This is an example of an curl SSL initialisation call back. The callback sets:
|
||||
- a private key and certificate
|
||||
- a trusted ca certificate
|
||||
- a preferred cipherlist
|
||||
- an application verification callback (the function above)
|
||||
*/
|
||||
|
||||
static CURLcode sslctxfun(CURL * curl, void * sslctx, void * parm) {
|
||||
|
||||
sslctxparm * p = (sslctxparm *) parm;
|
||||
SSL_CTX * ctx = (SSL_CTX *) sslctx ;
|
||||
|
||||
if (!SSL_CTX_use_certificate(ctx,p->usercert)) {
|
||||
BIO_printf(p->errorbio, "SSL_CTX_use_certificate problem\n"); goto err;
|
||||
}
|
||||
if (!SSL_CTX_use_PrivateKey(ctx,p->pkey)) {
|
||||
BIO_printf(p->errorbio, "SSL_CTX_use_PrivateKey\n"); goto err;
|
||||
}
|
||||
|
||||
if (!SSL_CTX_check_private_key(ctx)) {
|
||||
BIO_printf(p->errorbio, "SSL_CTX_check_private_key\n"); goto err;
|
||||
}
|
||||
|
||||
SSL_CTX_set_quiet_shutdown(ctx,1);
|
||||
SSL_CTX_set_cipher_list(ctx,"RC4-MD5");
|
||||
SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
|
||||
|
||||
X509_STORE_add_cert(ctx->cert_store,sk_X509_value(p->ca,
|
||||
sk_X509_num(p->ca)-1));
|
||||
|
||||
SSL_CTX_set_verify_depth(ctx,2);
|
||||
|
||||
SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,ZERO_NULL);
|
||||
|
||||
SSL_CTX_set_cert_verify_callback(ctx, ssl_app_verify_callback, parm);
|
||||
|
||||
|
||||
return CURLE_OK ;
|
||||
err:
|
||||
ERR_print_errors(p->errorbio);
|
||||
return CURLE_SSL_CERTPROBLEM;
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
BIO* in=NULL;
|
||||
BIO* out=NULL;
|
||||
|
||||
char * outfile = NULL;
|
||||
char * infile = NULL ;
|
||||
|
||||
int tabLength=100;
|
||||
char *binaryptr;
|
||||
char* mimetype;
|
||||
char* mimetypeaccept=NULL;
|
||||
char* contenttype;
|
||||
const char** pp;
|
||||
unsigned char* hostporturl = NULL;
|
||||
BIO * p12bio ;
|
||||
char **args = argv + 1;
|
||||
unsigned char * serverurl;
|
||||
sslctxparm p;
|
||||
char *response;
|
||||
|
||||
CURLcode res;
|
||||
struct curl_slist * headers=NULL;
|
||||
int badarg=0;
|
||||
|
||||
binaryptr = malloc(tabLength);
|
||||
|
||||
p.verbose = 0;
|
||||
p.errorbio = BIO_new_fp (stderr, BIO_NOCLOSE);
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
/* we need some more for the P12 decoding */
|
||||
|
||||
OpenSSL_add_all_ciphers();
|
||||
OpenSSL_add_all_digests();
|
||||
ERR_load_crypto_strings();
|
||||
|
||||
|
||||
|
||||
while (*args && *args[0] == '-') {
|
||||
if (!strcmp (*args, "-in")) {
|
||||
if (args[1]) {
|
||||
infile=*(++args);
|
||||
} else badarg=1;
|
||||
} else if (!strcmp (*args, "-out")) {
|
||||
if (args[1]) {
|
||||
outfile=*(++args);
|
||||
} else badarg=1;
|
||||
} else if (!strcmp (*args, "-p12")) {
|
||||
if (args[1]) {
|
||||
p.p12file = *(++args);
|
||||
} else badarg=1;
|
||||
} else if (strcmp(*args,"-envpass") == 0) {
|
||||
if (args[1]) {
|
||||
p.pst = getenv(*(++args));
|
||||
} else badarg=1;
|
||||
} else if (strcmp(*args,"-connect") == 0) {
|
||||
if (args[1]) {
|
||||
hostporturl = *(++args);
|
||||
} else badarg=1;
|
||||
} else if (strcmp(*args,"-mimetype") == 0) {
|
||||
if (args[1]) {
|
||||
mimetype = *(++args);
|
||||
} else badarg=1;
|
||||
} else if (strcmp(*args,"-acceptmime") == 0) {
|
||||
if (args[1]) {
|
||||
mimetypeaccept = *(++args);
|
||||
} else badarg=1;
|
||||
} else if (strcmp(*args,"-accesstype") == 0) {
|
||||
if (args[1]) {
|
||||
if ((p.accesstype = OBJ_obj2nid(OBJ_txt2obj(*++args,0))) == 0) badarg=1;
|
||||
} else badarg=1;
|
||||
} else if (strcmp(*args,"-verbose") == 0) {
|
||||
p.verbose++;
|
||||
} else badarg=1;
|
||||
args++;
|
||||
}
|
||||
|
||||
if (mimetype==NULL || mimetypeaccept == NULL) badarg = 1;
|
||||
|
||||
if (badarg) {
|
||||
for (pp=curlx_usage; (*pp != NULL); pp++)
|
||||
BIO_printf(p.errorbio,"%s\n",*pp);
|
||||
BIO_printf(p.errorbio,"\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* set input */
|
||||
|
||||
if ((in=BIO_new(BIO_s_file())) == NULL) {
|
||||
BIO_printf(p.errorbio, "Error setting input bio\n");
|
||||
goto err;
|
||||
} else if (infile == NULL)
|
||||
BIO_set_fp(in,stdin,BIO_NOCLOSE|BIO_FP_TEXT);
|
||||
else if (BIO_read_filename(in,infile) <= 0) {
|
||||
BIO_printf(p.errorbio, "Error opening input file %s\n", infile);
|
||||
BIO_free(in);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* set output */
|
||||
|
||||
if ((out=BIO_new(BIO_s_file())) == NULL) {
|
||||
BIO_printf(p.errorbio, "Error setting output bio.\n");
|
||||
goto err;
|
||||
} else if (outfile == NULL)
|
||||
BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
|
||||
else if (BIO_write_filename(out,outfile) <= 0) {
|
||||
BIO_printf(p.errorbio, "Error opening output file %s\n", outfile);
|
||||
BIO_free(out);
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
p.errorbio = BIO_new_fp (stderr, BIO_NOCLOSE);
|
||||
|
||||
if (!(p.curl = curl_easy_init())) {
|
||||
BIO_printf(p.errorbio, "Cannot init curl lib\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!(p12bio = BIO_new_file(p.p12file , "rb"))) {
|
||||
BIO_printf(p.errorbio, "Error opening P12 file %s\n", p.p12file); goto err;
|
||||
}
|
||||
if (!(p.p12 = d2i_PKCS12_bio (p12bio, NULL))) {
|
||||
BIO_printf(p.errorbio, "Cannot decode P12 structure %s\n", p.p12file); goto err;
|
||||
}
|
||||
|
||||
p.ca= NULL;
|
||||
if (!(PKCS12_parse (p.p12, p.pst, &(p.pkey), &(p.usercert), &(p.ca) ) )) {
|
||||
BIO_printf(p.errorbio,"Invalid P12 structure in %s\n", p.p12file); goto err;
|
||||
}
|
||||
|
||||
if (sk_X509_num(p.ca) <= 0) {
|
||||
BIO_printf(p.errorbio,"No trustworthy CA given.%s\n", p.p12file); goto err;
|
||||
}
|
||||
|
||||
if (p.verbose > 1)
|
||||
X509_print_ex(p.errorbio,p.usercert,0,0);
|
||||
|
||||
/* determine URL to go */
|
||||
|
||||
if (hostporturl) {
|
||||
serverurl = malloc(9+strlen(hostporturl));
|
||||
sprintf(serverurl,"https://%s",hostporturl);
|
||||
}
|
||||
else if (p.accesstype != 0) { /* see whether we can find an AIA or SIA for a given access type */
|
||||
if (!(serverurl = my_get_ext(p.usercert,p.accesstype,NID_info_access))) {
|
||||
int j=0;
|
||||
BIO_printf(p.errorbio,"no service URL in user cert "
|
||||
"cherching in others certificats\n");
|
||||
for (j=0;j<sk_X509_num(p.ca);j++) {
|
||||
if ((serverurl = my_get_ext(sk_X509_value(p.ca,j),p.accesstype,
|
||||
NID_info_access)))
|
||||
break;
|
||||
if ((serverurl = my_get_ext(sk_X509_value(p.ca,j),p.accesstype,
|
||||
NID_sinfo_access)))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!serverurl) {
|
||||
BIO_printf(p.errorbio, "no service URL in certificats,"
|
||||
" check '-accesstype (AD_DVCS | ad_timestamping)'"
|
||||
" or use '-connect'\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (p.verbose)
|
||||
BIO_printf(p.errorbio, "Service URL: <%s>\n", serverurl);
|
||||
|
||||
curl_easy_setopt(p.curl, CURLOPT_URL, serverurl);
|
||||
|
||||
/* Now specify the POST binary data */
|
||||
|
||||
curl_easy_setopt(p.curl, CURLOPT_POSTFIELDS, binaryptr);
|
||||
curl_easy_setopt(p.curl, CURLOPT_POSTFIELDSIZE,(long)tabLength);
|
||||
|
||||
/* pass our list of custom made headers */
|
||||
|
||||
contenttype = malloc(15+strlen(mimetype));
|
||||
sprintf(contenttype,"Content-type: %s",mimetype);
|
||||
headers = curl_slist_append(headers,contenttype);
|
||||
curl_easy_setopt(p.curl, CURLOPT_HTTPHEADER, headers);
|
||||
|
||||
if (p.verbose)
|
||||
BIO_printf(p.errorbio, "Service URL: <%s>\n", serverurl);
|
||||
|
||||
{
|
||||
FILE *outfp;
|
||||
BIO_get_fp(out,&outfp);
|
||||
curl_easy_setopt(p.curl, CURLOPT_WRITEDATA, outfp);
|
||||
}
|
||||
|
||||
res = curl_easy_setopt(p.curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun) ;
|
||||
|
||||
if (res != CURLE_OK)
|
||||
BIO_printf(p.errorbio,"%d %s=%d %d\n", __LINE__, "CURLOPT_SSL_CTX_FUNCTION",CURLOPT_SSL_CTX_FUNCTION,res);
|
||||
|
||||
curl_easy_setopt(p.curl, CURLOPT_SSL_CTX_DATA, &p);
|
||||
|
||||
{
|
||||
int lu; int i=0;
|
||||
while ((lu = BIO_read (in,&binaryptr[i],tabLength-i)) >0 ) {
|
||||
i+=lu;
|
||||
if (i== tabLength) {
|
||||
tabLength+=100;
|
||||
binaryptr=realloc(binaryptr,tabLength); /* should be more careful */
|
||||
}
|
||||
}
|
||||
tabLength = i;
|
||||
}
|
||||
/* Now specify the POST binary data */
|
||||
|
||||
curl_easy_setopt(p.curl, CURLOPT_POSTFIELDS, binaryptr);
|
||||
curl_easy_setopt(p.curl, CURLOPT_POSTFIELDSIZE,(long)tabLength);
|
||||
|
||||
|
||||
/* Perform the request, res will get the return code */
|
||||
|
||||
BIO_printf(p.errorbio,"%d %s %d\n", __LINE__, "curl_easy_perform",
|
||||
res = curl_easy_perform(p.curl));
|
||||
{
|
||||
int result =curl_easy_getinfo(p.curl,CURLINFO_CONTENT_TYPE,&response);
|
||||
if( mimetypeaccept && p.verbose)
|
||||
if(!strcmp(mimetypeaccept,response))
|
||||
BIO_printf(p.errorbio,"the response has a correct mimetype : %s\n",
|
||||
response);
|
||||
else
|
||||
BIO_printf(p.errorbio,"the reponse doesn\'t has an acceptable "
|
||||
"mime type, it is %s instead of %s\n",
|
||||
response,mimetypeaccept);
|
||||
}
|
||||
|
||||
/*** code d'erreur si accept mime ***, egalement code return HTTP != 200 ***/
|
||||
|
||||
/* free the header list*/
|
||||
|
||||
curl_slist_free_all(headers);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(p.curl);
|
||||
|
||||
BIO_free(in);
|
||||
BIO_free(out);
|
||||
return (EXIT_SUCCESS);
|
||||
|
||||
err: BIO_printf(p.errorbio,"error");
|
||||
exit(1);
|
||||
}
|
||||
128
third-party/curl-7.21.4/docs/examples/debug.c
vendored
Normal file
128
third-party/curl-7.21.4/docs/examples/debug.c
vendored
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
struct data {
|
||||
char trace_ascii; /* 1 or 0 */
|
||||
};
|
||||
|
||||
static
|
||||
void dump(const char *text,
|
||||
FILE *stream, unsigned char *ptr, size_t size,
|
||||
char nohex)
|
||||
{
|
||||
size_t i;
|
||||
size_t c;
|
||||
|
||||
unsigned int width=0x10;
|
||||
|
||||
if(nohex)
|
||||
/* without the hex output, we can fit more on screen */
|
||||
width = 0x40;
|
||||
|
||||
fprintf(stream, "%s, %10.10ld bytes (0x%8.8lx)\n",
|
||||
text, (long)size, (long)size);
|
||||
|
||||
for(i=0; i<size; i+= width) {
|
||||
|
||||
fprintf(stream, "%4.4lx: ", (long)i);
|
||||
|
||||
if(!nohex) {
|
||||
/* hex not disabled, show it */
|
||||
for(c = 0; c < width; c++)
|
||||
if(i+c < size)
|
||||
fprintf(stream, "%02x ", ptr[i+c]);
|
||||
else
|
||||
fputs(" ", stream);
|
||||
}
|
||||
|
||||
for(c = 0; (c < width) && (i+c < size); c++) {
|
||||
/* check for 0D0A; if found, skip past and start a new line of output */
|
||||
if (nohex && (i+c+1 < size) && ptr[i+c]==0x0D && ptr[i+c+1]==0x0A) {
|
||||
i+=(c+2-width);
|
||||
break;
|
||||
}
|
||||
fprintf(stream, "%c",
|
||||
(ptr[i+c]>=0x20) && (ptr[i+c]<0x80)?ptr[i+c]:'.');
|
||||
/* check again for 0D0A, to avoid an extra \n if it's at width */
|
||||
if (nohex && (i+c+2 < size) && ptr[i+c+1]==0x0D && ptr[i+c+2]==0x0A) {
|
||||
i+=(c+3-width);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fputc('\n', stream); /* newline */
|
||||
}
|
||||
fflush(stream);
|
||||
}
|
||||
|
||||
static
|
||||
int my_trace(CURL *handle, curl_infotype type,
|
||||
char *data, size_t size,
|
||||
void *userp)
|
||||
{
|
||||
struct data *config = (struct data *)userp;
|
||||
const char *text;
|
||||
(void)handle; /* prevent compiler warning */
|
||||
|
||||
switch (type) {
|
||||
case CURLINFO_TEXT:
|
||||
fprintf(stderr, "== Info: %s", data);
|
||||
default: /* in case a new one is introduced to shock us */
|
||||
return 0;
|
||||
|
||||
case CURLINFO_HEADER_OUT:
|
||||
text = "=> Send header";
|
||||
break;
|
||||
case CURLINFO_DATA_OUT:
|
||||
text = "=> Send data";
|
||||
break;
|
||||
case CURLINFO_SSL_DATA_OUT:
|
||||
text = "=> Send SSL data";
|
||||
break;
|
||||
case CURLINFO_HEADER_IN:
|
||||
text = "<= Recv header";
|
||||
break;
|
||||
case CURLINFO_DATA_IN:
|
||||
text = "<= Recv data";
|
||||
break;
|
||||
case CURLINFO_SSL_DATA_IN:
|
||||
text = "<= Recv SSL data";
|
||||
break;
|
||||
}
|
||||
|
||||
dump(text, stderr, (unsigned char *)data, size, config->trace_ascii);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct data config;
|
||||
|
||||
config.trace_ascii = 1; /* enable ascii tracing */
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, my_trace);
|
||||
curl_easy_setopt(curl, CURLOPT_DEBUGDATA, &config);
|
||||
|
||||
/* the DEBUGFUNCTION has no effect until we enable VERBOSE */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/");
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
429
third-party/curl-7.21.4/docs/examples/evhiperfifo.c
vendored
Normal file
429
third-party/curl-7.21.4/docs/examples/evhiperfifo.c
vendored
Normal file
|
|
@ -0,0 +1,429 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*
|
||||
* Example application source code using the multi socket interface to
|
||||
* download many files at once.
|
||||
*
|
||||
* This example features the same basic functionality as hiperfifo.c does,
|
||||
* but this uses libev instead of libevent.
|
||||
*
|
||||
* Written by Jeff Pohlmeyer, converted to use libev by Markus Koetter
|
||||
|
||||
Requires libev and a (POSIX?) system that has mkfifo().
|
||||
|
||||
This is an adaptation of libcurl's "hipev.c" and libevent's "event-test.c"
|
||||
sample programs.
|
||||
|
||||
When running, the program creates the named pipe "hiper.fifo"
|
||||
|
||||
Whenever there is input into the fifo, the program reads the input as a list
|
||||
of URL's and creates some new easy handles to fetch each URL via the
|
||||
curl_multi "hiper" API.
|
||||
|
||||
|
||||
Thus, you can try a single URL:
|
||||
% echo http://www.yahoo.com > hiper.fifo
|
||||
|
||||
Or a whole bunch of them:
|
||||
% cat my-url-list > hiper.fifo
|
||||
|
||||
The fifo buffer is handled almost instantly, so you can even add more URL's
|
||||
while the previous requests are still being downloaded.
|
||||
|
||||
Note:
|
||||
For the sake of simplicity, URL length is limited to 1023 char's !
|
||||
|
||||
This is purely a demo app, all retrieved data is simply discarded by the write
|
||||
callback.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/poll.h>
|
||||
#include <curl/curl.h>
|
||||
#include <ev.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define DPRINT(x...) printf(x)
|
||||
|
||||
#define MSG_OUT stdout /* Send info to stdout, change to stderr if you want */
|
||||
|
||||
|
||||
/* Global information, common to all connections */
|
||||
typedef struct _GlobalInfo
|
||||
{
|
||||
struct ev_loop *loop;
|
||||
struct ev_io fifo_event;
|
||||
struct ev_timer timer_event;
|
||||
CURLM *multi;
|
||||
int still_running;
|
||||
FILE* input;
|
||||
} GlobalInfo;
|
||||
|
||||
|
||||
/* Information associated with a specific easy handle */
|
||||
typedef struct _ConnInfo
|
||||
{
|
||||
CURL *easy;
|
||||
char *url;
|
||||
GlobalInfo *global;
|
||||
char error[CURL_ERROR_SIZE];
|
||||
} ConnInfo;
|
||||
|
||||
|
||||
/* Information associated with a specific socket */
|
||||
typedef struct _SockInfo
|
||||
{
|
||||
curl_socket_t sockfd;
|
||||
CURL *easy;
|
||||
int action;
|
||||
long timeout;
|
||||
struct ev_io ev;
|
||||
int evset;
|
||||
GlobalInfo *global;
|
||||
} SockInfo;
|
||||
|
||||
static void timer_cb(EV_P_ struct ev_timer *w, int revents);
|
||||
|
||||
/* Update the event timer after curl_multi library calls */
|
||||
static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g)
|
||||
{
|
||||
DPRINT("%s %li\n", __PRETTY_FUNCTION__, timeout_ms);
|
||||
ev_timer_stop(g->loop, &g->timer_event);
|
||||
if (timeout_ms > 0)
|
||||
{
|
||||
double t = timeout_ms / 1000;
|
||||
ev_timer_init(&g->timer_event, timer_cb, t, 0.);
|
||||
ev_timer_start(g->loop, &g->timer_event);
|
||||
}else
|
||||
timer_cb(g->loop, &g->timer_event, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Die if we get a bad CURLMcode somewhere */
|
||||
static void mcode_or_die(const char *where, CURLMcode code)
|
||||
{
|
||||
if ( CURLM_OK != code )
|
||||
{
|
||||
const char *s;
|
||||
switch ( code )
|
||||
{
|
||||
case CURLM_CALL_MULTI_PERFORM: s="CURLM_CALL_MULTI_PERFORM"; break;
|
||||
case CURLM_BAD_HANDLE: s="CURLM_BAD_HANDLE"; break;
|
||||
case CURLM_BAD_EASY_HANDLE: s="CURLM_BAD_EASY_HANDLE"; break;
|
||||
case CURLM_OUT_OF_MEMORY: s="CURLM_OUT_OF_MEMORY"; break;
|
||||
case CURLM_INTERNAL_ERROR: s="CURLM_INTERNAL_ERROR"; break;
|
||||
case CURLM_UNKNOWN_OPTION: s="CURLM_UNKNOWN_OPTION"; break;
|
||||
case CURLM_LAST: s="CURLM_LAST"; break;
|
||||
default: s="CURLM_unknown";
|
||||
break;
|
||||
case CURLM_BAD_SOCKET: s="CURLM_BAD_SOCKET";
|
||||
fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s);
|
||||
/* ignore this error */
|
||||
return;
|
||||
}
|
||||
fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s);
|
||||
exit(code);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Check for completed transfers, and remove their easy handles */
|
||||
static void check_multi_info(GlobalInfo *g)
|
||||
{
|
||||
char *eff_url;
|
||||
CURLMsg *msg;
|
||||
int msgs_left;
|
||||
ConnInfo *conn;
|
||||
CURL *easy;
|
||||
CURLcode res;
|
||||
|
||||
fprintf(MSG_OUT, "REMAINING: %d\n", g->still_running);
|
||||
while ((msg = curl_multi_info_read(g->multi, &msgs_left))) {
|
||||
if (msg->msg == CURLMSG_DONE) {
|
||||
easy = msg->easy_handle;
|
||||
res = msg->data.result;
|
||||
curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn);
|
||||
curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url);
|
||||
fprintf(MSG_OUT, "DONE: %s => (%d) %s\n", eff_url, res, conn->error);
|
||||
curl_multi_remove_handle(g->multi, easy);
|
||||
free(conn->url);
|
||||
curl_easy_cleanup(easy);
|
||||
free(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Called by libevent when we get action on a multi socket */
|
||||
static void event_cb(EV_P_ struct ev_io *w, int revents)
|
||||
{
|
||||
DPRINT("%s w %p revents %i\n", __PRETTY_FUNCTION__, w, revents);
|
||||
GlobalInfo *g = (GlobalInfo*) w->data;
|
||||
CURLMcode rc;
|
||||
|
||||
int action = (revents&EV_READ?CURL_POLL_IN:0)|
|
||||
(revents&EV_WRITE?CURL_POLL_OUT:0);
|
||||
rc = curl_multi_socket_action(g->multi, w->fd, action, &g->still_running);
|
||||
mcode_or_die("event_cb: curl_multi_socket_action", rc);
|
||||
check_multi_info(g);
|
||||
if ( g->still_running <= 0 )
|
||||
{
|
||||
fprintf(MSG_OUT, "last transfer done, kill timeout\n");
|
||||
ev_timer_stop(g->loop, &g->timer_event);
|
||||
}
|
||||
}
|
||||
|
||||
/* Called by libevent when our timeout expires */
|
||||
static void timer_cb(EV_P_ struct ev_timer *w, int revents)
|
||||
{
|
||||
DPRINT("%s w %p revents %i\n", __PRETTY_FUNCTION__, w, revents);
|
||||
|
||||
GlobalInfo *g = (GlobalInfo *)w->data;
|
||||
CURLMcode rc;
|
||||
|
||||
rc = curl_multi_socket_action(g->multi, CURL_SOCKET_TIMEOUT, 0, &g->still_running);
|
||||
mcode_or_die("timer_cb: curl_multi_socket_action", rc);
|
||||
check_multi_info(g);
|
||||
}
|
||||
|
||||
/* Clean up the SockInfo structure */
|
||||
static void remsock(SockInfo *f, GlobalInfo *g)
|
||||
{
|
||||
printf("%s \n", __PRETTY_FUNCTION__);
|
||||
if ( f )
|
||||
{
|
||||
if ( f->evset )
|
||||
ev_io_stop(g->loop, &f->ev);
|
||||
free(f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Assign information to a SockInfo structure */
|
||||
static void setsock(SockInfo*f, curl_socket_t s, CURL*e, int act, GlobalInfo*g)
|
||||
{
|
||||
printf("%s \n", __PRETTY_FUNCTION__);
|
||||
|
||||
int kind = (act&CURL_POLL_IN?EV_READ:0)|(act&CURL_POLL_OUT?EV_WRITE:0);
|
||||
|
||||
f->sockfd = s;
|
||||
f->action = act;
|
||||
f->easy = e;
|
||||
if ( f->evset )
|
||||
ev_io_stop(g->loop, &f->ev);
|
||||
ev_io_init(&f->ev, event_cb, f->sockfd, kind);
|
||||
f->ev.data = g;
|
||||
f->evset=1;
|
||||
ev_io_start(g->loop, &f->ev);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Initialize a new SockInfo structure */
|
||||
static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g)
|
||||
{
|
||||
SockInfo *fdp = calloc(sizeof(SockInfo), 1);
|
||||
|
||||
fdp->global = g;
|
||||
setsock(fdp, s, easy, action, g);
|
||||
curl_multi_assign(g->multi, s, fdp);
|
||||
}
|
||||
|
||||
/* CURLMOPT_SOCKETFUNCTION */
|
||||
static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
|
||||
{
|
||||
DPRINT("%s e %p s %i what %i cbp %p sockp %p\n",
|
||||
__PRETTY_FUNCTION__, e, s, what, cbp, sockp);
|
||||
|
||||
GlobalInfo *g = (GlobalInfo*) cbp;
|
||||
SockInfo *fdp = (SockInfo*) sockp;
|
||||
const char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE"};
|
||||
|
||||
fprintf(MSG_OUT,
|
||||
"socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]);
|
||||
if ( what == CURL_POLL_REMOVE )
|
||||
{
|
||||
fprintf(MSG_OUT, "\n");
|
||||
remsock(fdp, g);
|
||||
} else
|
||||
{
|
||||
if ( !fdp )
|
||||
{
|
||||
fprintf(MSG_OUT, "Adding data: %s\n", whatstr[what]);
|
||||
addsock(s, e, what, g);
|
||||
} else
|
||||
{
|
||||
fprintf(MSG_OUT,
|
||||
"Changing action from %s to %s\n",
|
||||
whatstr[fdp->action], whatstr[what]);
|
||||
setsock(fdp, s, e, what, g);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* CURLOPT_WRITEFUNCTION */
|
||||
static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
size_t realsize = size * nmemb;
|
||||
ConnInfo *conn = (ConnInfo*) data;
|
||||
(void)ptr;
|
||||
(void)conn;
|
||||
return realsize;
|
||||
}
|
||||
|
||||
|
||||
/* CURLOPT_PROGRESSFUNCTION */
|
||||
static int prog_cb (void *p, double dltotal, double dlnow, double ult,
|
||||
double uln)
|
||||
{
|
||||
ConnInfo *conn = (ConnInfo *)p;
|
||||
(void)ult;
|
||||
(void)uln;
|
||||
|
||||
fprintf(MSG_OUT, "Progress: %s (%g/%g)\n", conn->url, dlnow, dltotal);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Create a new easy handle, and add it to the global curl_multi */
|
||||
static void new_conn(char *url, GlobalInfo *g )
|
||||
{
|
||||
ConnInfo *conn;
|
||||
CURLMcode rc;
|
||||
|
||||
conn = calloc(1, sizeof(ConnInfo));
|
||||
memset(conn, 0, sizeof(ConnInfo));
|
||||
conn->error[0]='\0';
|
||||
|
||||
conn->easy = curl_easy_init();
|
||||
if ( !conn->easy )
|
||||
{
|
||||
fprintf(MSG_OUT, "curl_easy_init() failed, exiting!\n");
|
||||
exit(2);
|
||||
}
|
||||
conn->global = g;
|
||||
conn->url = strdup(url);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, &conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_NOPROGRESS, 0L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSFUNCTION, prog_cb);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSDATA, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_TIME, 3L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_LIMIT, 10L);
|
||||
|
||||
fprintf(MSG_OUT,
|
||||
"Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url);
|
||||
rc = curl_multi_add_handle(g->multi, conn->easy);
|
||||
mcode_or_die("new_conn: curl_multi_add_handle", rc);
|
||||
|
||||
/* note that the add_handle() will set a time-out to trigger very soon so
|
||||
that the necessary socket_action() call will be called by this app */
|
||||
}
|
||||
|
||||
/* This gets called whenever data is received from the fifo */
|
||||
static void fifo_cb(EV_P_ struct ev_io *w, int revents)
|
||||
{
|
||||
char s[1024];
|
||||
long int rv=0;
|
||||
int n=0;
|
||||
GlobalInfo *g = (GlobalInfo *)w->data;
|
||||
|
||||
do
|
||||
{
|
||||
s[0]='\0';
|
||||
rv=fscanf(g->input, "%1023s%n", s, &n);
|
||||
s[n]='\0';
|
||||
if ( n && s[0] )
|
||||
{
|
||||
new_conn(s,g); /* if we read a URL, go get it! */
|
||||
} else break;
|
||||
} while ( rv != EOF );
|
||||
}
|
||||
|
||||
/* Create a named pipe and tell libevent to monitor it */
|
||||
static int init_fifo (GlobalInfo *g)
|
||||
{
|
||||
struct stat st;
|
||||
static const char *fifo = "hiper.fifo";
|
||||
curl_socket_t sockfd;
|
||||
|
||||
fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo);
|
||||
if ( lstat (fifo, &st) == 0 )
|
||||
{
|
||||
if ( (st.st_mode & S_IFMT) == S_IFREG )
|
||||
{
|
||||
errno = EEXIST;
|
||||
perror("lstat");
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
unlink(fifo);
|
||||
if ( mkfifo (fifo, 0600) == -1 )
|
||||
{
|
||||
perror("mkfifo");
|
||||
exit (1);
|
||||
}
|
||||
sockfd = open(fifo, O_RDWR | O_NONBLOCK, 0);
|
||||
if ( sockfd == -1 )
|
||||
{
|
||||
perror("open");
|
||||
exit (1);
|
||||
}
|
||||
g->input = fdopen(sockfd, "r");
|
||||
|
||||
fprintf(MSG_OUT, "Now, pipe some URL's into > %s\n", fifo);
|
||||
ev_io_init(&g->fifo_event, fifo_cb, sockfd, EV_READ);
|
||||
ev_io_start(g->loop, &g->fifo_event);
|
||||
return(0);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
GlobalInfo g;
|
||||
CURLMcode rc;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
memset(&g, 0, sizeof(GlobalInfo));
|
||||
g.loop = ev_default_loop(0);
|
||||
|
||||
init_fifo(&g);
|
||||
g.multi = curl_multi_init();
|
||||
|
||||
ev_timer_init(&g.timer_event, timer_cb, 0., 0.);
|
||||
g.timer_event.data = &g;
|
||||
g.fifo_event.data = &g;
|
||||
curl_multi_setopt(g.multi, CURLMOPT_SOCKETFUNCTION, sock_cb);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_SOCKETDATA, &g);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_TIMERFUNCTION, multi_timer_cb);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_TIMERDATA, &g);
|
||||
|
||||
/* we don't call any curl_multi_socket*() function yet as we have no handles
|
||||
added! */
|
||||
|
||||
ev_loop(g.loop, 0);
|
||||
curl_multi_cleanup(g.multi);
|
||||
return 0;
|
||||
}
|
||||
67
third-party/curl-7.21.4/docs/examples/fileupload.c
vendored
Normal file
67
third-party/curl-7.21.4/docs/examples/fileupload.c
vendored
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct stat file_info;
|
||||
double speed_upload, total_time;
|
||||
FILE *fd;
|
||||
|
||||
fd = fopen("debugit", "rb"); /* open file to upload */
|
||||
if(!fd) {
|
||||
|
||||
return 1; /* can't continue */
|
||||
}
|
||||
|
||||
/* to get the file size */
|
||||
if(fstat(fileno(fd), &file_info) != 0) {
|
||||
|
||||
return 1; /* can't continue */
|
||||
}
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* upload to this place */
|
||||
curl_easy_setopt(curl, CURLOPT_URL,
|
||||
"file:///home/dast/src/curl/debug/new");
|
||||
|
||||
/* tell it to "upload" to the URL */
|
||||
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
|
||||
|
||||
/* set where to read from (on Windows you need to use READFUNCTION too) */
|
||||
curl_easy_setopt(curl, CURLOPT_READDATA, fd);
|
||||
|
||||
/* and give the size of the upload (optional) */
|
||||
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
|
||||
(curl_off_t)file_info.st_size);
|
||||
|
||||
/* enable verbose for easier tracing */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* now extract transfer info */
|
||||
curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD, &speed_upload);
|
||||
curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &total_time);
|
||||
|
||||
fprintf(stderr, "Speed: %.3f bytes/sec during %.3f seconds\n",
|
||||
speed_upload, total_time);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
527
third-party/curl-7.21.4/docs/examples/fopen.c
vendored
Normal file
527
third-party/curl-7.21.4/docs/examples/fopen.c
vendored
Normal file
|
|
@ -0,0 +1,527 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This example source code introduces a c library buffered I/O interface to
|
||||
* URL reads it supports fopen(), fread(), fgets(), feof(), fclose(),
|
||||
* rewind(). Supported functions have identical prototypes to their normal c
|
||||
* lib namesakes and are preceaded by url_ .
|
||||
*
|
||||
* Using this code you can replace your program's fopen() with url_fopen()
|
||||
* and fread() with url_fread() and it become possible to read remote streams
|
||||
* instead of (only) local files. Local files (ie those that can be directly
|
||||
* fopened) will drop back to using the underlying clib implementations
|
||||
*
|
||||
* See the main() function at the bottom that shows an app that retrives from a
|
||||
* specified url using fgets() and fread() and saves as two output files.
|
||||
*
|
||||
* Copyright (c) 2003 Simtec Electronics
|
||||
*
|
||||
* Re-implemented by Vincent Sanders <vince@kyllikki.org> with extensive
|
||||
* reference to original curl example code
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This example requires libcurl 7.9.7 or later.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifndef WIN32
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
enum fcurl_type_e {
|
||||
CFTYPE_NONE=0,
|
||||
CFTYPE_FILE=1,
|
||||
CFTYPE_CURL=2
|
||||
};
|
||||
|
||||
struct fcurl_data
|
||||
{
|
||||
enum fcurl_type_e type; /* type of handle */
|
||||
union {
|
||||
CURL *curl;
|
||||
FILE *file;
|
||||
} handle; /* handle */
|
||||
|
||||
char *buffer; /* buffer to store cached data*/
|
||||
size_t buffer_len; /* currently allocated buffers length */
|
||||
size_t buffer_pos; /* end of data in buffer*/
|
||||
int still_running; /* Is background url fetch still in progress */
|
||||
};
|
||||
|
||||
typedef struct fcurl_data URL_FILE;
|
||||
|
||||
/* exported functions */
|
||||
URL_FILE *url_fopen(const char *url,const char *operation);
|
||||
int url_fclose(URL_FILE *file);
|
||||
int url_feof(URL_FILE *file);
|
||||
size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file);
|
||||
char * url_fgets(char *ptr, size_t size, URL_FILE *file);
|
||||
void url_rewind(URL_FILE *file);
|
||||
|
||||
/* we use a global one for convenience */
|
||||
CURLM *multi_handle;
|
||||
|
||||
/* curl calls this routine to get more data */
|
||||
static size_t write_callback(char *buffer,
|
||||
size_t size,
|
||||
size_t nitems,
|
||||
void *userp)
|
||||
{
|
||||
char *newbuff;
|
||||
size_t rembuff;
|
||||
|
||||
URL_FILE *url = (URL_FILE *)userp;
|
||||
size *= nitems;
|
||||
|
||||
rembuff=url->buffer_len - url->buffer_pos; /* remaining space in buffer */
|
||||
|
||||
if(size > rembuff) {
|
||||
/* not enough space in buffer */
|
||||
newbuff=realloc(url->buffer,url->buffer_len + (size - rembuff));
|
||||
if(newbuff==NULL) {
|
||||
fprintf(stderr,"callback buffer grow failed\n");
|
||||
size=rembuff;
|
||||
}
|
||||
else {
|
||||
/* realloc suceeded increase buffer size*/
|
||||
url->buffer_len+=size - rembuff;
|
||||
url->buffer=newbuff;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(&url->buffer[url->buffer_pos], buffer, size);
|
||||
url->buffer_pos += size;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/* use to attempt to fill the read buffer up to requested number of bytes */
|
||||
static int fill_buffer(URL_FILE *file, size_t want)
|
||||
{
|
||||
fd_set fdread;
|
||||
fd_set fdwrite;
|
||||
fd_set fdexcep;
|
||||
struct timeval timeout;
|
||||
int rc;
|
||||
|
||||
/* only attempt to fill buffer if transactions still running and buffer
|
||||
* doesnt exceed required size already
|
||||
*/
|
||||
if((!file->still_running) || (file->buffer_pos > want))
|
||||
return 0;
|
||||
|
||||
/* attempt to fill buffer */
|
||||
do {
|
||||
int maxfd = -1;
|
||||
long curl_timeo = -1;
|
||||
|
||||
FD_ZERO(&fdread);
|
||||
FD_ZERO(&fdwrite);
|
||||
FD_ZERO(&fdexcep);
|
||||
|
||||
/* set a suitable timeout to fail on */
|
||||
timeout.tv_sec = 60; /* 1 minute */
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
curl_multi_timeout(multi_handle, &curl_timeo);
|
||||
if(curl_timeo >= 0) {
|
||||
timeout.tv_sec = curl_timeo / 1000;
|
||||
if(timeout.tv_sec > 1)
|
||||
timeout.tv_sec = 1;
|
||||
else
|
||||
timeout.tv_usec = (curl_timeo % 1000) * 1000;
|
||||
}
|
||||
|
||||
/* get file descriptors from the transfers */
|
||||
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||
|
||||
/* In a real-world program you OF COURSE check the return code of the
|
||||
function calls. On success, the value of maxfd is guaranteed to be
|
||||
greater or equal than -1. We call select(maxfd + 1, ...), specially
|
||||
in case of (maxfd == -1), we call select(0, ...), which is basically
|
||||
equal to sleep. */
|
||||
|
||||
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||
|
||||
switch(rc) {
|
||||
case -1:
|
||||
/* select error */
|
||||
break;
|
||||
|
||||
case 0:
|
||||
default:
|
||||
/* timeout or readable/writable sockets */
|
||||
curl_multi_perform(multi_handle, &file->still_running);
|
||||
break;
|
||||
}
|
||||
} while(file->still_running && (file->buffer_pos < want));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* use to remove want bytes from the front of a files buffer */
|
||||
static int use_buffer(URL_FILE *file,int want)
|
||||
{
|
||||
/* sort out buffer */
|
||||
if((file->buffer_pos - want) <=0) {
|
||||
/* ditch buffer - write will recreate */
|
||||
if(file->buffer)
|
||||
free(file->buffer);
|
||||
|
||||
file->buffer=NULL;
|
||||
file->buffer_pos=0;
|
||||
file->buffer_len=0;
|
||||
}
|
||||
else {
|
||||
/* move rest down make it available for later */
|
||||
memmove(file->buffer,
|
||||
&file->buffer[want],
|
||||
(file->buffer_pos - want));
|
||||
|
||||
file->buffer_pos -= want;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
URL_FILE *url_fopen(const char *url,const char *operation)
|
||||
{
|
||||
/* this code could check for URLs or types in the 'url' and
|
||||
basicly use the real fopen() for standard files */
|
||||
|
||||
URL_FILE *file;
|
||||
(void)operation;
|
||||
|
||||
file = malloc(sizeof(URL_FILE));
|
||||
if(!file)
|
||||
return NULL;
|
||||
|
||||
memset(file, 0, sizeof(URL_FILE));
|
||||
|
||||
if((file->handle.file=fopen(url,operation)))
|
||||
file->type = CFTYPE_FILE; /* marked as URL */
|
||||
|
||||
else {
|
||||
file->type = CFTYPE_CURL; /* marked as URL */
|
||||
file->handle.curl = curl_easy_init();
|
||||
|
||||
curl_easy_setopt(file->handle.curl, CURLOPT_URL, url);
|
||||
curl_easy_setopt(file->handle.curl, CURLOPT_WRITEDATA, file);
|
||||
curl_easy_setopt(file->handle.curl, CURLOPT_VERBOSE, 0L);
|
||||
curl_easy_setopt(file->handle.curl, CURLOPT_WRITEFUNCTION, write_callback);
|
||||
|
||||
if(!multi_handle)
|
||||
multi_handle = curl_multi_init();
|
||||
|
||||
curl_multi_add_handle(multi_handle, file->handle.curl);
|
||||
|
||||
/* lets start the fetch */
|
||||
curl_multi_perform(multi_handle, &file->still_running);
|
||||
|
||||
if((file->buffer_pos == 0) && (!file->still_running)) {
|
||||
/* if still_running is 0 now, we should return NULL */
|
||||
|
||||
/* make sure the easy handle is not in the multi handle anymore */
|
||||
curl_multi_remove_handle(multi_handle, file->handle.curl);
|
||||
|
||||
/* cleanup */
|
||||
curl_easy_cleanup(file->handle.curl);
|
||||
|
||||
free(file);
|
||||
|
||||
file = NULL;
|
||||
}
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
int url_fclose(URL_FILE *file)
|
||||
{
|
||||
int ret=0;/* default is good return */
|
||||
|
||||
switch(file->type) {
|
||||
case CFTYPE_FILE:
|
||||
ret=fclose(file->handle.file); /* passthrough */
|
||||
break;
|
||||
|
||||
case CFTYPE_CURL:
|
||||
/* make sure the easy handle is not in the multi handle anymore */
|
||||
curl_multi_remove_handle(multi_handle, file->handle.curl);
|
||||
|
||||
/* cleanup */
|
||||
curl_easy_cleanup(file->handle.curl);
|
||||
break;
|
||||
|
||||
default: /* unknown or supported type - oh dear */
|
||||
ret=EOF;
|
||||
errno=EBADF;
|
||||
break;
|
||||
}
|
||||
|
||||
if(file->buffer)
|
||||
free(file->buffer);/* free any allocated buffer space */
|
||||
|
||||
free(file);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int url_feof(URL_FILE *file)
|
||||
{
|
||||
int ret=0;
|
||||
|
||||
switch(file->type) {
|
||||
case CFTYPE_FILE:
|
||||
ret=feof(file->handle.file);
|
||||
break;
|
||||
|
||||
case CFTYPE_CURL:
|
||||
if((file->buffer_pos == 0) && (!file->still_running))
|
||||
ret = 1;
|
||||
break;
|
||||
|
||||
default: /* unknown or supported type - oh dear */
|
||||
ret=-1;
|
||||
errno=EBADF;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file)
|
||||
{
|
||||
size_t want;
|
||||
|
||||
switch(file->type) {
|
||||
case CFTYPE_FILE:
|
||||
want=fread(ptr,size,nmemb,file->handle.file);
|
||||
break;
|
||||
|
||||
case CFTYPE_CURL:
|
||||
want = nmemb * size;
|
||||
|
||||
fill_buffer(file,want);
|
||||
|
||||
/* check if theres data in the buffer - if not fill_buffer()
|
||||
* either errored or EOF */
|
||||
if(!file->buffer_pos)
|
||||
return 0;
|
||||
|
||||
/* ensure only available data is considered */
|
||||
if(file->buffer_pos < want)
|
||||
want = file->buffer_pos;
|
||||
|
||||
/* xfer data to caller */
|
||||
memcpy(ptr, file->buffer, want);
|
||||
|
||||
use_buffer(file,want);
|
||||
|
||||
want = want / size; /* number of items */
|
||||
break;
|
||||
|
||||
default: /* unknown or supported type - oh dear */
|
||||
want=0;
|
||||
errno=EBADF;
|
||||
break;
|
||||
|
||||
}
|
||||
return want;
|
||||
}
|
||||
|
||||
char *url_fgets(char *ptr, size_t size, URL_FILE *file)
|
||||
{
|
||||
size_t want = size - 1;/* always need to leave room for zero termination */
|
||||
size_t loop;
|
||||
|
||||
switch(file->type) {
|
||||
case CFTYPE_FILE:
|
||||
ptr = fgets(ptr,size,file->handle.file);
|
||||
break;
|
||||
|
||||
case CFTYPE_CURL:
|
||||
fill_buffer(file,want);
|
||||
|
||||
/* check if theres data in the buffer - if not fill either errored or
|
||||
* EOF */
|
||||
if(!file->buffer_pos)
|
||||
return NULL;
|
||||
|
||||
/* ensure only available data is considered */
|
||||
if(file->buffer_pos < want)
|
||||
want = file->buffer_pos;
|
||||
|
||||
/*buffer contains data */
|
||||
/* look for newline or eof */
|
||||
for(loop=0;loop < want;loop++) {
|
||||
if(file->buffer[loop] == '\n') {
|
||||
want=loop+1;/* include newline */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* xfer data to caller */
|
||||
memcpy(ptr, file->buffer, want);
|
||||
ptr[want]=0;/* allways null terminate */
|
||||
|
||||
use_buffer(file,want);
|
||||
|
||||
break;
|
||||
|
||||
default: /* unknown or supported type - oh dear */
|
||||
ptr=NULL;
|
||||
errno=EBADF;
|
||||
break;
|
||||
}
|
||||
|
||||
return ptr;/*success */
|
||||
}
|
||||
|
||||
void url_rewind(URL_FILE *file)
|
||||
{
|
||||
switch(file->type) {
|
||||
case CFTYPE_FILE:
|
||||
rewind(file->handle.file); /* passthrough */
|
||||
break;
|
||||
|
||||
case CFTYPE_CURL:
|
||||
/* halt transaction */
|
||||
curl_multi_remove_handle(multi_handle, file->handle.curl);
|
||||
|
||||
/* restart */
|
||||
curl_multi_add_handle(multi_handle, file->handle.curl);
|
||||
|
||||
/* ditch buffer - write will recreate - resets stream pos*/
|
||||
if(file->buffer)
|
||||
free(file->buffer);
|
||||
|
||||
file->buffer=NULL;
|
||||
file->buffer_pos=0;
|
||||
file->buffer_len=0;
|
||||
|
||||
break;
|
||||
|
||||
default: /* unknown or supported type - oh dear */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Small main program to retrive from a url using fgets and fread saving the
|
||||
* output to two test files (note the fgets method will corrupt binary files if
|
||||
* they contain 0 chars */
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
URL_FILE *handle;
|
||||
FILE *outf;
|
||||
|
||||
int nread;
|
||||
char buffer[256];
|
||||
const char *url;
|
||||
|
||||
if(argc < 2)
|
||||
url="http://192.168.7.3/testfile";/* default to testurl */
|
||||
else
|
||||
url=argv[1];/* use passed url */
|
||||
|
||||
/* copy from url line by line with fgets */
|
||||
outf=fopen("fgets.test","w+");
|
||||
if(!outf) {
|
||||
perror("couldn't open fgets output file\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
handle = url_fopen(url, "r");
|
||||
if(!handle) {
|
||||
printf("couldn't url_fopen() %s\n", url);
|
||||
fclose(outf);
|
||||
return 2;
|
||||
}
|
||||
|
||||
while(!url_feof(handle)) {
|
||||
url_fgets(buffer,sizeof(buffer),handle);
|
||||
fwrite(buffer,1,strlen(buffer),outf);
|
||||
}
|
||||
|
||||
url_fclose(handle);
|
||||
|
||||
fclose(outf);
|
||||
|
||||
|
||||
/* Copy from url with fread */
|
||||
outf=fopen("fread.test","w+");
|
||||
if(!outf) {
|
||||
perror("couldn't open fread output file\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
handle = url_fopen("testfile", "r");
|
||||
if(!handle) {
|
||||
printf("couldn't url_fopen() testfile\n");
|
||||
fclose(outf);
|
||||
return 2;
|
||||
}
|
||||
|
||||
do {
|
||||
nread = url_fread(buffer, 1,sizeof(buffer), handle);
|
||||
fwrite(buffer,1,nread,outf);
|
||||
} while(nread);
|
||||
|
||||
url_fclose(handle);
|
||||
|
||||
fclose(outf);
|
||||
|
||||
|
||||
/* Test rewind */
|
||||
outf=fopen("rewind.test","w+");
|
||||
if(!outf) {
|
||||
perror("couldn't open fread output file\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
handle = url_fopen("testfile", "r");
|
||||
if(!handle) {
|
||||
printf("couldn't url_fopen() testfile\n");
|
||||
fclose(outf);
|
||||
return 2;
|
||||
}
|
||||
|
||||
nread = url_fread(buffer, 1,sizeof(buffer), handle);
|
||||
fwrite(buffer,1,nread,outf);
|
||||
url_rewind(handle);
|
||||
|
||||
buffer[0]='\n';
|
||||
fwrite(buffer,1,1,outf);
|
||||
|
||||
nread = url_fread(buffer, 1,sizeof(buffer), handle);
|
||||
fwrite(buffer,1,nread,outf);
|
||||
|
||||
|
||||
url_fclose(handle);
|
||||
|
||||
fclose(outf);
|
||||
|
||||
|
||||
return 0;/* all done */
|
||||
}
|
||||
135
third-party/curl-7.21.4/docs/examples/ftp-wildcard.c
vendored
Normal file
135
third-party/curl-7.21.4/docs/examples/ftp-wildcard.c
vendored
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*/
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct callback_data {
|
||||
FILE *output;
|
||||
};
|
||||
|
||||
static long file_is_comming(struct curl_fileinfo *finfo,
|
||||
struct callback_data *data,
|
||||
int remains);
|
||||
|
||||
static long file_is_downloaded(struct callback_data *data);
|
||||
|
||||
static size_t write_it(char *buff, size_t size, size_t nmemb,
|
||||
struct callback_data *data);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int rc = CURLE_OK;
|
||||
|
||||
/* curl easy handle */
|
||||
CURL *handle;
|
||||
|
||||
/* help data */
|
||||
struct callback_data data = { 0 };
|
||||
|
||||
/* global initialization */
|
||||
rc = curl_global_init(CURL_GLOBAL_ALL);
|
||||
if(rc)
|
||||
return rc;
|
||||
|
||||
/* initialization of easy handle */
|
||||
handle = curl_easy_init();
|
||||
if(!handle) {
|
||||
curl_global_cleanup();
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* turn on wildcard matching */
|
||||
curl_easy_setopt(handle, CURLOPT_WILDCARDMATCH, 1L);
|
||||
|
||||
/* callback is called before download of concrete file started */
|
||||
curl_easy_setopt(handle, CURLOPT_CHUNK_BGN_FUNCTION, file_is_comming);
|
||||
|
||||
/* callback is called after data from the file have been transferred */
|
||||
curl_easy_setopt(handle, CURLOPT_CHUNK_END_FUNCTION, file_is_downloaded);
|
||||
|
||||
/* this callback will write contents into files */
|
||||
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_it);
|
||||
|
||||
/* put transfer data into callbacks */
|
||||
curl_easy_setopt(handle, CURLOPT_CHUNK_DATA, &data);
|
||||
curl_easy_setopt(handle, CURLOPT_WRITEDATA, &data);
|
||||
|
||||
/* curl_easy_setopt(handle, CURLOPT_VERBOSE, 1L); */
|
||||
|
||||
/* set an URL containing wildcard pattern (only in the last part) */
|
||||
if(argc == 2)
|
||||
curl_easy_setopt(handle, CURLOPT_URL, argv[1]);
|
||||
else
|
||||
curl_easy_setopt(handle, CURLOPT_URL, "ftp://example.com/test/*");
|
||||
|
||||
/* and start transfer! */
|
||||
rc = curl_easy_perform(handle);
|
||||
|
||||
curl_easy_cleanup(handle);
|
||||
curl_global_cleanup();
|
||||
return rc;
|
||||
}
|
||||
|
||||
static long file_is_comming(struct curl_fileinfo *finfo,
|
||||
struct callback_data *data,
|
||||
int remains)
|
||||
{
|
||||
printf("%3d %40s %10luB ", remains, finfo->filename,
|
||||
(unsigned long)finfo->size);
|
||||
|
||||
switch(finfo->filetype) {
|
||||
case CURLFILETYPE_DIRECTORY:
|
||||
printf(" DIR\n");
|
||||
break;
|
||||
case CURLFILETYPE_FILE:
|
||||
printf("FILE ");
|
||||
break;
|
||||
default:
|
||||
printf("OTHER\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if(finfo->filetype == CURLFILETYPE_FILE) {
|
||||
/* do not transfer files >= 50B */
|
||||
if(finfo->size > 50) {
|
||||
printf("SKIPPED\n");
|
||||
return CURL_CHUNK_BGN_FUNC_SKIP;
|
||||
}
|
||||
|
||||
data->output = fopen(finfo->filename, "w");
|
||||
if(!data->output) {
|
||||
return CURL_CHUNK_BGN_FUNC_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
return CURL_CHUNK_BGN_FUNC_OK;
|
||||
}
|
||||
|
||||
static long file_is_downloaded(struct callback_data *data)
|
||||
{
|
||||
if(data->output) {
|
||||
printf("DOWNLOADED\n");
|
||||
fclose(data->output);
|
||||
data->output = 0x0;
|
||||
}
|
||||
return CURL_CHUNK_END_FUNC_OK;
|
||||
}
|
||||
|
||||
static size_t write_it(char *buff, size_t size, size_t nmemb,
|
||||
struct callback_data *data)
|
||||
{
|
||||
size_t written = 0;
|
||||
if(data->output)
|
||||
written = fwrite(buff, size, nmemb, data->output);
|
||||
else
|
||||
/* listing output */
|
||||
written = fwrite(buff, size, nmemb, stdout);
|
||||
return written;
|
||||
}
|
||||
84
third-party/curl-7.21.4/docs/examples/ftpget.c
vendored
Normal file
84
third-party/curl-7.21.4/docs/examples/ftpget.c
vendored
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h>
|
||||
#include <curl/easy.h>
|
||||
|
||||
/*
|
||||
* This is an example showing how to get a single file from an FTP server.
|
||||
* It delays the actual destination file creation until the first write
|
||||
* callback so that it won't create an empty file in case the remote file
|
||||
* doesn't exist or something else fails.
|
||||
*/
|
||||
|
||||
struct FtpFile {
|
||||
const char *filename;
|
||||
FILE *stream;
|
||||
};
|
||||
|
||||
static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
struct FtpFile *out=(struct FtpFile *)stream;
|
||||
if(out && !out->stream) {
|
||||
/* open file for writing */
|
||||
out->stream=fopen(out->filename, "wb");
|
||||
if(!out->stream)
|
||||
return -1; /* failure, can't open file to write */
|
||||
}
|
||||
return fwrite(buffer, size, nmemb, out->stream);
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct FtpFile ftpfile={
|
||||
"curl.tar.gz", /* name to store the file as if succesful */
|
||||
NULL
|
||||
};
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/*
|
||||
* You better replace the URL with one that works!
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_URL,
|
||||
"ftp://ftp.example.com/pub/www/utilities/curl/curl-7.9.2.tar.gz");
|
||||
/* Define our callback to get called when there's data to be written */
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
|
||||
/* Set a pointer to our struct to pass to the callback */
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
|
||||
|
||||
/* Switch on full protocol/debug output */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
if(CURLE_OK != res) {
|
||||
/* we failed */
|
||||
fprintf(stderr, "curl told us %d\n", res);
|
||||
}
|
||||
}
|
||||
|
||||
if(ftpfile.stream)
|
||||
fclose(ftpfile.stream); /* close the local file */
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
77
third-party/curl-7.21.4/docs/examples/ftpgetinfo.c
vendored
Normal file
77
third-party/curl-7.21.4/docs/examples/ftpgetinfo.c
vendored
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h>
|
||||
#include <curl/easy.h>
|
||||
|
||||
/*
|
||||
* This is an example showing how to check a single file's size and mtime
|
||||
* from an FTP server.
|
||||
*/
|
||||
|
||||
static size_t throw_away(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
(void)ptr;
|
||||
(void)data;
|
||||
/* we are not interested in the headers itself,
|
||||
so we only return the size we would have saved ... */
|
||||
return (size_t)(size * nmemb);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
char ftpurl[] = "ftp://ftp.example.com/gnu/binutils/binutils-2.19.1.tar.bz2";
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
const time_t filetime;
|
||||
const double filesize;
|
||||
const char *filename = strrchr(ftpurl, '/') + 1;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_URL, ftpurl);
|
||||
/* No download if the file */
|
||||
curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
|
||||
/* Ask for filetime */
|
||||
curl_easy_setopt(curl, CURLOPT_FILETIME, 1L);
|
||||
/* No header output: TODO 14.1 http-style HEAD output for ftp */
|
||||
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, throw_away);
|
||||
curl_easy_setopt(curl, CURLOPT_HEADER, 0L);
|
||||
/* Switch on full protocol/debug output */
|
||||
/* curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); */
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
if(CURLE_OK == res) {
|
||||
/* http://curl.haxx.se/libcurl/c/curl_easy_getinfo.html */
|
||||
res = curl_easy_getinfo(curl, CURLINFO_FILETIME, &filetime);
|
||||
if((CURLE_OK == res) && filetime)
|
||||
printf("filetime %s: %s", filename, ctime(&filetime));
|
||||
res = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &filesize);
|
||||
if((CURLE_OK == res) && (filesize>0))
|
||||
printf("filesize %s: %0.0f bytes\n", filename, filesize);
|
||||
} else {
|
||||
/* we failed */
|
||||
fprintf(stderr, "curl told us %d\n", res);
|
||||
}
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
62
third-party/curl-7.21.4/docs/examples/ftpgetresp.c
vendored
Normal file
62
third-party/curl-7.21.4/docs/examples/ftpgetresp.c
vendored
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h>
|
||||
#include <curl/easy.h>
|
||||
|
||||
/*
|
||||
* Similar to ftpget.c but this also stores the received response-lines
|
||||
* in a separate file using our own callback!
|
||||
*
|
||||
* This functionality was introduced in libcurl 7.9.3.
|
||||
*/
|
||||
|
||||
static size_t
|
||||
write_response(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
FILE *writehere = (FILE *)data;
|
||||
return fwrite(ptr, size, nmemb, writehere);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
FILE *ftpfile;
|
||||
FILE *respfile;
|
||||
|
||||
/* local file name to store the file as */
|
||||
ftpfile = fopen("ftp-list", "wb"); /* b is binary, needed on win32 */
|
||||
|
||||
/* local file name to store the FTP server's response lines in */
|
||||
respfile = fopen("ftp-responses", "wb"); /* b is binary, needed on win32 */
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Get a file listing from sunet */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "ftp://ftp.example.com/");
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, ftpfile);
|
||||
/* If you intend to use this on windows with a libcurl DLL, you must use
|
||||
CURLOPT_WRITEFUNCTION as well */
|
||||
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, write_response);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEHEADER, respfile);
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
fclose(ftpfile); /* close the local file */
|
||||
fclose(respfile); /* close the response file */
|
||||
|
||||
return 0;
|
||||
}
|
||||
120
third-party/curl-7.21.4/docs/examples/ftpupload.c
vendored
Normal file
120
third-party/curl-7.21.4/docs/examples/ftpupload.c
vendored
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#ifdef WIN32
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This example shows an FTP upload, with a rename of the file just after
|
||||
* a successful upload.
|
||||
*
|
||||
* Example based on source code provided by Erick Nuwendam. Thanks!
|
||||
*/
|
||||
|
||||
#define LOCAL_FILE "/tmp/uploadthis.txt"
|
||||
#define UPLOAD_FILE_AS "while-uploading.txt"
|
||||
#define REMOTE_URL "ftp://example.com/" UPLOAD_FILE_AS
|
||||
#define RENAME_FILE_TO "renamed-and-fine.txt"
|
||||
|
||||
/* NOTE: if you want this example to work on Windows with libcurl as a
|
||||
DLL, you MUST also provide a read callback with CURLOPT_READFUNCTION.
|
||||
Failing to do so will give you a crash since a DLL may not use the
|
||||
variable's memory when passed in to it from an app like this. */
|
||||
static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
/* in real-world cases, this would probably get this data differently
|
||||
as this fread() stuff is exactly what the library already would do
|
||||
by default internally */
|
||||
size_t retcode = fread(ptr, size, nmemb, stream);
|
||||
|
||||
fprintf(stderr, "*** We read %d bytes from file\n", retcode);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
FILE *hd_src;
|
||||
struct stat file_info;
|
||||
curl_off_t fsize;
|
||||
|
||||
struct curl_slist *headerlist=NULL;
|
||||
static const char buf_1 [] = "RNFR " UPLOAD_FILE_AS;
|
||||
static const char buf_2 [] = "RNTO " RENAME_FILE_TO;
|
||||
|
||||
/* get the file size of the local file */
|
||||
if(stat(LOCAL_FILE, &file_info)) {
|
||||
printf("Couldnt open '%s': %s\n", LOCAL_FILE, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
fsize = (curl_off_t)file_info.st_size;
|
||||
|
||||
printf("Local file size: %" CURL_FORMAT_CURL_OFF_T " bytes.\n", fsize);
|
||||
|
||||
/* get a FILE * of the same file */
|
||||
hd_src = fopen(LOCAL_FILE, "rb");
|
||||
|
||||
/* In windows, this will init the winsock stuff */
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
/* get a curl handle */
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* build a list of commands to pass to libcurl */
|
||||
headerlist = curl_slist_append(headerlist, buf_1);
|
||||
headerlist = curl_slist_append(headerlist, buf_2);
|
||||
|
||||
/* we want to use our own read function */
|
||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
|
||||
|
||||
/* enable uploading */
|
||||
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
|
||||
|
||||
/* specify target */
|
||||
curl_easy_setopt(curl,CURLOPT_URL, REMOTE_URL);
|
||||
|
||||
/* pass in that last of FTP commands to run after the transfer */
|
||||
curl_easy_setopt(curl, CURLOPT_POSTQUOTE, headerlist);
|
||||
|
||||
/* now specify which file to upload */
|
||||
curl_easy_setopt(curl, CURLOPT_READDATA, hd_src);
|
||||
|
||||
/* Set the size of the file to upload (optional). If you give a *_LARGE
|
||||
option you MUST make sure that the type of the passed-in argument is a
|
||||
curl_off_t. If you use CURLOPT_INFILESIZE (without _LARGE) you must
|
||||
make sure that to pass in a type 'long' argument. */
|
||||
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
|
||||
(curl_off_t)fsize);
|
||||
|
||||
/* Now run off and do what you've been told! */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* clean up the FTP commands list */
|
||||
curl_slist_free_all (headerlist);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
fclose(hd_src); /* close the local file */
|
||||
|
||||
curl_global_cleanup();
|
||||
return 0;
|
||||
}
|
||||
161
third-party/curl-7.21.4/docs/examples/ftpuploadresume.c
vendored
Normal file
161
third-party/curl-7.21.4/docs/examples/ftpuploadresume.c
vendored
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*
|
||||
* Upload to FTP, resuming failed transfers
|
||||
*
|
||||
* Compile for MinGW like this:
|
||||
* gcc -Wall -pedantic -std=c99 ftpuploadwithresume.c -o ftpuploadresume.exe
|
||||
* -lcurl -lmsvcr70
|
||||
*
|
||||
* Written by Philip Bock
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1300)
|
||||
# error _snscanf requires MSVC 7.0 or later.
|
||||
#endif
|
||||
|
||||
/* The MinGW headers are missing a few Win32 function definitions,
|
||||
you shouldn't need this if you use VC++ */
|
||||
#ifdef __MINGW32__
|
||||
int __cdecl _snscanf(const char * input, size_t length, const char * format, ...);
|
||||
#endif
|
||||
|
||||
|
||||
/* parse headers for Content-Length */
|
||||
size_t getcontentlengthfunc(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
int r;
|
||||
long len = 0;
|
||||
|
||||
/* _snscanf() is Win32 specific */
|
||||
r = _snscanf(ptr, size * nmemb, "Content-Length: %ld\n", &len);
|
||||
|
||||
if (r) /* Microsoft: we don't read the specs */
|
||||
*((long *) stream) = len;
|
||||
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
/* discard downloaded data */
|
||||
size_t discardfunc(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
/* read data to upload */
|
||||
size_t readfunc(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
FILE *f = stream;
|
||||
size_t n;
|
||||
|
||||
if (ferror(f))
|
||||
return CURL_READFUNC_ABORT;
|
||||
|
||||
n = fread(ptr, size, nmemb, f) * size;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
int upload(CURL *curlhandle, const char * remotepath, const char * localpath,
|
||||
long timeout, long tries)
|
||||
{
|
||||
FILE *f;
|
||||
long uploaded_len = 0;
|
||||
CURLcode r = CURLE_GOT_NOTHING;
|
||||
int c;
|
||||
|
||||
f = fopen(localpath, "rb");
|
||||
if (f == NULL) {
|
||||
perror(NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curlhandle, CURLOPT_UPLOAD, 1L);
|
||||
|
||||
curl_easy_setopt(curlhandle, CURLOPT_URL, remotepath);
|
||||
|
||||
if (timeout)
|
||||
curl_easy_setopt(curlhandle, CURLOPT_FTP_RESPONSE_TIMEOUT, timeout);
|
||||
|
||||
curl_easy_setopt(curlhandle, CURLOPT_HEADERFUNCTION, getcontentlengthfunc);
|
||||
curl_easy_setopt(curlhandle, CURLOPT_HEADERDATA, &uploaded_len);
|
||||
|
||||
curl_easy_setopt(curlhandle, CURLOPT_WRITEFUNCTION, discardfunc);
|
||||
|
||||
curl_easy_setopt(curlhandle, CURLOPT_READFUNCTION, readfunc);
|
||||
curl_easy_setopt(curlhandle, CURLOPT_READDATA, f);
|
||||
|
||||
curl_easy_setopt(curlhandle, CURLOPT_FTPPORT, "-"); /* disable passive mode */
|
||||
curl_easy_setopt(curlhandle, CURLOPT_FTP_CREATE_MISSING_DIRS, 1L);
|
||||
|
||||
curl_easy_setopt(curlhandle, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
for (c = 0; (r != CURLE_OK) && (c < tries); c++) {
|
||||
/* are we resuming? */
|
||||
if (c) { /* yes */
|
||||
/* determine the length of the file already written */
|
||||
|
||||
/*
|
||||
* With NOBODY and NOHEADER, libcurl will issue a SIZE
|
||||
* command, but the only way to retrieve the result is
|
||||
* to parse the returned Content-Length header. Thus,
|
||||
* getcontentlengthfunc(). We need discardfunc() above
|
||||
* because HEADER will dump the headers to stdout
|
||||
* without it.
|
||||
*/
|
||||
curl_easy_setopt(curlhandle, CURLOPT_NOBODY, 1L);
|
||||
curl_easy_setopt(curlhandle, CURLOPT_HEADER, 1L);
|
||||
|
||||
r = curl_easy_perform(curlhandle);
|
||||
if (r != CURLE_OK)
|
||||
continue;
|
||||
|
||||
curl_easy_setopt(curlhandle, CURLOPT_NOBODY, 0L);
|
||||
curl_easy_setopt(curlhandle, CURLOPT_HEADER, 0L);
|
||||
|
||||
fseek(f, uploaded_len, SEEK_SET);
|
||||
|
||||
curl_easy_setopt(curlhandle, CURLOPT_APPEND, 1L);
|
||||
}
|
||||
else { /* no */
|
||||
curl_easy_setopt(curlhandle, CURLOPT_APPEND, 0L);
|
||||
}
|
||||
|
||||
r = curl_easy_perform(curlhandle);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
if (r == CURLE_OK)
|
||||
return 1;
|
||||
else {
|
||||
fprintf(stderr, "%s\n", curl_easy_strerror(r));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int c, char **argv)
|
||||
{
|
||||
CURL *curlhandle = NULL;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
curlhandle = curl_easy_init();
|
||||
|
||||
upload(curlhandle, "ftp://user:pass@example.com/path/file", "C:\\file", 0, 3);
|
||||
|
||||
curl_easy_cleanup(curlhandle);
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
41
third-party/curl-7.21.4/docs/examples/getinfo.c
vendored
Normal file
41
third-party/curl-7.21.4/docs/examples/getinfo.c
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
/* http://curl.haxx.se/libcurl/c/curl_easy_init.html */
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTURL */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "http://www.example.com/");
|
||||
/* http://curl.haxx.se/libcurl/c/curl_easy_perform.html */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
if(CURLE_OK == res) {
|
||||
char *ct;
|
||||
/* ask for the content-type */
|
||||
/* http://curl.haxx.se/libcurl/c/curl_easy_getinfo.html */
|
||||
res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct);
|
||||
|
||||
if((CURLE_OK == res) && ct)
|
||||
printf("We received Content-Type: %s\n", ct);
|
||||
}
|
||||
|
||||
/* always cleanup */
|
||||
/* http://curl.haxx.se/libcurl/c/curl_easy_cleanup.html */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
99
third-party/curl-7.21.4/docs/examples/getinmemory.c
vendored
Normal file
99
third-party/curl-7.21.4/docs/examples/getinmemory.c
vendored
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*
|
||||
* Example source code to show how the callback function can be used to
|
||||
* download data into a chunk of memory instead of storing it in a file.
|
||||
*/
|
||||
|
||||
#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 *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
size_t realsize = size * nmemb;
|
||||
struct MemoryStruct *mem = (struct MemoryStruct *)data;
|
||||
|
||||
mem->memory = realloc(mem->memory, mem->size + realsize + 1);
|
||||
if (mem->memory == NULL) {
|
||||
/* out of memory! */
|
||||
printf("not enough memory (realloc returned NULL)\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
memcpy(&(mem->memory[mem->size]), ptr, realsize);
|
||||
mem->size += realsize;
|
||||
mem->memory[mem->size] = 0;
|
||||
|
||||
return realsize;
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl_handle;
|
||||
|
||||
struct MemoryStruct chunk;
|
||||
|
||||
chunk.memory = malloc(1); /* will be grown as needed by the realloc above */
|
||||
chunk.size = 0; /* no data at this point */
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
/* init the curl session */
|
||||
curl_handle = curl_easy_init();
|
||||
|
||||
/* specify URL to get */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_URL, "http://www.example.com/");
|
||||
|
||||
/* send all data to this function */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
|
||||
|
||||
/* we pass our 'chunk' struct to the callback function */
|
||||
curl_easy_setopt(curl_handle, 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_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
|
||||
|
||||
/* get it! */
|
||||
curl_easy_perform(curl_handle);
|
||||
|
||||
/* cleanup curl stuff */
|
||||
curl_easy_cleanup(curl_handle);
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*
|
||||
* 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);
|
||||
|
||||
if(chunk.memory)
|
||||
free(chunk.memory);
|
||||
|
||||
/* we're done with libcurl, so clean it up */
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
439
third-party/curl-7.21.4/docs/examples/ghiper.c
vendored
Normal file
439
third-party/curl-7.21.4/docs/examples/ghiper.c
vendored
Normal file
|
|
@ -0,0 +1,439 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*
|
||||
* Example application source code using the multi socket interface to
|
||||
* download many files at once.
|
||||
*
|
||||
* Written by Jeff Pohlmeyer
|
||||
|
||||
Requires glib-2.x and a (POSIX?) system that has mkfifo().
|
||||
|
||||
This is an adaptation of libcurl's "hipev.c" and libevent's "event-test.c"
|
||||
sample programs, adapted to use glib's g_io_channel in place of libevent.
|
||||
|
||||
When running, the program creates the named pipe "hiper.fifo"
|
||||
|
||||
Whenever there is input into the fifo, the program reads the input as a list
|
||||
of URL's and creates some new easy handles to fetch each URL via the
|
||||
curl_multi "hiper" API.
|
||||
|
||||
|
||||
Thus, you can try a single URL:
|
||||
% echo http://www.yahoo.com > hiper.fifo
|
||||
|
||||
Or a whole bunch of them:
|
||||
% cat my-url-list > hiper.fifo
|
||||
|
||||
The fifo buffer is handled almost instantly, so you can even add more URL's
|
||||
while the previous requests are still being downloaded.
|
||||
|
||||
This is purely a demo app, all retrieved data is simply discarded by the write
|
||||
callback.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include <glib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
||||
#define MSG_OUT g_print /* Change to "g_error" to write to stderr */
|
||||
#define SHOW_VERBOSE 0 /* Set to non-zero for libcurl messages */
|
||||
#define SHOW_PROGRESS 0 /* Set to non-zero to enable progress callback */
|
||||
|
||||
|
||||
|
||||
/* Global information, common to all connections */
|
||||
typedef struct _GlobalInfo {
|
||||
CURLM *multi;
|
||||
guint timer_event;
|
||||
int still_running;
|
||||
} GlobalInfo;
|
||||
|
||||
|
||||
|
||||
/* Information associated with a specific easy handle */
|
||||
typedef struct _ConnInfo {
|
||||
CURL *easy;
|
||||
char *url;
|
||||
GlobalInfo *global;
|
||||
char error[CURL_ERROR_SIZE];
|
||||
} ConnInfo;
|
||||
|
||||
|
||||
/* Information associated with a specific socket */
|
||||
typedef struct _SockInfo {
|
||||
curl_socket_t sockfd;
|
||||
CURL *easy;
|
||||
int action;
|
||||
long timeout;
|
||||
GIOChannel *ch;
|
||||
guint ev;
|
||||
GlobalInfo *global;
|
||||
} SockInfo;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Die if we get a bad CURLMcode somewhere */
|
||||
static void mcode_or_die(const char *where, CURLMcode code) {
|
||||
if ( CURLM_OK != code ) {
|
||||
const char *s;
|
||||
switch (code) {
|
||||
case CURLM_CALL_MULTI_PERFORM: s="CURLM_CALL_MULTI_PERFORM"; break;
|
||||
case CURLM_BAD_HANDLE: s="CURLM_BAD_HANDLE"; break;
|
||||
case CURLM_BAD_EASY_HANDLE: s="CURLM_BAD_EASY_HANDLE"; break;
|
||||
case CURLM_OUT_OF_MEMORY: s="CURLM_OUT_OF_MEMORY"; break;
|
||||
case CURLM_INTERNAL_ERROR: s="CURLM_INTERNAL_ERROR"; break;
|
||||
case CURLM_BAD_SOCKET: s="CURLM_BAD_SOCKET"; break;
|
||||
case CURLM_UNKNOWN_OPTION: s="CURLM_UNKNOWN_OPTION"; break;
|
||||
case CURLM_LAST: s="CURLM_LAST"; break;
|
||||
default: s="CURLM_unknown";
|
||||
}
|
||||
MSG_OUT("ERROR: %s returns %s\n", where, s);
|
||||
exit(code);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Check for completed transfers, and remove their easy handles */
|
||||
static void check_multi_info(GlobalInfo *g)
|
||||
{
|
||||
char *eff_url;
|
||||
CURLMsg *msg;
|
||||
int msgs_left;
|
||||
ConnInfo *conn;
|
||||
CURL *easy;
|
||||
CURLcode res;
|
||||
|
||||
MSG_OUT("REMAINING: %d\n", g->still_running);
|
||||
while ((msg = curl_multi_info_read(g->multi, &msgs_left))) {
|
||||
if (msg->msg == CURLMSG_DONE) {
|
||||
easy = msg->easy_handle;
|
||||
res = msg->data.result;
|
||||
curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn);
|
||||
curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url);
|
||||
MSG_OUT("DONE: %s => (%d) %s\n", eff_url, res, conn->error);
|
||||
curl_multi_remove_handle(g->multi, easy);
|
||||
free(conn->url);
|
||||
curl_easy_cleanup(easy);
|
||||
free(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Called by glib when our timeout expires */
|
||||
static gboolean timer_cb(gpointer data)
|
||||
{
|
||||
GlobalInfo *g = (GlobalInfo *)data;
|
||||
CURLMcode rc;
|
||||
|
||||
rc = curl_multi_socket_action(g->multi,
|
||||
CURL_SOCKET_TIMEOUT, 0, &g->still_running);
|
||||
mcode_or_die("timer_cb: curl_multi_socket_action", rc);
|
||||
check_multi_info(g);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Update the event timer after curl_multi library calls */
|
||||
static int update_timeout_cb(CURLM *multi, long timeout_ms, void *userp)
|
||||
{
|
||||
struct timeval timeout;
|
||||
GlobalInfo *g=(GlobalInfo *)userp;
|
||||
timeout.tv_sec = timeout_ms/1000;
|
||||
timeout.tv_usec = (timeout_ms%1000)*1000;
|
||||
|
||||
MSG_OUT("*** update_timeout_cb %ld => %ld:%ld ***\n",
|
||||
timeout_ms, timeout.tv_sec, timeout.tv_usec);
|
||||
|
||||
g->timer_event = g_timeout_add(timeout_ms, timer_cb, g);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Called by glib when we get action on a multi socket */
|
||||
static gboolean event_cb(GIOChannel *ch, GIOCondition condition, gpointer data)
|
||||
{
|
||||
GlobalInfo *g = (GlobalInfo*) data;
|
||||
CURLMcode rc;
|
||||
int fd=g_io_channel_unix_get_fd(ch);
|
||||
|
||||
int action =
|
||||
(condition & G_IO_IN ? CURL_CSELECT_IN : 0) |
|
||||
(condition & G_IO_OUT ? CURL_CSELECT_OUT : 0);
|
||||
|
||||
rc = curl_multi_socket_action(g->multi, fd, action, &g->still_running);
|
||||
mcode_or_die("event_cb: curl_multi_socket_action", rc);
|
||||
|
||||
check_multi_info(g);
|
||||
if(g->still_running) {
|
||||
return TRUE;
|
||||
} else {
|
||||
MSG_OUT("last transfer done, kill timeout\n");
|
||||
if (g->timer_event) { g_source_remove(g->timer_event); }
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Clean up the SockInfo structure */
|
||||
static void remsock(SockInfo *f)
|
||||
{
|
||||
if (!f) { return; }
|
||||
if (f->ev) { g_source_remove(f->ev); }
|
||||
g_free(f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Assign information to a SockInfo structure */
|
||||
static void setsock(SockInfo*f, curl_socket_t s, CURL*e, int act, GlobalInfo*g)
|
||||
{
|
||||
GIOCondition kind =
|
||||
(act&CURL_POLL_IN?G_IO_IN:0)|(act&CURL_POLL_OUT?G_IO_OUT:0);
|
||||
|
||||
f->sockfd = s;
|
||||
f->action = act;
|
||||
f->easy = e;
|
||||
if (f->ev) { g_source_remove(f->ev); }
|
||||
f->ev=g_io_add_watch(f->ch, kind, event_cb,g);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Initialize a new SockInfo structure */
|
||||
static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g)
|
||||
{
|
||||
SockInfo *fdp = g_malloc0(sizeof(SockInfo));
|
||||
|
||||
fdp->global = g;
|
||||
fdp->ch=g_io_channel_unix_new(s);
|
||||
setsock(fdp, s, easy, action, g);
|
||||
curl_multi_assign(g->multi, s, fdp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* CURLMOPT_SOCKETFUNCTION */
|
||||
static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
|
||||
{
|
||||
GlobalInfo *g = (GlobalInfo*) cbp;
|
||||
SockInfo *fdp = (SockInfo*) sockp;
|
||||
static const char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE" };
|
||||
|
||||
MSG_OUT("socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]);
|
||||
if (what == CURL_POLL_REMOVE) {
|
||||
MSG_OUT("\n");
|
||||
remsock(fdp);
|
||||
} else {
|
||||
if (!fdp) {
|
||||
MSG_OUT("Adding data: %s%s\n",
|
||||
what&CURL_POLL_IN?"READ":"",
|
||||
what&CURL_POLL_OUT?"WRITE":"" );
|
||||
addsock(s, e, what, g);
|
||||
}
|
||||
else {
|
||||
MSG_OUT(
|
||||
"Changing action from %d to %d\n", fdp->action, what);
|
||||
setsock(fdp, s, e, what, g);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* CURLOPT_WRITEFUNCTION */
|
||||
static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
size_t realsize = size * nmemb;
|
||||
ConnInfo *conn = (ConnInfo*) data;
|
||||
(void)ptr;
|
||||
(void)conn;
|
||||
return realsize;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* CURLOPT_PROGRESSFUNCTION */
|
||||
static int prog_cb (void *p, double dltotal, double dlnow, double ult, double uln)
|
||||
{
|
||||
ConnInfo *conn = (ConnInfo *)p;
|
||||
MSG_OUT("Progress: %s (%g/%g)\n", conn->url, dlnow, dltotal);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Create a new easy handle, and add it to the global curl_multi */
|
||||
static void new_conn(char *url, GlobalInfo *g )
|
||||
{
|
||||
ConnInfo *conn;
|
||||
CURLMcode rc;
|
||||
|
||||
conn = g_malloc0(sizeof(ConnInfo));
|
||||
|
||||
conn->error[0]='\0';
|
||||
|
||||
conn->easy = curl_easy_init();
|
||||
if (!conn->easy) {
|
||||
MSG_OUT("curl_easy_init() failed, exiting!\n");
|
||||
exit(2);
|
||||
}
|
||||
conn->global = g;
|
||||
conn->url = g_strdup(url);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, &conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, (long)SHOW_VERBOSE);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_NOPROGRESS, SHOW_PROGRESS?0L:1L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSFUNCTION, prog_cb);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSDATA, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_CONNECTTIMEOUT, 30L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_LIMIT, 1L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_TIME, 30L);
|
||||
|
||||
MSG_OUT("Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url);
|
||||
rc =curl_multi_add_handle(g->multi, conn->easy);
|
||||
mcode_or_die("new_conn: curl_multi_add_handle", rc);
|
||||
|
||||
/* note that the add_handle() will set a time-out to trigger very soon so
|
||||
that the necessary socket_action() call will be called by this app */
|
||||
}
|
||||
|
||||
|
||||
/* This gets called by glib whenever data is received from the fifo */
|
||||
static gboolean fifo_cb (GIOChannel *ch, GIOCondition condition, gpointer data)
|
||||
{
|
||||
#define BUF_SIZE 1024
|
||||
gsize len, tp;
|
||||
gchar *buf, *tmp, *all=NULL;
|
||||
GIOStatus rv;
|
||||
|
||||
do {
|
||||
GError *err=NULL;
|
||||
rv = g_io_channel_read_line (ch,&buf,&len,&tp,&err);
|
||||
if ( buf ) {
|
||||
if (tp) { buf[tp]='\0'; }
|
||||
new_conn(buf,(GlobalInfo*)data);
|
||||
g_free(buf);
|
||||
} else {
|
||||
buf = g_malloc(BUF_SIZE+1);
|
||||
while (TRUE) {
|
||||
buf[BUF_SIZE]='\0';
|
||||
g_io_channel_read_chars(ch,buf,BUF_SIZE,&len,&err);
|
||||
if (len) {
|
||||
buf[len]='\0';
|
||||
if (all) {
|
||||
tmp=all;
|
||||
all=g_strdup_printf("%s%s", tmp, buf);
|
||||
g_free(tmp);
|
||||
} else {
|
||||
all = g_strdup(buf);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (all) {
|
||||
new_conn(all,(GlobalInfo*)data);
|
||||
g_free(all);
|
||||
}
|
||||
g_free(buf);
|
||||
}
|
||||
if ( err ) {
|
||||
g_error("fifo_cb: %s", err->message);
|
||||
g_free(err);
|
||||
break;
|
||||
}
|
||||
} while ( (len) && (rv == G_IO_STATUS_NORMAL) );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int init_fifo(void)
|
||||
{
|
||||
struct stat st;
|
||||
const char *fifo = "hiper.fifo";
|
||||
int socket;
|
||||
|
||||
if (lstat (fifo, &st) == 0) {
|
||||
if ((st.st_mode & S_IFMT) == S_IFREG) {
|
||||
errno = EEXIST;
|
||||
perror("lstat");
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
unlink (fifo);
|
||||
if (mkfifo (fifo, 0600) == -1) {
|
||||
perror("mkfifo");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
socket = open (fifo, O_RDWR | O_NONBLOCK, 0);
|
||||
|
||||
if (socket == -1) {
|
||||
perror("open");
|
||||
exit (1);
|
||||
}
|
||||
MSG_OUT("Now, pipe some URL's into > %s\n", fifo);
|
||||
|
||||
return socket;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
GlobalInfo *g;
|
||||
CURLMcode rc;
|
||||
GMainLoop*gmain;
|
||||
int fd;
|
||||
GIOChannel* ch;
|
||||
g=g_malloc0(sizeof(GlobalInfo));
|
||||
|
||||
fd=init_fifo();
|
||||
ch=g_io_channel_unix_new(fd);
|
||||
g_io_add_watch(ch,G_IO_IN,fifo_cb,g);
|
||||
gmain=g_main_loop_new(NULL,FALSE);
|
||||
g->multi = curl_multi_init();
|
||||
curl_multi_setopt(g->multi, CURLMOPT_SOCKETFUNCTION, sock_cb);
|
||||
curl_multi_setopt(g->multi, CURLMOPT_SOCKETDATA, g);
|
||||
curl_multi_setopt(g->multi, CURLMOPT_TIMERFUNCTION, update_timeout_cb);
|
||||
curl_multi_setopt(g->multi, CURLMOPT_TIMERDATA, g);
|
||||
|
||||
/* we don't call any curl_multi_socket*() function yet as we have no handles
|
||||
added! */
|
||||
|
||||
g_main_loop_run(gmain);
|
||||
curl_multi_cleanup(g->multi);
|
||||
return 0;
|
||||
}
|
||||
405
third-party/curl-7.21.4/docs/examples/hiperfifo.c
vendored
Normal file
405
third-party/curl-7.21.4/docs/examples/hiperfifo.c
vendored
Normal file
|
|
@ -0,0 +1,405 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*
|
||||
* Example application source code using the multi socket interface to
|
||||
* download many files at once.
|
||||
*
|
||||
* Written by Jeff Pohlmeyer
|
||||
|
||||
Requires libevent and a (POSIX?) system that has mkfifo().
|
||||
|
||||
This is an adaptation of libcurl's "hipev.c" and libevent's "event-test.c"
|
||||
sample programs.
|
||||
|
||||
When running, the program creates the named pipe "hiper.fifo"
|
||||
|
||||
Whenever there is input into the fifo, the program reads the input as a list
|
||||
of URL's and creates some new easy handles to fetch each URL via the
|
||||
curl_multi "hiper" API.
|
||||
|
||||
|
||||
Thus, you can try a single URL:
|
||||
% echo http://www.yahoo.com > hiper.fifo
|
||||
|
||||
Or a whole bunch of them:
|
||||
% cat my-url-list > hiper.fifo
|
||||
|
||||
The fifo buffer is handled almost instantly, so you can even add more URL's
|
||||
while the previous requests are still being downloaded.
|
||||
|
||||
Note:
|
||||
For the sake of simplicity, URL length is limited to 1023 char's !
|
||||
|
||||
This is purely a demo app, all retrieved data is simply discarded by the write
|
||||
callback.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/poll.h>
|
||||
#include <curl/curl.h>
|
||||
#include <event.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
#define MSG_OUT stdout /* Send info to stdout, change to stderr if you want */
|
||||
|
||||
|
||||
/* Global information, common to all connections */
|
||||
typedef struct _GlobalInfo {
|
||||
struct event fifo_event;
|
||||
struct event timer_event;
|
||||
CURLM *multi;
|
||||
int still_running;
|
||||
FILE* input;
|
||||
} GlobalInfo;
|
||||
|
||||
|
||||
/* Information associated with a specific easy handle */
|
||||
typedef struct _ConnInfo {
|
||||
CURL *easy;
|
||||
char *url;
|
||||
GlobalInfo *global;
|
||||
char error[CURL_ERROR_SIZE];
|
||||
} ConnInfo;
|
||||
|
||||
|
||||
/* Information associated with a specific socket */
|
||||
typedef struct _SockInfo {
|
||||
curl_socket_t sockfd;
|
||||
CURL *easy;
|
||||
int action;
|
||||
long timeout;
|
||||
struct event ev;
|
||||
int evset;
|
||||
GlobalInfo *global;
|
||||
} SockInfo;
|
||||
|
||||
|
||||
|
||||
/* Update the event timer after curl_multi library calls */
|
||||
static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g)
|
||||
{
|
||||
struct timeval timeout;
|
||||
(void)multi; /* unused */
|
||||
|
||||
timeout.tv_sec = timeout_ms/1000;
|
||||
timeout.tv_usec = (timeout_ms%1000)*1000;
|
||||
fprintf(MSG_OUT, "multi_timer_cb: Setting timeout to %ld ms\n", timeout_ms);
|
||||
evtimer_add(&g->timer_event, &timeout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Die if we get a bad CURLMcode somewhere */
|
||||
static void mcode_or_die(const char *where, CURLMcode code)
|
||||
{
|
||||
if ( CURLM_OK != code ) {
|
||||
const char *s;
|
||||
switch (code) {
|
||||
case CURLM_CALL_MULTI_PERFORM: s="CURLM_CALL_MULTI_PERFORM"; break;
|
||||
case CURLM_BAD_HANDLE: s="CURLM_BAD_HANDLE"; break;
|
||||
case CURLM_BAD_EASY_HANDLE: s="CURLM_BAD_EASY_HANDLE"; break;
|
||||
case CURLM_OUT_OF_MEMORY: s="CURLM_OUT_OF_MEMORY"; break;
|
||||
case CURLM_INTERNAL_ERROR: s="CURLM_INTERNAL_ERROR"; break;
|
||||
case CURLM_UNKNOWN_OPTION: s="CURLM_UNKNOWN_OPTION"; break;
|
||||
case CURLM_LAST: s="CURLM_LAST"; break;
|
||||
default: s="CURLM_unknown";
|
||||
break;
|
||||
case CURLM_BAD_SOCKET: s="CURLM_BAD_SOCKET";
|
||||
fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s);
|
||||
/* ignore this error */
|
||||
return;
|
||||
}
|
||||
fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s);
|
||||
exit(code);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Check for completed transfers, and remove their easy handles */
|
||||
static void check_multi_info(GlobalInfo *g)
|
||||
{
|
||||
char *eff_url;
|
||||
CURLMsg *msg;
|
||||
int msgs_left;
|
||||
ConnInfo *conn;
|
||||
CURL *easy;
|
||||
CURLcode res;
|
||||
|
||||
fprintf(MSG_OUT, "REMAINING: %d\n", g->still_running);
|
||||
while ((msg = curl_multi_info_read(g->multi, &msgs_left))) {
|
||||
if (msg->msg == CURLMSG_DONE) {
|
||||
easy = msg->easy_handle;
|
||||
res = msg->data.result;
|
||||
curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn);
|
||||
curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url);
|
||||
fprintf(MSG_OUT, "DONE: %s => (%d) %s\n", eff_url, res, conn->error);
|
||||
curl_multi_remove_handle(g->multi, easy);
|
||||
free(conn->url);
|
||||
curl_easy_cleanup(easy);
|
||||
free(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Called by libevent when we get action on a multi socket */
|
||||
static void event_cb(int fd, short kind, void *userp)
|
||||
{
|
||||
GlobalInfo *g = (GlobalInfo*) userp;
|
||||
CURLMcode rc;
|
||||
|
||||
int action =
|
||||
(kind & EV_READ ? CURL_CSELECT_IN : 0) |
|
||||
(kind & EV_WRITE ? CURL_CSELECT_OUT : 0);
|
||||
|
||||
rc = curl_multi_socket_action(g->multi, fd, action, &g->still_running);
|
||||
mcode_or_die("event_cb: curl_multi_socket_action", rc);
|
||||
|
||||
check_multi_info(g);
|
||||
if ( g->still_running <= 0 ) {
|
||||
fprintf(MSG_OUT, "last transfer done, kill timeout\n");
|
||||
if (evtimer_pending(&g->timer_event, NULL)) {
|
||||
evtimer_del(&g->timer_event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Called by libevent when our timeout expires */
|
||||
static void timer_cb(int fd, short kind, void *userp)
|
||||
{
|
||||
GlobalInfo *g = (GlobalInfo *)userp;
|
||||
CURLMcode rc;
|
||||
(void)fd;
|
||||
(void)kind;
|
||||
|
||||
rc = curl_multi_socket_action(g->multi,
|
||||
CURL_SOCKET_TIMEOUT, 0, &g->still_running);
|
||||
mcode_or_die("timer_cb: curl_multi_socket_action", rc);
|
||||
check_multi_info(g);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Clean up the SockInfo structure */
|
||||
static void remsock(SockInfo *f)
|
||||
{
|
||||
if (f) {
|
||||
if (f->evset)
|
||||
event_del(&f->ev);
|
||||
free(f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Assign information to a SockInfo structure */
|
||||
static void setsock(SockInfo*f, curl_socket_t s, CURL*e, int act, GlobalInfo*g)
|
||||
{
|
||||
int kind =
|
||||
(act&CURL_POLL_IN?EV_READ:0)|(act&CURL_POLL_OUT?EV_WRITE:0)|EV_PERSIST;
|
||||
|
||||
f->sockfd = s;
|
||||
f->action = act;
|
||||
f->easy = e;
|
||||
if (f->evset)
|
||||
event_del(&f->ev);
|
||||
event_set(&f->ev, f->sockfd, kind, event_cb, g);
|
||||
f->evset=1;
|
||||
event_add(&f->ev, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Initialize a new SockInfo structure */
|
||||
static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g) {
|
||||
SockInfo *fdp = calloc(sizeof(SockInfo), 1);
|
||||
|
||||
fdp->global = g;
|
||||
setsock(fdp, s, easy, action, g);
|
||||
curl_multi_assign(g->multi, s, fdp);
|
||||
}
|
||||
|
||||
/* CURLMOPT_SOCKETFUNCTION */
|
||||
static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
|
||||
{
|
||||
GlobalInfo *g = (GlobalInfo*) cbp;
|
||||
SockInfo *fdp = (SockInfo*) sockp;
|
||||
const char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE" };
|
||||
|
||||
fprintf(MSG_OUT,
|
||||
"socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]);
|
||||
if (what == CURL_POLL_REMOVE) {
|
||||
fprintf(MSG_OUT, "\n");
|
||||
remsock(fdp);
|
||||
}
|
||||
else {
|
||||
if (!fdp) {
|
||||
fprintf(MSG_OUT, "Adding data: %s\n", whatstr[what]);
|
||||
addsock(s, e, what, g);
|
||||
}
|
||||
else {
|
||||
fprintf(MSG_OUT,
|
||||
"Changing action from %s to %s\n",
|
||||
whatstr[fdp->action], whatstr[what]);
|
||||
setsock(fdp, s, e, what, g);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* CURLOPT_WRITEFUNCTION */
|
||||
static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
size_t realsize = size * nmemb;
|
||||
ConnInfo *conn = (ConnInfo*) data;
|
||||
(void)ptr;
|
||||
(void)conn;
|
||||
return realsize;
|
||||
}
|
||||
|
||||
|
||||
/* CURLOPT_PROGRESSFUNCTION */
|
||||
static int prog_cb (void *p, double dltotal, double dlnow, double ult,
|
||||
double uln)
|
||||
{
|
||||
ConnInfo *conn = (ConnInfo *)p;
|
||||
(void)ult;
|
||||
(void)uln;
|
||||
|
||||
fprintf(MSG_OUT, "Progress: %s (%g/%g)\n", conn->url, dlnow, dltotal);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Create a new easy handle, and add it to the global curl_multi */
|
||||
static void new_conn(char *url, GlobalInfo *g )
|
||||
{
|
||||
ConnInfo *conn;
|
||||
CURLMcode rc;
|
||||
|
||||
conn = calloc(1, sizeof(ConnInfo));
|
||||
memset(conn, 0, sizeof(ConnInfo));
|
||||
conn->error[0]='\0';
|
||||
|
||||
conn->easy = curl_easy_init();
|
||||
if (!conn->easy) {
|
||||
fprintf(MSG_OUT, "curl_easy_init() failed, exiting!\n");
|
||||
exit(2);
|
||||
}
|
||||
conn->global = g;
|
||||
conn->url = strdup(url);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, &conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_NOPROGRESS, 0L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSFUNCTION, prog_cb);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSDATA, conn);
|
||||
fprintf(MSG_OUT,
|
||||
"Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url);
|
||||
rc = curl_multi_add_handle(g->multi, conn->easy);
|
||||
mcode_or_die("new_conn: curl_multi_add_handle", rc);
|
||||
|
||||
/* note that the add_handle() will set a time-out to trigger very soon so
|
||||
that the necessary socket_action() call will be called by this app */
|
||||
}
|
||||
|
||||
/* This gets called whenever data is received from the fifo */
|
||||
static void fifo_cb(int fd, short event, void *arg)
|
||||
{
|
||||
char s[1024];
|
||||
long int rv=0;
|
||||
int n=0;
|
||||
GlobalInfo *g = (GlobalInfo *)arg;
|
||||
(void)fd; /* unused */
|
||||
(void)event; /* unused */
|
||||
|
||||
do {
|
||||
s[0]='\0';
|
||||
rv=fscanf(g->input, "%1023s%n", s, &n);
|
||||
s[n]='\0';
|
||||
if ( n && s[0] ) {
|
||||
new_conn(s,arg); /* if we read a URL, go get it! */
|
||||
} else break;
|
||||
} while ( rv != EOF);
|
||||
}
|
||||
|
||||
/* Create a named pipe and tell libevent to monitor it */
|
||||
static int init_fifo (GlobalInfo *g)
|
||||
{
|
||||
struct stat st;
|
||||
static const char *fifo = "hiper.fifo";
|
||||
curl_socket_t sockfd;
|
||||
|
||||
fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo);
|
||||
if (lstat (fifo, &st) == 0) {
|
||||
if ((st.st_mode & S_IFMT) == S_IFREG) {
|
||||
errno = EEXIST;
|
||||
perror("lstat");
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
unlink(fifo);
|
||||
if (mkfifo (fifo, 0600) == -1) {
|
||||
perror("mkfifo");
|
||||
exit (1);
|
||||
}
|
||||
sockfd = open(fifo, O_RDWR | O_NONBLOCK, 0);
|
||||
if (sockfd == -1) {
|
||||
perror("open");
|
||||
exit (1);
|
||||
}
|
||||
g->input = fdopen(sockfd, "r");
|
||||
|
||||
fprintf(MSG_OUT, "Now, pipe some URL's into > %s\n", fifo);
|
||||
event_set(&g->fifo_event, sockfd, EV_READ | EV_PERSIST, fifo_cb, g);
|
||||
event_add(&g->fifo_event, NULL);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
GlobalInfo g;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
memset(&g, 0, sizeof(GlobalInfo));
|
||||
event_init();
|
||||
init_fifo(&g);
|
||||
g.multi = curl_multi_init();
|
||||
evtimer_set(&g.timer_event, timer_cb, &g);
|
||||
|
||||
/* setup the generic multi interface options we want */
|
||||
curl_multi_setopt(g.multi, CURLMOPT_SOCKETFUNCTION, sock_cb);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_SOCKETDATA, &g);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_TIMERFUNCTION, multi_timer_cb);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_TIMERDATA, &g);
|
||||
|
||||
/* we don't call any curl_multi_socket*() function yet as we have no handles
|
||||
added! */
|
||||
|
||||
event_dispatch();
|
||||
curl_multi_cleanup(g.multi);
|
||||
return 0;
|
||||
}
|
||||
117
third-party/curl-7.21.4/docs/examples/htmltidy.c
vendored
Normal file
117
third-party/curl-7.21.4/docs/examples/htmltidy.c
vendored
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*
|
||||
* Download a document and use libtidy to parse the HTML.
|
||||
* Written by Jeff Pohlmeyer
|
||||
*
|
||||
* LibTidy => http://tidy.sourceforge.net
|
||||
*
|
||||
* gcc -Wall -I/usr/local/include tidycurl.c -lcurl -ltidy -o tidycurl
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <tidy/tidy.h>
|
||||
#include <tidy/buffio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* curl write callback, to fill tidy's input buffer... */
|
||||
uint write_cb(char *in, uint size, uint nmemb, TidyBuffer *out)
|
||||
{
|
||||
uint r;
|
||||
r = size * nmemb;
|
||||
tidyBufAppend( out, in, r );
|
||||
return(r);
|
||||
}
|
||||
|
||||
/* Traverse the document tree */
|
||||
void dumpNode(TidyDoc doc, TidyNode tnod, int indent )
|
||||
{
|
||||
TidyNode child;
|
||||
for ( child = tidyGetChild(tnod); child; child = tidyGetNext(child) )
|
||||
{
|
||||
ctmbstr name = tidyNodeGetName( child );
|
||||
if ( name )
|
||||
{
|
||||
/* if it has a name, then it's an HTML tag ... */
|
||||
TidyAttr attr;
|
||||
printf( "%*.*s%s ", indent, indent, "<", name);
|
||||
/* walk the attribute list */
|
||||
for ( attr=tidyAttrFirst(child); attr; attr=tidyAttrNext(attr) ) {
|
||||
printf(tidyAttrName(attr));
|
||||
tidyAttrValue(attr)?printf("=\"%s\" ",
|
||||
tidyAttrValue(attr)):printf(" ");
|
||||
}
|
||||
printf( ">\n");
|
||||
}
|
||||
else {
|
||||
/* if it doesn't have a name, then it's probably text, cdata, etc... */
|
||||
TidyBuffer buf;
|
||||
tidyBufInit(&buf);
|
||||
tidyNodeGetText(doc, child, &buf);
|
||||
printf("%*.*s\n", indent, indent, buf.bp?(char *)buf.bp:"");
|
||||
tidyBufFree(&buf);
|
||||
}
|
||||
dumpNode( doc, child, indent + 4 ); /* recursive */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv )
|
||||
{
|
||||
CURL *curl;
|
||||
char curl_errbuf[CURL_ERROR_SIZE];
|
||||
TidyDoc tdoc;
|
||||
TidyBuffer docbuf = {0};
|
||||
TidyBuffer tidy_errbuf = {0};
|
||||
int err;
|
||||
if ( argc == 2) {
|
||||
curl = curl_easy_init();
|
||||
curl_easy_setopt(curl, CURLOPT_URL, argv[1]);
|
||||
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_errbuf);
|
||||
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
|
||||
|
||||
tdoc = tidyCreate();
|
||||
tidyOptSetBool(tdoc, TidyForceOutput, yes); /* try harder */
|
||||
tidyOptSetInt(tdoc, TidyWrapLen, 4096);
|
||||
tidySetErrorBuffer( tdoc, &tidy_errbuf );
|
||||
tidyBufInit(&docbuf);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &docbuf);
|
||||
err=curl_easy_perform(curl);
|
||||
if ( !err ) {
|
||||
err = tidyParseBuffer(tdoc, &docbuf); /* parse the input */
|
||||
if ( err >= 0 ) {
|
||||
err = tidyCleanAndRepair(tdoc); /* fix any problems */
|
||||
if ( err >= 0 ) {
|
||||
err = tidyRunDiagnostics(tdoc); /* load tidy error buffer */
|
||||
if ( err >= 0 ) {
|
||||
dumpNode( tdoc, tidyGetRoot(tdoc), 0 ); /* walk the tree */
|
||||
fprintf(stderr, "%s\n", tidy_errbuf.bp); /* show errors */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "%s\n", curl_errbuf);
|
||||
|
||||
/* clean-up */
|
||||
curl_easy_cleanup(curl);
|
||||
tidyBufFree(&docbuf);
|
||||
tidyBufFree(&tidy_errbuf);
|
||||
tidyRelease(tdoc);
|
||||
return(err);
|
||||
|
||||
}
|
||||
else
|
||||
printf( "usage: %s <url>\n", argv[0] );
|
||||
|
||||
return(0);
|
||||
}
|
||||
301
third-party/curl-7.21.4/docs/examples/htmltitle.cc
vendored
Normal file
301
third-party/curl-7.21.4/docs/examples/htmltitle.cc
vendored
Normal file
|
|
@ -0,0 +1,301 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*/
|
||||
|
||||
// Get a web page, parse it with libxml.
|
||||
//
|
||||
// Written by Lars Nilsson
|
||||
//
|
||||
// GNU C++ compile command line suggestion (edit paths accordingly):
|
||||
//
|
||||
// g++ -Wall -I/opt/curl/include -I/opt/libxml/include/libxml2 htmltitle.cc \
|
||||
// -o htmltitle -L/opt/curl/lib -L/opt/libxml/lib -lcurl -lxml2
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include <curl/curl.h>
|
||||
#include <libxml/HTMLparser.h>
|
||||
|
||||
//
|
||||
// Case-insensitive string comparison
|
||||
//
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define COMPARE(a, b) (!stricmp((a), (b)))
|
||||
#else
|
||||
#define COMPARE(a, b) (!strcasecmp((a), (b)))
|
||||
#endif
|
||||
|
||||
//
|
||||
// libxml callback context structure
|
||||
//
|
||||
|
||||
struct Context
|
||||
{
|
||||
Context(): addTitle(false) { }
|
||||
|
||||
bool addTitle;
|
||||
std::string title;
|
||||
};
|
||||
|
||||
//
|
||||
// libcurl variables for error strings and returned data
|
||||
|
||||
static char errorBuffer[CURL_ERROR_SIZE];
|
||||
static std::string buffer;
|
||||
|
||||
//
|
||||
// libcurl write callback function
|
||||
//
|
||||
|
||||
static int writer(char *data, size_t size, size_t nmemb,
|
||||
std::string *writerData)
|
||||
{
|
||||
if (writerData == NULL)
|
||||
return 0;
|
||||
|
||||
writerData->append(data, size*nmemb);
|
||||
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
//
|
||||
// libcurl connection initialization
|
||||
//
|
||||
|
||||
static bool init(CURL *&conn, char *url)
|
||||
{
|
||||
CURLcode code;
|
||||
|
||||
conn = curl_easy_init();
|
||||
|
||||
if (conn == NULL)
|
||||
{
|
||||
fprintf(stderr, "Failed to create CURL connection\n");
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
code = curl_easy_setopt(conn, CURLOPT_ERRORBUFFER, errorBuffer);
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to set error buffer [%d]\n", code);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
code = curl_easy_setopt(conn, CURLOPT_URL, url);
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to set URL [%s]\n", errorBuffer);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
code = curl_easy_setopt(conn, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to set redirect option [%s]\n", errorBuffer);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
code = curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writer);
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to set writer [%s]\n", errorBuffer);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
code = curl_easy_setopt(conn, CURLOPT_WRITEDATA, &buffer);
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to set write data [%s]\n", errorBuffer);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// libxml start element callback function
|
||||
//
|
||||
|
||||
static void StartElement(void *voidContext,
|
||||
const xmlChar *name,
|
||||
const xmlChar **attributes)
|
||||
{
|
||||
Context *context = (Context *)voidContext;
|
||||
|
||||
if (COMPARE((char *)name, "TITLE"))
|
||||
{
|
||||
context->title = "";
|
||||
context->addTitle = true;
|
||||
}
|
||||
(void) attributes;
|
||||
}
|
||||
|
||||
//
|
||||
// libxml end element callback function
|
||||
//
|
||||
|
||||
static void EndElement(void *voidContext,
|
||||
const xmlChar *name)
|
||||
{
|
||||
Context *context = (Context *)voidContext;
|
||||
|
||||
if (COMPARE((char *)name, "TITLE"))
|
||||
context->addTitle = false;
|
||||
}
|
||||
|
||||
//
|
||||
// Text handling helper function
|
||||
//
|
||||
|
||||
static void handleCharacters(Context *context,
|
||||
const xmlChar *chars,
|
||||
int length)
|
||||
{
|
||||
if (context->addTitle)
|
||||
context->title.append((char *)chars, length);
|
||||
}
|
||||
|
||||
//
|
||||
// libxml PCDATA callback function
|
||||
//
|
||||
|
||||
static void Characters(void *voidContext,
|
||||
const xmlChar *chars,
|
||||
int length)
|
||||
{
|
||||
Context *context = (Context *)voidContext;
|
||||
|
||||
handleCharacters(context, chars, length);
|
||||
}
|
||||
|
||||
//
|
||||
// libxml CDATA callback function
|
||||
//
|
||||
|
||||
static void cdata(void *voidContext,
|
||||
const xmlChar *chars,
|
||||
int length)
|
||||
{
|
||||
Context *context = (Context *)voidContext;
|
||||
|
||||
handleCharacters(context, chars, length);
|
||||
}
|
||||
|
||||
//
|
||||
// libxml SAX callback structure
|
||||
//
|
||||
|
||||
static htmlSAXHandler saxHandler =
|
||||
{
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
StartElement,
|
||||
EndElement,
|
||||
NULL,
|
||||
Characters,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
cdata,
|
||||
NULL
|
||||
};
|
||||
|
||||
//
|
||||
// Parse given (assumed to be) HTML text and return the title
|
||||
//
|
||||
|
||||
static void parseHtml(const std::string &html,
|
||||
std::string &title)
|
||||
{
|
||||
htmlParserCtxtPtr ctxt;
|
||||
Context context;
|
||||
|
||||
ctxt = htmlCreatePushParserCtxt(&saxHandler, &context, "", 0, "",
|
||||
XML_CHAR_ENCODING_NONE);
|
||||
|
||||
htmlParseChunk(ctxt, html.c_str(), html.size(), 0);
|
||||
htmlParseChunk(ctxt, "", 0, 1);
|
||||
|
||||
htmlFreeParserCtxt(ctxt);
|
||||
|
||||
title = context.title;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
CURL *conn = NULL;
|
||||
CURLcode code;
|
||||
std::string title;
|
||||
|
||||
// Ensure one argument is given
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s <url>\n", argv[0]);
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
// Initialize CURL connection
|
||||
|
||||
if (!init(conn, argv[1]))
|
||||
{
|
||||
fprintf(stderr, "Connection initializion failed\n");
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Retrieve content for the URL
|
||||
|
||||
code = curl_easy_perform(conn);
|
||||
curl_easy_cleanup(conn);
|
||||
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to get '%s' [%s]\n", argv[1], errorBuffer);
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Parse the (assumed) HTML code
|
||||
|
||||
parseHtml(buffer, title);
|
||||
|
||||
// Display the extracted title
|
||||
|
||||
printf("Title: %s\n", title.c_str());
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
34
third-party/curl-7.21.4/docs/examples/http-post.c
vendored
Normal file
34
third-party/curl-7.21.4/docs/examples/http-post.c
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* First set the URL that is about to receive our POST. This URL can
|
||||
just as well be a https:// URL if that is what should receive the
|
||||
data. */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "http://postit.example.com/moo.cgi");
|
||||
/* Now specify the POST data */
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "name=daniel&project=curl");
|
||||
|
||||
/* Perform the request, res will get the return code */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
38
third-party/curl-7.21.4/docs/examples/httpcustomheader.c
vendored
Normal file
38
third-party/curl-7.21.4/docs/examples/httpcustomheader.c
vendored
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
struct curl_slist *chunk = NULL;
|
||||
|
||||
chunk = curl_slist_append(chunk, "Accept: moo");
|
||||
chunk = curl_slist_append(chunk, "Another: yes");
|
||||
|
||||
/* request with the built-in Accept: */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "localhost");
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* redo request with our own custom Accept: */
|
||||
res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
105
third-party/curl-7.21.4/docs/examples/httpput.c
vendored
Normal file
105
third-party/curl-7.21.4/docs/examples/httpput.c
vendored
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
/*
|
||||
* This example shows a HTTP PUT operation. PUTs a file given as a command
|
||||
* line argument to the URL also given on the command line.
|
||||
*
|
||||
* This example also uses its own read callback.
|
||||
*
|
||||
* Here's an article on how to setup a PUT handler for Apache:
|
||||
* http://www.apacheweek.com/features/put
|
||||
*/
|
||||
|
||||
static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
size_t retcode;
|
||||
|
||||
/* in real-world cases, this would probably get this data differently
|
||||
as this fread() stuff is exactly what the library already would do
|
||||
by default internally */
|
||||
retcode = fread(ptr, size, nmemb, stream);
|
||||
|
||||
fprintf(stderr, "*** We read %d bytes from file\n", retcode);
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
FILE * hd_src ;
|
||||
int hd ;
|
||||
struct stat file_info;
|
||||
|
||||
char *file;
|
||||
char *url;
|
||||
|
||||
if(argc < 3)
|
||||
return 1;
|
||||
|
||||
file= argv[1];
|
||||
url = argv[2];
|
||||
|
||||
/* get the file size of the local file */
|
||||
hd = open(file, O_RDONLY) ;
|
||||
fstat(hd, &file_info);
|
||||
close(hd) ;
|
||||
|
||||
/* get a FILE * of the same file, could also be made with
|
||||
fdopen() from the previous descriptor, but hey this is just
|
||||
an example! */
|
||||
hd_src = fopen(file, "rb");
|
||||
|
||||
/* In windows, this will init the winsock stuff */
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
/* get a curl handle */
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* we want to use our own read function */
|
||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
|
||||
|
||||
/* enable uploading */
|
||||
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
|
||||
|
||||
/* HTTP PUT please */
|
||||
curl_easy_setopt(curl, CURLOPT_PUT, 1L);
|
||||
|
||||
/* specify target URL, and note that this URL should include a file
|
||||
name, not only a directory */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
|
||||
/* now specify which file to upload */
|
||||
curl_easy_setopt(curl, CURLOPT_READDATA, hd_src);
|
||||
|
||||
/* provide the size of the upload, we specicially typecast the value
|
||||
to curl_off_t since we must be sure to use the correct data size */
|
||||
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
|
||||
(curl_off_t)file_info.st_size);
|
||||
|
||||
/* Now run off and do what you've been told! */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
fclose(hd_src); /* close the local file */
|
||||
|
||||
curl_global_cleanup();
|
||||
return 0;
|
||||
}
|
||||
52
third-party/curl-7.21.4/docs/examples/https.c
vendored
Normal file
52
third-party/curl-7.21.4/docs/examples/https.c
vendored
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");
|
||||
|
||||
#ifdef SKIP_PEER_VERIFICATION
|
||||
/*
|
||||
* If you want to connect to a site who isn't using a certificate that is
|
||||
* signed by one of the certs in the CA bundle you have, you can skip the
|
||||
* verification of the server's certificate. This makes the connection
|
||||
* A LOT LESS SECURE.
|
||||
*
|
||||
* If you have a CA cert for the server stored someplace else than in the
|
||||
* default bundle, then the CURLOPT_CAPATH option might come handy for
|
||||
* you.
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
#endif
|
||||
|
||||
#ifdef SKIP_HOSTNAME_VERFICATION
|
||||
/*
|
||||
* If the site you're connecting to uses a different host name that what
|
||||
* they have mentioned in their server certificate's commonName (or
|
||||
* subjectAltName) fields, libcurl will refuse to connect. You can skip
|
||||
* this check, but this will make the connection less secure.
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
#endif
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
39
third-party/curl-7.21.4/docs/examples/makefile.dj
vendored
Normal file
39
third-party/curl-7.21.4/docs/examples/makefile.dj
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#
|
||||
# Adapted for djgpp / Watt-32 / DOS by
|
||||
# Gisle Vanem <giva@bgnett.no>
|
||||
#
|
||||
|
||||
TOPDIR = ../..
|
||||
|
||||
include $(TOPDIR)/packages/DOS/common.dj
|
||||
|
||||
CFLAGS += -DFALSE=0 -DTRUE=1
|
||||
|
||||
LIBS = $(TOPDIR)/lib/libcurl.a
|
||||
|
||||
ifeq ($(USE_SSL),1)
|
||||
LIBS += $(OPENSSL_ROOT)/lib/libssl.a $(OPENSSL_ROOT)/lib/libcrypt.a
|
||||
endif
|
||||
|
||||
ifeq ($(USE_IDNA),1)
|
||||
LIBS += $(LIBIDN_ROOT)/lib/dj_obj/libidn.a -liconv
|
||||
endif
|
||||
|
||||
LIBS += $(WATT32_ROOT)/lib/libwatt.a $(ZLIB_ROOT)/libz.a
|
||||
|
||||
include Makefile.inc
|
||||
|
||||
PROGRAMS = $(patsubst %,%.exe,$(check_PROGRAMS))
|
||||
|
||||
all: $(PROGRAMS)
|
||||
@echo Welcome to libcurl example program
|
||||
|
||||
%.exe: %.c
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
|
||||
@echo
|
||||
|
||||
clean vclean realclean:
|
||||
- rm -f $(PROGRAMS) depend.dj
|
||||
|
||||
-include depend.dj
|
||||
|
||||
141
third-party/curl-7.21.4/docs/examples/multi-app.c
vendored
Normal file
141
third-party/curl-7.21.4/docs/examples/multi-app.c
vendored
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*
|
||||
* This is an example application source code using the multi interface.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* somewhat unix-specific */
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* curl stuff */
|
||||
#include <curl/curl.h>
|
||||
|
||||
/*
|
||||
* Download a HTTP file and upload an FTP file simultaneously.
|
||||
*/
|
||||
|
||||
#define HANDLECOUNT 2 /* Number of simultaneous transfers */
|
||||
#define HTTP_HANDLE 0 /* Index for the HTTP transfer */
|
||||
#define FTP_HANDLE 1 /* Index for the FTP transfer */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *handles[HANDLECOUNT];
|
||||
CURLM *multi_handle;
|
||||
|
||||
int still_running; /* keep number of running handles */
|
||||
int i;
|
||||
|
||||
CURLMsg *msg; /* for picking up messages with the transfer status */
|
||||
int msgs_left; /* how many messages are left */
|
||||
|
||||
/* Allocate one CURL handle per transfer */
|
||||
for (i=0; i<HANDLECOUNT; i++)
|
||||
handles[i] = curl_easy_init();
|
||||
|
||||
/* set the options (I left out a few, you'll get the point anyway) */
|
||||
curl_easy_setopt(handles[HTTP_HANDLE], CURLOPT_URL, "http://example.com");
|
||||
|
||||
curl_easy_setopt(handles[FTP_HANDLE], CURLOPT_URL, "ftp://example.com");
|
||||
curl_easy_setopt(handles[FTP_HANDLE], CURLOPT_UPLOAD, 1L);
|
||||
|
||||
/* init a multi stack */
|
||||
multi_handle = curl_multi_init();
|
||||
|
||||
/* add the individual transfers */
|
||||
for (i=0; i<HANDLECOUNT; i++)
|
||||
curl_multi_add_handle(multi_handle, handles[i]);
|
||||
|
||||
/* we start some action by calling perform right away */
|
||||
curl_multi_perform(multi_handle, &still_running);
|
||||
|
||||
while(still_running) {
|
||||
struct timeval timeout;
|
||||
int rc; /* select() return code */
|
||||
|
||||
fd_set fdread;
|
||||
fd_set fdwrite;
|
||||
fd_set fdexcep;
|
||||
int maxfd = -1;
|
||||
|
||||
long curl_timeo = -1;
|
||||
|
||||
FD_ZERO(&fdread);
|
||||
FD_ZERO(&fdwrite);
|
||||
FD_ZERO(&fdexcep);
|
||||
|
||||
/* set a suitable timeout to play around with */
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
curl_multi_timeout(multi_handle, &curl_timeo);
|
||||
if(curl_timeo >= 0) {
|
||||
timeout.tv_sec = curl_timeo / 1000;
|
||||
if(timeout.tv_sec > 1)
|
||||
timeout.tv_sec = 1;
|
||||
else
|
||||
timeout.tv_usec = (curl_timeo % 1000) * 1000;
|
||||
}
|
||||
|
||||
/* get file descriptors from the transfers */
|
||||
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||
|
||||
/* In a real-world program you OF COURSE check the return code of the
|
||||
function calls. On success, the value of maxfd is guaranteed to be
|
||||
greater or equal than -1. We call select(maxfd + 1, ...), specially in
|
||||
case of (maxfd == -1), we call select(0, ...), which is basically equal
|
||||
to sleep. */
|
||||
|
||||
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||
|
||||
switch(rc) {
|
||||
case -1:
|
||||
/* select error */
|
||||
break;
|
||||
case 0: /* timeout */
|
||||
default: /* action */
|
||||
curl_multi_perform(multi_handle, &still_running);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* See how the transfers went */
|
||||
while ((msg = curl_multi_info_read(multi_handle, &msgs_left))) {
|
||||
if (msg->msg == CURLMSG_DONE) {
|
||||
int idx, found = 0;
|
||||
|
||||
/* Find out which handle this message is about */
|
||||
for (idx=0; idx<HANDLECOUNT; idx++) {
|
||||
found = (msg->easy_handle == handles[idx]);
|
||||
if(found)
|
||||
break;
|
||||
}
|
||||
|
||||
switch (idx) {
|
||||
case HTTP_HANDLE:
|
||||
printf("HTTP transfer completed with status %d\n", msg->data.result);
|
||||
break;
|
||||
case FTP_HANDLE:
|
||||
printf("FTP transfer completed with status %d\n", msg->data.result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
curl_multi_cleanup(multi_handle);
|
||||
|
||||
/* Free the CURL handles */
|
||||
for (i=0; i<HANDLECOUNT; i++)
|
||||
curl_easy_cleanup(handles[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
194
third-party/curl-7.21.4/docs/examples/multi-debugcallback.c
vendored
Normal file
194
third-party/curl-7.21.4/docs/examples/multi-debugcallback.c
vendored
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*
|
||||
* This is a very simple example using the multi interface and the debug
|
||||
* callback.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* somewhat unix-specific */
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* curl stuff */
|
||||
#include <curl/curl.h>
|
||||
|
||||
typedef char bool;
|
||||
#define TRUE 1
|
||||
|
||||
static
|
||||
void dump(const char *text,
|
||||
FILE *stream, unsigned char *ptr, size_t size,
|
||||
bool nohex)
|
||||
{
|
||||
size_t i;
|
||||
size_t c;
|
||||
|
||||
unsigned int width=0x10;
|
||||
|
||||
if(nohex)
|
||||
/* without the hex output, we can fit more on screen */
|
||||
width = 0x40;
|
||||
|
||||
fprintf(stream, "%s, %10.10ld bytes (0x%8.8lx)\n",
|
||||
text, (long)size, (long)size);
|
||||
|
||||
for(i=0; i<size; i+= width) {
|
||||
|
||||
fprintf(stream, "%4.4lx: ", (long)i);
|
||||
|
||||
if(!nohex) {
|
||||
/* hex not disabled, show it */
|
||||
for(c = 0; c < width; c++)
|
||||
if(i+c < size)
|
||||
fprintf(stream, "%02x ", ptr[i+c]);
|
||||
else
|
||||
fputs(" ", stream);
|
||||
}
|
||||
|
||||
for(c = 0; (c < width) && (i+c < size); c++) {
|
||||
/* check for 0D0A; if found, skip past and start a new line of output */
|
||||
if (nohex && (i+c+1 < size) && ptr[i+c]==0x0D && ptr[i+c+1]==0x0A) {
|
||||
i+=(c+2-width);
|
||||
break;
|
||||
}
|
||||
fprintf(stream, "%c",
|
||||
(ptr[i+c]>=0x20) && (ptr[i+c]<0x80)?ptr[i+c]:'.');
|
||||
/* check again for 0D0A, to avoid an extra \n if it's at width */
|
||||
if (nohex && (i+c+2 < size) && ptr[i+c+1]==0x0D && ptr[i+c+2]==0x0A) {
|
||||
i+=(c+3-width);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fputc('\n', stream); /* newline */
|
||||
}
|
||||
fflush(stream);
|
||||
}
|
||||
|
||||
static
|
||||
int my_trace(CURL *handle, curl_infotype type,
|
||||
unsigned char *data, size_t size,
|
||||
void *userp)
|
||||
{
|
||||
const char *text;
|
||||
|
||||
(void)userp;
|
||||
(void)handle; /* prevent compiler warning */
|
||||
|
||||
switch (type) {
|
||||
case CURLINFO_TEXT:
|
||||
fprintf(stderr, "== Info: %s", data);
|
||||
default: /* in case a new one is introduced to shock us */
|
||||
return 0;
|
||||
|
||||
case CURLINFO_HEADER_OUT:
|
||||
text = "=> Send header";
|
||||
break;
|
||||
case CURLINFO_DATA_OUT:
|
||||
text = "=> Send data";
|
||||
break;
|
||||
case CURLINFO_HEADER_IN:
|
||||
text = "<= Recv header";
|
||||
break;
|
||||
case CURLINFO_DATA_IN:
|
||||
text = "<= Recv data";
|
||||
break;
|
||||
}
|
||||
|
||||
dump(text, stderr, data, size, TRUE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Simply download a HTTP file.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
CURL *http_handle;
|
||||
CURLM *multi_handle;
|
||||
|
||||
int still_running; /* keep number of running handles */
|
||||
|
||||
http_handle = curl_easy_init();
|
||||
|
||||
/* set the options (I left out a few, you'll get the point anyway) */
|
||||
curl_easy_setopt(http_handle, CURLOPT_URL, "http://www.example.com/");
|
||||
|
||||
curl_easy_setopt(http_handle, CURLOPT_DEBUGFUNCTION, my_trace);
|
||||
curl_easy_setopt(http_handle, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
/* init a multi stack */
|
||||
multi_handle = curl_multi_init();
|
||||
|
||||
/* add the individual transfers */
|
||||
curl_multi_add_handle(multi_handle, http_handle);
|
||||
|
||||
/* we start some action by calling perform right away */
|
||||
curl_multi_perform(multi_handle, &still_running);
|
||||
|
||||
while(still_running) {
|
||||
struct timeval timeout;
|
||||
int rc; /* select() return code */
|
||||
|
||||
fd_set fdread;
|
||||
fd_set fdwrite;
|
||||
fd_set fdexcep;
|
||||
int maxfd = -1;
|
||||
|
||||
long curl_timeo = -1;
|
||||
|
||||
FD_ZERO(&fdread);
|
||||
FD_ZERO(&fdwrite);
|
||||
FD_ZERO(&fdexcep);
|
||||
|
||||
/* set a suitable timeout to play around with */
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
curl_multi_timeout(multi_handle, &curl_timeo);
|
||||
if(curl_timeo >= 0) {
|
||||
timeout.tv_sec = curl_timeo / 1000;
|
||||
if(timeout.tv_sec > 1)
|
||||
timeout.tv_sec = 1;
|
||||
else
|
||||
timeout.tv_usec = (curl_timeo % 1000) * 1000;
|
||||
}
|
||||
|
||||
/* get file descriptors from the transfers */
|
||||
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||
|
||||
/* In a real-world program you OF COURSE check the return code of the
|
||||
function calls. On success, the value of maxfd is guaranteed to be
|
||||
greater or equal than -1. We call select(maxfd + 1, ...), specially in
|
||||
case of (maxfd == -1), we call select(0, ...), which is basically equal
|
||||
to sleep. */
|
||||
|
||||
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||
|
||||
switch(rc) {
|
||||
case -1:
|
||||
/* select error */
|
||||
still_running = 0;
|
||||
printf("select() returns error, this is badness\n");
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
/* timeout or readable/writable sockets */
|
||||
curl_multi_perform(multi_handle, &still_running);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
curl_multi_cleanup(multi_handle);
|
||||
|
||||
curl_easy_cleanup(http_handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
109
third-party/curl-7.21.4/docs/examples/multi-double.c
vendored
Normal file
109
third-party/curl-7.21.4/docs/examples/multi-double.c
vendored
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*
|
||||
* This is a very simple example using the multi interface.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* somewhat unix-specific */
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* curl stuff */
|
||||
#include <curl/curl.h>
|
||||
|
||||
/*
|
||||
* Simply download two HTTP files!
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
CURL *http_handle;
|
||||
CURL *http_handle2;
|
||||
CURLM *multi_handle;
|
||||
|
||||
int still_running; /* keep number of running handles */
|
||||
|
||||
http_handle = curl_easy_init();
|
||||
http_handle2 = curl_easy_init();
|
||||
|
||||
/* set options */
|
||||
curl_easy_setopt(http_handle, CURLOPT_URL, "http://www.example.com/");
|
||||
|
||||
/* set options */
|
||||
curl_easy_setopt(http_handle2, CURLOPT_URL, "http://localhost/");
|
||||
|
||||
/* init a multi stack */
|
||||
multi_handle = curl_multi_init();
|
||||
|
||||
/* add the individual transfers */
|
||||
curl_multi_add_handle(multi_handle, http_handle);
|
||||
curl_multi_add_handle(multi_handle, http_handle2);
|
||||
|
||||
/* we start some action by calling perform right away */
|
||||
curl_multi_perform(multi_handle, &still_running);
|
||||
|
||||
while(still_running) {
|
||||
struct timeval timeout;
|
||||
int rc; /* select() return code */
|
||||
|
||||
fd_set fdread;
|
||||
fd_set fdwrite;
|
||||
fd_set fdexcep;
|
||||
int maxfd = -1;
|
||||
|
||||
long curl_timeo = -1;
|
||||
|
||||
FD_ZERO(&fdread);
|
||||
FD_ZERO(&fdwrite);
|
||||
FD_ZERO(&fdexcep);
|
||||
|
||||
/* set a suitable timeout to play around with */
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
curl_multi_timeout(multi_handle, &curl_timeo);
|
||||
if(curl_timeo >= 0) {
|
||||
timeout.tv_sec = curl_timeo / 1000;
|
||||
if(timeout.tv_sec > 1)
|
||||
timeout.tv_sec = 1;
|
||||
else
|
||||
timeout.tv_usec = (curl_timeo % 1000) * 1000;
|
||||
}
|
||||
|
||||
/* get file descriptors from the transfers */
|
||||
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||
|
||||
/* In a real-world program you OF COURSE check the return code of the
|
||||
function calls. On success, the value of maxfd is guaranteed to be
|
||||
greater or equal than -1. We call select(maxfd + 1, ...), specially in
|
||||
case of (maxfd == -1), we call select(0, ...), which is basically equal
|
||||
to sleep. */
|
||||
|
||||
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||
|
||||
switch(rc) {
|
||||
case -1:
|
||||
/* select error */
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
/* timeout or readable/writable sockets */
|
||||
curl_multi_perform(multi_handle, &still_running);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
curl_multi_cleanup(multi_handle);
|
||||
|
||||
curl_easy_cleanup(http_handle);
|
||||
curl_easy_cleanup(http_handle2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
136
third-party/curl-7.21.4/docs/examples/multi-post.c
vendored
Normal file
136
third-party/curl-7.21.4/docs/examples/multi-post.c
vendored
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*
|
||||
* This is an example application source code using the multi interface
|
||||
* to do a multipart formpost without "blocking".
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
|
||||
CURLM *multi_handle;
|
||||
int still_running;
|
||||
|
||||
struct curl_httppost *formpost=NULL;
|
||||
struct curl_httppost *lastptr=NULL;
|
||||
struct curl_slist *headerlist=NULL;
|
||||
static const char buf[] = "Expect:";
|
||||
|
||||
/* Fill in the file upload field. This makes libcurl load data from
|
||||
the given file name when curl_easy_perform() is called. */
|
||||
curl_formadd(&formpost,
|
||||
&lastptr,
|
||||
CURLFORM_COPYNAME, "sendfile",
|
||||
CURLFORM_FILE, "postit2.c",
|
||||
CURLFORM_END);
|
||||
|
||||
/* Fill in the filename field */
|
||||
curl_formadd(&formpost,
|
||||
&lastptr,
|
||||
CURLFORM_COPYNAME, "filename",
|
||||
CURLFORM_COPYCONTENTS, "postit2.c",
|
||||
CURLFORM_END);
|
||||
|
||||
/* Fill in the submit field too, even if this is rarely needed */
|
||||
curl_formadd(&formpost,
|
||||
&lastptr,
|
||||
CURLFORM_COPYNAME, "submit",
|
||||
CURLFORM_COPYCONTENTS, "send",
|
||||
CURLFORM_END);
|
||||
|
||||
curl = curl_easy_init();
|
||||
multi_handle = curl_multi_init();
|
||||
|
||||
/* initalize custom header list (stating that Expect: 100-continue is not
|
||||
wanted */
|
||||
headerlist = curl_slist_append(headerlist, buf);
|
||||
if(curl && multi_handle) {
|
||||
|
||||
/* what URL that receives this POST */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "http://www.example.com/upload.cgi");
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
|
||||
|
||||
curl_multi_add_handle(multi_handle, curl);
|
||||
|
||||
curl_multi_perform(multi_handle, &still_running);
|
||||
|
||||
while(still_running) {
|
||||
struct timeval timeout;
|
||||
int rc; /* select() return code */
|
||||
|
||||
fd_set fdread;
|
||||
fd_set fdwrite;
|
||||
fd_set fdexcep;
|
||||
int maxfd = -1;
|
||||
|
||||
long curl_timeo = -1;
|
||||
|
||||
FD_ZERO(&fdread);
|
||||
FD_ZERO(&fdwrite);
|
||||
FD_ZERO(&fdexcep);
|
||||
|
||||
/* set a suitable timeout to play around with */
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
curl_multi_timeout(multi_handle, &curl_timeo);
|
||||
if(curl_timeo >= 0) {
|
||||
timeout.tv_sec = curl_timeo / 1000;
|
||||
if(timeout.tv_sec > 1)
|
||||
timeout.tv_sec = 1;
|
||||
else
|
||||
timeout.tv_usec = (curl_timeo % 1000) * 1000;
|
||||
}
|
||||
|
||||
/* get file descriptors from the transfers */
|
||||
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||
|
||||
/* In a real-world program you OF COURSE check the return code of the
|
||||
function calls. On success, the value of maxfd is guaranteed to be
|
||||
greater or equal than -1. We call select(maxfd + 1, ...), specially in
|
||||
case of (maxfd == -1), we call select(0, ...), which is basically equal
|
||||
to sleep. */
|
||||
|
||||
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||
|
||||
switch(rc) {
|
||||
case -1:
|
||||
/* select error */
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
/* timeout or readable/writable sockets */
|
||||
printf("perform!\n");
|
||||
curl_multi_perform(multi_handle, &still_running);
|
||||
printf("running: %d!\n", still_running);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
curl_multi_cleanup(multi_handle);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
/* then cleanup the formpost chain */
|
||||
curl_formfree(formpost);
|
||||
|
||||
/* free slist */
|
||||
curl_slist_free_all (headerlist);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
104
third-party/curl-7.21.4/docs/examples/multi-single.c
vendored
Normal file
104
third-party/curl-7.21.4/docs/examples/multi-single.c
vendored
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*
|
||||
* This is a very simple example using the multi interface.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* somewhat unix-specific */
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* curl stuff */
|
||||
#include <curl/curl.h>
|
||||
|
||||
/*
|
||||
* Simply download a HTTP file.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
CURL *http_handle;
|
||||
CURLM *multi_handle;
|
||||
|
||||
int still_running; /* keep number of running handles */
|
||||
|
||||
http_handle = curl_easy_init();
|
||||
|
||||
/* set the options (I left out a few, you'll get the point anyway) */
|
||||
curl_easy_setopt(http_handle, CURLOPT_URL, "http://www.example.com/");
|
||||
|
||||
/* init a multi stack */
|
||||
multi_handle = curl_multi_init();
|
||||
|
||||
/* add the individual transfers */
|
||||
curl_multi_add_handle(multi_handle, http_handle);
|
||||
|
||||
/* we start some action by calling perform right away */
|
||||
curl_multi_perform(multi_handle, &still_running);
|
||||
|
||||
while(still_running) {
|
||||
struct timeval timeout;
|
||||
int rc; /* select() return code */
|
||||
|
||||
fd_set fdread;
|
||||
fd_set fdwrite;
|
||||
fd_set fdexcep;
|
||||
int maxfd = -1;
|
||||
|
||||
long curl_timeo = -1;
|
||||
|
||||
FD_ZERO(&fdread);
|
||||
FD_ZERO(&fdwrite);
|
||||
FD_ZERO(&fdexcep);
|
||||
|
||||
/* set a suitable timeout to play around with */
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
curl_multi_timeout(multi_handle, &curl_timeo);
|
||||
if(curl_timeo >= 0) {
|
||||
timeout.tv_sec = curl_timeo / 1000;
|
||||
if(timeout.tv_sec > 1)
|
||||
timeout.tv_sec = 1;
|
||||
else
|
||||
timeout.tv_usec = (curl_timeo % 1000) * 1000;
|
||||
}
|
||||
|
||||
/* get file descriptors from the transfers */
|
||||
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||
|
||||
/* In a real-world program you OF COURSE check the return code of the
|
||||
function calls. On success, the value of maxfd is guaranteed to be
|
||||
greater or equal than -1. We call select(maxfd + 1, ...), specially in
|
||||
case of (maxfd == -1), we call select(0, ...), which is basically equal
|
||||
to sleep. */
|
||||
|
||||
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||
|
||||
switch(rc) {
|
||||
case -1:
|
||||
/* select error */
|
||||
still_running = 0;
|
||||
printf("select() returns error, this is badness\n");
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
/* timeout or readable/writable sockets */
|
||||
curl_multi_perform(multi_handle, &still_running);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
curl_multi_cleanup(multi_handle);
|
||||
|
||||
curl_easy_cleanup(http_handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
81
third-party/curl-7.21.4/docs/examples/multithread.c
vendored
Normal file
81
third-party/curl-7.21.4/docs/examples/multithread.c
vendored
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*/
|
||||
|
||||
/* A multi-threaded example that uses pthreads extensively to fetch
|
||||
* X remote files at once */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#define NUMT 4
|
||||
|
||||
/*
|
||||
List of URLs to fetch.
|
||||
|
||||
If you intend to use a SSL-based protocol here you MUST setup the OpenSSL
|
||||
callback functions as described here:
|
||||
|
||||
http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION
|
||||
|
||||
*/
|
||||
const char * const urls[NUMT]= {
|
||||
"http://curl.haxx.se/",
|
||||
"ftp://cool.haxx.se/",
|
||||
"http://www.contactor.se/",
|
||||
"www.haxx.se"
|
||||
};
|
||||
|
||||
static void *pull_one_url(void *url)
|
||||
{
|
||||
CURL *curl;
|
||||
|
||||
curl = curl_easy_init();
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
curl_easy_perform(curl); /* ignores error */
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
int pthread_create(pthread_t *new_thread_ID,
|
||||
const pthread_attr_t *attr,
|
||||
void * (*start_func)(void *), void *arg);
|
||||
*/
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
pthread_t tid[NUMT];
|
||||
int i;
|
||||
int error;
|
||||
|
||||
/* Must initialize libcurl before any threads are started */
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
for(i=0; i< NUMT; i++) {
|
||||
error = pthread_create(&tid[i],
|
||||
NULL, /* default attributes please */
|
||||
pull_one_url,
|
||||
(void *)urls[i]);
|
||||
if(0 != error)
|
||||
fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error);
|
||||
else
|
||||
fprintf(stderr, "Thread %d, gets %s\n", i, urls[i]);
|
||||
}
|
||||
|
||||
/* now wait for all threads to terminate */
|
||||
for(i=0; i< NUMT; i++) {
|
||||
error = pthread_join(tid[i], NULL);
|
||||
fprintf(stderr, "Thread %d terminated\n", i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
81
third-party/curl-7.21.4/docs/examples/opensslthreadlock.c
vendored
Normal file
81
third-party/curl-7.21.4/docs/examples/opensslthreadlock.c
vendored
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*
|
||||
* Example source code to show one way to set the necessary OpenSSL locking
|
||||
* callbacks if you want to do multi-threaded transfers with HTTPS/FTPS with
|
||||
* libcurl built to use OpenSSL.
|
||||
*
|
||||
* This is not a complete stand-alone example.
|
||||
*
|
||||
* Author: Jeremy Brown
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#define MUTEX_TYPE pthread_mutex_t
|
||||
#define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL)
|
||||
#define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x))
|
||||
#define MUTEX_LOCK(x) pthread_mutex_lock(&(x))
|
||||
#define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
|
||||
#define THREAD_ID pthread_self( )
|
||||
|
||||
|
||||
void handle_error(const char *file, int lineno, const char *msg){
|
||||
fprintf(stderr, "** %s:%d %s\n", file, lineno, msg);
|
||||
ERR_print_errors_fp(stderr);
|
||||
/* exit(-1); */
|
||||
}
|
||||
|
||||
/* This array will store all of the mutexes available to OpenSSL. */
|
||||
static MUTEX_TYPE *mutex_buf= NULL;
|
||||
|
||||
|
||||
static void locking_function(int mode, int n, const char * file, int line)
|
||||
{
|
||||
if (mode & CRYPTO_LOCK)
|
||||
MUTEX_LOCK(mutex_buf[n]);
|
||||
else
|
||||
MUTEX_UNLOCK(mutex_buf[n]);
|
||||
}
|
||||
|
||||
static unsigned long id_function(void)
|
||||
{
|
||||
return ((unsigned long)THREAD_ID);
|
||||
}
|
||||
|
||||
int thread_setup(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
mutex_buf = malloc(CRYPTO_num_locks( ) * sizeof(MUTEX_TYPE));
|
||||
if (!mutex_buf)
|
||||
return 0;
|
||||
for (i = 0; i < CRYPTO_num_locks( ); i++)
|
||||
MUTEX_SETUP(mutex_buf[i]);
|
||||
CRYPTO_set_id_callback(id_function);
|
||||
CRYPTO_set_locking_callback(locking_function);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int thread_cleanup(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!mutex_buf)
|
||||
return 0;
|
||||
CRYPTO_set_id_callback(NULL);
|
||||
CRYPTO_set_locking_callback(NULL);
|
||||
for (i = 0; i < CRYPTO_num_locks( ); i++)
|
||||
MUTEX_CLEANUP(mutex_buf[i]);
|
||||
free(mutex_buf);
|
||||
mutex_buf = NULL;
|
||||
return 1;
|
||||
}
|
||||
40
third-party/curl-7.21.4/docs/examples/persistant.c
vendored
Normal file
40
third-party/curl-7.21.4/docs/examples/persistant.c
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_HEADER, 1L);
|
||||
|
||||
/* get the first document */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/");
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* get another document from the same server using the same
|
||||
connection */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/docs/");
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
116
third-party/curl-7.21.4/docs/examples/post-callback.c
vendored
Normal file
116
third-party/curl-7.21.4/docs/examples/post-callback.c
vendored
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*
|
||||
* An example source code that issues a HTTP POST and we provide the actual
|
||||
* data through a read callback.
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
const char data[]="this is what we post to the silly web server";
|
||||
|
||||
struct WriteThis {
|
||||
const char *readptr;
|
||||
int sizeleft;
|
||||
};
|
||||
|
||||
static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp)
|
||||
{
|
||||
struct WriteThis *pooh = (struct WriteThis *)userp;
|
||||
|
||||
if(size*nmemb < 1)
|
||||
return 0;
|
||||
|
||||
if(pooh->sizeleft) {
|
||||
*(char *)ptr = pooh->readptr[0]; /* copy one single byte */
|
||||
pooh->readptr++; /* advance pointer */
|
||||
pooh->sizeleft--; /* less data left */
|
||||
return 1; /* we return 1 byte at a time! */
|
||||
}
|
||||
|
||||
return 0; /* no more data left to deliver */
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
struct WriteThis pooh;
|
||||
|
||||
pooh.readptr = data;
|
||||
pooh.sizeleft = strlen(data);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* First set the URL that is about to receive our POST. */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/index.cgi");
|
||||
|
||||
/* Now specify we want to POST data */
|
||||
curl_easy_setopt(curl, CURLOPT_POST, 1L);
|
||||
|
||||
/* we want to use our own read function */
|
||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
|
||||
|
||||
/* pointer to pass to our read function */
|
||||
curl_easy_setopt(curl, CURLOPT_READDATA, &pooh);
|
||||
|
||||
/* get verbose debug output please */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
/*
|
||||
If you use POST to a HTTP 1.1 server, you can send data without knowing
|
||||
the size before starting the POST if you use chunked encoding. You
|
||||
enable this by adding a header like "Transfer-Encoding: chunked" with
|
||||
CURLOPT_HTTPHEADER. With HTTP 1.0 or without chunked transfer, you must
|
||||
specify the size in the request.
|
||||
*/
|
||||
#ifdef USE_CHUNKED
|
||||
{
|
||||
struct curl_slist *chunk = NULL;
|
||||
|
||||
chunk = curl_slist_append(chunk, "Transfer-Encoding: chunked");
|
||||
res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
|
||||
/* use curl_slist_free_all() after the *perform() call to free this
|
||||
list again */
|
||||
}
|
||||
#else
|
||||
/* Set the expected POST size. If you want to POST large amounts of data,
|
||||
consider CURLOPT_POSTFIELDSIZE_LARGE */
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (curl_off_t)pooh.sizeleft);
|
||||
#endif
|
||||
|
||||
#ifdef DISABLE_EXPECT
|
||||
/*
|
||||
Using POST with HTTP 1.1 implies the use of a "Expect: 100-continue"
|
||||
header. You can disable this header with CURLOPT_HTTPHEADER as usual.
|
||||
NOTE: if you want chunked transfer too, you need to combine these two
|
||||
since you can only set one list of headers with CURLOPT_HTTPHEADER. */
|
||||
|
||||
/* A less good option would be to enforce HTTP 1.0, but that might also
|
||||
have other implications. */
|
||||
{
|
||||
struct curl_slist *chunk = NULL;
|
||||
|
||||
chunk = curl_slist_append(chunk, "Expect:");
|
||||
res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
|
||||
/* use curl_slist_free_all() after the *perform() call to free this
|
||||
list again */
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Perform the request, res will get the return code */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
86
third-party/curl-7.21.4/docs/examples/postit2.c
vendored
Normal file
86
third-party/curl-7.21.4/docs/examples/postit2.c
vendored
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*
|
||||
* Example code that uploads a file name 'foo' to a remote script that accepts
|
||||
* "HTML form based" (as described in RFC1738) uploads using HTTP POST.
|
||||
*
|
||||
* The imaginary form we'll fill in looks like:
|
||||
*
|
||||
* <form method="post" enctype="multipart/form-data" action="examplepost.cgi">
|
||||
* Enter file: <input type="file" name="sendfile" size="40">
|
||||
* Enter file name: <input type="text" name="filename" size="30">
|
||||
* <input type="submit" value="send" name="submit">
|
||||
* </form>
|
||||
*
|
||||
* This exact source code has not been verified to work.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h>
|
||||
#include <curl/easy.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
struct curl_httppost *formpost=NULL;
|
||||
struct curl_httppost *lastptr=NULL;
|
||||
struct curl_slist *headerlist=NULL;
|
||||
static const char buf[] = "Expect:";
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
/* Fill in the file upload field */
|
||||
curl_formadd(&formpost,
|
||||
&lastptr,
|
||||
CURLFORM_COPYNAME, "sendfile",
|
||||
CURLFORM_FILE, "postit2.c",
|
||||
CURLFORM_END);
|
||||
|
||||
/* Fill in the filename field */
|
||||
curl_formadd(&formpost,
|
||||
&lastptr,
|
||||
CURLFORM_COPYNAME, "filename",
|
||||
CURLFORM_COPYCONTENTS, "postit2.c",
|
||||
CURLFORM_END);
|
||||
|
||||
|
||||
/* Fill in the submit field too, even if this is rarely needed */
|
||||
curl_formadd(&formpost,
|
||||
&lastptr,
|
||||
CURLFORM_COPYNAME, "submit",
|
||||
CURLFORM_COPYCONTENTS, "send",
|
||||
CURLFORM_END);
|
||||
|
||||
curl = curl_easy_init();
|
||||
/* initalize custom header list (stating that Expect: 100-continue is not
|
||||
wanted */
|
||||
headerlist = curl_slist_append(headerlist, buf);
|
||||
if(curl) {
|
||||
/* what URL that receives this POST */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/examplepost.cgi");
|
||||
if ( (argc == 2) && (!strcmp(argv[1], "noexpectheader")) )
|
||||
/* only disable 100-continue header if explicitly requested */
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
/* then cleanup the formpost chain */
|
||||
curl_formfree(formpost);
|
||||
/* free slist */
|
||||
curl_slist_free_all (headerlist);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
94
third-party/curl-7.21.4/docs/examples/sampleconv.c
vendored
Normal file
94
third-party/curl-7.21.4/docs/examples/sampleconv.c
vendored
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*/
|
||||
/*
|
||||
This is a simple example showing how a program on a non-ASCII platform
|
||||
would invoke callbacks to do its own codeset conversions instead of
|
||||
using the built-in iconv functions in libcurl.
|
||||
|
||||
The IBM-1047 EBCDIC codeset is used for this example but the code
|
||||
would be similar for other non-ASCII codesets.
|
||||
|
||||
Three callback functions are created below:
|
||||
my_conv_from_ascii_to_ebcdic,
|
||||
my_conv_from_ebcdic_to_ascii, and
|
||||
my_conv_from_utf8_to_ebcdic
|
||||
|
||||
The "platform_xxx" calls represent platform-specific conversion routines.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
CURLcode my_conv_from_ascii_to_ebcdic(char *buffer, size_t length)
|
||||
{
|
||||
char *tempptrin, *tempptrout;
|
||||
size_t bytes = length;
|
||||
int rc;
|
||||
tempptrin = tempptrout = buffer;
|
||||
rc = platform_a2e(&tempptrin, &bytes, &tempptrout, &bytes);
|
||||
if (rc == PLATFORM_CONV_OK) {
|
||||
return(CURLE_OK);
|
||||
} else {
|
||||
return(CURLE_CONV_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
CURLcode my_conv_from_ebcdic_to_ascii(char *buffer, size_t length)
|
||||
{
|
||||
char *tempptrin, *tempptrout;
|
||||
size_t bytes = length;
|
||||
int rc;
|
||||
tempptrin = tempptrout = buffer;
|
||||
rc = platform_e2a(&tempptrin, &bytes, &tempptrout, &bytes);
|
||||
if (rc == PLATFORM_CONV_OK) {
|
||||
return(CURLE_OK);
|
||||
} else {
|
||||
return(CURLE_CONV_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
CURLcode my_conv_from_utf8_to_ebcdic(char *buffer, size_t length)
|
||||
{
|
||||
char *tempptrin, *tempptrout;
|
||||
size_t bytes = length;
|
||||
int rc;
|
||||
tempptrin = tempptrout = buffer;
|
||||
rc = platform_u2e(&tempptrin, &bytes, &tempptrout, &bytes);
|
||||
if (rc == PLATFORM_CONV_OK) {
|
||||
return(CURLE_OK);
|
||||
} else {
|
||||
return(CURLE_CONV_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
|
||||
|
||||
/* use platform-specific functions for codeset conversions */
|
||||
curl_easy_setopt(curl, CURLOPT_CONV_FROM_NETWORK_FUNCTION,
|
||||
my_conv_from_ascii_to_ebcdic);
|
||||
curl_easy_setopt(curl, CURLOPT_CONV_TO_NETWORK_FUNCTION,
|
||||
my_conv_from_ebcdic_to_ascii);
|
||||
curl_easy_setopt(curl, CURLOPT_CONV_FROM_UTF8_FUNCTION,
|
||||
my_conv_from_utf8_to_ebcdic);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
120
third-party/curl-7.21.4/docs/examples/sendrecv.c
vendored
Normal file
120
third-party/curl-7.21.4/docs/examples/sendrecv.c
vendored
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* An example of curl_easy_send() and curl_easy_recv() usage.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* Auxiliary function that waits on the socket. */
|
||||
static int wait_on_socket(curl_socket_t sockfd, int for_recv, long timeout_ms)
|
||||
{
|
||||
struct timeval tv;
|
||||
fd_set infd, outfd, errfd;
|
||||
int res;
|
||||
|
||||
tv.tv_sec = timeout_ms / 1000;
|
||||
tv.tv_usec= (timeout_ms % 1000) * 1000;
|
||||
|
||||
FD_ZERO(&infd);
|
||||
FD_ZERO(&outfd);
|
||||
FD_ZERO(&errfd);
|
||||
|
||||
FD_SET(sockfd, &errfd); /* always check for error */
|
||||
|
||||
if(for_recv)
|
||||
{
|
||||
FD_SET(sockfd, &infd);
|
||||
}
|
||||
else
|
||||
{
|
||||
FD_SET(sockfd, &outfd);
|
||||
}
|
||||
|
||||
/* select() returns the number of signalled sockets or -1 */
|
||||
res = select(sockfd + 1, &infd, &outfd, &errfd, &tv);
|
||||
return res;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
/* Minimalistic http request */
|
||||
const char *request = "GET / HTTP/1.0\r\nHost: example.com\r\n\r\n";
|
||||
curl_socket_t sockfd; /* socket */
|
||||
long sockextr;
|
||||
size_t iolen;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
|
||||
/* Do not do the transfer - only connect to host */
|
||||
curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1L);
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
if(CURLE_OK != res)
|
||||
{
|
||||
printf("Error: %s\n", strerror(res));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Extract the socket from the curl handle - we'll need it for waiting.
|
||||
* Note that this API takes a pointer to a 'long' while we use
|
||||
* curl_socket_t for sockets otherwise.
|
||||
*/
|
||||
res = curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, &sockextr);
|
||||
|
||||
if(CURLE_OK != res)
|
||||
{
|
||||
printf("Error: %s\n", curl_easy_strerror(res));
|
||||
return 1;
|
||||
}
|
||||
|
||||
sockfd = sockextr;
|
||||
|
||||
/* wait for the socket to become ready for sending */
|
||||
if(!wait_on_socket(sockfd, 0, 60000L))
|
||||
{
|
||||
printf("Error: timeout.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
puts("Sending request.");
|
||||
/* Send the request. Real applications should check the iolen
|
||||
* to see if all the request has been sent */
|
||||
res = curl_easy_send(curl, request, strlen(request), &iolen);
|
||||
|
||||
if(CURLE_OK != res)
|
||||
{
|
||||
printf("Error: %s\n", curl_easy_strerror(res));
|
||||
return 1;
|
||||
}
|
||||
puts("Reading response.");
|
||||
|
||||
/* read the response */
|
||||
for(;;)
|
||||
{
|
||||
char buf[1024];
|
||||
|
||||
wait_on_socket(sockfd, 1, 60000L);
|
||||
res = curl_easy_recv(curl, buf, 1024, &iolen);
|
||||
|
||||
if(CURLE_OK != res)
|
||||
break;
|
||||
|
||||
printf("Received %u bytes.\n", iolen);
|
||||
}
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
75
third-party/curl-7.21.4/docs/examples/sepheaders.c
vendored
Normal file
75
third-party/curl-7.21.4/docs/examples/sepheaders.c
vendored
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h>
|
||||
#include <curl/easy.h>
|
||||
|
||||
static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
int written = fwrite(ptr, size, nmemb, (FILE *)stream);
|
||||
return written;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl_handle;
|
||||
static const char *headerfilename = "head.out";
|
||||
FILE *headerfile;
|
||||
static const char *bodyfilename = "body.out";
|
||||
FILE *bodyfile;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
/* init the curl session */
|
||||
curl_handle = curl_easy_init();
|
||||
|
||||
/* set URL to get */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_URL, "http://example.com");
|
||||
|
||||
/* no progress meter please */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1L);
|
||||
|
||||
/* send all data to this function */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);
|
||||
|
||||
/* open the files */
|
||||
headerfile = fopen(headerfilename,"w");
|
||||
if (headerfile == NULL) {
|
||||
curl_easy_cleanup(curl_handle);
|
||||
return -1;
|
||||
}
|
||||
bodyfile = fopen(bodyfilename,"w");
|
||||
if (bodyfile == NULL) {
|
||||
curl_easy_cleanup(curl_handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* we want the headers to this file handle */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER, headerfile);
|
||||
|
||||
/*
|
||||
* Notice here that if you want the actual data sent anywhere else but
|
||||
* stdout, you should consider using the CURLOPT_WRITEDATA option. */
|
||||
|
||||
/* get it! */
|
||||
curl_easy_perform(curl_handle);
|
||||
|
||||
/* close the header file */
|
||||
fclose(headerfile);
|
||||
|
||||
/* cleanup curl stuff */
|
||||
curl_easy_cleanup(curl_handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
27
third-party/curl-7.21.4/docs/examples/simple.c
vendored
Normal file
27
third-party/curl-7.21.4/docs/examples/simple.c
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
36
third-party/curl-7.21.4/docs/examples/simplepost.c
vendored
Normal file
36
third-party/curl-7.21.4/docs/examples/simplepost.c
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
static const char *postthis="moo mooo moo moo";
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
|
||||
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));
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
71
third-party/curl-7.21.4/docs/examples/simplesmtp.c
vendored
Normal file
71
third-party/curl-7.21.4/docs/examples/simplesmtp.c
vendored
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct curl_slist *recipients = NULL;
|
||||
|
||||
/* value for envelope reverse-path */
|
||||
static const char *from = "<bradh@example.com>";
|
||||
|
||||
/* this becomes the envelope forward-path */
|
||||
static const char *to = "<bradh@example.net>";
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* this is the URL for your mailserver - you can also use an smtps:// URL
|
||||
* here */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "smtp://mail.example.net.");
|
||||
|
||||
/* Note that this option isn't strictly required, omitting it will result in
|
||||
* libcurl will sent the MAIL FROM command with no sender data. All
|
||||
* autoresponses should have an empty reverse-path, and should be directed
|
||||
* to the address in the reverse-path which triggered them. Otherwise, they
|
||||
* could cause an endless loop. See RFC 5321 Section 4.5.5 for more details.
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, from);
|
||||
|
||||
/* Note that the CURLOPT_MAIL_RCPT takes a list, not a char array. */
|
||||
recipients = curl_slist_append(recipients, to);
|
||||
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
|
||||
|
||||
/* You provide the payload (headers and the body of the message) as the
|
||||
* "data" element. There are two choices, either:
|
||||
* - provide a callback function and specify the function name using the
|
||||
* CURLOPT_READFUNCTION option; or
|
||||
* - just provide a FILE pointer that can be used to read the data from.
|
||||
* The easiest case is just to read from standard input, (which is available
|
||||
* as a FILE pointer) as shown here.
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_READDATA, stdin);
|
||||
|
||||
/* send the message (including headers) */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* free the list of recipients */
|
||||
curl_slist_free_all(recipients);
|
||||
|
||||
/* curl won't send the QUIT command until you call cleanup, so you should be
|
||||
* able to re-use this connection for additional messages (setting
|
||||
* CURLOPT_MAIL_FROM and CURLOPT_MAIL_RCPT as required, and calling
|
||||
* curl_easy_perform() again. It may not be a good idea to keep the
|
||||
* connection open for a very long time though (more than a few minutes may
|
||||
* result in the server timing out the connection), and you do want to clean
|
||||
* up in the end.
|
||||
*/
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
122
third-party/curl-7.21.4/docs/examples/simplessl.c
vendored
Normal file
122
third-party/curl-7.21.4/docs/examples/simplessl.c
vendored
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h>
|
||||
#include <curl/easy.h>
|
||||
|
||||
|
||||
/* some requirements for this to work:
|
||||
1. set pCertFile to the file with the client certificate
|
||||
2. if the key is passphrase protected, set pPassphrase to the
|
||||
passphrase you use
|
||||
3. if you are using a crypto engine:
|
||||
3.1. set a #define USE_ENGINE
|
||||
3.2. set pEngine to the name of the crypto engine you use
|
||||
3.3. set pKeyName to the key identifier you want to use
|
||||
4. if you don't use a crypto engine:
|
||||
4.1. set pKeyName to the file name of your client key
|
||||
4.2. if the format of the key file is DER, set pKeyType to "DER"
|
||||
|
||||
!! verify of the server certificate is not implemented here !!
|
||||
|
||||
**** This example only works with libcurl 7.9.3 and later! ****
|
||||
|
||||
*/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
FILE *headerfile;
|
||||
const char *pPassphrase = NULL;
|
||||
|
||||
static const char *pCertFile = "testcert.pem";
|
||||
static const char *pCACertFile="cacert.pem";
|
||||
|
||||
const char *pKeyName;
|
||||
const char *pKeyType;
|
||||
|
||||
const char *pEngine;
|
||||
|
||||
#ifdef USE_ENGINE
|
||||
pKeyName = "rsa_test";
|
||||
pKeyType = "ENG";
|
||||
pEngine = "chil"; /* for nChiper HSM... */
|
||||
#else
|
||||
pKeyName = "testkey.pem";
|
||||
pKeyType = "PEM";
|
||||
pEngine = NULL;
|
||||
#endif
|
||||
|
||||
headerfile = fopen("dumpit", "w");
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* what call to write: */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "HTTPS://your.favourite.ssl.site");
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEHEADER, headerfile);
|
||||
|
||||
while(1) /* do some ugly short cut... */
|
||||
{
|
||||
if (pEngine) /* use crypto engine */
|
||||
{
|
||||
if (curl_easy_setopt(curl, CURLOPT_SSLENGINE,pEngine) != CURLE_OK)
|
||||
{ /* load the crypto engine */
|
||||
fprintf(stderr,"can't set crypto engine\n");
|
||||
break;
|
||||
}
|
||||
if (curl_easy_setopt(curl, CURLOPT_SSLENGINE_DEFAULT,1L) != CURLE_OK)
|
||||
{ /* set the crypto engine as default */
|
||||
/* only needed for the first time you load
|
||||
a engine in a curl object... */
|
||||
fprintf(stderr,"can't set crypto engine as default\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* cert is stored PEM coded in file... */
|
||||
/* since PEM is default, we needn't set it for PEM */
|
||||
curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"PEM");
|
||||
|
||||
/* set the cert for client authentication */
|
||||
curl_easy_setopt(curl,CURLOPT_SSLCERT,pCertFile);
|
||||
|
||||
/* sorry, for engine we must set the passphrase
|
||||
(if the key has one...) */
|
||||
if (pPassphrase)
|
||||
curl_easy_setopt(curl,CURLOPT_KEYPASSWD,pPassphrase);
|
||||
|
||||
/* if we use a key stored in a crypto engine,
|
||||
we must set the key type to "ENG" */
|
||||
curl_easy_setopt(curl,CURLOPT_SSLKEYTYPE,pKeyType);
|
||||
|
||||
/* set the private key (file or ID in engine) */
|
||||
curl_easy_setopt(curl,CURLOPT_SSLKEY,pKeyName);
|
||||
|
||||
/* set the file with the certs vaildating the server */
|
||||
curl_easy_setopt(curl,CURLOPT_CAINFO,pCACertFile);
|
||||
|
||||
/* disconnect if we can't validate server's cert */
|
||||
curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,1L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
break; /* we are done... */
|
||||
}
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
217
third-party/curl-7.21.4/docs/examples/smooth-gtk-thread.c
vendored
Normal file
217
third-party/curl-7.21.4/docs/examples/smooth-gtk-thread.c
vendored
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*
|
||||
* This is a multi threaded application that uses a progress bar to show
|
||||
* status. It uses Gtk+ to make a smooth pulse.
|
||||
*
|
||||
* Written by Jud Bishop after studying the other examples provided with
|
||||
* libcurl.
|
||||
*
|
||||
* To compile (on a single line):
|
||||
* gcc -ggdb `pkg-config --cflags --libs gtk+-2.0` -lcurl -lssl -lcrypto
|
||||
* -lgthread-2.0 -dl smooth-gtk-thread.c -o smooth-gtk-thread
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <glib.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h> /* new for v7 */
|
||||
#include <curl/easy.h> /* new for v7 */
|
||||
|
||||
#define NUMT 4
|
||||
|
||||
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
int j = 0;
|
||||
gint num_urls = 9; /* Just make sure this is less than urls[]*/
|
||||
const char * const urls[]= {
|
||||
"90022",
|
||||
"90023",
|
||||
"90024",
|
||||
"90025",
|
||||
"90026",
|
||||
"90027",
|
||||
"90028",
|
||||
"90029",
|
||||
"90030"
|
||||
};
|
||||
|
||||
size_t write_file(void *ptr, size_t size, size_t nmemb, FILE *stream)
|
||||
{
|
||||
/* printf("write_file\n"); */
|
||||
return fwrite(ptr, size, nmemb, stream);
|
||||
}
|
||||
|
||||
/* http://xoap.weather.com/weather/local/46214?cc=*&dayf=5&unit=i */
|
||||
void *pull_one_url(void *NaN)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
gchar *http;
|
||||
FILE *outfile;
|
||||
|
||||
/* Stop threads from entering unless j is incremented */
|
||||
pthread_mutex_lock(&lock);
|
||||
while ( j < num_urls )
|
||||
{
|
||||
printf("j = %d\n", j);
|
||||
|
||||
http =
|
||||
g_strdup_printf("xoap.weather.com/weather/local/%s?cc=*&dayf=5&unit=i\n",
|
||||
urls[j]);
|
||||
|
||||
printf( "http %s", http );
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl)
|
||||
{
|
||||
|
||||
outfile = fopen(urls[j], "w");
|
||||
/* printf("fopen\n"); */
|
||||
|
||||
/* Set the URL and transfer type */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, http);
|
||||
|
||||
/* Write to the file */
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_file);
|
||||
|
||||
j++; /* critical line */
|
||||
pthread_mutex_unlock(&lock);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
fclose(outfile);
|
||||
printf("fclose\n");
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
g_free (http);
|
||||
|
||||
/* Adds more latency, testing the mutex.*/
|
||||
sleep(1);
|
||||
|
||||
} /* end while */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
gboolean pulse_bar(gpointer data)
|
||||
{
|
||||
gdk_threads_enter();
|
||||
gtk_progress_bar_pulse (GTK_PROGRESS_BAR (data));
|
||||
gdk_threads_leave();
|
||||
|
||||
/* Return true so the function will be called again;
|
||||
* returning false removes this timeout function.
|
||||
*/
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void *create_thread(void *progress_bar)
|
||||
{
|
||||
pthread_t tid[NUMT];
|
||||
int i;
|
||||
int error;
|
||||
|
||||
/* Make sure I don't create more threads than urls. */
|
||||
for(i=0; i < NUMT && i < num_urls ; i++) {
|
||||
error = pthread_create(&tid[i],
|
||||
NULL, /* default attributes please */
|
||||
pull_one_url,
|
||||
NULL);
|
||||
if(0 != error)
|
||||
fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error);
|
||||
else
|
||||
fprintf(stderr, "Thread %d, gets %s\n", i, urls[i]);
|
||||
}
|
||||
|
||||
/* Wait for all threads to terminate. */
|
||||
for(i=0; i < NUMT && i < num_urls; i++) {
|
||||
error = pthread_join(tid[i], NULL);
|
||||
fprintf(stderr, "Thread %d terminated\n", i);
|
||||
}
|
||||
|
||||
/* This stops the pulsing if you have it turned on in the progress bar
|
||||
section */
|
||||
g_source_remove(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(progress_bar),
|
||||
"pulse_id")));
|
||||
|
||||
/* This destroys the progress bar */
|
||||
gtk_widget_destroy(progress_bar);
|
||||
|
||||
/* [Un]Comment this out to kill the program rather than pushing close. */
|
||||
/* gtk_main_quit(); */
|
||||
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
static gboolean cb_delete(GtkWidget *window, gpointer data)
|
||||
{
|
||||
gtk_main_quit();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
GtkWidget *top_window, *outside_frame, *inside_frame, *progress_bar;
|
||||
|
||||
/* Must initialize libcurl before any threads are started */
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
/* Init thread */
|
||||
g_thread_init(NULL);
|
||||
gdk_threads_init ();
|
||||
gdk_threads_enter ();
|
||||
|
||||
gtk_init(&argc, &argv);
|
||||
|
||||
/* Base window */
|
||||
top_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
|
||||
/* Frame */
|
||||
outside_frame = gtk_frame_new(NULL);
|
||||
gtk_frame_set_shadow_type(GTK_FRAME(outside_frame), GTK_SHADOW_OUT);
|
||||
gtk_container_add(GTK_CONTAINER(top_window), outside_frame);
|
||||
|
||||
/* Frame */
|
||||
inside_frame = gtk_frame_new(NULL);
|
||||
gtk_frame_set_shadow_type(GTK_FRAME(inside_frame), GTK_SHADOW_IN);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(inside_frame), 5);
|
||||
gtk_container_add(GTK_CONTAINER(outside_frame), inside_frame);
|
||||
|
||||
/* Progress bar */
|
||||
progress_bar = gtk_progress_bar_new();
|
||||
gtk_progress_bar_pulse (GTK_PROGRESS_BAR (progress_bar));
|
||||
/* Make uniform pulsing */
|
||||
gint pulse_ref = g_timeout_add (300, pulse_bar, progress_bar);
|
||||
g_object_set_data(G_OBJECT(progress_bar), "pulse_id",
|
||||
GINT_TO_POINTER(pulse_ref));
|
||||
gtk_container_add(GTK_CONTAINER(inside_frame), progress_bar);
|
||||
|
||||
gtk_widget_show_all(top_window);
|
||||
printf("gtk_widget_show_all\n");
|
||||
|
||||
g_signal_connect(G_OBJECT (top_window), "delete-event",
|
||||
G_CALLBACK(cb_delete), NULL);
|
||||
|
||||
if (!g_thread_create(&create_thread, progress_bar, FALSE, NULL) != 0)
|
||||
g_warning("can't create the thread");
|
||||
|
||||
gtk_main();
|
||||
gdk_threads_leave();
|
||||
printf("gdk_threads_leave\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
192
third-party/curl-7.21.4/docs/examples/smtp-multi.c
vendored
Normal file
192
third-party/curl-7.21.4/docs/examples/smtp-multi.c
vendored
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*
|
||||
* This is an example application source code sending SMTP mail using the
|
||||
* multi interface.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/*
|
||||
* This is the list of basic details you need to tweak to get things right.
|
||||
*/
|
||||
#define USERNAME "user@example.com"
|
||||
#define PASSWORD "123qwerty"
|
||||
#define SMTPSERVER "smtp.example.com"
|
||||
#define SMTPPORT ":587" /* it is a colon+port string, but you can set it
|
||||
to "" to use the default port */
|
||||
#define RECIPIENT "<recipient@example.com>"
|
||||
#define MAILFROM "<realuser@example.com>"
|
||||
|
||||
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
|
||||
|
||||
/* Note that you should include the actual meta data headers here as well if
|
||||
you want the mail to have a Subject, another From:, show a To: or whatever
|
||||
you think your mail should feature! */
|
||||
static const char *text[]={
|
||||
"one\n",
|
||||
"two\n",
|
||||
"three\n",
|
||||
" Hello, this is CURL email SMTP\n",
|
||||
NULL
|
||||
};
|
||||
|
||||
struct WriteThis {
|
||||
int counter;
|
||||
};
|
||||
|
||||
static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp)
|
||||
{
|
||||
struct WriteThis *pooh = (struct WriteThis *)userp;
|
||||
const char *data;
|
||||
|
||||
if(size*nmemb < 1)
|
||||
return 0;
|
||||
|
||||
data = text[pooh->counter];
|
||||
|
||||
if(data) {
|
||||
size_t len = strlen(data);
|
||||
memcpy(ptr, data, len);
|
||||
pooh->counter++; /* advance pointer */
|
||||
return len;
|
||||
}
|
||||
return 0; /* no more data left to deliver */
|
||||
}
|
||||
|
||||
static struct timeval tvnow(void)
|
||||
{
|
||||
/*
|
||||
** time() returns the value of time in seconds since the Epoch.
|
||||
*/
|
||||
struct timeval now;
|
||||
now.tv_sec = (long)time(NULL);
|
||||
now.tv_usec = 0;
|
||||
return now;
|
||||
}
|
||||
|
||||
static long tvdiff(struct timeval newer, struct timeval older)
|
||||
{
|
||||
return (newer.tv_sec-older.tv_sec)*1000+
|
||||
(newer.tv_usec-older.tv_usec)/1000;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLM *mcurl;
|
||||
int still_running = 1;
|
||||
struct timeval mp_start;
|
||||
char mp_timedout = 0;
|
||||
struct WriteThis pooh;
|
||||
struct curl_slist* rcpt_list = NULL;
|
||||
|
||||
pooh.counter = 0;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(!curl)
|
||||
return 1;
|
||||
|
||||
mcurl = curl_multi_init();
|
||||
if(!mcurl)
|
||||
return 2;
|
||||
|
||||
rcpt_list = curl_slist_append(rcpt_list, RECIPIENT);
|
||||
/* more addresses can be added here
|
||||
rcpt_list = curl_slist_append(rcpt_list, "<others@example.com>");
|
||||
*/
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "smtp://" SMTPSERVER SMTPPORT);
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, USERNAME);
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, PASSWORD);
|
||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
|
||||
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, MAILFROM);
|
||||
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, rcpt_list);
|
||||
curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER,0);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
curl_easy_setopt(curl, CURLOPT_READDATA, &pooh);
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_SSLVERSION, 0);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_SESSIONID_CACHE, 0);
|
||||
curl_multi_add_handle(mcurl, curl);
|
||||
|
||||
mp_timedout = 0;
|
||||
mp_start = tvnow();
|
||||
|
||||
/* we start some action by calling perform right away */
|
||||
curl_multi_perform(mcurl, &still_running);
|
||||
|
||||
while(still_running) {
|
||||
struct timeval timeout;
|
||||
int rc; /* select() return code */
|
||||
|
||||
fd_set fdread;
|
||||
fd_set fdwrite;
|
||||
fd_set fdexcep;
|
||||
int maxfd = -1;
|
||||
|
||||
long curl_timeo = -1;
|
||||
|
||||
FD_ZERO(&fdread);
|
||||
FD_ZERO(&fdwrite);
|
||||
FD_ZERO(&fdexcep);
|
||||
|
||||
/* set a suitable timeout to play around with */
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
curl_multi_timeout(mcurl, &curl_timeo);
|
||||
if(curl_timeo >= 0) {
|
||||
timeout.tv_sec = curl_timeo / 1000;
|
||||
if(timeout.tv_sec > 1)
|
||||
timeout.tv_sec = 1;
|
||||
else
|
||||
timeout.tv_usec = (curl_timeo % 1000) * 1000;
|
||||
}
|
||||
|
||||
/* get file descriptors from the transfers */
|
||||
curl_multi_fdset(mcurl, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||
|
||||
/* In a real-world program you OF COURSE check the return code of the
|
||||
function calls. On success, the value of maxfd is guaranteed to be
|
||||
greater or equal than -1. We call select(maxfd + 1, ...), specially in
|
||||
case of (maxfd == -1), we call select(0, ...), which is basically equal
|
||||
to sleep. */
|
||||
|
||||
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||
|
||||
if (tvdiff(tvnow(), mp_start) > MULTI_PERFORM_HANG_TIMEOUT) {
|
||||
fprintf(stderr, "ABORTING TEST, since it seems "
|
||||
"that it would have run forever.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
switch(rc) {
|
||||
case -1:
|
||||
/* select error */
|
||||
break;
|
||||
case 0: /* timeout */
|
||||
default: /* action */
|
||||
curl_multi_perform(mcurl, &still_running);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
curl_slist_free_all(rcpt_list);
|
||||
curl_multi_remove_handle(mcurl, curl);
|
||||
curl_multi_cleanup(mcurl);
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
136
third-party/curl-7.21.4/docs/examples/smtp-tls.c
vendored
Normal file
136
third-party/curl-7.21.4/docs/examples/smtp-tls.c
vendored
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to send mail using libcurl's SMTP
|
||||
* capabilities. It builds on the simplesmtp.c example, adding some
|
||||
* authentication and transport security.
|
||||
*/
|
||||
|
||||
#define FROM "<sender@example.org>"
|
||||
#define TO "<addressee@example.net>"
|
||||
#define CC "<info@example.org>"
|
||||
|
||||
static const char *payload_text[]={
|
||||
"Date: Mon, 29 Nov 2010 21:54:29 +1100\n",
|
||||
"To: " TO "\n",
|
||||
"From: " FROM "(Example User)\n",
|
||||
"Cc: " CC "(Another example User)\n",
|
||||
"Message-ID: <dcd7cb36-11db-487a-9f3a-e652a9458efd@rfcpedant.example.org>\n",
|
||||
"Subject: SMTP TLS example message\n",
|
||||
"\n", /* empty line to divide headers from body, see RFC5322 */
|
||||
"The body of the message starts here.\n",
|
||||
"\n",
|
||||
"It could be a lot of lines, could be MIME encoded, whatever.\n",
|
||||
"Check RFC5322.\n",
|
||||
NULL
|
||||
};
|
||||
|
||||
struct upload_status {
|
||||
int lines_read;
|
||||
};
|
||||
|
||||
static size_t payload_source(void *ptr, size_t size, size_t nmemb, void *userp)
|
||||
{
|
||||
struct upload_status *upload_ctx = (struct upload_status *)userp;
|
||||
const char *data;
|
||||
|
||||
if ((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
data = payload_text[upload_ctx->lines_read];
|
||||
|
||||
if (data) {
|
||||
size_t len = strlen(data);
|
||||
memcpy(ptr, data, len);
|
||||
upload_ctx->lines_read ++;
|
||||
return len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct curl_slist *recipients = NULL;
|
||||
struct upload_status upload_ctx;
|
||||
|
||||
upload_ctx.lines_read = 0;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if (curl) {
|
||||
/* This is the URL for your mailserver. Note the use of port 587 here,
|
||||
* instead of the normal SMTP port (25). Port 587 is commonly used for
|
||||
* secure mail submission (see RFC4403), but you should use whatever
|
||||
* matches your server configuration. */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "smtp://mainserver.example.net:587");
|
||||
|
||||
/* In this example, we'll start with a plain text connection, and upgrade
|
||||
* to Transport Layer Security (TLS) using the STARTTLS command. Be careful
|
||||
* of using CURLUSESSL_TRY here, because if TLS upgrade fails, the transfer
|
||||
* will continue anyway - see the security discussion in the libcurl
|
||||
* tutorial for more details. */
|
||||
curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL);
|
||||
|
||||
/* If your server doesn't have a valid certificate, then you can disable
|
||||
* part of the Transport Layer Security protection by setting the
|
||||
* CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST options to 0 (false).
|
||||
* curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
* curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
* That is, in general, a bad idea. It is still better than sending your
|
||||
* authentication details in plain text though.
|
||||
* Instead, you should get the issuer certificate (or the host certificate
|
||||
* if the certificate is self-signed) and add it to the set of certificates
|
||||
* that are known to libcurl using CURLOPT_CAINFO and/or CURLOPT_CAPATH. See
|
||||
* docs/SSLCERTS for more information.
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_CAINFO, "/path/to/certificate.pem");
|
||||
|
||||
/* A common reason for requiring transport security is to protect
|
||||
* authentication details (user names and passwords) from being "snooped"
|
||||
* on the network. Here is how the user name and password are provided: */
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, "user@example.net");
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, "P@ssw0rd");
|
||||
|
||||
/* value for envelope reverse-path */
|
||||
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM);
|
||||
/* Add two recipients, in this particular case they correspond to the
|
||||
* To: and Cc: addressees in the header, but they could be any kind of
|
||||
* recipient. */
|
||||
recipients = curl_slist_append(recipients, TO);
|
||||
recipients = curl_slist_append(recipients, CC);
|
||||
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
|
||||
|
||||
/* In this case, we're using a callback function to specify the data. You
|
||||
* could just use the CURLOPT_READDATA option to specify a FILE pointer to
|
||||
* read from.
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, payload_source);
|
||||
curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx);
|
||||
|
||||
/* Since the traffic will be encrypted, it is very useful to turn on debug
|
||||
* information within libcurl to see what is happening during the transfer.
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
|
||||
|
||||
/* send the message (including headers) */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* free the list of recipients and clean up */
|
||||
curl_slist_free_all(recipients);
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
353
third-party/curl-7.21.4/docs/examples/synctime.c
vendored
Normal file
353
third-party/curl-7.21.4/docs/examples/synctime.c
vendored
Normal file
|
|
@ -0,0 +1,353 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*
|
||||
* This example code only builds as-is on Windows.
|
||||
*
|
||||
* While Unix/Linux user, you do not need this software.
|
||||
* You can achieve the same result as synctime using curl, awk and date.
|
||||
* Set proxy as according to your network, but beware of proxy Cache-Control.
|
||||
*
|
||||
* To set your system clock, root access is required.
|
||||
* # date -s "`curl -sI http://nist.time.gov/timezone.cgi?UTC/s/0 \
|
||||
* | awk -F': ' '/Date: / {print $2}'`"
|
||||
*
|
||||
* To view remote webserver date and time.
|
||||
* $ curl -sI http://nist.time.gov/timezone.cgi?UTC/s/0 \
|
||||
* | awk -F': ' '/Date: / {print $2}'
|
||||
*
|
||||
* Synchronising your computer clock via Internet time server usually relies
|
||||
* on DAYTIME, TIME, or NTP protocols. These protocols provide good accurate
|
||||
* time synchronisation but it does not work very well through a
|
||||
* firewall/proxy. Some adjustment has to be made to the firewall/proxy for
|
||||
* these protocols to work properly.
|
||||
*
|
||||
* There is an indirect method. Since most webserver provide server time in
|
||||
* their HTTP header, therefore you could synchronise your computer clock
|
||||
* using HTTP protocol which has no problem with firewall/proxy.
|
||||
*
|
||||
* For this software to work, you should take note of these items.
|
||||
* 1. Your firewall/proxy must allow your computer to surf internet.
|
||||
* 2. Webserver system time must in sync with the NTP time server,
|
||||
* or at least provide an accurate time keeping.
|
||||
* 3. Webserver HTTP header does not provide the milliseconds units,
|
||||
* so there is no way to get very accurate time.
|
||||
* 4. This software could only provide an accuracy of +- a few seconds,
|
||||
* as Round-Trip delay time is not taken into consideration.
|
||||
* Compensation of network, firewall/proxy delay cannot be simply divide
|
||||
* the Round-Trip delay time by half.
|
||||
* 5. Win32 SetSystemTime() API will set your computer clock according to
|
||||
* GMT/UTC time. Therefore your computer timezone must be properly set.
|
||||
* 6. Webserver data should not be cached by the proxy server. Some
|
||||
* webserver provide Cache-Control to prevent caching.
|
||||
*
|
||||
* References:
|
||||
* http://tf.nist.gov/timefreq/service/its.htm
|
||||
* http://tf.nist.gov/timefreq/service/firewall.htm
|
||||
*
|
||||
* Usage:
|
||||
* This software will synchronise your computer clock only when you issue
|
||||
* it with --synctime. By default, it only display the webserver's clock.
|
||||
*
|
||||
* Written by: Frank (contributed to libcurl)
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
||||
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* IN NO EVENT SHALL THE AUTHOR OF THIS SOFTWARE BE LIABLE FOR
|
||||
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
|
||||
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
|
||||
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#ifndef __CYGWIN__
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
||||
#define MAX_STRING 256
|
||||
#define MAX_STRING1 MAX_STRING+1
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char http_proxy[MAX_STRING1];
|
||||
char proxy_user[MAX_STRING1];
|
||||
char timeserver[MAX_STRING1];
|
||||
} conf_t;
|
||||
|
||||
const char DefaultTimeServer[4][MAX_STRING1] =
|
||||
{
|
||||
"http://nist.time.gov/timezone.cgi?UTC/s/0",
|
||||
"http://www.google.com/",
|
||||
"http://www.worldtimeserver.com/current_time_in_UTC.aspx",
|
||||
"http://www.worldtime.com/cgi-bin/wt.cgi"
|
||||
};
|
||||
|
||||
const char *DayStr[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
|
||||
const char *MthStr[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
|
||||
|
||||
int ShowAllHeader;
|
||||
int AutoSyncTime;
|
||||
SYSTEMTIME SYSTime;
|
||||
SYSTEMTIME LOCALTime;
|
||||
|
||||
#define HTTP_COMMAND_HEAD 0
|
||||
#define HTTP_COMMAND_GET 1
|
||||
|
||||
|
||||
size_t SyncTime_CURL_WriteOutput(void *ptr, size_t size, size_t nmemb,
|
||||
void *stream)
|
||||
{
|
||||
fwrite(ptr, size, nmemb, stream);
|
||||
return(nmemb*size);
|
||||
}
|
||||
|
||||
size_t SyncTime_CURL_WriteHeader(void *ptr, size_t size, size_t nmemb,
|
||||
void *stream)
|
||||
{
|
||||
int i, RetVal;
|
||||
char TmpStr1[26], TmpStr2[26];
|
||||
|
||||
if (ShowAllHeader == 1)
|
||||
fprintf(stderr, "%s", (char *)(ptr));
|
||||
|
||||
if (strncmp((char *)(ptr), "Date:", 5) == 0) {
|
||||
if (ShowAllHeader == 0)
|
||||
fprintf(stderr, "HTTP Server. %s", (char *)(ptr));
|
||||
|
||||
if (AutoSyncTime == 1) {
|
||||
*TmpStr1 = 0;
|
||||
*TmpStr2 = 0;
|
||||
if (strlen((char *)(ptr)) > 50) /* Can prevent buffer overflow to
|
||||
TmpStr1 & 2? */
|
||||
AutoSyncTime = 0;
|
||||
else {
|
||||
RetVal = sscanf ((char *)(ptr), "Date: %s %d %s %d %d:%d:%d",
|
||||
TmpStr1, &SYSTime.wDay, TmpStr2, &SYSTime.wYear,
|
||||
&SYSTime.wHour, &SYSTime.wMinute, &SYSTime.wSecond);
|
||||
|
||||
if (RetVal == 7) {
|
||||
|
||||
SYSTime.wMilliseconds = 500; /* adjust to midpoint, 0.5 sec */
|
||||
for (i=0; i<12; i++) {
|
||||
if (strcmp(MthStr[i], TmpStr2) == 0) {
|
||||
SYSTime.wMonth = i+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
AutoSyncTime = 3; /* Computer clock will be adjusted */
|
||||
}
|
||||
else {
|
||||
AutoSyncTime = 0; /* Error in sscanf() fields conversion */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (strncmp((char *)(ptr), "X-Cache: HIT", 12) == 0) {
|
||||
fprintf(stderr, "ERROR: HTTP Server data is cached."
|
||||
" Server Date is no longer valid.\n");
|
||||
AutoSyncTime = 0;
|
||||
}
|
||||
return(nmemb*size);
|
||||
}
|
||||
|
||||
void SyncTime_CURL_Init(CURL *curl, char *proxy_port,
|
||||
char *proxy_user_password)
|
||||
{
|
||||
if (strlen(proxy_port) > 0)
|
||||
curl_easy_setopt(curl, CURLOPT_PROXY, proxy_port);
|
||||
|
||||
if (strlen(proxy_user_password) > 0)
|
||||
curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, proxy_user_password);
|
||||
|
||||
/* Trick Webserver by claiming that you are using Microsoft WinXP SP2, IE6 */
|
||||
curl_easy_setopt(curl, CURLOPT_USERAGENT,
|
||||
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, *SyncTime_CURL_WriteOutput);
|
||||
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, *SyncTime_CURL_WriteHeader);
|
||||
}
|
||||
|
||||
int SyncTime_CURL_Fetch(CURL *curl, char *URL_Str, char *OutFileName,
|
||||
int HttpGetBody)
|
||||
{
|
||||
FILE *outfile;
|
||||
CURLcode res;
|
||||
|
||||
outfile = NULL;
|
||||
if (HttpGetBody == HTTP_COMMAND_HEAD)
|
||||
curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
|
||||
else {
|
||||
outfile = fopen(OutFileName, "wb");
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile);
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, URL_Str);
|
||||
res = curl_easy_perform(curl);
|
||||
if (outfile != NULL)
|
||||
fclose(outfile);
|
||||
return res; /* (CURLE_OK) */
|
||||
}
|
||||
|
||||
void showUsage(void)
|
||||
{
|
||||
fprintf(stderr, "SYNCTIME: Synchronising computer clock with time server"
|
||||
" using HTTP protocol.\n");
|
||||
fprintf(stderr, "Usage : SYNCTIME [Option]\n");
|
||||
fprintf(stderr, "Options :\n");
|
||||
fprintf(stderr, " --server=WEBSERVER Use this time server instead"
|
||||
" of default.\n");
|
||||
fprintf(stderr, " --showall Show all HTTP header.\n");
|
||||
fprintf(stderr, " --synctime Synchronising computer clock"
|
||||
" with time server.\n");
|
||||
fprintf(stderr, " --proxy-user=USER[:PASS] Set proxy username and"
|
||||
" password.\n");
|
||||
fprintf(stderr, " --proxy=HOST[:PORT] Use HTTP proxy on given"
|
||||
" port.\n");
|
||||
fprintf(stderr, " --help Print this help.\n");
|
||||
fprintf(stderr, "\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int conf_init(conf_t *conf)
|
||||
{
|
||||
int i;
|
||||
|
||||
*conf->http_proxy = 0;
|
||||
for (i=0; i<MAX_STRING1; i++)
|
||||
conf->proxy_user[i] = 0; /* Clean up password from memory */
|
||||
*conf->timeserver = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
CURL *curl;
|
||||
conf_t conf[1];
|
||||
int OptionIndex;
|
||||
struct tm *lt;
|
||||
struct tm *gmt;
|
||||
time_t tt;
|
||||
time_t tt_local;
|
||||
time_t tt_gmt;
|
||||
double tzonediffFloat;
|
||||
int tzonediffWord;
|
||||
char timeBuf[61];
|
||||
char tzoneBuf[16];
|
||||
int RetValue;
|
||||
|
||||
OptionIndex = 0;
|
||||
ShowAllHeader = 0; /* Do not show HTTP Header */
|
||||
AutoSyncTime = 0; /* Do not synchronise computer clock */
|
||||
RetValue = 0; /* Successful Exit */
|
||||
conf_init(conf);
|
||||
|
||||
if (argc > 1) {
|
||||
while (OptionIndex < argc) {
|
||||
if (strncmp(argv[OptionIndex], "--server=", 9) == 0)
|
||||
snprintf(conf->timeserver, MAX_STRING, "%s", &argv[OptionIndex][9]);
|
||||
|
||||
if (strcmp(argv[OptionIndex], "--showall") == 0)
|
||||
ShowAllHeader = 1;
|
||||
|
||||
if (strcmp(argv[OptionIndex], "--synctime") == 0)
|
||||
AutoSyncTime = 1;
|
||||
|
||||
if (strncmp(argv[OptionIndex], "--proxy-user=", 13) == 0)
|
||||
snprintf(conf->proxy_user, MAX_STRING, "%s", &argv[OptionIndex][13]);
|
||||
|
||||
if (strncmp(argv[OptionIndex], "--proxy=", 8) == 0)
|
||||
snprintf(conf->http_proxy, MAX_STRING, "%s", &argv[OptionIndex][8]);
|
||||
|
||||
if ((strcmp(argv[OptionIndex], "--help") == 0) ||
|
||||
(strcmp(argv[OptionIndex], "/?") == 0)) {
|
||||
showUsage();
|
||||
return 0;
|
||||
}
|
||||
OptionIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
if (*conf->timeserver == 0) /* Use default server for time information */
|
||||
snprintf(conf->timeserver, MAX_STRING, "%s", DefaultTimeServer[0]);
|
||||
|
||||
/* Init CURL before usage */
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
curl = curl_easy_init();
|
||||
if (curl) {
|
||||
SyncTime_CURL_Init(curl, conf->http_proxy, conf->proxy_user);
|
||||
|
||||
/* Calculating time diff between GMT and localtime */
|
||||
tt = time(0);
|
||||
lt = localtime(&tt);
|
||||
tt_local = mktime(lt);
|
||||
gmt = gmtime(&tt);
|
||||
tt_gmt = mktime(gmt);
|
||||
tzonediffFloat = difftime(tt_local, tt_gmt);
|
||||
tzonediffWord = (int)(tzonediffFloat/3600.0);
|
||||
|
||||
if ((double)(tzonediffWord * 3600) == tzonediffFloat)
|
||||
snprintf(tzoneBuf, 15, "%+03d'00'", tzonediffWord);
|
||||
else
|
||||
snprintf(tzoneBuf, 15, "%+03d'30'", tzonediffWord);
|
||||
|
||||
/* Get current system time and local time */
|
||||
GetSystemTime(&SYSTime);
|
||||
GetLocalTime(&LOCALTime);
|
||||
snprintf(timeBuf, 60, "%s, %02d %s %04d %02d:%02d:%02d.%03d, ",
|
||||
DayStr[LOCALTime.wDayOfWeek], LOCALTime.wDay,
|
||||
MthStr[LOCALTime.wMonth-1], LOCALTime.wYear,
|
||||
LOCALTime.wHour, LOCALTime.wMinute, LOCALTime.wSecond,
|
||||
LOCALTime.wMilliseconds);
|
||||
|
||||
fprintf(stderr, "Fetch: %s\n\n", conf->timeserver);
|
||||
fprintf(stderr, "Before HTTP. Date: %s%s\n\n", timeBuf, tzoneBuf);
|
||||
|
||||
/* HTTP HEAD command to the Webserver */
|
||||
SyncTime_CURL_Fetch(curl, conf->timeserver, "index.htm",
|
||||
HTTP_COMMAND_HEAD);
|
||||
|
||||
GetLocalTime(&LOCALTime);
|
||||
snprintf(timeBuf, 60, "%s, %02d %s %04d %02d:%02d:%02d.%03d, ",
|
||||
DayStr[LOCALTime.wDayOfWeek], LOCALTime.wDay,
|
||||
MthStr[LOCALTime.wMonth-1], LOCALTime.wYear,
|
||||
LOCALTime.wHour, LOCALTime.wMinute, LOCALTime.wSecond,
|
||||
LOCALTime.wMilliseconds);
|
||||
fprintf(stderr, "\nAfter HTTP. Date: %s%s\n", timeBuf, tzoneBuf);
|
||||
|
||||
if (AutoSyncTime == 3) {
|
||||
/* Synchronising computer clock */
|
||||
if (!SetSystemTime(&SYSTime)) { /* Set system time */
|
||||
fprintf(stderr, "ERROR: Unable to set system time.\n");
|
||||
RetValue = 1;
|
||||
}
|
||||
else {
|
||||
/* Successfully re-adjusted computer clock */
|
||||
GetLocalTime(&LOCALTime);
|
||||
snprintf(timeBuf, 60, "%s, %02d %s %04d %02d:%02d:%02d.%03d, ",
|
||||
DayStr[LOCALTime.wDayOfWeek], LOCALTime.wDay,
|
||||
MthStr[LOCALTime.wMonth-1], LOCALTime.wYear,
|
||||
LOCALTime.wHour, LOCALTime.wMinute, LOCALTime.wSecond,
|
||||
LOCALTime.wMilliseconds);
|
||||
fprintf(stderr, "\nNew System's Date: %s%s\n", timeBuf, tzoneBuf);
|
||||
}
|
||||
}
|
||||
|
||||
/* Cleanup before exit */
|
||||
conf_init(conf);
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return RetValue;
|
||||
}
|
||||
149
third-party/curl-7.21.4/docs/examples/threaded-ssl.c
vendored
Normal file
149
third-party/curl-7.21.4/docs/examples/threaded-ssl.c
vendored
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*
|
||||
* A multi-threaded example that uses pthreads and fetches 4 remote files at
|
||||
* once over HTTPS. The lock callbacks and stuff assume OpenSSL or GnuTLS
|
||||
* (libgcrypt) so far.
|
||||
*
|
||||
* OpenSSL docs for this:
|
||||
* http://www.openssl.org/docs/crypto/threads.html
|
||||
* gcrypt docs for this:
|
||||
* http://gnupg.org/documentation/manuals/gcrypt/Multi_002dThreading.html
|
||||
*/
|
||||
|
||||
#define USE_OPENSSL /* or USE_GNUTLS accordingly */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#define NUMT 4
|
||||
|
||||
/* we have this global to let the callback get easy access to it */
|
||||
static pthread_mutex_t *lockarray;
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
#include <openssl/crypto.h>
|
||||
static void lock_callback(int mode, int type, char *file, int line)
|
||||
{
|
||||
(void)file;
|
||||
(void)line;
|
||||
if (mode & CRYPTO_LOCK) {
|
||||
pthread_mutex_lock(&(lockarray[type]));
|
||||
}
|
||||
else {
|
||||
pthread_mutex_unlock(&(lockarray[type]));
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned long thread_id(void)
|
||||
{
|
||||
unsigned long ret;
|
||||
|
||||
ret=(unsigned long)pthread_self();
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static void init_locks(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
lockarray=(pthread_mutex_t *)OPENSSL_malloc(CRYPTO_num_locks() *
|
||||
sizeof(pthread_mutex_t));
|
||||
for (i=0; i<CRYPTO_num_locks(); i++) {
|
||||
pthread_mutex_init(&(lockarray[i]),NULL);
|
||||
}
|
||||
|
||||
CRYPTO_set_id_callback((unsigned long (*)())thread_id);
|
||||
CRYPTO_set_locking_callback((void (*)())lock_callback);
|
||||
}
|
||||
|
||||
static void kill_locks(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
CRYPTO_set_locking_callback(NULL);
|
||||
for (i=0; i<CRYPTO_num_locks(); i++)
|
||||
pthread_mutex_destroy(&(lockarray[i]));
|
||||
|
||||
OPENSSL_free(lockarray);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_GNUTLS
|
||||
#include <gcrypt.h>
|
||||
#include <errno.h>
|
||||
|
||||
GCRY_THREAD_OPTION_PTHREAD_IMPL;
|
||||
|
||||
void init_locks(void)
|
||||
{
|
||||
gcry_control(GCRYCTL_SET_THREAD_CBS);
|
||||
}
|
||||
|
||||
#define kill_locks()
|
||||
#endif
|
||||
|
||||
/* List of URLs to fetch.*/
|
||||
const char * const urls[]= {
|
||||
"https://www.example.com/",
|
||||
"https://www2.example.com/",
|
||||
"https://www3.example.com/",
|
||||
"https://www4.example.com/",
|
||||
};
|
||||
|
||||
static void *pull_one_url(void *url)
|
||||
{
|
||||
CURL *curl;
|
||||
|
||||
curl = curl_easy_init();
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
/* this example doesn't verify the server's certificate, which means we
|
||||
might be downloading stuff from an impostor */
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
curl_easy_perform(curl); /* ignores error */
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
pthread_t tid[NUMT];
|
||||
int i;
|
||||
int error;
|
||||
(void)argc; /* we don't use any arguments in this example */
|
||||
(void)argv;
|
||||
|
||||
/* Must initialize libcurl before any threads are started */
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
init_locks();
|
||||
|
||||
for(i=0; i< NUMT; i++) {
|
||||
error = pthread_create(&tid[i],
|
||||
NULL, /* default attributes please */
|
||||
pull_one_url,
|
||||
(void *)urls[i]);
|
||||
if(0 != error)
|
||||
fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error);
|
||||
else
|
||||
fprintf(stderr, "Thread %d, gets %s\n", i, urls[i]);
|
||||
}
|
||||
|
||||
/* now wait for all threads to terminate */
|
||||
for(i=0; i< NUMT; i++) {
|
||||
error = pthread_join(tid[i], NULL);
|
||||
fprintf(stderr, "Thread %d terminated\n", i);
|
||||
}
|
||||
|
||||
kill_locks();
|
||||
|
||||
return 0;
|
||||
}
|
||||
105
third-party/curl-7.21.4/docs/examples/version-check.pl
vendored
Executable file
105
third-party/curl-7.21.4/docs/examples/version-check.pl
vendored
Executable file
|
|
@ -0,0 +1,105 @@
|
|||
#!/usr/bin/env perl
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2010, 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 accepts a source file as input on the command line.
|
||||
#
|
||||
# It first loads the 'symbols-in-versions' document and stores a lookup
|
||||
# table for all known symbols for which version they were introduced.
|
||||
#
|
||||
# It then scans the given source file to dig up all symbols starting with CURL.
|
||||
# Finally, it sorts the internal list of found symbols (using the version
|
||||
# number as sort key) and then it outputs the most recent version number and
|
||||
# the symbols from that version that are used.
|
||||
#
|
||||
# Usage:
|
||||
#
|
||||
# version-check.pl [source file]
|
||||
#
|
||||
|
||||
open(S, "<../libcurl/symbols-in-versions") || die;
|
||||
|
||||
my %doc;
|
||||
my %rem;
|
||||
while(<S>) {
|
||||
if(/(^CURL[^ \n]*) *(.*)/) {
|
||||
my ($sym, $rest)=($1, $2);
|
||||
my @a=split(/ +/, $rest);
|
||||
|
||||
$doc{$sym}=$a[0]; # when it was introduced
|
||||
|
||||
if($a[2]) {
|
||||
# this symbol is documented to have been present the last time
|
||||
# in this release
|
||||
$rem{$sym}=$a[2];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
close(S);
|
||||
|
||||
sub age {
|
||||
my ($ver)=@_;
|
||||
|
||||
my @s=split(/\./, $ver);
|
||||
return $s[0]*10000+$s[1]*100+$s[2];
|
||||
}
|
||||
|
||||
my %used;
|
||||
open(C, "<$ARGV[0]") || die;
|
||||
|
||||
while(<C>) {
|
||||
if(/\W(CURL[_A-Z0-9v]+)\W/) {
|
||||
#print "$1\n";
|
||||
$used{$1}++;
|
||||
}
|
||||
}
|
||||
|
||||
close(C);
|
||||
|
||||
sub sortversions {
|
||||
my $r = age($doc{$a}) <=> age($doc{$b});
|
||||
if(!$r) {
|
||||
$r = $a cmp $b;
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
|
||||
my @recent = reverse sort sortversions keys %used;
|
||||
|
||||
# the most recent symbol
|
||||
my $newsym = $recent[0];
|
||||
# the most recent version
|
||||
my $newver = $doc{$newsym};
|
||||
|
||||
print "The scanned source uses these symbols introduced in $newver:\n";
|
||||
|
||||
for my $w (@recent) {
|
||||
if($doc{$w} eq $newver) {
|
||||
printf " $w\n";
|
||||
next;
|
||||
}
|
||||
last;
|
||||
}
|
||||
|
||||
|
||||
2
third-party/curl-7.21.4/docs/libcurl/.gitignore
vendored
Normal file
2
third-party/curl-7.21.4/docs/libcurl/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
*.html
|
||||
*.pdf
|
||||
69
third-party/curl-7.21.4/docs/libcurl/ABI
vendored
Normal file
69
third-party/curl-7.21.4/docs/libcurl/ABI
vendored
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
libcurl's binary interface
|
||||
|
||||
ABI - Application Binary Interface
|
||||
|
||||
First, allow me to define the word for this context: ABI describes the
|
||||
low-level interface between an application program and a library. Calling
|
||||
conventions, function arguments, return values, struct sizes/defines and
|
||||
more.
|
||||
|
||||
For a longer description, see
|
||||
http://en.wikipedia.org/wiki/Application_binary_interface
|
||||
|
||||
Upgrades
|
||||
|
||||
In the vast majority of all cases, a typical libcurl upgrade does not break
|
||||
the ABI at all. Your application can remain using libcurl just as before,
|
||||
only with less bugs and possibly with added new features. You need to read
|
||||
the release notes, and if they mention an ABI break/soname bump, you may
|
||||
have to verify that your application still builds fine and uses libcurl as
|
||||
it now is defined to work.
|
||||
|
||||
Version Numbers
|
||||
|
||||
In libcurl land, you really can't tell by the libcurl version number if that
|
||||
libcurl is binary compatible or not with another libcurl version.
|
||||
|
||||
Soname Bumps
|
||||
|
||||
Whenever there are changes done to the library that will cause an ABI
|
||||
breakage, that may require your application to get attention or possibly be
|
||||
changed to adhere to new things, we will bump the soname. Then the library
|
||||
will get a different output name and thus can in fact be installed in
|
||||
parallel with an older installed lib (on most systems). Thus, old
|
||||
applications built against the previous ABI version will remain working and
|
||||
using the older lib, while newer applications build and use the newer one.
|
||||
|
||||
During the first seven years of libcurl releases, there have only been four
|
||||
ABI breakages.
|
||||
|
||||
Downgrades
|
||||
|
||||
Going to an older libcurl version from one you're currently using can be a
|
||||
tricky thing. Mostly we add features and options to newer libcurls as that
|
||||
won't break ABI or hamper existing applications. This has the implication
|
||||
that going backwards may get you in a situation where you pick a libcurl
|
||||
that doesn't support the options your application needs. Or possibly you
|
||||
even downgrade so far so you cross an ABI break border and thus a different
|
||||
soname, and then your application may need to adapt to the modified ABI.
|
||||
|
||||
History
|
||||
|
||||
The previous major library soname number bumps (breaking backwards
|
||||
compatibility) have happened the following times:
|
||||
|
||||
0 - libcurl 7.1, August 2000
|
||||
|
||||
1 - libcurl 7.5 December 2000
|
||||
|
||||
2 - libcurl 7.7 March 2001
|
||||
|
||||
3 - libcurl 7.12.0 June 2004
|
||||
|
||||
4 - libcurl 7.16.0 October 2006
|
||||
83
third-party/curl-7.21.4/docs/libcurl/Makefile.am
vendored
Normal file
83
third-party/curl-7.21.4/docs/libcurl/Makefile.am
vendored
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
#
|
||||
#
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign no-dependencies
|
||||
|
||||
man_MANS = curl_easy_cleanup.3 curl_easy_getinfo.3 curl_easy_init.3 \
|
||||
curl_easy_perform.3 curl_easy_setopt.3 curl_easy_duphandle.3 \
|
||||
curl_formadd.3 curl_formfree.3 curl_getdate.3 curl_getenv.3 \
|
||||
curl_slist_append.3 curl_slist_free_all.3 curl_version.3 \
|
||||
curl_version_info.3 curl_escape.3 curl_unescape.3 curl_free.3 \
|
||||
curl_strequal.3 curl_mprintf.3 curl_global_init.3 curl_global_cleanup.3 \
|
||||
curl_multi_add_handle.3 curl_multi_cleanup.3 curl_multi_fdset.3 \
|
||||
curl_multi_info_read.3 curl_multi_init.3 curl_multi_perform.3 \
|
||||
curl_multi_remove_handle.3 curl_share_cleanup.3 curl_share_init.3 \
|
||||
curl_share_setopt.3 libcurl.3 libcurl-easy.3 libcurl-multi.3 \
|
||||
libcurl-share.3 libcurl-errors.3 curl_easy_strerror.3 \
|
||||
curl_multi_strerror.3 curl_share_strerror.3 curl_global_init_mem.3 \
|
||||
libcurl-tutorial.3 curl_easy_reset.3 curl_easy_escape.3 \
|
||||
curl_easy_unescape.3 curl_multi_setopt.3 curl_multi_socket.3 \
|
||||
curl_multi_timeout.3 curl_formget.3 curl_multi_assign.3 \
|
||||
curl_easy_pause.3 curl_easy_recv.3 curl_easy_send.3 \
|
||||
curl_multi_socket_action.3
|
||||
|
||||
HTMLPAGES = curl_easy_cleanup.html curl_easy_getinfo.html \
|
||||
curl_easy_init.html curl_easy_perform.html curl_easy_setopt.html \
|
||||
curl_easy_duphandle.html curl_formadd.html curl_formfree.html \
|
||||
curl_getdate.html curl_getenv.html curl_slist_append.html \
|
||||
curl_slist_free_all.html curl_version.html curl_version_info.html \
|
||||
curl_escape.html curl_unescape.html curl_free.html curl_strequal.html \
|
||||
curl_mprintf.html curl_global_init.html curl_global_cleanup.html \
|
||||
curl_multi_add_handle.html curl_multi_cleanup.html \
|
||||
curl_multi_fdset.html curl_multi_info_read.html curl_multi_init.html \
|
||||
curl_multi_perform.html curl_multi_remove_handle.html \
|
||||
curl_share_cleanup.html curl_share_init.html curl_share_setopt.html \
|
||||
libcurl.html libcurl-multi.html libcurl-easy.html libcurl-share.html \
|
||||
libcurl-errors.html curl_easy_strerror.html curl_multi_strerror.html \
|
||||
curl_share_strerror.html curl_global_init_mem.html \
|
||||
libcurl-tutorial.html curl_easy_reset.html curl_easy_escape.html \
|
||||
curl_easy_unescape.html curl_multi_setopt.html curl_multi_socket.html \
|
||||
curl_multi_timeout.html curl_formget.html curl_multi_assign.html \
|
||||
curl_easy_pause.html curl_easy_recv.html curl_easy_send.html \
|
||||
curl_multi_socket_action.html
|
||||
|
||||
PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf \
|
||||
curl_easy_init.pdf curl_easy_perform.pdf curl_easy_setopt.pdf \
|
||||
curl_easy_duphandle.pdf curl_formadd.pdf curl_formfree.pdf \
|
||||
curl_getdate.pdf curl_getenv.pdf curl_slist_append.pdf \
|
||||
curl_slist_free_all.pdf curl_version.pdf curl_version_info.pdf \
|
||||
curl_escape.pdf curl_unescape.pdf curl_free.pdf curl_strequal.pdf \
|
||||
curl_mprintf.pdf curl_global_init.pdf curl_global_cleanup.pdf \
|
||||
curl_multi_add_handle.pdf curl_multi_cleanup.pdf curl_multi_fdset.pdf \
|
||||
curl_multi_info_read.pdf curl_multi_init.pdf curl_multi_perform.pdf \
|
||||
curl_multi_remove_handle.pdf curl_share_cleanup.pdf curl_share_init.pdf \
|
||||
curl_share_setopt.pdf libcurl.pdf libcurl-multi.pdf libcurl-easy.pdf \
|
||||
libcurl-share.pdf libcurl-errors.pdf curl_easy_strerror.pdf \
|
||||
curl_multi_strerror.pdf curl_share_strerror.pdf \
|
||||
curl_global_init_mem.pdf libcurl-tutorial.pdf curl_easy_reset.pdf \
|
||||
curl_easy_escape.pdf curl_easy_unescape.pdf curl_multi_setopt.pdf \
|
||||
curl_multi_socket.pdf curl_multi_timeout.pdf curl_formget.pdf \
|
||||
curl_multi_assign.pdf curl_easy_pause.pdf curl_easy_recv.pdf \
|
||||
curl_easy_send.pdf curl_multi_socket_action.pdf
|
||||
|
||||
CLEANFILES = $(HTMLPAGES) $(PDFPAGES)
|
||||
|
||||
EXTRA_DIST = $(man_MANS) $(HTMLPAGES) index.html $(PDFPAGES) libcurl.m4 ABI \
|
||||
symbols-in-versions
|
||||
MAN2HTML= roffit --mandir=. < $< >$@
|
||||
|
||||
SUFFIXES = .3 .html
|
||||
|
||||
html: $(HTMLPAGES)
|
||||
|
||||
.3.html:
|
||||
$(MAN2HTML)
|
||||
|
||||
pdf: $(PDFPAGES)
|
||||
|
||||
.3.pdf:
|
||||
@(foo=`echo $@ | sed -e 's/\.[0-9]$$//g'`; \
|
||||
groff -Tps -man $< >$$foo.ps; \
|
||||
ps2pdf $$foo.ps $@; \
|
||||
rm $$foo.ps; \
|
||||
echo "converted $< to $@")
|
||||
50
third-party/curl-7.21.4/docs/libcurl/curl_easy_cleanup.3
vendored
Normal file
50
third-party/curl-7.21.4/docs/libcurl/curl_easy_cleanup.3
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
.\" **************************************************************************
|
||||
.\" * _ _ ____ _
|
||||
.\" * Project ___| | | | _ \| |
|
||||
.\" * / __| | | | |_) | |
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * Copyright (C) 1998 - 2007, 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.
|
||||
.\" *
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH curl_easy_cleanup 3 "22 aug 2007" "libcurl 7.17.0" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_easy_cleanup - End a libcurl easy session
|
||||
.SH SYNOPSIS
|
||||
.B #include <curl/curl.h>
|
||||
|
||||
.BI "void curl_easy_cleanup(CURL *" handle ");"
|
||||
|
||||
.SH DESCRIPTION
|
||||
This function must be the last function to call for an easy session. It is the
|
||||
opposite of the \fIcurl_easy_init(3)\fP function and must be called with the
|
||||
same \fIhandle\fP as input that the curl_easy_init call returned.
|
||||
|
||||
This will effectively close all connections this handle has used and possibly
|
||||
has kept open until now. Don't call this function if you intend to transfer
|
||||
more files.
|
||||
|
||||
Any uses of the \fBhandle\fP after this function has been called are
|
||||
illegal. This kills the handle and all memory associated with it!
|
||||
|
||||
With libcurl versions prior to 7.17.: when you've called this, you can safely
|
||||
remove all the strings you've previously told libcurl to use, as it won't use
|
||||
them anymore now.
|
||||
.SH RETURN VALUE
|
||||
None
|
||||
.SH "SEE ALSO"
|
||||
.BR curl_easy_init "(3), "
|
||||
|
||||
33
third-party/curl-7.21.4/docs/libcurl/curl_easy_duphandle.3
vendored
Normal file
33
third-party/curl-7.21.4/docs/libcurl/curl_easy_duphandle.3
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
.\" You can view this file with:
|
||||
.\" nroff -man [file]
|
||||
.\"
|
||||
.TH curl_easy_duphandle 3 "18 September 2001" "libcurl 7.9" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_easy_duphandle - Clone a libcurl session handle
|
||||
.SH SYNOPSIS
|
||||
.B #include <curl/curl.h>
|
||||
|
||||
.BI "CURL *curl_easy_duphandle(CURL *"handle ");"
|
||||
|
||||
.SH DESCRIPTION
|
||||
This function will return a new curl handle, a duplicate, using all the
|
||||
options previously set in the input curl \fIhandle\fP. Both handles can
|
||||
subsequently be used independently and they must both be freed with
|
||||
\fIcurl_easy_cleanup(3)\fP.
|
||||
|
||||
All strings that the input handle has been told to point to (as opposed to
|
||||
copy) with previous calls to \fIcurl_easy_setopt(3)\fP using char * inputs,
|
||||
will be pointed to by the new handle as well. You must therefore make sure to
|
||||
keep the data around until both handles have been cleaned up.
|
||||
|
||||
The new handle will \fBnot\fP inherit any state information, no connections,
|
||||
no SSL sessions and no cookies.
|
||||
|
||||
\fBNote\fP that even in multi-threaded programs, this function must be called
|
||||
in a synchronous way, the input handle may not be in use when cloned.
|
||||
.SH RETURN VALUE
|
||||
If this function returns NULL, something went wrong and no valid handle was
|
||||
returned.
|
||||
.SH "SEE ALSO"
|
||||
.BR curl_easy_init "(3)," curl_easy_cleanup "(3)," curl_global_init "(3)
|
||||
|
||||
46
third-party/curl-7.21.4/docs/libcurl/curl_easy_escape.3
vendored
Normal file
46
third-party/curl-7.21.4/docs/libcurl/curl_easy_escape.3
vendored
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
.\" **************************************************************************
|
||||
.\" * _ _ ____ _
|
||||
.\" * Project ___| | | | _ \| |
|
||||
.\" * / __| | | | |_) | |
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * Copyright (C) 1998 - 2008, 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.
|
||||
.\" *
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH curl_easy_escape 3 "7 April 2006" "libcurl 7.15.4" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_easy_escape - URL encodes the given string
|
||||
.SH SYNOPSIS
|
||||
.B #include <curl/curl.h>
|
||||
.sp
|
||||
.BI "char *curl_easy_escape( CURL *" curl ", char *" url ", int "length " );"
|
||||
.ad
|
||||
.SH DESCRIPTION
|
||||
This function converts the given input string to an URL encoded string and
|
||||
returns that as a new allocated string. All input characters that are not a-z,
|
||||
A-Z or 0-9 are converted to their "URL escaped" version (%NN where NN is a
|
||||
two-digit hexadecimal number).
|
||||
|
||||
If the \fBlength\fP argument is set to 0 (zero), \fIcurl_easy_escape(3)\fP
|
||||
uses strlen() on the input \fBurl\fP to find out the size.
|
||||
|
||||
You must \fIcurl_free(3)\fP the returned string when you're done with it.
|
||||
.SH AVAILABILITY
|
||||
Added in 7.15.4 and replaces the old \fIcurl_escape(3)\fP function.
|
||||
.SH RETURN VALUE
|
||||
A pointer to a zero terminated string or NULL if it failed.
|
||||
.SH "SEE ALSO"
|
||||
.BR curl_easy_unescape "(3), " curl_free "(3), " RFC 2396
|
||||
289
third-party/curl-7.21.4/docs/libcurl/curl_easy_getinfo.3
vendored
Normal file
289
third-party/curl-7.21.4/docs/libcurl/curl_easy_getinfo.3
vendored
Normal file
|
|
@ -0,0 +1,289 @@
|
|||
.\" **************************************************************************
|
||||
.\" * _ _ ____ _
|
||||
.\" * Project ___| | | | _ \| |
|
||||
.\" * / __| | | | |_) | |
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * Copyright (C) 1998 - 2010, 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.
|
||||
.\" *
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH curl_easy_getinfo 3 "11 Feb 2009" "libcurl 7.19.4" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_easy_getinfo - extract information from a curl handle
|
||||
.SH SYNOPSIS
|
||||
.B #include <curl/curl.h>
|
||||
|
||||
.B "CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ... );"
|
||||
|
||||
.SH DESCRIPTION
|
||||
Request internal information from the curl session with this function. The
|
||||
third argument \fBMUST\fP be a pointer to a long, a pointer to a char *, a
|
||||
pointer to a struct curl_slist * or a pointer to a double (as this
|
||||
documentation describes further down). The data pointed-to will be filled in
|
||||
accordingly and can be relied upon only if the function returns CURLE_OK. Use
|
||||
this function AFTER a performed transfer if you want to get transfer- oriented
|
||||
data.
|
||||
|
||||
You should not free the memory returned by this function unless it is
|
||||
explicitly mentioned below.
|
||||
.SH AVAILABLE INFORMATION
|
||||
The following information can be extracted:
|
||||
.IP CURLINFO_EFFECTIVE_URL
|
||||
Pass a pointer to a char pointer to receive the last used effective URL.
|
||||
.IP CURLINFO_RESPONSE_CODE
|
||||
Pass a pointer to a long to receive the last received HTTP or FTP code. This
|
||||
option was known as CURLINFO_HTTP_CODE in libcurl 7.10.7 and earlier. This
|
||||
will be zero if no server response code has been received. Note that a proxy's
|
||||
CONNECT response should be read with \fICURLINFO_HTTP_CONNECTCODE\fP and not
|
||||
this.
|
||||
.IP CURLINFO_HTTP_CONNECTCODE
|
||||
Pass a pointer to a long to receive the last received proxy response code to a
|
||||
CONNECT request.
|
||||
.IP CURLINFO_FILETIME
|
||||
Pass a pointer to a long to receive the remote time of the retrieved document
|
||||
(in number of seconds since 1 jan 1970 in the GMT/UTC time zone). If you get
|
||||
-1, it can be because of many reasons (unknown, the server hides it or the
|
||||
server doesn't support the command that tells document time etc) and the time
|
||||
of the document is unknown. Note that you must tell the server to collect this
|
||||
information before the transfer is made, by using the CURLOPT_FILETIME option
|
||||
to \fIcurl_easy_setopt(3)\fP or you will unconditionally get a -1 back. (Added
|
||||
in 7.5)
|
||||
.IP CURLINFO_TOTAL_TIME
|
||||
Pass a pointer to a double to receive the total time in seconds for the
|
||||
previous transfer, including name resolving, TCP connect etc.
|
||||
.IP CURLINFO_NAMELOOKUP_TIME
|
||||
Pass a pointer to a double to receive the time, in seconds, it took from the
|
||||
start until the name resolving was completed.
|
||||
.IP CURLINFO_CONNECT_TIME
|
||||
Pass a pointer to a double to receive the time, in seconds, it took from the
|
||||
start until the connect to the remote host (or proxy) was completed.
|
||||
.IP CURLINFO_APPCONNECT_TIME
|
||||
Pass a pointer to a double to receive the time, in seconds, it took from the
|
||||
start until the SSL/SSH connect/handshake to the remote host was completed.
|
||||
This time is most often very near to the PRETRANSFER time, except for cases
|
||||
such as HTTP pippelining where the pretransfer time can be delayed due to
|
||||
waits in line for the pipeline and more. (Added in 7.19.0)
|
||||
.IP CURLINFO_PRETRANSFER_TIME
|
||||
Pass a pointer to a double to receive the time, in seconds, it took from the
|
||||
start until the file transfer is just about to begin. This includes all
|
||||
pre-transfer commands and negotiations that are specific to the particular
|
||||
protocol(s) involved.
|
||||
.IP CURLINFO_STARTTRANSFER_TIME
|
||||
Pass a pointer to a double to receive the time, in seconds, it took from the
|
||||
start until the first byte is just about to be transferred. This includes
|
||||
CURLINFO_PRETRANSFER_TIME and also the time the server needs to calculate
|
||||
the result.
|
||||
.IP CURLINFO_REDIRECT_TIME
|
||||
Pass a pointer to a double to receive the total time, in seconds, it took for
|
||||
all redirection steps include name lookup, connect, pretransfer and transfer
|
||||
before final transaction was started. CURLINFO_REDIRECT_TIME contains the
|
||||
complete execution time for multiple redirections. (Added in 7.9.7)
|
||||
.IP CURLINFO_REDIRECT_COUNT
|
||||
Pass a pointer to a long to receive the total number of redirections that were
|
||||
actually followed. (Added in 7.9.7)
|
||||
.IP CURLINFO_REDIRECT_URL
|
||||
Pass a pointer to a char pointer to receive the URL a redirect \fIwould\fP
|
||||
take you to if you would enable CURLOPT_FOLLOWLOCATION. This can come very
|
||||
handy if you think using the built-in libcurl redirect logic isn't good enough
|
||||
for you but you would still prefer to avoid implementing all the magic of
|
||||
figuring out the new URL. (Added in 7.18.2)
|
||||
.IP CURLINFO_SIZE_UPLOAD
|
||||
Pass a pointer to a double to receive the total amount of bytes that were
|
||||
uploaded.
|
||||
.IP CURLINFO_SIZE_DOWNLOAD
|
||||
Pass a pointer to a double to receive the total amount of bytes that were
|
||||
downloaded. The amount is only for the latest transfer and will be reset again
|
||||
for each new transfer.
|
||||
.IP CURLINFO_SPEED_DOWNLOAD
|
||||
Pass a pointer to a double to receive the average download speed that curl
|
||||
measured for the complete download. Measured in bytes/second.
|
||||
.IP CURLINFO_SPEED_UPLOAD
|
||||
Pass a pointer to a double to receive the average upload speed that curl
|
||||
measured for the complete upload. Measured in bytes/second.
|
||||
.IP CURLINFO_HEADER_SIZE
|
||||
Pass a pointer to a long to receive the total size of all the headers
|
||||
received. Measured in number of bytes.
|
||||
.IP CURLINFO_REQUEST_SIZE
|
||||
Pass a pointer to a long to receive the total size of the issued
|
||||
requests. This is so far only for HTTP requests. Note that this may be more
|
||||
than one request if FOLLOWLOCATION is true.
|
||||
.IP CURLINFO_SSL_VERIFYRESULT
|
||||
Pass a pointer to a long to receive the result of the certification
|
||||
verification that was requested (using the CURLOPT_SSL_VERIFYPEER option to
|
||||
\fIcurl_easy_setopt(3)\fP).
|
||||
.IP CURLINFO_SSL_ENGINES
|
||||
Pass the address of a 'struct curl_slist *' to receive a linked-list of
|
||||
OpenSSL crypto-engines supported. Note that engines are normally implemented
|
||||
in separate dynamic libraries. Hence not all the returned engines may be
|
||||
available at run-time. \fBNOTE:\fP you must call \fIcurl_slist_free_all(3)\fP
|
||||
on the list pointer once you're done with it, as libcurl will not free the
|
||||
data for you. (Added in 7.12.3)
|
||||
.IP CURLINFO_CONTENT_LENGTH_DOWNLOAD
|
||||
Pass a pointer to a double to receive the content-length of the download. This
|
||||
is the value read from the Content-Length: field. Since 7.19.4, this returns -1
|
||||
if the size isn't known.
|
||||
.IP CURLINFO_CONTENT_LENGTH_UPLOAD
|
||||
Pass a pointer to a double to receive the specified size of the upload. Since
|
||||
7.19.4, this returns -1 if the size isn't known.
|
||||
.IP CURLINFO_CONTENT_TYPE
|
||||
Pass a pointer to a char pointer to receive the content-type of the downloaded
|
||||
object. This is the value read from the Content-Type: field. If you get NULL,
|
||||
it means that the server didn't send a valid Content-Type header or that the
|
||||
protocol used doesn't support this.
|
||||
.IP CURLINFO_PRIVATE
|
||||
Pass a pointer to a char pointer to receive the pointer to the private data
|
||||
associated with the curl handle (set with the CURLOPT_PRIVATE option to
|
||||
\fIcurl_easy_setopt(3)\fP). Please note that for internal reasons, the
|
||||
value is returned as a char pointer, although effectively being a 'void *'.
|
||||
(Added in 7.10.3)
|
||||
.IP CURLINFO_HTTPAUTH_AVAIL
|
||||
Pass a pointer to a long to receive a bitmask indicating the authentication
|
||||
method(s) available. The meaning of the bits is explained in the
|
||||
CURLOPT_HTTPAUTH option for \fIcurl_easy_setopt(3)\fP. (Added in 7.10.8)
|
||||
.IP CURLINFO_PROXYAUTH_AVAIL
|
||||
Pass a pointer to a long to receive a bitmask indicating the authentication
|
||||
method(s) available for your proxy authentication. (Added in 7.10.8)
|
||||
.IP CURLINFO_OS_ERRNO
|
||||
Pass a pointer to a long to receive the errno variable from a connect failure.
|
||||
Note that the value is only set on failure, it is not reset upon a
|
||||
successfull operation. (Added in 7.12.2)
|
||||
.IP CURLINFO_NUM_CONNECTS
|
||||
Pass a pointer to a long to receive how many new connections libcurl had to
|
||||
create to achieve the previous transfer (only the successful connects are
|
||||
counted). Combined with \fICURLINFO_REDIRECT_COUNT\fP you are able to know
|
||||
how many times libcurl successfully reused existing connection(s) or not. See
|
||||
the Connection Options of \fIcurl_easy_setopt(3)\fP to see how libcurl tries
|
||||
to make persistent connections to save time. (Added in 7.12.3)
|
||||
.IP CURLINFO_PRIMARY_IP
|
||||
Pass a pointer to a char pointer to receive the pointer to a zero-terminated
|
||||
string holding the IP address of the most recent connection done with this
|
||||
\fBcurl\fP handle. This string may be IPv6 if that's enabled. Note that you
|
||||
get a pointer to a memory area that will be re-used at next request so you
|
||||
need to copy the string if you want to keep the information. (Added in 7.19.0)
|
||||
.IP CURLINFO_PRIMARY_PORT
|
||||
Pass a pointer to a long to receive the destination port of the most recent
|
||||
connection done with this \fBcurl\fP handle. (Added in 7.21.0)
|
||||
.IP CURLINFO_LOCAL_IP
|
||||
Pass a pointer to a char pointer to receive the pointer to a zero-terminated
|
||||
string holding the local (source) IP address of the most recent connection done
|
||||
with this \fBcurl\fP handle. This string may be IPv6 if that's enabled. The
|
||||
same restrictions apply as to \fICURLINFO_PRIMARY_IP\fP. (Added in 7.21.0)
|
||||
.IP CURLINFO_LOCAL_PORT
|
||||
Pass a pointer to a long to receive the local (source) port of the most recent
|
||||
connection done with this \fBcurl\fP handle. (Added in 7.21.0)
|
||||
.IP CURLINFO_COOKIELIST
|
||||
Pass a pointer to a 'struct curl_slist *' to receive a linked-list of all
|
||||
cookies cURL knows (expired ones, too). Don't forget to
|
||||
\fIcurl_slist_free_all(3)\fP the list after it has been used. If there are no
|
||||
cookies (cookies for the handle have not been enabled or simply none have been
|
||||
received) 'struct curl_slist *' will be set to point to NULL. (Added in
|
||||
7.14.1)
|
||||
.IP CURLINFO_LASTSOCKET
|
||||
Pass a pointer to a long to receive the last socket used by this curl
|
||||
session. If the socket is no longer valid, -1 is returned. When you finish
|
||||
working with the socket, you must call curl_easy_cleanup() as usual and let
|
||||
libcurl close the socket and cleanup other resources associated with the
|
||||
handle. This is typically used in combination with \fICURLOPT_CONNECT_ONLY\fP.
|
||||
(Added in 7.15.2)
|
||||
|
||||
NOTE: this API is not really working on win64, since the SOCKET type on win64
|
||||
is 64 bit large while its 'long' is only 32 bits.
|
||||
.IP CURLINFO_FTP_ENTRY_PATH
|
||||
Pass a pointer to a char pointer to receive a pointer to a string holding the
|
||||
path of the entry path. That is the initial path libcurl ended up in when
|
||||
logging on to the remote FTP server. This stores a NULL as pointer if
|
||||
something is wrong. (Added in 7.15.4)
|
||||
|
||||
Also works for SFTP since 7.21.4
|
||||
.IP CURLINFO_CERTINFO
|
||||
Pass a pointer to a 'struct curl_certinfo *' and you'll get it set to point to
|
||||
struct that holds a number of linked lists with info about the certificate
|
||||
chain, assuming you had CURLOPT_CERTINFO enabled when the previous request was
|
||||
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
|
||||
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
|
||||
option is only available in libcurl built with OpenSSL support. (Added in
|
||||
7.19.1)
|
||||
.IP CURLINFO_CONDITION_UNMET
|
||||
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
|
||||
this returns a 1 you know that the reason you didn't get data in return is
|
||||
because it didn't fulfill the condition. The long ths argument points to will
|
||||
get a zero stored if the condition instead was met. (Added in 7.19.4)
|
||||
.IP CURLINFO_RTSP_SESSION_ID
|
||||
Pass a pointer to a char pointer to receive a pointer to a string holding the
|
||||
most recent RTSP Session ID.
|
||||
|
||||
Applications wishing to resume an RTSP session on another connection should
|
||||
retreive this info before closing the active connection.
|
||||
.IP CURLINFO_RTSP_CLIENT_CSEQ
|
||||
Pass a pointer to a long to receive the next CSeq that will be used by the
|
||||
application.
|
||||
.IP CURLINFO_RTSP_SERVER_CSEQ
|
||||
Pass a pointer to a long to receive the next server CSeq that will be expected
|
||||
by the application.
|
||||
|
||||
\fI(NOTE: listening for server initiated requests is currently
|
||||
unimplemented).\fP
|
||||
|
||||
Applications wishing to resume an RTSP session on another connection should
|
||||
retreive this info before closing the active connection.
|
||||
.IP CURLINFO_RTSP_CSEQ_RECV
|
||||
Pass a pointer to a long to receive the most recently received CSeq from the
|
||||
server. If your application encounters a \fICURLE_RTSP_CSEQ_ERROR\fP then you
|
||||
may wish to troubleshoot and/or fix the CSeq mismatch by peeking at this value.
|
||||
.SH TIMES
|
||||
.nf
|
||||
An overview of the six time values available from curl_easy_getinfo()
|
||||
|
||||
curl_easy_perform()
|
||||
|
|
||||
|--NAMELOOKUP
|
||||
|--|--CONNECT
|
||||
|--|--|--APPCONNECT
|
||||
|--|--|--|--PRETRANSFER
|
||||
|--|--|--|--|--STARTTRANSFER
|
||||
|--|--|--|--|--|--TOTAL
|
||||
|--|--|--|--|--|--REDIRECT
|
||||
.fi
|
||||
.IP NAMELOOKUP
|
||||
\fICURLINFO_NAMELOOKUP_TIME\fP. The time it took from the start until the name
|
||||
resolving was completed.
|
||||
.IP CONNECT
|
||||
\fICURLINFO_CONNECT_TIME\fP. The time it took from the start until the connect
|
||||
to the remote host (or proxy) was completed.
|
||||
.IP APPCONNECT
|
||||
\fICURLINFO_APPCONNECT_TIME\fP. The time it took from the start until the SSL
|
||||
connect/handshake with the remote host was completed. (Added in in 7.19.0)
|
||||
.IP PRETRANSFER
|
||||
\fICURLINFO_PRETRANSFER_TIME\fP. The time it took from the start until the
|
||||
file transfer is just about to begin. This includes all pre-transfer commands
|
||||
and negotiations that are specific to the particular protocol(s) involved.
|
||||
.IP STARTTRANSFER
|
||||
\fICURLINFO_STARTTRANSFER_TIME\fP. The time it took from the start until the
|
||||
first byte is just about to be transferred.
|
||||
.IP TOTAL
|
||||
\fICURLINFO_TOTAL_TIME\fP. Total time of the previous request.
|
||||
.IP REDIRECT
|
||||
\fICURLINFO_REDIRECT_TIME\fP. The time it took for all redirection steps
|
||||
include name lookup, connect, pretransfer and transfer before final
|
||||
transaction was started. So, this is zero if no redirection took place.
|
||||
.SH RETURN VALUE
|
||||
If the operation was successful, CURLE_OK is returned. Otherwise an
|
||||
appropriate error code will be returned.
|
||||
.SH "SEE ALSO"
|
||||
.BR curl_easy_setopt "(3)"
|
||||
31
third-party/curl-7.21.4/docs/libcurl/curl_easy_init.3
vendored
Normal file
31
third-party/curl-7.21.4/docs/libcurl/curl_easy_init.3
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
.\"
|
||||
.TH curl_easy_init 3 "4 March 2002" "libcurl 7.8.1" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_easy_init - Start a libcurl easy session
|
||||
.SH SYNOPSIS
|
||||
.B #include <curl/curl.h>
|
||||
|
||||
.BI "CURL *curl_easy_init( );"
|
||||
|
||||
.SH DESCRIPTION
|
||||
This function must be the first function to call, and it returns a CURL easy
|
||||
handle that you must use as input to other easy-functions. curl_easy_init
|
||||
initializes curl and this call \fBMUST\fP have a corresponding call to
|
||||
\fIcurl_easy_cleanup(3)\fP when the operation is complete.
|
||||
|
||||
If you did not already call \fIcurl_global_init(3)\fP,
|
||||
\fIcurl_easy_init(3)\fP does it automatically.
|
||||
This may be lethal in multi-threaded cases, since \fIcurl_global_init(3)\fP is
|
||||
not thread-safe, and it may result in resource problems because there is
|
||||
no corresponding cleanup.
|
||||
|
||||
You are strongly advised to not allow this automatic behaviour, by
|
||||
calling \fIcurl_global_init(3)\fP yourself properly.
|
||||
See the description in \fBlibcurl\fP(3) of global environment
|
||||
requirements for details of how to use this function.
|
||||
|
||||
.SH RETURN VALUE
|
||||
If this function returns NULL, something went wrong and you cannot use the
|
||||
other curl functions.
|
||||
.SH "SEE ALSO"
|
||||
.BR curl_easy_cleanup "(3), " curl_global_init "(3), " curl_easy_reset "(3)"
|
||||
65
third-party/curl-7.21.4/docs/libcurl/curl_easy_pause.3
vendored
Normal file
65
third-party/curl-7.21.4/docs/libcurl/curl_easy_pause.3
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
.\"
|
||||
.TH curl_easy_pause 3 "17 Dec 2007" "libcurl 7.18.0" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_easy_pause - pause and unpause a connection
|
||||
.SH SYNOPSIS
|
||||
.B #include <curl/curl.h>
|
||||
|
||||
.BI "CURLcode curl_easy_pause(CURL *"handle ", int "bitmask " );"
|
||||
|
||||
.SH DESCRIPTION
|
||||
Using this function, you can explicitly mark a running connection to get
|
||||
paused, and you can unpause a connection that was previously paused.
|
||||
|
||||
A connection can be paused by using this function or by letting the read
|
||||
or the write callbacks return the proper magic return code
|
||||
(\fICURL_READFUNC_PAUSE\fP and \fICURL_WRITEFUNC_PAUSE\fP). A write callback
|
||||
that returns pause signals to the library that it couldn't take care of any
|
||||
data at all, and that data will then be delivered again to the callback when
|
||||
the writing is later unpaused.
|
||||
|
||||
NOTE: while it may feel tempting, take care and notice that you cannot call
|
||||
this function from another thread.
|
||||
|
||||
When this function is called to unpause reading, the chance is high that you
|
||||
will get your write callback called before this function returns.
|
||||
|
||||
The \fBhandle\fP argument is of course identifying the handle that operates on
|
||||
the connection you want to pause or unpause.
|
||||
|
||||
The \fBbitmask\fP argument is a set of bits that sets the new state of the
|
||||
connection. The following bits can be used:
|
||||
.IP CURLPAUSE_RECV
|
||||
Pause receiving data. There will be no data received on this connection until
|
||||
this function is called again without this bit set. Thus, the write callback
|
||||
(\fICURLOPT_WRITEFUNCTION\fP) won't be called.
|
||||
.IP CURLPAUSE_SEND
|
||||
Pause sending data. There will be no data sent on this connection until this
|
||||
function is called again without this bit set. Thus, the read callback
|
||||
(\fICURLOPT_READFUNCTION\fP) won't be called.
|
||||
.IP CURLPAUSE_ALL
|
||||
Convenience define that pauses both directions.
|
||||
.IP CURLPAUSE_CONT
|
||||
Convenience define that unpauses both directions
|
||||
.SH RETURN VALUE
|
||||
CURLE_OK (zero) means that the option was set properly, and a non-zero return
|
||||
code means something wrong occurred after the new state was set. See the
|
||||
\fIlibcurl-errors(3)\fP man page for the full list with descriptions.
|
||||
.SH AVAILABILITY
|
||||
This function was added in libcurl 7.18.0. Before this version, there was no
|
||||
explicit support for pausing transfers.
|
||||
.SH "MEMORY USE"
|
||||
When pausing a read by returning the magic return code from a write callback,
|
||||
the read data is already in libcurl's internal buffers so it'll have to keep
|
||||
it in an allocated buffer until the reading is again unpaused using this
|
||||
function.
|
||||
|
||||
If the downloaded data is compressed and is asked to get uncompressed
|
||||
automatically on download, libcurl will continue to uncompress the entire
|
||||
downloaded chunk and it will cache the data uncompressed. This has the side-
|
||||
effect that if you download something that is compressed a lot, it can result
|
||||
in a very large data amount needing to be allocated to save the data during
|
||||
the pause. This said, you should probably consider not using paused reading if
|
||||
you allow libcurl to uncompress data automatically.
|
||||
.SH "SEE ALSO"
|
||||
.BR curl_easy_cleanup "(3), " curl_easy_reset "(3)"
|
||||
39
third-party/curl-7.21.4/docs/libcurl/curl_easy_perform.3
vendored
Normal file
39
third-party/curl-7.21.4/docs/libcurl/curl_easy_perform.3
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
.\" You can view this file with:
|
||||
.\" nroff -man [file]
|
||||
.\"
|
||||
.TH curl_easy_perform 3 "5 Mar 2001" "libcurl 7.7" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_easy_perform - Perform a file transfer
|
||||
.SH SYNOPSIS
|
||||
.B #include <curl/curl.h>
|
||||
.sp
|
||||
.BI "CURLcode curl_easy_perform(CURL *" handle ");"
|
||||
.ad
|
||||
.SH DESCRIPTION
|
||||
This function is called after the init and all the \fIcurl_easy_setopt(3)\fP
|
||||
calls are made, and will perform the transfer as described in the options. It
|
||||
must be called with the same
|
||||
.I handle
|
||||
as input as the curl_easy_init call returned.
|
||||
|
||||
You can do any amount of calls to \fIcurl_easy_perform(3)\fP while using the
|
||||
same handle. If you intend to transfer more than one file, you are even
|
||||
encouraged to do so. libcurl will then attempt to re-use the same connection
|
||||
for the following transfers, thus making the operations faster, less CPU
|
||||
intense and using less network resources. Just note that you will have to use
|
||||
\fIcurl_easy_setopt(3)\fP between the invokes to set options for the following
|
||||
curl_easy_perform.
|
||||
|
||||
You must never call this function simultaneously from two places using the
|
||||
same handle. Let the function return first before invoking it another time. If
|
||||
you want parallel transfers, you must use several curl handles.
|
||||
.SH RETURN VALUE
|
||||
0 means everything was ok, non-zero means an error occurred as
|
||||
.I <curl/curl.h>
|
||||
defines. If the CURLOPT_ERRORBUFFER was set with
|
||||
.I curl_easy_setopt
|
||||
there will be a readable error message in the error buffer when non-zero is
|
||||
returned.
|
||||
.SH "SEE ALSO"
|
||||
.BR curl_easy_init "(3), " curl_easy_setopt "(3), "
|
||||
|
||||
69
third-party/curl-7.21.4/docs/libcurl/curl_easy_recv.3
vendored
Normal file
69
third-party/curl-7.21.4/docs/libcurl/curl_easy_recv.3
vendored
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
.\" **************************************************************************
|
||||
.\" * _ _ ____ _
|
||||
.\" * Project ___| | | | _ \| |
|
||||
.\" * / __| | | | |_) | |
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * Copyright (C) 1998 - 2008, 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.
|
||||
.\" *
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH curl_easy_recv 3 "29 April 2008" "libcurl 7.18.2" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_easy_recv - receives raw data on an "easy" connection
|
||||
.SH SYNOPSIS
|
||||
.B #include <curl/easy.h>
|
||||
.sp
|
||||
.BI "CURLcode curl_easy_recv( CURL *" curl ", void *" buffer ","
|
||||
.BI "size_t " buflen ", size_t *" n ");"
|
||||
.ad
|
||||
.SH DESCRIPTION
|
||||
This function receives raw data from the established connection. You may use
|
||||
it together with \fIcurl_easy_send(3)\fP to implement custom protocols using
|
||||
libcurl. This functionality can be particularly useful if you use proxies
|
||||
and/or SSL encryption: libcurl will take care of proxy negotiation and
|
||||
connection set-up.
|
||||
|
||||
\fBbuffer\fP is a pointer to your buffer that will get the received
|
||||
data. \fBbuflen\fP is the maximum amount of data you can get in that
|
||||
buffer. The variable \fBn\fP points to will receive the number of received
|
||||
bytes.
|
||||
|
||||
To establish the connection, set \fBCURLOPT_CONNECT_ONLY\fP option before
|
||||
calling \fIcurl_easy_perform(3)\fP. Note that \fIcurl_easy_recv(3)\fP does not
|
||||
work on connections that were created without this option.
|
||||
|
||||
You must ensure that the socket has data to read before calling
|
||||
\fIcurl_easy_recv(3)\fP, otherwise the call will return \fBCURLE_AGAIN\fP -
|
||||
the socket is used in non-blocking mode internally. Use
|
||||
\fIcurl_easy_getinfo(3)\fP with \fBCURLINFO_LASTSOCKET\fP to obtain the
|
||||
socket; use your operating system facilities like \fIselect(2)\fP to check if
|
||||
it has any data you can read.
|
||||
.SH AVAILABILITY
|
||||
Added in 7.18.2.
|
||||
.SH RETURN VALUE
|
||||
On success, returns \fBCURLE_OK\fP, stores the received data into
|
||||
\fBbuffer\fP, and the number of bytes it actually read into \fB*n\fP.
|
||||
|
||||
On failure, returns the appropriate error code.
|
||||
|
||||
If there is no data to read, the function returns \fBCURLE_AGAIN\fP. Use
|
||||
your operating system facilities to wait until the data is ready, and retry.
|
||||
.SH EXAMPLE
|
||||
See \fBsendrecv.c\fP in \fBdocs/examples\fP directory for usage example.
|
||||
.SH "SEE ALSO"
|
||||
.BR curl_easy_setopt "(3), " curl_easy_perform "(3), "
|
||||
.BR curl_easy_getinfo "(3), "
|
||||
.BR curl_easy_send "(3) "
|
||||
23
third-party/curl-7.21.4/docs/libcurl/curl_easy_reset.3
vendored
Normal file
23
third-party/curl-7.21.4/docs/libcurl/curl_easy_reset.3
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
.\"
|
||||
.TH curl_easy_reset 3 "31 July 2004" "libcurl 7.12.1" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_easy_reset - reset all options of a libcurl session handle
|
||||
.SH SYNOPSIS
|
||||
.B #include <curl/curl.h>
|
||||
|
||||
.BI "void curl_easy_reset(CURL *"handle ");"
|
||||
|
||||
.SH DESCRIPTION
|
||||
Re-initializes all options previously set on a specified CURL handle to the
|
||||
default values. This puts back the handle to the same state as it was in when
|
||||
it was just created with \fIcurl_easy_init(3)\fP.
|
||||
|
||||
It does not change the following information kept in the handle: live
|
||||
connections, the Session ID cache, the DNS cache, the cookies and shares.
|
||||
.SH AVAILABILITY
|
||||
This function was added in libcurl 7.12.1
|
||||
.SH RETURN VALUE
|
||||
Nothing
|
||||
.SH "SEE ALSO"
|
||||
.BR curl_easy_init "(3)," curl_easy_cleanup "(3)," curl_easy_setopt "(3)
|
||||
|
||||
64
third-party/curl-7.21.4/docs/libcurl/curl_easy_send.3
vendored
Normal file
64
third-party/curl-7.21.4/docs/libcurl/curl_easy_send.3
vendored
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
.\" **************************************************************************
|
||||
.\" * _ _ ____ _
|
||||
.\" * Project ___| | | | _ \| |
|
||||
.\" * / __| | | | |_) | |
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * Copyright (C) 1998 - 2010, 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.
|
||||
.\" *
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH curl_easy_send 3 "29 April 2008" "libcurl 7.18.2" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_easy_send - sends raw data over an "easy" connection
|
||||
.SH SYNOPSIS
|
||||
.B #include <curl/easy.h>
|
||||
.sp
|
||||
.BI "CURLcode curl_easy_send( CURL *" curl ", const void *" buffer ","
|
||||
.BI " size_t " buflen ", size_t *" n ");"
|
||||
.ad
|
||||
.SH DESCRIPTION
|
||||
This function sends arbitrary data over the established connection. You may
|
||||
use it together with \fIcurl_easy_recv(3)\fP to implement custom protocols
|
||||
using libcurl. This functionality can be particularly useful if you use
|
||||
proxies and/or SSL encryption: libcurl will take care of proxy negotiation and
|
||||
connection set-up.
|
||||
|
||||
\fBbuffer\fP is a pointer to the data of length \fBbuflen\fP that you want sent.
|
||||
The variable \fBn\fP points to will receive the number of sent bytes.
|
||||
|
||||
To establish the connection, set \fBCURLOPT_CONNECT_ONLY\fP option before
|
||||
calling \fIcurl_easy_perform(3)\fP. Note that \fIcurl_easy_send(3)\fP will not
|
||||
work on connections that were created without this option.
|
||||
|
||||
You must ensure that the socket is writable before calling
|
||||
\fIcurl_easy_send(3)\fP, otherwise the call will return \fBCURLE_AGAIN\fP -
|
||||
the socket is used in non-blocking mode internally. Use
|
||||
\fIcurl_easy_getinfo(3)\fP with \fBCURLINFO_LASTSOCKET\fP to obtain the
|
||||
socket; use your operating system facilities like \fIselect(2)\fP to check if
|
||||
it can be written to.
|
||||
.SH AVAILABILITY
|
||||
Added in 7.18.2.
|
||||
.SH RETURN VALUE
|
||||
On success, returns \fBCURLE_OK\fP and stores the number of bytes actually
|
||||
sent into \fB*n\fP. Note that this may very well be less than the amount you
|
||||
wanted to send.
|
||||
|
||||
On failure, returns the appropriate error code.
|
||||
.SH EXAMPLE
|
||||
See \fBsendrecv.c\fP in \fBdocs/examples\fP directory for usage example.
|
||||
.SH "SEE ALSO"
|
||||
.BR curl_easy_setopt "(3), " curl_easy_perform "(3), " curl_easy_getinfo "(3), "
|
||||
.BR curl_easy_recv "(3) "
|
||||
2163
third-party/curl-7.21.4/docs/libcurl/curl_easy_setopt.3
vendored
Normal file
2163
third-party/curl-7.21.4/docs/libcurl/curl_easy_setopt.3
vendored
Normal file
File diff suppressed because it is too large
Load diff
19
third-party/curl-7.21.4/docs/libcurl/curl_easy_strerror.3
vendored
Normal file
19
third-party/curl-7.21.4/docs/libcurl/curl_easy_strerror.3
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
.\" You can view this file with:
|
||||
.\" nroff -man [file]
|
||||
.\"
|
||||
.TH curl_easy_strerror 3 "26 Apr 2004" "libcurl 7.12" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_easy_strerror - return string describing error code
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.B #include <curl/curl.h>
|
||||
.BI "const char *curl_easy_strerror(CURLcode " errornum ");"
|
||||
.SH DESCRIPTION
|
||||
The curl_easy_strerror() function returns a string describing the CURLcode
|
||||
error code passed in the argument \fIerrornum\fP.
|
||||
.SH AVAILABILITY
|
||||
This function was added in libcurl 7.12.0
|
||||
.SH RETURN VALUE
|
||||
A pointer to a zero terminated string.
|
||||
.SH "SEE ALSO"
|
||||
.BR libcurl-errors "(3), " curl_multi_strerror "(3), " curl_share_strerror "(3)"
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue