diff options
Diffstat (limited to 'docs')
167 files changed, 31514 insertions, 0 deletions
diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 000000000..23f832b73 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,2 @@ +*.html +*.pdf diff --git a/docs/BINDINGS b/docs/BINDINGS new file mode 100644 index 000000000..5cf07fecd --- /dev/null +++ b/docs/BINDINGS @@ -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 diff --git a/docs/BUGS b/docs/BUGS new file mode 100644 index 000000000..697b4e5c7 --- /dev/null +++ b/docs/BUGS @@ -0,0 +1,148 @@ + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + +BUGS + + 1. Bugs + 1.1 There are still bugs + 1.2 Where to report + 1.3 What to report + 1.4 libcurl problems + 1.5 Who will fix the problems + 1.6 How to get a stack trace + 1.7 Bugs in libcurl bindings + +============================================================================== + +1.1 There are still bugs + + Curl and libcurl have grown substantially since the beginning. At the time + of writing (September 2011), there are about 66000 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. + +1.2 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 can optionally also post your bug/problem at + curl's bug tracking system over at + + http://sourceforge.net/tracker/?group_id=976&atid=100976 + + Please read the rest of this document below first before doing that! Also, + you need to login to your sourceforge account before being able to submit a + bug report (necessary evil done to avoid spam). + + 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/ + +1.3 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 + + - 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. + +1.4 libcurl problems + + First, post all libcurl problems on the curl-library mailing list. + + When you've written your own application with libcurl to perform transfers, + it is even more important to be specific and detailed when reporting bugs. + + Tell us the libcurl version and your operating system. Tell us the name and + version of all relevant sub-components like for example the SSL library + you're using and what name resolving your libcurl uses. If you use SFTP or + SCP, the libssh2 version is relevant etc. + + Showing us a real source code example repeating your problem is the best way + to get our attention and it will greatly increase our chances to understand + your problem and to work on a fix (if we agree it truly is a problem). + + Lots of problems that appear to be libcurl problems are actually just abuses + of the libcurl API or other malfunctions in your applications. It is advised + that you run your problematic program using a memory debug tool like + valgrind or similar before you post memory-related or "crashing" problems to + us. + +1.5 Who will fix the problems + + If the problems or bugs you describe are considered to be bugs, we want to + have the problems fixed. + + There are no developers in the curl project that are paid to work on bugs. + All developers that take on reported bugs do this on a voluntary basis. We + do it out of an ambition to keep curl and libcurl excellent products and out + of pride. + + But please do not assume that you can just lump over something to us and it + will then magically be fixed after some given time. Most often we need + feedback and help to understand what you've experienced and how to repeat a + problem. Then we may only be able to assist YOU to debug the problem and to + track down the proper fix. + + We get reports from many people every month and each report can take a + considerable amount of time to really go to the bottom with. + +1.6 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. + +1.7 Bugs in libcurl bindings + + There will of course pop up bugs in libcurl bindings. You should then + primarily approach the team that works on that particular binding and see + what you can do to help them fix the problem. + + If you suspect that the problem exists in the underlying libcurl, then + please convert your program over to plain C and follow the steps outlined + above. diff --git a/docs/CONTRIBUTE b/docs/CONTRIBUTE new file mode 100644 index 000000000..33a1f21e8 --- /dev/null +++ b/docs/CONTRIBUTE @@ -0,0 +1,303 @@ + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + + 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 + 3.6 Please don't send pull requests + +============================================================================== + +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 + + Submit your patch to the curl-library mailing list. + + Make the patch against as recent sources as possible. + + 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. + + 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. + + If you've followed the above 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 + +3.6 Please don't send pull requests + + With git (and especially github) it is easy and tempting to send a pull + request to one or more people in the curl project to have changes merged this + way instead of mailing patches to the curl-library mailing list. + + We don't like that. We want them mailed for these reasons: + + - Peer review. Anyone and everyone on the list can review, comment and + improve on the patch. Pull requests limit this ability. + + - Anyone can merge the patch into their own trees for testing and those who + have push rights can push it to the main repo. It doesn't have to be anyone + the patch author knows beforehand. + + - Commit messages can be tweaked and changed if merged locally instead of + using github. Merges directly on github requires the changes to be perfect + already, which they seldom are. + + - Merges on github prevents rebases and even enforces --no-ff which is a git + style we don't otherwise use in the project + + However: once patches have been reviewed and deemed fine on list they are + perfectly OK to be pulled from a published git tree. diff --git a/docs/DISTRO-DILEMMA b/docs/DISTRO-DILEMMA new file mode 100644 index 000000000..108e6bad1 --- /dev/null +++ b/docs/DISTRO-DILEMMA @@ -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 diff --git a/docs/FAQ b/docs/FAQ new file mode 100644 index 000000000..130111108 --- /dev/null +++ b/docs/FAQ @@ -0,0 +1,1422 @@ + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + +FAQ + + 1. Philosophy + 1.1 What is cURL? + 1.2 What is libcurl? + 1.3 What is curl not? + 1.4 When will you make curl do XXXX ? + 1.5 Who makes curl? + 1.6 What do you get for making curl? + 1.7 What about CURL from curl.com? + 1.8 I have a problem who do I mail? + 1.9 Where do I buy commercial support for curl? + 1.10 How many are using curl? + 1.11 Why don't you update ca-bundle.crt + 1.12 I have a problem who can I chat with? + 1.13 curl's ECCN number? + 1.14 How do I submit my patch? + + 2. Install Related Problems + 2.1 configure doesn't find OpenSSL even when it is installed + 2.1.1 native linker doesn't find OpenSSL + 2.1.2 only the libssl lib is missing + 2.2 Does curl work/build with other SSL libraries? + 2.3 Where can I find a copy of LIBEAY32.DLL? + 2.4 Does curl support SOCKS (RFC 1928) ? + + 3. Usage Problems + 3.1 curl: (1) SSL is disabled, https: not supported + 3.2 How do I tell curl to resume a transfer? + 3.3 Why doesn't my posting using -F work? + 3.4 How do I tell curl to run custom FTP commands? + 3.5 How can I disable the Accept: */* header? + 3.6 Does curl support ASP, XML, XHTML or HTML version Y? + 3.7 Can I use curl to delete/rename a file through FTP? + 3.8 How do I tell curl to follow HTTP redirects? + 3.9 How do I use curl in my favorite programming language? + 3.10 What about SOAP, WebDAV, XML-RPC or similar protocols over HTTP? + 3.11 How do I POST with a different Content-Type? + 3.12 Why do FTP specific features over HTTP proxy fail? + 3.13 Why does my single/double quotes fail? + 3.14 Does curl support Javascript or PAC (automated proxy config)? + 3.15 Can I do recursive fetches with curl? + 3.16 What certificates do I need when I use SSL? + 3.17 How do I list the root dir of an FTP server? + 3.18 Can I use curl to send a POST/PUT and not wait for a response? + 3.19 How do I get HTTP from a host using a specific IP address? + 3.20 How to SFTP from my user's home directory? + 3.21 Protocol xxx not supported or disabled in libcurl + + 4. Running Problems + 4.1 Problems connecting to SSL servers. + 4.2 Why do I get problems when I use & or % in the URL? + 4.3 How can I use {, }, [ or ] to specify multiple URLs? + 4.4 Why do I get downloaded data even though the web page doesn't exist? + 4.5 Why do I get return code XXX from a HTTP server? + 4.5.1 "400 Bad Request" + 4.5.2 "401 Unauthorized" + 4.5.3 "403 Forbidden" + 4.5.4 "404 Not Found" + 4.5.5 "405 Method Not Allowed" + 4.5.6 "301 Moved Permanently" + 4.6 Can you tell me what error code 142 means? + 4.7 How do I keep user names and passwords secret in Curl command lines? + 4.8 I found a bug! + 4.9 Curl can't authenticate to the server that requires NTLM? + 4.10 My HTTP request using HEAD, PUT or DELETE doesn't work! + 4.11 Why does my HTTP range requests return the full document? + 4.12 Why do I get "certificate verify failed" ? + 4.13 Why is curl -R on Windows one hour off? + 4.14 Redirects work in browser but not with curl! + 4.15 FTPS doesn't work + 4.16 My HTTP POST or PUT requests are slow! + 4.17 Non-functional connect timeouts on Windows + 4.18 file:// URLs containing drive letters (Windows, NetWare) + 4.19 Why doesn't cURL return an error when the network cable is unplugged? + + 5. libcurl Issues + 5.1 Is libcurl thread-safe? + 5.2 How can I receive all data into a large memory chunk? + 5.3 How do I fetch multiple files with libcurl? + 5.4 Does libcurl do Winsock initing on win32 systems? + 5.5 Does CURLOPT_WRITEDATA and CURLOPT_READDATA work on win32 ? + 5.6 What about Keep-Alive or persistent connections? + 5.7 Link errors when building libcurl on Windows! + 5.8 libcurl.so.X: open failed: No such file or directory + 5.9 How does libcurl resolve host names? + 5.10 How do I prevent libcurl from writing the response to stdout? + 5.11 How do I make libcurl not receive the whole HTTP response? + 5.12 Can I make libcurl fake or hide my real IP address? + 5.13 How do I stop an ongoing transfer? + 5.14 Using C++ non-static functions for callbacks? + 5.15 How do I get an FTP directory listing? + 5.16 I want a different time-out! + + 6. License Issues + 6.1 I have a GPL program, can I use the libcurl library? + 6.2 I have a closed-source program, can I use the libcurl library? + 6.3 I have a BSD licensed program, can I use the libcurl library? + 6.4 I have a program that uses LGPL libraries, can I use libcurl? + 6.5 Can I modify curl/libcurl for my program and keep the changes secret? + 6.6 Can you please change the curl/libcurl license to XXXX? + 6.7 What are my obligations when using libcurl in my commercial apps? + + 7. PHP/CURL Issues + 7.1 What is PHP/CURL? + 7.2 Who wrote PHP/CURL? + 7.3 Can I perform multiple requests using the same handle? + +============================================================================== + +1. Philosophy + + 1.1 What is cURL? + + cURL is the name of the project. The name is a play on 'Client for URLs', + originally with URL spelled in uppercase to make it obvious it deals with + URLs. The fact it can also be pronounced 'see URL' also helped, it works as + an abbreviation for "Client URL Request Library" or why not the recursive + version: "Curl URL Request Library". + + The cURL project produces two products: + + libcurl + + A free and easy-to-use client-side URL transfer library, supporting DICT, + FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, + POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET and TFTP. + + libcurl supports HTTPS certificates, HTTP POST, HTTP PUT, FTP uploading, + kerberos, HTTP form based upload, proxies, cookies, user+password + authentication, file transfer resume, http proxy tunneling and more! + + libcurl is highly portable, it builds and works identically on numerous + platforms, including Solaris, NetBSD, FreeBSD, OpenBSD, Darwin, HPUX, + IRIX, AIX, Tru64, Linux, UnixWare, HURD, Windows, Amiga, OS/2, BeOS, Mac + OS X, Ultrix, QNX, OpenVMS, RISC OS, Novell NetWare, DOS, Symbian, OSF, + Android, Minix, IBM TPF and more... + + libcurl is free, thread-safe, IPv6 compatible, feature rich, well + supported and fast. + + curl + + A command line tool for getting or sending files using URL syntax. + + Since curl uses libcurl, curl supports the same wide range of common + Internet protocols that libcurl does. + + We pronounce curl and cURL with an initial k sound: [kurl]. + + There are numerous sub-projects and related projects that also use the word + curl in the project names in various combinations, but you should take + notice that this FAQ is directed at the command-line tool named curl (and + libcurl the library), and may therefore not be valid for other curl-related + projects. (There is however a small section for the PHP/CURL in this FAQ.) + + 1.2 What is libcurl? + + libcurl is a reliable and portable library which provides you with an easy + interface to a range of common Internet protocols. + + You can use libcurl for free in your application, be it open source, + commercial or closed-source. + + libcurl is most probably the most portable, most powerful and most often + used C-based multi-platform file transfer library on this planet - be it + open source or commercial. + + 1.3 What is curl not? + + Curl is not a wget clone. That is a common misconception. Never, during + curl's development, have we intended curl to replace wget or compete on its + market. Curl is targeted at single-shot file transfers. + + Curl is not a web site mirroring program. If you want to use curl to mirror + something: fine, go ahead and write a script that wraps around curl to make + it reality (like curlmirror.pl does). + + Curl is not an FTP site mirroring program. Sure, get and send FTP with curl + but if you want systematic and sequential behavior you should write a + script (or write a new program that interfaces libcurl) and do it. + + Curl is not a PHP tool, even though it works perfectly well when used from + or with PHP (when using the PHP/CURL module). + + Curl is not a program for a single operating system. Curl exists, compiles, + builds and runs under a wide range of operating systems, including all + modern Unixes (and a bunch of older ones too), Windows, Amiga, BeOS, OS/2, + OS X, QNX etc. + + 1.4 When will you make curl do XXXX ? + + We love suggestions of what to change in order to make curl and libcurl + better. We do however believe in a few rules when it comes to the future of + curl: + + * Curl -- the command line tool -- is to remain a non-graphical command line + tool. If you want GUIs or fancy scripting capabilities, you should look + for another tool that uses libcurl. + + * We do not add things to curl that other small and available tools already + do very fine at the side. Curl's output is fine to pipe into another + program or redirect to another file for the next program to interpret. + + * We focus on protocol related issues and improvements. If you wanna do more + magic with the supported protocols than curl currently does, chances are + big we will agree. If you wanna add more protocols, we may very well + agree. + + * If you want someone else to make all the work while you wait for us to + implement it for you, that is not a very friendly attitude. We spend a + considerable time already on maintaining and developing curl. In order to + get more out of us, you should consider trading in some of your time and + efforts in return. + + * If you write the code, chances are bigger that it will get into curl + faster. + + 1.5 Who makes curl? + + curl and libcurl are not made by any single individual. Daniel Stenberg is + project leader and main developer, but other persons' submissions are + important and crucial. Anyone can contribute and post their changes and + improvements and have them inserted in the main sources (of course on the + condition that developers agree on that the fixes are good). + + The full list of all contributors is found in the docs/THANKS file. + + curl is developed by a community, with Daniel at the wheel. + + 1.6 What do you get for making curl? + + Project cURL is entirely free and open. No person gets paid for developing + (lib)curl on full or even part time. We do this voluntarily on our spare + time. Occasionally companies pay individual developers to work on curl, but + that's up to each company and developer. It is not controlled by nor + supervised in any way by the project. + + We still get help from companies. Haxx provides web site, bandwidth, mailing + lists etc and sourceforge.net hosts project services we take advantage from, + like the bug tracker. Also again, some companies have sponsored certain + parts of the development in the past and I hope some will continue to do so + in the future. + + If you want to support our project, consider a donation or a banner-program + or even better: by helping us coding, documenting, testing etc. + + 1.7 What about CURL from curl.com? + + During the summer 2001, curl.com was busy advertising their client-side + programming language for the web, named CURL. + + We are in no way associated with curl.com or their CURL programming + language. + + Our project name curl has been in effective use since 1998. We were not the + first computer related project to use the name "curl" and do not claim any + first-hand rights to the name. + + We recognize that we will be living in parallel with curl.com and wish them + every success. + + 1.8 I have a problem who do I mail? + + Please do not mail any single individual unless you really need to. Keep + curl-related questions on a suitable mailing list. All available mailing + lists are listed in the MANUAL document and online at + http://curl.haxx.se/mail/ + + Keeping curl-related questions and discussions on mailing lists allows + others to join in and help, to share their ideas, contribute their + suggestions and spread their wisdom. Keeping discussions on public mailing + lists also allows for others to learn from this (both current and future + users thanks to the web based archives of the mailing lists), thus saving us + from having to repeat ourselves even more. Thanks for respecting this. + + If you have found or simply suspect a security problem in curl or libcurl, + mail curl-security at haxx.se (closed list of receivers, mails are not + disclosed) and tell. Then we can produce a fix in a timely manner before the + flaw is announced to the world, thus lessen the impact the problem will have + on existing users. + + 1.9 Where do I buy commercial support for curl? + + curl is fully open source. It means you can hire any skilled engineer to fix + your curl-related problems. + + We list available alternatives on the curl web site: + http://curl.haxx.se/support.html + + 1.10 How many are using curl? + + It is impossible to tell. + + We don't know how many users that knowingly have installed and use curl. + + We don't know how many users that use curl without knowing that they are in + fact using it. + + We don't know how many users that downloaded or installed curl and then + never use it. + + In May 2012 Daniel did a counting game and came up with a number that may + be completely wrong or somewhat accurate. 300 million! + + See http://daniel.haxx.se/blog/2012/05/16/300m-users/ + + 1.11 Why don't you update ca-bundle.crt + + The ca-bundle.crt file that used to be bundled with curl was very outdated + (it being last modified year 2000 should tell) and must be replaced with a + much more modern and up-to-date version by anyone who wants to verify peers + anyway. It is no longer provided, the last curl release that shipped it was + curl 7.18.0. + + In the cURL project we've decided not to attempt to keep this file updated + (or even present anymore) since deciding what to add to a ca cert bundle is + an undertaking we've not been ready to accept, and the one we can get from + Mozilla is perfectly fine so there's no need to duplicate that work. + + Today, with many services performed over HTTPS, every operating system + should come with a default ca cert bundle that can be deemed somewhat + trustworthy and that collection (if reasonably updated) should be deemed to + be a lot better than a private curl version. + + If you want the most recent collection of ca certs that Mozilla Firefox + uses, we recommend that you extract the collection yourself from Mozilla + Firefox (by running 'make ca-bundle), or by using our online service setup + for this purpose: http://curl.haxx.se/docs/caextract.html + + 1.12 I have a problem who can I chat with? + + There's a bunch of friendly people hanging out in the #curl channel on the + IRC network irc.freenode.net. If you're polite and nice, chances are big + that you can get -- or provide -- help instantly. + + 1.13 curl's ECCN number? + + The US government restricts exports of software that contains or uses + cryptography. When doing so, the Export Control Classification Number (ECCN) + is used to identify the level of export control etc. + + ASF gives a good explanation at http://www.apache.org/dev/crypto.html + + We believe curl's number might be ECCN 5D002, another possibility is + 5D992. It seems necessary to write them, asking to confirm. + + Comprehensible explanations of the meaning of such numbers and how to + obtain them (resp.) are here + + http://www.bis.doc.gov/licensing/exportingbasics.htm + http://www.bis.doc.gov/licensing/do_i_needaneccn.html + + An incomprehensible description of the two numbers above is here + http://www.access.gpo.gov/bis/ear/pdf/ccl5-pt2.pdf + + 1.14 How do I submit my patch? + + When you have made a patch or a change of whatever sort, and want to submit + that to the project, there are a few different ways we prefer: + + o send a patch to the curl-library mailing list. We're many subscribers + there and there are lots of people who can review patches, comment on them + and "receive" them properly. + + o if your patch changes or fixes a bug, you can also opt to submit a bug + report in the bug tracker and attach your patch there. There are less + people involved there. + + Lots of more details are found in the CONTRIBUTE and INTERNALS docs. + + +2. Install Related Problems + + 2.1 configure doesn't find OpenSSL even when it is installed + + This may be because of several reasons. + + 2.1.1 native linker doesn't find openssl + + Affected platforms: + Solaris (native cc compiler) + HPUX (native cc compiler) + SGI IRIX (native cc compiler) + SCO UNIX (native cc compiler) + + When configuring curl, I specify --with-ssl. OpenSSL is installed in + /usr/local/ssl Configure reports SSL in /usr/local/ssl, but fails to find + CRYPTO_lock in -lcrypto + + Cause: The cc for this test places the -L/usr/local/ssl/lib AFTER + -lcrypto, so ld can't find the library. This is due to a bug in the GNU + autoconf tool. + + Workaround: Specifying "LDFLAGS=-L/usr/local/ssl/lib" in front of + ./configure places the -L/usr/local/ssl/lib early enough in the command + line to make things work + + 2.1.2 only the libssl lib is missing + + If all include files and the libcrypto lib is present, with only the + libssl being missing according to configure, this is mostly likely because + a few functions are left out from the libssl. + + If the function names missing include RSA or RSAREF you can be certain + that this is because libssl requires the RSA and RSAREF libs to build. + + See the INSTALL file section that explains how to add those libs to + configure. Make sure that you remove the config.cache file before you + rerun configure with the new flags. + + 2.2 Does curl work/build with other SSL libraries? + + Curl has been written to use OpenSSL, GnuTLS, yassl, NSS, PolarSSL, axTLS or + qssl, although there should not be many problems using a different + library. If anyone does "port" curl to use a different SSL library, we are + of course very interested in getting the patch! + + 2.3 Where can I find a copy of LIBEAY32.DLL? + + That is an OpenSSL binary built for Windows. + + Curl uses OpenSSL to do the SSL stuff. The LIBEAY32.DLL is what curl needs + on a windows machine to do https://. Check out the curl web site to find + accurate and up-to-date pointers to recent OpenSSL DLLs and other binary + packages. + + 2.4 Does curl support SOCKS (RFC 1928) ? + + Yes, SOCKS 4 and 5 are supported. + + +3. Usage problems + + 3.1 curl: (1) SSL is disabled, https: not supported + + If you get this output when trying to get anything from a https:// server, + it means that the instance of curl/libcurl that you're using was built + without support for this protocol. + + This could've happened if the configure script that was run at build time + couldn't find all libs and include files curl requires for SSL to work. If + the configure script fails to find them, curl is simply built without SSL + support. + + To get the https:// support into a curl that was previously built but that + reports that https:// is not supported, you should dig through the document + and logs and check out why the configure script doesn't find the SSL libs + and/or include files. + + Also, check out the other paragraph in this FAQ labelled "configure doesn't + find OpenSSL even when it is installed". + + 3.2 How do I tell curl to resume a transfer? + + Curl supports resumed transfers both ways on both FTP and HTTP. + Try the -C option. + + 3.3 Why doesn't my posting using -F work? + + You can't simply use -F or -d at your choice. The web server that will + receive your post assumes one of the formats. If the form you're trying to + "fake" sets the type to 'multipart/form-data', then and only then you must + use the -F type. In all the most common cases, you should use -d which then + causes a posting with the type 'application/x-www-form-urlencoded'. + + This is described in some detail in the MANUAL and TheArtOfHttpScripting + documents, and if you don't understand it the first time, read it again + before you post questions about this to the mailing list. Also, try reading + through the mailing list archives for old postings and questions regarding + this. + + 3.4 How do I tell curl to run custom FTP commands? + + You can tell curl to perform optional commands both before and/or after a + file transfer. Study the -Q/--quote option. + + Since curl is used for file transfers, you don't normally use curl to + perform FTP commands without transferring anything. Therefore you must + always specify a URL to transfer to/from even when doing custom FTP + commands, or use -I which implies the "no body" option sent to libcurl. + + 3.5 How can I disable the Accept: */* header? + + You can change all internally generated headers by adding a replacement with + the -H/--header option. By adding a header with empty contents you safely + disable that one. Use -H "Accept:" to disable that specific header. + + 3.6 Does curl support ASP, XML, XHTML or HTML version Y? + + To curl, all contents are alike. It doesn't matter how the page was + generated. It may be ASP, PHP, Perl, shell-script, SSI or plain + HTML-files. There's no difference to curl and it doesn't even know what kind + of language that generated the page. + + See also item 3.14 regarding javascript. + + 3.7 Can I use curl to delete/rename a file through FTP? + + Yes. You specify custom FTP commands with -Q/--quote. + + One example would be to delete a file after you have downloaded it: + + curl -O ftp://download.com/coolfile -Q '-DELE coolfile' + + or rename a file after upload: + + curl -T infile ftp://upload.com/dir/ -Q "-RNFR infile" -Q "-RNTO newname" + + 3.8 How do I tell curl to follow HTTP redirects? + + Curl does not follow so-called redirects by default. The Location: header + that informs the client about this is only interpreted if you're using the + -L/--location option. As in: + + curl -L http://redirector.com + + Not all redirects are HTTP ones, see 4.14 + + 3.9 How do I use curl in my favorite programming language? + + There exist many language interfaces/bindings for curl that integrates it + better with various languages. If you are fluid in a script language, you + may very well opt to use such an interface instead of using the command line + tool. + + Find out more about which languages that support curl directly, and how to + install and use them, in the libcurl section of the curl web site: + http://curl.haxx.se/libcurl/ + + All the various bindings to libcurl are made by other projects and people, + outside of the cURL project. The cURL project itself only produces libcurl + with its plain C API. If you don't find anywhere else to ask you can ask + about bindings on the curl-library list too, but be prepared that people on + that list may not know anything about bindings. + + In October 2009, there were interfaces available for the following + languages: Ada95, Basic, C, C++, Ch, Cocoa, D, Dylan, Eiffel, Euphoria, + Ferite, Gambas, glib/GTK+, Haskell, ILE/RPG, Java, Lisp, Lua, Mono, .NET, + Object-Pascal, O'Caml, Pascal, Perl, PHP, PostgreSQL, Python, R, Rexx, Ruby, + Scheme, S-Lang, Smalltalk, SP-Forth, SPL, Tcl, Visual Basic, Visual FoxPro, + Q, wxwidgets and XBLite. By the time you read this, additional ones may have + appeared! + + 3.10 What about SOAP, WebDAV, XML-RPC or similar protocols over HTTP? + + Curl adheres to the HTTP spec, which basically means you can play with *any* + protocol that is built on top of HTTP. Protocols such as SOAP, WEBDAV and + XML-RPC are all such ones. You can use -X to set custom requests and -H to + set custom headers (or replace internally generated ones). + + Using libcurl is of course just as fine and you'd just use the proper + library options to do the same. + + 3.11 How do I POST with a different Content-Type? + + You can always replace the internally generated headers with -H/--header. + To make a simple HTTP POST with text/xml as content-type, do something like: + + curl -d "datatopost" -H "Content-Type: text/xml" [URL] + + 3.12 Why do FTP specific features over HTTP proxy fail? + + Because when you use a HTTP proxy, the protocol spoken on the network will + be HTTP, even if you specify a FTP URL. This effectively means that you + normally can't use FTP specific features such as FTP upload and FTP quote + etc. + + There is one exception to this rule, and that is if you can "tunnel through" + the given HTTP proxy. Proxy tunneling is enabled with a special option (-p) + and is generally not available as proxy admins usually disable tunneling to + other ports than 443 (which is used for HTTPS access through proxies). + + 3.13 Why does my single/double quotes fail? + + To specify a command line option that includes spaces, you might need to + put the entire option within quotes. Like in: + + curl -d " with spaces " url.com + + or perhaps + + curl -d ' with spaces ' url.com + + Exactly what kind of quotes and how to do this is entirely up to the shell + or command line interpreter that you are using. For most unix shells, you + can more or less pick either single (') or double (") quotes. For + Windows/DOS prompts I believe you're forced to use double (") quotes. + + Please study the documentation for your particular environment. Examples in + the curl docs will use a mix of both these ones as shown above. You must + adjust them to work in your environment. + + Remember that curl works and runs on more operating systems than most single + individuals have ever tried. + + 3.14 Does curl support Javascript or PAC (automated proxy config)? + + Many web pages do magic stuff using embedded Javascript. Curl and libcurl + have no built-in support for that, so it will be treated just like any other + contents. + + .pac files are a netscape invention and are sometimes used by organizations + to allow them to differentiate which proxies to use. The .pac contents is + just a Javascript program that gets invoked by the browser and that returns + the name of the proxy to connect to. Since curl doesn't support Javascript, + it can't support .pac proxy configuration either. + + Some workarounds usually suggested to overcome this Javascript dependency: + + - Depending on the Javascript complexity, write up a script that + translates it to another language and execute that. + + - Read the Javascript code and rewrite the same logic in another language. + + - Implement a Javascript interpreter, people have successfully used the + Mozilla Javascript engine in the past. + + - Ask your admins to stop this, for a static proxy setup or similar. + + 3.15 Can I do recursive fetches with curl? + + No. curl itself has no code that performs recursive operations, such as + those performed by wget and similar tools. + + There exist wrapper scripts with that functionality (for example the + curlmirror perl script), and you can write programs based on libcurl to do + it, but the command line tool curl itself cannot. + + 3.16 What certificates do I need when I use SSL? + + There are three different kinds of "certificates" to keep track of when we + talk about using SSL-based protocols (HTTPS or FTPS) using curl or libcurl. + + - Client certificate. The server you communicate may require that you can + provide this in order to prove that you actually are who you claim to be. + If the server doesn't require this, you don't need a client certificate. + + A client certificate is always used together with a private key, and the + private key has a pass phrase that protects it. + + - Server certificate. The server you communicate with has a server + certificate. You can and should verify this certificate to make sure that + you are truly talking to the real server and not a server impersonating + it. + + - Certificate Authority certificate ("CA cert"). You often have several CA + certs in a CA cert bundle that can be used to verify a server certificate + that was signed by one of the authorities in the bundle. curl does not + come with a CA cert bundle but most curl installs provide one. You can + also override the default. + + The server certificate verification process is made by using a Certificate + Authority certificate ("CA cert") that was used to sign the server + certificate. Server certificate verification is enabled by default in curl + and libcurl and is often the reason for problems as explained in FAQ entry + 4.12 and the SSLCERTS document + (http://curl.haxx.se/docs/sslcerts.html). Server certificates that are + "self-signed" or otherwise signed by a CA that you do not have a CA cert + for, cannot be verified. If the verification during a connect fails, you + are refused access. You then need to explicitly disable the verification + to connect to the server. + + 3.17 How do I list the root dir of an FTP server? + + There are two ways. The way defined in the RFC is to use an encoded slash + in the first path part. List the "/tmp" dir like this: + + curl ftp://ftp.sunet.se/%2ftmp/ + + or the not-quite-kosher-but-more-readable way, by simply starting the path + section of the URL with a slash: + + curl ftp://ftp.sunet.se//tmp/ + + 3.18 Can I use curl to send a POST/PUT and not wait for a response? + + No. + + But you could easily write your own program using libcurl to do such stunts. + + 3.19 How do I get HTTP from a host using a specific IP address? + + For example, you may be trying out a web site installation that isn't yet in + the DNS. Or you have a site using multiple IP addresses for a given host + name and you want to address a specific one out of the set. + + Set a custom Host: header that identifies the server name you want to reach + but use the target IP address in the URL: + + curl --header "Host: www.example.com" http://127.0.0.1/ + + You can also opt to add faked host name entries to curl with the --resolve + option. That has the added benefit that things like redirects will also work + properly. The above operation would instead be done as: + + curl --resolve www.example.com:80:127.0.0.1 http://www.example.com/ + + 3.20 How to SFTP from my user's home directory? + + Contrary to how FTP works, SFTP and SCP URLs specify the exact directory to + work with. It means that if you don't specify that you want the user's home + directory, you get the actual root directory. + + To specify a file in your user's home directory, you need to use the correct + URL syntax which for sftp might look similar to: + + curl -O -u user:password sftp://example.com/~/file.txt + + and for SCP it is just a different protocol prefix: + + curl -O -u user:password scp://example.com/~/file.txt + + 3.21 Protocol xxx not supported or disabled in libcurl + + When passing on a URL to curl to use, it may respond that the particular + protocol is not supported or disabled. The particular way this error message + is phrased is because curl doesn't make a distinction internally of whether + a particular protocol is not supported (ie never got any code added that + knows how to speak that protocol) or if it was explicitly disabled. curl can + be built to only support a given set of protocols, and the rest would then + be disabled or not supported. + + Note that this error will also occur if you pass a wrongly spelled protocol + part as in "htpt://example.com" or as in the less evident case if you prefix + the protocol part with a space as in " http://example.com/". + + +4. Running Problems + + 4.1 Problems connecting to SSL servers. + + It took a very long time before we could sort out why curl had problems to + connect to certain SSL servers when using SSLeay or OpenSSL v0.9+. The + error sometimes showed up similar to: + + 16570:error:1407D071:SSL routines:SSL2_READ:bad mac decode:s2_pkt.c:233: + + It turned out to be because many older SSL servers don't deal with SSLv3 + requests properly. To correct this problem, tell curl to select SSLv2 from + the command line (-2/--sslv2). + + There have also been examples where the remote server didn't like the SSLv2 + request and instead you had to force curl to use SSLv3 with -3/--sslv3. + + 4.2 Why do I get problems when I use & or % in the URL? + + In general unix shells, the & symbol is treated specially and when used, it + runs the specified command in the background. To safely send the & as a part + of a URL, you should quote the entire URL by using single (') or double (") + quotes around it. Similar problems can also occur on some shells with other + characters, including ?*!$~(){}<>\|;`. When in doubt, quote the URL. + + An example that would invoke a remote CGI that uses &-symbols could be: + + curl 'http://www.altavista.com/cgi-bin/query?text=yes&q=curl' + + In Windows, the standard DOS shell treats the %-symbol specially and you + need to use TWO %-symbols for each single one you want to use in the URL. + + Also note that if you want the literal %-symbol to be part of the data you + pass in a POST using -d/--data you must encode it as '%25' (which then also + needs the %-symbol doubled on Windows machines). + + 4.3 How can I use {, }, [ or ] to specify multiple URLs? + + Because those letters have a special meaning to the shell, and to be used in + a URL specified to curl you must quote them. + + An example that downloads two URLs (sequentially) would do: + + curl '{curl,www}.haxx.se' + + To be able to use those letters as actual parts of the URL (without using + them for the curl URL "globbing" system), use the -g/--globoff option: + + curl -g 'www.site.com/weirdname[].html' + + 4.4 Why do I get downloaded data even though the web page doesn't exist? + + Curl asks remote servers for the page you specify. If the page doesn't exist + at the server, the HTTP protocol defines how the server should respond and + that means that headers and a "page" will be returned. That's simply how + HTTP works. + + By using the --fail option you can tell curl explicitly to not get any data + if the HTTP return code doesn't say success. + + 4.5 Why do I get return code XXX from a HTTP server? + + RFC2616 clearly explains the return codes. This is a short transcript. Go + read the RFC for exact details: + + 4.5.1 "400 Bad Request" + + The request could not be understood by the server due to malformed + syntax. The client SHOULD NOT repeat the request without modifications. + + 4.5.2 "401 Unauthorized" + + The request requires user authentication. + + 4.5.3 "403 Forbidden" + + The server understood the request, but is refusing to fulfil it. + Authorization will not help and the request SHOULD NOT be repeated. + + 4.5.4 "404 Not Found" + + The server has not found anything matching the Request-URI. No indication + is given of whether the condition is temporary or permanent. + + 4.5.5 "405 Method Not Allowed" + + The method specified in the Request-Line is not allowed for the resource + identified by the Request-URI. The response MUST include an Allow header + containing a list of valid methods for the requested resource. + + 4.5.6 "301 Moved Permanently" + + If you get this return code and an HTML output similar to this: + + <H1>Moved Permanently</H1> The document has moved <A + HREF="http://same_url_now_with_a_trailing_slash/">here</A>. + + it might be because you request a directory URL but without the trailing + slash. Try the same operation again _with_ the trailing URL, or use the + -L/--location option to follow the redirection. + + 4.6 Can you tell me what error code 142 means? + + All curl error codes are described at the end of the man page, in the + section called "EXIT CODES". + + Error codes that are larger than the highest documented error code means + that curl has exited due to a crash. This is a serious error, and we + appreciate a detailed bug report from you that describes how we could go + ahead and repeat this! + + 4.7 How do I keep user names and passwords secret in Curl command lines? + + This problem has two sides: + + The first part is to avoid having clear-text passwords in the command line + so that they don't appear in 'ps' outputs and similar. That is easily + avoided by using the "-K" option to tell curl to read parameters from a file + or stdin to which you can pass the secret info. curl itself will also + attempt to "hide" the given password by blanking out the option - this + doesn't work on all platforms. + + To keep the passwords in your account secret from the rest of the world is + not a task that curl addresses. You could of course encrypt them somehow to + at least hide them from being read by human eyes, but that is not what + anyone would call security. + + Also note that regular HTTP (using Basic authentication) and FTP passwords + are sent in clear across the network. All it takes for anyone to fetch them + is to listen on the network. Eavesdropping is very easy. Use more secure + authentication methods (like Digest, Negotiate or even NTLM) or consider the + SSL-based alternatives HTTPS and FTPS. + + 4.8 I found a bug! + + It is not a bug if the behavior is documented. Read the docs first. + Especially check out the KNOWN_BUGS file, it may be a documented bug! + + If it is a problem with a binary you've downloaded or a package for your + particular platform, try contacting the person who built the package/archive + you have. + + If there is a bug, read the BUGS document first. Then report it as described + in there. + + 4.9 Curl can't authenticate to the server that requires NTLM? + + NTLM support requires OpenSSL, GnuTLS, NSS or Microsoft Windows libraries at + build-time to provide this functionality. + + NTLM is a Microsoft proprietary protocol. Proprietary formats are evil. You + should not use such ones. + + 4.10 My HTTP request using HEAD, PUT or DELETE doesn't work! + + Many web servers allow or demand that the administrator configures the + server properly for these requests to work on the web server. + + Some servers seem to support HEAD only on certain kinds of URLs. + + To fully grasp this, try the documentation for the particular server + software you're trying to interact with. This is not anything curl can do + anything about. + + 4.11 Why does my HTTP range requests return the full document? + + Because the range may not be supported by the server, or the server may + choose to ignore it and return the full document anyway. + + 4.12 Why do I get "certificate verify failed" ? + + You invoke curl 7.10 or later to communicate on a https:// URL and get an + error back looking something similar to this: + + curl: (35) SSL: error:14090086:SSL routines: + SSL3_GET_SERVER_CERTIFICATE:certificate verify failed + + Then it means that curl couldn't verify that the server's certificate was + good. Curl verifies the certificate using the CA cert bundle that comes with + the curl installation. + + To disable the verification (which makes it act like curl did before 7.10), + use -k. This does however enable man-in-the-middle attacks. + + If you get this failure but are having a CA cert bundle installed and used, + the server's certificate is not signed by one of the CA's in the bundle. It + might for example be self-signed. You then correct this problem by obtaining + a valid CA cert for the server. Or again, decrease the security by disabling + this check. + + Details are also in the SSLCERTS file in the release archives, found online + here: http://curl.haxx.se/docs/sslcerts.html + + 4.13 Why is curl -R on Windows one hour off? + + During daylight savings time, when -R is used, curl will set a time that + appears one hour off. This happens due to a flaw in how Windows stores and + uses file modification times and it is not easily worked around. For details + on this problem, read this: http://www.codeproject.com/datetime/dstbugs.asp + + 4.14 Redirects work in browser but not with curl! + + curl supports HTTP redirects fine (see item 3.8). Browsers generally support + at least two other ways to perform directs that curl does not: + + - Meta tags. You can write a HTML tag that will cause the browser to + redirect to another given URL after a certain time. + + - Javascript. You can write a Javascript program embedded in a HTML page + that redirects the browser to another given URL. + + There is no way to make curl follow these redirects. You must either + manually figure out what the page is set to do, or you write a script that + parses the results and fetches the new URL. + + 4.15 FTPS doesn't work + + curl supports FTPS (sometimes known as FTP-SSL) both implicit and explicit + mode. + + When a URL is used that starts with FTPS://, curl assumes implicit SSL on + the control connection and will therefore immediately connect and try to + speak SSL. FTPS:// connections default to port 990. + + To use explicit FTPS, you use a FTP:// URL and the --ftp-ssl option (or one + of its related flavours). This is the most common method, and the one + mandated by RFC4217. This kind of connection then of course uses the + standard FTP port 21 by default. + + 4.16 My HTTP POST or PUT requests are slow! + + libcurl makes all POST and PUT requests (except for POST requests with a + very tiny request body) use the "Expect: 100-continue" header. This header + allows the server to deny the operation early so that libcurl can bail out + already before having to send any data. This is useful in authentication + cases and others. + + However, many servers don't implement the Expect: stuff properly and if the + server doesn't respond (positively) within 1 second libcurl will continue + and send off the data anyway. + + You can disable libcurl's use of the Expect: header the same way you disable + any header, using -H / CURLOPT_HTTPHEADER, or by forcing it to use HTTP 1.0. + + 4.17 Non-functional connect timeouts + + In most Windows setups having a timeout longer than 21 seconds make no + difference, as it will only send 3 TCP SYN packets and no more. The second + packet sent three seconds after the first and the third six seconds after + the second. No more than three packets are sent, no matter how long the + timeout is set. + + See option TcpMaxConnectRetransmissions on this page: + http://support.microsoft.com/?scid=kb%3Ben-us%3B175523&x=6&y=7 + + Also, even on non-Windows systems there may run a firewall or anti-virus + software or similar that accepts the connection but does not actually do + anything else. This will make (lib)curl to consider the connection connected + and thus the connect timeout won't trigger. + + 4.18 file:// URLs containing drive letters (Windows, NetWare) + + When using cURL to try to download a local file, one might use a URL + in this format: + + file://D:/blah.txt + + You'll find that even if D:\blah.txt does exist, cURL returns a 'file + not found' error. + + According to RFC 1738 (http://www.faqs.org/rfcs/rfc1738.html), + file:// URLs must contain a host component, but it is ignored by + most implementations. In the above example, 'D:' is treated as the + host component, and is taken away. Thus, cURL tries to open '/blah.txt'. + If your system is installed to drive C:, that will resolve to 'C:\blah.txt', + and if that doesn't exist you will get the not found error. + + To fix this problem, use file:// URLs with *three* leading slashes: + + file:///D:/blah.txt + + Alternatively, if it makes more sense, specify 'localhost' as the host + component: + + file://localhost/D:/blah.txt + + In either case, cURL should now be looking for the correct file. + + 4.19 Why doesn't cURL return an error when the network cable is unplugged? + + Unplugging the cable is not an error situation. The TCP/IP protocol stack + was designed to be fault tolerant, so even though there may be a physical + break somewhere the connection shouldn't be affected, just possibly + delayed. Eventually, the physical break will be fixed or the data will be + re-routed around the physical problem. + + In such cases, the TCP/IP stack is responsible for detecting when the + network connection is irrevocably lost. Since with some protocols it is + perfectly legal for the client wait indefinitely for data, the stack may + never report a problem, and even when it does, it can take up to 20 minutes + for it to detect an issue. The curl option --keepalive-time enables + keep-alive support in the TCP/IP stack which makes it periodically probe the + connection to make sure it is still available to send data. That should + reliably detect any TCP/IP network failure. + + But even that won't detect the network going down before the TCP/IP + connection is established (e.g. during a DNS lookup) or using protocols that + don't use TCP. To handle those situations, curl offers a number of timeouts + on its own. --speed-limit/--speed-time will abort if the data transfer rate + falls too low, and --connect-timeout and --max-time can be used to put an + overall timeout on the connection phase or the entire transfer. + + +5. libcurl Issues + + 5.1 Is libcurl thread-safe? + + Yes. + + We have written the libcurl code specifically adjusted for multi-threaded + programs. libcurl will use thread-safe functions instead of non-safe ones if + your system has such. + + If you use a OpenSSL-powered libcurl in a multi-threaded environment, you + need to provide one or two locking functions: + + http://www.openssl.org/docs/crypto/threads.html + + If you use a GnuTLS-powered libcurl in a multi-threaded environment, you + need to provide locking function(s) for libgcrypt (which is used by GnuTLS + for the crypto functions). + + http://www.gnu.org/software/gnutls/manual/html_node/Multi_002dthreaded-applications.html + + No special locking is needed with a NSS-powered libcurl. NSS is thread-safe. + + 5.2 How can I receive all data into a large memory chunk? + + [ See also the examples/getinmemory.c source ] + + You are in full control of the callback function that gets called every time + there is data received from the remote server. You can make that callback do + whatever you want. You do not have to write the received data to a file. + + One solution to this problem could be to have a pointer to a struct that you + pass to the callback function. You set the pointer using the + CURLOPT_WRITEDATA option. Then that pointer will be passed to the callback + instead of a FILE * to a file: + + /* imaginary struct */ + struct MemoryStruct { + char *memory; + size_t size; + }; + + /* imaginary callback function */ + 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 = (char *)realloc(mem->memory, mem->size + realsize + 1); + if (mem->memory) { + memcpy(&(mem->memory[mem->size]), ptr, realsize); + mem->size += realsize; + mem->memory[mem->size] = 0; + } + return realsize; + } + + 5.3 How do I fetch multiple files with libcurl? + + libcurl has excellent support for transferring multiple files. You should + just repeatedly set new URLs with curl_easy_setopt() and then transfer it + with curl_easy_perform(). The handle you get from curl_easy_init() is not + only reusable, but you're even encouraged to reuse it if you can, as that + will enable libcurl to use persistent connections. + + 5.4 Does libcurl do Winsock initialization on win32 systems? + + Yes, if told to in the curl_global_init() call. + + 5.5 Does CURLOPT_WRITEDATA and CURLOPT_READDATA work on win32 ? + + Yes, but you cannot open a FILE * and pass the pointer to a DLL and have + that DLL use the FILE * (as the DLL and the client application cannot access + each others' variable memory areas). If you set CURLOPT_WRITEDATA you must + also use CURLOPT_WRITEFUNCTION as well to set a function that writes the + file, even if that simply writes the data to the specified FILE *. + Similarly, if you use CURLOPT_READDATA you must also specify + CURLOPT_READFUNCTION. + + 5.6 What about Keep-Alive or persistent connections? + + curl and libcurl have excellent support for persistent connections when + transferring several files from the same server. Curl will attempt to reuse + connections for all URLs specified on the same command line/config file, and + libcurl will reuse connections for all transfers that are made using the + same libcurl handle. + + When you use the easy interface, the connection cache is kept within the + easy handle. If you instead use the multi interface, the connection cache + will be kept within the multi handle and will be shared among all the easy + handles that are used within the same multi handle. + + 5.7 Link errors when building libcurl on Windows! + + You need to make sure that your project, and all the libraries (both static + and dynamic) that it links against, are compiled/linked against the same run + time library. + + This is determined by the /MD, /ML, /MT (and their corresponding /M?d) + options to the command line compiler. /MD (linking against MSVCRT dll) seems + to be the most commonly used option. + + When building an application that uses the static libcurl library, you must + add -DCURL_STATICLIB to your CFLAGS. Otherwise the linker will look for + dynamic import symbols. If you're using Visual Studio, you need to instead + add CURL_STATICLIB in the "Preprocessor Definitions" section. + + If you get linker error like "unknown symbol __imp__curl_easy_init ..." you + have linked against the wrong (static) library. If you want to use the + libcurl.dll and import lib, you don't need any extra CFLAGS, but use one of + the import libraries below. These are the libraries produced by the various + lib/Makefile.* files: + + Target: static lib. import lib for libcurl*.dll. + ----------------------------------------------------------- + MingW: libcurl.a libcurldll.a + MSVC (release): libcurl.lib libcurl_imp.lib + MSVC (debug): libcurld.lib libcurld_imp.lib + Borland: libcurl.lib libcurl_imp.lib + + 5.8 libcurl.so.X: open failed: No such file or directory + + This is an error message you might get when you try to run a program linked + with a shared version of libcurl and your run-time linker (ld.so) couldn't + find the shared library named libcurl.so.X. (Where X is the number of the + current libcurl ABI, typically 3 or 4). + + You need to make sure that ld.so finds libcurl.so.X. You can do that + multiple ways, and it differs somewhat between different operating systems, + but they are usually: + + * Add an option to the linker command line that specify the hard-coded path + the run-time linker should check for the lib (usually -R) + + * Set an environment variable (LD_LIBRARY_PATH for example) where ld.so + should check for libs + + * Adjust the system's config to check for libs in the directory where you've + put the dir (like Linux's /etc/ld.so.conf) + + 'man ld.so' and 'man ld' will tell you more details + + 5.9 How does libcurl resolve host names? + + libcurl supports a large a number of different name resolve functions. One + of them is picked at build-time and will be used unconditionally. Thus, if + you want to change name resolver function you must rebuild libcurl and tell + it to use a different function. + + - The non-ipv6 resolver that can use one out of four host name resolve calls + (depending on what your system supports): + + A - gethostbyname() + B - gethostbyname_r() with 3 arguments + C - gethostbyname_r() with 5 arguments + D - gethostbyname_r() with 6 arguments + + - The ipv6-resolver that uses getaddrinfo() + + - The c-ares based name resolver that uses the c-ares library for resolves. + Using this offers asynchronous name resolves. + + - The threaded resolver (default option on Windows). It uses: + + A - gethostbyname() on plain ipv4 hosts + B - getaddrinfo() on ipv6-enabled hosts + + Also note that libcurl never resolves or reverse-lookups addresses given as + pure numbers, such as 127.0.0.1 or ::1. + + 5.10 How do I prevent libcurl from writing the response to stdout? + + libcurl provides a default built-in write function that writes received data + to stdout. Set the CURLOPT_WRITEFUNCTION to receive the data, or possibly + set CURLOPT_WRITEDATA to a different FILE * handle. + + 5.11 How do I make libcurl not receive the whole HTTP response? + + You make the write callback (or progress callback) return an error and + libcurl will then abort the transfer. + + 5.12 Can I make libcurl fake or hide my real IP address? + + No. libcurl operates on a higher level than so. Besides, faking IP address + would imply sending IP packages with a made-up source address, and then you + normally get a problem with intercepting the packages sent back as they + would then not be routed to you! + + If you use a proxy to access remote sites, the sites will not see your local + IP address but instead the address of the proxy. + + Also note that on many networks NATs or other IP-munging techniques are used + that makes you see and use a different IP address locally than what the + remote server will see you coming from. + + 5.13 How do I stop an ongoing transfer? + + With the easy interface you make sure to return the correct error code from + one of the callbacks, but none of them are instant. There is no function you + can call from another thread or similar that will stop it immediately. + Instead, you need to make sure that one of the callbacks you use returns an + appropriate value that will stop the transfer. Suitable callbacks that you + can do this with include the progress callback, the read callback and the + write callback. + + If you're using the multi interface, you can also stop a transfer by + removing the particular easy handle from the multi stack at any moment you + think the transfer is done. + + 5.14 Using C++ non-static functions for callbacks? + + libcurl is a C library, it doesn't know anything about C++ member functions. + + You can overcome this "limitation" with a relative ease using a static + member function that is passed a pointer to the class: + + // f is the pointer to your object. + static YourClass::func(void *buffer, size_t sz, size_t n, void *f) + { + // Call non-static member function. + static_cast<YourClass*>(f)->nonStaticFunction(); + } + + // This is how you pass pointer to the static function: + curl_easy_setopt(hcurl, CURLOPT_WRITEFUNCTION, YourClass:func); + curl_easy_setopt(hcurl, CURLOPT_WRITEDATA, this); + + 5.15 How do I get an FTP directory listing? + + If you end the FTP URL you request with a slash, libcurl will provide you + with a directory listing of that given directory. You can also set + CURLOPT_CUSTOMREQUEST to alter what exact listing command libcurl would use + to list the files. + + The follow-up question that tend to follow the previous one, is how a + program is supposed to parse the directory listing. How does it know what's + a file and what's a dir and what's a symlink etc. The harsh reality is that + FTP provides no such fine and easy-to-parse output. The output format FTP + servers respond to LIST commands are entirely at the server's own liking and + the NLST output doesn't reveal any types and in many cases don't even + include all the directory entries. Also, both LIST and NLST tend to hide + unix-style hidden files (those that start with a dot) by default so you need + to do "LIST -a" or similar to see them. + + The application thus needs to parse the LIST output. One such existing + list parser is available at http://cr.yp.to/ftpparse.html Versions of + libcurl since 7.21.0 also provide the ability to specify a wildcard to + download multiple files from one FTP directory. + + 5.16 I want a different time-out! + + Time and time again users realize that CURLOPT_TIMEOUT and + CURLOPT_CONNECTIMEOUT are not sufficiently advanced or flexible to cover all + the various use cases and scenarios applications end up with. + + libcurl offers many more ways to time-out operations. A common alternative + is to use the CURLOPT_LOW_SPEED_LIMIT and CURLOPT_LOW_SPEED_TIME options to + specify the lowest possible speed to accept before to consider the transfer + timed out. + + The most flexible way is by writing your own time-out logic and using + CURLOPT_PROGRESSFUNCTION (perhaps in combination with other callbacks) and + use that to figure out exactly when the right condition is met when the + transfer should get stopped. + + +6. License Issues + + Curl and libcurl are released under a MIT/X derivate license. The license is + very liberal and should not impose a problem for your project. This section + is just a brief summary for the cases we get the most questions. (Parts of + this section was much enhanced by Bjorn Reese.) + + We are not lawyers and this is not legal advice. You should probably consult + one if you want true and accurate legal insights without our prejudice. Note + especially that this section concerns the libcurl license only; compiling in + features of libcurl that depend on other libraries (e.g. OpenSSL) may affect + the licensing obligations of your application. + + 6.1 I have a GPL program, can I use the libcurl library? + + Yes! + + Since libcurl may be distributed under the MIT/X derivate license, it can be + used together with GPL in any software. + + 6.2 I have a closed-source program, can I use the libcurl library? + + Yes! + + libcurl does not put any restrictions on the program that uses the library. + + 6.3 I have a BSD licensed program, can I use the libcurl library? + + Yes! + + libcurl does not put any restrictions on the program that uses the library. + + 6.4 I have a program that uses LGPL libraries, can I use libcurl? + + Yes! + + The LGPL license doesn't clash with other licenses. + + 6.5 Can I modify curl/libcurl for my program and keep the changes secret? + + Yes! + + The MIT/X derivate license practically allows you to do almost anything with + the sources, on the condition that the copyright texts in the sources are + left intact. + + 6.6 Can you please change the curl/libcurl license to XXXX? + + No. + + We have carefully picked this license after years of development and + discussions and a large amount of people have contributed with source code + knowing that this is the license we use. This license puts the restrictions + we want on curl/libcurl and it does not spread to other programs or + libraries that use it. It should be possible for everyone to use libcurl or + curl in their projects, no matter what license they already have in use. + + 6.7 What are my obligations when using libcurl in my commercial apps? + + Next to none. All you need to adhere to is the MIT-style license (stated in + the COPYING file) which basically says you have to include the copyright + notice in "all copies" and that you may not use the copyright holder's name + when promoting your software. + + You do not have to release any of your source code. + + You do not have to reveal or make public any changes to the libcurl source + code. + + You do not have to broadcast to the world that you are using libcurl within + your app. + + All we ask is that you disclose "the copyright notice and this permission + notice" somewhere. Most probably like in the documentation or in the section + where other third party dependencies already are mentioned and acknowledged. + + As can be seen here: http://curl.haxx.se/docs/companies.html and elsewhere, + more and more companies are discovering the power of libcurl and take + advantage of it even in commercial environments. + + +7. PHP/CURL Issues + + 7.1 What is PHP/CURL? + + The module for PHP that makes it possible for PHP programs to access curl- + functions from within PHP. + + In the cURL project we call this module PHP/CURL to differentiate it from + curl the command line tool and libcurl the library. The PHP team however + does not refer to it like this (for unknown reasons). They call it plain + CURL (often using all caps) or sometimes ext/curl, but both cause much + confusion to users which in turn gives us a higher question load. + + 7.2 Who wrote PHP/CURL? + + PHP/CURL is a module that comes with the regular PHP package. It depends and + uses libcurl, so you need to have libcurl installed properly first before + PHP/CURL can be used. PHP/CURL was initially written by Sterling Hughes. + + 7.3 Can I perform multiple requests using the same handle? + + Yes - at least in PHP version 4.3.8 and later (this has been known to not + work in earlier versions, but the exact version when it started to work is + unknown to me). + + After a transfer, you just set new options in the handle and make another + transfer. This will make libcurl to re-use the same connection if it can. diff --git a/docs/FEATURES b/docs/FEATURES new file mode 100644 index 000000000..930222240 --- /dev/null +++ b/docs/FEATURES @@ -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 + - persistent 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 + - replaceable 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, PolarSSL or schannel + *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 diff --git a/docs/HISTORY b/docs/HISTORY new file mode 100644 index 000000000..e04fb53df --- /dev/null +++ b/docs/HISTORY @@ -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) diff --git a/docs/HTTP-COOKIES b/docs/HTTP-COOKIES new file mode 100644 index 000000000..818e161ee --- /dev/null +++ b/docs/HTTP-COOKIES @@ -0,0 +1,123 @@ +Updated: July 3, 2012 (http://curl.haxx.se/docs/http-cookies.html) + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + + +HTTP Cookies + + 1. HTTP Cookies + 1.1 Cookie overview + 1.2 Cookies saved to disk + 1.3 Cookies with curl the command line tool + 1.4 Cookies with libcurl + 1.5 Cookies with javascript + +============================================================================== + +1. HTTP Cookies + + 1.1 Cookie overview + + HTTP cookies are pieces of 'name=contents' snippets that a server tells the + client to hold and then the client sends back those the server on subsequent + requests to the same domains/paths for which the cookies were set. + + Cookies are either "session cookies" which typically are forgotten when the + session is over which is often translated to equal when browser quits, or + the cookies aren't session cookies they have expiration dates after which + the client will throw them away. + + Cookies are set to the client with the Set-Cookie: header and are sent to + servers with the Cookie: header. + + For a very long time, the only spec explaining how to use cookies was the + original Netscape spec from 1994: http://curl.haxx.se/rfc/cookie_spec.html + + In 2011, RFC6265 (http://www.ietf.org/rfc/rfc6265.txt) was finally published + and details how cookies work within HTTP. + + 1.2 Cookies saved to disk + + Netscape once created a file format for storing cookies on disk so that they + would survive browser restarts. curl adopted that file format to allow + sharing the cookies with browsers, only to see browsers move away from that + format. Modern browsers no longer use it, while curl still does. + + The netscape cookie file format stores one cookie per physical line in the + file with a bunch of associated meta data, each field separated with + TAB. That file is called the cookiejar in curl terminology. + + When libcurl saves a cookiejar, it creates a file header of its own in which + there is a URL mention that will link to the web version of this document. + + 1.3 Cookies with curl the command line tool + + curl has a full cookie "engine" built in. If you just activate it, you can + have curl receive and send cookies exactly as mandated in the specs. + + Command line options: + + -b, --cookie + + tell curl a file to read cookies from and start the cookie engine, or if + it isn't a file it will pass on the given string. -b name=var works and so + does -b cookiefile. + + -j, --junk-session-cookies + + when used in combination with -b, it will skip all "session cookies" on + load so as to appear to start a new cookie session. + + -c, --cookie-jar + + tell curl to start the cookie engine and write cookies to the given file + after the request(s) + + 1.4 Cookies with libcurl + + libcurl offers several ways to enable and interface the cookie engine. These + options are the ones provided by the native API. libcurl bindings may offer + access to them using other means. + + CURLOPT_COOKIE + + Is used when you want to specify the exact contents of a cookie header to + send to the server. + + CURLOPT_COOKIEFILE + + Tell libcurl to activate the cookie engine, and to read the initial set of + cookies from the given file. Read-only. + + CURLOPT_COOKIEJAR + + Tell libcurl to activate the cookie engine, and when the easy handle is + closed save all known cookies to the given cookiejar file. Write-only. + + CURLOPT_COOKIELIST + + Provide detailed information about a single cookie to add to the internal + storage of cookies. Pass in the cookie as a HTTP header with all the + details set, or pass in a line from a netscape cookie file. This option + can also be used to flush the cookies etc. + + CURLINFO_COOKIELIST + + Extract cookie information from the internal cookie storage as a linked + list. + + 1.5 Cookies with javascript + + These days a lot of the web is built up by javascript. The webbrowser loads + complete programs that render the page you see. These javascript programs + can also set and access cookies. + + Since curl and libcurl are plain HTTP clients without any knowledge of or + capability to handle javascript, such cookies will not be detected or used. + + Often, if you want to mimic what a browser does on such web sites, you can + record web browser HTTP traffic when using such a site and then repeat the + cookie operations using curl or libcurl. diff --git a/docs/INSTALL b/docs/INSTALL new file mode 100644 index 000000000..eac3cd555 --- /dev/null +++ b/docs/INSTALL @@ -0,0 +1,1100 @@ + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + + How To Compile + +Installing Binary Packages +========================== + + Lots of people download binary distributions of curl and libcurl. This + document does not describe how to install curl or libcurl using such a + binary package. This document describes how to compile, build and install + curl and libcurl from source code. + +Building from git +================= + + If you get your code off a git repository, see the GIT-INFO file in the + root directory for specific instructions on how to proceed. + +UNIX +==== + A normal unix installation is made in three or four steps (after you've + unpacked the source archive): + + ./configure + make + make test (optional) + make install + + You probably need to be root when doing the last command. + + If you have checked out the sources from the git repository, read the + GIT-INFO on how to proceed. + + Get a full listing of all available configure options by invoking it like: + + ./configure --help + + If you want to install curl in a different file hierarchy than /usr/local, + you need to specify that already when running configure: + + ./configure --prefix=/path/to/curl/tree + + If you happen to have write permission in that directory, you can do 'make + install' without being root. An example of this would be to make a local + install in your own home directory: + + ./configure --prefix=$HOME + make + make install + + The configure script always tries to find a working SSL library unless + explicitly told not to. If you have OpenSSL installed in the default search + path for your compiler/linker, you don't need to do anything special. If + you have OpenSSL installed in /usr/local/ssl, you can run configure like: + + ./configure --with-ssl + + If you have OpenSSL installed somewhere else (for example, /opt/OpenSSL) + and you have pkg-config installed, set the pkg-config path first, like this: + + env PKG_CONFIG_PATH=/opt/OpenSSL/lib/pkgconfig ./configure --with-ssl + + Without pkg-config installed, use this: + + ./configure --with-ssl=/opt/OpenSSL + + If you insist on forcing a build without SSL support, even though you may + have OpenSSL installed in your system, you can run configure like this: + + ./configure --without-ssl + + If you have OpenSSL installed, but with the libraries in one place and the + header files somewhere else, you have to set the LDFLAGS and CPPFLAGS + environment variables prior to running configure. Something like this + should work: + + (with the Bourne shell and its clones): + + CPPFLAGS="-I/path/to/ssl/include" LDFLAGS="-L/path/to/ssl/lib" \ + ./configure + + (with csh, tcsh and their clones): + + env CPPFLAGS="-I/path/to/ssl/include" LDFLAGS="-L/path/to/ssl/lib" \ + ./configure + + If you have shared SSL libs installed in a directory where your run-time + linker doesn't find them (which usually causes configure failures), you can + provide the -R option to ld on some operating systems to set a hard-coded + path to the run-time linker: + + env LDFLAGS=-R/usr/local/ssl/lib ./configure --with-ssl + + MORE OPTIONS + ------------ + + To force configure to use the standard cc compiler if both cc and gcc are + present, run configure like + + CC=cc ./configure + or + env CC=cc ./configure + + To force a static library compile, disable the shared library creation + by running configure like: + + ./configure --disable-shared + + To tell the configure script to skip searching for thread-safe functions, + add an option like: + + ./configure --disable-thread + + To build curl with kerberos4 support enabled, curl requires the krb4 libs + and headers installed. You can then use a set of options to tell + configure where those are: + + --with-krb4-includes[=DIR] Specify location of kerberos4 headers + --with-krb4-libs[=DIR] Specify location of kerberos4 libs + --with-krb4[=DIR] where to look for Kerberos4 + + In most cases, /usr/athena is the install prefix and then it works with + + ./configure --with-krb4=/usr/athena + + If you're a curl developer and use gcc, you might want to enable more + debug options with the --enable-debug option. + + curl can be built to use a whole range of libraries to provide various + useful services, and configure will try to auto-detect a decent + default. But if you want to alter it, you can select how to deal with + each individual library. + + To build with GnuTLS support instead of OpenSSL for SSL/TLS, note that + you need to use both --without-ssl and --with-gnutls. + + To build with yassl support instead of OpenSSL or GnuTLS, you must build + yassl with its OpenSSL emulation enabled and point to that directory root + with configure --with-ssl. + + To build with NSS support instead of OpenSSL for SSL/TLS, note that + you need to use both --without-ssl and --with-nss. + + To build with PolarSSL support instead of OpenSSL for SSL/TLS, note that + you need to use both --without-ssl and --with-polarssl. + + To build with axTLS support instead of OpenSSL for TLS, note that you + need to use both --without-ssl and --with-axtls. + + To get GSSAPI support, build with --with-gssapi and have the MIT or + Heimdal Kerberos 5 packages installed. + + To get support for SCP and SFTP, build with --with-libssh2 and have + libssh2 0.16 or later installed. + + To get Metalink support, build with --with-libmetalink and have the + libmetalink packages installed. + + SPECIAL CASES + ------------- + Some versions of uClibc require configuring with CPPFLAGS=-D_GNU_SOURCE=1 + to get correct large file support. + + The Open Watcom C compiler on Linux requires configuring with the variables: + + ./configure CC=owcc AR="$WATCOM/binl/wlib" AR_FLAGS=-q \ + RANLIB=/bin/true STRIP="$WATCOM/binl/wstrip" CFLAGS=-Wextra + + +Win32 +===== + + Building Windows DLLs and C run-time (CRT) linkage issues + --------------------------------------------------------- + + As a general rule, building a DLL with static CRT linkage is highly + discouraged, and intermixing CRTs in the same app is something to + avoid at any cost. + + Reading and comprehension of Microsoft Knowledge Base articles + KB94248 and KB140584 is a must for any Windows developer. Especially + important is full understanding if you are not going to follow the + advice given above. + + KB94248 - How To Use the C Run-Time + http://support.microsoft.com/kb/94248/en-us + + KB140584 - How to link with the correct C Run-Time (CRT) library + http://support.microsoft.com/kb/140584/en-us + + KB190799 - Potential Errors Passing CRT Objects Across DLL Boundaries + http://msdn.microsoft.com/en-us/library/ms235460 + + If your app is misbehaving in some strange way, or it is suffering + from memory corruption, before asking for further help, please try + first to rebuild every single library your app uses as well as your + app using the debug multithreaded dynamic C runtime. + + If you get linkage errors read section 5.7 of the FAQ document. + + + MingW32 + ------- + + Make sure that MinGW32's bin dir is in the search path, for example: + + set PATH=c:\mingw32\bin;%PATH% + + then run 'mingw32-make mingw32' in the root dir. There are other + make targets available to build libcurl with more features, use: + 'mingw32-make mingw32-zlib' to build with Zlib support; + 'mingw32-make mingw32-ssl-zlib' to build with SSL and Zlib enabled; + 'mingw32-make mingw32-ssh2-ssl-zlib' to build with SSH2, SSL, Zlib; + 'mingw32-make mingw32-ssh2-ssl-sspi-zlib' to build with SSH2, SSL, Zlib + and SSPI support. + + If you have any problems linking libraries or finding header files, be sure + to verify that the provided "Makefile.m32" files use the proper paths, and + adjust as necessary. It is also possible to override these paths with + environment variables, for example: + + set ZLIB_PATH=c:\zlib-1.2.7 + set OPENSSL_PATH=c:\openssl-0.9.8x + set LIBSSH2_PATH=c:\libssh2-1.4.2 + + ATTENTION: if you want to build with libssh2 support you have to use latest + version 0.17 - previous versions will NOT work with 7.17.0 and later! + Use 'mingw32-make mingw32-ssh2-ssl-zlib' to build with SSH2 and SSL enabled. + + It is now also possible to build with other LDAP SDKs than MS LDAP; + currently it is possible to build with native Win32 OpenLDAP, or with the + Novell CLDAP SDK. If you want to use these you need to set these vars: + + set LDAP_SDK=c:\openldap + set USE_LDAP_OPENLDAP=1 + + or for using the Novell SDK: + + set USE_LDAP_NOVELL=1 + + If you want to enable LDAPS support then set LDAPS=1. + + - optional MingW32-built OpenLDAP SDK available from: + http://www.gknw.net/mirror/openldap/ + - optional recent Novell CLDAP SDK available from: + http://developer.novell.com/ndk/cldap.htm + + + Cygwin + ------ + + Almost identical to the unix installation. Run the configure script in the + curl root with 'sh configure'. Make sure you have the sh executable in + /bin/ or you'll see the configure fail toward the end. + + Run 'make' + + Dev-Cpp + ------- + + See the separate INSTALL.devcpp file for details. + + MSVC 6 caveats + -------------- + + If you use MSVC 6 it is required that you use the February 2003 edition PSDK: + http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm + + Building any software with MSVC 6 without having PSDK installed is just + asking for trouble down the road once you have released it, you might notice + the problems in the first corner or ten miles ahead, depending mostly on your + choice of static vs dynamic runtime and third party libraries. Anyone using + software built in such way will at some point regret having done so. + + When someone uses MSVC 6 without PSDK he is using a compiler back from 1998. + + If the compiler has been updated with the installation of a service pack as + those mentioned in http://support.microsoft.com/kb/194022 the compiler can be + safely used to read source code, translate and make it object code. + + But, even with the service packs mentioned above installed, the resulting + software generated in such an environment will be using outdated system + header files and libraries with bugs and security issues which have already + been addressed and fixed long time ago. + + In order to make use of the updated system headers and fixed libraries + for MSVC 6, it is required that 'Platform SDK', PSDK from now onwards, + is installed. The specific PSDK that must be installed for MSVC 6 is the + February 2003 edition, which is the latest one supporting the MSVC 6 compiler, + this PSDK is also known as 'Windows Server 2003 PSDK' and can be downloaded + from http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm + + So, building curl and libcurl with MSVC 6 without PSDK is absolutely + discouraged for the benefit of anyone using software built in such + environment. And it will not be supported in any way, as we could just + be hunting bugs which have already been fixed way back in 2003. + + When building with MSVC 6 we attempt to detect if PSDK is not being used, + and if this is the case the build process will fail hard with an error + message stating that the February 2003 PSDK is required. This is done to + protect the unsuspecting and avoid PEBKAC issues. + + Additionally it might happen that a die hard MSVC hacker still wants to + build curl and libcurl with MSVC 6 without PSDK installed, even knowing + that this is a highly discouraged and unsupported build environment. In + this case the brave of heart will be able to build in such an environment + with the requisite of defining preprocessor symbol ALLOW_MSVC6_WITHOUT_PSDK + in lib/config-win32.h and knowing that LDAP and IPv6 support will be missing. + + MSVC from command line + ---------------------- + + Run the 'vcvars32.bat' file to get a proper environment. The + vcvars32.bat file is part of the Microsoft development environment and + you may find it in 'C:\Program Files\Microsoft Visual Studio\vc98\bin' + provided that you installed Visual C/C++ 6 in the default directory. + + Then run 'nmake vc' in curl's root directory. + + If you want to compile with zlib support, you will need to build + zlib (http://www.gzip.org/zlib/) as well. Please read the zlib + documentation on how to compile zlib. Define the ZLIB_PATH environment + variable to the location of zlib.h and zlib.lib, for example: + + set ZLIB_PATH=c:\zlib-1.2.7 + + Then run 'nmake vc-zlib' in curl's root directory. + + If you want to compile with SSL support you need the OpenSSL package. + Please read the OpenSSL documentation on how to compile and install + the OpenSSL libraries. The build process of OpenSSL generates the + libeay32.dll and ssleay32.dll files in the out32dll subdirectory in + the OpenSSL home directory. OpenSSL static libraries (libeay32.lib, + ssleay32.lib, RSAglue.lib) are created in the out32 subdirectory. + + Before running nmake define the OPENSSL_PATH environment variable with + the root/base directory of OpenSSL, for example: + + set OPENSSL_PATH=c:\openssl-0.9.8x + + Then run 'nmake vc-ssl' or 'nmake vc-ssl-dll' in curl's root + directory. 'nmake vc-ssl' will create a libcurl static and dynamic + libraries in the lib subdirectory, as well as a statically linked + version of curl.exe in the src subdirectory. This statically linked + version is a standalone executable not requiring any DLL at + runtime. This make method requires that you have the static OpenSSL + libraries available in OpenSSL's out32 subdirectory. + 'nmake vc-ssl-dll' creates the libcurl dynamic library and + links curl.exe against libcurl and OpenSSL dynamically. + This executable requires libcurl.dll and the OpenSSL DLLs + at runtime. + Run 'nmake vc-ssl-zlib' to build with both ssl and zlib support. + + MSVC 6 IDE + ---------- + + A minimal VC++ 6.0 reference workspace (vc6curl.dsw) is available with the + source distribution archive to allow proper building of the two included + projects, the libcurl library and the curl tool. + + 1) Open the vc6curl.dsw workspace with MSVC6's IDE. + 2) Select 'Build' from top menu. + 3) Select 'Batch Build' from dropdown menu. + 4) Make sure that the eight project configurations are 'checked'. + 5) Click on the 'Build' button. + 6) Once the eight project configurations are built you are done. + + Dynamic and static libcurl libraries are built in debug and release flavours, + and can be located each one in its own subdirectory, DLL-Debug, DLL-Release, + LIB-Debug and LIB-Release, all of them below the 'lib' subdirectory. + + In the same way four curl executables are created, each using its respective + library. The resulting curl executables are located in its own subdirectory, + DLL-Debug, DLL-Release, LIB-Debug and LIB-Release, below the 'src' subdir. + + These reference VC++ 6.0 configurations are generated using the dynamic CRT. + + Intentionally, these reference VC++ 6.0 projects and configurations don't use + third party libraries, such as OpenSSL or Zlib, to allow proper compilation + and configuration for all new users without further requirements. + + If you need something more 'involved' you might adjust them for your own use, + or explore the world of makefiles described above 'MSVC from command line'. + + Borland C++ compiler + --------------------- + + Ensure that your build environment is properly set up to use the compiler + and associated tools. PATH environment variable must include the path to + bin subdirectory of your compiler installation, eg: c:\Borland\BCC55\bin + + It is advisable to set environment variable BCCDIR to the base path of + the compiler installation. + + set BCCDIR=c:\Borland\BCC55 + + In order to build a plain vanilla version of curl and libcurl run the + following command from curl's root directory: + + make borland + + To build curl and libcurl with zlib and OpenSSL support set environment + variables ZLIB_PATH and OPENSSL_PATH to the base subdirectories of the + already built zlib and OpenSSL libraries and from curl's root directory + run command: + + make borland-ssl-zlib + + libcurl library will be built in 'lib' subdirectory while curl tool + is built in 'src' subdirectory. In order to use libcurl library it is + advisable to modify compiler's configuration file bcc32.cfg located + in c:\Borland\BCC55\bin to reflect the location of libraries include + paths for example the '-I' line could result in something like: + + -I"c:\Borland\BCC55\include;c:\curl\include;c:\openssl\inc32" + + bcc3.cfg '-L' line could also be modified to reflect the location of + of libcurl library resulting for example: + + -L"c:\Borland\BCC55\lib;c:\curl\lib;c:\openssl\out32" + + In order to build sample program 'simple.c' from the docs\examples + subdirectory run following command from mentioned subdirectory: + + bcc32 simple.c libcurl.lib cw32mt.lib + + In order to build sample program simplessl.c an SSL enabled libcurl + is required, as well as the OpenSSL libeay32.lib and ssleay32.lib + libraries. + + + OTHER MSVC IDEs + --------------- + + If you use VC++, Borland or similar compilers. Include all lib source + files in a static lib "project" (all .c and .h files that is). + (you should name it libcurl or similar) + + Make the sources in the src/ drawer be a "win32 console application" + project. Name it curl. + + + Disabling Specific Protocols in Win32 builds + -------------------------------------------- + + The configure utility, unfortunately, is not available for the Windows + environment, therefore, you cannot use the various disable-protocol + options of the configure utility on this platform. + + However, you can use the following defines to disable specific + protocols: + + HTTP_ONLY disables all protocols except HTTP + CURL_DISABLE_FTP disables FTP + CURL_DISABLE_LDAP disables LDAP + CURL_DISABLE_TELNET disables TELNET + CURL_DISABLE_DICT disables DICT + CURL_DISABLE_FILE disables FILE + CURL_DISABLE_TFTP disables TFTP + CURL_DISABLE_HTTP disables HTTP + + If you want to set any of these defines you have the following + possibilities: + + - Modify lib/config-win32.h + - Modify lib/setup.h + - Modify lib/Makefile.vc6 + - Add defines to Project/Settings/C/C++/General/Preprocessor Definitions + in the vc6libcurl.dsw/vc6libcurl.dsp Visual C++ 6 IDE project. + + + Using BSD-style lwIP instead of Winsock TCP/IP stack in Win32 builds + -------------------------------------------------------------------- + + In order to compile libcurl and curl using BSD-style lwIP TCP/IP stack + it is necessary to make definition of preprocessor symbol USE_LWIPSOCK + visible to libcurl and curl compilation processes. To set this definition + you have the following alternatives: + + - Modify lib/config-win32.h and src/config-win32.h + - Modify lib/Makefile.vc6 + - Add definition to Project/Settings/C/C++/General/Preprocessor Definitions + in the vc6libcurl.dsw/vc6libcurl.dsp Visual C++ 6 IDE project. + + Once that libcurl has been built with BSD-style lwIP TCP/IP stack support, + in order to use it with your program it is mandatory that your program + includes lwIP header file <lwip/opt.h> (or another lwIP header that includes + this) before including any libcurl header. Your program does not need the + USE_LWIPSOCK preprocessor definition which is for libcurl internals only. + + Compilation has been verified with lwIP 1.4.0 and contrib-1.4.0 from: + + http://download.savannah.gnu.org/releases/lwip/lwip-1.4.0.zip + http://download.savannah.gnu.org/releases/lwip/contrib-1.4.0.zip + + This BSD-style lwIP TCP/IP stack support must be considered experimental + given that it has been verified that lwIP 1.4.0 still needs some polish, + and libcurl might yet need some additional adjustment, caveat emptor. + + Important static libcurl usage note + ----------------------------------- + + When building an application that uses the static libcurl library, you must + add '-DCURL_STATICLIB' to your CFLAGS. Otherwise the linker will look for + dynamic import symbols. + + +IBM OS/2 +======== + Building under OS/2 is not much different from building under unix. + You need: + + - emx 0.9d + - GNU make + - GNU patch + - ksh + - GNU bison + - GNU file utilities + - GNU sed + - autoconf 2.13 + + If you want to build with OpenSSL or OpenLDAP support, you'll need to + download those libraries, too. Dirk Ohme has done some work to port SSL + libraries under OS/2, but it looks like he doesn't care about emx. You'll + find his patches on: http://come.to/Dirk_Ohme + + If during the linking you get an error about _errno being an undefined + symbol referenced from the text segment, you need to add -D__ST_MT_ERRNO__ + in your definitions. + + If everything seems to work fine but there's no curl.exe, you need to add + -Zexe to your linker flags. + + If you're getting huge binaries, probably your makefiles have the -g in + CFLAGS. + + +VMS +=== + (The VMS section is in whole contributed by the friendly Nico Baggus) + + Curl seems to work with FTP & HTTP other protocols are not tested. (the + perl http/ftp testing server supplied as testing too cannot work on VMS + because vms has no concept of fork(). [ I tried to give it a whack, but + that's of no use. + + SSL stuff has not been ported. + + Telnet has about the same issues as for Win32. When the changes for Win32 + are clear maybe they'll work for VMS too. The basic problem is that select + ONLY works for sockets. + + Marked instances of fopen/[f]stat that might become a problem, especially + for non stream files. In this regard, the files opened for writing will be + created stream/lf and will thus be safe. Just keep in mind that non-binary + read/wring from/to files will have a records size limit of 32767 bytes + imposed. + + Stat to get the size of the files is again only safe for stream files & + fixed record files without implied CC. + + -- My guess is that only allowing access to stream files is the quickest + way to get around the most issues. Therefore all files need to to be + checked to be sure they will be stream/lf before processing them. This is + the easiest way out, I know. The reason for this is that code that needs to + report the filesize will become a pain in the ass otherwise. + + Exit status.... Well we needed something done here, + + VMS has a structured exist status: + | 3 | 2 | 1 | 0| + |1098|765432109876|5432109876543|210| + +----+------------+-------------+---+ + |Ctrl| Facility | Error code |sev| + +----+------------+-------------+---+ + + With the Ctrl-bits an application can tell if part or the whole message has + already been printed from the program, DCL doesn't need to print it again. + + Facility - basically the program ID. A code assigned to the program + the name can be fetched from external or internal message libraries + Error code - the err codes assigned by the application + Sev. - severity: Even = error, off = non error + 0 = Warning + 1 = Success + 2 = Error + 3 = Information + 4 = Fatal + <5-7> reserved. + + This all presents itself with: + %<FACILITY>-<Sev>-<Errorname>, <Error message> + + See also the src/curlmsg.msg file, it has the source for the messages In + src/main.c a section is devoted to message status values, the globalvalues + create symbols with certain values, referenced from a compiled message + file. Have all exit function use a exit status derived from a translation + table with the compiled message codes. + + This was all compiled with: + + Compaq C V6.2-003 on OpenVMS Alpha V7.1-1H2 + + So far for porting notes as of: + 13-jul-2001 + N. Baggus + + +QNX +=== + (This section was graciously brought to us by David Bentham) + + As QNX is targeted for resource constrained environments, the QNX headers + set conservative limits. This includes the FD_SETSIZE macro, set by default + to 32. Socket descriptors returned within the CURL library may exceed this, + resulting in memory faults/SIGSEGV crashes when passed into select(..) + calls using fd_set macros. + + A good all-round solution to this is to override the default when building + libcurl, by overriding CFLAGS during configure, example + # configure CFLAGS='-DFD_SETSIZE=64 -g -O2' + + +RISC OS +======= + The library can be cross-compiled using gccsdk as follows: + + CC=riscos-gcc AR=riscos-ar RANLIB='riscos-ar -s' ./configure \ + --host=arm-riscos-aof --without-random --disable-shared + make + + where riscos-gcc and riscos-ar are links to the gccsdk tools. + You can then link your program with curl/lib/.libs/libcurl.a + + +AmigaOS +======= + (This section was graciously brought to us by Diego Casorran) + + To build cURL/libcurl on AmigaOS just type 'make amiga' ... + + What you need is: (not tested with others versions) + + GeekGadgets / gcc 2.95.3 (http://www.geekgadgets.org/) + + AmiTCP SDK v4.3 (http://www.aminet.net/comm/tcp/AmiTCP-SDK-4.3.lha) + + Native Developer Kit (http://www.amiga.com/3.9/download/NDK3.9.lha) + + As no ixemul.library is required you will be able to build it for + WarpOS/PowerPC (not tested by me), as well a MorphOS version should be + possible with no problems. + + To enable SSL support, you need a OpenSSL native version (without ixemul), + you can find a precompiled package at http://amiga.sourceforge.net/OpenSSL/ + + +NetWare +======= + To compile curl.nlm / libcurl.nlm you need: + - either any gcc / nlmconv, or CodeWarrior 7 PDK 4 or later. + - gnu make and awk running on the platform you compile on; + native Win32 versions can be downloaded from: + http://www.gknw.net/development/prgtools/ + - recent Novell LibC SDK available from: + http://developer.novell.com/ndk/libc.htm + - or recent Novell CLib SDK available from: + http://developer.novell.com/ndk/clib.htm + - optional recent Novell CLDAP SDK available from: + http://developer.novell.com/ndk/cldap.htm + - optional zlib sources (static or dynamic linking with zlib.imp); + sources with NetWare Makefile can be obtained from: + http://www.gknw.net/mirror/zlib/ + - optional OpenSSL sources (version 0.9.8 or later build with BSD sockets); + you can find precompiled packages at: + http://www.gknw.net/development/ossl/netware/ + for CLIB-based builds OpenSSL 0.9.8h or later is required - earlier versions + don't support building with CLIB BSD sockets. + - optional SSH2 sources (version 0.17 or later); + + Set a search path to your compiler, linker and tools; on Linux make + sure that the var OSTYPE contains the string 'linux'; set the var + NDKBASE to point to the base of your Novell NDK; and then type + 'make netware' from the top source directory; other targets available + are 'netware-ssl', 'netware-ssl-zlib', 'netware-zlib' and 'netware-ares'; + if you need other combinations you can control the build with the + environment variables WITH_SSL, WITH_ZLIB, WITH_ARES, WITH_SSH2, and + ENABLE_IPV6; you can set LINK_STATIC=1 to link curl.nlm statically. + By default LDAP support is enabled, however currently you will need a patch + in order to use the CLDAP NDK with BSD sockets (Novell Bug 300237): + http://www.gknw.net/test/curl/cldap_ndk/ldap_ndk.diff + I found on some Linux systems (RH9) that OS detection didn't work although + a 'set | grep OSTYPE' shows the var present and set; I simply overwrote it + with 'OSTYPE=linux-rh9-gnu' and the detection in the Makefile worked... + Any help in testing appreciated! + Builds automatically created 8 times a day from current git are here: + http://www.gknw.net/mirror/curl/autobuilds/ + the status of these builds can be viewed at the autobuild table: + http://curl.haxx.se/dev/builds.html + + +eCos +==== + curl does not use the eCos build system, so you must first build eCos + separately, then link curl to the resulting eCos library. Here's a sample + configure line to do so on an x86 Linux box targeting x86: + + GCCLIB=`gcc -print-libgcc-file-name` && \ + CFLAGS="-D__ECOS=1 -nostdinc -I$ECOS_INSTALL/include \ + -I`dirname $GCCLIB`/include" \ + LDFLAGS="-nostdlib -Wl,--gc-sections -Wl,-static \ + -L$ECOS_INSTALL/lib -Ttarget.ld -ltarget" \ + ./configure --host=i386 --disable-shared \ + --without-ssl --without-zlib --disable-manual --disable-ldap + + In most cases, eCos users will be using libcurl from within a custom + embedded application. Using the standard 'curl' executable from + within eCos means facing the limitation of the standard eCos C + startup code which does not allow passing arguments in main(). To + run 'curl' from eCos and have it do something useful, you will need + to either modify the eCos startup code to pass in some arguments, or + modify the curl application itself to retrieve its arguments from + some location set by the bootloader or hard-code them. + + Something like the following patch could be used to hard-code some + arguments. The MTAB_ENTRY line mounts a RAM disk as the root filesystem + (without mounting some kind of filesystem, eCos errors out all file + operations which curl does not take to well). The next section synthesizes + some command-line arguments for curl to use, in this case to direct curl + to read further arguments from a file. It then creates that file on the + RAM disk and places within it a URL to download: a file: URL that + just happens to point to the configuration file itself. The results + of running curl in this way is the contents of the configuration file + printed to the console. + +--- src/main.c 19 Jul 2006 19:09:56 -0000 1.363 ++++ src/main.c 24 Jul 2006 21:37:23 -0000 +@@ -4286,11 +4286,31 @@ + } + + ++#ifdef __ECOS ++#include <cyg/fileio/fileio.h> ++MTAB_ENTRY( testfs_mte1, ++ "/", ++ "ramfs", ++ "", ++ 0); ++#endif + + int main(int argc, char *argv[]) + { + int res; + struct Configurable config; ++#ifdef __ECOS ++ char *args[] = {"ecos-curl", "-K", "curlconf.txt"}; ++ FILE *f; ++ argc = sizeof(args)/sizeof(args[0]); ++ argv = args; ++ ++ f = fopen("curlconf.txt", "w"); ++ if (f) { ++ fprintf(f, "--url file:curlconf.txt"); ++ fclose(f); ++ } ++#endif + memset(&config, 0, sizeof(struct Configurable)); + + config.errors = stderr; /* default errors to stderr */ + + +Minix +===== + curl can be compiled on Minix 3 using gcc or ACK (starting with + ver. 3.1.3). Ensure that GNU gawk and bash are both installed and + available in the PATH. + + ACK + --- + Increase the heap sizes of the compiler with the command: + + binsizes xxl + + then configure and compile curl with: + + ./configure CC=cc LD=cc AR=/usr/bin/aal GREP=grep \ + CPPFLAGS='-D_POSIX_SOURCE=1 -I/usr/local/include' + make + chmem =256000 src/curl + + GCC + --- + Make sure gcc is in your PATH with the command: + + export PATH=/usr/gnu/bin:$PATH + + then configure and compile curl with: + + ./configure CC=gcc AR=/usr/gnu/bin/gar GREP=grep + make + chmem =256000 src/curl + + +Symbian OS +========== + The Symbian OS port uses the Symbian build system to compile. From the + packages/Symbian/group/ directory, run: + + bldmake bldfiles + abld build + + to compile and install curl and libcurl using SBSv1. If your Symbian + SDK doesn't include support for P.I.P.S., you will need to contact + your SDK vendor to obtain that first. + + +VxWorks +======== + Build for VxWorks is performed using cross compilation. + That means you build on Windows machine using VxWorks tools and + run the built image on the VxWorks device. + + To build libcurl for VxWorks you need: + + - CYGWIN (free, http://cygwin.com/) + - Wind River Workbench (commercial) + + If you have CYGWIN and Workbench installed on you machine + follow after next steps: + + 1. Open the Command Prompt window and change directory ('cd') + to the libcurl 'lib' folder. + 2. Add CYGWIN 'bin' folder to the PATH environment variable. + For example, type 'set PATH=C:/embedded/cygwin/bin;%PATH%'. + 3. Adjust environment variables defined in 'Environment' section + of the Makefile.vxworks file to point to your software folders. + 4. Build the libcurl by typing 'make -f ./Makefile.vxworks' + + As a result the libcurl.a library should be created in the 'lib' folder. + To clean the build results type 'make -f ./Makefile.vxworks clean'. + + +Android +======= + Method using the static makefile: + - see the build notes in the Android.mk file. + + Method using a configure cross-compile (tested with Android NDK r7c, r8): + - prepare the toolchain of the Android NDK for standalone use; this can + be done by invoking the script: + ./build/tools/make-standalone-toolchain.sh + which creates a usual cross-compile toolchain. Lets assume that you put + this toolchain below /opt then invoke configure with something like: + export PATH=/opt/arm-linux-androideabi-4.4.3/bin:$PATH + ./configure --host=arm-linux-androideabi [more configure options] + make + - if you want to compile directly from our GIT repo you might run into + this issue with older automake stuff: + checking host system type... + Invalid configuration `arm-linux-androideabi': + system `androideabi' not recognized + configure: error: /bin/sh ./config.sub arm-linux-androideabi failed + this issue can be fixed with using more recent versions of config.sub + and config.guess which can be obtained here: + http://git.savannah.gnu.org/gitweb/?p=config.git;a=tree + you need to replace your system-own versions which usually can be + found in your automake folder: + find /usr -name config.sub + + Wrapper for pkg-config + - In order to make proper use of pkg-config so that configure is able to + find all dependencies you should create a wrapper script for pkg-config; + file /opt/arm-linux-androideabi-4.4.3/bin/arm-linux-androideabi-pkg-config: + + #!/bin/sh + SYSROOT=$(dirname ${0%/*})/sysroot + export PKG_CONFIG_DIR= + export PKG_CONFIG_LIBDIR=${SYSROOT}/usr/local/lib/pkgconfig:${SYSROOT}/usr/share/pkgconfig + export PKG_CONFIG_SYSROOT_DIR=${SYSROOT} + exec pkg-config "$@" + + also create a copy or symlink with name arm-unknown-linux-androideabi-pkg-config. + + +CROSS COMPILE +============= + (This section was graciously brought to us by Jim Duey, with additions by + Dan Fandrich) + + Download and unpack the cURL package. + + 'cd' to the new directory. (e.g. cd curl-7.12.3) + + Set environment variables to point to the cross-compile toolchain and call + configure with any options you need. Be sure and specify the '--host' and + '--build' parameters at configuration time. The following script is an + example of cross-compiling for the IBM 405GP PowerPC processor using the + toolchain from MonteVista for Hardhat Linux. + + (begin script) + + #! /bin/sh + + export PATH=$PATH:/opt/hardhat/devkit/ppc/405/bin + export CPPFLAGS="-I/opt/hardhat/devkit/ppc/405/target/usr/include" + export AR=ppc_405-ar + export AS=ppc_405-as + export LD=ppc_405-ld + export RANLIB=ppc_405-ranlib + export CC=ppc_405-gcc + export NM=ppc_405-nm + + ./configure --target=powerpc-hardhat-linux \ + --host=powerpc-hardhat-linux \ + --build=i586-pc-linux-gnu \ + --prefix=/opt/hardhat/devkit/ppc/405/target/usr/local \ + --exec-prefix=/usr/local + + (end script) + + You may also need to provide a parameter like '--with-random=/dev/urandom' + to configure as it cannot detect the presence of a random number + generating device for a target system. The '--prefix' parameter + specifies where cURL will be installed. If 'configure' completes + successfully, do 'make' and 'make install' as usual. + + In some cases, you may be able to simplify the above commands to as + little as: + + ./configure --host=ARCH-OS + + +REDUCING SIZE +============= + There are a number of configure options that can be used to reduce the + size of libcurl for embedded applications where binary size is an + important factor. First, be sure to set the CFLAGS variable when + configuring with any relevant compiler optimization flags to reduce the + size of the binary. For gcc, this would mean at minimum the -Os option, + and potentially the -march=X and -mdynamic-no-pic options as well, e.g. + + ./configure CFLAGS='-Os' ... + + Note that newer compilers often produce smaller code than older versions + due to improved optimization. + + Be sure to specify as many --disable- and --without- flags on the configure + command-line as you can to disable all the libcurl features that you + know your application is not going to need. Besides specifying the + --disable-PROTOCOL flags for all the types of URLs your application + will not use, here are some other flags that can reduce the size of the + library: + + --disable-ares (disables support for the C-ARES DNS library) + --disable-cookies (disables support for HTTP cookies) + --disable-crypto-auth (disables HTTP cryptographic authentication) + --disable-ipv6 (disables support for IPv6) + --disable-manual (disables support for the built-in documentation) + --disable-proxy (disables support for HTTP and SOCKS proxies) + --disable-verbose (eliminates debugging strings and error code strings) + --enable-hidden-symbols (eliminates unneeded symbols in the shared library) + --without-libidn (disables support for the libidn DNS library) + --without-ssl (disables support for SSL/TLS) + --without-zlib (disables support for on-the-fly decompression) + + The GNU compiler and linker have a number of options that can reduce the + size of the libcurl dynamic libraries on some platforms even further. + Specify them by providing appropriate CFLAGS and LDFLAGS variables on the + configure command-line, e.g. + CFLAGS="-Os -ffunction-sections -fdata-sections \ + -fno-unwind-tables -fno-asynchronous-unwind-tables" \ + LDFLAGS="-Wl,-s -Wl,-Bsymbolic -Wl,--gc-sections" + + Be sure also to strip debugging symbols from your binaries after + compiling using 'strip' (or the appropriate variant if cross-compiling). + If space is really tight, you may be able to remove some unneeded + sections of the shared library using the -R option to objcopy (e.g. the + .comment section). + + Using these techniques it is possible to create a basic HTTP-only shared + libcurl library for i386 Linux platforms that is only 106 KiB in size, and + an FTP-only library that is 108 KiB in size (as of libcurl version 7.27.0, + using gcc 4.6.3). + + You may find that statically linking libcurl to your application will + result in a lower total size than dynamically linking. + + Note that the curl test harness can detect the use of some, but not all, of + the --disable statements suggested above. Use will cause tests relying on + those features to fail. The test harness can be manually forced to skip + the relevant tests by specifying certain key words on the runtests.pl + command line. Following is a list of appropriate key words: + + --disable-cookies !cookies + --disable-crypto-auth !HTTP\ Digest\ auth !HTTP\ proxy\ Digest\ auth + --disable-manual !--manual + --disable-proxy !HTTP\ proxy !proxytunnel !SOCKS4 !SOCKS5 + + +PORTS +===== + This is a probably incomplete list of known hardware and operating systems + that curl has been compiled for. If you know a system curl compiles and + runs on, that isn't listed, please let us know! + + - Alpha DEC OSF 4 + - Alpha Digital UNIX v3.2 + - Alpha FreeBSD 4.1, 4.5 + - Alpha Linux 2.2, 2.4 + - Alpha NetBSD 1.5.2 + - Alpha OpenBSD 3.0 + - Alpha OpenVMS V7.1-1H2 + - Alpha Tru64 v5.0 5.1 + - AVR32 Linux + - ARM Android 1.5, 2.1 + - ARM INTEGRITY + - ARM iPhone OS + - Cell Linux + - Cell Cell OS + - HP-PA HP-UX 9.X 10.X 11.X + - HP-PA Linux + - HP3000 MPE/iX + - MicroBlaze uClinux + - MIPS IRIX 6.2, 6.5 + - MIPS Linux + - OS/400 + - Pocket PC/Win CE 3.0 + - Power AIX 3.2.5, 4.2, 4.3.1, 4.3.2, 5.1, 5.2 + - PowerPC Darwin 1.0 + - PowerPC INTEGRITY + - PowerPC Linux + - PowerPC Mac OS 9 + - PowerPC Mac OS X + - SH4 Linux 2.6.X + - SH4 OS21 + - SINIX-Z v5 + - Sparc Linux + - Sparc Solaris 2.4, 2.5, 2.5.1, 2.6, 7, 8, 9, 10 + - Sparc SunOS 4.1.X + - StrongARM (and other ARM) RISC OS 3.1, 4.02 + - StrongARM/ARM7/ARM9 Linux 2.4, 2.6 + - StrongARM NetBSD 1.4.1 + - Symbian OS (P.I.P.S.) 9.x + - TPF + - Ultrix 4.3a + - UNICOS 9.0 + - i386 BeOS + - i386 DOS + - i386 eCos 1.3.1 + - i386 Esix 4.1 + - i386 FreeBSD + - i386 HURD + - i386 Haiku OS + - i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4, 2.6 + - i386 MINIX 3.1 + - i386 NetBSD + - i386 Novell NetWare + - i386 OS/2 + - i386 OpenBSD + - i386 QNX 6 + - i386 SCO unix + - i386 Solaris 2.7 + - i386 Windows 95, 98, ME, NT, 2000, XP, 2003 + - i486 ncr-sysv4.3.03 (NCR MP-RAS) + - ia64 Linux 2.3.99 + - m68k AmigaOS 3 + - m68k Linux + - m68k uClinux + - m68k OpenBSD + - m88k dg-dgux5.4R3.00 + - s390 Linux + - x86_64 Linux + - XScale/PXA250 Linux 2.4 + - Nios II uClinux + +Useful URLs +=========== + +axTLS http://axtls.sourceforge.net/ +c-ares http://c-ares.haxx.se/ +GNU GSS http://www.gnu.org/software/gss/ +GnuTLS http://www.gnu.org/software/gnutls/ +Heimdal http://www.pdc.kth.se/heimdal/ +libidn http://www.gnu.org/software/libidn/ +libssh2 http://www.libssh2.org/ +MIT Kerberos http://web.mit.edu/kerberos/www/dist/ +NSS http://www.mozilla.org/projects/security/pki/nss/ +OpenLDAP http://www.openldap.org/ +OpenSSL http://www.openssl.org/ +PolarSSL http://polarssl.org/ +yassl http://www.yassl.com/ +Zlib http://www.zlib.net/ + +MingW http://www.mingw.org/ +MinGW-w64 http://mingw-w64.sourceforge.net/ +OpenWatcom http://www.openwatcom.org/ diff --git a/docs/INSTALL.cmake b/docs/INSTALL.cmake new file mode 100644 index 000000000..e44f514e5 --- /dev/null +++ b/docs/INSTALL.cmake @@ -0,0 +1,102 @@ + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + + 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 specified 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. + +Current flaws in the curl CMake build +===================================== + + Missing features in the cmake build: + + - Builds libcurl without large file support + - It doesn't build src/hugehelp.c which creates the --manual output + - Can't select which SSL library to build with, only OpenSSL + - Doesn't build with SCP and SFTP support (libssh2) + - Doesn't allow different resolver backends (no c-ares build support) + - No RTMP support built + - Doesn't allow build curl and libcurl debug enabled + - Doesn't allow a custom CA bundle path + - Doesn't allow you to disable specific protocols from the build + - Doesn't properly enable IPv6 support by default + - Doesn't find or use krb4 or GSS + - Rebuilds test files too eagerly, but still can't run the tests + + +Important notice +================== + If you got your curl sources from a distribution tarball, make sure to + delete the generic 'include/curl/curlbuild.h' file that comes with it: + rm -f curl/include/curl/curlbuild.h + + The purpose of this file is to provide reasonable definitions for systems + where autoconfiguration is not available. CMake will create its own + version of this file in its build directory. If the "generic" version + is not deleted, weird build errors may occur on some systems. + +Command Line CMake +================== + A CMake build of curl is similar to the autotools build of curl. It + consists of the following steps after you have unpacked the source. + + 1. Create an out of source build tree parallel to the curl source + tree and change into that directory + + $ mkdir curl-build + $ cd curl-build + + 2. 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 specify the compile, you can set the CC environment + variable prior to running CMake. + + $ cmake ../curl + $ make + + 3. Install to default location: + + $ make install + + (The teste suit does not work with the cmake build) + +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 substitute + 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 directory 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 generate. + diff --git a/docs/INSTALL.devcpp b/docs/INSTALL.devcpp new file mode 100644 index 000000000..46d1836af --- /dev/null +++ b/docs/INSTALL.devcpp @@ -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 +through 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 diff --git a/docs/INTERNALS b/docs/INTERNALS new file mode 100644 index 000000000..d06d62209 --- /dev/null +++ b/docs/INTERNALS @@ -0,0 +1,505 @@ + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + +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 + cyassl 2.0.0 + openldap 2.0 + MIT krb5 lib 1.2.4 + qsossl V5R2M0 + NSS 3.12.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 5.004 + 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 a curl_config-win32.h file in lib directory that is 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 connections. + + A quick roundup on internal function sequences (many of these call + protocol-specific function-pointers): + + Curl_connect - connects to a remote site and does initial connect fluff + This also checks for an existing connection to the requested site and uses + that one if it is possible. + + Curl_do - starts a transfer + Curl_handler::do_it() - transfers data + Curl_done - ends a transfer + + Curl_disconnect - disconnects from a remote site. This is called when the + disconnect is really requested, which doesn't necessarily have to be + exactly after curl_done in case we want to keep the connection open for + a while. + + HTTP(S) + + HTTP 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 and lib/openldap.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 +========== + + The test suite 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, do this: + + 1. Tag the source code accordingly. + + 2. run the 'maketgz' script (using 'make distcheck' will give you a pretty + good view on the status of the current sources). maketgz requires a + version number and creates the 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. + + 3. When that's complete, sign the output files. + + 4. Upload + + 5. Update web site and changelog on site + + 6. Send announcement to the mailing lists + + NOTE: you must 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. diff --git a/docs/KNOWN_BUGS b/docs/KNOWN_BUGS new file mode 100644 index 000000000..d36382740 --- /dev/null +++ b/docs/KNOWN_BUGS @@ -0,0 +1,242 @@ +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! + +80. Curl doesn't recognize certificates in DER format in keychain, but it + works with PEM. + http://curl.haxx.se/bug/view.cgi?id=3439999 + +79. SMTP. When sending data to multiple recipients, curl will abort and return + failure if one of the recipients indicate failure (on the "RCPT TO" + command). Ordinary mail programs would proceed and still send to the ones + that can receive data. This is subject for change in the future. + http://curl.haxx.se/bug/view.cgi?id=3438362 + +78. curl and libcurl don't always signal the client properly when "sending" + zero bytes files - it makes for example the command line client not creating + any file at all. Like when using FTP. + http://curl.haxx.se/bug/view.cgi?id=3438362 + +77. CURLOPT_FORBID_REUSE on a handle prevents NTLM from working since it + "abuses" the underlying connection re-use system and if connections are + forced to close they break the NTLM support. + +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 only works + properly if built with UNICODE defined together with the schannel/winssl + backend. The original problem was mentioned in: + http://curl.haxx.se/mail/lib-2009-10/0024.html + http://curl.haxx.se/bug/view.cgi?id=2944325 + + The schannel version verified to work as mentioned in + http://curl.haxx.se/mail/lib-2012-07/0073.html + +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 + +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: + 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 diff --git a/docs/LICENSE-MIXING b/docs/LICENSE-MIXING new file mode 100644 index 000000000..f596546da --- /dev/null +++ b/docs/LICENSE-MIXING @@ -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/ diff --git a/docs/MAIL-ETIQUETTE b/docs/MAIL-ETIQUETTE new file mode 100644 index 000000000..ae1821a89 --- /dev/null +++ b/docs/MAIL-ETIQUETTE @@ -0,0 +1,228 @@ + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + +MAIL ETIQUETTE + + 1. About the lists + 1.1 Mailing Lists + 1.2 Netiquette + 1.3 Do Not Mail a Single Individual + 1.4 Subscription Required + 1.5 Moderation of new posters + 1.6 Handling trolls and spam + 1.7 How to unsubscribe + + 2. Sending mail + 2.1 Reply or New Mail + 2.2 Reply to the List + 2.3 Use a Sensible Subject + 2.4 Do Not Top-Post + 2.5 HTML is not for mails + 2.6 Quoting + 2.7 Digest + 2.8 Please Tell Us How You Solved The Problem! + +============================================================================== + +1. About the lists + + 1.1 Mailing Lists + + The mailing lists we have are all listed and described at + http://curl.haxx.se/mail/ + + Each mailing list is targeted to a specific set of users and subjects, + please use the one or the ones that suit you the most. + + Each mailing list have hundreds up to thousands of readers, meaning that + each mail sent will be received and read by a very large amount of people. + People from various cultures, regions, religions and continents. + + 1.2 Netiquette + + Netiquette is a common name for how to behave on the internet. Of course, in + each particular group and subculture there will be differences in what is + acceptable and what is considered good manners. + + This document outlines what we in the cURL project considers to be good + etiquette, and primarily this focus on how to behave on and how to use our + mailing lists. + + 1.3 Do Not Mail a Single Individual + + Many people send one question to one person. One person gets many mails, and + there is only one person who can give you a reply. The question may be + something that other people are also wanting to ask. These other people have + no way to read the reply, but to ask the one person the question. The one + person consequently gets overloaded with mail. + + If you really want to contact an individual and perhaps pay for his or her + services, by all means go ahead, but if it's just another curl question, + take it to a suitable list instead. + + 1.4 Subscription Required + + All curl mailing lists require that you are subscribed to allow a mail to go + through to all the subscribers. + + If you post without being subscribed (or from a different mail address than + the one you are subscribed with), your mail will simply be silently + discarded. You have to subscribe first, then post. + + The reason for this unfortunate and strict subscription policy is of course + to stop spam from pestering the lists. + + 1.5 Moderation of new posters + + Several of the curl mailing lists automatically make all posts from new + subscribers require moderation. This means that after you've subscribed and + send your first mail to a list, that mail will not be let through to the + list until a mailing list administrator has verified that it is OK and + permits it to get posted. + + Once a first post has been made that proves the sender is actually talking + about curl-related subjects, the moderation "flag" will be switched off and + future posts will go through without being moderated. + + The reason for this moderation policy is that we do suffer from spammers who + actually subscribe and send spam to our lists. + + 1.6 Handling trolls and spam + + Despite our good intentions and hard work to keep spam off the lists and to + maintain a friendly and positive atmosphere, there will be times when spam + and or trolls get through. + + Troll - "someone who posts inflammatory, extraneous, or off-topic messages + in an online community" + + Spam - "use of electronic messaging systems to send unsolicited bulk + messages" + + No matter what, we NEVER EVER respond to trolls or spammers on the list. If + you believe the list admin should do something particular, contact him/her + off-list. The subject will be taken care of as good as possible to prevent + repeated offences, but responding on the list to such messages never lead to + anything good and only puts the light even more on the offender: which was + the entire purpose of it getting to the list in the first place. + + Don't feed the trolls! + + 1.7 How to unsubscribe + + You unsubscribe the same way you subscribed in the first place. You go to + the page for the particular mailing list you're subscribed to and you enter + your email address and password and press the unsubscribe button. + + Also, this information is included in the headers of every mail that is sent + out to all curl related mailing lists and there's footer in each mail that + links to the "admin" page on which you can unsubscribe and change other + options. + + You NEVER EVER email the mailing list requesting someone else to get you off + the list. + + +2. Sending mail + + 2.1 Reply or New Mail + + Please do not reply to an existing message as a short-cut to post a message + to the lists. + + Many mail programs and web archivers use information within mails to keep + them together as "threads", as collections of posts that discuss a certain + subject. If you don't intend to reply on the same or similar subject, don't + just hit reply on an existing mail and change subject, create a new mail. + + 2.2 Reply to the List + + When replying to a message from the list, make sure that you do "group + reply" or "reply to all", and not just reply to the author of the single + mail you reply to. + + We're actively discouraging replying back to the single person by setting + the Reply-To: field in outgoing mails back to the mailing list address, + making it harder for people to mail the author only by mistake. + + 2.3 Use a Sensible Subject + + Please use a subject of the mail that makes sense and that is related to the + contents of your mail. It makes it a lot easier to find your mail afterwards + and it makes it easier to track mail threads and topics. + + 2.4 Do Not Top-Post + + If you reply to a message, don't use top-posting. Top-posting is when you + write the new text at the top of a mail and you insert the previous quoted + mail conversation below. It forces users to read the mail in a backwards + order to properly understand it. + + This is why top posting is so bad: + + A: Because it messes up the order in which people normally read + text. + Q: Why is top-posting such a bad thing? + A: Top-posting. + Q: What is the most annoying thing in e-mail? + + Apart from the screwed up read order (especially when mixed together in a + thread when someone responds using the mandated bottom-posting style), it + also makes it impossible to quote only parts of the original mail. + + When you reply to a mail. You let the mail client insert the previous mail + quoted. Then you put the cursor on the first line of the mail and you move + down through the mail, deleting all parts of the quotes that don't add + context for your comments. When you want to add a comment you do so, inline, + right after the quotes that relate to your comment. Then you continue + downwards again. + + When most of the quotes have been removed and you've added your own words, + you're done! + + 2.5 HTML is not for mails + + Please switch off those HTML encoded messages. You can mail all those funny + mails to your friends. We speak plain text mails. + + 2.6 Quoting + + Quote as little as possible. Just enough to provide the context you cannot + leave out. A lengthy description can be found here: + + http://www.netmeister.org/news/learn2quote.html + + 2.7 Digest + + We allow subscribers to subscribe to the "digest" version of the mailing + lists. A digest is a collection of mails lumped together in one single mail. + + Should you decide to reply to a mail sent out as a digest, there are two + things you MUST consider if you really really cannot subscribe normally + instead: + + Cut off all mails and chatter that is not related to the mail you want to + reply to. + + Change the subject name to something sensible and related to the subject, + preferably even the actual subject of the single mail you wanted to reply to + + 2.8 Please Tell Us How You Solved The Problem! + + Many people mail questions to the list, people spend some of their time and + make an effort in providing good answers to these questions. + + If you are the one who asks, please consider responding once more in case + one of the hints was what solved your problems. The guys who write answers + feel good to know that they provided a good answer and that you fixed the + problem. Far too often, the person who asked the question is never heard of + again, and we never get to know if he/she is gone because the problem was + solved or perhaps because the problem was unsolvable! + + Getting the solution posted also helps other users that experience the same + problem(s). They get to see (possibly in the web archives) that the + suggested fixes actually has helped at least one person. + diff --git a/docs/MANUAL b/docs/MANUAL new file mode 100644 index 000000000..4ad2e135e --- /dev/null +++ b/docs/MANUAL @@ -0,0 +1,1023 @@ +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 directory listing 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 with a specific name: + + 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! According to the URL specification, HTTP URLs can not contain a user + and password, so that style will not work when using curl via a proxy, even + though curl allows it at other times. When using a proxy, you _must_ use + the -u style for user and password. + + HTTPS + + Probably most commonly used with private certificates, as explained below. + +PROXY + + curl supports both HTTP and SOCKS proxy servers, with optional authentication. + It does not have special support for FTP proxy servers since there are no + standards for those, but it can still be made to work with many of them. You + can also use both HTTP and SOCKS proxies to transfer files to and from FTP + servers. + + Get an ftp file using an HTTP proxy named my-proxy that uses port 888: + + curl -x my-proxy:888 ftp://ftp.leachsite.com/README + + Get a file from an 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 supports that offer further proxy + control. + + Most FTP proxy servers are set up to appear as a normal FTP server from the + client's perspective, with special commands to select the remote FTP server. + curl supports the -u, -Q and --ftp-account options that can be used to + set up transfers through many FTP proxies. For example, a file can be + uploaded to a remote FTP server using a Blue Coat FTP proxy with the + options: + + curl -u "Remote-FTP-Username@remote.ftp.server Proxy-Username:Remote-Pass" \ + --ftp-account Proxy-Password --upload-file local-file \ + ftp://my-ftp.proxy.server:21/remote/upload/path/ + + See the manual for your FTP proxy to determine the form it expects to set up + transfers, and curl's -v option to see exactly what curl is sending. + +RANGES + + HTTP 1.1 introduced byte-ranges. 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 at the remote + site 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 + replace 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 + use the default type 'application/octet-stream'. + + 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 + + An HTTP request has the option to include information about which address + referred it to the 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 + + An 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 transferred. 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 doesn't allow + incoming connections. + + curl ftp.download.com + + If the server, for example, is behind a firewall that doesn't allow connections + on ports other 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 IP number and port (as parameters to the + PORT command). + + 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, which newer versions + of OpenSSL etc use, 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: + + In Netscape, you start with hitting the 'Security' menu button. + + 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] + + In Firefox, select Options, then Advanced, then the Encryption tab, + View Certificates. This opens the Certificate Manager, where you can + Export. Be sure to select PEM for the Save as type. + + In Internet Explorer, select Internet Options, then the Content tab, then + Certificates. Then you can Export, and depending on the format you may + need to convert to PEM. + + In Chrome, select Settings, then Show Advanced Settings. Under HTTPS/SSL + select Manage Certificates. + +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 allows 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 + advise 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 how 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 to (using the -n/--netrc and + --netrc-optional options). This is not restricted to just FTP, + so 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 + available. + + 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 an 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. + +METALINK + + Curl supports Metalink (both version 3 and 4 (RFC 5854) are supported), a way + to list multiple URIs and hashes for a file. Curl will make use of the mirrors + listed within for failover if there are errors (such as the file or server not + being available). It will also verify the hash of the file after the download + completes. The Metalink file itself is downloaded and processed in memory and + not stored in the local file system. + + Example to use a remote Metalink file: + + curl --metalink http://www.example.com/example.metalink + + To use a Metalink file in the local file system, use FILE protocol (file://): + + curl --metalink file://example.metalink + + Please note that if FILE protocol is disabled, there is no way to use a local + Metalink file at the time of this writing. Also note that if --metalink and + --include are used together, --include will be ignored. This is because including + headers in the response will break Metalink parser and if the headers are included + in the file described in Metalink file, hash check will fail. + +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. diff --git a/docs/Makefile.am b/docs/Makefile.am new file mode 100644 index 000000000..0701ba823 --- /dev/null +++ b/docs/Makefile.am @@ -0,0 +1,60 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2012, 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. +# +########################################################################### + +AUTOMAKE_OPTIONS = foreign no-dependencies + +man_MANS = curl.1 curl-config.1 mk-ca-bundle.1 +GENHTMLPAGES = curl.html curl-config.html mk-ca-bundle.html +PDFPAGES = curl.pdf curl-config.pdf mk-ca-bundle.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 \ + MAIL-ETIQUETTE HTTP-COOKIES + +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 $@") + diff --git a/docs/README.cmake b/docs/README.cmake new file mode 100644 index 000000000..084c1de6d --- /dev/null +++ b/docs/README.cmake @@ -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. diff --git a/docs/README.netware b/docs/README.netware new file mode 100644 index 000000000..41da2e8dc --- /dev/null +++ b/docs/README.netware @@ -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. + + diff --git a/docs/README.win32 b/docs/README.win32 new file mode 100644 index 000000000..cfd45dd25 --- /dev/null +++ b/docs/README.win32 @@ -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. + + diff --git a/docs/RESOURCES b/docs/RESOURCES new file mode 100644 index 000000000..760e75975 --- /dev/null +++ b/docs/RESOURCES @@ -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 diff --git a/docs/SSLCERTS b/docs/SSLCERTS new file mode 100644 index 000000000..0d1414cea --- /dev/null +++ b/docs/SSLCERTS @@ -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 + + diff --git a/docs/THANKS b/docs/THANKS new file mode 100644 index 000000000..46965163b --- /dev/null +++ b/docs/THANKS @@ -0,0 +1,999 @@ + 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 +Aaron Orenstein +Adam D. Moss +Adam Light +Adam Piggott +Adam Tkac +Adrian Schuur +Adriano Meirelles +Ajit Dhumale +Akos Pasztory +Alan Pinstein +Albert Chin +Albert Chin-A-Young +Albert Choy +Ale Vesely +Alejandro Alvarez +Aleksandar Milivojevic +Alessandro Ghedini +Alessandro Vesely +Alex Bligh +Alex Fishman +Alex Gruz +Alex Neblett +Alex Suykov +Alex Vinnik +Alex aka WindEagle +Alexander Beedie +Alexander Kourakos +Alexander Krasnostavsky +Alexander Lazic +Alexander Zhuravlev +Alexey Borzov +Alexey Pesternikov +Alexey Simak +Alexey Zakhlestin +Alexis Carvalho +Alfred Gebert +Allen Pulsifer +Amol Pattekar +Amr Shahin +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 +Andrei Cipu +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 +Anthony G. Basile +Antoine Calando +Anton Bychkov +Anton Kalmykov +Anton Malov +Anton Yabchinskiy +Arkadiusz Miskiewicz +Armel Asselin +Arnaud Compan +Arnaud Ebalard +Arthur Murray +Arve Knudsen +Ates Goral +Augustus Saunders +Avery Fay +Axel Tillequin +Balint Szilakszi +Bart Whiteley +Bas Mevissen +Ben Darnell +Ben Greear +Ben Madsen +Ben Noordhuis +Ben Van Hof +Ben Winslow +Benbuck Nason +Benjamin Gerard +Benjamin Johnson +Bernard Leak +Bernhard Reutner-Fischer +Bertrand Demiddelaer +Bill Egert +Bill Hoffman +Bjoern Sikora +Bjorn Augustsson +Bjorn Reese +Björn Stenberg +Blaise Potard +Bob Richmond +Bob Schader +Bogdan Nicula +Brad Burdick +Brad Hards +Brad King +Bradford Bruce +Brandon Wang +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 +Cedric Deltheil +Chad Monroe +Chandrakant Bagul +Charles Kerr +Chih-Chung Chang +Chris "Bob Bob" +Chris Combes +Chris Conroy +Chris Deidun +Chris Flerackers +Chris Gaukroger +Chris Maltby +Chris Mumford +Chris Smowton +Christian Grothoff +Christian Hagele +Christian Hägele +Christian Krause +Christian Kurz +Christian Robottom Reis +Christian Schmitz +Christian Vogt +Christophe Demory +Christophe Legry +Christopher Conroy +Christopher Palow +Christopher R. Palmer +Christopher Stone +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 +Cristian Rodriguez +Cristian RodrÃguez +Curt Bogmine +Cyrill Osterwalder +Dag Ekengren +Dagobert Michelsen +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 Johnson +Daniel Mentz +Daniel Steinberg +Daniel Stenberg +Daniel Theron +Daniel at touchtunes +Darryl House +Darshan Mody +Dave Dribin +Dave Halbakken +Dave Hamilton +Dave May +Dave Reisner +Dave Vasilevsky +David Bau +David Binderman +David Blaikie +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 +Dominique Leuenberger +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 +Edward Sheldrake +Eelco Dolstra +Eetu Ojanen +Ellis Pritchard +Emanuele Bovisio +Emil Romanus +Emiliano Ida +Enrico Scholz +Enrik Berkhan +Eric Cooper +Eric Hu +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 Hiernaux +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 +Frank Van Uffelen +FrantiÅ¡ek KuÄera +Fred Machado +Fred New +Fred Noz +Frederic Lepied +Gabriel Kuri +Gabriel Sjoberg +Garrett Holmstrom +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 +Ghennadi Procopciuc +Giancarlo Formicuccia +Giaslas Georgios +Gil Weber +Gilad +Gilbert Ramirez Jr. +Gilles Blanc +Gisle Vanem +Giuseppe Attardi +Giuseppe D'Ambrosio +Glen Nakamura +Glen Scott +Gokhan Sengun +Grant Erickson +Greg Hewgill +Greg Morse +Greg Onufer +Greg Zavertnik +Grigory Entin +Guenole Bescon +Guenter Knauf +Guido Berhoerster +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 +Henry Ludemann +Herve Amblard +Hidemoto Nakada +Ho-chi Chen +Hoi-Ho Chan +Hongli Lai +Howard Chu +Hzhijun +Ian D Allen +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 Ehrhardt +Jan Koen Annot +Jan Kunder +Jan Schaumann +Jan Van Boghout +Jared Lundell +Jari Sundell +Jason Glasgow +Jason Liu +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 Connelly +Jeff Johnson +Jeff Lawson +Jeff Phillips +Jeff Pohlmeyer +Jeff Weber +Jeffrey Pohlmeyer +Jeremy Friesner +Jerome Muffat-Meridol +Jerome Vouillon +Jerry Wu +Jes Badwal +Jesper Jensen +Jesse Noller +Jie He +Jim Drash +Jim Freeman +Jim Hollinger +Jim Meyering +Jocelyn Jaubert +Joe Halpin +Joe Malicki +Joe Mason +Joel Chen +Jofell Gallardo +Johan Anderson +Johan Nilsson +Johan van Selst +Johannes Bauer +John Bradshaw +John Crow +John Dennis +John E. Malmberg +John Janssen +John Joseph Bachir +John Kelly +John Lask +John Lightsey +John Marino +John McGowan +John P. McCaskey +John Suprock +John Wilkinson +John-Mark Bell +Johnny Luong +Jon Grubbs +Jon Nelson +Jon Sargeant +Jon Travis +Jon Turner +Jonas Forsman +Jonas Schnelli +Jonatan Lander +Jonathan Hseu +Jonathan Nieder +Jongki Suwandi +Jose Kahan +Josef Wolf +Josh Kapell +Joshua Kwan +Josue Andrade Gomes +Juan Barreto +Juan F. Codagnone +Juan Ignacio Hervás +Judson Bishop +Juergen Wilke +Jukka Pihl +Julian Noble +Julian Taylor +Julien Chaffraix +Julien Royer +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 M +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 Buitinck +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 +Lijo Antony +Linas Vepstas +Ling Thio +Linus Nielsen Feltzing +Lisa Xu +Liza Alenchery +Loic Dachary +Loren Kirkby +Luca Altea +Luca Alteas +Lucas Adamski +Lukasz Czekierda +Luke Amery +Luke Call +Luong Dinh Dung +Maciej Karpiuk +Maciej W. Rozycki +Mamoru Tasaka +Mandy Wu +Manfred Schwarb +Manuel Massing +Marc Boucher +Marc Hoersken +Marc Kleine-Budde +Marcel Raad +Marcel Roelofs +Marcelo Juchem +Marcin Adamski +Marcin Konicki +Marco G. Salvagno +Marco Maggi +Marcus Sundberg +Marcus Webster +Mario Schroeder +Mark Brand +Mark Butler +Mark Davies +Mark Eichin +Mark Incley +Mark Karpeles +Mark Lentczner +Mark Salisbury +Mark Snelling +Mark Tully +Markus Duft +Markus Koetter +Markus Moeller +Markus Oberhumer +Martijn Koster +Martin C. Martin +Martin Drasar +Martin Hager +Martin Hedenfalk +Martin Lemke +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 +Matteo Rocco +Matthew Blain +Matthew Clarke +Matthias Bolte +Maurice Barnum +Mauro Iorio +Max Katsev +Maxim Ivanov +Maxim Perenesenko +Maxim Prohorov +Maxime Larocque +Mehmet Bozkurt +Mekonikum +Mettgut Jamalla +Michael Benedict +Michael Calmer +Michael Cronenworth +Michael Curtis +Michael Day +Michael Goffioul +Michael Jahn +Michael Jerris +Michael Mealling +Michael Mueller +Michael Smith +Michael Stillwell +Michael Wallner +Michal Bonino +Michal Gorny +Michal Kowalczyk +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 Chandran +Naveen Noel +Neil Bowers +Neil Dunbar +Neil Spring +Nic Roets +Nicholas Maniscalco +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 +Nikos Mavrogiannopoulos +Ning Dong +Nir Soffer +Nis Jorgensen +Nodak Sodak +Norbert Frese +Norbert Novotny +Ofer +Olaf Flebbe +Olaf Stueben +Olaf Stüben +Olivier Berger +Oren Tirosh +Ori Avtalion +Oscar Koeroo +Oscar Norlander +P R Schaffner +Paolo Piacentini +Pascal Terjan +Pasha Kuznetsov +Pat Ray +Patrice Guerin +Patrick Bihan-Faou +Patrick Monnerat +Patrick Scott +Patrick Smith +Patrik Thunstrom +Pau Garcia i Quiles +Paul Harrington +Paul Howarth +Paul Marquis +Paul Moore +Paul Nolan +Paul Querna +Pavel Cenek +Pavel Orehov +Pavel Raiskup +Pawel A. Gajda +Pawel Kierski +Pedro Larroy +Pedro Neves +Pete Su +Peter Bray +Peter Forret +Peter Heuchert +Peter Hjalmarsson +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 Craig +Philip Gladstone +Philip Langdale +Philippe Hameau +Philippe Raoult +Philippe Vaucher +Pierre +Pierre Brico +Pierre Chapuis +Pierre Joye +Pierre Ynard +Pooyan McSporran +Pramod Sharma +Puneet Pawaia +Quagmire +Quanah Gibson-Mount +Quinn Slack +Rafa Muyo +Rafael Sagula +Rainer Canavan +Rainer Koenig +Rajesh Naganathan +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 +Reza Arbab +Ricardo Cadime +Rich Gray +Rich Rauenzahn +Richard Archer +Richard Atterer +Richard Bramante +Richard Clayton +Richard Cooper +Richard Gorton +Richard Prescott +Richard Silverman +Rick Jones +Rick Richardson +Rob Crittenden +Rob Jones +Rob Stanzel +Rob Ward +Robert A. Monat +Robert B. Harris +Robert D. Young +Robert Foreman +Robert Iakobashvili +Robert Olson +Robert Schumann +Robert Weaver +Robin Cornelius +Robin Johnson +Robin Kay +Robson Braga Araujo +Rodney Simmons +Rodrigo Silva +Roland Blom +Roland Krikava +Roland Zimmermann +Rolland Dudemaine +Roman Koifman +Roman Mamedov +Ron Zapp +Rosimildo da Silva +Roy Shan +Rune Kleveland +Ruslan Gazizov +Rutger Hofman +Ryan Chan +Ryan Nelson +Ryan Schmidt +S. Moonesamy +Salvador Dávila +Salvatore Sorrentino +Sam Listopad +Sampo Kellomaki +Samuel DÃaz GarcÃa +Samuel Listopad +Samuel Thibault +Sander Gates +Sandor Feldi +Santhana Todatry +Saqib Ali +Sara Golemon +Saul good +Scott Bailey +Scott Barrett +Scott Cantor +Scott Davis +Scott McCreary +Sebastian Rasmussen +Sebastien Willemijns +Senthil Raja Velu +Sergei Nikulov +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 H Truong +Steve Holme +Steve Lhomme +Steve Little +Steve Marx +Steve Oliphant +Steve Roskowski +Steven Bazyl +Steven G. Johnson +Steven M. Schweda +Steven Parkes +Stoned Elipot +Sven Anders +Sven Neuhaus +Sven Wegener +Sébastien Willemijns +T. Bharath +T. Yamada +Taneli Vahakangas +Tanguy Fautre +Tatsuhiro Tsujikawa +Temprimus +Thomas J. Moore +Thomas Klausner +Thomas L. Shinnick +Thomas Lopatic +Thomas Schwinge +Thomas Tonino +Tim Ansell +Tim Baker +Tim Bartley +Tim Chen +Tim Costello +Tim Harder +Tim Heckman +Tim Newsome +Tim Sneddon +Tinus van den Berg +Tobias Rundström +Toby Peterson +Todd A Ouska +Todd Kulesza +Todd Ouska +Todd Vierling +Tom Benoist +Tom Donovan +Tom Lee +Tom Mattison +Tom Moers +Tom Mueller +Tom Regner +Tom Wright +Tom Zerucha +Tomas Mlcoch +Tomas Pospisek +Tomas Szepe +Tomasz Lacki +Tommie Gannert +Tommy Tam +Ton Voon +Toni Moreno +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 +Vincent Torri +Vlad Grachov +Vlad Ureche +Vladimir Grishchenko +Vladimir Lazarenko +Vojtech Janota +Vojtech Minarik +Vsevolod Novikov +Walter J. Mack +Ward Willats +Wayne Haigh +Werner Koch +Wesley Laxton +Wesley Miaw +Wez Furlong +Wilfredo Sanchez +Wojciech Zwiefka +Wu Yongzheng +Xavier Bouchoux +Yang Tse +Yarram Sunil +Yehoshua Hershberg +Yukihiro Kawada +Yuriy Sosov +Yves Lejeune +Zmey Petroff +Zvi Har'El +nk +swalkaus at yahoo.com +tommink[at]post.pl diff --git a/docs/TODO b/docs/TODO new file mode 100644 index 000000000..30c0a64ab --- /dev/null +++ b/docs/TODO @@ -0,0 +1,662 @@ + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + + 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.2 More data sharing + 1.3 struct lifreq + 1.4 signal-based resolver timeouts + 1.5 get rid of PATH_MAX + 1.6 progress callback without doubles + 1.7 Happy Eyeball dual stack connect + + 2. libcurl - multi interface + 2.1 More non-blocking + 2.2 Remove easy interface internally + 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.9 improve configure --with-ssl + 7.10 Support DANE + + 8. GnuTLS + 8.1 SSL engine stuff + 8.3 check connection + + 9. SMTP + 9.1 Specify the preferred authentication mechanism + 9.2 Initial response + 9.3 Pipelining + + 10. POP3 + 10.1 auth= in URLs + + 11. IMAP + 11.1 SASL based authentication mechanisms + + 12. LDAP + 12.1 SASL based authentication mechanisms + + 13. Other protocols + + 14. New protocols + 14.1 RSYNC + + 15. SASL + 15.1 Other authentication mechanisms + + 16. Client + 16.1 sync + 16.2 glob posts + 16.3 prevent file overwriting + 16.4 simultaneous parallel transfers + 16.5 provide formpost headers + 16.6 url-specific options + 16.7 warning when setting an option + 16.8 IPv6 addresses with globbing + + 17. Build + 17.1 roffit + + 18. Test suite + 18.1 SSL tunnel + 18.2 nicer lacking perl message + 18.3 more protocols supported + 18.4 more platforms supported + + 19. Next SONAME bump + 19.1 http-style HEAD output for ftp + 19.2 combine error codes + 19.3 extend CURLOPT_SOCKOPTFUNCTION prototype + + 20. Next major release + 20.1 cleanup return codes + 20.2 remove obsolete defines + 20.3 size_t + 20.4 remove several functions + 20.5 remove CURLOPT_FAILONERROR + 20.6 remove CURLOPT_DNS_USE_GLOBAL_CACHE + 20.7 remove progress meter from libcurl + 20.8 remove 'curl_httppost' from public + 20.9 have form functions use CURL handle argument + 20.10 Add CURLOPT_MAIL_CLIENT option + +============================================================================== + +1. libcurl + +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. + +1.6 progress callback without doubles + + The progress callback was introduced way back in the days and the choice to + use doubles in the arguments was possibly good at the time. Today the doubles + only confuse users and make the amounts less precise. We should introduce + another progress callback option that take precedence over the old one and + have both co-exist for a forseeable time until we can remove the double-using + one. + +1.7 Happy Eyeball dual stack connect + + In order to make alternative technologies not suffer when transitioning, like + when introducing IPv6 as an alternative to IPv4 and there are more than one + option existing simultaneously there are reasons to reconsider internal + choices. + + To make libcurl do blazing fast IPv6 in a dual-stack configuration, this needs + to be addressed: + + http://tools.ietf.org/html/rfc6555 + + +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 + - 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.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.9 improve configure --with-ssl + + make the configure --with-ssl option first check for OpenSSL, then GnuTLS, + then NSS... + +7.10 Support DANE + + DNS-Based Authentication of Named Entities (DANE) is a way to provide SSL + keys and certs over DNS using DNSSEC as an alternative to the CA model. + http://www.rfc-editor.org/rfc/rfc6698.txt + + +8. GnuTLS + +8.1 SSL engine stuff + + Is this even possible? + +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. + + +9. SMTP + +9.1 Specify the preferred authentication mechanism + + Add the ability to specify the preferred authentication mechanism or a list + of mechanisms that should be used. Not only that, but the order that is + returned by the server during the EHLO response should be honored by curl. + +9.2 Initial response + + Add the ability for the user to specify whether the initial response is + included in the AUTH command. Some email servers, such as Microsoft + Exchange, can work with either whilst others need to have the initial + response sent separately: + + http://curl.haxx.se/mail/lib-2012-03/0114.html + +9.3 Pipelining + + Add support for pipelining emails. + +10. POP3 + +10.1 auth= in URLs + + Being able to specify the preferred authentication mechanism in the URL as + per RFC2384. + +11. IMAP + +11.1 SASL based authentication mechanisms + + Curl currently sends usernames and passwords as clear text whilst SASL based + authentication mechanisms can be more secure. As such, support should be + added to support these authentication mechanisms. + +12. LDAP + +12.1 SASL based authentication mechansims + + Currently the LDAP module only supports ldap_simple_bind_s() in order to bind + to an LDAP server. However, this function sends username and password details + using the simple authentication mechanism (as clear text). However, it should + be possible to use ldap_bind_s() instead specifing the security context + information ourselves. + +13. Other protocols + +14. New protocols + +14.1 RSYNC + + There's no RFC for the protocol or an URI/URL format. An implementation + should most probably use an existing rsync library, such as librsync. + +15. SASL + +15.1 Other authentication mechanisms + + Add support for gssapi to SMTP and POP3. + +16. Client + +16.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. + +16.2 glob posts + + Globbing support for -d and -F, as in 'curl -d "name=foo[0-9]" URL'. + This is easily scripted though. + +16.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. + +16.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 + +16.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...) + +16.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. + +16.7 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. + +16.8 IPv6 addresses with globbing + + Currently the command line client needs to get url globbing disabled (with + -g) for it to support IPv6 numerical addresses. This is a rather silly flaw + that should be corrected. It probably involves a smarter detection of the + '[' and ']' letters. + +17. Build + +17.1 roffit + + Consider extending 'roffit' to produce decent ASCII output, and use that + instead of (g)nroff when building src/hugehelp.c + +18. Test suite + +18.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 + +18.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. + +18.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). + +18.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. + +19. Next SONAME bump + +19.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 + +19.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 + +19.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. + +20. Next major release + +20.1 cleanup return codes + + curl_easy_cleanup() returns void, but curl_multi_cleanup() returns a + CURLMcode. These should be changed to be the same. + +20.2 remove obsolete defines + + remove obsolete defines from curl/curl.h + +20.3 size_t + + make several functions use size_t instead of int in their APIs + +20.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 + +20.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. + +20.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". + +20.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. + +20.8 remove 'curl_httppost' from public + + curl_formadd() was made to fill in a public struct, but the fact that the + struct is public is never really used by application for their own advantage + but instead often restricts how the form functions can or can't be modified. + + Changing them to return a private handle will benefit the implementation and + allow us much greater freedoms while still maintining a solid API and ABI. + +20.9 have form functions use CURL handle argument + + curl_formadd() and curl_formget() both currently have no CURL handle + argument, but both can use a callback that is set in the easy handle, and + thus curl_formget() with callback cannot function without first having + curl_easy_perform() (or similar) called - which is hard to grasp and a design + mistake. + +20.10 Add CURLOPT_MAIL_CLIENT option + + Rather than use the URL to specify the mail client string to present in the + HELO and EHLO commands, libcurl should support a new CURLOPT specifically for + specifing this data as the URL is non-standard and to be honest a bit of a + hack ;-) + + Please see the following thread for more information: + http://curl.haxx.se/mail/lib-2012-05/0178.html +
\ No newline at end of file diff --git a/docs/TheArtOfHttpScripting b/docs/TheArtOfHttpScripting new file mode 100644 index 000000000..b0dab5ff2 --- /dev/null +++ b/docs/TheArtOfHttpScripting @@ -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 diff --git a/docs/VERSIONS b/docs/VERSIONS new file mode 100644 index 000000000..0670089bd --- /dev/null +++ b/docs/VERSIONS @@ -0,0 +1,60 @@ + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + +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] + + Where + X is main version number + Y is release number + Z is patch 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 main version number will get bumped when *really* big, world colliding + changes are made. The release number is bumped when changes are performed or + things/features are added. The patch number is bumped when the changes are + mere bugfixes. + + 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. + + 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 number fields are always represented using two digits + (eight bits each). 1.2 would appear as "0x010200" while version 9.11.7 + appears as "0x090b07". + + This 6-digit hexadecimal number 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. diff --git a/docs/curl-config.1 b/docs/curl-config.1 new file mode 100644 index 000000000..14a9d2ba8 --- /dev/null +++ b/docs/curl-config.1 @@ -0,0 +1,98 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2012, 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` -o example example.c `curl-config --libs` +.SH "SEE ALSO" +.BR curl (1) diff --git a/docs/curl.1 b/docs/curl.1 new file mode 100644 index 000000000..6808d07e5 --- /dev/null +++ b/docs/curl.1 @@ -0,0 +1,1944 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2012, 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 1 "27 July 2012" "Curl 7.27.0" "Curl Manual" +.SH NAME +curl \- transfer a URL +.SH SYNOPSIS +.B curl [options] +.I [URL...] +.SH DESCRIPTION +.B curl +is a tool to transfer data from or to a server, using one of the supported +protocols (DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, +LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET and TFTP). The +command is designed to work without user interaction. + +curl offers a busload of useful tricks like proxy support, user +authentication, FTP upload, HTTP post, SSL connections, cookies, file transfer +resume, Metalink, and more. As you will see below, the number of features will +make your head spin! + +curl is powered by libcurl for all transfer-related features. See +.BR libcurl (3) +for details. +.SH URL +The URL syntax is protocol-dependent. You'll find a detailed description in +RFC 3986. + +You can specify multiple URLs or parts of URLs by writing part sets within +braces as in: + + http://site.{one,two,three}.com + +or you can get sequences of alphanumeric series by using [] as in: + + ftp://ftp.numericals.com/file[1-100].txt + ftp://ftp.numericals.com/file[001-100].txt (with leading zeros) + ftp://ftp.letters.com/file[a-z].txt + +Nested sequences are not supported, but you can use several ones next to each +other: + + http://any.org/archive[1996-1999]/vol[1-4]/part{a,b,c}.html + +You can specify any amount of URLs on the command line. They will be fetched +in a sequential manner in the specified order. + +You can specify a step counter for the ranges to get every Nth number or +letter: + + http://www.numericals.com/file[1-100:10].txt + http://www.letters.com/file[a-z:2].txt + +If you specify URL without protocol:// prefix, curl will attempt to guess what +protocol you might want. It will then default to HTTP but try other protocols +based on often-used host name prefixes. For example, for host names starting +with "ftp." curl will assume you want to speak FTP. + +curl will do its best to use what you pass to it as a URL. It is not trying to +validate it as a syntactically correct URL by any means but is instead +\fBvery\fP liberal with what it accepts. + +curl will attempt to re-use connections for multiple file transfers, so that +getting many files from the same server will not do multiple connects / +handshakes. This improves speed. Of course this is only done on files +specified on a single command line and cannot be used between separate curl +invokes. +.SH "PROGRESS METER" +curl normally displays a progress meter during operations, indicating the +amount of transferred data, transfer speeds and estimated time left, etc. + +curl displays this data to the terminal by default, so if you invoke curl to +do an operation and it is about to write data to the terminal, it +\fIdisables\fP the progress meter as otherwise it would mess up the output +mixing progress meter and response data. + +If you want a progress meter for HTTP POST or PUT requests, you need to +redirect the response output to a file, using shell redirect (>), -o [file] or +similar. + +It is not the same case for FTP upload as that operation does not spit out +any response data to the terminal. + +If you prefer a progress "bar" instead of the regular meter, \fI-#\fP is your +friend. +.SH OPTIONS +In general, all boolean options are enabled with --\fBoption\fP and yet again +disabled with --\fBno-\fPoption. That is, you use the exact same option name +but prefix it with "no-". However, in this list we mostly only list and show +the --option version of them. (This concept with --no options was added in +7.19.0. Previously most options were toggled on/off on repeated use of the +same command line option.) +.IP "-#, --progress-bar" +Make curl display progress as a simple progress bar instead of the standard, +more informational, meter. +.IP "-0, --http1.0" +(HTTP) Forces curl to issue its requests using HTTP 1.0 instead of using its +internally preferred: HTTP 1.1. +.IP "-1, --tlsv1" +(SSL) +Forces curl to use TLS version 1 when negotiating with a remote TLS server. +.IP "-2, --sslv2" +(SSL) +Forces curl to use SSL version 2 when negotiating with a remote SSL server. +.IP "-3, --sslv3" +(SSL) +Forces curl to use SSL version 3 when negotiating with a remote SSL server. +.IP "-4, --ipv4" +If curl is capable of resolving an address to multiple IP versions (which it +is if it is IPv6-capable), this option tells curl to resolve names to IPv4 +addresses only. +.IP "-6, --ipv6" +If curl is capable of resolving an address to multiple IP versions (which it +is if it is IPv6-capable), this option tells curl to resolve names to IPv6 +addresses only. +.IP "-a, --append" +(FTP/SFTP) When used in an upload, this will tell curl to append to the target +file instead of overwriting it. If the file doesn't exist, it will be created. +Note that this flag is ignored by some SSH servers (including OpenSSH). +.IP "-A, --user-agent <agent string>" +(HTTP) Specify the User-Agent string to send to the HTTP server. Some badly +done CGIs fail if this field isn't set to "Mozilla/4.0". To encode blanks in +the string, surround the string with single quote marks. This can also be set +with the \fI-H, --header\fP option of course. + +If this option is used several times, the last one will be used. +.IP "--anyauth" +(HTTP) Tells curl to figure out authentication method by itself, and use the +most secure one the remote site claims to support. This is done by first +doing a request and checking the response-headers, thus possibly inducing an +extra network round-trip. This is used instead of setting a specific +authentication method, which you can do with \fI--basic\fP, \fI--digest\fP, +\fI--ntlm\fP, and \fI--negotiate\fP. + +Note that using --anyauth is not recommended if you do uploads from stdin, +since it may require data to be sent twice and then the client must be able to +rewind. If the need should arise when uploading from stdin, the upload +operation will fail. +.IP "-b, --cookie <name=data>" +(HTTP) +Pass the data to the HTTP server as a cookie. It is supposedly the +data previously received from the server in a "Set-Cookie:" line. +The data should be in the format "NAME1=VALUE1; NAME2=VALUE2". + +If no '=' symbol is used in the line, it is treated as a filename to use to +read previously stored cookie lines from, which should be used in this session +if they match. Using this method also activates the "cookie parser" which will +make curl record incoming cookies too, which may be handy if you're using this +in combination with the \fI-L, --location\fP option. The file format of the +file to read cookies from should be plain HTTP headers or the Netscape/Mozilla +cookie file format. + +\fBNOTE\fP that the file specified with \fI-b, --cookie\fP is only used as +input. No cookies will be stored in the file. To store cookies, use the +\fI-c, --cookie-jar\fP option or you could even save the HTTP headers to a file +using \fI-D, --dump-header\fP! + +If this option is used several times, the last one will be used. +.IP "-B, --use-ascii" +(FTP/LDAP) Enable ASCII transfer. For FTP, this can also be +enforced by using an URL that ends with ";type=A". This option causes data +sent to stdout to be in text mode for win32 systems. +.IP "--basic" +(HTTP) Tells curl to use HTTP Basic authentication. This is the default and +this option is usually pointless, unless you use it to override a previously +set option that sets a different authentication method (such as \fI--ntlm\fP, +\fI--digest\fP, or \fI--negotiate\fP). +.IP "-c, --cookie-jar <file name>" +(HTTP) Specify to which file you want curl to write all cookies after a +completed operation. Curl writes all cookies previously read from a specified +file as well as all cookies received from remote server(s). If no cookies are +known, no file will be written. The file will be written using the Netscape +cookie file format. If you set the file name to a single dash, "-", the +cookies will be written to stdout. + +This command line option will activate the cookie engine that makes curl +record and use cookies. Another way to activate it is to use the \fI-b, +--cookie\fP option. + +If the cookie jar can't be created or written to, the whole curl operation +won't fail or even report an error clearly. Using -v will get a warning +displayed, but that is the only visible feedback you get about this possibly +lethal situation. + +If this option is used several times, the last specified file name will be +used. +.IP "-C, --continue-at <offset>" +Continue/Resume a previous file transfer at the given offset. The given offset +is the exact number of bytes that will be skipped, counting from the beginning +of the source file before it is transferred to the destination. If used with +uploads, the FTP server command SIZE will not be used by curl. + +Use "-C -" to tell curl to automatically find out where/how to resume the +transfer. It then uses the given output/input files to figure that out. + +If this option is used several times, the last one will be used. +.IP "--ciphers <list of ciphers>" +(SSL) Specifies which ciphers to use in the connection. The list of ciphers +must specify valid ciphers. Read up on SSL cipher list details on this URL: +\fIhttp://www.openssl.org/docs/apps/ciphers.html\fP + +NSS ciphers are done differently than OpenSSL and GnuTLS. The full list of NSS +ciphers is in the NSSCipherSuite entry at this URL: +\fIhttp://git.fedorahosted.org/cgit/mod_nss.git/plain/docs/mod_nss.html#Directives\fP + +If this option is used several times, the last one will be used. +.IP "--compressed" +(HTTP) Request a compressed response using one of the algorithms curl +supports, and save the uncompressed document. If this option is used and the +server sends an unsupported encoding, curl will report an error. +.IP "--connect-timeout <seconds>" +Maximum time in seconds that you allow the connection to the server to take. +This only limits the connection phase, once curl has connected this option is +of no more use. See also the \fI-m, --max-time\fP option. + +If this option is used several times, the last one will be used. +.IP "--create-dirs" +When used in conjunction with the \fI-o\fP option, curl will create the +necessary local directory hierarchy as needed. This option creates the dirs +mentioned with the \fI-o\fP option, nothing else. If the \fI-o\fP file name +uses no dir or if the dirs it mentions already exist, no dir will be created. + +To create remote directories when using FTP or SFTP, try +\fI--ftp-create-dirs\fP. +.IP "--crlf" +(FTP) Convert LF to CRLF in upload. Useful for MVS (OS/390). +.IP "--crlfile <file>" +(HTTPS/FTPS) Provide a file using PEM format with a Certificate Revocation +List that may specify peer certificates that are to be considered revoked. + +If this option is used several times, the last one will be used. + +(Added in 7.19.7) +.IP "-d, --data <data>" +(HTTP) Sends the specified data in a POST request to the HTTP server, in the +same way that a browser does when a user has filled in an HTML form and +presses the submit button. This will cause curl to pass the data to the server +using the content-type application/x-www-form-urlencoded. Compare to +\fI-F, --form\fP. + +\fI-d, --data\fP is the same as \fI--data-ascii\fP. To post data purely binary, +you should instead use the \fI--data-binary\fP option. To URL-encode the value +of a form field you may use \fI--data-urlencode\fP. + +If any of these options is used more than once on the same command line, the +data pieces specified will be merged together with a separating +&-symbol. Thus, using '-d name=daniel -d skill=lousy' would generate a post +chunk that looks like \&'name=daniel&skill=lousy'. + +If you start the data with the letter @, the rest should be a file name to +read the data from, or - if you want curl to read the data from stdin. The +contents of the file must already be URL-encoded. Multiple files can also be +specified. Posting data from a file named 'foobar' would thus be done with +\fI--data @foobar\fP. +.IP "-D, --dump-header <file>" +Write the protocol headers to the specified file. + +This option is handy to use when you want to store the headers that an HTTP +site sends to you. Cookies from the headers could then be read in a second +curl invocation by using the \fI-b, --cookie\fP option! The +\fI-c, --cookie-jar\fP option is however a better way to store cookies. + +When used in FTP, the FTP server response lines are considered being "headers" +and thus are saved there. + +If this option is used several times, the last one will be used. + +.IP "--data-ascii <data>" +See \fI-d, --data\fP. +.IP "--data-binary <data>" +(HTTP) This posts data exactly as specified with no extra processing +whatsoever. + +If you start the data with the letter @, the rest should be a filename. Data +is posted in a similar manner as \fI--data-ascii\fP does, except that newlines +are preserved and conversions are never done. + +If this option is used several times, the ones following the first will append +data as described in \fI-d, --data\fP. +.IP "--data-urlencode <data>" +(HTTP) This posts data, similar to the other --data options with the exception +that this performs URL-encoding. (Added in 7.18.0) + +To be CGI-compliant, the <data> part should begin with a \fIname\fP followed +by a separator and a content specification. The <data> part can be passed to +curl using one of the following syntaxes: +.RS +.IP "content" +This will make curl URL-encode the content and pass that on. Just be careful +so that the content doesn't contain any = or @ symbols, as that will then make +the syntax match one of the other cases below! +.IP "=content" +This will make curl URL-encode the content and pass that on. The preceding = +symbol is not included in the data. +.IP "name=content" +This will make curl URL-encode the content part and pass that on. Note that +the name part is expected to be URL-encoded already. +.IP "@filename" +This will make curl load data from the given file (including any newlines), +URL-encode that data and pass it on in the POST. +.IP "name@filename" +This will make curl load data from the given file (including any newlines), +URL-encode that data and pass it on in the POST. The name part gets an equal +sign appended, resulting in \fIname=urlencoded-file-content\fP. Note that the +name is expected to be URL-encoded already. +.RE +.IP "--delegation LEVEL" +Set \fILEVEL\fP to tell the server what it is allowed to delegate when it +comes to user credentials. Used with GSS/kerberos. +.RS +.IP "none" +Don't allow any delegation. +.IP "policy" +Delegates if and only if the OK-AS-DELEGATE flag is set in the Kerberos +service ticket, which is a matter of realm policy. +.IP "always" +Unconditionally allow the server to delegate. +.RE +.IP "--digest" +(HTTP) Enables HTTP Digest authentication. This is an authentication scheme +that prevents the password from being sent over the wire in clear text. Use +this in combination with the normal \fI-u, --user\fP option to set user name +and password. See also \fI--ntlm\fP, \fI--negotiate\fP and \fI--anyauth\fP for +related options. + +If this option is used several times, only the first one is used. +.IP "--disable-eprt" +(FTP) Tell curl to disable the use of the EPRT and LPRT commands when doing +active FTP transfers. Curl will normally always first attempt to use EPRT, +then LPRT before using PORT, but with this option, it will use PORT right +away. EPRT and LPRT are extensions to the original FTP protocol, and may not +work on all servers, but they enable more functionality in a better way than +the traditional PORT command. + +\fB--eprt\fP can be used to explicitly enable EPRT again and \fB--no-eprt\fP +is an alias for \fB--disable-eprt\fP. + +Disabling EPRT only changes the active behavior. If you want to switch to +passive mode you need to not use \fI-P, --ftp-port\fP or force it with +\fI--ftp-pasv\fP. +.IP "--disable-epsv" +(FTP) Tell curl to disable the use of the EPSV command when doing passive FTP +transfers. Curl will normally always first attempt to use EPSV before PASV, +but with this option, it will not try using EPSV. + +\fB--epsv\fP can be used to explicitly enable EPSV again and \fB--no-epsv\fP +is an alias for \fB--disable-epsv\fP. + +Disabling EPSV only changes the passive behavior. If you want to switch to +active mode you need to use \fI-P, --ftp-port\fP. +.IP "-e, --referer <URL>" +(HTTP) Sends the "Referer Page" information to the HTTP server. This can also +be set with the \fI-H, --header\fP flag of course. When used with +\fI-L, --location\fP you can append ";auto" to the --referer URL to make curl +automatically set the previous URL when it follows a Location: header. The +\&";auto" string can be used alone, even if you don't set an initial --referer. + +If this option is used several times, the last one will be used. +.IP "-E, --cert <certificate[:password]>" +(SSL) Tells curl to use the specified client certificate file when getting a +file with HTTPS, FTPS or another SSL-based protocol. The certificate must be +in PEM format. If the optional password isn't specified, it will be queried +for on the terminal. Note that this option assumes a \&"certificate" file that +is the private key and the private certificate concatenated! See \fI--cert\fP +and \fI--key\fP to specify them independently. + +If curl is built against the NSS SSL library then this option can tell +curl the nickname of the certificate to use within the NSS database defined +by the environment variable SSL_DIR (or by default /etc/pki/nssdb). If the +NSS PEM PKCS#11 module (libnsspem.so) is available then PEM files may be +loaded. If you want to use a file from the current directory, please precede +it with "./" prefix, in order to avoid confusion with a nickname. + +If this option is used several times, the last one will be used. +.IP "--engine <name>" +Select the OpenSSL crypto engine to use for cipher +operations. Use \fI--engine list\fP to print a list of build-time supported +engines. Note that not all (or none) of the engines may be available at +run-time. +.IP "--environment" +(RISC OS ONLY) Sets a range of environment variables, using the names the +\fI-w\fP option supports, to allow easier extraction of useful information +after having run curl. +.IP "--egd-file <file>" +(SSL) Specify the path name to the Entropy Gathering Daemon socket. The socket +is used to seed the random engine for SSL connections. See also the +\fI--random-file\fP option. +.IP "--cert-type <type>" +(SSL) Tells curl what certificate type the provided certificate is in. PEM, +DER and ENG are recognized types. If not specified, PEM is assumed. + +If this option is used several times, the last one will be used. +.IP "--cacert <CA certificate>" +(SSL) Tells curl to use the specified certificate file to verify the peer. The +file may contain multiple CA certificates. The certificate(s) must be in PEM +format. Normally curl is built to use a default file for this, so this option +is typically used to alter that default file. + +curl recognizes the environment variable named 'CURL_CA_BUNDLE' if it is +set, and uses the given path as a path to a CA cert bundle. This option +overrides that variable. + +The windows version of curl will automatically look for a CA certs file named +\'curl-ca-bundle.crt\', either in the same directory as curl.exe, or in the +Current Working Directory, or in any folder along your PATH. + +If curl is built against the NSS SSL library then this option tells +curl the nickname of the CA certificate to use within the NSS database +defined by the environment variable SSL_DIR (or by default /etc/pki/nssdb). +If the NSS PEM PKCS#11 module (libnsspem.so) is available then PEM files +may be loaded. + +If this option is used several times, the last one will be used. +.IP "--capath <CA certificate directory>" +(SSL) Tells curl to use the specified certificate directory to verify the +peer. Multiple paths can be provided by separating them with ":" (e.g. +\&"path1:path2:path3"). The certificates must be in PEM format, and if curl is +built against OpenSSL, the directory must have been processed using the +c_rehash utility supplied with OpenSSL. Using \fI--capath\fP can allow +OpenSSL-powered curl to make SSL-connections much more efficiently than using +\fI--cacert\fP if the \fI--cacert\fP file contains many CA certificates. + +If this option is set, the default capath value will be ignored, and if it is +used several times, the last one will be used. +.IP "-f, --fail" +(HTTP) Fail silently (no output at all) on server errors. This is mostly done +to better enable scripts etc to better deal with failed attempts. In +normal cases when an HTTP server fails to deliver a document, it returns an +HTML document stating so (which often also describes why and more). This flag +will prevent curl from outputting that and return error 22. + +This method is not fail-safe and there are occasions where non-successful +response codes will slip through, especially when authentication is involved +(response codes 401 and 407). +.IP "-F, --form <name=content>" +(HTTP) This lets curl emulate a filled-in form in which a user has pressed the +submit button. This causes curl to POST data using the Content-Type +multipart/form-data according to RFC 2388. This enables uploading of binary +files etc. To force the 'content' part to be a file, prefix the file name +with an @ sign. To just get the content part from a file, prefix the file name +with the symbol <. The difference between @ and < is then that @ makes a file +get attached in the post as a file upload, while the < makes a text field and +just get the contents for that text field from a file. + +Example, to send your password file to the server, where +\&'password' is the name of the form-field to which /etc/passwd will be the +input: + +\fBcurl\fP -F password=@/etc/passwd www.mypasswords.com + +To read content from stdin instead of a file, use - as the filename. This goes +for both @ and < constructs. + +You can also tell curl what Content-Type to use by using 'type=', in a manner +similar to: + +\fBcurl\fP -F "web=@index.html;type=text/html" url.com + +or + +\fBcurl\fP -F "name=daniel;type=text/foo" url.com + +You can also explicitly change the name field of a file upload part by setting +filename=, like this: + +\fBcurl\fP -F "file=@localfile;filename=nameinpost" url.com + +See further examples and details in the MANUAL. + +This option can be used multiple times. +.IP "--ftp-account [data]" +(FTP) When an FTP server asks for "account data" after user name and password +has been provided, this data is sent off using the ACCT command. (Added in +7.13.0) + +If this option is used several times, the last one will be used. +.IP "--ftp-alternative-to-user <command>" +(FTP) If authenticating with the USER and PASS commands fails, send this +command. When connecting to Tumbleweed's Secure Transport server over FTPS +using a client certificate, using "SITE AUTH" will tell the server to retrieve +the username from the certificate. (Added in 7.15.5) +.IP "--ftp-create-dirs" +(FTP/SFTP) When an FTP or SFTP URL/operation uses a path that doesn't +currently exist on the server, the standard behavior of curl is to +fail. Using this option, curl will instead attempt to create missing +directories. +.IP "--ftp-method [method]" +(FTP) Control what method curl should use to reach a file on an FTP(S) +server. The method argument should be one of the following alternatives: +.RS +.IP multicwd +curl does a single CWD operation for each path part in the given URL. For deep +hierarchies this means very many commands. This is how RFC 1738 says it should +be done. This is the default but the slowest behavior. +.IP nocwd +curl does no CWD at all. curl will do SIZE, RETR, STOR etc and give a full +path to the server for all these commands. This is the fastest behavior. +.IP singlecwd +curl does one CWD with the full target directory and then operates on the file +\&"normally" (like in the multicwd case). This is somewhat more standards +compliant than 'nocwd' but without the full penalty of 'multicwd'. +.RE +(Added in 7.15.1) +.IP "--ftp-pasv" +(FTP) Use passive mode for the data connection. Passive is the internal default +behavior, but using this option can be used to override a previous +\fI-P/-ftp-port\fP option. (Added in 7.11.0) + +If this option is used several times, only the first one is used. Undoing an +enforced passive really isn't doable but you must then instead enforce the +correct \fI-P, --ftp-port\fP again. + +Passive mode means that curl will try the EPSV command first and then PASV, +unless \fI--disable-epsv\fP is used. +.IP "--ftp-skip-pasv-ip" +(FTP) Tell curl to not use the IP address the server suggests in its response +to curl's PASV command when curl connects the data connection. Instead curl +will re-use the same IP address it already uses for the control +connection. (Added in 7.14.2) + +This option has no effect if PORT, EPRT or EPSV is used instead of PASV. +.IP "--ftp-pret" +(FTP) Tell curl to send a PRET command before PASV (and EPSV). Certain +FTP servers, mainly drftpd, require this non-standard command for +directory listings as well as up and downloads in PASV mode. +(Added in 7.20.x) +.IP "--ftp-ssl-ccc" +(FTP) Use CCC (Clear Command Channel) +Shuts down the SSL/TLS layer after authenticating. The rest of the +control channel communication will be unencrypted. This allows +NAT routers to follow the FTP transaction. The default mode is +passive. See \fI--ftp-ssl-ccc-mode\fP for other modes. +(Added in 7.16.1) +.IP "--ftp-ssl-ccc-mode [active/passive]" +(FTP) Use CCC (Clear Command Channel) +Sets the CCC mode. The passive mode will not initiate the shutdown, but +instead wait for the server to do it, and will not reply to the +shutdown from the server. The active mode initiates the shutdown and +waits for a reply from the server. +(Added in 7.16.2) +.IP "--ftp-ssl-control" +(FTP) Require SSL/TLS for the FTP login, clear for transfer. Allows secure +authentication, but non-encrypted data transfers for efficiency. Fails the +transfer if the server doesn't support SSL/TLS. (Added in 7.16.0) +that can still be used but will be removed in a future version. +.IP "--form-string <name=string>" +(HTTP) Similar to \fI--form\fP except that the value string for the named +parameter is used literally. Leading \&'@' and \&'<' characters, and the +\&';type=' string in the value have no special meaning. Use this in preference +to \fI--form\fP if there's any possibility that the string value may +accidentally trigger the \&'@' or \&'<' features of \fI--form\fP. +.IP "-g, --globoff" +This option switches off the "URL globbing parser". When you set this option, +you can specify URLs that contain the letters {}[] without having them being +interpreted by curl itself. Note that these letters are not normal legal URL +contents but they should be encoded according to the URI standard. +.IP "-G, --get" +When used, this option will make all data specified with \fI-d, --data\fP or +\fI--data-binary\fP to be used in an HTTP GET request instead of the POST +request that otherwise would be used. The data will be appended to the URL +with a '?' separator. + +If used in combination with -I, the POST data will instead be appended to the +URL with a HEAD request. + +If this option is used several times, only the first one is used. This is +because undoing a GET doesn't make sense, but you should then instead enforce +the alternative method you prefer. +.IP "-H, --header <header>" +(HTTP) Extra header to use when getting a web page. You may specify any number +of extra headers. Note that if you should add a custom header that has the +same name as one of the internal ones curl would use, your externally set +header will be used instead of the internal one. This allows you to make even +trickier stuff than curl would normally do. You should not replace internally +set headers without knowing perfectly well what you're doing. Remove an +internal header by giving a replacement without content on the right side of +the colon, as in: -H \&"Host:". If you send the custom header with no-value +then its header must be terminated with a semicolon, such as \-H +\&"X-Custom-Header;" to send "X-Custom-Header:". + +curl will make sure that each header you add/replace is sent with the proper +end-of-line marker, you should thus \fBnot\fP add that as a part of the header +content: do not add newlines or carriage returns, they will only mess things up +for you. + +See also the \fI-A, --user-agent\fP and \fI-e, --referer\fP options. + +This option can be used multiple times to add/replace/remove multiple headers. +.IP "--hostpubmd5 <md5>" +(SCP/SFTP) Pass a string containing 32 hexadecimal digits. The string should +be the 128 bit MD5 checksum of the remote host's public key, curl will refuse +the connection with the host unless the md5sums match. (Added in 7.17.1) +.IP "--ignore-content-length" +(HTTP) +Ignore the Content-Length header. This is particularly useful for servers +running Apache 1.x, which will report incorrect Content-Length for files +larger than 2 gigabytes. +.IP "-i, --include" +(HTTP) Include the HTTP-header in the output. The HTTP-header includes things +like server-name, date of the document, HTTP-version and more... +.IP "-I, --head" +(HTTP/FTP/FILE) +Fetch the HTTP-header only! HTTP-servers feature the command HEAD +which this uses to get nothing but the header of a document. When used +on an FTP or FILE file, curl displays the file size and last modification +time only. +.IP "--interface <name>" +Perform an operation using a specified interface. You can enter interface +name, IP address or host name. An example could look like: + + curl --interface eth0:1 http://www.netscape.com/ + +If this option is used several times, the last one will be used. +.IP "-j, --junk-session-cookies" +(HTTP) When curl is told to read cookies from a given file, this option will +make it discard all "session cookies". This will basically have the same effect +as if a new session is started. Typical browsers always discard session +cookies when they're closed down. +.IP "-J, --remote-header-name" +(HTTP) This option tells the \fI-O, --remote-name\fP option to use the +server-specified Content-Disposition filename instead of extracting a filename +from the URL. +.IP "-k, --insecure" +(SSL) This option explicitly allows curl to perform "insecure" SSL connections +and transfers. All SSL connections are attempted to be made secure by using +the CA certificate bundle installed by default. This makes all connections +considered "insecure" fail unless \fI-k, --insecure\fP is used. + +See this online resource for further details: +\fBhttp://curl.haxx.se/docs/sslcerts.html\fP +.IP "-K, --config <config file>" +Specify which config file to read curl arguments from. The config file is a +text file in which command line arguments can be written which then will be +used as if they were written on the actual command line. Options and their +parameters must be specified on the same config file line, separated by +whitespace, colon, the equals sign or any combination thereof (however, +the preferred separator is the equals sign). If the parameter is to contain +whitespace, the parameter must be enclosed within quotes. Within double +quotes, the following escape sequences are available: \\\\, \\", \\t, \\n, +\\r and \\v. A backslash preceding any other letter is ignored. If the +first column of a config line is a '#' character, the rest of the line will be +treated as a comment. Only write one option per physical line in the config +file. + +Specify the filename to -K, --config as '-' to make curl read the file from +stdin. + +Note that to be able to specify a URL in the config file, you need to specify +it using the \fI--url\fP option, and not by simply writing the URL on its own +line. So, it could look similar to this: + +url = "http://curl.haxx.se/docs/" + +Long option names can optionally be given in the config file without the +initial double dashes. + +When curl is invoked, it always (unless \fI-q\fP is used) checks for a default +config file and uses it if found. The default config file is checked for in +the following places in this order: + +1) curl tries to find the "home dir": It first checks for the CURL_HOME and +then the HOME environment variables. Failing that, it uses getpwuid() on +UNIX-like systems (which returns the home dir given the current user in your +system). On Windows, it then checks for the APPDATA variable, or as a last +resort the '%USERPROFILE%\\Application Data'. + +2) On windows, if there is no _curlrc file in the home dir, it checks for one +in the same dir the curl executable is placed. On UNIX-like systems, it will +simply try to load .curlrc from the determined home dir. + +.nf +# --- Example file --- +# this is a comment +url = "curl.haxx.se" +output = "curlhere.html" +user-agent = "superagent/1.0" + +# and fetch another URL too +url = "curl.haxx.se/docs/manpage.html" +-O +referer = "http://nowhereatall.com/" +# --- End of example file --- +.fi + +This option can be used multiple times to load multiple config files. +.IP "--keepalive-time <seconds>" +This option sets the time a connection needs to remain idle before sending +keepalive probes and the time between individual keepalive probes. It is +currently effective on operating systems offering the TCP_KEEPIDLE and +TCP_KEEPINTVL socket options (meaning Linux, recent AIX, HP-UX and more). This +option has no effect if \fI--no-keepalive\fP is used. (Added in 7.18.0) + +If this option is used several times, the last one will be used. If +unspecified, the option defaults to 60 seconds. +.IP "--key <key>" +(SSL/SSH) Private key file name. Allows you to provide your private key in this +separate file. + +If this option is used several times, the last one will be used. +.IP "--key-type <type>" +(SSL) Private key file type. Specify which type your \fI--key\fP provided +private key is. DER, PEM, and ENG are supported. If not specified, PEM is +assumed. + +If this option is used several times, the last one will be used. +.IP "--krb <level>" +(FTP) Enable Kerberos authentication and use. The level must be entered and +should be one of 'clear', 'safe', 'confidential', or 'private'. Should you use +a level that is not one of these, 'private' will instead be used. + +This option requires a library built with kerberos4 or GSSAPI +(GSS-Negotiate) support. This is not very common. Use \fI-V, --version\fP to +see if your curl supports it. + +If this option is used several times, the last one will be used. +.IP "-l, --list-only" +(FTP) +When listing an FTP directory, this switch forces a name-only view. +Especially useful if you want to machine-parse the contents of an FTP +directory since the normal directory view doesn't use a standard look +or format. + +This option causes an FTP NLST command to be sent. Some FTP servers +list only files in their response to NLST; they do not include +subdirectories and symbolic links. + +.IP "-L, --location" +(HTTP/HTTPS) If the server reports that the requested page has moved to a +different location (indicated with a Location: header and a 3XX response code), +this option will make curl redo the request on the new place. If used together +with \fI-i, --include\fP or \fI-I, --head\fP, headers from all requested pages +will be shown. When authentication is used, curl only sends its credentials to +the initial host. If a redirect takes curl to a different host, it won't be +able to intercept the user+password. See also \fI--location-trusted\fP on how +to change this. You can limit the amount of redirects to follow by using the +\fI--max-redirs\fP option. + +When curl follows a redirect and the request is not a plain GET (for example +POST or PUT), it will do the following request with a GET if the HTTP response +was 301, 302, or 303. If the response code was any other 3xx code, curl will +re-send the following request using the same unmodified method. +.IP "--libcurl <file>" +Append this option to any ordinary curl command line, and you will get a +libcurl-using C source code written to the file that does the equivalent +of what your command-line operation does! + +If this option is used several times, the last given file name will be +used. (Added in 7.16.1) +.IP "--limit-rate <speed>" +Specify the maximum transfer rate you want curl to use. This feature is useful +if you have a limited pipe and you'd like your transfer not to use your entire +bandwidth. + +The given speed is measured in bytes/second, unless a suffix is appended. +Appending 'k' or 'K' will count the number as kilobytes, 'm' or M' makes it +megabytes, while 'g' or 'G' makes it gigabytes. Examples: 200K, 3m and 1G. + +The given rate is the average speed counted during the entire transfer. It +means that curl might use higher transfer speeds in short bursts, but over +time it uses no more than the given rate. + +If you also use the \fI-Y, --speed-limit\fP option, that option will take +precedence and might cripple the rate-limiting slightly, to help keeping the +speed-limit logic working. + +If this option is used several times, the last one will be used. +.IP "--local-port <num>[-num]" +Set a preferred number or range of local port numbers to use for the +connection(s). Note that port numbers by nature are a scarce resource that +will be busy at times so setting this range to something too narrow might +cause unnecessary connection setup failures. (Added in 7.15.2) +.IP "--location-trusted" +(HTTP/HTTPS) Like \fI-L, --location\fP, but will allow sending the name + +password to all hosts that the site may redirect to. This may or may not +introduce a security breach if the site redirects you to a site to which +you'll send your authentication info (which is plaintext in the case of HTTP +Basic authentication). +.IP "-m, --max-time <seconds>" +Maximum time in seconds that you allow the whole operation to take. This is +useful for preventing your batch jobs from hanging for hours due to slow +networks or links going down. See also the \fI--connect-timeout\fP option. + +If this option is used several times, the last one will be used. +.IP "--mail-auth <address>" +(SMTP) Specify a single address. This will be used to specify the +authentication address (identity) of a submitted message that is being relayed +to another server. + +(Added in 7.25.0) +.IP "--mail-from <address>" +(SMTP) Specify a single address that the given mail should get sent from. + +(Added in 7.20.0) +.IP "--max-filesize <bytes>" +Specify the maximum size (in bytes) of a file to download. If the file +requested is larger than this value, the transfer will not start and curl will +return with exit code 63. + +\fBNOTE:\fP The file size is not always known prior to download, and for such +files this option has no effect even if the file transfer ends up being larger +than this given limit. This concerns both FTP and HTTP transfers. +.IP "--mail-rcpt <address>" +(SMTP) Specify a single address that the given mail should get sent to. This +option can be used multiple times to specify many recipients. + +(Added in 7.20.0) +.IP "--max-redirs <num>" +Set maximum number of redirection-followings allowed. If \fI-L, --location\fP +is used, this option can be used to prevent curl from following redirections +\&"in absurdum". By default, the limit is set to 50 redirections. Set this +option to -1 to make it limitless. + +If this option is used several times, the last one will be used. +.IP "--metalink" +This option can tell curl to parse and process a given URI as Metalink file +(both version 3 and 4 (RFC 5854) are supported) and make use of the mirrors +listed within for failover if there are errors (such as the file or server not +being available). It will also verify the hash of the file after the download +completes. The Metalink file itself is downloaded and processed in memory and +not stored in the local file system. + +Example to use a remote Metalink file: + +\fBcurl\fP --metalink http://www.example.com/example.metalink + +To use a Metalink file in the local file system, use FILE protocol +(file://): + +\fBcurl\fP --metalink file://example.metalink + +Please note that if FILE protocol is disabled, there is no way to use +a local Metalink file at the time of this writing. Also note that if +\fI--metalink\fP and \fI--include\fP are used together, \fI--include\fP will be +ignored. This is because including headers in the response will break +Metalink parser and if the headers are included in the file described +in Metalink file, hash check will fail. + +(Added in 7.27.0, if built against the libmetalink library.) +.IP "-n, --netrc" +Makes curl scan the \fI.netrc\fP (\fI_netrc\fP on Windows) file in the user's +home directory for login name and password. This is typically used for FTP on +UNIX. If used with HTTP, curl will enable user authentication. See +.BR netrc(4) +or +.BR ftp(1) +for details on the file format. Curl will not complain if that file +doesn't have the right permissions (it should not be either world- or +group-readable). The environment variable "HOME" is used to find the home +directory. + +A quick and very simple example of how to setup a \fI.netrc\fP to allow curl +to FTP to the machine host.domain.com with user name \&'myself' and password +\&'secret' should look similar to: + +.B "machine host.domain.com login myself password secret" +.IP "-N, --no-buffer" +Disables the buffering of the output stream. In normal work situations, curl +will use a standard buffered output stream that will have the effect that it +will output the data in chunks, not necessarily exactly when the data arrives. +Using this option will disable that buffering. + +Note that this is the negated option name documented. You can thus use +\fI--buffer\fP to enforce the buffering. +.IP "--netrc-file" +This option is similar to \fI--netrc\fP, except that you provide the path +(absolute or relative) to the netrc file that Curl should use. +You can only specify one netrc file per invocation. If several +\fI--netrc-file\fP options are provided, only the \fBlast one\fP will be used. +(Added in 7.21.5) + +This option overrides any use of \fI--netrc\fP as they are mutually exclusive. +It will also abide by \fI--netrc-optional\fP if specified. + +.IP "--netrc-optional" +Very similar to \fI--netrc\fP, but this option makes the .netrc usage +\fBoptional\fP and not mandatory as the \fI--netrc\fP option does. + +.IP "--negotiate" +(HTTP) Enables GSS-Negotiate authentication. The GSS-Negotiate method was +designed by Microsoft and is used in their web applications. It is primarily +meant as a support for Kerberos5 authentication but may be also used along +with another authentication method. For more information see IETF draft +draft-brezak-spnego-http-04.txt. + +If you want to enable Negotiate for your proxy authentication, then use +\fI--proxy-negotiate\fP. + +This option requires a library built with GSSAPI support. This is +not very common. Use \fI-V, --version\fP to see if your version supports +GSS-Negotiate. + +When using this option, you must also provide a fake \fI-u, --user\fP option to +activate the authentication code properly. Sending a '-u :' is enough as the +user name and password from the \fI-u\fP option aren't actually used. + +If this option is used several times, only the first one is used. +.IP "--no-keepalive" +Disables the use of keepalive messages on the TCP connection, as by default +curl enables them. + +Note that this is the negated option name documented. You can thus use +\fI--keepalive\fP to enforce keepalive. +.IP "--no-sessionid" +(SSL) Disable curl's use of SSL session-ID caching. By default all transfers +are done using the cache. Note that while nothing should ever get hurt by +attempting to reuse SSL session-IDs, there seem to be broken SSL +implementations in the wild that may require you to disable this in order for +you to succeed. (Added in 7.16.0) + +Note that this is the negated option name documented. You can thus use +\fI--sessionid\fP to enforce session-ID caching. +.IP "--noproxy <no-proxy-list>" +Comma-separated list of hosts which do not use a proxy, if one is specified. +The only wildcard is a single * character, which matches all hosts, and +effectively disables the proxy. Each name in this list is matched as either +a domain which contains the hostname, or the hostname itself. For example, +local.com would match local.com, local.com:80, and www.local.com, but not +www.notlocal.com. (Added in 7.19.4). +.IP "--ntlm" +(HTTP) Enables NTLM authentication. The NTLM authentication method was +designed by Microsoft and is used by IIS web servers. It is a proprietary +protocol, reverse-engineered by clever people and implemented in curl based +on their efforts. This kind of behavior should not be endorsed, you should +encourage everyone who uses NTLM to switch to a public and documented +authentication method instead, such as Digest. + +If you want to enable NTLM for your proxy authentication, then use +\fI--proxy-ntlm\fP. + +This option requires a library built with SSL support. Use +\fI-V, --version\fP to see if your curl supports NTLM. + +If this option is used several times, only the first one is used. +.IP "-o, --output <file>" +Write output to <file> instead of stdout. If you are using {} or [] to fetch +multiple documents, you can use '#' followed by a number in the <file> +specifier. That variable will be replaced with the current string for the URL +being fetched. Like in: + + curl http://{one,two}.site.com -o "file_#1.txt" + +or use several variables like: + + curl http://{site,host}.host[1-5].com -o "#1_#2" + +You may use this option as many times as the number of URLs you have. + +See also the \fI--create-dirs\fP option to create the local directories +dynamically. Specifying the output as '-' (a single dash) will force the +output to be done to stdout. +.IP "-O, --remote-name" +Write output to a local file named like the remote file we get. (Only the file +part of the remote file is used, the path is cut off.) + +The remote file name to use for saving is extracted from the given URL, +nothing else. + +Consequentially, the file will be saved in the current working directory. If +you want the file saved in a different directory, make sure you change current +working directory before you invoke curl with the \fB-O, --remote-name\fP flag! + +You may use this option as many times as the number of URLs you have. +.IP "-p, --proxytunnel" +When an HTTP proxy is used (\fI-x, --proxy\fP), this option will cause non-HTTP +protocols to attempt to tunnel through the proxy instead of merely using it to +do HTTP-like operations. The tunnel approach is made with the HTTP proxy +CONNECT request and requires that the proxy allows direct connect to the +remote port number curl wants to tunnel through to. +.IP "-P, --ftp-port <address>" +(FTP) Reverses the default initiator/listener roles when connecting with +FTP. This switch makes curl use active mode. In practice, curl then tells the +server to connect back to the client's specified address and port, while +passive mode asks the server to setup an IP address and port for it to connect +to. <address> should be one of: +.RS +.IP interface +i.e "eth0" to specify which interface's IP address you want to use (Unix only) +.IP "IP address" +i.e "192.168.10.1" to specify the exact IP address +.IP "host name" +i.e "my.host.domain" to specify the machine +.IP "-" +make curl pick the same IP address that is already used for the control +connection +.RE + +If this option is used several times, the last one will be used. Disable the +use of PORT with \fI--ftp-pasv\fP. Disable the attempt to use the EPRT command +instead of PORT by using \fI--disable-eprt\fP. EPRT is really PORT++. + +Starting in 7.19.5, you can append \&":[start]-[end]\&" to the right of the +address, to tell curl what TCP port range to use. That means you specify a +port range, from a lower to a higher number. A single number works as well, +but do note that it increases the risk of failure since the port may not be +available. +.IP "--pass <phrase>" +(SSL/SSH) Passphrase for the private key + +If this option is used several times, the last one will be used. +.IP "--post301" +(HTTP) Tells curl to respect RFC 2616/10.3.2 and not convert POST requests +into GET requests when following a 301 redirection. The non-RFC behaviour is +ubiquitous in web browsers, so curl does the conversion by default to maintain +consistency. However, a server may require a POST to remain a POST after such +a redirection. This option is meaningful only when using \fI-L, --location\fP +(Added in 7.17.1) +.IP "--post302" +(HTTP) Tells curl to respect RFC 2616/10.3.2 and not convert POST requests +into GET requests when following a 302 redirection. The non-RFC behaviour is +ubiquitous in web browsers, so curl does the conversion by default to maintain +consistency. However, a server may require a POST to remain a POST after such +a redirection. This option is meaningful only when using \fI-L, --location\fP +(Added in 7.19.1) +.IP "--proto <protocols>" +Tells curl to use the listed protocols for its initial retrieval. Protocols +are evaluated left to right, are comma separated, and are each a protocol +name or 'all', optionally prefixed by zero or more modifiers. Available +modifiers are: +.RS +.TP 3 +.B + +Permit this protocol in addition to protocols already permitted (this is +the default if no modifier is used). +.TP +.B - +Deny this protocol, removing it from the list of protocols already permitted. +.TP +.B = +Permit only this protocol (ignoring the list already permitted), though +subject to later modification by subsequent entries in the comma separated +list. +.RE +.IP +For example: +.RS +.TP 15 +.B --proto -ftps +uses the default protocols, but disables ftps +.TP +.B --proto -all,https,+http +only enables http and https +.TP +.B --proto =http,https +also only enables http and https +.RE +.IP +Unknown protocols produce a warning. This allows scripts to safely rely on +being able to disable potentially dangerous protocols, without relying upon +support for that protocol being built into curl to avoid an error. + +This option can be used multiple times, in which case the effect is the same +as concatenating the protocols into one instance of the option. + +(Added in 7.20.2) +.IP "--proto-redir <protocols>" +Tells curl to use the listed protocols after a redirect. See --proto for +how protocols are represented. + +(Added in 7.20.2) +.IP "--proxy-anyauth" +Tells curl to pick a suitable authentication method when communicating with +the given proxy. This might cause an extra request/response round-trip. (Added +in 7.13.2) +.IP "--proxy-basic" +Tells curl to use HTTP Basic authentication when communicating with the given +proxy. Use \fI--basic\fP for enabling HTTP Basic with a remote host. Basic is +the default authentication method curl uses with proxies. +.IP "--proxy-digest" +Tells curl to use HTTP Digest authentication when communicating with the given +proxy. Use \fI--digest\fP for enabling HTTP Digest with a remote host. +.IP "--proxy-negotiate" +Tells curl to use HTTP Negotiate authentication when communicating +with the given proxy. Use \fI--negotiate\fP for enabling HTTP Negotiate +with a remote host. (Added in 7.17.1) +.IP "--proxy-ntlm" +Tells curl to use HTTP NTLM authentication when communicating with the given +proxy. Use \fI--ntlm\fP for enabling NTLM with a remote host. +.IP "--proxy1.0 <proxyhost[:port]>" +Use the specified HTTP 1.0 proxy. If the port number is not specified, it is +assumed at port 1080. + +The only difference between this and the HTTP proxy option (\fI-x, --proxy\fP), +is that attempts to use CONNECT through the proxy will specify an HTTP 1.0 +protocol instead of the default HTTP 1.1. +.IP "--pubkey <key>" +(SSH) Public key file name. Allows you to provide your public key in this +separate file. + +If this option is used several times, the last one will be used. +.IP "-q" +If used as the first parameter on the command line, the \fIcurlrc\fP config +file will not be read and used. See the \fI-K, --config\fP for details on the +default config file search path. +.IP "-Q, --quote <command>" +(FTP/SFTP) Send an arbitrary command to the remote FTP or SFTP server. Quote +commands are sent BEFORE the transfer takes place (just after the initial PWD +command in an FTP transfer, to be exact). To make commands take place after a +successful transfer, prefix them with a dash '-'. To make commands be sent +after curl has changed the working directory, just before the transfer +command(s), prefix the command with a '+' (this is only supported for +FTP). You may specify any number of commands. If the server returns failure +for one of the commands, the entire operation will be aborted. You must send +syntactically correct FTP commands as RFC 959 defines to FTP servers, or one +of the commands listed below to SFTP servers. This option can be used +multiple times. When speaking to an FTP server, prefix the command with an +asterisk (*) to make curl continue even if the command fails as by default +curl will stop at first failure. + +SFTP is a binary protocol. Unlike for FTP, curl interprets SFTP quote commands +itself before sending them to the server. File names may be quoted +shell-style to embed spaces or special characters. Following is the list of +all supported SFTP quote commands: +.RS +.IP "chgrp group file" +The chgrp command sets the group ID of the file named by the file operand to +the group ID specified by the group operand. The group operand is a decimal +integer group ID. +.IP "chmod mode file" +The chmod command modifies the file mode bits of the specified file. The +mode operand is an octal integer mode number. +.IP "chown user file" +The chown command sets the owner of the file named by the file operand to the +user ID specified by the user operand. The user operand is a decimal +integer user ID. +.IP "ln source_file target_file" +The ln and symlink commands create a symbolic link at the target_file location +pointing to the source_file location. +.IP "mkdir directory_name" +The mkdir command creates the directory named by the directory_name operand. +.IP "pwd" +The pwd command returns the absolute pathname of the current working directory. +.IP "rename source target" +The rename command renames the file or directory named by the source +operand to the destination path named by the target operand. +.IP "rm file" +The rm command removes the file specified by the file operand. +.IP "rmdir directory" +The rmdir command removes the directory entry specified by the directory +operand, provided it is empty. +.IP "symlink source_file target_file" +See ln. +.RE +.IP "-r, --range <range>" +(HTTP/FTP/SFTP/FILE) Retrieve a byte range (i.e a partial document) from a +HTTP/1.1, FTP or SFTP server or a local FILE. Ranges can be specified +in a number of ways. +.RS +.TP 10 +.B 0-499 +specifies the first 500 bytes +.TP +.B 500-999 +specifies the second 500 bytes +.TP +.B -500 +specifies the last 500 bytes +.TP +.B 9500- +specifies the bytes from offset 9500 and forward +.TP +.B 0-0,-1 +specifies the first and last byte only(*)(H) +.TP +.B 500-700,600-799 +specifies 300 bytes from offset 500(H) +.TP +.B 100-199,500-599 +specifies two separate 100-byte ranges(*)(H) +.RE + +(*) = NOTE that this will cause the server to reply with a multipart +response! + +Only digit characters (0-9) are valid in the 'start' and 'stop' fields of the +\&'start-stop' range syntax. If a non-digit character is given in the range, +the server's response will be unspecified, depending on the server's +configuration. + +You should also be aware that many HTTP/1.1 servers do not have this feature +enabled, so that when you attempt to get a range, you'll instead get the whole +document. + +FTP and SFTP range downloads only support the simple 'start-stop' syntax +(optionally with one of the numbers omitted). FTP use depends on the extended +FTP command SIZE. + +If this option is used several times, the last one will be used. +.IP "-R, --remote-time" +When used, this will make curl attempt to figure out the timestamp of the +remote file, and if that is available make the local file get that same +timestamp. +.IP "--random-file <file>" +(SSL) Specify the path name to file containing what will be considered as +random data. The data is used to seed the random engine for SSL connections. +See also the \fI--egd-file\fP option. +.IP "--raw" +(HTTP) When used, it disables all internal HTTP decoding of content or transfer +encodings and instead makes them passed on unaltered, raw. (Added in 7.16.2) +.IP "--remote-name-all" +This option changes the default action for all given URLs to be dealt with as +if \fI-O, --remote-name\fP were used for each one. So if you want to disable +that for a specific URL after \fI--remote-name-all\fP has been used, you must +use "-o -" or \fI--no-remote-name\fP. (Added in 7.19.0) +.IP "--resolve <host:port:address>" +Provide a custom address for a specific host and port pair. Using this, you +can make the curl requests(s) use a specified address and prevent the +otherwise normally resolved address to be used. Consider it a sort of +/etc/hosts alternative provided on the command line. The port number should be +the number used for the specific protocol the host will be used for. It means +you need several entries if you want to provide address for the same host but +different ports. + +This option can be used many times to add many host names to resolve. + +(Added in 7.21.3) +.IP "--retry <num>" +If a transient error is returned when curl tries to perform a transfer, it +will retry this number of times before giving up. Setting the number to 0 +makes curl do no retries (which is the default). Transient error means either: +a timeout, an FTP 4xx response code or an HTTP 5xx response code. + +When curl is about to retry a transfer, it will first wait one second and then +for all forthcoming retries it will double the waiting time until it reaches +10 minutes which then will be the delay between the rest of the retries. By +using \fI--retry-delay\fP you disable this exponential backoff algorithm. See +also \fI--retry-max-time\fP to limit the total time allowed for +retries. (Added in 7.12.3) + +If this option is used several times, the last one will be used. +.IP "--retry-delay <seconds>" +Make curl sleep this amount of time before each retry when a transfer has +failed with a transient error (it changes the default backoff time algorithm +between retries). This option is only interesting if \fI--retry\fP is also +used. Setting this delay to zero will make curl use the default backoff time. +(Added in 7.12.3) + +If this option is used several times, the last one will be used. +.IP "--retry-max-time <seconds>" +The retry timer is reset before the first transfer attempt. Retries will be +done as usual (see \fI--retry\fP) as long as the timer hasn't reached this +given limit. Notice that if the timer hasn't reached the limit, the request +will be made and while performing, it may take longer than this given time +period. To limit a single request\'s maximum time, use \fI-m, --max-time\fP. +Set this option to zero to not timeout retries. (Added in 7.12.3) + +If this option is used several times, the last one will be used. +.IP "-s, --silent" +Silent or quiet mode. Don't show progress meter or error messages. Makes +Curl mute. +.IP "-S, --show-error" +When used with \fI-s\fP it makes curl show an error message if it fails. +.IP "--ssl" +(FTP, POP3, IMAP, SMTP) Try to use SSL/TLS for the connection. Reverts to a +non-secure connection if the server doesn't support SSL/TLS. See also +\fI--ftp-ssl-control\fP and \fI--ssl-reqd\fP for different levels of +encryption required. (Added in 7.20.0) + +This option was formerly known as \fI--ftp-ssl\fP (Added in 7.11.0). That +option name can still be used but will be removed in a future version. +.IP "--ssl-reqd" +(FTP, POP3, IMAP, SMTP) Require SSL/TLS for the connection. Terminates the +connection if the server doesn't support SSL/TLS. (Added in 7.20.0) + +This option was formerly known as \fI--ftp-ssl-reqd\fP (added in 7.15.5). That +option name can still be used but will be removed in a future version. +.IP "--ssl-allow-beast" +(SSL) This option tells curl to not work around a security flaw in the SSL3 +and TLS1.0 protocols known as BEAST. If this option isn't used, the SSL layer +may use work-arounds known to cause interoperability problems with some older +SSL implementations. WARNING: this option loosens the SSL security, and by +using this flag you ask for exactly that. (Added in 7.25.0) +.IP "--socks4 <host[:port]>" +Use the specified SOCKS4 proxy. If the port number is not specified, it is +assumed at port 1080. (Added in 7.15.2) + +This option overrides any previous use of \fI-x, --proxy\fP, as they are +mutually exclusive. + +Since 7.21.7, this option is superfluous since you can specify a socks4 proxy +with \fI-x, --proxy\fP using a socks4:// protocol prefix. + +If this option is used several times, the last one will be used. +.IP "--socks4a <host[:port]>" +Use the specified SOCKS4a proxy. If the port number is not specified, it is +assumed at port 1080. (Added in 7.18.0) + +This option overrides any previous use of \fI-x, --proxy\fP, as they are +mutually exclusive. + +Since 7.21.7, this option is superfluous since you can specify a socks4a proxy +with \fI-x, --proxy\fP using a socks4a:// protocol prefix. + +If this option is used several times, the last one will be used. +.IP "--socks5-hostname <host[:port]>" +Use the specified SOCKS5 proxy (and let the proxy resolve the host name). If +the port number is not specified, it is assumed at port 1080. (Added in +7.18.0) + +This option overrides any previous use of \fI-x, --proxy\fP, as they are +mutually exclusive. + +Since 7.21.7, this option is superfluous since you can specify a socks5 +hostname proxy with \fI-x, --proxy\fP using a socks5h:// protocol prefix. + +If this option is used several times, the last one will be used. (This option +was previously wrongly documented and used as --socks without the number +appended.) +.IP "--socks5 <host[:port]>" +Use the specified SOCKS5 proxy - but resolve the host name locally. If the +port number is not specified, it is assumed at port 1080. + +This option overrides any previous use of \fI-x, --proxy\fP, as they are +mutually exclusive. + +Since 7.21.7, this option is superfluous since you can specify a socks5 proxy +with \fI-x, --proxy\fP using a socks5:// protocol prefix. + +If this option is used several times, the last one will be used. (This option +was previously wrongly documented and used as --socks without the number +appended.) + +This option (as well as \fI--socks4\fP) does not work with IPV6, FTPS or LDAP. +.IP "--socks5-gssapi-service <servicename>" +The default service name for a socks server is rcmd/server-fqdn. This option +allows you to change it. + +Examples: --socks5 proxy-name \fI--socks5-gssapi-service\fP sockd would use +sockd/proxy-name --socks5 proxy-name \fI--socks5-gssapi-service\fP +sockd/real-name would use sockd/real-name for cases where the proxy-name does +not match the principal name. (Added in 7.19.4). +.IP "--socks5-gssapi-nec" +As part of the gssapi negotiation a protection mode is negotiated. RFC 1961 +says in section 4.3/4.4 it should be protected, but the NEC reference +implementation does not. The option \fI--socks5-gssapi-nec\fP allows the +unprotected exchange of the protection mode negotiation. (Added in 7.19.4). +.IP "--stderr <file>" +Redirect all writes to stderr to the specified file instead. If the file name +is a plain '-', it is instead written to stdout. + +If this option is used several times, the last one will be used. +.IP "-t, --telnet-option <OPT=val>" +Pass options to the telnet protocol. Supported options are: + +TTYPE=<term> Sets the terminal type. + +XDISPLOC=<X display> Sets the X display location. + +NEW_ENV=<var,val> Sets an environment variable. +.IP "-T, --upload-file <file>" +This transfers the specified local file to the remote URL. If there is no file +part in the specified URL, Curl will append the local file name. NOTE that you +must use a trailing / on the last directory to really prove to Curl that there +is no file name or curl will think that your last directory name is the remote +file name to use. That will most likely cause the upload operation to fail. If +this is used on an HTTP(S) server, the PUT command will be used. + +Use the file name "-" (a single dash) to use stdin instead of a given file. +Alternately, the file name "." (a single period) may be specified instead +of "-" to use stdin in non-blocking mode to allow reading server output +while stdin is being uploaded. + +You can specify one -T for each URL on the command line. Each -T + URL pair +specifies what to upload and to where. curl also supports "globbing" of the -T +argument, meaning that you can upload multiple files to a single URL by using +the same URL globbing style supported in the URL, like this: + +curl -T "{file1,file2}" http://www.uploadtothissite.com + +or even + +curl -T "img[1-1000].png" ftp://ftp.picturemania.com/upload/ +.IP "--tcp-nodelay" +Turn on the TCP_NODELAY option. See the \fIcurl_easy_setopt(3)\fP man page for +details about this option. (Added in 7.11.2) +.IP "--tftp-blksize <value>" +(TFTP) Set TFTP BLKSIZE option (must be >512). This is the block size that +curl will try to use when transferring data to or from a TFTP server. By +default 512 bytes will be used. + +If this option is used several times, the last one will be used. + +(Added in 7.20.0) +.IP "--tlsauthtype <authtype>" +Set TLS authentication type. Currently, the only supported option is "SRP", +for TLS-SRP (RFC 5054). If \fI--tlsuser\fP and \fI--tlspassword\fP are +specified but \fI--tlsauthtype\fP is not, then this option defaults to "SRP". +(Added in 7.21.4) +.IP "--tlsuser <user>" +Set username for use with the TLS authentication method specified with +\fI--tlsauthtype\fP. Requires that \fI--tlspassword\fP also be set. (Added in +7.21.4) +.IP "--tlspassword <password>" +Set password for use with the TLS authentication method specified with +\fI--tlsauthtype\fP. Requires that \fI--tlsuser\fP also be set. (Added in +7.21.4) +.IP "--tr-encoding" +(HTTP) Request a compressed Transfer-Encoding response using one of the +algorithms curl supports, and uncompress the data while receiving it. + +(Added in 7.21.6) +.IP "--trace <file>" +Enables a full trace dump of all incoming and outgoing data, including +descriptive information, to the given output file. Use "-" as filename to have +the output sent to stdout. + +This option overrides previous uses of \fI-v, --verbose\fP or +\fI--trace-ascii\fP. + +If this option is used several times, the last one will be used. +.IP "--trace-ascii <file>" +Enables a full trace dump of all incoming and outgoing data, including +descriptive information, to the given output file. Use "-" as filename to have +the output sent to stdout. + +This is very similar to \fI--trace\fP, but leaves out the hex part and only +shows the ASCII part of the dump. It makes smaller output that might be easier +to read for untrained humans. + +This option overrides previous uses of \fI-v, --verbose\fP or \fI--trace\fP. + +If this option is used several times, the last one will be used. +.IP "--trace-time" +Prepends a time stamp to each trace or verbose line that curl displays. +(Added in 7.14.0) +.IP "-u, --user <user:password>" +Specify the user name and password to use for server authentication. Overrides +\fI-n, --netrc\fP and \fI--netrc-optional\fP. + +If you just give the user name (without entering a colon) curl will prompt for +a password. + +If you use an SSPI-enabled curl binary and do NTLM authentication, you can +force curl to pick up the user name and password from your environment by +simply specifying a single colon with this option: "-u :". + +If this option is used several times, the last one will be used. +.IP "-U, --proxy-user <user:password>" +Specify the user name and password to use for proxy authentication. + +If you use an SSPI-enabled curl binary and do NTLM authentication, you can +force curl to pick up the user name and password from your environment by +simply specifying a single colon with this option: "-U :". + +If this option is used several times, the last one will be used. +.IP "--url <URL>" +Specify a URL to fetch. This option is mostly handy when you want to specify +URL(s) in a config file. + +This option may be used any number of times. To control where this URL is +written, use the \fI-o, --output\fP or the \fI-O, --remote-name\fP options. +.IP "-v, --verbose" +Makes the fetching more verbose/talkative. Mostly useful for debugging. A line +starting with '>' means "header data" sent by curl, '<' means "header data" +received by curl that is hidden in normal cases, and a line starting with '*' +means additional info provided by curl. + +Note that if you only want HTTP headers in the output, \fI-i, --include\fP +might be the option you're looking for. + +If you think this option still doesn't give you enough details, consider using +\fI--trace\fP or \fI--trace-ascii\fP instead. + +This option overrides previous uses of \fI--trace-ascii\fP or \fI--trace\fP. + +Use \fI-s, --silent\fP to make curl quiet. +.IP "-w, --write-out <format>" +Defines what to display on stdout after a completed and successful +operation. The format is a string that may contain plain text mixed with any +number of variables. The string can be specified as "string", to get read from +a particular file you specify it "@filename" and to tell curl to read the +format from stdin you write "@-". + +The variables present in the output format will be substituted by the value or +text that curl thinks fit, as described below. All variables are specified +as %{variable_name} and to output a normal % you just write them as +%%. You can output a newline by using \\n, a carriage return with \\r and a tab +space with \\t. + +.B NOTE: +The %-symbol is a special symbol in the win32-environment, where all +occurrences of % must be doubled when using this option. + +The variables available are: +.RS +.TP 15 +.B content_type +The Content-Type of the requested document, if there was any. +.TP +.B filename_effective +The ultimate filename that curl writes out to. This is only meaningful if curl +is told to write to a file with the \fI--remote-name\fP or \fI--output\fP +option. It's most useful in combination with the \fI--remote-header-name\fP +option. (Added in 7.25.1) +.TP +.B ftp_entry_path +The initial path curl ended up in when logging on to the remote FTP +server. (Added in 7.15.4) +.TP +.B http_code +The numerical response code that was found in the last retrieved HTTP(S) or +FTP(s) transfer. In 7.18.2 the alias \fBresponse_code\fP was added to show the +same info. +.TP +.B http_connect +The numerical code that was found in the last response (from a proxy) to a +curl CONNECT request. (Added in 7.12.4) +.TP +.B num_connects +Number of new connects made in the recent transfer. (Added in 7.12.3) +.TP +.B num_redirects +Number of redirects that were followed in the request. (Added in 7.12.3) +.TP +.B redirect_url +When an HTTP request was made without -L to follow redirects, this variable +will show the actual URL a redirect \fIwould\fP take you to. (Added in 7.18.2) +.TP +.B size_download +The total amount of bytes that were downloaded. +.TP +.B size_header +The total amount of bytes of the downloaded headers. +.TP +.B size_request +The total amount of bytes that were sent in the HTTP request. +.TP +.B size_upload +The total amount of bytes that were uploaded. +.TP +.B speed_download +The average download speed that curl measured for the complete download. Bytes +per second. +.TP +.B speed_upload +The average upload speed that curl measured for the complete upload. Bytes per +second. +.TP +.B ssl_verify_result +The result of the SSL peer certificate verification that was requested. 0 +means the verification was successful. (Added in 7.19.0) +.TP +.B time_appconnect +The time, in seconds, it took from the start until the SSL/SSH/etc +connect/handshake to the remote host was completed. (Added in 7.19.0) +.TP +.B time_connect +The time, in seconds, it took from the start until the TCP connect to the +remote host (or proxy) was completed. +.TP +.B time_namelookup +The time, in seconds, it took from the start until the name resolving was +completed. +.TP +.B time_pretransfer +The time, in seconds, it took from the start until the file transfer was just +about to begin. This includes all pre-transfer commands and negotiations that +are specific to the particular protocol(s) involved. +.TP +.B time_redirect +The time, in seconds, it took for all redirection steps include name lookup, +connect, pretransfer and transfer before the final transaction was +started. time_redirect shows the complete execution time for multiple +redirections. (Added in 7.12.3) +.TP +.B time_starttransfer +The time, in seconds, it took from the start until the first byte was just +about to be transferred. This includes time_pretransfer and also the time the +server needed to calculate the result. +.TP +.B time_total +The total time, in seconds, that the full operation lasted. The time will be +displayed with millisecond resolution. +.TP +.B url_effective +The URL that was fetched last. This is most meaningful if you've told curl +to follow location: headers. +.RE + +If this option is used several times, the last one will be used. +.IP "-x, --proxy <[protocol://][user:password@]proxyhost[:port]>" +Use the specified HTTP proxy. If the port number is not specified, it is +assumed at port 1080. + +This option overrides existing environment variables that set the proxy to +use. If there's an environment variable setting a proxy, you can set proxy to +\&"" to override it. + +All operations that are performed over an HTTP proxy will transparently be +converted to HTTP. It means that certain protocol specific operations might +not be available. This is not the case if you can tunnel through the proxy, as +one with the \fI-p, --proxytunnel\fP option. + +User and password that might be provided in the proxy string are URL decoded +by curl. This allows you to pass in special characters such as @ by using %40 +or pass in a colon with %3a. + +The proxy host can be specified the exact same way as the proxy environment +variables, including the protocol prefix (http://) and the embedded user + +password. + +From 7.21.7, the proxy string may be specified with a protocol:// prefix to +specify alternative proxy protocols. Use socks4://, socks4a://, socks5:// or +socks5h:// to request the specific SOCKS version to be used. No protocol +specified, http:// and all others will be treated as HTTP proxies. + +If this option is used several times, the last one will be used. +.IP "-X, --request <command>" +(HTTP) Specifies a custom request method to use when communicating with the +HTTP server. The specified request will be used instead of the method +otherwise used (which defaults to GET). Read the HTTP 1.1 specification for +details and explanations. Common additional HTTP requests include PUT and +DELETE, but related technologies like WebDAV offers PROPFIND, COPY, MOVE and +more. + +(FTP) +Specifies a custom FTP command to use instead of LIST when doing file lists +with FTP. + +If this option is used several times, the last one will be used. + +.IP "--xattr" +When saving output to a file, this option tells curl to store certain file +metadata in extened file attributes. Currently, the URL is stored in the +xdg.origin.url attribute and, for HTTP, the content type is stored in +the mime_type attribute. If the file system does not support extended +attributes, a warning is issued. + +.IP "-y, --speed-time <time>" +If a download is slower than speed-limit bytes per second during a speed-time +period, the download gets aborted. If speed-time is used, the default +speed-limit will be 1 unless set with \fI-Y\fP. + +This option controls transfers and thus will not affect slow connects etc. If +this is a concern for you, try the \fI--connect-timeout\fP option. + +If this option is used several times, the last one will be used. +.IP "-Y, --speed-limit <speed>" +If a download is slower than this given speed (in bytes per second) for +speed-time seconds it gets aborted. speed-time is set with \fI-y\fP and is 30 +if not set. + +If this option is used several times, the last one will be used. +.IP "-z/--time-cond <date expression>|<file>" +(HTTP/FTP) Request a file that has been modified later than the given time and +date, or one that has been modified before that time. The <date expression> +can be all sorts of date strings or if it doesn't match any internal ones, it +is taken as a filename and tries to get the modification date (mtime) from +<file> instead. See the \fIcurl_getdate(3)\fP man pages for date expression +details. + +Start the date expression with a dash (-) to make it request for a document +that is older than the given date/time, default is a document that is newer +than the specified date/time. + +If this option is used several times, the last one will be used. +.IP "-h, --help" +Usage help. +.IP "-M, --manual" +Manual. Display the huge help text. +.IP "-V, --version" +Displays information about curl and the libcurl version it uses. + +The first line includes the full version of curl, libcurl and other 3rd party +libraries linked with the executable. + +The second line (starts with "Protocols:") shows all protocols that libcurl +reports to support. + +The third line (starts with "Features:") shows specific features libcurl +reports to offer. Available features include: +.RS +.IP "IPv6" +You can use IPv6 with this. +.IP "krb4" +Krb4 for FTP is supported. +.IP "SSL" +HTTPS and FTPS are supported. +.IP "libz" +Automatic decompression of compressed files over HTTP is supported. +.IP "NTLM" +NTLM authentication is supported. +.IP "GSS-Negotiate" +Negotiate authentication and krb5 for FTP is supported. +.IP "Debug" +This curl uses a libcurl built with Debug. This enables more error-tracking +and memory debugging etc. For curl-developers only! +.IP "AsynchDNS" +This curl uses asynchronous name resolves. +.IP "SPNEGO" +SPNEGO Negotiate authentication is supported. +.IP "Largefile" +This curl supports transfers of large files, files larger than 2GB. +.IP "IDN" +This curl supports IDN - international domain names. +.IP "SSPI" +SSPI is supported. If you use NTLM and set a blank user name, curl will +authenticate with your current user and password. +.IP "TLS-SRP" +SRP (Secure Remote Password) authentication is supported for TLS. +.IP "Metalink" +This curl supports Metalink (both version 3 and 4 (RFC 5854)), which +describes mirrors and hashes. curl will use mirrors for failover if +there are errors (such as the file or server not being available). +.RE +.SH FILES +.I ~/.curlrc +.RS +Default config file, see \fI-K, --config\fP for details. +.SH ENVIRONMENT +The environment variables can be specified in lower case or upper case. The +lower case version has precedence. http_proxy is an exception as it is only +available in lower case. + +Using an environment variable to set the proxy has the same effect as using +the \fI--proxy\fP option. + +.IP "http_proxy [protocol://]<host>[:port]" +Sets the proxy server to use for HTTP. +.IP "HTTPS_PROXY [protocol://]<host>[:port]" +Sets the proxy server to use for HTTPS. +.IP "[url-protocol]_PROXY [protocol://]<host>[:port]" +Sets the proxy server to use for [url-protocol], where the protocol is a +protocol that curl supports and as specified in a URL. FTP, FTPS, POP3, IMAP, +SMTP, LDAP etc. +.IP "ALL_PROXY [protocol://]<host>[:port]" +Sets the proxy server to use if no protocol-specific proxy is set. +.IP "NO_PROXY <comma-separated list of hosts>" +list of host names that shouldn't go through any proxy. If set to a asterisk +\&'*' only, it matches all hosts. +.SH "PROXY PROTOCOL PREFIXES" +Since curl version 7.21.7, the proxy string may be specified with a +protocol:// prefix to specify alternative proxy protocols. + +If no protocol is specified in the proxy string or if the string doesn't match +a supported one, the proxy will be treated as an HTTP proxy. + +The supported proxy protocol prefixes are as follows: +.IP "socks4://" +Makes it the equivalent of \fI--socks4\fP +.IP "socks4a://" +Makes it the equivalent of \fI--socks4a\fP +.IP "socks5://" +Makes it the equivalent of \fI--socks5\fP +.IP "socks5h://" +Makes it the equivalent of \fI--socks5-hostname\fP +.SH EXIT CODES +There are a bunch of different error codes and their corresponding error +messages that may appear during bad conditions. At the time of this writing, +the exit codes are: +.IP 1 +Unsupported protocol. This build of curl has no support for this protocol. +.IP 2 +Failed to initialize. +.IP 3 +URL malformed. The syntax was not correct. +.IP 4 +A feature or option that was needed to perform the desired request was not +enabled or was explicitly disabled at build-time. To make curl able to do +this, you probably need another build of libcurl! +.IP 5 +Couldn't resolve proxy. The given proxy host could not be resolved. +.IP 6 +Couldn't resolve host. The given remote host was not resolved. +.IP 7 +Failed to connect to host. +.IP 8 +FTP weird server reply. The server sent data curl couldn't parse. +.IP 9 +FTP access denied. The server denied login or denied access to the particular +resource or directory you wanted to reach. Most often you tried to change to a +directory that doesn't exist on the server. +.IP 11 +FTP weird PASS reply. Curl couldn't parse the reply sent to the PASS request. +.IP 13 +FTP weird PASV reply, Curl couldn't parse the reply sent to the PASV request. +.IP 14 +FTP weird 227 format. Curl couldn't parse the 227-line the server sent. +.IP 15 +FTP can't get host. Couldn't resolve the host IP we got in the 227-line. +.IP 17 +FTP couldn't set binary. Couldn't change transfer method to binary. +.IP 18 +Partial file. Only a part of the file was transferred. +.IP 19 +FTP couldn't download/access the given file, the RETR (or similar) command +failed. +.IP 21 +FTP quote error. A quote command returned error from the server. +.IP 22 +HTTP page not retrieved. The requested url was not found or returned another +error with the HTTP error code being 400 or above. This return code only +appears if \fI-f, --fail\fP is used. +.IP 23 +Write error. Curl couldn't write data to a local filesystem or similar. +.IP 25 +FTP couldn't STOR file. The server denied the STOR operation, used for FTP +uploading. +.IP 26 +Read error. Various reading problems. +.IP 27 +Out of memory. A memory allocation request failed. +.IP 28 +Operation timeout. The specified time-out period was reached according to the +conditions. +.IP 30 +FTP PORT failed. The PORT command failed. Not all FTP servers support the PORT +command, try doing a transfer using PASV instead! +.IP 31 +FTP couldn't use REST. The REST command failed. This command is used for +resumed FTP transfers. +.IP 33 +HTTP range error. The range "command" didn't work. +.IP 34 +HTTP post error. Internal post-request generation error. +.IP 35 +SSL connect error. The SSL handshaking failed. +.IP 36 +FTP bad download resume. Couldn't continue an earlier aborted download. +.IP 37 +FILE couldn't read file. Failed to open the file. Permissions? +.IP 38 +LDAP cannot bind. LDAP bind operation failed. +.IP 39 +LDAP search failed. +.IP 41 +Function not found. A required LDAP function was not found. +.IP 42 +Aborted by callback. An application told curl to abort the operation. +.IP 43 +Internal error. A function was called with a bad parameter. +.IP 45 +Interface error. A specified outgoing interface could not be used. +.IP 47 +Too many redirects. When following redirects, curl hit the maximum amount. +.IP 48 +Unknown option specified to libcurl. This indicates that you passed a weird +option to curl that was passed on to libcurl and rejected. Read up in the +manual! +.IP 49 +Malformed telnet option. +.IP 51 +The peer's SSL certificate or SSH MD5 fingerprint was not OK. +.IP 52 +The server didn't reply anything, which here is considered an error. +.IP 53 +SSL crypto engine not found. +.IP 54 +Cannot set SSL crypto engine as default. +.IP 55 +Failed sending network data. +.IP 56 +Failure in receiving network data. +.IP 58 +Problem with the local certificate. +.IP 59 +Couldn't use specified SSL cipher. +.IP 60 +Peer certificate cannot be authenticated with known CA certificates. +.IP 61 +Unrecognized transfer encoding. +.IP 62 +Invalid LDAP URL. +.IP 63 +Maximum file size exceeded. +.IP 64 +Requested FTP SSL level failed. +.IP 65 +Sending the data requires a rewind that failed. +.IP 66 +Failed to initialise SSL Engine. +.IP 67 +The user name, password, or similar was not accepted and curl failed to log in. +.IP 68 +File not found on TFTP server. +.IP 69 +Permission problem on TFTP server. +.IP 70 +Out of disk space on TFTP server. +.IP 71 +Illegal TFTP operation. +.IP 72 +Unknown TFTP transfer ID. +.IP 73 +File already exists (TFTP). +.IP 74 +No such user (TFTP). +.IP 75 +Character conversion failed. +.IP 76 +Character conversion functions required. +.IP 77 +Problem with reading the SSL CA cert (path? access rights?). +.IP 78 +The resource referenced in the URL does not exist. +.IP 79 +An unspecified error occurred during the SSH session. +.IP 80 +Failed to shut down the SSL connection. +.IP 82 +Could not load CRL file, missing or wrong format (added in 7.19.0). +.IP 83 +Issuer check failed (added in 7.19.0). +.IP 84 +The FTP PRET command failed +.IP 85 +RTSP: mismatch of CSeq numbers +.IP 86 +RTSP: mismatch of Session Identifiers +.IP 87 +unable to parse FTP file list +.IP 88 +FTP chunk callback reported error +.IP XX +More error codes will appear here in future releases. The existing ones +are meant to never change. +.SH AUTHORS / CONTRIBUTORS +Daniel Stenberg is the main author, but the whole list of contributors is +found in the separate THANKS file. +.SH WWW +http://curl.haxx.se +.SH FTP +ftp://ftp.sunet.se/pub/www/utilities/curl/ +.SH "SEE ALSO" +.BR ftp (1), +.BR wget (1) diff --git a/docs/examples/.gitignore b/docs/examples/.gitignore new file mode 100644 index 000000000..cbe0d04d4 --- /dev/null +++ b/docs/examples/.gitignore @@ -0,0 +1,45 @@ +10-at-a-time +anyauthput +certinfo +chkspeed +cookie_interface +debug +externalsocket +fileupload +fopen +ftp-wildcard +ftpget +ftpgetinfo +ftpgetresp +ftpsget +ftpupload +getinfo +getinmemory +http-post +httpcustomheader +httpput +https +imap +multi-app +multi-debugcallback +multi-double +multi-post +multi-single +persistant +pop3s +pop3slist +post-callback +postit2 +progressfunc +resolve +rtsp +sendrecv +sepheaders +sftpget +simple +simplepost +simplesmtp +simplessl +smtp-multi +smtp-tls +url2file diff --git a/docs/examples/10-at-a-time.c b/docs/examples/10-at-a-time.c new file mode 100644 index 000000000..a85fff46f --- /dev/null +++ b/docs/examples/10-at-a-time.c @@ -0,0 +1,197 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +/* Example 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; +} diff --git a/docs/examples/Makefile.am b/docs/examples/Makefile.am new file mode 100644 index 000000000..865f09371 --- /dev/null +++ b/docs/examples/Makefile.am @@ -0,0 +1,64 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2012, 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. +# +########################################################################### + +AUTOMAKE_OPTIONS = foreign nostdinc + +EXTRA_DIST = README Makefile.example Makefile.inc Makefile.m32 \ + Makefile.netware 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 + +AM_CPPFLAGS = -I$(top_builddir)/include/curl \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/include + +LIBDIR = $(top_builddir)/lib + +# Avoid libcurl obsolete stuff +AM_CPPFLAGS += -DCURL_NO_OLDIES + +# Mostly for Windows build targets, when using static libcurl +if USE_CPPFLAG_CURL_STATICLIB +AM_CPPFLAGS += -DCURL_STATICLIB +endif + +# Prevent LIBS from being used for all link targets +LIBS = $(BLANK_AT_MAKETIME) + +# Dependencies +if USE_EXPLICIT_LIB_DEPS +LDADD = $(LIBDIR)/libcurl.la @LIBCURL_LIBS@ +else +LDADD = $(LIBDIR)/libcurl.la +endif + +# Makefile.inc provides the check_PROGRAMS and COMPLICATED_EXAMPLES defines +include Makefile.inc + +all: $(check_PROGRAMS) diff --git a/docs/examples/Makefile.example b/docs/examples/Makefile.example new file mode 100644 index 000000000..dfd117873 --- /dev/null +++ b/docs/examples/Makefile.example @@ -0,0 +1,53 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2011, 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. +# +########################################################################### + +# 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) $< diff --git a/docs/examples/Makefile.inc b/docs/examples/Makefile.inc new file mode 100644 index 000000000..9aabfcabd --- /dev/null +++ b/docs/examples/Makefile.inc @@ -0,0 +1,15 @@ +# 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 rtsp externalsocket resolve \ + progressfunc pop3s pop3slist imap url2file sftpget ftpsget + +# 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.cpp cacertinmem.c \ + ftpuploadresume.c ghiper.c hiperfifo.c htmltidy.c multithread.c \ + opensslthreadlock.c sampleconv.c synctime.c threaded-ssl.c evhiperfifo.c \ + smooth-gtk-thread.c version-check.pl href_extractor.c asiohiper.cpp diff --git a/docs/examples/Makefile.m32 b/docs/examples/Makefile.m32 new file mode 100644 index 000000000..c1db6207a --- /dev/null +++ b/docs/examples/Makefile.m32 @@ -0,0 +1,282 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2011, 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. +# +########################################################################### +# +## Makefile for building curl examples with MingW (GCC-3.2 or later) +## and optionally OpenSSL (0.9.8), libssh2 (1.3), zlib (1.2.5), librtmp (2.3) +## +## Usage: mingw32-make -f Makefile.m32 CFG=-feature1[-feature2][-feature3][...] +## Example: mingw32-make -f Makefile.m32 CFG=-zlib-ssl-spi-winidn +## +## Hint: you can also set environment vars to control the build, f.e.: +## set ZLIB_PATH=c:/zlib-1.2.7 +## set ZLIB=1 +# +########################################################################### + +# Edit the path below to point to the base of your Zlib sources. +ifndef ZLIB_PATH +ZLIB_PATH = ../../../zlib-1.2.7 +endif +# Edit the path below to point to the base of your OpenSSL package. +ifndef OPENSSL_PATH +OPENSSL_PATH = ../../../openssl-0.9.8x +endif +# Edit the path below to point to the base of your LibSSH2 package. +ifndef LIBSSH2_PATH +LIBSSH2_PATH = ../../../libssh2-1.4.2 +endif +# Edit the path below to point to the base of your librtmp package. +ifndef LIBRTMP_PATH +LIBRTMP_PATH = ../../../librtmp-2.3 +endif +# Edit the path below to point to the base of your libidn package. +ifndef LIBIDN_PATH +LIBIDN_PATH = ../../../libidn-1.18 +endif +# Edit the path below to point to the base of your MS IDN package. +# Microsoft Internationalized Domain Names (IDN) Mitigation APIs 1.1 +# http://www.microsoft.com/downloads/en/details.aspx?FamilyID=ad6158d7-ddba-416a-9109-07607425a815 +ifndef WINIDN_PATH +WINIDN_PATH = ../../../Microsoft IDN Mitigation APIs +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 = ../.. + +# Edit the path below to point to the base of your c-ares package. +ifndef LIBCARES_PATH +LIBCARES_PATH = $(PROOT)/ares +endif + +# Edit the var below to set to your architecture or set environment var. +ifndef ARCH +ARCH = w32 +endif + +CC = $(CROSSPREFIX)gcc +CFLAGS = -g -O2 -Wall +CFLAGS += -fno-strict-aliasing +ifeq ($(ARCH),w64) +CFLAGS += -D_AMD64_ +endif +# comment LDFLAGS below to keep debug info +LDFLAGS = -s +RC = $(CROSSPREFIX)windres +RCFLAGS = --include-dir=$(PROOT)/include -O COFF -i + +# Platform-dependent helper tool macros +ifeq ($(findstring /sh,$(SHELL)),/sh) +DEL = rm -f $1 +RMDIR = rm -fr $1 +MKDIR = mkdir -p $1 +COPY = -cp -afv $1 $2 +#COPYR = -cp -afr $1/* $2 +COPYR = -rsync -aC $1/* $2 +TOUCH = touch $1 +CAT = cat +ECHONL = echo "" +DL = ' +else +ifeq "$(OS)" "Windows_NT" +DEL = -del 2>NUL /q /f $(subst /,\,$1) +RMDIR = -rd 2>NUL /q /s $(subst /,\,$1) +else +DEL = -del 2>NUL $(subst /,\,$1) +RMDIR = -deltree 2>NUL /y $(subst /,\,$1) +endif +MKDIR = -md 2>NUL $(subst /,\,$1) +COPY = -copy 2>NUL /y $(subst /,\,$1) $(subst /,\,$2) +COPYR = -xcopy 2>NUL /q /y /e $(subst /,\,$1) $(subst /,\,$2) +TOUCH = copy 2>&1>NUL /b $(subst /,\,$1) +,, +CAT = type +ECHONL = $(ComSpec) /c echo. +endif + +######################################################## +## Nothing more to do below this line! + +ifeq ($(findstring -dyn,$(CFG)),-dyn) +DYN = 1 +endif +ifeq ($(findstring -ares,$(CFG)),-ares) +ARES = 1 +endif +ifeq ($(findstring -rtmp,$(CFG)),-rtmp) +RTMP = 1 +SSL = 1 +ZLIB = 1 +endif +ifeq ($(findstring -ssh2,$(CFG)),-ssh2) +SSH2 = 1 +SSL = 1 +ZLIB = 1 +endif +ifeq ($(findstring -ssl,$(CFG)),-ssl) +SSL = 1 +endif +ifeq ($(findstring -zlib,$(CFG)),-zlib) +ZLIB = 1 +endif +ifeq ($(findstring -idn,$(CFG)),-idn) +IDN = 1 +endif +ifeq ($(findstring -winidn,$(CFG)),-winidn) +WINIDN = 1 +endif +ifeq ($(findstring -sspi,$(CFG)),-sspi) +SSPI = 1 +endif +ifeq ($(findstring -spnego,$(CFG)),-spnego) +SPNEGO = 1 +endif +ifeq ($(findstring -ldaps,$(CFG)),-ldaps) +LDAPS = 1 +endif +ifeq ($(findstring -ipv6,$(CFG)),-ipv6) +IPV6 = 1 +endif +ifeq ($(findstring -metalink,$(CFG)),-metalink) +METALINK = 1 +endif +ifeq ($(findstring -winssl,$(CFG)),-winssl) +SCHANNEL = 1 +SSPI = 1 +endif + +INCLUDES = -I. -I$(PROOT) -I$(PROOT)/include -I$(PROOT)/lib + +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 + LDFLAGS += -static +endif +ifdef ARES + ifndef DYN + curl_DEPENDENCIES += $(LIBCARES_PATH)/libcares.a + endif + CFLAGS += -DUSE_ARES + curl_LDADD += -L"$(LIBCARES_PATH)" -lcares +endif +ifdef RTMP + CFLAGS += -DUSE_LIBRTMP + curl_LDADD += -L"$(LIBRTMP_PATH)/librtmp" -lrtmp -lwinmm +endif +ifdef SSH2 + CFLAGS += -DUSE_LIBSSH2 -DHAVE_LIBSSH2_H + curl_LDADD += -L"$(LIBSSH2_PATH)/win32" -lssh2 +endif +ifdef SSL + ifndef OPENSSL_LIBPATH + OPENSSL_LIBS = -lssl -lcrypto + ifeq "$(wildcard $(OPENSSL_PATH)/out)" "$(OPENSSL_PATH)/out" + OPENSSL_LIBPATH = $(OPENSSL_PATH)/out + ifdef DYN + OPENSSL_LIBS = -lssl32 -leay32 + endif + endif + ifeq "$(wildcard $(OPENSSL_PATH)/lib)" "$(OPENSSL_PATH)/lib" + OPENSSL_LIBPATH = $(OPENSSL_PATH)/lib + endif + endif + ifndef DYN + OPENSSL_LIBS += -lgdi32 -lcrypt32 + endif + CFLAGS += -DUSE_SSLEAY + curl_LDADD += -L"$(OPENSSL_LIBPATH)" $(OPENSSL_LIBS) +endif +ifdef ZLIB + INCLUDES += -I"$(ZLIB_PATH)" + CFLAGS += -DHAVE_LIBZ -DHAVE_ZLIB_H + curl_LDADD += -L"$(ZLIB_PATH)" -lz +endif +ifdef IDN + CFLAGS += -DUSE_LIBIDN + curl_LDADD += -L"$(LIBIDN_PATH)/lib" -lidn +else +ifdef WINIDN + CFLAGS += -DUSE_WIN32_IDN + curl_LDADD += -L"$(WINIDN_PATH)" -lnormaliz +endif +endif +ifdef SSPI + CFLAGS += -DUSE_WINDOWS_SSPI + ifdef SCHANNEL + CFLAGS += -DUSE_SCHANNEL + endif +endif +ifdef SPNEGO + CFLAGS += -DHAVE_SPNEGO +endif +ifdef IPV6 + CFLAGS += -DENABLE_IPV6 -D_WIN32_WINNT=0x0501 +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 + +# Makefile.inc provides the check_PROGRAMS and COMPLICATED_EXAMPLES defines +include Makefile.inc + +check_PROGRAMS := $(patsubst %,%.exe,$(strip $(check_PROGRAMS))) +check_PROGRAMS += ftpuploadresume.exe synctime.exe + +.PRECIOUS: %.o + + +all: $(check_PROGRAMS) + +%.exe: %.o $(curl_DEPENDENCIES) + $(CC) $(LDFLAGS) -o $@ $< $(curl_LDADD) + +%.o: %.c + $(CC) $(INCLUDES) $(CFLAGS) -c $< + +%.res: %.rc + $(RC) $(RCFLAGS) $< -o $@ + +clean: + @$(call DEL, $(check_PROGRAMS:.exe=.o)) + +distclean vclean: clean + @$(call DEL, $(check_PROGRAMS)) + diff --git a/docs/examples/Makefile.netware b/docs/examples/Makefile.netware new file mode 100644 index 000000000..934f17aef --- /dev/null +++ b/docs/examples/Makefile.netware @@ -0,0 +1,441 @@ +################################################################# +# +## Makefile for building curl.nlm (NetWare version - gnu make) +## Use: make -f Makefile.netware +## +## Comments to: Guenter Knauf http://www.gknw.net/phpbb +# +################################################################# + +# Edit the path below to point to the base of your Novell NDK. +ifndef NDKBASE +NDKBASE = c:/novell +endif + +# Edit the path below to point to the base of your Zlib sources. +ifndef ZLIB_PATH +ZLIB_PATH = ../../../zlib-1.2.7 +endif + +# Edit the path below to point to the base of your OpenSSL package. +ifndef OPENSSL_PATH +OPENSSL_PATH = ../../../openssl-0.9.8x +endif + +# Edit the path below to point to the base of your LibSSH2 package. +ifndef LIBSSH2_PATH +LIBSSH2_PATH = ../../../libssh2-1.4.2 +endif + +# Edit the path below to point to the base of your axTLS package. +ifndef AXTLS_PATH +AXTLS_PATH = ../../../axTLS-1.2.7 +endif + +# Edit the path below to point to the base of your libidn package. +ifndef LIBIDN_PATH +LIBIDN_PATH = ../../../libidn-1.18 +endif + +# Edit the path below to point to the base of your librtmp package. +ifndef LIBRTMP_PATH +LIBRTMP_PATH = ../../../librtmp-2.3 +endif + +# Edit the path below to point to the base of your fbopenssl package. +ifndef FBOPENSSL_PATH +FBOPENSSL_PATH = ../../fbopenssl-0.4 +endif + +# Edit the path below to point to the base of your c-ares package. +ifndef LIBCARES_PATH +LIBCARES_PATH = ../../ares +endif + +ifndef INSTDIR +INSTDIR = ..$(DS)..$(DS)curl-$(LIBCURL_VERSION_STR)-bin-nw +endif + +# Edit the vars below to change NLM target settings. +TARGET = examples +VERSION = $(LIBCURL_VERSION) +COPYR = Copyright (C) $(LIBCURL_COPYRIGHT_STR) +DESCR = cURL ($(LIBARCH)) +MTSAFE = YES +STACK = 8192 +SCREEN = Example Program +# Comment the line below if you dont want to load protected automatically. +# LDRING = 3 + +# Uncomment the next line to enable linking with POSIX semantics. +# POSIXFL = 1 + +# Edit the var below to point to your lib architecture. +ifndef LIBARCH +LIBARCH = LIBC +endif + +# must be equal to NDEBUG or DEBUG, CURLDEBUG +ifndef DB +DB = NDEBUG +endif +# Optimization: -O<n> or debugging: -g +ifeq ($(DB),NDEBUG) + OPT = -O2 + OBJDIR = release +else + OPT = -g + OBJDIR = debug +endif + +# The following lines defines your compiler. +ifdef CWFolder + METROWERKS = $(CWFolder) +endif +ifdef METROWERKS + # MWCW_PATH = $(subst \,/,$(METROWERKS))/Novell Support + MWCW_PATH = $(subst \,/,$(METROWERKS))/Novell Support/Metrowerks Support + CC = mwccnlm +else + CC = gcc +endif +PERL = perl +# Here you can find a native Win32 binary of the original awk: +# http://www.gknw.net/development/prgtools/awk-20100523.zip +AWK = awk +CP = cp -afv +MKDIR = mkdir +# RM = rm -f +# If you want to mark the target as MTSAFE you will need a tool for +# generating the xdc data for the linker; here's a minimal tool: +# http://www.gknw.net/development/prgtools/mkxdc.zip +MPKXDC = mkxdc + +# LIBARCH_U = $(shell $(AWK) 'BEGIN {print toupper(ARGV[1])}' $(LIBARCH)) +LIBARCH_L = $(shell $(AWK) 'BEGIN {print tolower(ARGV[1])}' $(LIBARCH)) + +# Include the version info retrieved from curlver.h +-include $(OBJDIR)/version.inc + +# Global flags for all compilers +CFLAGS += $(OPT) -D$(DB) -DNETWARE -DHAVE_CONFIG_H -nostdinc + +ifeq ($(CC),mwccnlm) +LD = mwldnlm +LDFLAGS = -nostdlib $< $(PRELUDE) $(LDLIBS) -o $@ -commandfile +LIBEXT = lib +CFLAGS += -gccinc -inline off -opt nointrinsics -proc 586 +CFLAGS += -relax_pointers +#CFLAGS += -w on +ifeq ($(LIBARCH),LIBC) +ifeq ($(POSIXFL),1) + PRELUDE = $(NDK_LIBC)/imports/posixpre.o +else + PRELUDE = $(NDK_LIBC)/imports/libcpre.o +endif + CFLAGS += -align 4 +else + # PRELUDE = $(NDK_CLIB)/imports/clibpre.o + # to avoid the __init_* / __deinit_* whoes dont use prelude from NDK + PRELUDE = "$(MWCW_PATH)/libraries/runtime/prelude.obj" + # CFLAGS += -include "$(MWCW_PATH)/headers/nlm_clib_prefix.h" + CFLAGS += -align 1 +endif +else +LD = nlmconv +LDFLAGS = -T +LIBEXT = a +CFLAGS += -m32 +CFLAGS += -fno-builtin -fno-strict-aliasing +ifeq ($(findstring gcc,$(CC)),gcc) +CFLAGS += -fpcc-struct-return +endif +CFLAGS += -Wall # -pedantic +ifeq ($(LIBARCH),LIBC) +ifeq ($(POSIXFL),1) + PRELUDE = $(NDK_LIBC)/imports/posixpre.gcc.o +else + PRELUDE = $(NDK_LIBC)/imports/libcpre.gcc.o +endif +else + # PRELUDE = $(NDK_CLIB)/imports/clibpre.gcc.o + # to avoid the __init_* / __deinit_* whoes dont use prelude from NDK + # http://www.gknw.net/development/mk_nlm/gcc_pre.zip + PRELUDE = $(NDK_ROOT)/pre/prelude.o + CFLAGS += -include $(NDKBASE)/nlmconv/genlm.h +endif +endif + +NDK_ROOT = $(NDKBASE)/ndk +ifndef NDK_CLIB +NDK_CLIB = $(NDK_ROOT)/nwsdk +endif +ifndef NDK_LIBC +NDK_LIBC = $(NDK_ROOT)/libc +endif +ifndef NDK_LDAP +NDK_LDAP = $(NDK_ROOT)/cldapsdk/netware +endif +CURL_INC = ../../include +CURL_LIB = ../../lib + +INCLUDES = -I$(CURL_INC) + +ifeq ($(findstring -static,$(CFG)),-static) +LINK_STATIC = 1 +endif +ifeq ($(findstring -ares,$(CFG)),-ares) +WITH_ARES = 1 +endif +ifeq ($(findstring -rtmp,$(CFG)),-rtmp) +WITH_RTMP = 1 +WITH_SSL = 1 +WITH_ZLIB = 1 +endif +ifeq ($(findstring -ssh2,$(CFG)),-ssh2) +WITH_SSH2 = 1 +WITH_SSL = 1 +WITH_ZLIB = 1 +endif +ifeq ($(findstring -axtls,$(CFG)),-axtls) +WITH_AXTLS = 1 +WITH_SSL = +else +ifeq ($(findstring -ssl,$(CFG)),-ssl) +WITH_SSL = 1 +endif +endif +ifeq ($(findstring -zlib,$(CFG)),-zlib) +WITH_ZLIB = 1 +endif +ifeq ($(findstring -idn,$(CFG)),-idn) +WITH_IDN = 1 +endif +ifeq ($(findstring -spnego,$(CFG)),-spnego) +WITH_SPNEGO = 1 +endif +ifeq ($(findstring -ipv6,$(CFG)),-ipv6) +ENABLE_IPV6 = 1 +endif + +ifdef LINK_STATIC + LDLIBS = $(CURL_LIB)/libcurl.$(LIBEXT) +ifdef WITH_ARES + LDLIBS += $(LIBCARES_PATH)/libcares.$(LIBEXT) +endif +else + MODULES = libcurl.nlm + IMPORTS = @$(CURL_LIB)/libcurl.imp +endif +ifdef WITH_SSH2 + # INCLUDES += -I$(LIBSSH2_PATH)/include +ifdef LINK_STATIC + LDLIBS += $(LIBSSH2_PATH)/nw/libssh2.$(LIBEXT) +else + MODULES += libssh2.nlm + IMPORTS += @$(LIBSSH2_PATH)/nw/libssh2.imp +endif +endif +ifdef WITH_RTMP + # INCLUDES += -I$(LIBRTMP_PATH) +ifdef LINK_STATIC + LDLIBS += $(LIBRTMP_PATH)/librtmp/librtmp.$(LIBEXT) +endif +endif +ifdef WITH_SSL + INCLUDES += -I$(OPENSSL_PATH)/outinc_nw_$(LIBARCH_L) + LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/ssl.$(LIBEXT) + LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/crypto.$(LIBEXT) + IMPORTS += GetProcessSwitchCount RunningProcess +ifdef WITH_SPNEGO + # INCLUDES += -I$(FBOPENSSL_PATH)/include + LDLIBS += $(FBOPENSSL_PATH)/nw/fbopenssl.$(LIBEXT) +endif +else +ifdef WITH_AXTLS + INCLUDES += -I$(AXTLS_PATH)/inc +ifdef LINK_STATIC + LDLIBS += $(AXTLS_PATH)/lib/libaxtls.$(LIBEXT) +else + MODULES += libaxtls.nlm + IMPORTS += $(AXTLS_PATH)/lib/libaxtls.imp +endif +endif +endif +ifdef WITH_ZLIB + # INCLUDES += -I$(ZLIB_PATH) +ifdef LINK_STATIC + LDLIBS += $(ZLIB_PATH)/nw/$(LIBARCH)/libz.$(LIBEXT) +else + MODULES += libz.nlm + IMPORTS += @$(ZLIB_PATH)/nw/$(LIBARCH)/libz.imp +endif +endif +ifdef WITH_IDN + # INCLUDES += -I$(LIBIDN_PATH)/include + LDLIBS += $(LIBIDN_PATH)/lib/libidn.$(LIBEXT) +endif + +ifeq ($(LIBARCH),LIBC) + INCLUDES += -I$(NDK_LIBC)/include + # INCLUDES += -I$(NDK_LIBC)/include/nks + # INCLUDES += -I$(NDK_LIBC)/include/winsock + CFLAGS += -D_POSIX_SOURCE +else + INCLUDES += -I$(NDK_CLIB)/include/nlm + # INCLUDES += -I$(NDK_CLIB)/include +endif +ifndef DISABLE_LDAP + # INCLUDES += -I$(NDK_LDAP)/$(LIBARCH_L)/inc +endif +CFLAGS += $(INCLUDES) + +ifeq ($(MTSAFE),YES) + XDCOPT = -n +endif +ifeq ($(MTSAFE),NO) + XDCOPT = -u +endif +ifdef XDCOPT + XDCDATA = $(OBJDIR)/$(TARGET).xdc +endif + +ifeq ($(findstring /sh,$(SHELL)),/sh) +DL = ' +DS = / +PCT = % +#-include $(NDKBASE)/nlmconv/ncpfs.inc +else +DS = \\ +PCT = %% +endif + +# Makefile.inc provides the CSOURCES and HHEADERS defines +include Makefile.inc + +check_PROGRAMS := $(patsubst %,%.nlm,$(strip $(check_PROGRAMS))) + +.PRECIOUS: $(OBJDIR)/%.o $(OBJDIR)/%.def $(OBJDIR)/%.xdc + + +all: prebuild $(check_PROGRAMS) + +prebuild: $(OBJDIR) $(OBJDIR)/version.inc + +$(OBJDIR)/%.o: %.c + @echo Compiling $< + $(CC) $(CFLAGS) -c $< -o $@ + +$(OBJDIR)/version.inc: $(CURL_INC)/curl/curlver.h $(OBJDIR) + @echo Creating $@ + @$(AWK) -f ../../packages/NetWare/get_ver.awk $< > $@ + +install: $(INSTDIR) all + @$(CP) $(check_PROGRAMS) $(INSTDIR) + +clean: + -$(RM) -r $(OBJDIR) + +distclean vclean: clean + -$(RM) $(check_PROGRAMS) + +$(OBJDIR) $(INSTDIR): + @$(MKDIR) $@ + +%.nlm: $(OBJDIR)/%.o $(OBJDIR)/%.def $(XDCDATA) + @echo Linking $@ + @-$(RM) $@ + @$(LD) $(LDFLAGS) $(OBJDIR)/$(@:.nlm=.def) + +$(OBJDIR)/%.xdc: Makefile.netware + @echo Creating $@ + @$(MPKXDC) $(XDCOPT) $@ + +$(OBJDIR)/%.def: Makefile.netware + @echo $(DL)# DEF file for linking with $(LD)$(DL) > $@ + @echo $(DL)# Do not edit this file - it is created by Make!$(DL) >> $@ + @echo $(DL)# All your changes will be lost!!$(DL) >> $@ + @echo $(DL)#$(DL) >> $@ + @echo $(DL)copyright "$(COPYR)"$(DL) >> $@ + @echo $(DL)description "$(DESCR) $(notdir $(@:.def=)) Example"$(DL) >> $@ + @echo $(DL)version $(VERSION)$(DL) >> $@ +ifdef NLMTYPE + @echo $(DL)type $(NLMTYPE)$(DL) >> $@ +endif +ifdef STACK + @echo $(DL)stack $(STACK)$(DL) >> $@ +endif +ifdef SCREEN + @echo $(DL)screenname "$(DESCR) $(notdir $(@:.def=)) $(SCREEN)"$(DL) >> $@ +else + @echo $(DL)screenname "DEFAULT"$(DL) >> $@ +endif +ifneq ($(DB),NDEBUG) + @echo $(DL)debug$(DL) >> $@ +endif + @echo $(DL)threadname "_$(notdir $(@:.def=))"$(DL) >> $@ +ifdef XDCDATA + @echo $(DL)xdcdata $(XDCDATA)$(DL) >> $@ +endif +ifeq ($(LDRING),0) + @echo $(DL)flag_on 16$(DL) >> $@ +endif +ifeq ($(LDRING),3) + @echo $(DL)flag_on 512$(DL) >> $@ +endif +ifeq ($(LIBARCH),CLIB) + @echo $(DL)start _Prelude$(DL) >> $@ + @echo $(DL)exit _Stop$(DL) >> $@ + @echo $(DL)import @$(NDK_CLIB)/imports/clib.imp$(DL) >> $@ + @echo $(DL)import @$(NDK_CLIB)/imports/threads.imp$(DL) >> $@ + @echo $(DL)import @$(NDK_CLIB)/imports/nlmlib.imp$(DL) >> $@ + @echo $(DL)import @$(NDK_CLIB)/imports/socklib.imp$(DL) >> $@ + @echo $(DL)module clib$(DL) >> $@ +ifndef DISABLE_LDAP + @echo $(DL)import @$(NDK_LDAP)/clib/imports/ldapsdk.imp$(DL) >> $@ + @echo $(DL)import @$(NDK_LDAP)/clib/imports/ldapssl.imp$(DL) >> $@ +# @echo $(DL)import @$(NDK_LDAP)/clib/imports/ldapx.imp$(DL) >> $@ + @echo $(DL)module ldapsdk ldapssl$(DL) >> $@ +endif +else +ifeq ($(POSIXFL),1) + @echo $(DL)flag_on 4194304$(DL) >> $@ +endif + @echo $(DL)flag_on 64$(DL) >> $@ + @echo $(DL)pseudopreemption$(DL) >> $@ +ifeq ($(findstring posixpre,$(PRELUDE)),posixpre) + @echo $(DL)start POSIX_Start$(DL) >> $@ + @echo $(DL)exit POSIX_Stop$(DL) >> $@ + @echo $(DL)check POSIX_CheckUnload$(DL) >> $@ +else + @echo $(DL)start _LibCPrelude$(DL) >> $@ + @echo $(DL)exit _LibCPostlude$(DL) >> $@ + @echo $(DL)check _LibCCheckUnload$(DL) >> $@ +endif + @echo $(DL)import @$(NDK_LIBC)/imports/libc.imp$(DL) >> $@ + @echo $(DL)import @$(NDK_LIBC)/imports/netware.imp$(DL) >> $@ + @echo $(DL)module libc$(DL) >> $@ +ifndef DISABLE_LDAP + @echo $(DL)import @$(NDK_LDAP)/libc/imports/lldapsdk.imp$(DL) >> $@ + @echo $(DL)import @$(NDK_LDAP)/libc/imports/lldapssl.imp$(DL) >> $@ +# @echo $(DL)import @$(NDK_LDAP)/libc/imports/lldapx.imp$(DL) >> $@ + @echo $(DL)module lldapsdk lldapssl$(DL) >> $@ +endif +endif +ifdef MODULES + @echo $(DL)module $(MODULES)$(DL) >> $@ +endif +ifdef EXPORTS + @echo $(DL)export $(EXPORTS)$(DL) >> $@ +endif +ifdef IMPORTS + @echo $(DL)import $(IMPORTS)$(DL) >> $@ +endif +ifeq ($(findstring nlmconv,$(LD)),nlmconv) + @echo $(DL)input $(PRELUDE)$(DL) >> $@ + @echo $(DL)input $(@:.def=.o)$(DL) >> $@ +ifdef LDLIBS + @echo $(DL)input $(LDLIBS)$(DL) >> $@ +endif + @echo $(DL)output $(notdir $(@:.def=.nlm))$(DL) >> $@ +endif diff --git a/docs/examples/README b/docs/examples/README new file mode 100644 index 000000000..270048a6c --- /dev/null +++ b/docs/examples/README @@ -0,0 +1,80 @@ + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + +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 +imap.c - simple IMAP 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 +pop3s.c - POP3S transfer +pop3slist.c - POP3S LIST +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 +url2file.c - download a document and store it in a file +10-at-a-time.c - Download many files simultaneously, 10 at a time. diff --git a/docs/examples/adddocsref.pl b/docs/examples/adddocsref.pl new file mode 100755 index 000000000..2dcc24b63 --- /dev/null +++ b/docs/examples/adddocsref.pl @@ -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"); +} diff --git a/docs/examples/anyauthput.c b/docs/examples/anyauthput.c new file mode 100644 index 000000000..b89dca2e1 --- /dev/null +++ b/docs/examples/anyauthput.c @@ -0,0 +1,185 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include <stdio.h> +#include <fcntl.h> +#ifdef WIN32 +# include <io.h> +#else +# ifdef __VMS + typedef int intptr_t; +# endif +# if !defined(_AIX) && !defined(__sgi) && !defined(__osf__) +# 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 + +#if defined(_AIX) || defined(__sgi) || defined(__osf__) +#ifndef intptr_t +#define intptr_t long +#endif +#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; + curl_off_t nread; + + intptr_t fd = (intptr_t)stream; + + retcode = read(fd, ptr, size * nmemb); + + nread = (curl_off_t)retcode; + + fprintf(stderr, "*** We read %" CURL_FORMAT_CURL_OFF_T + " bytes from file\n", nread); + + 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); + /* Check for errors */ + if(res != CURLE_OK) + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(res)); + + /* always cleanup */ + curl_easy_cleanup(curl); + } + close(hd); /* close the local file */ + + curl_global_cleanup(); + return 0; +} diff --git a/docs/examples/asiohiper.cpp b/docs/examples/asiohiper.cpp new file mode 100644 index 000000000..44836fdc1 --- /dev/null +++ b/docs/examples/asiohiper.cpp @@ -0,0 +1,454 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2012, 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. + * + ***************************************************************************/ + +/* + * file: asiohiper.cpp + * Example program to demonstrate the use of multi socket interface + * with boost::asio + * + * This program is in c++ and uses boost::asio instead of libevent/libev. + * Requires boost::asio, boost::bind and boost::system + * + * This is an adaptation of libcurl's "hiperfifo.c" and "evhiperfifo.c" + * sample programs. This example implements a subset of the functionality from + * hiperfifo.c, for full functionality refer hiperfifo.c or evhiperfifo.c + * + * Written by Lijo Antony based on hiperfifo.c by Jeff Pohlmeyer + * + * When running, the program creates an easy handle for a URL and + * uses the curl_multi API to fetch it. + * + * Note: + * For the sake of simplicity, URL is hard coded to "www.google.com" + * + * This is purely a demo app, all retrieved data is simply discarded by the write + * callback. + */ + + +#include <curl/curl.h> +#include <boost/asio.hpp> +#include <boost/bind.hpp> + +#define MSG_OUT stdout /* Send info to stdout, change to stderr if you want */ + +/* boost::asio related objects + * using global variables for simplicity + */ +boost::asio::io_service io_service; +boost::asio::deadline_timer timer(io_service); +std::map<curl_socket_t, boost::asio::ip::tcp::socket *> socket_map; + +/* Global information, common to all connections */ +typedef struct _GlobalInfo +{ + CURLM *multi; + 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; + +static void timer_cb(const boost::system::error_code & error, GlobalInfo *g); + +/* Update the event timer after curl_multi library calls */ +static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g) +{ + fprintf(MSG_OUT, "\nmulti_timer_cb: timeout_ms %ld", timeout_ms); + + /* cancel running timer */ + timer.cancel(); + + if ( timeout_ms > 0 ) + { + /* update timer */ + timer.expires_from_now(boost::posix_time::millisec(timeout_ms)); + timer.async_wait(boost::bind(&timer_cb, _1, g)); + } + else + { + /* call timeout function immediately */ + boost::system::error_code error; /*success*/ + timer_cb(error, g); + } + + 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, "\nERROR: %s returns %s", where, s); + /* ignore this error */ + return; + } + fprintf(MSG_OUT, "\nERROR: %s returns %s", 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, "\nREMAINING: %d", 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, "\nDONE: %s => (%d) %s", eff_url, res, conn->error); + curl_multi_remove_handle(g->multi, easy); + free(conn->url); + curl_easy_cleanup(easy); + free(conn); + } + } +} + +/* Called by asio when there is an action on a socket */ +static void event_cb(GlobalInfo * g, boost::asio::ip::tcp::socket * tcp_socket, int action) +{ + fprintf(MSG_OUT, "\nevent_cb: action=%d", action); + + CURLMcode rc; + rc = curl_multi_socket_action(g->multi, tcp_socket->native_handle(), 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, "\nlast transfer done, kill timeout"); + timer.cancel(); + } +} + +/* Called by asio when our timeout expires */ +static void timer_cb(const boost::system::error_code & error, GlobalInfo *g) +{ + if ( !error) + { + fprintf(MSG_OUT, "\ntimer_cb: "); + + 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 any data */ +static void remsock(int *f, GlobalInfo *g) +{ + fprintf(MSG_OUT, "\nremsock: "); + + if ( f ) + { + free(f); + } +} + +static void setsock(int *fdp, curl_socket_t s, CURL*e, int act, GlobalInfo*g) +{ + fprintf(MSG_OUT, "\nsetsock: socket=%d, act=%d, fdp=%p", s, act, fdp); + + std::map<curl_socket_t, boost::asio::ip::tcp::socket *>::iterator it = socket_map.find(s); + + if ( it == socket_map.end() ) + { + fprintf(MSG_OUT, "\nsocket %d is a c-ares socket, ignoring", s); + return; + } + + boost::asio::ip::tcp::socket * tcp_socket = it->second; + + *fdp = act; + + if ( act == CURL_POLL_IN ) + { + fprintf(MSG_OUT, "\nwatching for socket to become readable"); + + tcp_socket->async_read_some(boost::asio::null_buffers(), + boost::bind(&event_cb, g, + tcp_socket, + act)); + } + else if ( act == CURL_POLL_OUT ) + { + fprintf(MSG_OUT, "\nwatching for socket to become writable"); + + tcp_socket->async_write_some(boost::asio::null_buffers(), + boost::bind(&event_cb, g, + tcp_socket, + act)); + } + else if ( act == CURL_POLL_INOUT ) + { + fprintf(MSG_OUT, "\nwatching for socket to become readable & writable"); + + tcp_socket->async_read_some(boost::asio::null_buffers(), + boost::bind(&event_cb, g, + tcp_socket, + act)); + + tcp_socket->async_write_some(boost::asio::null_buffers(), + boost::bind(&event_cb, g, + tcp_socket, + act)); + } +} + + +static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g) +{ + int *fdp = (int *)calloc(sizeof(int), 1); /* fdp is used to store current action */ + + 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) +{ + fprintf(MSG_OUT, "\nsock_cb: socket=%d, what=%d, sockp=%p", s, what, sockp); + + GlobalInfo *g = (GlobalInfo*) cbp; + int *actionp = (int*) sockp; + const char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE"}; + + fprintf(MSG_OUT, + "\nsocket callback: s=%d e=%p what=%s ", s, e, whatstr[what]); + + if ( what == CURL_POLL_REMOVE ) + { + fprintf(MSG_OUT, "\n"); + remsock(actionp, g); + } + else + { + if ( !actionp ) + { + fprintf(MSG_OUT, "\nAdding data: %s", whatstr[what]); + addsock(s, e, what, g); + } + else + { + fprintf(MSG_OUT, + "\nChanging action from %s to %s", + whatstr[*actionp], whatstr[what]); + setsock(actionp, 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 written = size * nmemb; + char* pBuffer = (char*)malloc(written + 1); + + strncpy(pBuffer, (const char *)ptr, written); + pBuffer [written] = '\0'; + + fprintf(MSG_OUT, "%s", pBuffer); + + free(pBuffer); + + return written; +} + + +/* 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, "\nProgress: %s (%g/%g)", conn->url, dlnow, dltotal); + fprintf(MSG_OUT, "\nProgress: %s (%g)", conn->url, ult); + + return 0; +} + +/* CURLOPT_OPENSOCKETFUNCTION */ +static curl_socket_t opensocket(void *clientp, + curlsocktype purpose, + struct curl_sockaddr *address) +{ + fprintf(MSG_OUT, "\nopensocket :"); + + curl_socket_t sockfd = CURL_SOCKET_BAD; + + /* restrict to ipv4 */ + if (purpose == CURLSOCKTYPE_IPCXN && address->family == AF_INET) + { + /* create a tcp socket object */ + boost::asio::ip::tcp::socket *tcp_socket = new boost::asio::ip::tcp::socket(io_service); + + /* open it and get the native handle*/ + boost::system::error_code ec; + tcp_socket->open(boost::asio::ip::tcp::v4(), ec); + + if (ec) + { + //An error occurred + std::cout << std::endl << "Couldn't open socket [" << ec << "][" << ec.message() << "]"; + fprintf(MSG_OUT, "\nERROR: Returning CURL_SOCKET_BAD to signal error"); + } + else + { + sockfd = tcp_socket->native_handle(); + fprintf(MSG_OUT, "\nOpened socket %d", sockfd); + + /* save it for monitoring */ + socket_map.insert(std::pair<curl_socket_t, boost::asio::ip::tcp::socket *>(sockfd, tcp_socket)); + } + } + + return sockfd; +} + +/* CURLOPT_CLOSESOCKETFUNCTION */ +static int closesocket(void *clientp, curl_socket_t item) +{ + fprintf(MSG_OUT, "\nclosesocket : %d", item); + + std::map<curl_socket_t, boost::asio::ip::tcp::socket *>::iterator it = socket_map.find(item); + + if ( it != socket_map.end() ) + { + delete it->second; + socket_map.erase(it); + } + + 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 = (ConnInfo *)calloc(1, sizeof(ConnInfo)); + memset(conn, 0, sizeof(ConnInfo)); + conn->error[0]='\0'; + + conn->easy = curl_easy_init(); + + if ( !conn->easy ) + { + fprintf(MSG_OUT, "\ncurl_easy_init() failed, exiting!"); + 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, 1L); + 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); + + /* call this function to get a socket */ + curl_easy_setopt(conn->easy, CURLOPT_OPENSOCKETFUNCTION, opensocket); + + /* call this function to close a socket */ + curl_easy_setopt(conn->easy, CURLOPT_CLOSESOCKETFUNCTION, closesocket); + + fprintf(MSG_OUT, + "\nAdding easy %p to multi %p (%s)", 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 */ +} + +int main(int argc, char **argv) +{ + GlobalInfo g; + CURLMcode rc; + (void)argc; + (void)argv; + + memset(&g, 0, sizeof(GlobalInfo)); + 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, multi_timer_cb); + curl_multi_setopt(g.multi, CURLMOPT_TIMERDATA, &g); + + new_conn((char *)"www.google.com", &g); /* add a URL */ + + /* enter io_service run loop */ + io_service.run(); + + curl_multi_cleanup(g.multi); + + fprintf(MSG_OUT, "\ndone.\n"); + return 0; +} diff --git a/docs/examples/cacertinmem.c b/docs/examples/cacertinmem.c new file mode 100644 index 000000000..051afbca9 --- /dev/null +++ b/docs/examples/cacertinmem.c @@ -0,0 +1,151 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +/* Example using 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; +} diff --git a/docs/examples/certinfo.c b/docs/examples/certinfo.c new file mode 100644 index 000000000..ffcec6356 --- /dev/null +++ b/docs/examples/certinfo.c @@ -0,0 +1,81 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include <stdio.h> + +#include <curl/curl.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; +} diff --git a/docs/examples/chkspeed.c b/docs/examples/chkspeed.c new file mode 100644 index 000000000..b5c397ab7 --- /dev/null +++ b/docs/examples/chkspeed.c @@ -0,0 +1,176 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +/* Example 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> + +#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; +} diff --git a/docs/examples/cookie_interface.c b/docs/examples/cookie_interface.c new file mode 100644 index 000000000..2e7c66db2 --- /dev/null +++ b/docs/examples/cookie_interface.c @@ -0,0 +1,124 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, 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 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", (unsigned long)time(NULL) + 31337UL, "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; +} diff --git a/docs/examples/curlgtk.c b/docs/examples/curlgtk.c new file mode 100644 index 000000000..8cb9914c6 --- /dev/null +++ b/docs/examples/curlgtk.c @@ -0,0 +1,106 @@ +/***************************************************************************** + * _ _ ____ _ + * 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> + +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; +} + diff --git a/docs/examples/curlx.c b/docs/examples/curlx.c new file mode 100644 index 000000000..89d5f407b --- /dev/null +++ b/docs/examples/curlx.c @@ -0,0 +1,513 @@ +/* + 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(SSL_CTX_get_cert_store(ctx), 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); +} diff --git a/docs/examples/debug.c b/docs/examples/debug.c new file mode 100644 index 000000000..3852bf2cc --- /dev/null +++ b/docs/examples/debug.c @@ -0,0 +1,144 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include <stdio.h> +#include <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); + /* Check for errors */ + if(res != CURLE_OK) + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(res)); + + /* always cleanup */ + curl_easy_cleanup(curl); + } + return 0; +} diff --git a/docs/examples/evhiperfifo.c b/docs/examples/evhiperfifo.c new file mode 100644 index 000000000..c2e87fcc5 --- /dev/null +++ b/docs/examples/evhiperfifo.c @@ -0,0 +1,442 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +/* Example 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; +} diff --git a/docs/examples/externalsocket.c b/docs/examples/externalsocket.c new file mode 100644 index 000000000..1b326c8b2 --- /dev/null +++ b/docs/examples/externalsocket.c @@ -0,0 +1,153 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, 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 is an example demonstrating how an application can pass in a custom + * socket to libcurl to use. This example also handles the connect itself. + */ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <curl/curl.h> + +#ifdef WIN32 +#include <windows.h> +#include <winsock2.h> +#include <ws2tcpip.h> +#define close closesocket +#else +#include <sys/types.h> /* socket types */ +#include <sys/socket.h> /* socket definitions */ +#include <netinet/in.h> +#include <arpa/inet.h> /* inet (3) funtions */ +#include <unistd.h> /* misc. UNIX functions */ +#endif + +#include <errno.h> + +/* The IP address and port number to connect to */ +#define IPADDR "127.0.0.1" +#define PORTNUM 80 + +#ifndef INADDR_NONE +#define INADDR_NONE 0xffffffff +#endif + +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; +} + +static curl_socket_t opensocket(void *clientp, + curlsocktype purpose, + struct curl_sockaddr *address) +{ + curl_socket_t sockfd; + (void)purpose; + (void)address; + sockfd = *(curl_socket_t *)clientp; + /* the actual externally set socket is passed in via the OPENSOCKETDATA + option */ + return sockfd; +} + +static int sockopt_callback(void *clientp, curl_socket_t curlfd, + curlsocktype purpose) +{ + (void)clientp; + (void)curlfd; + (void)purpose; + /* This return code was added in libcurl 7.21.5 */ + return CURL_SOCKOPT_ALREADY_CONNECTED; +} + +int main(void) +{ + CURL *curl; + CURLcode res; + struct sockaddr_in servaddr; /* socket address structure */ + curl_socket_t sockfd; + +#ifdef WIN32 + WSADATA wsaData; + int initwsa; + + if((initwsa = WSAStartup(MAKEWORD(2,0), &wsaData)) != 0) { + printf("WSAStartup failed: %d\n", initwsa); + return 1; + } +#endif + + curl = curl_easy_init(); + if(curl) { + /* + * Note that libcurl will internally think that you connect to the host + * and port that you specify in the URL option. + */ + curl_easy_setopt(curl, CURLOPT_URL, "http://99.99.99.99:9999"); + + /* Create the socket "manually" */ + if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) == CURL_SOCKET_BAD ) { + printf("Error creating listening socket.\n"); + return 3; + } + + memset(&servaddr, 0, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(PORTNUM); + + if (INADDR_NONE == (servaddr.sin_addr.s_addr = inet_addr(IPADDR))) + return 2; + + if(connect(sockfd,(struct sockaddr *) &servaddr, sizeof(servaddr)) == + -1) { + close(sockfd); + printf("client error: connect: %s\n", strerror(errno)); + return 1; + } + + /* no progress meter please */ + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L); + + /* send all data to this function */ + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); + + /* call this function to get a socket */ + curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, opensocket); + curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, &sockfd); + + /* call this function to set options for the socket */ + curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback); + + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); + + res = curl_easy_perform(curl); + + curl_easy_cleanup(curl); + + if(res) { + printf("libcurl error: %d\n", res); + return 4; + } + } + return 0; +} diff --git a/docs/examples/fileupload.c b/docs/examples/fileupload.c new file mode 100644 index 000000000..665eca0af --- /dev/null +++ b/docs/examples/fileupload.c @@ -0,0 +1,86 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include <stdio.h> +#include <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); + /* Check for errors */ + if(res != CURLE_OK) { + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(res)); + + } + else { + /* 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; +} diff --git a/docs/examples/fopen.c b/docs/examples/fopen.c new file mode 100644 index 000000000..6fe5c0f9f --- /dev/null +++ b/docs/examples/fopen.c @@ -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 */ +} diff --git a/docs/examples/ftp-wildcard.c b/docs/examples/ftp-wildcard.c new file mode 100644 index 000000000..5a2a10311 --- /dev/null +++ b/docs/examples/ftp-wildcard.c @@ -0,0 +1,148 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include <curl/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, + void *cb_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, + void *cb_data) +{ + struct callback_data *data = cb_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; +} diff --git a/docs/examples/ftpget.c b/docs/examples/ftpget.c new file mode 100644 index 000000000..bcb42bb30 --- /dev/null +++ b/docs/examples/ftpget.c @@ -0,0 +1,94 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include <stdio.h> + +#include <curl/curl.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; +} diff --git a/docs/examples/ftpgetinfo.c b/docs/examples/ftpgetinfo.c new file mode 100644 index 000000000..dfdcf78b7 --- /dev/null +++ b/docs/examples/ftpgetinfo.c @@ -0,0 +1,89 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include <stdio.h> +#include <string.h> + +#include <curl/curl.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; + long filetime = -1; + double filesize = 0.0; + 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 >= 0)) { + time_t file_time = (time_t)filetime; + printf("filetime %s: %s", filename, ctime(&file_time)); + } + res = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &filesize); + if((CURLE_OK == res) && (filesize>0.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; +} diff --git a/docs/examples/ftpgetresp.c b/docs/examples/ftpgetresp.c new file mode 100644 index 000000000..db96a3a13 --- /dev/null +++ b/docs/examples/ftpgetresp.c @@ -0,0 +1,76 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include <stdio.h> + +#include <curl/curl.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); + /* Check for errors */ + if(res != CURLE_OK) + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(res)); + + /* always cleanup */ + curl_easy_cleanup(curl); + } + + fclose(ftpfile); /* close the local file */ + fclose(respfile); /* close the response file */ + + return 0; +} diff --git a/docs/examples/ftpsget.c b/docs/examples/ftpsget.c new file mode 100644 index 000000000..0cfe32024 --- /dev/null +++ b/docs/examples/ftpsget.c @@ -0,0 +1,101 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include <stdio.h> + +#include <curl/curl.h> + +/* + * This is an example showing how to get a single file from an FTPS 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={ + "yourfile.bin", /* 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! Note that we use an + * FTP:// URL with standard explicit FTPS. You can also do FTPS:// URLs if + * you want to do the rarer kind of transfers: implicit. + */ + curl_easy_setopt(curl, CURLOPT_URL, + "ftp://user@server/home/user/file.txt"); + /* 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); + + /* We activate SSL and we require it for both control and data */ + curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL); + + /* 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; +} diff --git a/docs/examples/ftpupload.c b/docs/examples/ftpupload.c new file mode 100644 index 000000000..e79f8d842 --- /dev/null +++ b/docs/examples/ftpupload.c @@ -0,0 +1,140 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include <stdio.h> +#include <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) +{ + curl_off_t nread; + /* 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); + + nread = (curl_off_t)retcode; + + fprintf(stderr, "*** We read %" CURL_FORMAT_CURL_OFF_T + " bytes from file\n", nread); + 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); + /* Check for errors */ + if(res != CURLE_OK) + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(res)); + + /* 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; +} diff --git a/docs/examples/ftpuploadresume.c b/docs/examples/ftpuploadresume.c new file mode 100644 index 000000000..55b8986c7 --- /dev/null +++ b/docs/examples/ftpuploadresume.c @@ -0,0 +1,174 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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. + * + ***************************************************************************/ +/* 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++ */ +#if defined(__MINGW32__) && !defined(__MINGW64__) +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; +} diff --git a/docs/examples/getinfo.c b/docs/examples/getinfo.c new file mode 100644 index 000000000..acbe1e1af --- /dev/null +++ b/docs/examples/getinfo.c @@ -0,0 +1,53 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include <stdio.h> +#include <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; +} diff --git a/docs/examples/getinmemory.c b/docs/examples/getinmemory.c new file mode 100644 index 000000000..78e6deb10 --- /dev/null +++ b/docs/examples/getinmemory.c @@ -0,0 +1,112 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +/* Example 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 *contents, size_t size, size_t nmemb, void *userp) +{ + size_t realsize = size * nmemb; + struct MemoryStruct *mem = (struct MemoryStruct *)userp; + + mem->memory = realloc(mem->memory, mem->size + realsize + 1); + if (mem->memory == NULL) { + /* out of memory! */ + printf("not enough memory (realloc returned NULL)\n"); + exit(EXIT_FAILURE); + } + + memcpy(&(mem->memory[mem->size]), contents, 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; +} diff --git a/docs/examples/ghiper.c b/docs/examples/ghiper.c new file mode 100644 index 000000000..9a3f46d3f --- /dev/null +++ b/docs/examples/ghiper.c @@ -0,0 +1,452 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +/* Example 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; +} diff --git a/docs/examples/hiperfifo.c b/docs/examples/hiperfifo.c new file mode 100644 index 000000000..6036643b1 --- /dev/null +++ b/docs/examples/hiperfifo.c @@ -0,0 +1,418 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +/* Example 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; +} diff --git a/docs/examples/href_extractor.c b/docs/examples/href_extractor.c new file mode 100644 index 000000000..4b307a29e --- /dev/null +++ b/docs/examples/href_extractor.c @@ -0,0 +1,86 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2012, 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 example uses the "Streaming HTML parser" to extract the href pieces in + * a streaming manner from a downloaded HTML. Kindly donated by Michał + * Kowalczyk. + * + * The parser is found at + * http://code.google.com/p/htmlstreamparser/ + */ + +#include <stdio.h> +#include <curl/curl.h> +#include <htmlstreamparser.h> + + +static size_t write_callback(void *buffer, size_t size, size_t nmemb, + void *hsp) +{ + size_t realsize = size * nmemb, p; + for (p = 0; p < realsize; p++) { + html_parser_char_parse(hsp, ((char *)buffer)[p]); + if (html_parser_cmp_tag(hsp, "a", 1)) + if (html_parser_cmp_attr(hsp, "href", 4)) + if (html_parser_is_in(hsp, HTML_VALUE_ENDED)) { + html_parser_val(hsp)[html_parser_val_length(hsp)] = '\0'; + printf("%s\n", html_parser_val(hsp)); + } + } + return realsize; +} + +int main(int argc, char *argv[]) +{ + char tag[1], attr[4], val[128]; + CURL *curl; + HTMLSTREAMPARSER *hsp; + + if (argc != 2) { + printf("Usage: %s URL\n", argv[0]); + return EXIT_FAILURE; + } + + curl = curl_easy_init(); + + hsp = html_parser_init(); + + html_parser_set_tag_to_lower(hsp, 1); + html_parser_set_attr_to_lower(hsp, 1); + html_parser_set_tag_buffer(hsp, tag, sizeof(tag)); + html_parser_set_attr_buffer(hsp, attr, sizeof(attr)); + html_parser_set_val_buffer(hsp, val, sizeof(val)-1); + + curl_easy_setopt(curl, CURLOPT_URL, argv[1]); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, hsp); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); + + curl_easy_perform(curl); + + curl_easy_cleanup(curl); + + html_parser_cleanup(hsp); + + return EXIT_SUCCESS; +} diff --git a/docs/examples/htmltidy.c b/docs/examples/htmltidy.c new file mode 100644 index 000000000..a36e331bf --- /dev/null +++ b/docs/examples/htmltidy.c @@ -0,0 +1,130 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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. + * + ***************************************************************************/ +/* 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); +} diff --git a/docs/examples/htmltitle.cpp b/docs/examples/htmltitle.cpp new file mode 100644 index 000000000..55a7935ac --- /dev/null +++ b/docs/examples/htmltitle.cpp @@ -0,0 +1,313 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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. + * + ***************************************************************************/ +// 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; +} diff --git a/docs/examples/http-post.c b/docs/examples/http-post.c new file mode 100644 index 000000000..f1975b1ec --- /dev/null +++ b/docs/examples/http-post.c @@ -0,0 +1,55 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include <stdio.h> +#include <curl/curl.h> + +int main(void) +{ + CURL *curl; + CURLcode res; + + /* In windows, this will init the winsock stuff */ + curl_global_init(CURL_GLOBAL_ALL); + + /* get a curl handle */ + 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); + /* Check for errors */ + if(res != CURLE_OK) + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(res)); + + /* always cleanup */ + curl_easy_cleanup(curl); + } + curl_global_cleanup(); + return 0; +} diff --git a/docs/examples/httpcustomheader.c b/docs/examples/httpcustomheader.c new file mode 100644 index 000000000..07ff95997 --- /dev/null +++ b/docs/examples/httpcustomheader.c @@ -0,0 +1,61 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include <stdio.h> +#include <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); + /* Check for errors */ + if(res != CURLE_OK) + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(res)); + + /* redo request with our own custom Accept: */ + res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk); + res = curl_easy_perform(curl); + /* Check for errors */ + if(res != CURLE_OK) + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(res)); + + /* always cleanup */ + curl_easy_cleanup(curl); + + /* free the custom headers */ + curl_slist_free_all(chunk); + } + return 0; +} diff --git a/docs/examples/httpput.c b/docs/examples/httpput.c new file mode 100644 index 000000000..fbbca9448 --- /dev/null +++ b/docs/examples/httpput.c @@ -0,0 +1,125 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include <stdio.h> +#include <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; + curl_off_t nread; + + /* 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); + + nread = (curl_off_t)retcode; + + fprintf(stderr, "*** We read %" CURL_FORMAT_CURL_OFF_T + " bytes from file\n", nread); + + 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); + /* Check for errors */ + if(res != CURLE_OK) + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(res)); + + /* always cleanup */ + curl_easy_cleanup(curl); + } + fclose(hd_src); /* close the local file */ + + curl_global_cleanup(); + return 0; +} diff --git a/docs/examples/https.c b/docs/examples/https.c new file mode 100644 index 000000000..bd9a33ba6 --- /dev/null +++ b/docs/examples/https.c @@ -0,0 +1,74 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include <stdio.h> +#include <curl/curl.h> + +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://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_VERIFICATION + /* + * 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 + + /* Perform the request, res will get the return code */ + res = curl_easy_perform(curl); + /* Check for errors */ + if(res != CURLE_OK) + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(res)); + + /* always cleanup */ + curl_easy_cleanup(curl); + } + + curl_global_cleanup(); + + return 0; +} diff --git a/docs/examples/imap.c b/docs/examples/imap.c new file mode 100644 index 000000000..ba07f022a --- /dev/null +++ b/docs/examples/imap.c @@ -0,0 +1,44 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include <stdio.h> +#include <curl/curl.h> + +int main(void) +{ + CURL *curl; + CURLcode res = CURLE_OK; + + curl = curl_easy_init(); + if(curl) { + /* Set username and password */ + curl_easy_setopt(curl, CURLOPT_USERPWD, "user:password"); + + /* This will fetch the mailbox named "foobar" */ + curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com/foobar"); + + res = curl_easy_perform(curl); + + /* always cleanup */ + curl_easy_cleanup(curl); + } + return (int)res; +} diff --git a/docs/examples/makefile.dj b/docs/examples/makefile.dj new file mode 100644 index 000000000..c18ef8a70 --- /dev/null +++ b/docs/examples/makefile.dj @@ -0,0 +1,60 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2011, 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. +# +########################################################################### +# +# Adapted for djgpp / Watt-32 / DOS by +# Gisle Vanem <gvanem@broadpark.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 + diff --git a/docs/examples/multi-app.c b/docs/examples/multi-app.c new file mode 100644 index 000000000..a5f71c5ac --- /dev/null +++ b/docs/examples/multi-app.c @@ -0,0 +1,153 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 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); + + do { + 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; + } + } while(still_running); + + /* 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; +} diff --git a/docs/examples/multi-debugcallback.c b/docs/examples/multi-debugcallback.c new file mode 100644 index 000000000..8eedcee5b --- /dev/null +++ b/docs/examples/multi-debugcallback.c @@ -0,0 +1,205 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 is an example showing 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); + + do { + 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; + } + } while(still_running); + + curl_multi_cleanup(multi_handle); + + curl_easy_cleanup(http_handle); + + return 0; +} diff --git a/docs/examples/multi-double.c b/docs/examples/multi-double.c new file mode 100644 index 000000000..91422e6e2 --- /dev/null +++ b/docs/examples/multi-double.c @@ -0,0 +1,119 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include <stdio.h> +#include <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); + + do { + 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; + } + } while(still_running); + + curl_multi_cleanup(multi_handle); + + curl_easy_cleanup(http_handle); + curl_easy_cleanup(http_handle2); + + return 0; +} diff --git a/docs/examples/multi-post.c b/docs/examples/multi-post.c new file mode 100644 index 000000000..965a2c3f6 --- /dev/null +++ b/docs/examples/multi-post.c @@ -0,0 +1,148 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 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); + + do { + 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; + } + } while(still_running); + + 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; +} diff --git a/docs/examples/multi-single.c b/docs/examples/multi-single.c new file mode 100644 index 000000000..aeda71419 --- /dev/null +++ b/docs/examples/multi-single.c @@ -0,0 +1,116 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 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); + + do { + 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; + } + } while(still_running); + + curl_multi_cleanup(multi_handle); + + curl_easy_cleanup(http_handle); + + return 0; +} diff --git a/docs/examples/multithread.c b/docs/examples/multithread.c new file mode 100644 index 000000000..831a07467 --- /dev/null +++ b/docs/examples/multithread.c @@ -0,0 +1,93 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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. + * + ***************************************************************************/ +/* 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; +} diff --git a/docs/examples/opensslthreadlock.c b/docs/examples/opensslthreadlock.c new file mode 100644 index 000000000..ad54f08ea --- /dev/null +++ b/docs/examples/opensslthreadlock.c @@ -0,0 +1,94 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +/* Example 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; +} diff --git a/docs/examples/persistant.c b/docs/examples/persistant.c new file mode 100644 index 000000000..0917dfdb8 --- /dev/null +++ b/docs/examples/persistant.c @@ -0,0 +1,64 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include <stdio.h> +#include <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/"); + + /* Perform the request, res will get the return code */ + res = curl_easy_perform(curl); + /* Check for errors */ + if(res != CURLE_OK) + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(res)); + + /* get another document from the same server using the same + connection */ + curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/docs/"); + + /* Perform the request, res will get the return code */ + res = curl_easy_perform(curl); + /* Check for errors */ + if(res != CURLE_OK) + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(res)); + + /* always cleanup */ + curl_easy_cleanup(curl); + } + + return 0; +} diff --git a/docs/examples/pop3s.c b/docs/examples/pop3s.c new file mode 100644 index 000000000..44d7c80d0 --- /dev/null +++ b/docs/examples/pop3s.c @@ -0,0 +1,73 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include <stdio.h> +#include <curl/curl.h> + +int main(void) +{ + CURL *curl; + CURLcode res; + + curl = curl_easy_init(); + if(curl) { + /* Set username and password */ + curl_easy_setopt(curl, CURLOPT_USERPWD, "user:password"); + + /* This will only fetch the message with ID "1" of the given mailbox */ + curl_easy_setopt(curl, CURLOPT_URL, "pop3s://user@pop.example.com/1"); + +#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 + + /* Perform the request, res will get the return code */ + res = curl_easy_perform(curl); + /* Check for errors */ + if(res != CURLE_OK) + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(res)); + + /* always cleanup */ + curl_easy_cleanup(curl); + } + return 0; +} diff --git a/docs/examples/pop3slist.c b/docs/examples/pop3slist.c new file mode 100644 index 000000000..9d9668fa0 --- /dev/null +++ b/docs/examples/pop3slist.c @@ -0,0 +1,73 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include <stdio.h> +#include <curl/curl.h> + +int main(void) +{ + CURL *curl; + CURLcode res; + + curl = curl_easy_init(); + if(curl) { + /* Set username and password */ + curl_easy_setopt(curl, CURLOPT_USERPWD, "user:password"); + + /* This will list every message of the given mailbox */ + curl_easy_setopt(curl, CURLOPT_URL, "pop3s://user@pop.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 + + /* Perform the request, res will get the return code */ + res = curl_easy_perform(curl); + /* Check for errors */ + if(res != CURLE_OK) + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(res)); + + /* always cleanup */ + curl_easy_cleanup(curl); + } + return 0; +} diff --git a/docs/examples/post-callback.c b/docs/examples/post-callback.c new file mode 100644 index 000000000..3e1cfb060 --- /dev/null +++ b/docs/examples/post-callback.c @@ -0,0 +1,143 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, 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. + * + ***************************************************************************/ +/* 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; + long 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 = (long)strlen(data); + + /* In windows, this will init the winsock stuff */ + res = curl_global_init(CURL_GLOBAL_DEFAULT); + /* Check for errors */ + if(res != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed: %s\n", + curl_easy_strerror(res)); + return 1; + } + + /* get a curl handle */ + 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, 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); + /* Check for errors */ + if(res != CURLE_OK) + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(res)); + + /* always cleanup */ + curl_easy_cleanup(curl); + } + curl_global_cleanup(); + return 0; +} diff --git a/docs/examples/postit2.c b/docs/examples/postit2.c new file mode 100644 index 000000000..67dcc1330 --- /dev/null +++ b/docs/examples/postit2.c @@ -0,0 +1,103 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +/* Example 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> + +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); + + /* Perform the request, res will get the return code */ + res = curl_easy_perform(curl); + /* Check for errors */ + if(res != CURLE_OK) + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(res)); + + /* always cleanup */ + curl_easy_cleanup(curl); + + /* then cleanup the formpost chain */ + curl_formfree(formpost); + /* free slist */ + curl_slist_free_all (headerlist); + } + return 0; +} diff --git a/docs/examples/progressfunc.c b/docs/examples/progressfunc.c new file mode 100644 index 000000000..51a9c9b5e --- /dev/null +++ b/docs/examples/progressfunc.c @@ -0,0 +1,84 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include <stdio.h> +#include <curl/curl.h> + +#define STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES 6000 +#define MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL 3 + +struct myprogress { + double lastruntime; + CURL *curl; +}; + +static int progress(void *p, + double dltotal, double dlnow, + double ultotal, double ulnow) +{ + struct myprogress *myp = (struct myprogress *)p; + CURL *curl = myp->curl; + double curtime = 0; + + curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &curtime); + + /* under certain circumstances it may be desirable for certain functionality + to only run every N seconds, in order to do this the transaction time can + be used */ + if((curtime - myp->lastruntime) >= MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL) { + myp->lastruntime = curtime; + fprintf(stderr, "TOTAL TIME: %f \r\n", curtime); + } + + fprintf(stderr, "UP: %g of %g DOWN: %g of %g\r\n", + ulnow, ultotal, dlnow, dltotal); + + if(dlnow > STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES) + return 1; + return 0; +} + +int main(void) +{ + CURL *curl; + CURLcode res = CURLE_OK; + struct myprogress prog; + + curl = curl_easy_init(); + if(curl) { + prog.lastruntime = 0; + prog.curl = curl; + + curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/"); + curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress); + /* pass the struct pointer into the progress function */ + curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &prog); + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); + res = curl_easy_perform(curl); + + if(res != CURLE_OK) + fprintf(stderr, "%s\n", curl_easy_strerror(res)); + + /* always cleanup */ + curl_easy_cleanup(curl); + } + return (int)res; +} diff --git a/docs/examples/resolve.c b/docs/examples/resolve.c new file mode 100644 index 000000000..7b3e5656e --- /dev/null +++ b/docs/examples/resolve.c @@ -0,0 +1,51 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include <stdio.h> +#include <curl/curl.h> + +int main(void) +{ + CURL *curl; + CURLcode res = CURLE_OK; + struct curl_slist *host = NULL; + + /* Each single name resolve string should be written using the format + HOST:PORT:ADDRESS where HOST is the name libcurl will try to resolve, + PORT is the port number of the service where libcurl wants to connect to + the HOST and ADDRESS is the numerical IP address + */ + host = curl_slist_append(NULL, "example.com:80:127.0.0.1"); + + curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_RESOLVE, host); + curl_easy_setopt(curl, CURLOPT_URL, "http://example.com"); + res = curl_easy_perform(curl); + + /* always cleanup */ + curl_easy_cleanup(curl); + } + + curl_slist_free_all(host); + + return (int)res; +} diff --git a/docs/examples/rtsp.c b/docs/examples/rtsp.c new file mode 100644 index 000000000..669780a9b --- /dev/null +++ b/docs/examples/rtsp.c @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2011, Jim Hollinger + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Jim Hollinger nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * OWNER OR 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. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#if defined (WIN32) +# include <conio.h> /* _getch() */ +#else +# include <termios.h> +# include <unistd.h> + +static int _getch(void) +{ + struct termios oldt, newt; + int ch; + tcgetattr( STDIN_FILENO, &oldt ); + newt = oldt; + newt.c_lflag &= ~( ICANON | ECHO ); + tcsetattr( STDIN_FILENO, TCSANOW, &newt ); + ch = getchar(); + tcsetattr( STDIN_FILENO, TCSANOW, &oldt ); + return ch; +} +#endif + +#include <curl/curl.h> + +#define VERSION_STR "V1.0" + +/* error handling macros */ +#define my_curl_easy_setopt(A, B, C) \ + if ((res = curl_easy_setopt((A), (B), (C))) != CURLE_OK) \ + fprintf(stderr, "curl_easy_setopt(%s, %s, %s) failed: %d\n", \ + #A, #B, #C, res); + +#define my_curl_easy_perform(A) \ + if ((res = curl_easy_perform((A))) != CURLE_OK) \ + fprintf(stderr, "curl_easy_perform(%s) failed: %d\n", #A, res); + + +/* send RTSP OPTIONS request */ +static void rtsp_options(CURL *curl, const char *uri) +{ + CURLcode res = CURLE_OK; + printf("\nRTSP: OPTIONS %s\n", uri); + my_curl_easy_setopt(curl, CURLOPT_RTSP_STREAM_URI, uri); + my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_OPTIONS); + my_curl_easy_perform(curl); +} + + +/* send RTSP DESCRIBE request and write sdp response to a file */ +static void rtsp_describe(CURL *curl, const char *uri, + const char *sdp_filename) +{ + CURLcode res = CURLE_OK; + FILE *sdp_fp = fopen(sdp_filename, "wt"); + printf("\nRTSP: DESCRIBE %s\n", uri); + if (sdp_fp == NULL) { + fprintf(stderr, "Could not open '%s' for writing\n", sdp_filename); + sdp_fp = stdout; + } + else { + printf("Writing SDP to '%s'\n", sdp_filename); + } + my_curl_easy_setopt(curl, CURLOPT_WRITEDATA, sdp_fp); + my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_DESCRIBE); + my_curl_easy_perform(curl); + my_curl_easy_setopt(curl, CURLOPT_WRITEDATA, stdout); + if (sdp_fp != stdout) { + fclose(sdp_fp); + } +} + +/* send RTSP SETUP request */ +static void rtsp_setup(CURL *curl, const char *uri, const char *transport) +{ + CURLcode res = CURLE_OK; + printf("\nRTSP: SETUP %s\n", uri); + printf(" TRANSPORT %s\n", transport); + my_curl_easy_setopt(curl, CURLOPT_RTSP_STREAM_URI, uri); + my_curl_easy_setopt(curl, CURLOPT_RTSP_TRANSPORT, transport); + my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_SETUP); + my_curl_easy_perform(curl); +} + + +/* send RTSP PLAY request */ +static void rtsp_play(CURL *curl, const char *uri, const char *range) +{ + CURLcode res = CURLE_OK; + printf("\nRTSP: PLAY %s\n", uri); + my_curl_easy_setopt(curl, CURLOPT_RTSP_STREAM_URI, uri); + my_curl_easy_setopt(curl, CURLOPT_RANGE, range); + my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_PLAY); + my_curl_easy_perform(curl); +} + + +/* send RTSP TEARDOWN request */ +static void rtsp_teardown(CURL *curl, const char *uri) +{ + CURLcode res = CURLE_OK; + printf("\nRTSP: TEARDOWN %s\n", uri); + my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_TEARDOWN); + my_curl_easy_perform(curl); +} + + +/* convert url into an sdp filename */ +static void get_sdp_filename(const char *url, char *sdp_filename) +{ + const char *s = strrchr(url, '/'); + strcpy(sdp_filename, "video.sdp"); + if (s != NULL) { + s++; + if (s[0] != '\0') { + sprintf(sdp_filename, "%s.sdp", s); + } + } +} + + +/* scan sdp file for media control attribute */ +static void get_media_control_attribute(const char *sdp_filename, + char *control) +{ + int max_len = 256; + char *s = malloc(max_len); + FILE *sdp_fp = fopen(sdp_filename, "rt"); + control[0] = '\0'; + if (sdp_fp != NULL) { + while (fgets(s, max_len - 2, sdp_fp) != NULL) { + sscanf(s, " a = control: %s", control); + } + fclose(sdp_fp); + } + free(s); +} + + +/* main app */ +int main(int argc, char * const argv[]) +{ +#if 1 + const char *transport = "RTP/AVP;unicast;client_port=1234-1235"; /* UDP */ +#else + const char *transport = "RTP/AVP/TCP;unicast;client_port=1234-1235"; /* TCP */ +#endif + const char *range = "0.000-"; + int rc = EXIT_SUCCESS; + char *base_name = NULL; + + printf("\nRTSP request %s\n", VERSION_STR); + printf(" Project web site: http://code.google.com/p/rtsprequest/\n"); + printf(" Requires cURL V7.20 or greater\n\n"); + + /* check command line */ + if ((argc != 2) && (argc != 3)) { + base_name = strrchr(argv[0], '/'); + if (base_name == NULL) { + base_name = strrchr(argv[0], '\\'); + } + if (base_name == NULL) { + base_name = argv[0]; + } else { + base_name++; + } + printf("Usage: %s url [transport]\n", base_name); + printf(" url of video server\n"); + printf(" transport (optional) specifier for media stream protocol\n"); + printf(" default transport: %s\n", transport); + printf("Example: %s rtsp://192.168.0.2/media/video1\n\n", base_name); + rc = EXIT_FAILURE; + } else { + const char *url = argv[1]; + char *uri = malloc(strlen(url) + 32); + char *sdp_filename = malloc(strlen(url) + 32); + char *control = malloc(strlen(url) + 32); + CURLcode res; + get_sdp_filename(url, sdp_filename); + if (argc == 3) { + transport = argv[2]; + } + + /* initialize curl */ + res = curl_global_init(CURL_GLOBAL_ALL); + if (res == CURLE_OK) { + curl_version_info_data *data = curl_version_info(CURLVERSION_NOW); + CURL *curl; + fprintf(stderr, " cURL V%s loaded\n", data->version); + + /* initialize this curl session */ + curl = curl_easy_init(); + if (curl != NULL) { + my_curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L); + my_curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L); + my_curl_easy_setopt(curl, CURLOPT_WRITEHEADER, stdout); + my_curl_easy_setopt(curl, CURLOPT_URL, url); + + /* request server options */ + sprintf(uri, "%s", url); + rtsp_options(curl, uri); + + /* request session description and write response to sdp file */ + rtsp_describe(curl, uri, sdp_filename); + + /* get media control attribute from sdp file */ + get_media_control_attribute(sdp_filename, control); + + /* setup media stream */ + sprintf(uri, "%s/%s", url, control); + rtsp_setup(curl, uri, transport); + + /* start playing media stream */ + sprintf(uri, "%s/", url); + rtsp_play(curl, uri, range); + printf("Playing video, press any key to stop ..."); + _getch(); + printf("\n"); + + /* teardown session */ + rtsp_teardown(curl, uri); + + /* cleanup */ + curl_easy_cleanup(curl); + curl = NULL; + } else { + fprintf(stderr, "curl_easy_init() failed\n"); + } + curl_global_cleanup(); + } else { + fprintf(stderr, "curl_global_init(%s) failed: %d\n", + "CURL_GLOBAL_ALL", res); + } + free(control); + free(sdp_filename); + free(uri); + } + + return rc; +} diff --git a/docs/examples/sampleconv.c b/docs/examples/sampleconv.c new file mode 100644 index 000000000..3db316096 --- /dev/null +++ b/docs/examples/sampleconv.c @@ -0,0 +1,107 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 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; +} diff --git a/docs/examples/sendrecv.c b/docs/examples/sendrecv.c new file mode 100644 index 000000000..88fddf59f --- /dev/null +++ b/docs/examples/sendrecv.c @@ -0,0 +1,135 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, 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. + * + ***************************************************************************/ +/* 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_off_t nread; + + 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; + + nread = (curl_off_t)iolen; + + printf("Received %" CURL_FORMAT_CURL_OFF_T " bytes.\n", nread); + } + + /* always cleanup */ + curl_easy_cleanup(curl); + } + return 0; +} diff --git a/docs/examples/sepheaders.c b/docs/examples/sepheaders.c new file mode 100644 index 000000000..afa14fc85 --- /dev/null +++ b/docs/examples/sepheaders.c @@ -0,0 +1,85 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include <curl/curl.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; +} diff --git a/docs/examples/sftpget.c b/docs/examples/sftpget.c new file mode 100644 index 000000000..8317462e9 --- /dev/null +++ b/docs/examples/sftpget.c @@ -0,0 +1,106 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include <stdio.h> + +#include <curl/curl.h> + +/* define this to switch off the use of ssh-agent in this program */ +#undef DISABLE_SSH_AGENT + +/* + * This is an example showing how to get a single file from an SFTP 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={ + "yourfile.bin", /* 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, + "sftp://user@server/home/user/file.txt"); + /* 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); + +#ifndef DISABLE_SSH_AGENT + /* We activate ssh agent. For this to work you need + to have ssh-agent running (type set | grep SSH_AGENT to check) or + pageant on Windows (there is an icon in systray if so) */ + curl_easy_setopt(curl, CURLOPT_SSH_AUTH_TYPES, CURLSSH_AUTH_AGENT); +#endif + + /* 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; +} diff --git a/docs/examples/simple.c b/docs/examples/simple.c new file mode 100644 index 000000000..cb23b7ae3 --- /dev/null +++ b/docs/examples/simple.c @@ -0,0 +1,45 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include <stdio.h> +#include <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"); + + /* Perform the request, res will get the return code */ + res = curl_easy_perform(curl); + /* Check for errors */ + if(res != CURLE_OK) + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(res)); + + /* always cleanup */ + curl_easy_cleanup(curl); + } + return 0; +} diff --git a/docs/examples/simplepost.c b/docs/examples/simplepost.c new file mode 100644 index 000000000..8657771f4 --- /dev/null +++ b/docs/examples/simplepost.c @@ -0,0 +1,53 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include <stdio.h> +#include <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)); + + /* Perform the request, res will get the return code */ + res = curl_easy_perform(curl); + /* Check for errors */ + if(res != CURLE_OK) + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(res)); + + /* always cleanup */ + curl_easy_cleanup(curl); + } + return 0; +} diff --git a/docs/examples/simplesmtp.c b/docs/examples/simplesmtp.c new file mode 100644 index 000000000..df8516242 --- /dev/null +++ b/docs/examples/simplesmtp.c @@ -0,0 +1,87 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include <stdio.h> +#include <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); + /* Check for errors */ + if(res != CURLE_OK) + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(res)); + + /* 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; +} diff --git a/docs/examples/simplessl.c b/docs/examples/simplessl.c new file mode 100644 index 000000000..74c58461a --- /dev/null +++ b/docs/examples/simplessl.c @@ -0,0 +1,138 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include <stdio.h> + +#include <curl/curl.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) +{ + int i; + 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); + + for(i = 0; i < 1; i++) /* single-iteration loop, just to break out from */ + { + 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); + + /* Perform the request, res will get the return code */ + res = curl_easy_perform(curl); + /* Check for errors */ + if(res != CURLE_OK) + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(res)); + + /* we are done... */ + } + /* always cleanup */ + curl_easy_cleanup(curl); + } + + curl_global_cleanup(); + + return 0; +} diff --git a/docs/examples/smooth-gtk-thread.c b/docs/examples/smooth-gtk-thread.c new file mode 100644 index 000000000..932f6e396 --- /dev/null +++ b/docs/examples/smooth-gtk-thread.c @@ -0,0 +1,228 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 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> + +#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; +} + diff --git a/docs/examples/smtp-multi.c b/docs/examples/smtp-multi.c new file mode 100644 index 000000000..6462aff2d --- /dev/null +++ b/docs/examples/smtp-multi.c @@ -0,0 +1,203 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 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; + 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, (long)CURLUSESSL_ALL); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_READDATA, &pooh); + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(curl, CURLOPT_SSLVERSION, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_SESSIONID_CACHE, 0L); + curl_multi_add_handle(mcurl, curl); + + 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; +} + + diff --git a/docs/examples/smtp-tls.c b/docs/examples/smtp-tls.c new file mode 100644 index 000000000..3635c103f --- /dev/null +++ b/docs/examples/smtp-tls.c @@ -0,0 +1,152 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include <stdio.h> +#include <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, (long)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, 0L); + * curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + * 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, 1L); + + /* send the message (including headers) */ + res = curl_easy_perform(curl); + /* Check for errors */ + if(res != CURLE_OK) + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(res)); + + /* free the list of recipients and clean up */ + curl_slist_free_all(recipients); + curl_easy_cleanup(curl); + } + return 0; +} diff --git a/docs/examples/synctime.c b/docs/examples/synctime.c new file mode 100644 index 000000000..14d77de27 --- /dev/null +++ b/docs/examples/synctime.c @@ -0,0 +1,366 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 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 %hu %s %hu %hu:%hu:%hu", + 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; +} diff --git a/docs/examples/threaded-ssl.c b/docs/examples/threaded-ssl.c new file mode 100644 index 000000000..a7e9c2de1 --- /dev/null +++ b/docs/examples/threaded-ssl.c @@ -0,0 +1,162 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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. + * + ***************************************************************************/ +/* 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; +} diff --git a/docs/examples/url2file.c b/docs/examples/url2file.c new file mode 100644 index 000000000..64d27c88f --- /dev/null +++ b/docs/examples/url2file.c @@ -0,0 +1,81 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include <curl/curl.h> + +static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream) +{ + size_t written = fwrite(ptr, size, nmemb, (FILE *)stream); + return written; +} + +int main(int argc, char *argv[]) +{ + CURL *curl_handle; + static const char *pagefilename = "page.out"; + FILE *pagefile; + + if(argc < 2 ) { + printf("Usage: %s <URL>\n", argv[0]); + return 1; + } + + curl_global_init(CURL_GLOBAL_ALL); + + /* init the curl session */ + curl_handle = curl_easy_init(); + + /* set URL to get here */ + curl_easy_setopt(curl_handle, CURLOPT_URL, argv[1]); + + /* Switch on full protocol/debug output while testing */ + curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L); + + /* disable progress meter, set to 0L to enable and disable debug output */ + 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 file */ + pagefile = fopen(pagefilename, "wb"); + if (pagefile) { + + /* write the page body to this file handle. CURLOPT_FILE is also known as + CURLOPT_WRITEDATA*/ + curl_easy_setopt(curl_handle, CURLOPT_FILE, pagefile); + + /* get it! */ + curl_easy_perform(curl_handle); + + /* close the header file */ + fclose(pagefile); + } + + /* cleanup curl stuff */ + curl_easy_cleanup(curl_handle); + + return 0; +} diff --git a/docs/examples/version-check.pl b/docs/examples/version-check.pl new file mode 100755 index 000000000..92f0808d6 --- /dev/null +++ b/docs/examples/version-check.pl @@ -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; +} + + diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 000000000..4390378af --- /dev/null +++ b/docs/index.html @@ -0,0 +1,20 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html><head> +<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> +<title>Index to Curl documentation</title> +</head> + +<body> +<h1 align="center">Index to Curl documentation</h1> + +<h2>Programs</h2> +<a href="curl-config.html">curl-config</A> +<br><a href="curl.html">curl</A> + +<h2>Tutorial</h2> +<a href="TheArtOfHttpScripting">The Art Of Scripting HTTP Requests Using Curl</a> (plain text) + +<h2>libcurl</h2> +See the <a href="libcurl/index.html">libcurl section</a> + +</body></html> diff --git a/docs/libcurl/.gitignore b/docs/libcurl/.gitignore new file mode 100644 index 000000000..23f832b73 --- /dev/null +++ b/docs/libcurl/.gitignore @@ -0,0 +1,2 @@ +*.html +*.pdf diff --git a/docs/libcurl/ABI b/docs/libcurl/ABI new file mode 100644 index 000000000..3ec0e04de --- /dev/null +++ b/docs/libcurl/ABI @@ -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 diff --git a/docs/libcurl/Makefile.am b/docs/libcurl/Makefile.am new file mode 100644 index 000000000..3114e2b3b --- /dev/null +++ b/docs/libcurl/Makefile.am @@ -0,0 +1,102 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2012, 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. +# +########################################################################### + +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 curl_multi_wait.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 curl_multi_wait.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 curl_multi_wait.pdf + +CLEANFILES = $(HTMLPAGES) $(PDFPAGES) + +EXTRA_DIST = $(man_MANS) $(HTMLPAGES) index.html $(PDFPAGES) libcurl.m4 ABI \ + symbols-in-versions symbols.pl +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 $@") diff --git a/docs/libcurl/curl_easy_cleanup.3 b/docs/libcurl/curl_easy_cleanup.3 new file mode 100644 index 000000000..d8a3f9fcf --- /dev/null +++ b/docs/libcurl/curl_easy_cleanup.3 @@ -0,0 +1,57 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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. + +Occasionally you may get your progress callback or header callback called from +within \fIcurl_easy_cleanup(3)\fP (if previously set for the handle using +\fIcurl_easy_setopt(3)\fP). Like if libcurl decides to shut down the +connection and the protocol is of a kind that requires a command/response +sequence before disconnect. Examples of such protocols are FTP, POP3 and IMAP. + +Any uses of the \fBhandle\fP after this function has been called and have +returned, 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), " + diff --git a/docs/libcurl/curl_easy_duphandle.3 b/docs/libcurl/curl_easy_duphandle.3 new file mode 100644 index 000000000..e53ced48b --- /dev/null +++ b/docs/libcurl/curl_easy_duphandle.3 @@ -0,0 +1,51 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_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) + diff --git a/docs/libcurl/curl_easy_escape.3 b/docs/libcurl/curl_easy_escape.3 new file mode 100644 index 000000000..3a98e6fe8 --- /dev/null +++ b/docs/libcurl/curl_easy_escape.3 @@ -0,0 +1,46 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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, 0-9, '-', '.', '_' or '~' 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 diff --git a/docs/libcurl/curl_easy_getinfo.3 b/docs/libcurl/curl_easy_getinfo.3 new file mode 100644 index 000000000..096813609 --- /dev/null +++ b/docs/libcurl/curl_easy_getinfo.3 @@ -0,0 +1,292 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2012, 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, FTP or SMTP +response code. This option was previously known as CURLINFO_HTTP_CODE in +libcurl 7.10.7 and earlier. The value 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. + +Support for SMTP responses added in 7.25.0. +.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. It does \fInot\fP involve the sending of the protocol- +specific request that triggers a transfer. +.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 received by libcurl. 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 received by libcurl. +.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)" diff --git a/docs/libcurl/curl_easy_init.3 b/docs/libcurl/curl_easy_init.3 new file mode 100644 index 000000000..837ba32a5 --- /dev/null +++ b/docs/libcurl/curl_easy_init.3 @@ -0,0 +1,51 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_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)" diff --git a/docs/libcurl/curl_easy_pause.3 b/docs/libcurl/curl_easy_pause.3 new file mode 100644 index 000000000..25d67bfbb --- /dev/null +++ b/docs/libcurl/curl_easy_pause.3 @@ -0,0 +1,85 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_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)" diff --git a/docs/libcurl/curl_easy_perform.3 b/docs/libcurl/curl_easy_perform.3 new file mode 100644 index 000000000..8f8517f22 --- /dev/null +++ b/docs/libcurl/curl_easy_perform.3 @@ -0,0 +1,57 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_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), " + diff --git a/docs/libcurl/curl_easy_recv.3 b/docs/libcurl/curl_easy_recv.3 new file mode 100644 index 000000000..1ede58944 --- /dev/null +++ b/docs/libcurl/curl_easy_recv.3 @@ -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) " diff --git a/docs/libcurl/curl_easy_reset.3 b/docs/libcurl/curl_easy_reset.3 new file mode 100644 index 000000000..592d3ed5c --- /dev/null +++ b/docs/libcurl/curl_easy_reset.3 @@ -0,0 +1,43 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_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) + diff --git a/docs/libcurl/curl_easy_send.3 b/docs/libcurl/curl_easy_send.3 new file mode 100644 index 000000000..17c4c1f54 --- /dev/null +++ b/docs/libcurl/curl_easy_send.3 @@ -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) " diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3 new file mode 100644 index 000000000..9d712a45e --- /dev/null +++ b/docs/libcurl/curl_easy_setopt.3 @@ -0,0 +1,2527 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2012, 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_setopt 3 "1 Jan 2010" "libcurl 7.20.0" "libcurl Manual" +.SH NAME +curl_easy_setopt \- set options for a curl easy handle +.SH SYNOPSIS +#include <curl/curl.h> + +CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter); +.SH DESCRIPTION +curl_easy_setopt() is used to tell libcurl how to behave. By using the +appropriate options to \fIcurl_easy_setopt\fP, you can change libcurl's +behavior. All options are set with the \fIoption\fP followed by a +\fIparameter\fP. That parameter can be a \fBlong\fP, a \fBfunction pointer\fP, +an \fBobject pointer\fP or a \fBcurl_off_t\fP, depending on what the specific +option expects. Read this manual carefully as bad input values may cause +libcurl to behave badly! You can only set one option in each function call. A +typical application uses many curl_easy_setopt() calls in the setup phase. + +Options set with this function call are valid for all forthcoming transfers +performed using this \fIhandle\fP. The options are not in any way reset +between transfers, so if you want subsequent transfers with different options, +you must change them between the transfers. You can optionally reset all +options back to internal default with \fIcurl_easy_reset(3)\fP. + +Strings passed to libcurl as 'char *' arguments, are copied by the library; +thus the string storage associated to the pointer argument may be overwritten +after curl_easy_setopt() returns. Exceptions to this rule are described in +the option details below. + +Before version 7.17.0, strings were not copied. Instead the user was forced +keep them available until libcurl no longer needed them. + +The \fIhandle\fP is the return code from a \fIcurl_easy_init(3)\fP or +\fIcurl_easy_duphandle(3)\fP call. +.SH BEHAVIOR OPTIONS +.IP CURLOPT_VERBOSE +Set the parameter to 1 to get the library to display a lot of verbose +information about its operations. Very useful for libcurl and/or protocol +debugging and understanding. The verbose information will be sent to stderr, +or the stream set with \fICURLOPT_STDERR\fP. + +You hardly ever want this set in production use, you will almost always want +this when you debug/report problems. Another neat option for debugging is the +\fICURLOPT_DEBUGFUNCTION\fP. +.IP CURLOPT_HEADER +A parameter set to 1 tells the library to include the header in the body +output. This is only relevant for protocols that actually have headers +preceding the data (like HTTP). +.IP CURLOPT_NOPROGRESS +Pass a long. If set to 1, it tells the library to shut off the progress meter +completely. It will also prevent the \fICURLOPT_PROGRESSFUNCTION\fP from +getting called. + +Future versions of libcurl are likely to not have any built-in progress meter +at all. +.IP CURLOPT_NOSIGNAL +Pass a long. If it is 1, libcurl will not use any functions that +install signal handlers or any functions that cause signals to be sent to the +process. This option is mainly here to allow multi-threaded unix applications +to still set/use all timeout options etc, without risking getting signals. +(Added in 7.10) + +If this option is set and libcurl has been built with the standard name +resolver, timeouts will not occur while the name resolve takes place. +Consider building libcurl with c-ares support to enable asynchronous DNS +lookups, which enables nice timeouts for name resolves without signals. + +Setting \fICURLOPT_NOSIGNAL\fP to 1 makes libcurl NOT ask the system to ignore +SIGPIPE signals, which otherwise are sent by the system when trying to send +data to a socket which is closed in the other end. libcurl makes an effort to +never cause such SIGPIPEs to trigger, but some operating systems have no way +to avoid them and even on those that have there are some corner cases when +they may still happen, contrary to our desire. In addition, using +\fICURLAUTH_NTLM_WB\fP authentication could cause a SIGCHLD signal to be +raised. +.IP CURLOPT_WILDCARDMATCH +Set this option to 1 if you want to transfer multiple files according to a +file name pattern. The pattern can be specified as part of the +\fICURLOPT_URL\fP option, using an fnmatch-like pattern (Shell Pattern +Matching) in the last part of URL (file name). + +By default, libcurl uses its internal wildcard matching implementation. You +can provide your own matching function by the \fICURLOPT_FNMATCH_FUNCTION\fP +option. + +This feature is only supported by the FTP download for now. + +A brief introduction of its syntax follows: +.RS +.IP "* - ASTERISK" +\&ftp://example.com/some/path/\fB*.txt\fP (for all txt's from the root +directory) +.RE +.RS +.IP "? - QUESTION MARK" +Question mark matches any (exactly one) character. + +\&ftp://example.com/some/path/\fBphoto?.jpeg\fP +.RE +.RS +.IP "[ - BRACKET EXPRESSION" +The left bracket opens a bracket expression. The question mark and asterisk have +no special meaning in a bracket expression. Each bracket expression ends by the +right bracket and matches exactly one character. Some examples follow: + +\fB[a-zA-Z0\-9]\fP or \fB[f\-gF\-G]\fP \- character interval + +\fB[abc]\fP - character enumeration + +\fB[^abc]\fP or \fB[!abc]\fP - negation + +\fB[[:\fP\fIname\fP\fB:]]\fP class expression. Supported classes are +\fBalnum\fP,\fBlower\fP, \fBspace\fP, \fBalpha\fP, \fBdigit\fP, \fBprint\fP, +\fBupper\fP, \fBblank\fP, \fBgraph\fP, \fBxdigit\fP. + +\fB[][-!^]\fP - special case \- matches only '\-', ']', '[', '!' or '^'. These +characters have no special purpose. + +\fB[\\[\\]\\\\]\fP - escape syntax. Matches '[', ']' or '\\'. + +Using the rules above, a file name pattern can be constructed: + +\&ftp://example.com/some/path/\fB[a-z[:upper:]\\\\].jpeg\fP +.RE +.PP +(This was added in 7.21.0) +.SH CALLBACK OPTIONS +.IP CURLOPT_WRITEFUNCTION +Pass a pointer to a function that matches the following prototype: +\fBsize_t function( char *ptr, size_t size, size_t nmemb, void *userdata);\fP +This function gets called by libcurl as soon as there is data received that +needs to be saved. The size of the data pointed to by \fIptr\fP is \fIsize\fP +multiplied with \fInmemb\fP, it will not be zero terminated. Return the number +of bytes actually taken care of. If that amount differs from the amount passed +to your function, it'll signal an error to the library. This will abort the +transfer and return \fICURLE_WRITE_ERROR\fP. + +From 7.18.0, the function can return CURL_WRITEFUNC_PAUSE which then will +cause writing to this connection to become paused. See +\fIcurl_easy_pause(3)\fP for further details. + +This function may be called with zero bytes data if the transferred file is +empty. + +Set this option to NULL to get the internal default function. The internal +default function will write the data to the FILE * given with +\fICURLOPT_WRITEDATA\fP. + +Set the \fIuserdata\fP argument with the \fICURLOPT_WRITEDATA\fP option. + +The callback function will be passed as much data as possible in all invokes, +but you cannot possibly make any assumptions. It may be one byte, it may be +thousands. The maximum amount of body data that can be passed to the write +callback is defined in the curl.h header file: CURL_MAX_WRITE_SIZE (the usual +default is 16K). If you however have \fICURLOPT_HEADER\fP set, which sends +header data to the write callback, you can get up to +\fICURL_MAX_HTTP_HEADER\fP bytes of header data passed into it. This usually +means 100K. +.IP CURLOPT_WRITEDATA +Data pointer to pass to the file write function. If you use the +\fICURLOPT_WRITEFUNCTION\fP option, this is the pointer you'll get as +input. If you don't use a callback, you must pass a 'FILE *' as libcurl will +pass this to fwrite() when writing data. + +The internal \fICURLOPT_WRITEFUNCTION\fP will write the data to the FILE * +given with this option, or to stdout if this option hasn't been set. + +If you're using libcurl as a win32 DLL, you \fBMUST\fP use the +\fICURLOPT_WRITEFUNCTION\fP if you set this option or you will experience +crashes. + +This option is also known with the older name \fICURLOPT_FILE\fP, the name +\fICURLOPT_WRITEDATA\fP was introduced in 7.9.7. +.IP CURLOPT_READFUNCTION +Pass a pointer to a function that matches the following prototype: +\fBsize_t function( void *ptr, size_t size, size_t nmemb, void *userdata);\fP +This function gets called by libcurl as soon as it needs to read data in order +to send it to the peer. The data area pointed at by the pointer \fIptr\fP may +be filled with at most \fIsize\fP multiplied with \fInmemb\fP number of +bytes. Your function must return the actual number of bytes that you stored in +that memory area. Returning 0 will signal end-of-file to the library and cause +it to stop the current transfer. + +If you stop the current transfer by returning 0 "pre-maturely" (i.e before the +server expected it, like when you've said you will upload N bytes and you +upload less than N bytes), you may experience that the server "hangs" waiting +for the rest of the data that won't come. + +The read callback may return \fICURL_READFUNC_ABORT\fP to stop the current +operation immediately, resulting in a \fICURLE_ABORTED_BY_CALLBACK\fP error +code from the transfer (Added in 7.12.1) + +From 7.18.0, the function can return CURL_READFUNC_PAUSE which then will cause +reading from this connection to become paused. See \fIcurl_easy_pause(3)\fP +for further details. + +\fBBugs\fP: when doing TFTP uploads, you must return the exact amount of data +that the callback wants, or it will be considered the final packet by the +server end and the transfer will end there. + +If you set this callback pointer to NULL, or don't set it at all, the default +internal read function will be used. It is doing an fread() on the FILE * +userdata set with \fICURLOPT_READDATA\fP. +.IP CURLOPT_READDATA +Data pointer to pass to the file read function. If you use the +\fICURLOPT_READFUNCTION\fP option, this is the pointer you'll get as input. If +you don't specify a read callback but instead rely on the default internal +read function, this data must be a valid readable FILE *. + +If you're using libcurl as a win32 DLL, you MUST use a +\fICURLOPT_READFUNCTION\fP if you set this option. + +This option was also known by the older name \fICURLOPT_INFILE\fP, the name +\fICURLOPT_READDATA\fP was introduced in 7.9.7. +.IP CURLOPT_IOCTLFUNCTION +Pass a pointer to a function that matches the following prototype: +\fBcurlioerr function(CURL *handle, int cmd, void *clientp);\fP. This function +gets called by libcurl when something special I/O-related needs to be done +that the library can't do by itself. For now, rewinding the read data stream +is the only action it can request. The rewinding of the read data stream may +be necessary when doing a HTTP PUT or POST with a multi-pass authentication +method. (Option added in 7.12.3). + +Use \fICURLOPT_SEEKFUNCTION\fP instead to provide seeking! +.IP CURLOPT_IOCTLDATA +Pass a pointer that will be untouched by libcurl and passed as the 3rd +argument in the ioctl callback set with \fICURLOPT_IOCTLFUNCTION\fP. (Option +added in 7.12.3) +.IP CURLOPT_SEEKFUNCTION +Pass a pointer to a function that matches the following prototype: \fBint +function(void *instream, curl_off_t offset, int origin);\fP This function gets +called by libcurl to seek to a certain position in the input stream and can be +used to fast forward a file in a resumed upload (instead of reading all +uploaded bytes with the normal read function/callback). It is also called to +rewind a stream when doing a HTTP PUT or POST with a multi-pass authentication +method. The function shall work like "fseek" or "lseek" and accepted SEEK_SET, +SEEK_CUR and SEEK_END as argument for origin, although (in 7.18.0) libcurl +only passes SEEK_SET. The callback must return 0 (CURL_SEEKFUNC_OK) on +success, 1 (CURL_SEEKFUNC_FAIL) to cause the upload operation to fail or 2 +(CURL_SEEKFUNC_CANTSEEK) to indicate that while the seek failed, libcurl is +free to work around the problem if possible. The latter can sometimes be done +by instead reading from the input or similar. + +If you forward the input arguments directly to "fseek" or "lseek", note that +the data type for \fIoffset\fP is not the same as defined for curl_off_t on +many systems! (Option added in 7.18.0) +.IP CURLOPT_SEEKDATA +Data pointer to pass to the file seek function. If you use the +\fICURLOPT_SEEKFUNCTION\fP option, this is the pointer you'll get as input. If +you don't specify a seek callback, NULL is passed. (Option added in 7.18.0) +.IP CURLOPT_SOCKOPTFUNCTION +Pass a pointer to a function that matches the following prototype: \fBint +function(void *clientp, curl_socket_t curlfd, curlsocktype purpose);\fP. This +function gets called by libcurl after the socket() call but before the +connect() call. The callback's \fIpurpose\fP argument identifies the exact +purpose for this particular socket: + +\fICURLSOCKTYPE_IPCXN\fP for actively created connections or since 7.28.0 +\fICURLSOCKTYPE_ACCEPT\fP for FTP when the connection was setup with PORT/EPSV +(in earlier versions these sockets weren't passed to this callback). + +Future versions of libcurl may support more purposes. It passes the newly +created socket descriptor so additional setsockopt() calls can be done at the +user's discretion. Return 0 (zero) from the callback on success. Return 1 +from the callback function to signal an unrecoverable error to the library and +it will close the socket and return \fICURLE_COULDNT_CONNECT\fP. (Option +added in 7.16.0) + +Added in 7.21.5, the callback function may return +\fICURL_SOCKOPT_ALREADY_CONNECTED\fP, which tells libcurl that the socket is +in fact already connected and then libcurl will not attempt to connect it. +.IP CURLOPT_SOCKOPTDATA +Pass a pointer that will be untouched by libcurl and passed as the first +argument in the sockopt callback set with \fICURLOPT_SOCKOPTFUNCTION\fP. +(Option added in 7.16.0) +.IP CURLOPT_OPENSOCKETFUNCTION +Pass a pointer to a function that matches the following prototype: +\fBcurl_socket_t function(void *clientp, curlsocktype purpose, struct +curl_sockaddr *address);\fP. This function gets called by libcurl instead of +the \fIsocket(2)\fP call. The callback's \fIpurpose\fP argument identifies the +exact purpose for this particular socket: \fICURLSOCKTYPE_IPCXN\fP is for IP +based connections. Future versions of libcurl may support more purposes. It +passes the resolved peer address as a \fIaddress\fP argument so the callback +can modify the address or refuse to connect at all. The callback function +should return the socket or \fICURL_SOCKET_BAD\fP in case no connection could +be established or another error was detected. Any additional +\fIsetsockopt(2)\fP calls can be done on the socket at the user's discretion. +\fICURL_SOCKET_BAD\fP return value from the callback function will signal an +unrecoverable error to the library and it will return +\fICURLE_COULDNT_CONNECT\fP. This return code can be used for IP address +blacklisting. The default behavior is: +.nf + return socket(addr->family, addr->socktype, addr->protocol); +.fi +(Option added in 7.17.1.) +.IP CURLOPT_OPENSOCKETDATA +Pass a pointer that will be untouched by libcurl and passed as the first +argument in the opensocket callback set with \fICURLOPT_OPENSOCKETFUNCTION\fP. +(Option added in 7.17.1.) +.IP CURLOPT_CLOSESOCKETFUNCTION +Pass a pointer to a function that matches the following prototype: \fBint +function(void *clientp, curl_socket_t item);\fP. This function gets called by +libcurl instead of the \fIclose(3)\fP or \fIclosesocket(3)\fP call when +sockets are closed (not for any other file descriptors). This is pretty much +the reverse to the \fICURLOPT_OPENSOCKETFUNCTION\fP option. Return 0 to signal +success and 1 if there was an error. (Option added in 7.21.7) +.IP CURLOPT_CLOSESOCKETDATA +Pass a pointer that will be untouched by libcurl and passed as the first +argument in the closesocket callback set with +\fICURLOPT_CLOSESOCKETFUNCTION\fP. (Option added in 7.21.7) +.IP CURLOPT_PROGRESSFUNCTION +Pass a pointer to a function that matches the following prototype: \fBint +function(void *clientp, double dltotal, double dlnow, double ultotal, double +ulnow); \fP. This function gets called by libcurl instead of its internal +equivalent with a frequent interval during operation (roughly once per second +or sooner) no matter if data is being transferred or not. Unknown/unused +argument values passed to the callback will be set to zero (like if you only +download data, the upload size will remain 0). Returning a non-zero value from +this callback will cause libcurl to abort the transfer and return +\fICURLE_ABORTED_BY_CALLBACK\fP. + +If you transfer data with the multi interface, this function will not be +called during periods of idleness unless you call the appropriate libcurl +function that performs transfers. + +\fICURLOPT_NOPROGRESS\fP must be set to 0 to make this function actually +get called. +.IP CURLOPT_PROGRESSDATA +Pass a pointer that will be untouched by libcurl and passed as the first +argument in the progress callback set with \fICURLOPT_PROGRESSFUNCTION\fP. +.IP CURLOPT_HEADERFUNCTION +Pass a pointer to a function that matches the following prototype: +\fBsize_t function( void *ptr, size_t size, size_t nmemb, void +*userdata);\fP. This function gets called by libcurl as soon as it has +received header data. The header callback will be called once for each header +and only complete header lines are passed on to the callback. Parsing headers +is very easy using this. The size of the data pointed to by \fIptr\fP is +\fIsize\fP multiplied with \fInmemb\fP. Do not assume that the header line is +zero terminated! The pointer named \fIuserdata\fP is the one you set with the +\fICURLOPT_WRITEHEADER\fP option. The callback function must return the number +of bytes actually taken care of. If that amount differs from the amount passed +to your function, it'll signal an error to the library. This will abort the +transfer and return \fICURL_WRITE_ERROR\fP. + +A complete HTTP header that is passed to this function can be up to +\fICURL_MAX_HTTP_HEADER\fP (100K) bytes. + +If this option is not set, or if it is set to NULL, but +\fICURLOPT_HEADERDATA\fP (\fICURLOPT_WRITEHEADER\fP) is set to anything but +NULL, the function used to accept response data will be used instead. That is, +it will be the function specified with \fICURLOPT_WRITEFUNCTION\fP, or if it +is not specified or NULL - the default, stream-writing function. + +It's important to note that the callback will be invoked for the headers of +all responses received after initiating a request and not just the final +response. This includes all responses which occur during authentication +negotiation. If you need to operate on only the headers from the final +response, you will need to collect headers in the callback yourself and use +HTTP status lines, for example, to delimit response boundaries. + +When a server sends a chunked encoded transfer, it may contain a trailer. That +trailer is identical to a HTTP header and if such a trailer is received it is +passed to the application using this callback as well. There are several ways +to detect it being a trailer and not an ordinary header: 1) it comes after the +response-body. 2) it comes after the final header line (CR LF) 3) a Trailer: +header among the regular response-headers mention what header(s) to expect in +the trailer. + +For non-HTTP protocols like FTP, POP3, IMAP and SMTP this function will get +called with the server responses to the commands that libcurl sends. +.IP CURLOPT_WRITEHEADER +(This option is also known as \fBCURLOPT_HEADERDATA\fP) Pass a pointer to be +used to write the header part of the received data to. If you don't use +\fICURLOPT_WRITEFUNCTION\fP or \fICURLOPT_HEADERFUNCTION\fP to take care of +the writing, this must be a valid FILE * as the internal default will then be +a plain fwrite(). See also the \fICURLOPT_HEADERFUNCTION\fP option above on +how to set a custom get-all-headers callback. +.IP CURLOPT_DEBUGFUNCTION +Pass a pointer to a function that matches the following prototype: \fBint +curl_debug_callback (CURL *, curl_infotype, char *, size_t, void *);\fP +\fICURLOPT_DEBUGFUNCTION\fP replaces the standard debug function used when +\fICURLOPT_VERBOSE \fP is in effect. This callback receives debug information, +as specified with the \fBcurl_infotype\fP argument. This function must return +0. The data pointed to by the char * passed to this function WILL NOT be zero +terminated, but will be exactly of the size as told by the size_t argument. + +Available curl_infotype values: +.RS +.IP CURLINFO_TEXT +The data is informational text. +.IP CURLINFO_HEADER_IN +The data is header (or header-like) data received from the peer. +.IP CURLINFO_HEADER_OUT +The data is header (or header-like) data sent to the peer. +.IP CURLINFO_DATA_IN +The data is protocol data received from the peer. +.IP CURLINFO_DATA_OUT +The data is protocol data sent to the peer. +.RE +.IP CURLOPT_DEBUGDATA +Pass a pointer to whatever you want passed in to your +\fICURLOPT_DEBUGFUNCTION\fP in the last void * argument. This pointer is not +used by libcurl, it is only passed to the callback. +.IP CURLOPT_SSL_CTX_FUNCTION +This option does only function for libcurl powered by OpenSSL. If libcurl was +built against another SSL library, this functionality is absent. + +Pass a pointer to a function that matches the following prototype: +\fBCURLcode sslctxfun(CURL *curl, void *sslctx, void *parm);\fP This function +gets called by libcurl just before the initialization of a SSL connection +after having processed all other SSL related options to give a last chance to +an application to modify the behaviour of openssl's ssl initialization. The +\fIsslctx\fP parameter is actually a pointer to an openssl \fISSL_CTX\fP. If +an error is returned no attempt to establish a connection is made and the +perform operation will return the error code from this callback function. Set +the \fIparm\fP argument with the \fICURLOPT_SSL_CTX_DATA\fP option. This +option was introduced in 7.11.0. + +This function will get called on all new connections made to a server, during +the SSL negotiation. The SSL_CTX pointer will be a new one every time. + +To use this properly, a non-trivial amount of knowledge of the openssl +libraries is necessary. For example, using this function allows you to use +openssl callbacks to add additional validation code for certificates, and even +to change the actual URI of a HTTPS request (example used in the lib509 test +case). See also the example section for a replacement of the key, certificate +and trust file settings. +.IP CURLOPT_SSL_CTX_DATA +Data pointer to pass to the ssl context callback set by the option +\fICURLOPT_SSL_CTX_FUNCTION\fP, this is the pointer you'll get as third +parameter, otherwise \fBNULL\fP. (Added in 7.11.0) +.IP CURLOPT_CONV_TO_NETWORK_FUNCTION +.IP CURLOPT_CONV_FROM_NETWORK_FUNCTION +.IP CURLOPT_CONV_FROM_UTF8_FUNCTION +Pass a pointer to a function that matches the following prototype: +\fBCURLcode function(char *ptr, size_t length);\fP + +These three options apply to non-ASCII platforms only. They are available +only if \fBCURL_DOES_CONVERSIONS\fP was defined when libcurl was built. When +this is the case, \fIcurl_version_info(3)\fP will return the CURL_VERSION_CONV +feature bit set. + +The data to be converted is in a buffer pointed to by the ptr parameter. The +amount of data to convert is indicated by the length parameter. The converted +data overlays the input data in the buffer pointed to by the ptr parameter. +CURLE_OK should be returned upon successful conversion. A CURLcode return +value defined by curl.h, such as CURLE_CONV_FAILED, should be returned if an +error was encountered. + +\fBCURLOPT_CONV_TO_NETWORK_FUNCTION\fP and +\fBCURLOPT_CONV_FROM_NETWORK_FUNCTION\fP convert between the host encoding and +the network encoding. They are used when commands or ASCII data are +sent/received over the network. + +\fBCURLOPT_CONV_FROM_UTF8_FUNCTION\fP is called to convert from UTF8 into the +host encoding. It is required only for SSL processing. + +If you set a callback pointer to NULL, or don't set it at all, the built-in +libcurl iconv functions will be used. If HAVE_ICONV was not defined when +libcurl was built, and no callback has been established, conversion will +return the CURLE_CONV_REQD error code. + +If HAVE_ICONV is defined, CURL_ICONV_CODESET_OF_HOST must also be defined. +For example: + + \&#define CURL_ICONV_CODESET_OF_HOST "IBM-1047" + +The iconv code in libcurl will default the network and UTF8 codeset names as +follows: + + \&#define CURL_ICONV_CODESET_OF_NETWORK "ISO8859-1" + + \&#define CURL_ICONV_CODESET_FOR_UTF8 "UTF-8" + +You will need to override these definitions if they are different on your +system. +.IP CURLOPT_INTERLEAVEFUNCTION +Pass a pointer to a function that matches the following prototype: +\fBsize_t function( void *ptr, size_t size, size_t nmemb, void +*userdata)\fP. This function gets called by libcurl as soon as it has received +interleaved RTP data. This function gets called for each $ block and therefore +contains exactly one upper-layer protocol unit (e.g. one RTP packet). Curl +writes the interleaved header as well as the included data for each call. The +first byte is always an ASCII dollar sign. The dollar sign is followed by a +one byte channel identifier and then a 2 byte integer length in network byte +order. See \fIRFC2326 Section 10.12\fP for more information on how RTP +interleaving behaves. If unset or set to NULL, curl will use the default write +function. + +Interleaved RTP poses some challenges for the client application. Since the +stream data is sharing the RTSP control connection, it is critical to service +the RTP in a timely fashion. If the RTP data is not handled quickly, +subsequent response processing may become unreasonably delayed and the +connection may close. The application may use \fICURL_RTSPREQ_RECEIVE\fP to +service RTP data when no requests are desired. If the application makes a +request, (e.g. \fICURL_RTSPREQ_PAUSE\fP) then the response handler will +process any pending RTP data before marking the request as finished. (Added +in 7.20.0) +.IP CURLOPT_INTERLEAVEDATA +This is the userdata pointer that will be passed to +\fICURLOPT_INTERLEAVEFUNCTION\fP when interleaved RTP data is received. (Added +in 7.20.0) +.IP CURLOPT_CHUNK_BGN_FUNCTION +Pass a pointer to a function that matches the following prototype: +\fBlong function (const void *transfer_info, void *ptr, int remains)\fP. This +function gets called by libcurl before a part of the stream is going to be +transferred (if the transfer supports chunks). + +This callback makes sense only when using the \fICURLOPT_WILDCARDMATCH\fP +option for now. + +The target of transfer_info parameter is a "feature depended" structure. For +the FTP wildcard download, the target is curl_fileinfo structure (see +\fIcurl/curl.h\fP). The parameter ptr is a pointer given by +\fICURLOPT_CHUNK_DATA\fP. The parameter remains contains number of chunks +remaining per the transfer. If the feature is not available, the parameter has +zero value. + +Return \fICURL_CHUNK_BGN_FUNC_OK\fP if everything is fine, +\fICURL_CHUNK_BGN_FUNC_SKIP\fP if you want to skip the concrete chunk or +\fICURL_CHUNK_BGN_FUNC_FAIL\fP to tell libcurl to stop if some error occurred. +(This was added in 7.21.0) +.IP CURLOPT_CHUNK_END_FUNCTION +Pass a pointer to a function that matches the following prototype: +\fBlong function(void *ptr)\fP. This function gets called by libcurl as soon +as a part of the stream has been transferred (or skipped). + +Return \fICURL_CHUNK_END_FUNC_OK\fP if everything is fine or +\fBCURL_CHUNK_END_FUNC_FAIL\fP to tell the lib to stop if some error occurred. +(This was added in 7.21.0) +.IP CURLOPT_CHUNK_DATA +Pass a pointer that will be untouched by libcurl and passed as the ptr +argument to the \fICURL_CHUNK_BGN_FUNTION\fP and \fICURL_CHUNK_END_FUNTION\fP. +(This was added in 7.21.0) +.IP CURLOPT_FNMATCH_FUNCTION +Pass a pointer to a function that matches the following prototype: \fBint +function(void *ptr, const char *pattern, const char *string)\fP prototype (see +\fIcurl/curl.h\fP). It is used internally for the wildcard matching feature. + +Return \fICURL_FNMATCHFUNC_MATCH\fP if pattern matches the string, +\fICURL_FNMATCHFUNC_NOMATCH\fP if not or \fICURL_FNMATCHFUNC_FAIL\fP if an +error occurred. (This was added in 7.21.0) +.IP CURLOPT_FNMATCH_DATA +Pass a pointer that will be untouched by libcurl and passed as the ptr argument +to the \fICURL_FNMATCH_FUNCTION\fP. (This was added in 7.21.0) +.SH ERROR OPTIONS +.IP CURLOPT_ERRORBUFFER +Pass a char * to a buffer that the libcurl may store human readable error +messages in. This may be more helpful than just the return code from +\fIcurl_easy_perform\fP. The buffer must be at least CURL_ERROR_SIZE big. +Although this argument is a 'char *', it does not describe an input string. +Therefore the (probably undefined) contents of the buffer is NOT copied by the +library. You must keep the associated storage available until libcurl no +longer needs it. Failing to do so will cause very odd behavior or even +crashes. libcurl will need it until you call \fIcurl_easy_cleanup(3)\fP or you +set the same option again to use a different pointer. + +Use \fICURLOPT_VERBOSE\fP and \fICURLOPT_DEBUGFUNCTION\fP to better +debug/trace why errors happen. + +If the library does not return an error, the buffer may not have been +touched. Do not rely on the contents in those cases. + +.IP CURLOPT_STDERR +Pass a FILE * as parameter. Tell libcurl to use this stream instead of stderr +when showing the progress meter and displaying \fICURLOPT_VERBOSE\fP data. +.IP CURLOPT_FAILONERROR +A parameter set to 1 tells the library to fail silently if the HTTP code +returned is equal to or larger than 400. The default action would be to return +the page normally, ignoring that code. + +This method is not fail-safe and there are occasions where non-successful +response codes will slip through, especially when authentication is involved +(response codes 401 and 407). + +You might get some amounts of headers transferred before this situation is +detected, like when a "100-continue" is received as a response to a +POST/PUT and a 401 or 407 is received immediately afterwards. +.SH NETWORK OPTIONS +.IP CURLOPT_URL +Pass in a pointer to the actual URL to deal with. The parameter should be a +char * to a zero terminated string which must be URL-encoded in the following +format: + +scheme://host:port/path + +For a greater explanation of the format please see RFC3986. + +If the given URL lacks the scheme, or protocol, part ("http://" or "ftp://" +etc), libcurl will attempt to resolve which protocol to use based on the +given host mame. If the protocol is not supported, libcurl will return +(\fICURLE_UNSUPPORTED_PROTOCOL\fP) when you call \fIcurl_easy_perform(3)\fP +or \fIcurl_multi_perform(3)\fP. Use \fIcurl_version_info(3)\fP for detailed +information on which protocols are supported. + +The host part of the URL contains the address of the server that you want to +connect to. This can be the fully qualified domain name of the server, the +local network name of the machine on your network or the IP address of the +server or machine represented by either an IPv4 or IPv6 address. For example: + +http://www.example.com/ + +http://hostname/ + +http://192.168.0.1/ + +http://[2001:1890:1112:1::20]/ + +It is also possible to specify the user name and password as part of the +host, for some protocols, when connecting to servers that require +authentication. + +For example the following types of authentication support this: + +http://user:password@www.example.com + +ftp://user:password@ftp.example.com + +pop3://user:password@mail.example.com + +The port is optional and when not specified libcurl will use the default port +based on the determined or specified protocol: 80 for HTTP, 21 for FTP and 25 +for SMTP, etc. The following examples show how to specify the port: + +http://www.example.com:8080/ - This will connect to a web server using port +8080 rather than 80. + +smtp://mail.example.com:587/ - This will connect to a SMTP server on the +alternative mail port. + +The path part of the URL is protocol specific and whilst some examples are +given below this list is not conclusive: + +.B HTTP + +The path part of a HTTP request specifies the file to retrieve and from what +directory. If the directory is not specified then the web server's root +directory is used. If the file is omitted then the default document will be +retrieved for either the directory specified or the root directory. The +exact resource returned for each URL is entirely dependent on the server's +configuration. + +http://www.example.com - This gets the main page from the web server. + +http://www.example.com/index.html - This returns the main page by explicitly +requesting it. + +http://www.example.com/contactus/ - This returns the default document from +the contactus directory. + +.B FTP + +The path part of an FTP request specifies the file to retrieve and from what +directory. If the file part is omitted then libcurl downloads the directory +listing for the directory specified. If the directory is omitted then +the directory listing for the root / home directory will be returned. + +ftp://ftp.example.com - This retrieves the directory listing for the root +directory. + +ftp://ftp.example.com/readme.txt - This downloads the file readme.txt from the +root directory. + +ftp://ftp.example.com/libcurl/readme.txt - This downloads readme.txt from the +libcurl directory. + +ftp://user:password@ftp.example.com/readme.txt - This retrieves the readme.txt +file from the user's home directory. When a username and password is +specified, everything that is specified in the path part is relative to the +user's home directory. To retrieve files from the root directory or a +directory underneath the root directory then the absolute path must be +specified by prepending an additional forward slash to the beginning of the +path. + +ftp://user:password@ftp.example.com//readme.txt - This retrieves the readme.txt +from the root directory when logging in as a specified user. + +.B SMTP + +The path part of a SMTP request specifies the host name to present during +communication with the mail server. If the path is omitted then libcurl will +attempt to resolve the local computer's host name. However, this may not +return the fully qualified domain name that is required by some mail servers +and specifying this path allows you to set an alternative name, such as +your machine's fully qualified domain name, which you might have obtained +from an external function such as gethostname or getaddrinfo. + +smtp://mail.example.com - This connects to the mail server at example.com and +sends your local computer's host name in the HELO / EHLO command. + +smtp://mail.example.com/client.example.com - This will send client.example.com in +the HELO / EHLO command to the mail server at example.com. + +.B POP3 + +The path part of a POP3 request specifies the mailbox (message) to retrieve. +If the mailbox is not specified then a list of waiting messages is returned +instead. + +pop3://user:password@mail.example.com - This lists the available messages +pop3://user:password@mail.example.com/1 - This retrieves the first message + +.B SCP + +The path part of a SCP request specifies the file to retrieve and from what +directory. The file part may not be omitted. The file is taken as an absolute +path from the root directory on the server. To specify a path relative to +the user's home directory on the server, prepend ~/ to the path portion. +If the user name is not embedded in the URL, it can be set with the +\fICURLOPT_USERPWD\fP or \fBCURLOPT_USERNAME\fP option. + +scp://user@example.com/etc/issue - This specifies the file /etc/issue + +scp://example.com/~/my-file - This specifies the file my-file in the +user's home directory on the server + +.B SFTP + +The path part of a SFTP request specifies the file to retrieve and from what +directory. If the file part is omitted then libcurl downloads the directory +listing for the directory specified. If the path ends in a / then a directory +listing is returned instead of a file. If the path is omitted entirely then +the directory listing for the root / home directory will be returned. +If the user name is not embedded in the URL, it can be set with the +\fICURLOPT_USERPWD\fP or \fBCURLOPT_USERNAME\fP option. + +sftp://user:password@example.com/etc/issue - This specifies the file +/etc/issue + +sftp://user@example.com/~/my-file - This specifies the file my-file in the +user's home directory + +sftp://ssh.example.com/~/Documents/ - This requests a directory listing +of the Documents directory under the user's home directory + +.B LDAP + +The path part of a LDAP request can be used to specify the: Distinguished +Name, Attributes, Scope, Filter and Extension for a LDAP search. Each field +is separated by a question mark and when that field is not required an empty +string with the question mark separator should be included. + +ldap://ldap.example.com/o=My%20Organisation - This will perform a LDAP search +with the DN as My Organisation. + +ldap://ldap.example.com/o=My%20Organisation?postalAddress - This will perform +the same search but will only return postalAddress attributes. + +ldap://ldap.example.com/?rootDomainNamingContext - This specifies an empty DN +and requests information about the rootDomainNamingContext attribute for an +Active Directory server. + +For more information about the individual components of a LDAP URL please +see RFC4516. + +.B NOTES + +Starting with version 7.20.0, the fragment part of the URI will not be sent as +part of the path, which was previously the case. + +\fICURLOPT_URL\fP is the only option that \fBmust\fP be set before +\fIcurl_easy_perform(3)\fP is called. + +\fICURLOPT_PROTOCOLS\fP can be used to limit what protocols libcurl will use +for this transfer, independent of what libcurl has been compiled to +support. That may be useful if you accept the URL from an external source and +want to limit the accessibility. +.IP CURLOPT_PROTOCOLS +Pass a long that holds a bitmask of CURLPROTO_* defines. If used, this bitmask +limits what protocols libcurl may use in the transfer. This allows you to have +a libcurl built to support a wide range of protocols but still limit specific +transfers to only be allowed to use a subset of them. By default libcurl will +accept all protocols it supports. See also +\fICURLOPT_REDIR_PROTOCOLS\fP. (Added in 7.19.4) +.IP CURLOPT_REDIR_PROTOCOLS +Pass a long that holds a bitmask of CURLPROTO_* defines. If used, this bitmask +limits what protocols libcurl may use in a transfer that it follows to in a +redirect when \fICURLOPT_FOLLOWLOCATION\fP is enabled. This allows you to +limit specific transfers to only be allowed to use a subset of protocols in +redirections. By default libcurl will allow all protocols except for FILE and +SCP. This is a difference compared to pre-7.19.4 versions which +unconditionally would follow to all protocols supported. (Added in 7.19.4) +.IP CURLOPT_PROXY +Set HTTP proxy to use. The parameter should be a char * to a zero terminated +string holding the host name or dotted IP address. To specify port number in +this string, append :[port] to the end of the host name. The proxy string may +be prefixed with [protocol]:// since any such prefix will be ignored. The +proxy's port number may optionally be specified with the separate option. If +not specified, libcurl will default to using port 1080 for proxies. +\fICURLOPT_PROXYPORT\fP. + +When you tell the library to use a HTTP proxy, libcurl will transparently +convert operations to HTTP even if you specify an FTP URL etc. This may have +an impact on what other features of the library you can use, such as +\fICURLOPT_QUOTE\fP and similar FTP specifics that don't work unless you +tunnel through the HTTP proxy. Such tunneling is activated with +\fICURLOPT_HTTPPROXYTUNNEL\fP. + +libcurl respects the environment variables \fBhttp_proxy\fP, \fBftp_proxy\fP, +\fBall_proxy\fP etc, if any of those are set. The \fICURLOPT_PROXY\fP option +does however override any possibly set environment variables. + +Setting the proxy string to "" (an empty string) will explicitly disable the +use of a proxy, even if there is an environment variable set for it. + +Since 7.14.1, the proxy host string given in environment variables can be +specified the exact same way as the proxy can be set with \fICURLOPT_PROXY\fP, +include protocol prefix (http://) and embedded user + password. + +Since 7.21.7, the proxy string may be specified with a protocol:// prefix to +specify alternative proxy protocols. Use socks4://, socks4a://, socks5:// or +socks5h:// (the last one to enable socks5 and asking the proxy to do the +resolving, also known as CURLPROXY_SOCKS5_HOSTNAME type) to request the +specific SOCKS version to be used. No protocol specified, http:// and all +others will be treated as HTTP proxies. +.IP CURLOPT_PROXYPORT +Pass a long with this option to set the proxy port to connect to unless it is +specified in the proxy string \fICURLOPT_PROXY\fP. +.IP CURLOPT_PROXYTYPE +Pass a long with this option to set type of the proxy. Available options for +this are \fICURLPROXY_HTTP\fP, \fICURLPROXY_HTTP_1_0\fP (added in 7.19.4), +\fICURLPROXY_SOCKS4\fP (added in 7.10), \fICURLPROXY_SOCKS5\fP, +\fICURLPROXY_SOCKS4A\fP (added in 7.18.0) and \fICURLPROXY_SOCKS5_HOSTNAME\fP +(added in 7.18.0). The HTTP type is default. (Added in 7.10) + +If you set \fBCURLOPT_PROXYTYPE\fP to \fICURLPROXY_HTTP_1_0\fP, it will only +affect how libcurl speaks to a proxy when CONNECT is used. The HTTP version +used for "regular" HTTP requests is instead controlled with +\fICURLOPT_HTTP_VERSION\fP. +.IP CURLOPT_NOPROXY +Pass a pointer to a zero terminated string. The string consists of a comma +separated list of host names that do not require a proxy to get reached, even +if one is specified. The only wildcard available is a single * character, +which matches all hosts, and effectively disables the proxy. Each name in this +list is matched as either a domain which contains the hostname, or the +hostname itself. For example, example.com would match example.com, +example.com:80, and www.example.com, but not www.notanexample.com. (Added in +7.19.4) +.IP CURLOPT_HTTPPROXYTUNNEL +Set the parameter to 1 to make the library tunnel all operations through a +given HTTP proxy. There is a big difference between using a proxy and to +tunnel through it. If you don't know what this means, you probably don't want +this tunneling option. +.IP CURLOPT_SOCKS5_GSSAPI_SERVICE +Pass a char * as parameter to a string holding the name of the service. The +default service name for a SOCKS5 server is rcmd/server-fqdn. This option +allows you to change it. (Added in 7.19.4) +.IP CURLOPT_SOCKS5_GSSAPI_NEC +Pass a long set to 1 to enable or 0 to disable. As part of the gssapi +negotiation a protection mode is negotiated. The RFC1961 says in section +4.3/4.4 it should be protected, but the NEC reference implementation does not. +If enabled, this option allows the unprotected exchange of the protection mode +negotiation. (Added in 7.19.4). +.IP CURLOPT_INTERFACE +Pass a char * as parameter. This sets the interface name to use as outgoing +network interface. The name can be an interface name, an IP address, or a host +name. + +Starting with 7.24.0: If the parameter starts with "if!" then it is treated as +only as interface name and no attempt will ever be named to do treat it as an +IP address or to do name resolution on it. If the parameter starts with +\&"host!" it is treated as either an IP address or a hostname. Hostnames are +resolved synchronously. Using the if! format is highly recommended when using +the multi interfaces to avoid allowing the code to block. If "if!" is +specified but the parameter does not match an existing interface, +CURLE_INTERFACE_FAILED is returned. +.IP CURLOPT_LOCALPORT +Pass a long. This sets the local port number of the socket used for +connection. This can be used in combination with \fICURLOPT_INTERFACE\fP and +you are recommended to use \fICURLOPT_LOCALPORTRANGE\fP as well when this is +set. Valid port numbers are 1 - 65535. (Added in 7.15.2) +.IP CURLOPT_LOCALPORTRANGE +Pass a long. This is the number of attempts libcurl will make to find a +working local port number. It starts with the given \fICURLOPT_LOCALPORT\fP +and adds one to the number for each retry. Setting this to 1 or below will +make libcurl do only one try for the exact port number. Port numbers by nature +are scarce resources that will be busy at times so setting this value to +something too low might cause unnecessary connection setup failures. (Added in +7.15.2) +.IP CURLOPT_DNS_CACHE_TIMEOUT +Pass a long, this sets the timeout in seconds. Name resolves will be kept in +memory for this number of seconds. Set to zero to completely disable +caching, or set to -1 to make the cached entries remain forever. By default, +libcurl caches this info for 60 seconds. + +The name resolve functions of various libc implementations don't re-read name +server information unless explicitly told so (for example, by calling +\fIres_init(3)\fP). This may cause libcurl to keep using the older server even +if DHCP has updated the server info, and this may look like a DNS cache issue +to the casual libcurl-app user. +.IP CURLOPT_DNS_USE_GLOBAL_CACHE +Pass a long. If the value is 1, it tells curl to use a global DNS cache +that will survive between easy handle creations and deletions. This is not +thread-safe and this will use a global variable. + +\fBWARNING:\fP this option is considered obsolete. Stop using it. Switch over +to using the share interface instead! See \fICURLOPT_SHARE\fP and +\fIcurl_share_init(3)\fP. +.IP CURLOPT_BUFFERSIZE +Pass a long specifying your preferred size (in bytes) for the receive buffer +in libcurl. The main point of this would be that the write callback gets +called more often and with smaller chunks. This is just treated as a request, +not an order. You cannot be guaranteed to actually get the given size. (Added +in 7.10) + +This size is by default set as big as possible (CURL_MAX_WRITE_SIZE), so it +only makes sense to use this option if you want it smaller. +.IP CURLOPT_PORT +Pass a long specifying what remote port number to connect to, instead of the +one specified in the URL or the default port for the used protocol. +.IP CURLOPT_TCP_NODELAY +Pass a long specifying whether the TCP_NODELAY option is to be set or cleared +(1 = set, 0 = clear). The option is cleared by default. This will have no +effect after the connection has been established. + +Setting this option will disable TCP's Nagle algorithm. The purpose of this +algorithm is to try to minimize the number of small packets on the network +(where "small packets" means TCP segments less than the Maximum Segment Size +(MSS) for the network). + +Maximizing the amount of data sent per TCP segment is good because it +amortizes the overhead of the send. However, in some cases (most notably +telnet or rlogin) small segments may need to be sent without delay. This is +less efficient than sending larger amounts of data at a time, and can +contribute to congestion on the network if overdone. +.IP CURLOPT_ADDRESS_SCOPE +Pass a long specifying the scope_id value to use when connecting to IPv6 +link-local or site-local addresses. (Added in 7.19.0) +.IP CURLOPT_TCP_KEEPALIVE +Pass a long. If set to 1, TCP keepalive probes will be sent. The delay and +frequency of these probes can be controlled by the \fICURLOPT_TCP_KEEPIDLE\fP +and \fICURLOPT_TCP_KEEPINTVL\fP options, provided the operating system supports +them. Set to 0 (default behavior) to disable keepalive probes (Added in +7.25.0). +.IP CURLOPT_TCP_KEEPIDLE +Pass a long. Sets the delay, in seconds, that the operating system will wait +while the connection is idle before sending keepalive probes. Not all operating +systems support this option. (Added in 7.25.0) +.IP CURLOPT_TCP_KEEPINTVL +Pass a long. Sets the interval, in seconds, that the operating system will wait +between sending keepalive probes. Not all operating systems support this +option. (Added in 7.25.0) +.SH NAMES and PASSWORDS OPTIONS (Authentication) +.IP CURLOPT_NETRC +This parameter controls the preference of libcurl between using user names and +passwords from your \fI~/.netrc\fP file, relative to user names and passwords +in the URL supplied with \fICURLOPT_URL\fP. + +libcurl uses a user name (and supplied or prompted password) supplied with +\fICURLOPT_USERPWD\fP in preference to any of the options controlled by this +parameter. + +Pass a long, set to one of the values described below. +.RS +.IP CURL_NETRC_OPTIONAL +The use of your \fI~/.netrc\fP file is optional, and information in the URL is +to be preferred. The file will be scanned for the host and user name (to +find the password only) or for the host only, to find the first user name and +password after that \fImachine\fP, which ever information is not specified in +the URL. + +Undefined values of the option will have this effect. +.IP CURL_NETRC_IGNORED +The library will ignore the file and use only the information in the URL. + +This is the default. +.IP CURL_NETRC_REQUIRED +This value tells the library that use of the file is required, to ignore the +information in the URL, and to search the file for the host only. +.RE +Only machine name, user name and password are taken into account +(init macros and similar things aren't supported). + +libcurl does not verify that the file has the correct properties set (as the +standard Unix ftp client does). It should only be readable by user. +.IP CURLOPT_NETRC_FILE +Pass a char * as parameter, pointing to a zero terminated string containing +the full path name to the file you want libcurl to use as .netrc file. If this +option is omitted, and \fICURLOPT_NETRC\fP is set, libcurl will attempt to +find a .netrc file in the current user's home directory. (Added in 7.10.9) +.IP CURLOPT_USERPWD +Pass a char * as parameter, which should be [user name]:[password] to use for +the connection. Use \fICURLOPT_HTTPAUTH\fP to decide the authentication method. + +When using NTLM, you can set the domain by prepending it to the user name and +separating the domain and name with a forward (/) or backward slash (\\). Like +this: "domain/user:password" or "domain\\user:password". Some HTTP servers (on +Windows) support this style even for Basic authentication. + +When using HTTP and \fICURLOPT_FOLLOWLOCATION\fP, libcurl might perform +several requests to possibly different hosts. libcurl will only send this user +and password information to hosts using the initial host name (unless +\fICURLOPT_UNRESTRICTED_AUTH\fP is set), so if libcurl follows locations to +other hosts it will not send the user and password to those. This is enforced +to prevent accidental information leakage. +.IP CURLOPT_PROXYUSERPWD +Pass a char * as parameter, which should be [user name]:[password] to use for +the connection to the HTTP proxy. Use \fICURLOPT_PROXYAUTH\fP to decide +the authentication method. +.IP CURLOPT_USERNAME +Pass a char * as parameter, which should be pointing to the zero terminated +user name to use for the transfer. + +\fBCURLOPT_USERNAME\fP sets the user name to be used in protocol +authentication. You should not use this option together with the (older) +CURLOPT_USERPWD option. + +In order to specify the password to be used in conjunction with the user name +use the \fICURLOPT_PASSWORD\fP option. (Added in 7.19.1) +.IP CURLOPT_PASSWORD +Pass a char * as parameter, which should be pointing to the zero terminated +password to use for the transfer. + +The CURLOPT_PASSWORD option should be used in conjunction with +the \fICURLOPT_USERNAME\fP option. (Added in 7.19.1) +.IP CURLOPT_PROXYUSERNAME +Pass a char * as parameter, which should be pointing to the zero terminated +user name to use for the transfer while connecting to Proxy. + +The CURLOPT_PROXYUSERNAME option should be used in same way as the +\fICURLOPT_PROXYUSERPWD\fP is used. In comparison to +\fICURLOPT_PROXYUSERPWD\fP the CURLOPT_PROXYUSERNAME allows the username to +contain a colon, like in the following example: "sip:user@example.com". The +CURLOPT_PROXYUSERNAME option is an alternative way to set the user name while +connecting to Proxy. There is no meaning to use it together with the +\fICURLOPT_PROXYUSERPWD\fP option. + +In order to specify the password to be used in conjunction with the user name +use the \fICURLOPT_PROXYPASSWORD\fP option. (Added in 7.19.1) +.IP CURLOPT_PROXYPASSWORD +Pass a char * as parameter, which should be pointing to the zero terminated +password to use for the transfer while connecting to Proxy. + +The CURLOPT_PROXYPASSWORD option should be used in conjunction with +the \fICURLOPT_PROXYUSERNAME\fP option. (Added in 7.19.1) +.IP CURLOPT_HTTPAUTH +Pass a long as parameter, which is set to a bitmask, to tell libcurl which +authentication method(s) you want it to use. The available bits are listed +below. If more than one bit is set, libcurl will first query the site to see +which authentication methods it supports and then pick the best one you allow +it to use. For some methods, this will induce an extra network round-trip. Set +the actual name and password with the \fICURLOPT_USERPWD\fP option or +with the \fICURLOPT_USERNAME\fP and the \fICURLOPT_PASSWORD\fP options. +(Added in 7.10.6) +.RS +.IP CURLAUTH_BASIC +HTTP Basic authentication. This is the default choice, and the only method +that is in wide-spread use and supported virtually everywhere. This sends +the user name and password over the network in plain text, easily captured by +others. +.IP CURLAUTH_DIGEST +HTTP Digest authentication. Digest authentication is defined in RFC2617 and +is a more secure way to do authentication over public networks than the +regular old-fashioned Basic method. +.IP CURLAUTH_DIGEST_IE +HTTP Digest authentication with an IE flavor. Digest authentication is +defined in RFC2617 and is a more secure way to do authentication over public +networks than the regular old-fashioned Basic method. The IE flavor is simply +that libcurl will use a special "quirk" that IE is known to have used before +version 7 and that some servers require the client to use. (This define was +added in 7.19.3) +.IP CURLAUTH_GSSNEGOTIATE +HTTP GSS-Negotiate authentication. The GSS-Negotiate (also known as plain +\&"Negotiate") method was designed by Microsoft and is used in their web +applications. It is primarily meant as a support for Kerberos5 authentication +but may also be used along with other authentication methods. For more +information see IETF draft draft-brezak-spnego-http-04.txt. + +You need to build libcurl with a suitable GSS-API library for this to work. +.IP CURLAUTH_NTLM +HTTP NTLM authentication. A proprietary protocol invented and used by +Microsoft. It uses a challenge-response and hash concept similar to Digest, to +prevent the password from being eavesdropped. + +You need to build libcurl with either OpenSSL, GnuTLS or NSS support for this +option to work, or build libcurl on Windows. +.IP CURLAUTH_NTLM_WB +NTLM delegating to winbind helper. Authentication is performed by a separate +binary application that is executed when needed. The name of the application +is specified at compile time but is typically /usr/bin/ntlm_auth +(Added in 7.22.0) + +Note that libcurl will fork when necessary to run the winbind application and +kill it when complete, calling waitpid() to await its exit when done. On POSIX +operating systems, killing the process will cause a SIGCHLD signal to be +raised (regardless of whether \fICURLOPT_NOSIGNAL\fP is set), which must be +handled intelligently by the application. In particular, the application must +not unconditionally call wait() in its SIGCHLD signal handler to avoid being +subject to a race condition. This behavior is subject to change in future +versions of libcurl. +.IP CURLAUTH_ANY +This is a convenience macro that sets all bits and thus makes libcurl pick any +it finds suitable. libcurl will automatically select the one it finds most +secure. +.IP CURLAUTH_ANYSAFE +This is a convenience macro that sets all bits except Basic and thus makes +libcurl pick any it finds suitable. libcurl will automatically select the one +it finds most secure. +.IP CURLAUTH_ONLY +This is a meta symbol. Or this value together with a single specific auth +value to force libcurl to probe for un-restricted auth and if not, only that +single auth algorithm is acceptable. (Added in 7.21.3) +.RE +.IP CURLOPT_TLSAUTH_TYPE +Pass a long as parameter, which is set to a bitmask, to tell libcurl which +authentication method(s) you want it to use for TLS authentication. +.RS +.IP CURLOPT_TLSAUTH_SRP +TLS-SRP authentication. Secure Remote Password authentication for TLS is +defined in RFC5054 and provides mutual authentication if both sides have a +shared secret. To use TLS-SRP, you must also set the +\fICURLOPT_TLSAUTH_USERNAME\fP and \fICURLOPT_TLSAUTH_PASSWORD\fP options. + +You need to build libcurl with GnuTLS or OpenSSL with TLS-SRP support for this +to work. (Added in 7.21.4) +.RE +.IP CURLOPT_TLSAUTH_USERNAME +Pass a char * as parameter, which should point to the zero terminated username +to use for the TLS authentication method specified with the +\fICURLOPT_TLSAUTH_TYPE\fP option. Requires that the +\fICURLOPT_TLS_PASSWORD\fP option also be set. (Added in 7.21.4) +.IP CURLOPT_TLSAUTH_PASSWORD +Pass a char * as parameter, which should point to the zero terminated password +to use for the TLS authentication method specified with the +\fICURLOPT_TLSAUTH_TYPE\fP option. Requires that the +\fICURLOPT_TLS_USERNAME\fP option also be set. (Added in 7.21.4) +.IP CURLOPT_PROXYAUTH +Pass a long as parameter, which is set to a bitmask, to tell libcurl which +authentication method(s) you want it to use for your proxy authentication. If +more than one bit is set, libcurl will first query the site to see what +authentication methods it supports and then pick the best one you allow it to +use. For some methods, this will induce an extra network round-trip. Set the +actual name and password with the \fICURLOPT_PROXYUSERPWD\fP option. The +bitmask can be constructed by or'ing together the bits listed above for the +\fICURLOPT_HTTPAUTH\fP option. As of this writing, only Basic, Digest and NTLM +work. (Added in 7.10.7) +.SH HTTP OPTIONS +.IP CURLOPT_AUTOREFERER +Pass a parameter set to 1 to enable this. When enabled, libcurl will +automatically set the Referer: field in requests where it follows a Location: +redirect. +.IP CURLOPT_ACCEPT_ENCODING +Sets the contents of the Accept-Encoding: header sent in a HTTP request, and +enables decoding of a response when a Content-Encoding: header is received. +Three encodings are supported: \fIidentity\fP, which does nothing, +\fIdeflate\fP which requests the server to compress its response using the +zlib algorithm, and \fIgzip\fP which requests the gzip algorithm. If a +zero-length string is set, then an Accept-Encoding: header containing all +supported encodings is sent. + +This is a request, not an order; the server may or may not do it. This option +must be set (to any non-NULL value) or else any unsolicited encoding done by +the server is ignored. See the special file lib/README.encoding for details. + +(This option was called CURLOPT_ENCODING before 7.21.6) +.IP CURLOPT_TRANSFER_ENCODING +Adds a request for compressed Transfer Encoding in the outgoing HTTP +request. If the server supports this and so desires, it can respond with the +HTTP response sent using a compressed Transfer-Encoding that will be +automatically uncompressed by libcurl on reception. + +Transfer-Encoding differs slightly from the Content-Encoding you ask for with +\fBCURLOPT_ACCEPT_ENCODING\fP in that a Transfer-Encoding is strictly meant to +be for the transfer and thus MUST be decoded before the data arrives in the +client. Traditionally, Transfer-Encoding has been much less used and supported +by both HTTP clients and HTTP servers. + +(Added in 7.21.6) +.IP CURLOPT_FOLLOWLOCATION +A parameter set to 1 tells the library to follow any Location: header that the +server sends as part of a HTTP header. + +This means that the library will re-send the same request on the new location +and follow new Location: headers all the way until no more such headers are +returned. \fICURLOPT_MAXREDIRS\fP can be used to limit the number of redirects +libcurl will follow. + +Since 7.19.4, libcurl can limit what protocols it will automatically +follow. The accepted protocols are set with \fICURLOPT_REDIR_PROTOCOLS\fP and +it excludes the FILE protocol by default. +.IP CURLOPT_UNRESTRICTED_AUTH +A parameter set to 1 tells the library it can continue to send authentication +(user+password) when following locations, even when hostname changed. This +option is meaningful only when setting \fICURLOPT_FOLLOWLOCATION\fP. +.IP CURLOPT_MAXREDIRS +Pass a long. The set number will be the redirection limit. If that many +redirections have been followed, the next redirect will cause an error +(\fICURLE_TOO_MANY_REDIRECTS\fP). This option only makes sense if the +\fICURLOPT_FOLLOWLOCATION\fP is used at the same time. Added in 7.15.1: +Setting the limit to 0 will make libcurl refuse any redirect. Set it to -1 for +an infinite number of redirects (which is the default) +.IP CURLOPT_POSTREDIR +Pass a bitmask to control how libcurl acts on redirects after POSTs that get a +301, 302 or 303 response back. A parameter with bit 0 set (value +\fBCURL_REDIR_POST_301\fP) tells the library to respect RFC2616/10.3.2 and not +convert POST requests into GET requests when following a 301 redirection. +Setting bit 1 (value \fBCURL_REDIR_POST_302\fP) makes libcurl maintain the +request method after a 302 redirect whilst setting bit 2 (value +\fBCURL_REDIR_POST_303\fP) makes libcurl maintain the request method after a +303 redirect. The value \fBCURL_REDIR_POST_ALL\fP is a convenience define that +sets all three bits. + +The non-RFC behaviour is ubiquitous in web browsers, so the library does the +conversion by default to maintain consistency. However, a server may require a +POST to remain a POST after such a redirection. This option is meaningful only +when setting \fICURLOPT_FOLLOWLOCATION\fP. (Added in 7.17.1) (This option was +known as CURLOPT_POST301 up to 7.19.0 as it only supported the 301 then) +.IP CURLOPT_PUT +A parameter set to 1 tells the library to use HTTP PUT to transfer data. The +data should be set with \fICURLOPT_READDATA\fP and \fICURLOPT_INFILESIZE\fP. + +This option is deprecated and starting with version 7.12.1 you should instead +use \fICURLOPT_UPLOAD\fP. +.IP CURLOPT_POST +A parameter set to 1 tells the library to do a regular HTTP post. This will +also make the library use a "Content-Type: +application/x-www-form-urlencoded" header. (This is by far the most commonly +used POST method). + +Use one of \fICURLOPT_POSTFIELDS\fP or \fICURLOPT_COPYPOSTFIELDS\fP options to +specify what data to post and \fICURLOPT_POSTFIELDSIZE\fP or +\fICURLOPT_POSTFIELDSIZE_LARGE\fP to set the data size. + +Optionally, you can provide data to POST using the \fICURLOPT_READFUNCTION\fP +and \fICURLOPT_READDATA\fP options but then you must make sure to not set +\fICURLOPT_POSTFIELDS\fP to anything but NULL. When providing data with a +callback, you must transmit it using chunked transfer-encoding or you must set +the size of the data with the \fICURLOPT_POSTFIELDSIZE\fP or +\fICURLOPT_POSTFIELDSIZE_LARGE\fP option. To enable chunked encoding, you +simply pass in the appropriate Transfer-Encoding header, see the +post-callback.c example. + +You can override the default POST Content-Type: header by setting your own +with \fICURLOPT_HTTPHEADER\fP. + +Using POST with HTTP 1.1 implies the use of a "Expect: 100-continue" header. +You can disable this header with \fICURLOPT_HTTPHEADER\fP as usual. + +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 +\fICURLOPT_HTTPHEADER\fP. With HTTP 1.0 or without chunked transfer, you must +specify the size in the request. + +When setting \fICURLOPT_POST\fP to 1, it will automatically set +\fICURLOPT_NOBODY\fP to 0 (since 7.14.1). + +If you issue a POST request and then want to make a HEAD or GET using the same +re-used handle, you must explicitly set the new request type using +\fICURLOPT_NOBODY\fP or \fICURLOPT_HTTPGET\fP or similar. +.IP CURLOPT_POSTFIELDS +Pass a void * as parameter, which should be the full data to post in a HTTP +POST operation. You must make sure that the data is formatted the way you want +the server to receive it. libcurl will not convert or encode it for you. Most +web servers will assume this data to be url-encoded. + +The pointed data are NOT copied by the library: as a consequence, they must +be preserved by the calling application until the transfer finishes. + +This POST is a normal application/x-www-form-urlencoded kind (and libcurl will +set that Content-Type by default when this option is used), which is the most +commonly used one by HTML forms. See also the \fICURLOPT_POST\fP. Using +\fICURLOPT_POSTFIELDS\fP implies \fICURLOPT_POST\fP. + +If you want to do a zero-byte POST, you need to set +\fICURLOPT_POSTFIELDSIZE\fP explicitly to zero, as simply setting +\fICURLOPT_POSTFIELDS\fP to NULL or "" just effectively disables the sending +of the specified string. libcurl will instead assume that you'll send the POST +data using the read callback! + +Using POST with HTTP 1.1 implies the use of a "Expect: 100-continue" header. +You can disable this header with \fICURLOPT_HTTPHEADER\fP as usual. + +To make multipart/formdata posts (aka RFC2388-posts), check out the +\fICURLOPT_HTTPPOST\fP option. +.IP CURLOPT_POSTFIELDSIZE +If you want to post data to the server without letting libcurl do a strlen() +to measure the data size, this option must be used. When this option is used +you can post fully binary data, which otherwise is likely to fail. If this +size is set to -1, the library will use strlen() to get the size. +.IP CURLOPT_POSTFIELDSIZE_LARGE +Pass a curl_off_t as parameter. Use this to set the size of the +\fICURLOPT_POSTFIELDS\fP data to prevent libcurl from doing strlen() on the +data to figure out the size. This is the large file version of the +\fICURLOPT_POSTFIELDSIZE\fP option. (Added in 7.11.1) +.IP CURLOPT_COPYPOSTFIELDS +Pass a char * as parameter, which should be the full data to post in a HTTP +POST operation. It behaves as the \fICURLOPT_POSTFIELDS\fP option, but the +original data are copied by the library, allowing the application to overwrite +the original data after setting this option. + +Because data are copied, care must be taken when using this option in +conjunction with \fICURLOPT_POSTFIELDSIZE\fP or +\fICURLOPT_POSTFIELDSIZE_LARGE\fP: If the size has not been set prior to +\fICURLOPT_COPYPOSTFIELDS\fP, the data are assumed to be a NUL-terminated +string; else the stored size informs the library about the data byte count to +copy. In any case, the size must not be changed after +\fICURLOPT_COPYPOSTFIELDS\fP, unless another \fICURLOPT_POSTFIELDS\fP or +\fICURLOPT_COPYPOSTFIELDS\fP option is issued. +(Added in 7.17.1) +.IP CURLOPT_HTTPPOST +Tells libcurl you want a multipart/formdata HTTP POST to be made and you +instruct what data to pass on to the server. Pass a pointer to a linked list +of curl_httppost structs as parameter. The easiest way to create such a +list, is to use \fIcurl_formadd(3)\fP as documented. The data in this list +must remain intact until you close this curl handle again with +\fIcurl_easy_cleanup(3)\fP. + +Using POST with HTTP 1.1 implies the use of a "Expect: 100-continue" header. +You can disable this header with \fICURLOPT_HTTPHEADER\fP as usual. + +When setting \fICURLOPT_HTTPPOST\fP, it will automatically set +\fICURLOPT_NOBODY\fP to 0 (since 7.14.1). +.IP CURLOPT_REFERER +Pass a pointer to a zero terminated string as parameter. It will be used to +set the Referer: header in the http request sent to the remote server. This +can be used to fool servers or scripts. You can also set any custom header +with \fICURLOPT_HTTPHEADER\fP. +.IP CURLOPT_USERAGENT +Pass a pointer to a zero terminated string as parameter. It will be used to +set the User-Agent: header in the http request sent to the remote server. This +can be used to fool servers or scripts. You can also set any custom header +with \fICURLOPT_HTTPHEADER\fP. +.IP CURLOPT_HTTPHEADER +Pass a pointer to a linked list of HTTP headers to pass to the server in your +HTTP request. The linked list should be a fully valid list of \fBstruct +curl_slist\fP structs properly filled in. Use \fIcurl_slist_append(3)\fP to +create the list and \fIcurl_slist_free_all(3)\fP to clean up an entire +list. If you add a header that is otherwise generated and used by libcurl +internally, your added one will be used instead. If you add a header with no +content as in 'Accept:' (no data on the right side of the colon), the +internally used header will get disabled. Thus, using this option you can add +new headers, replace internal headers and remove internal headers. To add a +header with no content, make the content be two quotes: \&"". The headers +included in the linked list must not be CRLF-terminated, because curl adds +CRLF after each header item. Failure to comply with this will result in +strange bugs because the server will most likely ignore part of the headers +you specified. + +The first line in a request (containing the method, usually a GET or POST) is +not a header and cannot be replaced using this option. Only the lines +following the request-line are headers. Adding this method line in this list +of headers will only cause your request to send an invalid header. + +Pass a NULL to this to reset back to no custom headers. + +The most commonly replaced headers have "shortcuts" in the options +\fICURLOPT_COOKIE\fP, \fICURLOPT_USERAGENT\fP and \fICURLOPT_REFERER\fP. +.IP CURLOPT_HTTP200ALIASES +Pass a pointer to a linked list of aliases to be treated as valid HTTP 200 +responses. Some servers respond with a custom header response line. For +example, IceCast servers respond with "ICY 200 OK". By including this string +in your list of aliases, the response will be treated as a valid HTTP header +line such as "HTTP/1.0 200 OK". (Added in 7.10.3) + +The linked list should be a fully valid list of struct curl_slist structs, and +be properly filled in. Use \fIcurl_slist_append(3)\fP to create the list and +\fIcurl_slist_free_all(3)\fP to clean up an entire list. + +The alias itself is not parsed for any version strings. Before libcurl 7.16.3, +Libcurl used the value set by option \fICURLOPT_HTTP_VERSION\fP, but starting +with 7.16.3 the protocol is assumed to match HTTP 1.0 when an alias matched. +.IP CURLOPT_COOKIE +Pass a pointer to a zero terminated string as parameter. It will be used to +set a cookie in the http request. The format of the string should be +NAME=CONTENTS, where NAME is the cookie name and CONTENTS is what the cookie +should contain. + +If you need to set multiple cookies, you need to set them all using a single +option and thus you need to concatenate them all in one single string. Set +multiple cookies in one string like this: "name1=content1; name2=content2;" +etc. + +This option sets the cookie header explicitly in the outgoing request(s). If +multiple requests are done due to authentication, followed redirections or +similar, they will all get this cookie passed on. + +Using this option multiple times will only make the latest string override the +previous ones. +.IP CURLOPT_COOKIEFILE +Pass a pointer to a zero terminated string as parameter. It should contain the +name of your file holding cookie data to read. The cookie data may be in +Netscape / Mozilla cookie data format or just regular HTTP-style headers +dumped to a file. + +Given an empty or non-existing file or by passing the empty string (""), this +option will enable cookies for this curl handle, making it understand and +parse received cookies and then use matching cookies in future requests. + +If you use this option multiple times, you just add more files to read. +Subsequent files will add more cookies. +.IP CURLOPT_COOKIEJAR +Pass a file name as char *, zero terminated. This will make libcurl write all +internally known cookies to the specified file when \fIcurl_easy_cleanup(3)\fP +is called. If no cookies are known, no file will be created. Specify "-" to +instead have the cookies written to stdout. Using this option also enables +cookies for this session, so if you for example follow a location it will make +matching cookies get sent accordingly. + +If the cookie jar file can't be created or written to (when the +\fIcurl_easy_cleanup(3)\fP is called), libcurl will not and cannot report an +error for this. Using \fICURLOPT_VERBOSE\fP or \fICURLOPT_DEBUGFUNCTION\fP +will get a warning to display, but that is the only visible feedback you get +about this possibly lethal situation. +.IP CURLOPT_COOKIESESSION +Pass a long set to 1 to mark this as a new cookie "session". It will force +libcurl to ignore all cookies it is about to load that are "session cookies" +from the previous session. By default, libcurl always stores and loads all +cookies, independent if they are session cookies or not. Session cookies are +cookies without expiry date and they are meant to be alive and existing for +this "session" only. +.IP CURLOPT_COOKIELIST +Pass a char * to a cookie string. Cookie can be either in Netscape / Mozilla +format or just regular HTTP-style header (Set-Cookie: ...) format. If cURL +cookie engine was not enabled it will enable its cookie engine. Passing a +magic string \&"ALL" will erase all cookies known by cURL. (Added in 7.14.1) +Passing the special string \&"SESS" will only erase all session cookies known +by cURL. (Added in 7.15.4) Passing the special string \&"FLUSH" will write +all cookies known by cURL to the file specified by \fICURLOPT_COOKIEJAR\fP. +(Added in 7.17.1) +.IP CURLOPT_HTTPGET +Pass a long. If the long is 1, this forces the HTTP request to get back +to GET. Usable if a POST, HEAD, PUT, or a custom request has been used +previously using the same curl handle. + +When setting \fICURLOPT_HTTPGET\fP to 1, it will automatically set +\fICURLOPT_NOBODY\fP to 0 (since 7.14.1). +.IP CURLOPT_HTTP_VERSION +Pass a long, set to one of the values described below. They force libcurl to +use the specific HTTP versions. This is not sensible to do unless you have a +good reason. +.RS +.IP CURL_HTTP_VERSION_NONE +We don't care about what version the library uses. libcurl will use whatever +it thinks fit. +.IP CURL_HTTP_VERSION_1_0 +Enforce HTTP 1.0 requests. +.IP CURL_HTTP_VERSION_1_1 +Enforce HTTP 1.1 requests. +.RE +.IP CURLOPT_IGNORE_CONTENT_LENGTH +Ignore the Content-Length header. This is useful for Apache 1.x (and similar +servers) which will report incorrect content length for files over 2 +gigabytes. If this option is used, curl will not be able to accurately report +progress, and will simply stop the download when the server ends the +connection. (added in 7.14.1) +.IP CURLOPT_HTTP_CONTENT_DECODING +Pass a long to tell libcurl how to act on content decoding. If set to zero, +content decoding will be disabled. If set to 1 it is enabled. Libcurl has no +default content decoding but requires you to use \fICURLOPT_ENCODING\fP for +that. (added in 7.16.2) +.IP CURLOPT_HTTP_TRANSFER_DECODING +Pass a long to tell libcurl how to act on transfer decoding. If set to zero, +transfer decoding will be disabled, if set to 1 it is enabled +(default). libcurl does chunked transfer decoding by default unless this +option is set to zero. (added in 7.16.2) +.SH SMTP OPTIONS +.IP CURLOPT_MAIL_FROM +Pass a pointer to a zero terminated string as parameter. This should be used +to specify the sender's email address when sending SMTP mail with libcurl. + +An originator email address should be specified with angled brackets (<>) +around it, which if not specified, will be added by libcurl from version +7.21.4 onwards. Failing to provide such brackets may cause the server to +reject the email. + +If this parameter is not specified then an empty address will be sent to the +mail server which may or may not cause the email to be rejected. + +(Added in 7.20.0) +.IP CURLOPT_MAIL_RCPT +Pass a pointer to a linked list of recipients to pass to the server in your +SMTP mail request. The linked list should be a fully valid list of \fBstruct +curl_slist\fP structs properly filled in. Use \fIcurl_slist_append(3)\fP to +create the list and \fIcurl_slist_free_all(3)\fP to clean up an entire list. + +Each recipient should be specified within a pair of angled brackets (<>), +however, should you not use an angled bracket as the first character libcurl +will assume you provided a single email address and enclose that address +within brackets for you. + +(Added in 7.20.0) +.IP CURLOPT_MAIL_AUTH +Pass a pointer to a zero terminated string as parameter. This will be used +to specify the authentication address (identity) of a submitted message that +is being relayed to another server. + +This optional parameter allows co-operating agents in a trusted environment to +communicate the authentication of individual messages and should only be used +by the application program, using libcurl, if the application is itself a +mail server acting in such an environment. If the application is operating as +such and the AUTH address is not known or is invalid, then an empty string +should be used for this parameter. + +Unlike CURLOPT_MAIL_FROM and CURLOPT_MAIL_RCPT, the address should not be +specified within a pair of angled brackets (<>). However, if an empty string +is used then a pair of brackets will be sent by libcurl as required by +RFC2554. + +(Added in 7.25.0) +.SH TFTP OPTIONS +.IP CURLOPT_TFTP_BLKSIZE +Specify block size to use for TFTP data transmission. Valid range as per +RFC2348 is 8-65464 bytes. The default of 512 bytes will be used if this option +is not specified. The specified block size will only be used pending support +by the remote server. If the server does not return an option acknowledgement +or returns an option acknowledgement with no blksize, the default of 512 bytes +will be used. (added in 7.19.4) +.SH FTP OPTIONS +.IP CURLOPT_FTPPORT +Pass a pointer to a zero terminated string as parameter. It will be used to +get the IP address to use for the FTP PORT instruction. The PORT instruction +tells the remote server to connect to our specified IP address. The string may +be a plain IP address, a host name, a network interface name (under Unix) or +just a '-' symbol to let the library use your system's default IP +address. Default FTP operations are passive, and thus won't use PORT. + +The address can be followed by a ':' to specify a port, optionally followed by +a '-' to specify a port range. If the port specified is 0, the operating +system will pick a free port. If a range is provided and all ports in the +range are not available, libcurl will report CURLE_FTP_PORT_FAILED for the +handle. Invalid port/range settings are ignored. IPv6 addresses followed by +a port or portrange have to be in brackets. IPv6 addresses without port/range +specifier can be in brackets. (added in 7.19.5) + +Examples with specified ports: + +.nf + eth0:0 + 192.168.1.2:32000-33000 + curl.se:32123 + [::1]:1234-4567 +.fi + +You disable PORT again and go back to using the passive version by setting +this option to NULL. +.IP CURLOPT_QUOTE +Pass a pointer to a linked list of FTP or SFTP commands to pass to the server +prior to your FTP request. This will be done before any other commands are +issued (even before the CWD command for FTP). The linked list should be a +fully valid list of 'struct curl_slist' structs properly filled in with text +strings. Use \fIcurl_slist_append(3)\fP to append strings (commands) to the +list, and clear the entire list afterwards with +\fIcurl_slist_free_all(3)\fP. Disable this operation again by setting a NULL +to this option. When speaking to a FTP (or SFTP since 7.24.0) server, prefix +the command with an asterisk (*) to make libcurl continue even if the command +fails as by default libcurl will stop at first failure. + +The set of valid FTP commands depends on the server (see RFC959 for a list of +mandatory commands). + +The valid SFTP commands are: chgrp, chmod, chown, ln, mkdir, pwd, rename, rm, +rmdir, symlink (see +.BR curl (1)) +(SFTP support added in 7.16.3) +.IP CURLOPT_POSTQUOTE +Pass a pointer to a linked list of FTP or SFTP commands to pass to the server +after your FTP transfer request. The commands will only be run if no error +occurred. The linked list should be a fully valid list of struct curl_slist +structs properly filled in as described for \fICURLOPT_QUOTE\fP. Disable this +operation again by setting a NULL to this option. +.IP CURLOPT_PREQUOTE +Pass a pointer to a linked list of FTP commands to pass to the server after +the transfer type is set. The linked list should be a fully valid list of +struct curl_slist structs properly filled in as described for +\fICURLOPT_QUOTE\fP. Disable this operation again by setting a NULL to this +option. Before version 7.16.0, if you also set \fICURLOPT_NOBODY\fP to 1, this +option didn't work. +.IP CURLOPT_DIRLISTONLY +A parameter set to 1 tells the library to just list the names of files in a +directory, instead of doing a full directory listing that would include file +sizes, dates etc. This works for FTP and SFTP URLs. + +This causes an FTP NLST command to be sent on an FTP server. Beware that some +FTP servers list only files in their response to NLST; they might not include +subdirectories and symbolic links. + +Setting this option to 1 also implies a directory listing even if the URL +doesn't end with a slash, which otherwise is necessary. + +Do NOT use this option if you also use \fICURLOPT_WILDCARDMATCH\fP as it will +effectively break that feature then. + +(This option was known as CURLOPT_FTPLISTONLY up to 7.16.4) +.IP CURLOPT_APPEND +A parameter set to 1 tells the library to append to the remote file instead of +overwrite it. This is only useful when uploading to an FTP site. + +(This option was known as CURLOPT_FTPAPPEND up to 7.16.4) +.IP CURLOPT_FTP_USE_EPRT +Pass a long. If the value is 1, it tells curl to use the EPRT (and +LPRT) command when doing active FTP downloads (which is enabled by +\fICURLOPT_FTPPORT\fP). Using EPRT means that it will first attempt to use +EPRT and then LPRT before using PORT, but if you pass zero to this +option, it will not try using EPRT or LPRT, only plain PORT. (Added in 7.10.5) + +If the server is an IPv6 host, this option will have no effect as of 7.12.3. +.IP CURLOPT_FTP_USE_EPSV +Pass a long. If the value is 1, it tells curl to use the EPSV command +when doing passive FTP downloads (which it always does by default). Using EPSV +means that it will first attempt to use EPSV before using PASV, but if you +pass zero to this option, it will not try using EPSV, only plain PASV. + +If the server is an IPv6 host, this option will have no effect as of 7.12.3. +.IP CURLOPT_FTP_USE_PRET +Pass a long. If the value is 1, it tells curl to send a PRET command before +PASV (and EPSV). Certain FTP servers, mainly drftpd, require this non-standard +command for directory listings as well as up and downloads in PASV mode. Has +no effect when using the active FTP transfers mode. (Added in 7.20.0) +.IP CURLOPT_FTP_CREATE_MISSING_DIRS +Pass a long. If the value is 1, curl will attempt to create any remote +directory that it fails to CWD into. CWD is the command that changes working +directory. (Added in 7.10.7) + +This setting also applies to SFTP-connections. curl will attempt to create +the remote directory if it can't obtain a handle to the target-location. The +creation will fail if a file of the same name as the directory to create +already exists or lack of permissions prevents creation. (Added in 7.16.3) + +Starting with 7.19.4, you can also set this value to 2, which will make +libcurl retry the CWD command again if the subsequent MKD command fails. This +is especially useful if you're doing many simultaneous connections against the +same server and they all have this option enabled, as then CWD may first fail +but then another connection does MKD before this connection and thus MKD fails +but trying CWD works! 7.19.4 also introduced the \fICURLFTP_CREATE_DIR\fP and +\fICURLFTP_CREATE_DIR_RETRY\fP enum names for these arguments. + +Before version 7.19.4, libcurl will simply ignore arguments set to 2 and act +as if 1 was selected. +.IP CURLOPT_FTP_RESPONSE_TIMEOUT +Pass a long. Causes curl to set a timeout period (in seconds) on the amount +of time that the server is allowed to take in order to generate a response +message for a command before the session is considered hung. While curl is +waiting for a response, this value overrides \fICURLOPT_TIMEOUT\fP. It is +recommended that if used in conjunction with \fICURLOPT_TIMEOUT\fP, you set +\fICURLOPT_FTP_RESPONSE_TIMEOUT\fP to a value smaller than +\fICURLOPT_TIMEOUT\fP. (Added in 7.10.8) +.IP CURLOPT_FTP_ALTERNATIVE_TO_USER +Pass a char * as parameter, pointing to a string which will be used to +authenticate if the usual FTP "USER user" and "PASS password" negotiation +fails. This is currently only known to be required when connecting to +Tumbleweed's Secure Transport FTPS server using client certificates for +authentication. (Added in 7.15.5) +.IP CURLOPT_FTP_SKIP_PASV_IP +Pass a long. If set to 1, it instructs libcurl to not use the IP address the +server suggests in its 227-response to libcurl's PASV command when libcurl +connects the data connection. Instead libcurl will re-use the same IP address +it already uses for the control connection. But it will use the port number +from the 227-response. (Added in 7.14.2) + +This option has no effect if PORT, EPRT or EPSV is used instead of PASV. +.IP CURLOPT_FTPSSLAUTH +Pass a long using one of the values from below, to alter how libcurl issues +\&"AUTH TLS" or "AUTH SSL" when FTP over SSL is activated (see +\fICURLOPT_USE_SSL\fP). (Added in 7.12.2) +.RS +.IP CURLFTPAUTH_DEFAULT +Allow libcurl to decide. +.IP CURLFTPAUTH_SSL +Try "AUTH SSL" first, and only if that fails try "AUTH TLS". +.IP CURLFTPAUTH_TLS +Try "AUTH TLS" first, and only if that fails try "AUTH SSL". +.RE +.IP CURLOPT_FTP_SSL_CCC +If enabled, this option makes libcurl use CCC (Clear Command Channel). It +shuts down the SSL/TLS layer after authenticating. The rest of the +control channel communication will be unencrypted. This allows NAT routers +to follow the FTP transaction. Pass a long using one of the values below. +(Added in 7.16.1) +.RS +.IP CURLFTPSSL_CCC_NONE +Don't attempt to use CCC. +.IP CURLFTPSSL_CCC_PASSIVE +Do not initiate the shutdown, but wait for the server to do it. Do not send +a reply. +.IP CURLFTPSSL_CCC_ACTIVE +Initiate the shutdown and wait for a reply. +.RE +.IP CURLOPT_FTP_ACCOUNT +Pass a pointer to a zero terminated string (or NULL to disable). When an FTP +server asks for "account data" after user name and password has been provided, +this data is sent off using the ACCT command. (Added in 7.13.0) +.IP CURLOPT_FTP_FILEMETHOD +Pass a long that should have one of the following values. This option controls +what method libcurl should use to reach a file on a FTP(S) server. The +argument should be one of the following alternatives: +.RS +.IP CURLFTPMETHOD_MULTICWD +libcurl does a single CWD operation for each path part in the given URL. For +deep hierarchies this means many commands. This is how RFC1738 says it +should be done. This is the default but the slowest behavior. +.IP CURLFTPMETHOD_NOCWD +libcurl does no CWD at all. libcurl will do SIZE, RETR, STOR etc and give a +full path to the server for all these commands. This is the fastest behavior. +.IP CURLFTPMETHOD_SINGLECWD +libcurl does one CWD with the full target directory and then operates on the +file \&"normally" (like in the multicwd case). This is somewhat more standards +compliant than 'nocwd' but without the full penalty of 'multicwd'. +.RE +(Added in 7.15.1) +.SH RTSP OPTIONS +.IP CURLOPT_RTSP_REQUEST +Tell libcurl what kind of RTSP request to make. Pass one of the following RTSP +enum values. Unless noted otherwise, commands require the Session ID to be +initialized. (Added in 7.20.0) +.RS +.IP CURL_RTSPREQ_OPTIONS +Used to retrieve the available methods of the server. The application is +responsible for parsing and obeying the response. \fB(The session ID is not +needed for this method.)\fP (Added in 7.20.0) +.IP CURL_RTSPREQ_DESCRIBE +Used to get the low level description of a stream. The application should note +what formats it understands in the \fI'Accept:'\fP header. Unless set +manually, libcurl will automatically fill in \fI'Accept: +application/sdp'\fP. Time-condition headers will be added to Describe requests +if the \fICURLOPT_TIMECONDITION\fP option is active. \fB(The session ID is not +needed for this method)\fP (Added in 7.20.0) +.IP CURL_RTSPREQ_ANNOUNCE +When sent by a client, this method changes the description of the session. For +example, if a client is using the server to record a meeting, the client can +use Announce to inform the server of all the meta-information about the +session. ANNOUNCE acts like a HTTP PUT or POST just like +\fICURL_RTSPREQ_SET_PARAMETER\fP (Added in 7.20.0) +.IP CURL_RTSPREQ_SETUP +Setup is used to initialize the transport layer for the session. The +application must set the desired Transport options for a session by using the +\fICURLOPT_RTSP_TRANSPORT\fP option prior to calling setup. If no session ID +is currently set with \fICURLOPT_RTSP_SESSION_ID\fP, libcurl will extract and +use the session ID in the response to this request. \fB(The session ID is not +needed for this method).\fP (Added in 7.20.0) +.IP CURL_RTSPREQ_PLAY +Send a Play command to the server. Use the \fICURLOPT_RANGE\fP option to +modify the playback time (e.g. 'npt=10-15'). (Added in 7.20.0) +.IP CURL_RTSPREQ_PAUSE +Send a Pause command to the server. Use the \fICURLOPT_RANGE\fP option with a +single value to indicate when the stream should be halted. (e.g. npt='25') +(Added in 7.20.0) +.IP CURL_RTSPREQ_TEARDOWN +This command terminates an RTSP session. Simply closing a connection does not +terminate the RTSP session since it is valid to control an RTSP session over +different connections. (Added in 7.20.0) +.IP CURL_RTSPREQ_GET_PARAMETER +Retrieve a parameter from the server. By default, libcurl will automatically +include a \fIContent-Type: text/parameters\fP header on all non-empty requests +unless a custom one is set. GET_PARAMETER acts just like a HTTP PUT or POST +(see \fICURL_RTSPREQ_SET_PARAMETER\fP). +Applications wishing to send a heartbeat message (e.g. in the presence of a +server-specified timeout) should send use an empty GET_PARAMETER request. +(Added in 7.20.0) +.IP CURL_RTSPREQ_SET_PARAMETER +Set a parameter on the server. By default, libcurl will automatically include +a \fIContent-Type: text/parameters\fP header unless a custom one is set. The +interaction with SET_PARAMTER is much like a HTTP PUT or POST. An application +may either use \fICURLOPT_UPLOAD\fP with \fICURLOPT_READDATA\fP like a HTTP +PUT, or it may use \fICURLOPT_POSTFIELDS\fP like a HTTP POST. No chunked +transfers are allowed, so the application must set the +\fICURLOPT_INFILESIZE\fP in the former and \fICURLOPT_POSTFIELDSIZE\fP in the +latter. Also, there is no use of multi-part POSTs within RTSP. (Added in +7.20.0) +.IP CURL_RTSPREQ_RECORD +Used to tell the server to record a session. Use the \fICURLOPT_RANGE\fP +option to modify the record time. (Added in 7.20.0) +.IP CURL_RTSPREQ_RECEIVE +This is a special request because it does not send any data to the server. The +application may call this function in order to receive interleaved RTP +data. It will return after processing one read buffer of data in order to give +the application a chance to run. (Added in 7.20.0) +.RE +.IP CURLOPT_RTSP_SESSION_ID +Pass a char * as a parameter to set the value of the current RTSP Session ID +for the handle. Useful for resuming an in-progress session. Once this value is +set to any non-NULL value, libcurl will return \fICURLE_RTSP_SESSION_ERROR\fP +if ID received from the server does not match. If unset (or set to NULL), +libcurl will automatically set the ID the first time the server sets it in a +response. (Added in 7.20.0) +.IP CURLOPT_RTSP_STREAM_URI +Set the stream URI to operate on by passing a char * . For example, a single +session may be controlling \fIrtsp://foo/twister/audio\fP and +\fIrtsp://foo/twister/video\fP and the application can switch to the +appropriate stream using this option. If unset, libcurl will default to +operating on generic server options by passing '*' in the place of the RTSP +Stream URI. This option is distinct from \fICURLOPT_URL\fP. When working with +RTSP, the \fICURLOPT_STREAM_URI\fP indicates what URL to send to the server in +the request header while the \fICURLOPT_URL\fP indicates where to make the +connection to. (e.g. the \fICURLOPT_URL\fP for the above examples might be +set to \fIrtsp://foo/twister\fP (Added in 7.20.0) +.IP CURLOPT_RTSP_TRANSPORT +Pass a char * to tell libcurl what to pass for the Transport: header for this +RTSP session. This is mainly a convenience method to avoid needing to set a +custom Transport: header for every SETUP request. The application must set a +Transport: header before issuing a SETUP request. (Added in 7.20.0) +.IP CURLOPT_RTSP_HEADER +This option is simply an alias for \fICURLOPT_HTTP_HEADER\fP. Use this to +replace the standard headers that RTSP and HTTP share. It is also valid to use +the shortcuts such as \fICURLOPT_USERAGENT\fP. (Added in 7.20.0) +.IP CURLOPT_RTSP_CLIENT_CSEQ +Manually set the the CSEQ number to issue for the next RTSP request. Useful if +the application is resuming a previously broken connection. The CSEQ will +increment from this new number henceforth. (Added in 7.20.0) +.IP CURLOPT_RTSP_SERVER_CSEQ +Manually set the CSEQ number to expect for the next RTSP Server->Client +request. At the moment, this feature (listening for Server requests) is +unimplemented. (Added in 7.20.0) +.SH PROTOCOL OPTIONS +.IP CURLOPT_TRANSFERTEXT +A parameter set to 1 tells the library to use ASCII mode for FTP transfers, +instead of the default binary transfer. For win32 systems it does not set the +stdout to binary mode. This option can be usable when transferring text data +between systems with different views on certain characters, such as newlines +or similar. + +libcurl does not do a complete ASCII conversion when doing ASCII transfers +over FTP. This is a known limitation/flaw that nobody has rectified. libcurl +simply sets the mode to ASCII and performs a standard transfer. +.IP CURLOPT_PROXY_TRANSFER_MODE +Pass a long. If the value is set to 1 (one), it tells libcurl to set the +transfer mode (binary or ASCII) for FTP transfers done via a HTTP proxy, by +appending ;type=a or ;type=i to the URL. Without this setting, or it being set +to 0 (zero, the default), \fICURLOPT_TRANSFERTEXT\fP has no effect when doing +FTP via a proxy. Beware that not all proxies support this feature. (Added in +7.18.0) +.IP CURLOPT_CRLF +Pass a long. If the value is set to 1 (one), libcurl converts Unix newlines to +CRLF newlines on transfers. Disable this option again by setting the value to +0 (zero). +.IP CURLOPT_RANGE +Pass a char * as parameter, which should contain the specified range you +want. It should be in the format "X-Y", where X or Y may be left out. HTTP +transfers also support several intervals, separated with commas as in +\fI"X-Y,N-M"\fP. Using this kind of multiple intervals will cause the HTTP +server to send the response document in pieces (using standard MIME separation +techniques). For RTSP, the formatting of a range should follow RFC2326 +Section 12.29. For RTSP, byte ranges are \fBnot\fP permitted. Instead, ranges +should be given in npt, utc, or smpte formats. + +Pass a NULL to this option to disable the use of ranges. + +Ranges work on HTTP, FTP, FILE (since 7.18.0), and RTSP (since 7.20.0) +transfers only. +.IP CURLOPT_RESUME_FROM +Pass a long as parameter. It contains the offset in number of bytes that you +want the transfer to start from. Set this option to 0 to make the transfer +start from the beginning (effectively disabling resume). For FTP, set this +option to -1 to make the transfer start from the end of the target file +(useful to continue an interrupted upload). + +When doing uploads with FTP, the resume position is where in the local/source +file libcurl should try to resume the upload from and it will then append the +source file to the remote target file. +.IP CURLOPT_RESUME_FROM_LARGE +Pass a curl_off_t as parameter. It contains the offset in number of bytes that +you want the transfer to start from. (Added in 7.11.0) +.IP CURLOPT_CUSTOMREQUEST +Pass a pointer to a zero terminated string as parameter. It can be used to +specify the request instead of GET or HEAD when performing HTTP based +requests, instead of LIST and NLST when performing FTP directory listings and +instead of LIST and RETR when issuing POP3 based commands. This is +particularly useful, for example, for performing a HTTP DELETE request or a +POP3 DELE command. + +Please don't perform this at will, on HTTP based requests, by making sure +your server supports the command you are sending first. + +When you change the request method by setting \fBCURLOPT_CUSTOMREQUEST\fP to +something, you don't actually change how libcurl behaves or acts in regards +to the particular request method, it will only change the actual string sent +in the request. + +For example: + +With the HTTP protocol when you tell libcurl to do a HEAD request, but then +specify a GET though a custom request libcurl will still act as if it sent a +HEAD. To switch to a proper HEAD use \fICURLOPT_NOBODY\fP, to switch to a +proper POST use \fICURLOPT_POST\fP or \fICURLOPT_POSTFIELDS\fP and to switch +to a proper GET use CURLOPT_HTTPGET. + +With the POP3 protocol when you tell libcurl to use a custom request it will +behave like a LIST or RETR command was sent where it expects data to be +returned by the server. As such \fICURLOPT_NOBODY\fP should be used when +specifying commands such as DELE and NOOP for example. + +Restore to the internal default by setting this to NULL. + +Many people have wrongly used this option to replace the entire request with +their own, including multiple headers and POST contents. While that might +work in many cases, it will cause libcurl to send invalid requests and it +could possibly confuse the remote server badly. Use \fICURLOPT_POST\fP and +\fICURLOPT_POSTFIELDS\fP to set POST data. Use \fICURLOPT_HTTPHEADER\fP to +replace or extend the set of headers sent by libcurl. Use +\fICURLOPT_HTTP_VERSION\fP to change HTTP version. + +(Support for POP3 added in 7.26.0) +.IP CURLOPT_FILETIME +Pass a long. If it is 1, libcurl will attempt to get the modification date of +the remote document in this operation. This requires that the remote server +sends the time or replies to a time querying command. The +\fIcurl_easy_getinfo(3)\fP function with the \fICURLINFO_FILETIME\fP argument +can be used after a transfer to extract the received time (if any). +.IP CURLOPT_NOBODY +A parameter set to 1 tells the library to not include the body-part in the +output. This is only relevant for protocols that have separate header and +body parts. On HTTP(S) servers, this will make libcurl do a HEAD request. + +To change request to GET, you should use \fICURLOPT_HTTPGET\fP. Change +request to POST with \fICURLOPT_POST\fP etc. +.IP CURLOPT_INFILESIZE +When uploading a file to a remote site, this option should be used to tell +libcurl what the expected size of the infile is. This value should be passed +as a long. See also \fICURLOPT_INFILESIZE_LARGE\fP. + +For uploading using SCP, this option or \fICURLOPT_INFILESIZE_LARGE\fP is +mandatory. + +When sending emails using SMTP, this command can be used to specify the +optional SIZE parameter for the MAIL FROM command. (Added in 7.23.0) + +This option does not limit how much data libcurl will actually send, as that +is controlled entirely by what the read callback returns. +.IP CURLOPT_INFILESIZE_LARGE +When uploading a file to a remote site, this option should be used to tell +libcurl what the expected size of the infile is. This value should be passed +as a curl_off_t. (Added in 7.11.0) + +For uploading using SCP, this option or \fICURLOPT_INFILESIZE\fP is mandatory. + +This option does not limit how much data libcurl will actually send, as that +is controlled entirely by what the read callback returns. +.IP CURLOPT_UPLOAD +A parameter set to 1 tells the library to prepare for an upload. The +\fICURLOPT_READDATA\fP and \fICURLOPT_INFILESIZE\fP or +\fICURLOPT_INFILESIZE_LARGE\fP options are also interesting for uploads. If +the protocol is HTTP, uploading means using the PUT request unless you tell +libcurl otherwise. + +Using PUT with HTTP 1.1 implies the use of a "Expect: 100-continue" header. +You can disable this header with \fICURLOPT_HTTPHEADER\fP as usual. + +If you use PUT to a HTTP 1.1 server, you can upload data without knowing the +size before starting the transfer if you use chunked encoding. You enable this +by adding a header like "Transfer-Encoding: chunked" with +\fICURLOPT_HTTPHEADER\fP. With HTTP 1.0 or without chunked transfer, you must +specify the size. +.IP CURLOPT_MAXFILESIZE +Pass a long as parameter. This allows you to specify the maximum size (in +bytes) of a file to download. If the file requested is larger than this value, +the transfer will not start and CURLE_FILESIZE_EXCEEDED will be returned. + +The file size is not always known prior to download, and for such files this +option has no effect even if the file transfer ends up being larger than this +given limit. This concerns both FTP and HTTP transfers. +.IP CURLOPT_MAXFILESIZE_LARGE +Pass a curl_off_t as parameter. This allows you to specify the maximum size +(in bytes) of a file to download. If the file requested is larger than this +value, the transfer will not start and \fICURLE_FILESIZE_EXCEEDED\fP will be +returned. (Added in 7.11.0) + +The file size is not always known prior to download, and for such files this +option has no effect even if the file transfer ends up being larger than this +given limit. This concerns both FTP and HTTP transfers. +.IP CURLOPT_TIMECONDITION +Pass a long as parameter. This defines how the \fICURLOPT_TIMEVALUE\fP time +value is treated. You can set this parameter to \fICURL_TIMECOND_IFMODSINCE\fP +or \fICURL_TIMECOND_IFUNMODSINCE\fP. This feature applies to HTTP, FTP, RTSP, +and FILE. + +The last modification time of a file is not always known and in such instances +this feature will have no effect even if the given time condition would not +have been met. \fIcurl_easy_getinfo(3)\fP with the +\fICURLINFO_CONDITION_UNMET\fP option can be used after a transfer to learn if +a zero-byte successful "transfer" was due to this condition not matching. +.IP CURLOPT_TIMEVALUE +Pass a long as parameter. This should be the time in seconds since 1 Jan 1970, +and the time will be used in a condition as specified with +\fICURLOPT_TIMECONDITION\fP. +.SH CONNECTION OPTIONS +.IP CURLOPT_TIMEOUT +Pass a long as parameter containing the maximum time in seconds that you allow +the libcurl transfer operation to take. Normally, name lookups can take a +considerable time and limiting operations to less than a few minutes risk +aborting perfectly normal operations. This option will cause curl to use the +SIGALRM to enable time-outing system calls. + +In unix-like systems, this might cause signals to be used unless +\fICURLOPT_NOSIGNAL\fP is set. + +Default timeout is 0 (zero) which means it never times out. +.IP CURLOPT_TIMEOUT_MS +Like \fICURLOPT_TIMEOUT\fP but takes number of milliseconds instead. If +libcurl is built to use the standard system name resolver, that portion +of the transfer will still use full-second resolution for timeouts with +a minimum timeout allowed of one second. +(Added in 7.16.2) +.IP CURLOPT_LOW_SPEED_LIMIT +Pass a long as parameter. It contains the transfer speed in bytes per second +that the transfer should be below during \fICURLOPT_LOW_SPEED_TIME\fP seconds +for the library to consider it too slow and abort. +.IP CURLOPT_LOW_SPEED_TIME +Pass a long as parameter. It contains the time in seconds that the transfer +should be below the \fICURLOPT_LOW_SPEED_LIMIT\fP for the library to consider +it too slow and abort. +.IP CURLOPT_MAX_SEND_SPEED_LARGE +Pass a curl_off_t as parameter. If an upload exceeds this speed (counted in +bytes per second) on cumulative average during the transfer, the transfer will +pause to keep the average rate less than or equal to the parameter value. +Defaults to unlimited speed. (Added in 7.15.5) +.IP CURLOPT_MAX_RECV_SPEED_LARGE +Pass a curl_off_t as parameter. If a download exceeds this speed (counted in +bytes per second) on cumulative average during the transfer, the transfer will +pause to keep the average rate less than or equal to the parameter +value. Defaults to unlimited speed. (Added in 7.15.5) +.IP CURLOPT_MAXCONNECTS +Pass a long. The set number will be the persistent connection cache size. The +set amount will be the maximum amount of simultaneously open connections that +libcurl may cache in this easy handle. Default is 5, and there isn't much +point in changing this value unless you are perfectly aware of how this works +and changes libcurl's behaviour. This concerns connections using any of the +protocols that support persistent connections. + +When reaching the maximum limit, curl closes the oldest one in the cache to +prevent increasing the number of open connections. + +If you already have performed transfers with this curl handle, setting a +smaller MAXCONNECTS than before may cause open connections to get closed +unnecessarily. + +If you add this easy handle to a multi handle, this setting is not +acknowledged, and you must instead use \fIcurl_multi_setopt(3)\fP and the +\fICURLMOPT_MAXCONNECTS\fP option. +.IP CURLOPT_CLOSEPOLICY +(Obsolete) This option does nothing. +.IP CURLOPT_FRESH_CONNECT +Pass a long. Set to 1 to make the next transfer use a new (fresh) connection +by force. If the connection cache is full before this connection, one of the +existing connections will be closed as according to the selected or default +policy. This option should be used with caution and only if you understand +what it does. Set this to 0 to have libcurl attempt re-using an existing +connection (default behavior). +.IP CURLOPT_FORBID_REUSE +Pass a long. Set to 1 to make the next transfer explicitly close the +connection when done. Normally, libcurl keeps all connections alive when done +with one transfer in case a succeeding one follows that can re-use them. +This option should be used with caution and only if you understand what it +does. Set to 0 to have libcurl keep the connection open for possible later +re-use (default behavior). +.IP CURLOPT_CONNECTTIMEOUT +Pass a long. It should contain the maximum time in seconds that you allow the +connection to the server to take. This only limits the connection phase, once +it has connected, this option is of no more use. Set to zero to switch to the +default built-in connection timeout - 300 seconds. See also the +\fICURLOPT_TIMEOUT\fP option. + +In unix-like systems, this might cause signals to be used unless +\fICURLOPT_NOSIGNAL\fP is set. +.IP CURLOPT_CONNECTTIMEOUT_MS +Like \fICURLOPT_CONNECTTIMEOUT\fP but takes the number of milliseconds +instead. If libcurl is built to use the standard system name resolver, +that portion of the connect will still use full-second resolution for +timeouts with a minimum timeout allowed of one second. +(Added in 7.16.2) +.IP CURLOPT_IPRESOLVE +Allows an application to select what kind of IP addresses to use when +resolving host names. This is only interesting when using host names that +resolve addresses using more than one version of IP. The allowed values are: +.RS +.IP CURL_IPRESOLVE_WHATEVER +Default, resolves addresses to all IP versions that your system allows. +.IP CURL_IPRESOLVE_V4 +Resolve to IPv4 addresses. +.IP CURL_IPRESOLVE_V6 +Resolve to IPv6 addresses. +.RE +.IP CURLOPT_CONNECT_ONLY +Pass a long. If the parameter equals 1, it tells the library to perform all +the required proxy authentication and connection setup, but no data transfer. +This option is implemented for HTTP, SMTP and POP3. + +The option can be used to simply test a connection to a server, but is more +useful when used with the \fICURLINFO_LASTSOCKET\fP option to +\fIcurl_easy_getinfo(3)\fP as the library can set up the connection and then +the application can obtain the most recently used socket for special data +transfers. (Added in 7.15.2) +.IP CURLOPT_USE_SSL +Pass a long using one of the values from below, to make libcurl use your +desired level of SSL for the transfer. (Added in 7.11.0) + +This is for enabling SSL/TLS when you use FTP, SMTP, POP3, IMAP etc. + +(This option was known as CURLOPT_FTP_SSL up to 7.16.4, and the constants +were known as CURLFTPSSL_*) +.RS +.IP CURLUSESSL_NONE +Don't attempt to use SSL. +.IP CURLUSESSL_TRY +Try using SSL, proceed as normal otherwise. +.IP CURLUSESSL_CONTROL +Require SSL for the control connection or fail with \fICURLE_USE_SSL_FAILED\fP. +.IP CURLUSESSL_ALL +Require SSL for all communication or fail with \fICURLE_USE_SSL_FAILED\fP. +.RE +.IP CURLOPT_RESOLVE +Pass a pointer to a linked list of strings with host name resolve information +to use for requests with this handle. The linked list should be a fully valid +list of \fBstruct curl_slist\fP structs properly filled in. Use +\fIcurl_slist_append(3)\fP to create the list and \fIcurl_slist_free_all(3)\fP +to clean up an entire list. + +Each single name resolve string should be written using the format +HOST:PORT:ADDRESS where HOST is the name libcurl will try to resolve, PORT is +the port number of the service where libcurl wants to connect to the HOST and +ADDRESS is the numerical IP address. If libcurl is built to support IPv6, +ADDRESS can of course be either IPv4 or IPv6 style addressing. + +This option effectively pre-populates the DNS cache with entries for the +host+port pair so redirects and everything that operations against the +HOST+PORT will instead use your provided ADDRESS. + +You can remove names from the DNS cache again, to stop providing these fake +resolves, by including a string in the linked list that uses the format +\&"-HOST:PORT". The host name must be prefixed with a dash, and the host name +and port number must exactly match what was already added previously. + +(Added in 7.21.3) +.IP CURLOPT_DNS_SERVERS +Set the list of DNS servers to be used instead of the system default. +The format of the dns servers option is: + +host[:port][,host[:port]]... + +For example: + +192.168.1.100,192.168.1.101,3.4.5.6 + +This option requires that libcurl was built with a resolver backend that +supports this operation. The c-ares backend is the only such one. + +(Added in 7.24.0) +.IP CURLOPT_ACCEPTTIMEOUT_MS +Pass a long telling libcurl the maximum number of milliseconds to wait for a +server to connect back to libcurl when an active FTP connection is used. If no +timeout is set, the internal default of 60000 will be used. (Added in 7.24.0) +.SH SSL and SECURITY OPTIONS +.IP CURLOPT_SSLCERT +Pass a pointer to a zero terminated string as parameter. The string should be +the file name of your certificate. The default format is "PEM" and can be +changed with \fICURLOPT_SSLCERTTYPE\fP. + +With NSS this can also be the nickname of the certificate you wish to +authenticate with. If you want to use a file from the current directory, please +precede it with "./" prefix, in order to avoid confusion with a nickname. +.IP CURLOPT_SSLCERTTYPE +Pass a pointer to a zero terminated string as parameter. The string should be +the format of your certificate. Supported formats are "PEM" and "DER". (Added +in 7.9.3) +.IP CURLOPT_SSLKEY +Pass a pointer to a zero terminated string as parameter. The string should be +the file name of your private key. The default format is "PEM" and can be +changed with \fICURLOPT_SSLKEYTYPE\fP. +.IP CURLOPT_SSLKEYTYPE +Pass a pointer to a zero terminated string as parameter. The string should be +the format of your private key. Supported formats are "PEM", "DER" and "ENG". + +The format "ENG" enables you to load the private key from a crypto engine. In +this case \fICURLOPT_SSLKEY\fP is used as an identifier passed to the +engine. You have to set the crypto engine with \fICURLOPT_SSLENGINE\fP. +\&"DER" format key file currently does not work because of a bug in OpenSSL. +.IP CURLOPT_KEYPASSWD +Pass a pointer to a zero terminated string as parameter. It will be used as +the password required to use the \fICURLOPT_SSLKEY\fP or +\fICURLOPT_SSH_PRIVATE_KEYFILE\fP private key. +You never needed a pass phrase to load a certificate but you need one to +load your private key. + +(This option was known as CURLOPT_SSLKEYPASSWD up to 7.16.4 and +CURLOPT_SSLCERTPASSWD up to 7.9.2) +.IP CURLOPT_SSLENGINE +Pass a pointer to a zero terminated string as parameter. It will be used as +the identifier for the crypto engine you want to use for your private +key. + +If the crypto device cannot be loaded, \fICURLE_SSL_ENGINE_NOTFOUND\fP is +returned. +.IP CURLOPT_SSLENGINE_DEFAULT +Sets the actual crypto engine as the default for (asymmetric) crypto +operations. + +If the crypto device cannot be set, \fICURLE_SSL_ENGINE_SETFAILED\fP is +returned. + +Even though this option doesn't need any parameter, in some configurations +\fIcurl_easy_setopt\fP might be defined as a macro taking exactly three +arguments. Therefore, it's recommended to pass 1 as parameter to this option. +.IP CURLOPT_SSLVERSION +Pass a long as parameter to control what version of SSL/TLS to attempt to use. +The available options are: +.RS +.IP CURL_SSLVERSION_DEFAULT +The default action. This will attempt to figure out the remote SSL protocol +version, i.e. either SSLv3 or TLSv1 (but not SSLv2, which became disabled +by default with 7.18.1). +.IP CURL_SSLVERSION_TLSv1 +Force TLSv1 +.IP CURL_SSLVERSION_SSLv2 +Force SSLv2 +.IP CURL_SSLVERSION_SSLv3 +Force SSLv3 +.RE +.IP CURLOPT_SSL_VERIFYPEER +Pass a long as parameter. By default, curl assumes a value of 1. + +This option determines whether curl verifies the authenticity of the peer's +certificate. A value of 1 means curl verifies; 0 (zero) means it doesn't. + +When negotiating a SSL connection, the server sends a certificate indicating +its identity. Curl verifies whether the certificate is authentic, i.e. that +you can trust that the server is who the certificate says it is. This trust +is based on a chain of digital signatures, rooted in certification authority +(CA) certificates you supply. curl uses a default bundle of CA certificates +(the path for that is determined at build time) and you can specify alternate +certificates with the \fICURLOPT_CAINFO\fP option or the \fICURLOPT_CAPATH\fP +option. + +When \fICURLOPT_SSL_VERIFYPEER\fP is nonzero, and the verification fails to +prove that the certificate is authentic, the connection fails. When the +option is zero, the peer certificate verification succeeds regardless. + +Authenticating the certificate is not by itself very useful. You typically +want to ensure that the server, as authentically identified by its +certificate, is the server you mean to be talking to. Use +\fICURLOPT_SSL_VERIFYHOST\fP to control that. The check that the host name in +the certificate is valid for the host name you're connecting to is done +independently of the \fICURLOPT_SSL_VERIFYPEER\fP option. +.IP CURLOPT_CAINFO +Pass a char * to a zero terminated string naming a file holding one or more +certificates to verify the peer with. This makes sense only when used in +combination with the \fICURLOPT_SSL_VERIFYPEER\fP option. If +\fICURLOPT_SSL_VERIFYPEER\fP is zero, \fICURLOPT_CAINFO\fP need not +even indicate an accessible file. + +This option is by default set to the system path where libcurl's cacert bundle +is assumed to be stored, as established at build time. + +When built against NSS, this is the directory that the NSS certificate +database resides in. +.IP CURLOPT_ISSUERCERT +Pass a char * to a zero terminated string naming a file holding a CA +certificate in PEM format. If the option is set, an additional check against +the peer certificate is performed to verify the issuer is indeed the one +associated with the certificate provided by the option. This additional check +is useful in multi-level PKI where one needs to enforce that the peer +certificate is from a specific branch of the tree. + +This option makes sense only when used in combination with the +\fICURLOPT_SSL_VERIFYPEER\fP option. Otherwise, the result of the check is not +considered as failure. + +A specific error code (CURLE_SSL_ISSUER_ERROR) is defined with the option, +which is returned if the setup of the SSL/TLS session has failed due to a +mismatch with the issuer of peer certificate (\fICURLOPT_SSL_VERIFYPEER\fP has +to be set too for the check to fail). (Added in 7.19.0) +.IP CURLOPT_CAPATH +Pass a char * to a zero terminated string naming a directory holding multiple +CA certificates to verify the peer with. If libcurl is built against OpenSSL, +the certificate directory must be prepared using the openssl c_rehash utility. +This makes sense only when used in combination with the +\fICURLOPT_SSL_VERIFYPEER\fP option. If \fICURLOPT_SSL_VERIFYPEER\fP is zero, +\fICURLOPT_CAPATH\fP need not even indicate an accessible path. The +\fICURLOPT_CAPATH\fP function apparently does not work in Windows due to some +limitation in openssl. This option is OpenSSL-specific and does nothing if +libcurl is built to use GnuTLS. NSS-powered libcurl provides the option only +for backward compatibility. +.IP CURLOPT_CRLFILE +Pass a char * to a zero terminated string naming a file with the concatenation +of CRL (in PEM format) to use in the certificate validation that occurs during +the SSL exchange. + +When curl is built to use NSS or GnuTLS, there is no way to influence the use +of CRL passed to help in the verification process. When libcurl is built with +OpenSSL support, X509_V_FLAG_CRL_CHECK and X509_V_FLAG_CRL_CHECK_ALL are both +set, requiring CRL check against all the elements of the certificate chain if +a CRL file is passed. + +This option makes sense only when used in combination with the +\fICURLOPT_SSL_VERIFYPEER\fP option. + +A specific error code (CURLE_SSL_CRL_BADFILE) is defined with the option. It +is returned when the SSL exchange fails because the CRL file cannot be loaded. +A failure in certificate verification due to a revocation information found in +the CRL does not trigger this specific error. (Added in 7.19.0) +.IP CURLOPT_SSL_VERIFYHOST +Pass a long as parameter. + +This option determines whether libcurl verifies that the server cert is for +the server it is known as. + +When negotiating a SSL connection, the server sends a certificate indicating +its identity. + +When \fICURLOPT_SSL_VERIFYHOST\fP is 2, that certificate must indicate that +the server is the server to which you meant to connect, or the connection +fails. + +Curl considers the server the intended one when the Common Name field or a +Subject Alternate Name field in the certificate matches the host name in the +URL to which you told Curl to connect. + +When the value is 1, libcurl will return a failure. It was previously (in +7.28.0 and earlier) a debug option of some sorts, but it is no longer +supported due to frequently leading to programmer mistakes. + +When the value is 0, the connection succeeds regardless of the names in the +certificate. + +The default value for this option is 2. + +This option controls checking the server's certificate's claimed identity. +The server could be lying. To control lying, see +\fICURLOPT_SSL_VERIFYPEER\fP. If libcurl is built against NSS and +\fICURLOPT_SSL_VERIFYPEER\fP is zero, \fICURLOPT_SSL_VERIFYHOST\fP +is ignored. + +.IP CURLOPT_CERTINFO +Pass a long set to 1 to enable libcurl's certificate chain info gatherer. With +this enabled, libcurl (if built with OpenSSL) will extract lots of information +and data about the certificates in the certificate chain used in the SSL +connection. This data is then possible to extract after a transfer using +\fIcurl_easy_getinfo(3)\fP and its option \fICURLINFO_CERTINFO\fP. (Added in +7.19.1) +.IP CURLOPT_RANDOM_FILE +Pass a char * to a zero terminated file name. The file will be used to read +from to seed the random engine for SSL. The more random the specified file is, +the more secure the SSL connection will become. +.IP CURLOPT_EGDSOCKET +Pass a char * to the zero terminated path name to the Entropy Gathering Daemon +socket. It will be used to seed the random engine for SSL. +.IP CURLOPT_SSL_CIPHER_LIST +Pass a char *, pointing to a zero terminated string holding the list of +ciphers to use for the SSL connection. The list must be syntactically correct, +it consists of one or more cipher strings separated by colons. Commas or +spaces are also acceptable separators but colons are normally used, \&!, \&- +and \&+ can be used as operators. + +For OpenSSL and GnuTLS valid examples of cipher lists include 'RC4-SHA', +\'SHA1+DES\', 'TLSv1' and 'DEFAULT'. The default list is normally set when you +compile OpenSSL. + +You'll find more details about cipher lists on this URL: +\fIhttp://www.openssl.org/docs/apps/ciphers.html\fP + +For NSS, valid examples of cipher lists include 'rsa_rc4_128_md5', +\'rsa_aes_128_sha\', etc. With NSS you don't add/remove ciphers. If one uses +this option then all known ciphers are disabled and only those passed in +are enabled. + +You'll find more details about the NSS cipher lists on this URL: +\fIhttp://git.fedorahosted.org/cgit/mod_nss.git/plain/docs/mod_nss.html#Directives\fP + +.IP CURLOPT_SSL_SESSIONID_CACHE +Pass a long set to 0 to disable libcurl's use of SSL session-ID caching. Set +this to 1 to enable it. By default all transfers are done using the +cache. While nothing ever should get hurt by attempting to reuse SSL +session-IDs, there seem to be broken SSL implementations in the wild that may +require you to disable this in order for you to succeed. (Added in 7.16.0) +.IP CURLOPT_SSL_OPTIONS +Pass a long with a bitmask to tell libcurl about specific SSL behaviors. + +CURLSSLOPT_ALLOW_BEAST is the only supported bit and by setting this the user +will tell libcurl to not attempt to use any workarounds for a security flaw +in the SSL3 and TLS1.0 protocols. If this option isn't used or this bit is +set to 0, the SSL layer libcurl uses may use a work-around for this flaw +although it might cause interoperability problems with some (older) SSL +implementations. WARNING: avoiding this work-around loosens the security, and +by setting this option to 1 you ask for exactly that. (Added in 7.25.0) +.IP CURLOPT_KRBLEVEL +Pass a char * as parameter. Set the kerberos security level for FTP; this also +enables kerberos awareness. This is a string, \&'clear', \&'safe', +\&'confidential' or \&'private'. If the string is set but doesn't match one +of these, 'private' will be used. Set the string to NULL to disable kerberos +support for FTP. + +(This option was known as CURLOPT_KRB4LEVEL up to 7.16.3) +.IP CURLOPT_GSSAPI_DELEGATION +Set the parameter to CURLGSSAPI_DELEGATION_FLAG to allow unconditional GSSAPI +credential delegation. The delegation is disabled by default since 7.21.7. +Set the parameter to CURLGSSAPI_DELEGATION_POLICY_FLAG to delegate only if +the OK-AS-DELEGATE flag is set in the service ticket in case this feature is +supported by the GSSAPI implementation and the definition of +GSS_C_DELEG_POLICY_FLAG was available at compile-time. +(Added in 7.22.0) +.SH SSH OPTIONS +.IP CURLOPT_SSH_AUTH_TYPES +Pass a long set to a bitmask consisting of one or more of +CURLSSH_AUTH_PUBLICKEY, CURLSSH_AUTH_PASSWORD, CURLSSH_AUTH_HOST, +CURLSSH_AUTH_KEYBOARD and CURLSSH_AUTH_AGENT. Set CURLSSH_AUTH_ANY to let +libcurl pick a suitable one. Currently CURLSSH_AUTH_HOST has no effect. (Added +in 7.16.1) If CURLSSH_AUTH_AGENT is used, libcurl attempts to connect to +ssh-agent or pageant and let the agent attempt the authentication. (Added in +7.28.0) +.IP CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 +Pass a char * pointing to a string containing 32 hexadecimal digits. The +string should be the 128 bit MD5 checksum of the remote host's public key, and +libcurl will reject the connection to the host unless the md5sums match. This +option is only for SCP and SFTP transfers. (Added in 7.17.1) +.IP CURLOPT_SSH_PUBLIC_KEYFILE +Pass a char * pointing to a file name for your public key. If not used, +libcurl defaults to \fB$HOME/.ssh/id_dsa.pub\fP if the HOME environment +variable is set, and just "id_dsa.pub" in the current directory if HOME is not +set. (Added in 7.16.1) +If an empty string is passed, libcurl will pass no public key to libssh2 +which then tries to compute it from the private key, this is known to work +when libssh2 1.4.0+ is linked against OpenSSL. (Added in 7.26.0) +.IP CURLOPT_SSH_PRIVATE_KEYFILE +Pass a char * pointing to a file name for your private key. If not used, +libcurl defaults to \fB$HOME/.ssh/id_dsa\fP if the HOME environment variable +is set, and just "id_dsa" in the current directory if HOME is not set. If the +file is password-protected, set the password with +\fICURLOPT_KEYPASSWD\fP. (Added in 7.16.1) +.IP CURLOPT_SSH_KNOWNHOSTS +Pass a pointer to a zero terminated string holding the file name of the +known_host file to use. The known_hosts file should use the OpenSSH file +format as supported by libssh2. If this file is specified, libcurl will only +accept connections with hosts that are known and present in that file, with a +matching public key. Use \fICURLOPT_SSH_KEYFUNCTION\fP to alter the default +behavior on host and key (mis)matching. (Added in 7.19.6) +.IP CURLOPT_SSH_KEYFUNCTION +Pass a pointer to a curl_sshkeycallback function. It gets called when the +known_host matching has been done, to allow the application to act and decide +for libcurl how to proceed. The callback will only be called if +\fICURLOPT_SSH_KNOWNHOSTS\fP is also set. + +The curl_sshkeycallback function gets passed the CURL handle, the key from the +known_hosts file, the key from the remote site, info from libcurl on the +matching status and a custom pointer (set with \fICURLOPT_SSH_KEYDATA\fP). It +MUST return one of the following return codes to tell libcurl how to act: +.RS +.IP CURLKHSTAT_FINE_ADD_TO_FILE +The host+key is accepted and libcurl will append it to the known_hosts file +before continuing with the connection. This will also add the host+key combo +to the known_host pool kept in memory if it wasn't already present there. The +adding of data to the file is done by completely replacing the file with a new +copy, so the permissions of the file must allow this. +.IP CURLKHSTAT_FINE +The host+key is accepted libcurl will continue with the connection. This will +also add the host+key combo to the known_host pool kept in memory if it wasn't +already present there. +.IP CURLKHSTAT_REJECT +The host+key is rejected. libcurl will deny the connection to continue and it +will be closed. +.IP CURLKHSTAT_DEFER +The host+key is rejected, but the SSH connection is asked to be kept alive. +This feature could be used when the app wants to somehow return back and act +on the host+key situation and then retry without needing the overhead of +setting it up from scratch again. +.RE + (Added in 7.19.6) +.IP CURLOPT_SSH_KEYDATA +Pass a void * as parameter. This pointer will be passed along verbatim to the +callback set with \fICURLOPT_SSH_KEYFUNCTION\fP. (Added in 7.19.6) +.SH OTHER OPTIONS +.IP CURLOPT_PRIVATE +Pass a void * as parameter, pointing to data that should be associated with +this curl handle. The pointer can subsequently be retrieved using +\fIcurl_easy_getinfo(3)\fP with the CURLINFO_PRIVATE option. libcurl itself +does nothing with this data. (Added in 7.10.3) +.IP CURLOPT_SHARE +Pass a share handle as a parameter. The share handle must have been created by +a previous call to \fIcurl_share_init(3)\fP. Setting this option, will make +this curl handle use the data from the shared handle instead of keeping the +data to itself. This enables several curl handles to share data. If the curl +handles are used simultaneously in multiple threads, you \fBMUST\fP use the +locking methods in the share handle. See \fIcurl_share_setopt(3)\fP for +details. + +If you add a share that is set to share cookies, your easy handle will use +that cookie cache and get the cookie engine enabled. If you unshare an object +that was using cookies (or change to another object that doesn't share +cookies), the easy handle will get its cookie engine disabled. + +Data that the share object is not set to share will be dealt with the usual +way, as if no share was used. +.IP CURLOPT_NEW_FILE_PERMS +Pass a long as a parameter, containing the value of the permissions that will +be assigned to newly created files on the remote server. The default value is +\fI0644\fP, but any valid value can be used. The only protocols that can use +this are \fIsftp://\fP, \fIscp://\fP, and \fIfile://\fP. (Added in 7.16.4) +.IP CURLOPT_NEW_DIRECTORY_PERMS +Pass a long as a parameter, containing the value of the permissions that will +be assigned to newly created directories on the remote server. The default +value is \fI0755\fP, but any valid value can be used. The only protocols that +can use this are \fIsftp://\fP, \fIscp://\fP, and \fIfile://\fP. +(Added in 7.16.4) +.SH TELNET OPTIONS +.IP CURLOPT_TELNETOPTIONS +Provide a pointer to a curl_slist with variables to pass to the telnet +negotiations. The variables should be in the format <option=value>. libcurl +supports the options 'TTYPE', 'XDISPLOC' and 'NEW_ENV'. See the TELNET +standard for details. +.SH RETURN VALUE +CURLE_OK (zero) means that the option was set properly, non-zero means an +error occurred as \fI<curl/curl.h>\fP defines. See the \fIlibcurl-errors(3)\fP +man page for the full list with descriptions. + +If you try to set an option that libcurl doesn't know about, perhaps because +the library is too old to support it or the option was removed in a recent +version, this function will return \fICURLE_FAILED_INIT\fP. +.SH "SEE ALSO" +.BR curl_easy_init "(3), " curl_easy_cleanup "(3), " curl_easy_reset "(3)" diff --git a/docs/libcurl/curl_easy_strerror.3 b/docs/libcurl/curl_easy_strerror.3 new file mode 100644 index 000000000..a26c9c5db --- /dev/null +++ b/docs/libcurl/curl_easy_strerror.3 @@ -0,0 +1,37 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2012, 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_strerror 3 "26 Apr 2004" "libcurl 7.12" "libcurl Manual" +.SH NAME +curl_easy_strerror - return string describing error code +.SH SYNOPSIS +#include <curl/curl.h> + +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)" diff --git a/docs/libcurl/curl_easy_unescape.3 b/docs/libcurl/curl_easy_unescape.3 new file mode 100644 index 000000000..9b03fd0f9 --- /dev/null +++ b/docs/libcurl/curl_easy_unescape.3 @@ -0,0 +1,51 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * 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_unescape 3 "7 April 2006" "libcurl 7.15.4" "libcurl Manual" +.SH NAME +curl_easy_unescape - URL decodes the given string +.SH SYNOPSIS +.B #include <curl/curl.h> +.sp +.BI "char *curl_easy_unescape( CURL *" curl ", char *" url ", int "inlength +.BI ", int *" outlength " );" +.ad +.SH DESCRIPTION +This function converts the given URL encoded input string to a "plain string" +and returns that in an allocated memory area. All input characters that are +URL encoded (%XX where XX is a two-digit hexadecimal number) are converted to +their binary versions. + +If the \fBlength\fP argument is set to 0 (zero), \fIcurl_easy_unescape(3)\fP +will use strlen() on the input \fIurl\fP string to find out the size. + +If \fBoutlength\fP is non-NULL, the function will write the length of the +returned string in the integer it points to. This allows an escaped string +containing %00 to still get used properly after unescaping. + +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_unescape(3)\fP function. +.SH RETURN VALUE +A pointer to a zero terminated string or NULL if it failed. +.SH "SEE ALSO" +.I curl_easy_escape(3), curl_free(3), RFC 2396 diff --git a/docs/libcurl/curl_escape.3 b/docs/libcurl/curl_escape.3 new file mode 100644 index 000000000..75fd51f2d --- /dev/null +++ b/docs/libcurl/curl_escape.3 @@ -0,0 +1,48 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_escape 3 "6 March 2002" "libcurl 7.9" "libcurl Manual" +.SH NAME +curl_escape - URL encodes the given string +.SH SYNOPSIS +.B #include <curl/curl.h> +.sp +.BI "char *curl_escape( char *" url ", int "length " );" +.ad +.SH DESCRIPTION +Obsolete function. Use \fIcurl_easy_escape(3)\fP instead! + +This function will convert the given input string to an URL encoded string and +return that as a new allocated string. All input characters that are not a-z, +A-Z or 0-9 will be converted to their "URL escaped" version (%NN where NN is a +two-digit hexadecimal number). + +If the 'length' argument is set to 0, curl_escape() will use strlen() on the +input 'url' string to find out the size. + +You must curl_free() the returned string when you're done with it. +.SH AVAILABILITY +Since 7.15.4, \fIcurl_easy_escape(3)\fP should be used. This function will +be removed in a future release. +.SH RETURN VALUE +A pointer to a zero terminated string or NULL if it failed. +.SH "SEE ALSO" +.BR curl_unescape "(3), " curl_free "(3), " RFC 2396 diff --git a/docs/libcurl/curl_formadd.3 b/docs/libcurl/curl_formadd.3 new file mode 100644 index 000000000..ce4df1e4b --- /dev/null +++ b/docs/libcurl/curl_formadd.3 @@ -0,0 +1,235 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_formadd 3 "24 June 2002" "libcurl 7.9.8" "libcurl Manual" +.SH NAME +curl_formadd - add a section to a multipart/formdata HTTP POST +.SH SYNOPSIS +.B #include <curl/curl.h> +.sp +.BI "CURLFORMcode curl_formadd(struct curl_httppost ** " firstitem, +.BI "struct curl_httppost ** " lastitem, " ...);" +.ad +.SH DESCRIPTION +curl_formadd() is used to append sections when building a multipart/formdata +HTTP POST (sometimes referred to as RFC2388-style posts). Append one section +at a time until you've added all the sections you want included and then you +pass the \fIfirstitem\fP pointer as parameter to \fBCURLOPT_HTTPPOST\fP. +\fIlastitem\fP is set after each \fIcurl_formadd(3)\fP call and on repeated +invokes it should be left as set to allow repeated invokes to find the end of +the list faster. + +After the \fIlastitem\fP pointer follow the real arguments. + +The pointers \fIfirstitem\fP and \fIlastitem\fP should both be pointing to +NULL in the first call to this function. All list-data will be allocated by +the function itself. You must call \fIcurl_formfree(3)\fP on the +\fIfirstitem\P after the form post has been done to free the resources. + +Using POST with HTTP 1.1 implies the use of a "Expect: 100-continue" header. +You can disable this header with \fICURLOPT_HTTPHEADER\fP as usual. + +First, there are some basics you need to understand about multipart/formdata +posts. Each part consists of at least a NAME and a CONTENTS part. If the part +is made for file upload, there are also a stored CONTENT-TYPE and a FILENAME. +Below, we'll discuss what options you use to set these properties in the +parts you want to add to your post. + +The options listed first are for making normal parts. The options from +\fICURLFORM_FILE\fP through \fICURLFORM_BUFFERLENGTH\fP are for file upload +parts. +.SH OPTIONS +.IP CURLFORM_COPYNAME +followed by a string which provides the \fIname\fP of this part. libcurl +copies the string so your application doesn't need to keep it around after +this function call. If the name isn't NUL-terminated, or if you'd +like it to contain zero bytes, you must set its length with +\fBCURLFORM_NAMELENGTH\fP. The copied data will be freed by +\fIcurl_formfree(3)\fP. +.IP CURLFORM_PTRNAME +followed by a string which provides the \fIname\fP of this part. libcurl +will use the pointer and refer to the data in your application, so you +must make sure it remains until curl no longer needs it. If the name +isn't NUL-terminated, or if you'd like it to contain zero +bytes, you must set its length with \fBCURLFORM_NAMELENGTH\fP. +.IP CURLFORM_COPYCONTENTS +followed by a pointer to the contents of this part, the actual data +to send away. libcurl copies the provided data, so your application doesn't +need to keep it around after this function call. If the data isn't null +terminated, or if you'd like it to contain zero bytes, you must +set the length of the name with \fBCURLFORM_CONTENTSLENGTH\fP. The copied +data will be freed by \fIcurl_formfree(3)\fP. +.IP CURLFORM_PTRCONTENTS +followed by a pointer to the contents of this part, the actual data +to send away. libcurl will use the pointer and refer to the data in your +application, so you must make sure it remains until curl no longer needs it. +If the data isn't NUL-terminated, or if you'd like it to contain zero bytes, +you must set its length with \fBCURLFORM_CONTENTSLENGTH\fP. +.IP CURLFORM_CONTENTSLENGTH +followed by a long giving the length of the contents. Note that for +\fICURLFORM_STREAM\fP contents, this option is mandatory. +.IP CURLFORM_FILECONTENT +followed by a filename, causes that file to be read and its contents used +as data in this part. This part does \fInot\fP automatically become a file +upload part simply because its data was read from a file. +.IP CURLFORM_FILE +followed by a filename, makes this part a file upload part. It sets the +\fIfilename\fP field to the basename of the provided filename, it reads the +contents of the file and passes them as data and sets the content-type if the +given file match one of the internally known file extensions. For +\fBCURLFORM_FILE\fP the user may send one or more files in one part by +providing multiple \fBCURLFORM_FILE\fP arguments each followed by the filename +(and each \fICURLFORM_FILE\fP is allowed to have a +\fICURLFORM_CONTENTTYPE\fP). +.IP CURLFORM_CONTENTTYPE +is used in combination with \fICURLFORM_FILE\fP. Followed by a pointer to a +string which provides the content-type for this part, possibly instead of an +internally chosen one. +.IP CURLFORM_FILENAME +is used in combination with \fICURLFORM_FILE\fP. Followed by a pointer to a +string, it tells libcurl to use the given string as the \fIfilename\fP in the +file upload part instead of the actual file name. +.IP CURLFORM_BUFFER +is used for custom file upload parts without use of \fICURLFORM_FILE\fP. It +tells libcurl that the file contents are already present in a buffer. The +parameter is a string which provides the \fIfilename\fP field in the content +header. +.IP CURLFORM_BUFFERPTR +is used in combination with \fICURLFORM_BUFFER\fP. The parameter is a pointer +to the buffer to be uploaded. This buffer must not be freed until after +\fIcurl_easy_cleanup(3)\fP is called. You must also use +\fICURLFORM_BUFFERLENGTH\fP to set the number of bytes in the buffer. +.IP CURLFORM_BUFFERLENGTH +is used in combination with \fICURLFORM_BUFFER\fP. The parameter is a +long which gives the length of the buffer. +.IP CURLFORM_STREAM +Tells libcurl to use the \fICURLOPT_READFUNCTION\fP callback to get data. The +parameter you pass to \fICURLFORM_STREAM\fP is the pointer passed on to the +read callback's fourth argument. If you want the part to look like a file +upload one, set the \fICURLFORM_FILENAME\fP parameter as well. Note that when +using \fICURLFORM_STREAM\fP, \fICURLFORM_CONTENTSLENGTH\fP must also be set +with the total expected length of the part. (Option added in libcurl 7.18.2) +.IP CURLFORM_ARRAY +Another possibility to send options to curl_formadd() is the +\fBCURLFORM_ARRAY\fP option, that passes a struct curl_forms array pointer as +its value. Each curl_forms structure element has a CURLformoption and a char +pointer. The final element in the array must be a CURLFORM_END. All available +options can be used in an array, except the CURLFORM_ARRAY option itself! The +last argument in such an array must always be \fBCURLFORM_END\fP. +.IP CURLFORM_CONTENTHEADER +specifies extra headers for the form POST section. This takes a curl_slist +prepared in the usual way using \fBcurl_slist_append\fP and appends the list +of headers to those libcurl automatically generates. The list must exist while +the POST occurs, if you free it before the post completes you may experience +problems. + +When you've passed the HttpPost pointer to \fIcurl_easy_setopt(3)\fP (using +the \fICURLOPT_HTTPPOST\fP option), you must not free the list until after +you've called \fIcurl_easy_cleanup(3)\fP for the curl handle. + +See example below. +.SH RETURN VALUE +0 means everything was ok, non-zero means an error occurred corresponding +to a CURL_FORMADD_* constant defined in +.I <curl/curl.h> +.SH EXAMPLE +.nf + + struct curl_httppost* post = NULL; + struct curl_httppost* last = NULL; + char namebuffer[] = "name buffer"; + long namelength = strlen(namebuffer); + char buffer[] = "test buffer"; + char htmlbuffer[] = "<HTML>test buffer</HTML>"; + long htmlbufferlength = strlen(htmlbuffer); + struct curl_forms forms[3]; + char file1[] = "my-face.jpg"; + char file2[] = "your-face.jpg"; + /* add null character into htmlbuffer, to demonstrate that + transfers of buffers containing null characters actually work + */ + htmlbuffer[8] = '\\0'; + + /* Add simple name/content section */ + curl_formadd(&post, &last, CURLFORM_COPYNAME, "name", + CURLFORM_COPYCONTENTS, "content", CURLFORM_END); + + /* Add simple name/content/contenttype section */ + curl_formadd(&post, &last, CURLFORM_COPYNAME, "htmlcode", + CURLFORM_COPYCONTENTS, "<HTML></HTML>", + CURLFORM_CONTENTTYPE, "text/html", CURLFORM_END); + + /* Add name/ptrcontent section */ + curl_formadd(&post, &last, CURLFORM_COPYNAME, "name_for_ptrcontent", + CURLFORM_PTRCONTENTS, buffer, CURLFORM_END); + + /* Add ptrname/ptrcontent section */ + curl_formadd(&post, &last, CURLFORM_PTRNAME, namebuffer, + CURLFORM_PTRCONTENTS, buffer, CURLFORM_NAMELENGTH, + namelength, CURLFORM_END); + + /* Add name/ptrcontent/contenttype section */ + curl_formadd(&post, &last, CURLFORM_COPYNAME, "html_code_with_hole", + CURLFORM_PTRCONTENTS, htmlbuffer, + CURLFORM_CONTENTSLENGTH, htmlbufferlength, + CURLFORM_CONTENTTYPE, "text/html", CURLFORM_END); + + /* Add simple file section */ + curl_formadd(&post, &last, CURLFORM_COPYNAME, "picture", + CURLFORM_FILE, "my-face.jpg", CURLFORM_END); + + /* Add file/contenttype section */ + curl_formadd(&post, &last, CURLFORM_COPYNAME, "picture", + CURLFORM_FILE, "my-face.jpg", + CURLFORM_CONTENTTYPE, "image/jpeg", CURLFORM_END); + + /* Add two file section */ + curl_formadd(&post, &last, CURLFORM_COPYNAME, "pictures", + CURLFORM_FILE, "my-face.jpg", + CURLFORM_FILE, "your-face.jpg", CURLFORM_END); + + /* Add two file section using CURLFORM_ARRAY */ + forms[0].option = CURLFORM_FILE; + forms[0].value = file1; + forms[1].option = CURLFORM_FILE; + forms[1].value = file2; + forms[2].option = CURLFORM_END; + + /* Add a buffer to upload */ + curl_formadd(&post, &last, + CURLFORM_COPYNAME, "name", + CURLFORM_BUFFER, "data", + CURLFORM_BUFFERPTR, record, + CURLFORM_BUFFERLENGTH, record_length, + CURLFORM_END); + + /* no option needed for the end marker */ + curl_formadd(&post, &last, CURLFORM_COPYNAME, "pictures", + CURLFORM_ARRAY, forms, CURLFORM_END); + /* Add the content of a file as a normal post text value */ + curl_formadd(&post, &last, CURLFORM_COPYNAME, "filecontent", + CURLFORM_FILECONTENT, ".bashrc", CURLFORM_END); + /* Set the form info */ + curl_easy_setopt(curl, CURLOPT_HTTPPOST, post); + +.SH "SEE ALSO" +.BR curl_easy_setopt "(3), " +.BR curl_formfree "(3)" diff --git a/docs/libcurl/curl_formfree.3 b/docs/libcurl/curl_formfree.3 new file mode 100644 index 000000000..7438a1640 --- /dev/null +++ b/docs/libcurl/curl_formfree.3 @@ -0,0 +1,44 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_formfree 3 "6 April 2001" "libcurl 7.7.1" "libcurl Manual" +.SH NAME +curl_formfree - free a previously build multipart/formdata HTTP POST chain +.SH SYNOPSIS +.B #include <curl/curl.h> +.sp +.BI "void curl_formfree(struct curl_httppost *" form); +.ad +.SH DESCRIPTION +curl_formfree() is used to clean up data previously built/appended with +\fIcurl_formadd(3)\fP. This must be called when the data has been used, which +typically means after \fIcurl_easy_perform(3)\fP has been called. + +The pointer to free is the same pointer you passed to the +\fBCURLOPT_HTTPPOST\fP option, which is the \fIfirstitem\fP pointer from the +\fIcurl_formadd(3)\fP invoke(s). + +\fBform\fP is the pointer as returned from a previous call to +\fIcurl_formadd(3)\fP and may be NULL. +.SH RETURN VALUE +None +.SH "SEE ALSO" +.BR curl_formadd "(3) " diff --git a/docs/libcurl/curl_formget.3 b/docs/libcurl/curl_formget.3 new file mode 100644 index 000000000..b52622136 --- /dev/null +++ b/docs/libcurl/curl_formget.3 @@ -0,0 +1,70 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_formget 3 "20 June 2006" "libcurl 7.15.5" "libcurl Manual" +.SH NAME +curl_formget - serialize a previously built multipart/formdata HTTP POST chain +.SH SYNOPSIS +.nf +.B #include <curl/curl.h> + +void curl_formget(struct curl_httppost * form, void *userp, + curl_formget_callback append ); +.SH DESCRIPTION +curl_formget() is used to serialize data previously built/appended with +\fIcurl_formadd(3)\fP. Accepts a void pointer as second argument named +\fIuserp\fP which will be passed as the first argument to the +curl_formget_callback function. + +.BI "typedef size_t (*curl_formget_callback)(void *" userp, " const char *" buf, +.BI " size_t " len ");" + +The curl_formget_callback will be executed for each part of the HTTP POST +chain. The character buffer passed to the callback must not be freed. The +callback should return the buffer length passed to it on success. + +If the \fBCURLFORM_STREAM\fP option is used in the formpost, it will prevent +\fIcurl_formget(3)\fP from working until you've performed the actual HTTP +request as only then will libcurl get the actual read callback to use! +.SH RETURN VALUE +0 means everything was ok, non-zero means an error occurred +.SH EXAMPLE +.nf + + size_t print_httppost_callback(void *arg, const char *buf, size_t len) + { + fwrite(buf, len, 1, stdout); + (*(size_t *) arg) += len; + return len; + } + + size_t print_httppost(struct curl_httppost *post) + { + size_t total_size = 0; + if(curl_formget(post, &total_size, print_httppost_callback)) { + return (size_t) -1; + } + return total_size; + } +.SH AVAILABILITY +This function was added in libcurl 7.15.5 +.SH "SEE ALSO" +.BR curl_formadd "(3) " diff --git a/docs/libcurl/curl_free.3 b/docs/libcurl/curl_free.3 new file mode 100644 index 000000000..08ec9b6b3 --- /dev/null +++ b/docs/libcurl/curl_free.3 @@ -0,0 +1,35 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_free 3 "12 Aug 2003" "libcurl 7.10" "libcurl Manual" +.SH NAME +curl_free - reclaim memory that has been obtained through a libcurl call +.SH SYNOPSIS +.B #include <curl/curl.h> +.sp +.BI "void curl_free( char *" ptr " );" +.ad +.SH DESCRIPTION +curl_free reclaims memory that has been obtained through a libcurl call. Use +curl_free() instead of free() to avoid anomalies that can result from +differences in memory management between your application and libcurl. +.SH "SEE ALSO" +.I curl_unescape(3) diff --git a/docs/libcurl/curl_getdate.3 b/docs/libcurl/curl_getdate.3 new file mode 100644 index 000000000..65eed9c57 --- /dev/null +++ b/docs/libcurl/curl_getdate.3 @@ -0,0 +1,117 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_getdate 3 "12 Aug 2005" "libcurl 7.0" "libcurl Manual" +.SH NAME +curl_getdate - Convert a date string to number of seconds since January 1, +1970 +.SH SYNOPSIS +.B #include <curl/curl.h> +.sp +.BI "time_t curl_getdate(char *" datestring ", time_t *"now " );" +.ad +.SH DESCRIPTION +This function returns the number of seconds since January 1st 1970 in the UTC +time zone, for the date and time that the \fIdatestring\fP parameter +specifies. The \fInow\fP parameter is not used, pass a NULL there. + +\fBNOTE:\fP This function was rewritten for the 7.12.2 release and this +documentation covers the functionality of the new one. The new one is not +feature-complete with the old one, but most of the formats supported by the +new one was supported by the old too. +.SH PARSING DATES AND TIMES +A "date" is a string containing several items separated by whitespace. The +order of the items is immaterial. A date string may contain many flavors of +items: +.TP 0.8i +.B calendar date items +Can be specified several ways. Month names can only be three-letter english +abbreviations, numbers can be zero-prefixed and the year may use 2 or 4 digits. +Examples: 06 Nov 1994, 06-Nov-94 and Nov-94 6. +.TP +.B time of the day items +This string specifies the time on a given day. You must specify it with 6 +digits with two colons: HH:MM:SS. To not include the time in a date string, +will make the function assume 00:00:00. Example: 18:19:21. +.TP +.B time zone items +Specifies international time zone. There are a few acronyms supported, but in +general you should instead use the specific relative time compared to +UTC. Supported formats include: -1200, MST, +0100. +.TP +.B day of the week items +Specifies a day of the week. Days of the week may be spelled out in full +(using english): `Sunday', `Monday', etc or they may be abbreviated to their +first three letters. This is usually not info that adds anything. +.TP +.B pure numbers +If a decimal number of the form YYYYMMDD appears, then YYYY is read as the +year, MM as the month number and DD as the day of the month, for the specified +calendar date. +.PP +.SH EXAMPLES +.nf +Sun, 06 Nov 1994 08:49:37 GMT +Sunday, 06-Nov-94 08:49:37 GMT +Sun Nov 6 08:49:37 1994 +06 Nov 1994 08:49:37 GMT +06-Nov-94 08:49:37 GMT +Nov 6 08:49:37 1994 +06 Nov 1994 08:49:37 +06-Nov-94 08:49:37 +1994 Nov 6 08:49:37 +GMT 08:49:37 06-Nov-94 Sunday +94 6 Nov 08:49:37 +1994 Nov 6 +06-Nov-94 +Sun Nov 6 94 +1994.Nov.6 +Sun/Nov/6/94/GMT +Sun, 06 Nov 1994 08:49:37 CET +06 Nov 1994 08:49:37 EST +Sun, 12 Sep 2004 15:05:58 -0700 +Sat, 11 Sep 2004 21:32:11 +0200 +20040912 15:05:58 -0700 +20040911 +0200 +.fi +.SH STANDARDS +This parser was written to handle date formats specified in RFC 822 (including +the update in RFC 1123) using time zone name or time zone delta and RFC 850 +(obsoleted by RFC 1036) and ANSI C's asctime() format. These formats are the +only ones RFC2616 says HTTP applications may use. +.SH RETURN VALUE +This function returns -1 when it fails to parse the date string. Otherwise it +returns the number of seconds as described. + +If the year is larger than 2037 on systems with 32 bit time_t, this function +will return 0x7fffffff (since that is the largest possible signed 32 bit +number). + +Having a 64 bit time_t is not a guarantee that dates beyond 03:14:07 UTC, +January 19, 2038 will work fine. On systems with a 64 bit time_t but with a +crippled mktime(), \fIcurl_getdate\fP will return -1 in this case. +.SH REWRITE +The former version of this function was built with yacc and was not only very +large, it was also never quite understood and it wasn't possible to build with +non-GNU tools since only GNU Bison could make it thread-safe! + +The rewrite was done for 7.12.2. The new one is much smaller and uses simpler +code. diff --git a/docs/libcurl/curl_getenv.3 b/docs/libcurl/curl_getenv.3 new file mode 100644 index 000000000..33554476a --- /dev/null +++ b/docs/libcurl/curl_getenv.3 @@ -0,0 +1,49 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_getenv 3 "30 April 2004" "libcurl 7.12" "libcurl Manual" +.SH NAME +curl_getenv - return value for environment name +.SH SYNOPSIS +.B #include <curl/curl.h> +.sp +.BI "char *curl_getenv(const char *" name ");" +.ad +.SH DESCRIPTION +curl_getenv() is a portable wrapper for the getenv() function, meant to +emulate its behaviour and provide an identical interface for all operating +systems libcurl builds on (including win32). +.SH AVAILABILITY +This function will be removed from the public libcurl API in a near future. It +will instead be made "available" by source code access only, and then as +curlx_getenv(). +.SH RETURN VALUE +If successful, curl_getenv() returns a pointer to the value of the specified +environment. The memory it refers to is malloc()ed so the application must +free() this when the data is no longer needed. When \fIcurl_getenv(3)\fP fails +to find the specified name, it returns a null pointer. +.SH NOTE +Under unix operating systems, there isn't any point in returning an allocated +memory, although other systems won't work properly if this isn't done. The +unix implementation thus has to suffer slightly from the drawbacks of other +systems. +.SH "SEE ALSO" +.BR getenv "(3C), " diff --git a/docs/libcurl/curl_global_cleanup.3 b/docs/libcurl/curl_global_cleanup.3 new file mode 100644 index 000000000..83a54e467 --- /dev/null +++ b/docs/libcurl/curl_global_cleanup.3 @@ -0,0 +1,49 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_global_cleanup 3 "17 Feb 2006" "libcurl 7.8" "libcurl Manual" +.SH NAME +curl_global_cleanup - global libcurl cleanup +.SH SYNOPSIS +.B #include <curl/curl.h> +.sp +.BI "void curl_global_cleanup(void);" +.ad +.SH DESCRIPTION +This function releases resources acquired by \fBcurl_global_init(3)\fP. + +You should call \fIcurl_global_cleanup(3)\fP once for each call you make to +\fIcurl_global_init(3)\fP, after you are done using libcurl. + +\fBThis function is not thread safe.\fP You must not call it when any other +thread in the program (i.e. a thread sharing the same memory) is running. +This doesn't just mean no other thread that is using libcurl. Because +\fBcurl_global_cleanup(3)\fP calls functions of other libraries that are +similarly thread unsafe, it could conflict with any other thread that uses +these other libraries. + +See the description in \fBlibcurl(3)\fP of global environment requirements for +details of how to use this function. + +.SH "SEE ALSO" +.BR curl_global_init "(3), " +.BR libcurl "(3), " + diff --git a/docs/libcurl/curl_global_init.3 b/docs/libcurl/curl_global_init.3 new file mode 100644 index 000000000..d91e1bdb7 --- /dev/null +++ b/docs/libcurl/curl_global_init.3 @@ -0,0 +1,80 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2012, 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_global_init 3 "11 May 2004" "libcurl 7.12" "libcurl Manual" +.SH NAME +curl_global_init - Global libcurl initialisation +.SH SYNOPSIS +.B #include <curl/curl.h> +.sp +.BI "CURLcode curl_global_init(long " flags ");" +.ad +.SH DESCRIPTION +This function sets up the program environment that libcurl needs. Think of it +as an extension of the library loader. + +This function must be called at least once within a program (a program is all +the code that shares a memory space) before the program calls any other +function in libcurl. The environment it sets up is constant for the life of +the program and is the same for every program, so multiple calls have the same +effect as one call. + +The flags option is a bit pattern that tells libcurl exactly what features to +init, as described below. Set the desired bits by ORing the values together. +In normal operation, you must specify CURL_GLOBAL_ALL. Don't use any other +value unless you are familiar with it and mean to control internal operations of +libcurl. + +\fBThis function is not thread safe.\fP You must not call it when any other +thread in the program (i.e. a thread sharing the same memory) is running. +This doesn't just mean no other thread that is using libcurl. Because +\fIcurl_global_init()\fP calls functions of other libraries that are similarly +thread unsafe, it could conflict with any other thread that uses these other +libraries. + +See the description in \fBlibcurl\fP(3) of global environment requirements for +details of how to use this function. + +.SH FLAGS +.TP 5 +.B CURL_GLOBAL_ALL +Initialize everything possible. This sets all known bits. +.TP +.B CURL_GLOBAL_SSL +Initialize SSL +.TP +.B CURL_GLOBAL_WIN32 +Initialize the Win32 socket libraries. +.TP +.B CURL_GLOBAL_NOTHING +Initialise nothing extra. This sets no bit. +.TP +.B CURL_GLOBAL_DEFAULT +A sensible default. It will init both SSL and Win32. Right now, this equals +the functionality of the \fBCURL_GLOBAL_ALL\fP mask. +.SH RETURN VALUE +If this function returns non-zero, something went wrong and you cannot use the +other curl functions. +.SH "SEE ALSO" +.BR curl_global_init_mem "(3), " +.BR curl_global_cleanup "(3), " +.BR curl_easy_init "(3) " +.BR libcurl "(3) " diff --git a/docs/libcurl/curl_global_init_mem.3 b/docs/libcurl/curl_global_init_mem.3 new file mode 100644 index 000000000..d13a17c6e --- /dev/null +++ b/docs/libcurl/curl_global_init_mem.3 @@ -0,0 +1,60 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_global_init_mem 3 "10 May 2004" "libcurl 7.12.0" "libcurl Manual" +.SH NAME +curl_global_init_mem - Global libcurl initialisation with memory callbacks +.SH SYNOPSIS +.B #include <curl/curl.h> +.nf +.B "CURLcode curl_global_init_mem(long " flags, +.B " curl_malloc_callback "m, +.B " curl_free_callback "f, +.B " curl_realloc_callback "r, +.B " curl_strdup_callback "s, +.B " curl_calloc_callback "c ");" +.SH DESCRIPTION +This function works exactly as \fIcurl_global_init(3)\fP with one addition: it +allows the application to set callbacks to replace the otherwise used internal +memory functions. + +This man page only adds documentation for the callbacks, see the +\fIcurl_global_init(3)\fP man page for all the rest. When you use this +function, all callback arguments must be set to valid function pointers. + +The prototypes for the given callbacks should match these: +.IP "void *malloc_callback(size_t size);" +To replace malloc() +.IP "void free_callback(void *ptr);" +To replace free() +.IP "void *realloc_callback(void *ptr, size_t size);" +To replace realloc() +.IP "char *strdup_callback(const char *str);" +To replace strdup() +.IP "void *calloc_callback(size_t nmemb, size_t size);" +To replace calloc() +.SH "CAUTION" +Manipulating these gives considerable powers to the application to severly +screw things up for libcurl. Take care! +.SH "SEE ALSO" +.BR curl_global_init "(3), " +.BR curl_global_cleanup "(3), " + diff --git a/docs/libcurl/curl_mprintf.3 b/docs/libcurl/curl_mprintf.3 new file mode 100644 index 000000000..cbf10e1ab --- /dev/null +++ b/docs/libcurl/curl_mprintf.3 @@ -0,0 +1,109 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_printf 3 "30 April 2004" "libcurl 7.12" "libcurl Manual" +.SH NAME +curl_maprintf, curl_mfprintf, curl_mprintf, curl_msnprintf, curl_msprintf +curl_mvaprintf, curl_mvfprintf, curl_mvprintf, curl_mvsnprintf, +curl_mvsprintf - formatted output conversion +.SH SYNOPSIS +.B #include <curl/mprintf.h> +.sp +.BI "int curl_mprintf(const char *" format ", ...);" +.br +.BI "int curl_mfprintf(FILE *" fd ", const char *" format ", ...);" +.br +.BI "int curl_msprintf(char *" buffer ", const char *" format ", ...);" +.br +.BI "int curl_msnprintf(char *" buffer ", size_t " maxlength ", const char *" format ", ...);" +.br +.BI "int curl_mvprintf(const char *" format ", va_list " args ");" +.br +.BI "int curl_mvfprintf(FILE *" fd ", const char *" format ", va_list " args ");" +.br +.BI "int curl_mvsprintf(char *" buffer ", const char *" format ", va_list " args ");" +.br +.BI "int curl_mvsnprintf(char *" buffer ", size_t " maxlength ", const char *" format ", va_list " args ");" +.br +.BI "char *curl_maprintf(const char *" format ", ...);" +.br +.BI "char *curl_mvaprintf(const char *" format ", va_list " args ");" +.SH DESCRIPTION +These are all functions that produce output according to a format string and +given arguments. These are mostly clones of the well-known C-style functions +and there will be no detailed explanation of all available formatting rules +and usage here. + +See this table for notable exceptions. +.RS +.TP +.B curl_mprintf() +Normal printf() clone. +.TP +.B curl_mfprintf() +Normal fprintf() clone. +.TP +.B curl_msprintf() +Normal sprintf() clone. +.TP +.B curl_msnprintf() +snprintf() clone. Many systems don't have this. It is just like \fBsprintf\fP +but with an extra argument after the buffer that specifies the length of the +target buffer. +.TP +.B curl_mvprintf() +Normal vprintf() clone. +.TP +.B curl_mvfprintf() +Normal vfprintf() clone. +.TP +.B curl_mvsprintf() +Normal vsprintf() clone. +.TP +.B curl_mvsnprintf() +vsnprintf() clone. Many systems don't have this. It is just like +\fBvsprintf\fP but with an extra argument after the buffer that specifies the +length of the target buffer. +.TP +.B curl_maprintf() +Like printf() but returns the output string as a malloc()ed string. The +returned string must be free()ed by the receiver. +.TP +.B curl_mvaprintf() +Like curl_maprintf() but takes a va_list pointer argument instead of a +variable amount of arguments. +.RE + +To easily use all these cloned functions instead of the normal ones, #define +_MPRINTF_REPLACE before you include the <curl/mprintf.h> file. Then all the +normal names like printf, fprintf, sprintf etc will use the curl-functions +instead. +.SH AVAILABILITY +These function will be removed from the public libcurl API in a near +future. They will instead be made "available" by source code access only, and +then as curlx_-prefixed functions. See lib/README.curlx for further details. +.SH RETURN VALUE +The \fBcurl_maprintf\fP and \fBcurl_mvaprintf\fP functions return a pointer to +a newly allocated string, or NULL if it failed. + +All other functions return the number of characters they actually outputted. +.SH "SEE ALSO" +.BR printf "(3), " sprintf "(3), " fprintf "(3), " vprintf "(3) " diff --git a/docs/libcurl/curl_multi_add_handle.3 b/docs/libcurl/curl_multi_add_handle.3 new file mode 100644 index 000000000..bae2c90fe --- /dev/null +++ b/docs/libcurl/curl_multi_add_handle.3 @@ -0,0 +1,57 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_multi_add_handle 3 "4 March 2002" "libcurl 7.9.5" "libcurl Manual" +.SH NAME +curl_multi_add_handle - add an easy handle to a multi session +.SH SYNOPSIS +#include <curl/curl.h> + +CURLMcode curl_multi_add_handle(CURLM *multi_handle, CURL *easy_handle); +.ad +.SH DESCRIPTION +Adds a standard easy handle to the multi stack. This function call will make +this \fImulti_handle\fP control the specified \fIeasy_handle\fP. +Furthermore, libcurl now initiates the connection associated with the +specified \fIeasy_handle\fP. + +When an easy handle has been added to a multi stack, you can not and you must +not use \fIcurl_easy_perform(3)\fP on that handle! + +If the easy handle is not set to use a shared (CURLOPT_SHARE) or global DNS +cache (CURLOPT_DNS_USE_GLOBAL_CACHE), it will be made to use the DNS cache +that is shared between all easy handles within the multi handle when +\fIcurl_multi_add_handle(3)\fP is called. + +The easy handle will remain added until you remove it again with +\fIcurl_multi_remove_handle(3)\fP. You should remove the easy handle from the +multi stack before you terminate first the easy handle and then the multi +handle: + +1 - \fIcurl_multi_remove_handle(3)\fP + +2 - \fIcurl_easy_cleanup(3)\fP + +3 - \fIcurl_multi_cleanup(3)\fP +.SH RETURN VALUE +CURLMcode type, general libcurl multi interface error code. +.SH "SEE ALSO" +.BR curl_multi_cleanup "(3)," curl_multi_init "(3)" diff --git a/docs/libcurl/curl_multi_assign.3 b/docs/libcurl/curl_multi_assign.3 new file mode 100644 index 000000000..0b580fe27 --- /dev/null +++ b/docs/libcurl/curl_multi_assign.3 @@ -0,0 +1,63 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_multi_assign 3 "9 Jul 2006" "libcurl 7.16.0" "libcurl Manual" +.SH NAME +curl_multi_assign \- set data to association with an internal socket +.SH SYNOPSIS +#include <curl/curl.h> + +CURLMcode curl_multi_assign(CURLM *multi_handle, curl_socket_t sockfd, + void *sockptr); +.SH DESCRIPTION +This function assigns an association in the multi handle between the given +socket and a private pointer of the application. This is (only) useful for +\fIcurl_multi_socket(3)\fP uses. + +When set, the \fIsockptr\fP pointer will be passed to all future socket +callbacks for the specific \fIsockfd\fP socket. + +If the given \fIsockfd\fP isn't already in use by libcurl, this function will +return an error. + +libcurl only keeps one single pointer associated with a socket, so calling +this function several times for the same socket will make the last set pointer +get used. + +The idea here being that this association (socket to private pointer) is +something that just about every application that uses this API will need and +then libcurl can just as well do it since it already has an internal hash +table lookup for this. +.SH "RETURN VALUE" +The standard CURLMcode for multi interface error codes. +.SH "TYPICAL USAGE" +In a typical application you allocate a struct or at least use some kind of +semi-dynamic data for each socket that we must wait for action on when using +the \fIcurl_multi_socket(3)\fP approach. + +When our socket-callback gets called by libcurl and we get to know about yet +another socket to wait for, we can use \fIcurl_multi_assign(3)\fP to point out +the particular data so that when we get updates about this same socket again, +we don't have to find the struct associated with this socket by ourselves. +.SH AVAILABILITY +This function was added in libcurl 7.15.5, although not deemed stable yet. +.SH "SEE ALSO" +.BR curl_multi_setopt "(3), " curl_multi_socket "(3) " diff --git a/docs/libcurl/curl_multi_cleanup.3 b/docs/libcurl/curl_multi_cleanup.3 new file mode 100644 index 000000000..e83c9f01b --- /dev/null +++ b/docs/libcurl/curl_multi_cleanup.3 @@ -0,0 +1,46 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_multi_cleanup 3 "1 March 2002" "libcurl 7.9.5" "libcurl Manual" +.SH NAME +curl_multi_cleanup - close down a multi session +.SH SYNOPSIS +.B #include <curl/curl.h> +.sp +.BI "CURLMcode curl_multi_cleanup( CURLM *multi_handle );" +.ad +.SH DESCRIPTION +Cleans up and removes a whole multi stack. It does not free or touch any +individual easy handles in any way - they still need to be closed +individually, using the usual \fIcurl_easy_cleanup(3)\fP way. The order of +cleaning up should be: + +1 - \fIcurl_multi_remove_handle(3)\fP before any easy handles are cleaned up + +2 - \fIcurl_easy_cleanup(3)\fP can now be called independently since the easy +handle is no longer connected to the multi handle + +3 - \fIcurl_multi_cleanup(3)\fP should be called when all easy handles are +removed +.SH RETURN VALUE +CURLMcode type, general libcurl multi interface error code. +.SH "SEE ALSO" +.BR curl_multi_init "(3)," curl_easy_cleanup "(3)," curl_easy_init "(3)" diff --git a/docs/libcurl/curl_multi_fdset.3 b/docs/libcurl/curl_multi_fdset.3 new file mode 100644 index 000000000..3dbdc4504 --- /dev/null +++ b/docs/libcurl/curl_multi_fdset.3 @@ -0,0 +1,70 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_multi_fdset 3 "2 Jan 2006" "libcurl 7.16.0" "libcurl Manual" +.SH NAME +curl_multi_fdset - extracts file descriptor information from a multi handle +.SH SYNOPSIS +.nf +#include <curl/curl.h> + +CURLMcode curl_multi_fdset(CURLM *multi_handle, + fd_set *read_fd_set, + fd_set *write_fd_set, + fd_set *exc_fd_set, + int *max_fd); +.ad +.SH DESCRIPTION +This function extracts file descriptor information from a given multi_handle. +libcurl returns its fd_set sets. The application can use these to select() on, +but be sure to FD_ZERO them before calling this function as +\fIcurl_multi_fdset(3)\fP only adds its own descriptors, it doesn't zero or +otherwise remove any others. The \fIcurl_multi_perform(3)\fP function should be +called as soon as one of them is ready to be read from or written to. + +If no file descriptors are set by libcurl, \fImax_fd\fP will contain -1 when +this function returns. Otherwise it will contain the higher descriptor number +libcurl set. When libcurl returns -1 in \fImax_fd\fP, it is because libcurl +currently does something that isn't possible for your application to monitor +with a socket and unfortunately you can then not know exactly when the current +action is completed using select(). When max_fd returns with -1, you need to +wait a while and then proceed and call \fIcurl_multi_perform\fP anyway. How +long to wait? I would suggest 100 milliseconds at least, but you may want to +test it out in your own particular conditions to find a suitable value. + +When doing select(), you should use \fBcurl_multi_timeout\fP to figure out how +long to wait for action. Call \fIcurl_multi_perform\fP even if no activity has +been seen on the fd_sets after the timeout expires as otherwise internal +retries and timeouts may not work as you'd think and want. + +If one of the sockets used by libcurl happens to be larger than what can be +set in an fd_set, which on POSIX systems means that the file descriptor is +larger than FD_SETSIZE, then libcurl will try to not set it. Setting a too +large file descriptor in an fd_set implies an out of bounds write which can +cause crashes, or worse. The effect of NOT storing it will possibly save you +from the crash, but will make your program NOT wait for sockets it should wait +for... +.SH RETURN VALUE +CURLMcode type, general libcurl multi interface error code. See +\fIlibcurl-errors(3)\fP +.SH "SEE ALSO" +.BR curl_multi_cleanup "(3), " curl_multi_init "(3), " +.BR curl_multi_timeout "(3), " curl_multi_perform "(3) " diff --git a/docs/libcurl/curl_multi_info_read.3 b/docs/libcurl/curl_multi_info_read.3 new file mode 100644 index 000000000..875176486 --- /dev/null +++ b/docs/libcurl/curl_multi_info_read.3 @@ -0,0 +1,76 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_multi_info_read 3 "18 Dec 2004" "libcurl 7.10.3" "libcurl Manual" +.SH NAME +curl_multi_info_read - read multi stack informationals +.SH SYNOPSIS +#include <curl/curl.h> + +CURLMsg *curl_multi_info_read( CURLM *multi_handle, + int *msgs_in_queue); +.ad +.SH DESCRIPTION +Ask the multi handle if there are any messages/informationals from the +individual transfers. Messages may include informationals such as an error +code from the transfer or just the fact that a transfer is completed. More +details on these should be written down as well. + +Repeated calls to this function will return a new struct each time, until a +NULL is returned as a signal that there is no more to get at this point. The +integer pointed to with \fImsgs_in_queue\fP will contain the number of +remaining messages after this function was called. + +When you fetch a message using this function, it is removed from the internal +queue so calling this function again will not return the same message +again. It will instead return new messages at each new invoke until the queue +is emptied. + +\fBWARNING:\fP The data the returned pointer points to will not survive +calling \fIcurl_multi_cleanup(3)\fP, \fIcurl_multi_remove_handle(3)\fP or +\fIcurl_easy_cleanup(3)\fP. + +The 'CURLMsg' struct is very simple and only contains very basic information. +If more involved information is wanted, the particular "easy handle" in +present in that struct and can thus be used in subsequent regular +\fIcurl_easy_getinfo(3)\fP calls (or similar): + +.nf + struct CURLMsg { + CURLMSG msg; /* what this message means */ + CURL *easy_handle; /* the handle it concerns */ + union { + void *whatever; /* message-specific data */ + CURLcode result; /* return code for transfer */ + } data; + }; +.fi +When \fBmsg\fP is \fICURLMSG_DONE\fP, the message identifies a transfer that +is done, and then \fBresult\fP contains the return code for the easy handle +that just completed. + +At this point, there are no other \fBmsg\fP types defined. +.SH "RETURN VALUE" +A pointer to a filled-in struct, or NULL if it failed or ran out of +structs. It also writes the number of messages left in the queue (after this +read) in the integer the second argument points to. +.SH "SEE ALSO" +.BR curl_multi_cleanup "(3), " curl_multi_init "(3), " curl_multi_perform "(3)" diff --git a/docs/libcurl/curl_multi_init.3 b/docs/libcurl/curl_multi_init.3 new file mode 100644 index 000000000..ca9374e15 --- /dev/null +++ b/docs/libcurl/curl_multi_init.3 @@ -0,0 +1,40 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_multi_init 3 "1 March 2002" "libcurl 7.9.5" "libcurl Manual" +.SH NAME +curl_multi_init - create a multi handle +.SH SYNOPSIS +.B #include <curl/curl.h> +.sp +.BI "CURLM *curl_multi_init( );" +.ad +.SH DESCRIPTION +This function returns a CURLM handle to be used as input to all the other +multi-functions, sometimes referred to as a multi handle in some places in the +documentation. This init call MUST have a corresponding call to +\fIcurl_multi_cleanup(3)\fP when the operation is complete. +.SH RETURN VALUE +If this function returns NULL, something went wrong and you cannot use the +other curl functions. +.SH "SEE ALSO" +.BR curl_multi_cleanup "(3)," curl_global_init "(3)," curl_easy_init "(3)" + diff --git a/docs/libcurl/curl_multi_perform.3 b/docs/libcurl/curl_multi_perform.3 new file mode 100644 index 000000000..304197b1a --- /dev/null +++ b/docs/libcurl/curl_multi_perform.3 @@ -0,0 +1,78 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2012, 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_multi_perform 3 "1 March 2002" "libcurl 7.9.5" "libcurl Manual" +.SH NAME +curl_multi_perform - reads/writes available data from each easy handle +.SH SYNOPSIS +#include <curl/curl.h> + +CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles); +.ad +.SH DESCRIPTION +This function handles transfers on all the added handles that need attention +in an non-blocking fashion. + +When an application has found out there's data available for the multi_handle +or a timeout has elapsed, the application should call this function to +read/write whatever there is to read or write right now etc. +curl_multi_perform() returns as soon as the reads/writes are done. This +function does not require that there actually is any data available for +reading or that data can be written, it can be called just in case. It will +write the number of handles that still transfer data in the second argument's +integer-pointer. + +If the amount of \fIrunning_handles\fP is changed from the previous call (or +is less than the amount of easy handles you've added to the multi handle), you +know that there is one or more transfers less "running". You can then call +\fIcurl_multi_info_read(3)\fP to get information about each individual +completed transfer, and that returned info includes CURLcode and more. If an +added handle fails very quickly, it may never be counted as a running_handle. + +When \fIrunning_handles\fP is set to zero (0) on the return of this function, +there is no longer any transfers in progress. +.SH "RETURN VALUE" +CURLMcode type, general libcurl multi interface error code. + +Before version 7.20.0: If you receive \fICURLM_CALL_MULTI_PERFORM\fP, this +basically means that you should call \fIcurl_multi_perform\fP again, before +you select() on more actions. You don't have to do it immediately, but the +return code means that libcurl may have more data available to return or that +there may be more data to send off before it is "satisfied". Do note that +\fIcurl_multi_perform(3)\fP will return \fICURLM_CALL_MULTI_PERFORM\fP only +when it wants to be called again \fBimmediately\fP. When things are fine and +there is nothing immediate it wants done, it'll return \fICURLM_OK\fP and you +need to wait for \&"action" and then call this function again. + +This function only returns errors etc regarding the whole multi stack. +Problems still might have occurred on individual transfers even when this +function returns \fICURLM_OK\fP. Use \fIcurl_multi_info_read(3)\fP to figure +out how individual transfers did. +.SH "TYPICAL USAGE" +Most applications will use \fIcurl_multi_fdset(3)\fP to get the multi_handle's +file descriptors, and \fIcurl_multi_timeout(3)\fP to get a suitable timeout +period, then it'll wait for action on the file descriptors using +\fBselect(3)\fP. As soon as one or more file descriptor is ready, +\fIcurl_multi_perform(3)\fP gets called. +.SH "SEE ALSO" +.BR curl_multi_cleanup "(3), " curl_multi_init "(3), " +.BR curl_multi_fdset "(3), " curl_multi_info_read "(3), " +.BR libcurl-errors "(3)" diff --git a/docs/libcurl/curl_multi_remove_handle.3 b/docs/libcurl/curl_multi_remove_handle.3 new file mode 100644 index 000000000..ad6d2bac8 --- /dev/null +++ b/docs/libcurl/curl_multi_remove_handle.3 @@ -0,0 +1,43 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_multi_remove_handle 3 "6 March 2002" "libcurl 7.9.5" "libcurl Manual" +.SH NAME +curl_multi_remove_handle - remove an easy handle from a multi session +.SH SYNOPSIS +#include <curl/curl.h> + +CURLMcode curl_multi_remove_handle(CURLM *multi_handle, CURL *easy_handle); +.ad +.SH DESCRIPTION +Removes a given easy_handle from the multi_handle. This will make the +specified easy handle be removed from this multi handle's control. + +When the easy handle has been removed from a multi stack, it is again +perfectly legal to invoke \fIcurl_easy_perform()\fP on this easy handle. + +Removing an easy handle while being used, will effectively halt the transfer +in progress involving that easy handle. All other easy handles and transfers +will remain unaffected. +.SH RETURN VALUE +CURLMcode type, general libcurl multi interface error code. +.SH "SEE ALSO" +.BR curl_multi_cleanup "(3)," curl_multi_init "(3)" diff --git a/docs/libcurl/curl_multi_setopt.3 b/docs/libcurl/curl_multi_setopt.3 new file mode 100644 index 000000000..baaaaeac0 --- /dev/null +++ b/docs/libcurl/curl_multi_setopt.3 @@ -0,0 +1,103 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_multi_setopt 3 "10 Oct 2006" "libcurl 7.16.0" "libcurl Manual" +.SH NAME +curl_multi_setopt \- set options for a curl multi handle +.SH SYNOPSIS +#include <curl/curl.h> + +CURLMcode curl_multi_setopt(CURLM * multi_handle, CURLMoption option, param); +.SH DESCRIPTION +curl_multi_setopt() is used to tell a libcurl multi handle how to behave. By +using the appropriate options to \fIcurl_multi_setopt(3)\fP, you can change +libcurl's behaviour when using that multi handle. All options are set with +the \fIoption\fP followed by the parameter \fIparam\fP. That parameter can be +a \fBlong\fP, a \fBfunction pointer\fP, an \fBobject pointer\fP or a +\fBcurl_off_t\fP type, depending on what the specific option expects. Read +this manual carefully as bad input values may cause libcurl to behave badly! +You can only set one option in each function call. + +.SH OPTIONS +.IP CURLMOPT_SOCKETFUNCTION +Pass a pointer to a function matching the \fBcurl_socket_callback\fP +prototype. The \fIcurl_multi_socket_action(3)\fP function informs the +application about updates in the socket (file descriptor) status by doing +none, one, or multiple calls to the curl_socket_callback given in the +\fBparam\fP argument. They update the status with changes since the previous +time a \fIcurl_multi_socket(3)\fP function was called. If the given callback +pointer is NULL, no callback will be called. Set the callback's \fBuserp\fP +argument with \fICURLMOPT_SOCKETDATA\fP. See \fIcurl_multi_socket(3)\fP for +more callback details. +.IP CURLMOPT_SOCKETDATA +Pass a pointer to whatever you want passed to the \fBcurl_socket_callback\fP's +forth argument, the userp pointer. This is not used by libcurl but only +passed-thru as-is. Set the callback pointer with +\fICURLMOPT_SOCKETFUNCTION\fP. +.IP CURLMOPT_PIPELINING +Pass a long set to 1 to enable or 0 to disable. Enabling pipelining on a multi +handle will make it attempt to perform HTTP Pipelining as far as possible for +transfers using this handle. This means that if you add a second request that +can use an already existing connection, the second request will be \&"piped" +on the same connection rather than being executed in parallel. (Added in +7.16.0) +.IP CURLMOPT_TIMERFUNCTION +Pass a pointer to a function matching the \fBcurl_multi_timer_callback\fP +prototype. This function will then be called when the timeout value +changes. The timeout value is at what latest time the application should call +one of the \&"performing" functions of the multi interface +(\fIcurl_multi_socket_action(3)\fP and \fIcurl_multi_perform(3)\fP) - to allow +libcurl to keep timeouts and retries etc to work. A timeout value of -1 means +that there is no timeout at all, and 0 means that the timeout is already +reached. Libcurl attempts to limit calling this only when the fixed future +timeout time actually changes. See also \fICURLMOPT_TIMERDATA\fP. This +callback can be used instead of, or in addition to, +\fIcurl_multi_timeout(3)\fP. (Added in 7.16.0) +.IP CURLMOPT_TIMERDATA +Pass a pointer to whatever you want passed to the +\fBcurl_multi_timer_callback\fP's third argument, the userp pointer. This is +not used by libcurl but only passed-thru as-is. Set the callback pointer with +\fICURLMOPT_TIMERFUNCTION\fP. (Added in 7.16.0) +.IP CURLMOPT_MAXCONNECTS +Pass a long. The set number will be used as the maximum amount of +simultaneously open connections that libcurl may cache. Default is 10, and +libcurl will enlarge the size for each added easy handle to make it fit 4 +times the number of added easy handles. + +By setting this option, you can prevent the cache size from growing beyond the +limit set by you. + +When the cache is full, curl closes the oldest one in the cache to prevent the +number of open connections from increasing. + +This option is for the multi handle's use only, when using the easy interface +you should instead use the \fICURLOPT_MAXCONNECTS\fP option. + +(Added in 7.16.3) +.SH RETURNS +The standard CURLMcode for multi interface error codes. Note that it returns a +CURLM_UNKNOWN_OPTION if you try setting an option that this version of libcurl +doesn't know of. +.SH AVAILABILITY +This function was added in libcurl 7.15.4. +.SH "SEE ALSO" +.BR curl_multi_cleanup "(3), " curl_multi_init "(3), " +.BR curl_multi_socket "(3), " curl_multi_info_read "(3)" diff --git a/docs/libcurl/curl_multi_socket.3 b/docs/libcurl/curl_multi_socket.3 new file mode 100644 index 000000000..6b262f292 --- /dev/null +++ b/docs/libcurl/curl_multi_socket.3 @@ -0,0 +1,158 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_multi_socket 3 "9 Jul 2006" "libcurl 7.16.0" "libcurl Manual" +.SH NAME +curl_multi_socket \- reads/writes available data +.SH SYNOPSIS +.nf +#include <curl/curl.h> +CURLMcode curl_multi_socket(CURLM * multi_handle, curl_socket_t sockfd, + int *running_handles); + +CURLMcode curl_multi_socket_all(CURLM *multi_handle, + int *running_handles); +.fi +.SH DESCRIPTION +These functions are deprecated. Do not use! See +\fIcurl_multi_socket_action(3)\fP instead! + +At return, the integer \fBrunning_handles\fP points to will contain the number +of still running easy handles within the multi handle. When this number +reaches zero, all transfers are complete/done. Note that when you call +\fIcurl_multi_socket_action(3)\fP on a specific socket and the counter +decreases by one, it DOES NOT necessarily mean that this exact socket/transfer +is the one that completed. Use \fIcurl_multi_info_read(3)\fP to figure out +which easy handle that completed. + +The \fBcurl_multi_socket_action(3)\fP functions inform the application about +updates in the socket (file descriptor) status by doing none, one, or multiple +calls to the socket callback function set with the CURLMOPT_SOCKETFUNCTION +option to \fIcurl_multi_setopt(3)\fP. They update the status with changes +since the previous time the callback was called. + +Get the timeout time by setting the \fICURLMOPT_TIMERFUNCTION\fP option with +\fIcurl_multi_setopt(3)\fP. Your application will then get called with +information on how long to wait for socket actions at most before doing the +timeout action: call the \fBcurl_multi_socket_action(3)\fP function with the +\fBsockfd\fP argument set to CURL_SOCKET_TIMEOUT. You can also use the +\fIcurl_multi_timeout(3)\fP function to poll the value at any given time, but +for an event-based system using the callback is far better than relying on +polling the timeout value. + +Usage of \fIcurl_multi_socket(3)\fP is deprecated, whereas the function is +equivalent to \fIcurl_multi_socket_action(3)\fP with \fBev_bitmask\fP set to +0. + +Force libcurl to (re-)check all its internal sockets and transfers instead of +just a single one by calling \fBcurl_multi_socket_all(3)\fP. Note that there +should not be any reason to use this function! +.SH "CALLBACK DETAILS" + +The socket \fBcallback\fP function uses a prototype like this +.nf + + int curl_socket_callback(CURL *easy, /* easy handle */ + curl_socket_t s, /* socket */ + int action, /* see values below */ + void *userp, /* private callback pointer */ + void *socketp); /* private socket pointer */ + +.fi +The callback MUST return 0. + +The \fIeasy\fP argument is a pointer to the easy handle that deals with this +particular socket. Note that a single handle may work with several sockets +simultaneously. + +The \fIs\fP argument is the actual socket value as you use it within your +system. + +The \fIaction\fP argument to the callback has one of five values: +.RS +.IP "CURL_POLL_NONE (0)" +register, not interested in readiness (yet) +.IP "CURL_POLL_IN (1)" +register, interested in read readiness +.IP "CURL_POLL_OUT (2)" +register, interested in write readiness +.IP "CURL_POLL_INOUT (3)" +register, interested in both read and write readiness +.IP "CURL_POLL_REMOVE (4)" +unregister +.RE + +The \fIsocketp\fP argument is a private pointer you have previously set with +\fIcurl_multi_assign(3)\fP to be associated with the \fIs\fP socket. If no +pointer has been set, socketp will be NULL. This argument is of course a +service to applications that want to keep certain data or structs that are +strictly associated to the given socket. + +The \fIuserp\fP argument is a private pointer you have previously set with +\fIcurl_multi_setopt(3)\fP and the CURLMOPT_SOCKETDATA option. +.SH "RETURN VALUE" +CURLMcode type, general libcurl multi interface error code. + +Legacy: If you receive \fICURLM_CALL_MULTI_PERFORM\fP, this basically means +that you should call \fIcurl_multi_socket(3)\fP again, before you wait for +more actions on libcurl's sockets. You don't have to do it immediately, but +the return code means that libcurl may have more data available to return or +that there may be more data to send off before it is "satisfied". + +In modern libcurls, \fICURLM_CALL_MULTI_PERFORM\fP or +\fICURLM_CALL_MULTI_SOKCET\fP should not be returned and no application needs +to care about them. + +NOTE that the return code is for the whole multi stack. Problems still might have +occurred on individual transfers even when one of these functions +return OK. +.SH "TYPICAL USAGE" +1. Create a multi handle + +2. Set the socket callback with CURLMOPT_SOCKETFUNCTION + +3. Set the timeout callback with CURLMOPT_TIMERFUNCTION, to get to know what +timeout value to use when waiting for socket activities. + +4. Add easy handles with curl_multi_add_handle() + +5. Provide some means to manage the sockets libcurl is using, so you can check +them for activity. This can be done through your application code, or by way +of an external library such as libevent or glib. + +6. Wait for activity on any of libcurl's sockets, use the timeout value your +callback has been told + +7, When activity is detected, call curl_multi_socket_action() for the +socket(s) that got action. If no activity is detected and the timeout expires, +call \fIcurl_multi_socket_action(3)\fP with \fICURL_SOCKET_TIMEOUT\fP + +8. Go back to step 6. +.SH AVAILABILITY +This function was added in libcurl 7.15.4, and is deemed stable since +7.16.0. + +\fIcurl_multi_socket(3)\fP is deprecated, use +\fIcurl_multi_socket_action(3)\fP instead! +.SH "SEE ALSO" +.BR curl_multi_cleanup "(3), " curl_multi_init "(3), " +.BR curl_multi_fdset "(3), " curl_multi_info_read "(3), " +.BR "the hiperfifo.c example" diff --git a/docs/libcurl/curl_multi_socket_action.3 b/docs/libcurl/curl_multi_socket_action.3 new file mode 100644 index 000000000..ac3b176c7 --- /dev/null +++ b/docs/libcurl/curl_multi_socket_action.3 @@ -0,0 +1,149 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2012, 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_multi_socket_action 3 "9 Jul 2006" "libcurl 7.16.0" "libcurl Manual" +.SH NAME +curl_multi_socket_action \- reads/writes available data given an action +.SH SYNOPSIS +.nf +#include <curl/curl.h> + +CURLMcode curl_multi_socket_action(CURLM * multi_handle, + curl_socket_t sockfd, int ev_bitmask, + int *running_handles); +.fi +.SH DESCRIPTION +When the application has detected action on a socket handled by libcurl, it +should call \fIcurl_multi_socket_action(3)\fP with the \fBsockfd\fP argument +set to the socket with the action. When the events on a socket are known, they +can be passed as an events bitmask \fBev_bitmask\fP by first setting +\fBev_bitmask\fP to 0, and then adding using bitwise OR (|) any combination of +events to be chosen from CURL_CSELECT_IN, CURL_CSELECT_OUT or +CURL_CSELECT_ERR. When the events on a socket are unknown, pass 0 instead, and +libcurl will test the descriptor internally. + +At return, the integer \fBrunning_handles\fP points to will contain the number +of running easy handles within the multi handle. When this number reaches +zero, all transfers are complete/done. When you call +\fIcurl_multi_socket_action(3)\fP on a specific socket and the counter +decreases by one, it DOES NOT necessarily mean that this exact socket/transfer +is the one that completed. Use \fIcurl_multi_info_read(3)\fP to figure out +which easy handle that completed. + +The \fBcurl_multi_socket_action(3)\fP functions inform the application about +updates in the socket (file descriptor) status by doing none, one, or multiple +calls to the socket callback function set with the CURLMOPT_SOCKETFUNCTION +option to \fIcurl_multi_setopt(3)\fP. They update the status with changes +since the previous time the callback was called. + +Get the timeout time by setting the \fICURLMOPT_TIMERFUNCTION\fP option with +\fIcurl_multi_setopt(3)\fP. Your application will then get called with +information on how long to wait for socket actions at most before doing the +timeout action: call the \fBcurl_multi_socket_action(3)\fP function with the +\fBsockfd\fP argument set to CURL_SOCKET_TIMEOUT. You can also use the +\fIcurl_multi_timeout(3)\fP function to poll the value at any given time, but +for an event-based system using the callback is far better than relying on +polling the timeout value. +.SH "CALLBACK DETAILS" + +The socket \fBcallback\fP function uses a prototype like this +.nf + + int curl_socket_callback(CURL *easy, /* easy handle */ + curl_socket_t s, /* socket */ + int action, /* see values below */ + void *userp, /* private callback pointer */ + void *socketp); /* private socket pointer */ + +.fi +The callback MUST return 0. + +The \fIeasy\fP argument is a pointer to the easy handle that deals with this +particular socket. Note that a single handle may work with several sockets +simultaneously. + +The \fIs\fP argument is the actual socket value as you use it within your +system. + +The \fIaction\fP argument to the callback has one of five values: +.RS +.IP "CURL_POLL_NONE (0)" +register, not interested in readiness (yet) +.IP "CURL_POLL_IN (1)" +register, interested in read readiness +.IP "CURL_POLL_OUT (2)" +register, interested in write readiness +.IP "CURL_POLL_INOUT (3)" +register, interested in both read and write readiness +.IP "CURL_POLL_REMOVE (4)" +unregister +.RE + +The \fIsocketp\fP argument is a private pointer you have previously set with +\fIcurl_multi_assign(3)\fP to be associated with the \fIs\fP socket. If no +pointer has been set, socketp will be NULL. This argument is of course a +service to applications that want to keep certain data or structs that are +strictly associated to the given socket. + +The \fIuserp\fP argument is a private pointer you have previously set with +\fIcurl_multi_setopt(3)\fP and the CURLMOPT_SOCKETDATA option. +.SH "RETURN VALUE" +CURLMcode type, general libcurl multi interface error code. + +Before version 7.20.0: If you receive \fICURLM_CALL_MULTI_PERFORM\fP, this +basically means that you should call \fIcurl_multi_socket_action(3)\fP again +before you wait for more actions on libcurl's sockets. You don't have to do it +immediately, but the return code means that libcurl may have more data +available to return or that there may be more data to send off before it is +"satisfied". + +The return code from this function is for the whole multi stack. Problems +still might have occurred on individual transfers even when one of these +functions return OK. +.SH "TYPICAL USAGE" +1. Create a multi handle + +2. Set the socket callback with CURLMOPT_SOCKETFUNCTION + +3. Set the timeout callback with CURLMOPT_TIMERFUNCTION, to get to know what +timeout value to use when waiting for socket activities. + +4. Add easy handles with curl_multi_add_handle() + +5. Provide some means to manage the sockets libcurl is using, so you can check +them for activity. This can be done through your application code, or by way +of an external library such as libevent or glib. + +6. Call curl_multi_socket_action(...CURL_SOCKET_TIMEOUT...) to kickstart +everything. To get one or more callbacks called. + +7. Wait for activity on any of libcurl's sockets, use the timeout value your +callback has been told + +8, When activity is detected, call curl_multi_socket_action() for the +socket(s) that got action. If no activity is detected and the timeout expires, +call \fIcurl_multi_socket_action(3)\fP with \fICURL_SOCKET_TIMEOUT\fP +.SH AVAILABILITY +This function was added in libcurl 7.15.4, and is deemed stable since 7.16.0. +.SH "SEE ALSO" +.BR curl_multi_cleanup "(3), " curl_multi_init "(3), " +.BR curl_multi_fdset "(3), " curl_multi_info_read "(3), " +.BR "the hiperfifo.c example" diff --git a/docs/libcurl/curl_multi_socket_all.3 b/docs/libcurl/curl_multi_socket_all.3 new file mode 100644 index 000000000..428dd06f9 --- /dev/null +++ b/docs/libcurl/curl_multi_socket_all.3 @@ -0,0 +1 @@ +.so man3/curl_multi_socket.3 diff --git a/docs/libcurl/curl_multi_strerror.3 b/docs/libcurl/curl_multi_strerror.3 new file mode 100644 index 000000000..40d0974c5 --- /dev/null +++ b/docs/libcurl/curl_multi_strerror.3 @@ -0,0 +1,37 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_multi_strerror 3 "26 Apr 2004" "libcurl 7.12" "libcurl Manual" +.SH NAME +curl_multi_strerror - return string describing error code +.SH SYNOPSIS +.nf +.B #include <curl/curl.h> +.BI "const char *curl_multi_strerror(CURLMcode " errornum ");" +.SH DESCRIPTION +The curl_multi_strerror() function returns a string describing the CURLMcode +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_easy_strerror "(3), " curl_share_strerror "(3)" diff --git a/docs/libcurl/curl_multi_timeout.3 b/docs/libcurl/curl_multi_timeout.3 new file mode 100644 index 000000000..5ad8008ea --- /dev/null +++ b/docs/libcurl/curl_multi_timeout.3 @@ -0,0 +1,63 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_multi_timeout 3 "2 Jan 2006" "libcurl 7.16.0" "libcurl Manual" +.SH NAME +curl_multi_timeout \- how long to wait for action before proceeding +.SH SYNOPSIS +#include <curl/curl.h> + +CURLMcode curl_multi_timeout(CURLM *multi_handle, long *timeout); +.SH DESCRIPTION + +An application using the libcurl multi interface should call +\fBcurl_multi_timeout(3)\fP to figure out how long it should wait for socket +actions \- at most \- before proceeding. + +Proceeding means either doing the socket-style timeout action: call the +\fBcurl_multi_socket_action(3)\fP function with the \fBsockfd\fP argument set +to CURL_SOCKET_TIMEOUT, or call \fBcurl_multi_perform(3)\fP if you're using +the simpler and older multi interface approach. + +The timeout value returned in the long \fBtimeout\fP points to, is in number +of milliseconds at this very moment. If 0, it means you should proceed +immediately without waiting for anything. If it returns -1, there's no timeout +at all set. + +An application that uses the multi_socket API SHOULD not use this function, but +SHOULD instead use \fIcurl_multi_setopt(3)\fP and its +\fPCURLMOPT_TIMERFUNCTION\fP option for proper and desired behavior. + +Note: if libcurl returns a -1 timeout here, it just means that libcurl +currently has no stored timeout value. You must not wait too long (more than a +few seconds perhaps) before you call curl_multi_perform() again. +.SH "RETURN VALUE" +The standard CURLMcode for multi interface error codes. +.SH "TYPICAL USAGE" +Call \fBcurl_multi_timeout(3)\fP, then wait for action on the sockets. You +figure out which sockets to wait for by calling \fBcurl_multi_fdset(3)\fP or +by a previous call to \fBcurl_multi_socket(3)\fP. +.SH AVAILABILITY +This function was added in libcurl 7.15.4. +.SH "SEE ALSO" +.BR curl_multi_fdset "(3), " curl_multi_info_read "(3), " +.BR curl_multi_socket "(3), " curl_multi_setopt "(3) " + diff --git a/docs/libcurl/curl_multi_wait.3 b/docs/libcurl/curl_multi_wait.3 new file mode 100644 index 000000000..b14760bf3 --- /dev/null +++ b/docs/libcurl/curl_multi_wait.3 @@ -0,0 +1,75 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2012, 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_multi_wait 3 "12 Jul 2012" "libcurl 7.28.0" "libcurl Manual" +.SH NAME +curl_multi_wait - polls on all easy handles in a multi handle +.SH SYNOPSIS +.nf +#include <curl/curl.h> + +CURLMcode curl_multi_wait(CURLM *multi_handle, + struct curl_waitfd extra_fds[], + unsigned int extra_nfds, + int timeout_ms, + int *numfds); +.ad +.SH DESCRIPTION +This function polls on all file descriptors used by the curl easy handles +contained in the given multi handle set. It will block until activity is +detected on at least one of the handles or \fItimeout_ms\fP has passed. + +The calling application may pass additional curl_waitfd structures which are +similar to \fIpoll(2)\fP's pollfd structure to be waited on in the same call. + +On completion, if \fInumfds\fP is supplied, it will be populated with the +number of file descriptors on which interesting events occured. + +If no extra file descriptors are provided and libcurl has no file descriptor +to offer to wait for, this function will return immediately. + +This function is encouraged to be used instead of select(3) when using the +multi interface to allow applications to easier circumvent the common problem +with 1024 maximum file descriptors. +.SH curl_waitfd +.nf +struct curl_waitfd { + curl_socket_t fd; + short events; + short revents; +}; +.fi +.IP CURL_WAIT_POLLIN +Bit flag to curl_waitfd.events indicating the socket should poll on read +events such as new data received. +.IP CURL_WAIT_POLLPRI +Bit flag to curl_waitfd.events indicating the socket should poll on high +priority read events such as out of band data. +.IP CURL_WAIT_POLLOUT +Bit flag to curl_waitfd.events indicating the socket should poll on write +events such as the socket being clear to write without blocking. +.SH RETURN VALUE +CURLMcode type, general libcurl multi interface error code. See +\fIlibcurl-errors(3)\fP +.SH AVAILABILITY +This function was added in libcurl 7.28.0. +.SH "SEE ALSO" +.BR curl_multi_fdset "(3), " curl_multi_perform "(3)" diff --git a/docs/libcurl/curl_share_cleanup.3 b/docs/libcurl/curl_share_cleanup.3 new file mode 100644 index 000000000..3af1707bb --- /dev/null +++ b/docs/libcurl/curl_share_cleanup.3 @@ -0,0 +1,40 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_share_cleanup 3 "8 Aug 2003" "libcurl 7.10.7" "libcurl Manual" +.SH NAME +curl_share_cleanup - Clean up a shared object +.SH SYNOPSIS +.B #include <curl/curl.h> +.sp +.BI "CURLSHcode curl_share_cleanup(CURLSH *" share_handle ");" +.ad +.SH DESCRIPTION +This function deletes a shared object. The share handle cannot be used anymore +when this function has been called. + +.SH RETURN VALUE +CURLSHE_OK (zero) means that the option was set properly, non-zero means an +error occurred as \fI<curl/curl.h>\fP defines. See the \fIlibcurl-errors.3\fP +man page for the full list with descriptions. If an error occurs, then the +share object will not be deleted. +.SH "SEE ALSO" +.BR curl_share_init "(3), " curl_share_setopt "(3)" diff --git a/docs/libcurl/curl_share_init.3 b/docs/libcurl/curl_share_init.3 new file mode 100644 index 000000000..ce00d958e --- /dev/null +++ b/docs/libcurl/curl_share_init.3 @@ -0,0 +1,44 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_share_init 3 "8 Aug 2003" "libcurl 7.10.7" "libcurl Manual" +.SH NAME +curl_share_init - Create a shared object +.SH SYNOPSIS +.B #include <curl/curl.h> +.sp +.BI "CURLSH *curl_share_init( );" +.ad +.SH DESCRIPTION +This function returns a CURLSH handle to be used as input to all the other +share-functions, sometimes referred to as a share handle in some places in the +documentation. This init call MUST have a corresponding call to +\fIcurl_share_cleanup\fP when all operations using the share are complete. + +This \fIshare handle\fP is what you pass to curl using the \fICURLOPT_SHARE\fP +option with \fIcurl_easy_setopt(3)\fP, to make that specific curl handle use +the data in this share. +.SH RETURN VALUE +If this function returns NULL, something went wrong (out of memory, etc.) +and therefore the share object was not created. +.SH "SEE ALSO" +.BR curl_share_cleanup "(3), " curl_share_setopt "(3)" + diff --git a/docs/libcurl/curl_share_setopt.3 b/docs/libcurl/curl_share_setopt.3 new file mode 100644 index 000000000..c196743ff --- /dev/null +++ b/docs/libcurl/curl_share_setopt.3 @@ -0,0 +1,85 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_share_setopt 3 "8 Aug 2003" "libcurl 7.10.7" "libcurl Manual" +.SH NAME +curl_share_setopt - Set options for a shared object +.SH SYNOPSIS +.B #include <curl/curl.h> +.sp +CURLSHcode curl_share_setopt(CURLSH *share, CURLSHoption option, parameter); +.ad +.SH DESCRIPTION +Set the \fIoption\fP to \fIparameter\fP for the given \fIshare\fP. +.SH OPTIONS +.IP CURLSHOPT_LOCKFUNC +The \fIparameter\fP must be a pointer to a function matching the following +prototype: + +void lock_function(CURL *handle, curl_lock_data data, curl_lock_access access, +void *userptr); + +\fIdata\fP defines what data libcurl wants to lock, and you must make sure that +only one lock is given at any time for each kind of data. + +\fIaccess\fP defines what access type libcurl wants, shared or single. + +\fIuserptr\fP is the pointer you set with \fICURLSHOPT_USERDATA\fP. +.IP CURLSHOPT_UNLOCKFUNC +The \fIparameter\fP must be a pointer to a function matching the following +prototype: + +void unlock_function(CURL *handle, curl_lock_data data, void *userptr); + +\fIdata\fP defines what data libcurl wants to unlock, and you must make sure +that only one lock is given at any time for each kind of data. + +\fIuserptr\fP is the pointer you set with \fICURLSHOPT_USERDATA\fP. +.IP CURLSHOPT_SHARE +The \fIparameter\fP specifies a type of data that should be shared. This may +be set to one of the values described below. +.RS +.IP CURL_LOCK_DATA_COOKIE +Cookie data will be shared across the easy handles using this shared object. +.IP CURL_LOCK_DATA_DNS +Cached DNS hosts will be shared across the easy handles using this shared +object. Note that when you use the multi interface, all easy handles added to +the same multi handle will share DNS cache by default without this having to +be used! +.IP CURL_LOCK_DATA_SSL_SESSION +SSL session IDs will be shared across the easy handles using this shared +object. This will reduce the time spent in the SSL handshake when reconnecting +to the same server. Note SSL session IDs are reused within the same easy handle +by default. +.RE +.IP CURLSHOPT_UNSHARE +This option does the opposite of \fICURLSHOPT_SHARE\fP. It specifies that +the specified \fIparameter\fP will no longer be shared. Valid values are +the same as those for \fICURLSHOPT_SHARE\fP. +.IP CURLSHOPT_USERDATA +The \fIparameter\fP allows you to specify a pointer to data that will be passed +to the lock_function and unlock_function each time it is called. +.SH RETURN VALUE +CURLSHE_OK (zero) means that the option was set properly, non-zero means an +error occurred as \fI<curl/curl.h>\fP defines. See the \fIlibcurl-errors.3\fP +man page for the full list with descriptions. +.SH "SEE ALSO" +.BR curl_share_cleanup "(3), " curl_share_init "(3)" diff --git a/docs/libcurl/curl_share_strerror.3 b/docs/libcurl/curl_share_strerror.3 new file mode 100644 index 000000000..f1bc39867 --- /dev/null +++ b/docs/libcurl/curl_share_strerror.3 @@ -0,0 +1,37 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_share_strerror 3 "26 Apr 2004" "libcurl 7.12" "libcurl Manual" +.SH NAME +curl_share_strerror - return string describing error code +.SH SYNOPSIS +.nf +.B #include <curl/curl.h> +.BI "const char *curl_share_strerror(CURLSHcode " errornum ");" +.SH DESCRIPTION +The curl_share_strerror() function returns a string describing the CURLSHcode +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_easy_strerror "(3)" diff --git a/docs/libcurl/curl_slist_append.3 b/docs/libcurl/curl_slist_append.3 new file mode 100644 index 000000000..529560e8a --- /dev/null +++ b/docs/libcurl/curl_slist_append.3 @@ -0,0 +1,56 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_slist_append 3 "19 Jun 2003" "libcurl 7.10.4" "libcurl Manual" +.SH NAME +curl_slist_append - add a string to an slist +.SH SYNOPSIS +.B #include <curl/curl.h> +.sp +.BI "struct curl_slist *curl_slist_append(struct curl_slist *" list, +.BI "const char * "string ");" +.ad +.SH DESCRIPTION +curl_slist_append() appends a specified string to a linked list of +strings. The existing \fIlist\fP should be passed as the first argument while +the new list is returned from this function. The specified \fIstring\fP has +been appended when this function returns. curl_slist_append() copies the +string. + +The list should be freed again (after usage) with +\fBcurl_slist_free_all(3)\fP. +.SH RETURN VALUE +A null pointer is returned if anything went wrong, otherwise the new list +pointer is returned. +.SH EXAMPLE +.nf + CURL handle; + struct curl_slist *slist=NULL; + + slist = curl_slist_append(slist, "pragma:"); + curl_easy_setopt(handle, CURLOPT_HTTPHEADER, slist); + + curl_easy_perform(handle); + + curl_slist_free_all(slist); /* free the list again */ +.fi +.SH "SEE ALSO" +.BR curl_slist_free_all "(3), " diff --git a/docs/libcurl/curl_slist_free_all.3 b/docs/libcurl/curl_slist_free_all.3 new file mode 100644 index 000000000..fab3d6080 --- /dev/null +++ b/docs/libcurl/curl_slist_free_all.3 @@ -0,0 +1,37 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_slist_free_all 3 "5 March 2001" "libcurl 7.0" "libcurl Manual" +.SH NAME +curl_slist_free_all - free an entire curl_slist list +.SH SYNOPSIS +.B #include <curl/curl.h> +.sp +.BI "void curl_slist_free_all(struct curl_slist *" list); +.ad +.SH DESCRIPTION +curl_slist_free_all() removes all traces of a previously built curl_slist +linked list. +.SH RETURN VALUE +Nothing. +.SH "SEE ALSO" +.BR curl_slist_append "(3), " + diff --git a/docs/libcurl/curl_strequal.3 b/docs/libcurl/curl_strequal.3 new file mode 100644 index 000000000..ce575d7ac --- /dev/null +++ b/docs/libcurl/curl_strequal.3 @@ -0,0 +1,51 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_strequal 3 "30 April 2004" "libcurl 7.12" "libcurl Manual" +.SH NAME +curl_strequal, curl_strnequal - case insensitive string comparisons +.SH SYNOPSIS +.B #include <curl/curl.h> +.sp +.BI "int curl_strequal(char *" str1 ", char *" str2 ");" +.sp +.BI "int curl_strenqual(char *" str1 ", char *" str2 ", size_t " len ");" +.SH DESCRIPTION +The +.B curl_strequal() +function compares the two strings \fIstr1\fP and \fIstr2\fP, ignoring the case +of the characters. It returns a non-zero (TRUE) integer if the strings are +identical. +.sp +The \fBcurl_strnequal()\fP function is similar, except it only compares the +first \fIlen\fP characters of \fIstr1\fP. +.sp +These functions are provided by libcurl to enable applications to compare +strings in a truly portable manner. There are no standard portable case +insensitive string comparison functions. These two work on all platforms. +.SH AVAILABILITY +These functions will be removed from the public libcurl API in a near +future. They will instead be made "available" by source code access only, and +then as curlx_strequal() and curlx_strenqual(). +.SH RETURN VALUE +Non-zero if the strings are identical. Zero if they're not. +.SH "SEE ALSO" +.BR strcmp "(3), " strcasecmp "(3)" diff --git a/docs/libcurl/curl_strnequal.3 b/docs/libcurl/curl_strnequal.3 new file mode 100644 index 000000000..ce41d3e41 --- /dev/null +++ b/docs/libcurl/curl_strnequal.3 @@ -0,0 +1 @@ +.so man3/curl_strequal.3 diff --git a/docs/libcurl/curl_unescape.3 b/docs/libcurl/curl_unescape.3 new file mode 100644 index 000000000..2a24866d3 --- /dev/null +++ b/docs/libcurl/curl_unescape.3 @@ -0,0 +1,48 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_unescape 3 "22 March 2001" "libcurl 7.7" "libcurl Manual" +.SH NAME +curl_unescape - URL decodes the given string +.SH SYNOPSIS +.B #include <curl/curl.h> +.sp +.BI "char *curl_unescape( char *" url ", int "length " );" +.ad +.SH DESCRIPTION +Obsolete function. Use \fIcurl_easy_unescape(3)\fP instead! + +This function will convert the given URL encoded input string to a "plain +string" and return that as a new allocated string. All input characters that +are URL encoded (%XX where XX is a two-digit hexadecimal number) will be +converted to their plain text versions. + +If the 'length' argument is set to 0, curl_unescape() will use strlen() on the +input 'url' string to find out the size. + +You must curl_free() the returned string when you're done with it. +.SH AVAILABILITY +Since 7.15.4, \fIcurl_easy_unescape(3)\fP should be used. This function will +be removed in a future release. +.SH RETURN VALUE +A pointer to a zero terminated string or NULL if it failed. +.SH "SEE ALSO" +.I curl_easy_escape(3), curl_easy_unescape(3), curl_free(3), RFC 2396 diff --git a/docs/libcurl/curl_version.3 b/docs/libcurl/curl_version.3 new file mode 100644 index 000000000..003329800 --- /dev/null +++ b/docs/libcurl/curl_version.3 @@ -0,0 +1,36 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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_version 3 "5 March 2001" "libcurl 7.0" "libcurl Manual" +.SH NAME +curl_version - returns the libcurl version string +.SH SYNOPSIS +.B #include <curl/curl.h> +.sp +.BI "char *curl_version( );" +.ad +.SH DESCRIPTION +Returns a human readable string with the version number of libcurl and some of +its important components (like OpenSSL version). +.SH RETURN VALUE +A pointer to a zero terminated string. +.SH "SEE ALSO" +.BR curl_version_info "(3)" diff --git a/docs/libcurl/curl_version_info.3 b/docs/libcurl/curl_version_info.3 new file mode 100644 index 000000000..ccb202834 --- /dev/null +++ b/docs/libcurl/curl_version_info.3 @@ -0,0 +1,154 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2009, 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_version_info 3 "10 June 2009" "libcurl 7.19.6" "libcurl Manual" +.SH NAME +curl_version_info - returns run-time libcurl version info +.SH SYNOPSIS +.B #include <curl/curl.h> +.sp +.BI "curl_version_info_data *curl_version_info( CURLversion "type ");" +.ad +.SH DESCRIPTION +Returns a pointer to a filled in struct with information about various +run-time features in libcurl. \fItype\fP should be set to the version of this +functionality by the time you write your program. This way, libcurl will +always return a proper struct that your program understands, while programs in +the future might get a different struct. CURLVERSION_NOW will be the most +recent one for the library you have installed: + + data = curl_version_info(CURLVERSION_NOW); + +Applications should use this information to judge if things are possible to do +or not, instead of using compile-time checks, as dynamic/DLL libraries can be +changed independent of applications. + +The curl_version_info_data struct looks like this + +.nf +typedef struct { + CURLversion age; /* see description below */ + + /* when 'age' is 0 or higher, the members below also exist: */ + const char *version; /* human readable string */ + unsigned int version_num; /* numeric representation */ + const char *host; /* human readable string */ + int features; /* bitmask, see below */ + char *ssl_version; /* human readable string */ + long ssl_version_num; /* not used, always zero */ + const char *libz_version; /* human readable string */ + const char **protocols; /* list of protocols */ + + /* when 'age' is 1 or higher, the members below also exist: */ + const char *ares; /* human readable string */ + int ares_num; /* number */ + + /* when 'age' is 2 or higher, the member below also exists: */ + const char *libidn; /* human readable string */ + + /* when 'age' is 3 or higher, the members below also exist: */ + int iconv_ver_num; /* '_libiconv_version' if iconv support enabled */ + + const char *libssh_version; /* human readable string */ + +} curl_version_info_data; +.fi + +\fIage\fP describes what the age of this struct is. The number depends on how +new the libcurl you're using is. You are however guaranteed to get a struct that you +have a matching struct for in the header, as you tell libcurl your "age" with +the input argument. + +\fIversion\fP is just an ascii string for the libcurl version. + +\fIversion_num\fP is a 24 bit number created like this: <8 bits major number> +| <8 bits minor number> | <8 bits patch number>. Version 7.9.8 is therefore +returned as 0x070908. + +\fIhost\fP is an ascii string showing what host information that this libcurl +was built for. As discovered by a configure script or set by the build +environment. + +\fIfeatures\fP can have none, one or more bits set, and the currently defined +bits are: +.RS +.IP CURL_VERSION_IPV6 +supports IPv6 +.IP CURL_VERSION_KERBEROS4 +supports kerberos4 (when using FTP) +.IP CURL_VERSION_SSL +supports SSL (HTTPS/FTPS) (Added in 7.10) +.IP CURL_VERSION_LIBZ +supports HTTP deflate using libz (Added in 7.10) +.IP CURL_VERSION_NTLM +supports HTTP NTLM (added in 7.10.6) +.IP CURL_VERSION_GSSNEGOTIATE +supports HTTP GSS-Negotiate (added in 7.10.6) +.IP CURL_VERSION_DEBUG +libcurl was built with debug capabilities (added in 7.10.6) +.IP CURL_VERSION_CURLDEBUG +libcurl was built with memory tracking debug capabilities. This is mainly of +interest for libcurl hackers. (added in 7.19.6) +.IP CURL_VERSION_ASYNCHDNS +libcurl was built with support for asynchronous name lookups, which allows +more exact timeouts (even on Windows) and less blocking when using the multi +interface. (added in 7.10.7) +.IP CURL_VERSION_SPNEGO +libcurl was built with support for SPNEGO authentication (Simple and Protected +GSS-API Negotiation Mechanism, defined in RFC 2478.) (added in 7.10.8) +.IP CURL_VERSION_LARGEFILE +libcurl was built with support for large files. (Added in 7.11.1) +.IP CURL_VERSION_IDN +libcurl was built with support for IDNA, domain names with international +letters. (Added in 7.12.0) +.IP CURL_VERSION_SSPI +libcurl was built with support for SSPI. This is only available on Windows and +makes libcurl use Windows-provided functions for NTLM authentication. It also +allows libcurl to use the current user and the current user's password without +the app having to pass them on. (Added in 7.13.2) +.IP CURL_VERSION_CONV +libcurl was built with support for character conversions, as provided by the +CURLOPT_CONV_* callbacks. (Added in 7.15.4) +.IP CURL_VERSION_TLSAUTH_SRP +libcurl was built with support for TLS-SRP. (Added in 7.21.4) +.IP CURL_VERSION_NTLM_WB +libcurl was built with support for NTLM delegation to a winbind helper. +(Added in 7.22.0) +.RE +\fIssl_version\fP is an ASCII string for the OpenSSL version used. If libcurl +has no SSL support, this is NULL. + +\fIssl_version_num\fP is the numerical OpenSSL version value as defined by the +OpenSSL project. If libcurl has no SSL support, this is 0. + +\fIlibz_version\fP is an ASCII string (there is no numerical version). If +libcurl has no libz support, this is NULL. + +\fIprotocols\fP is a pointer to an array of char * pointers, containing the +names protocols that libcurl supports (using lowercase letters). The protocol +names are the same as would be used in URLs. The array is terminated by a NULL +entry. +.SH RETURN VALUE +A pointer to a curl_version_info_data struct. +.SH "SEE ALSO" +\fIcurl_version(3)\fP + diff --git a/docs/libcurl/getinfo-times b/docs/libcurl/getinfo-times new file mode 100644 index 000000000..d767d7aae --- /dev/null +++ b/docs/libcurl/getinfo-times @@ -0,0 +1,27 @@ +An overview of the six time values available from curl_easy_getinfo() + +curk_easy_perform() + | + |--NT + |--|--CT + |--|--|--PT + |--|--|--|--ST + |--|--|--TT + |--|--|--|--|--RT + +NT = CURLINFO_NAMELOOKUP_TIME. The time it took from the start until the name + resolving was completed. +CT = CURLINFO_CONNECT_TIME. The time it took from the start until the connect + to the remote host (or proxy) was completed. +PT = CURLINFO_PRETRANSFER_TIME. 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. +ST = CURLINFO_STARTTRANSFER_TIME. The time it took from the start until the + first byte is just about to be transferred. +TT = CURLINFO_TOTAL_TIME. Time of the previous transfer. This time does not + include the connect time (CT), so if you want the complete operation + time, you should add that. +RT = CURLINFO_REDIRECT_TIME. 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. diff --git a/docs/libcurl/index.html b/docs/libcurl/index.html new file mode 100644 index 000000000..287a2dd69 --- /dev/null +++ b/docs/libcurl/index.html @@ -0,0 +1,61 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html><head> +<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> +<title>Index to libcurl documentation</title> +</head> + +<body> +<h1 align="center">Index to libcurl documentation</h1> + +<h2>Programs</h2> +<p><a href="../index.html">curl and tools</a> + +<h2>Overviews</h2> +<A HREF="libcurl.html">libcurl</A> +<br><a href="libcurl-easy.html">libcurl-easy</a> +<br><a href="libcurl-multi.html">libcurl-multi</a> +<br><a href="libcurl-share.html">libcurl-share</a> +<br><a href="libcurl-errors.html">libcurl-errors</a> +<br><a href="libcurl-tutorial.html">libcurl-tutorial</a> + +<H2>Library Functions (A-Z)</H2> +<a href="curl_easy_cleanup.html">curl_easy_cleanup</A> +<br><a href="curl_easy_duphandle.html">curl_easy_duphandle</A> +<br><a href="curl_easy_getinfo.html">curl_easy_getinfo</A> +<br><a href="curl_easy_init.html">curl_easy_init</A> +<br><a href="curl_easy_perform.html">curl_easy_perform</A> +<br><a href="curl_easy_recv.html">curl_easy_recv</A> +<br><a href="curl_easy_reset.html">curl_easy_reset</A> +<br><a href="curl_easy_send.html">curl_easy_send</A> +<br><a href="curl_easy_setopt.html">curl_easy_setopt</A> +<br><a href="curl_easy_strerror.html">curl_easy_strerror</A> +<br><a href="curl_escape.html">curl_escape</A> +<br><a href="curl_formadd.html">curl_formadd</A> +<br><a href="curl_formfree.html">curl_formfree</A> +<br><a href="curl_free.html">curl_free</A> +<br><a href="curl_getdate.html">curl_getdate</A> +<br><a href="curl_getenv.html">curl_getenv</A> +<br><a href="curl_global_cleanup.html">curl_global_cleanup</A> +<br><a href="curl_global_init.html">curl_global_init</A> +<br><a href="curl_global_init_mem.html">curl_global_init_mem</A> +<br><a href="curl_mprintf.html">curl_mprintf</A> +<br><a href="curl_multi_add_handle.html">curl_multi_add_handle</a> +<br><a href="curl_multi_cleanup.html">curl_multi_cleanup</a> +<br><a href="curl_multi_fdset.html">curl_multi_fdset</a> +<br><a href="curl_multi_info_read.html">curl_multi_info_read</a> +<br><a href="curl_multi_init.html">curl_multi_init</a> +<br><a href="curl_multi_perform.html">curl_multi_perform</a> +<br><a href="curl_multi_remove_handle.html">curl_multi_remove_handle</a> +<br><a href="curl_multi_strerror.html">curl_multi_strerror.html</a> +<br><a href="curl_share_cleanup.html">curl_share_cleanup</A> +<br><a href="curl_share_init.html">curl_share_init</A> +<br><a href="curl_share_setopt.html">curl_share_setopt</A> +<br><a href="curl_share_strerror.html">curl_share_strerror.html</a> +<br><a href="curl_slist_append.html">curl_slist_append</A> +<br><a href="curl_slist_free_all.html">curl_slist_free_all</A> +<br><a href="curl_strequal.html">curl_strequal and curl_strnequal</A> +<br><a href="curl_unescape.html">curl_unescape</A> +<br><a href="curl_version.html">curl_version</A> +<br><a href="curl_version_info.html">curl_version_info</A> + +</body></html> diff --git a/docs/libcurl/libcurl-easy.3 b/docs/libcurl/libcurl-easy.3 new file mode 100644 index 000000000..698a4ce72 --- /dev/null +++ b/docs/libcurl/libcurl-easy.3 @@ -0,0 +1,45 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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 libcurl 3 "12 Aug 2003" "libcurl 7.10.7" "libcurl easy interface" +.SH NAME +libcurl-easy \- easy interface overview +.SH DESCRIPTION +When using libcurl's "easy" interface you init your session and get a handle +(often referred to as an "easy handle"), which you use as input to the easy +interface functions you use. Use \fIcurl_easy_init(3)\fP to get the handle. + +You continue by setting all the options you want in the upcoming transfer, the +most important among them is the URL itself (you can't transfer anything +without a specified URL as you may have figured out yourself). You might want +to set some callbacks as well that will be called from the library when data +is available etc. \fIcurl_easy_setopt(3)\fP is used for all this. + +When all is setup, you tell libcurl to perform the transfer using +\fIcurl_easy_perform(3)\fP. It will then do the entire operation and won't +return until it is done (successfully or not). + +After the transfer has been made, you can set new options and make another +transfer, or if you're done, cleanup the session by calling +\fIcurl_easy_cleanup(3)\fP. If you want persistent connections, you don't +cleanup immediately, but instead run ahead and perform other transfers using +the same easy handle. + diff --git a/docs/libcurl/libcurl-errors.3 b/docs/libcurl/libcurl-errors.3 new file mode 100644 index 000000000..beee3971f --- /dev/null +++ b/docs/libcurl/libcurl-errors.3 @@ -0,0 +1,289 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2012, 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 libcurl-errors 3 "1 Jan 2010" "libcurl 7.20.0" "libcurl errors" +.SH NAME +libcurl-errors \- error codes in libcurl +.SH DESCRIPTION +This man page includes most, if not all, available error codes in libcurl. +Why they occur and possibly what you can do to fix the problem are also included. +.SH "CURLcode" +Almost all "easy" interface functions return a CURLcode error code. No matter +what, using the \fIcurl_easy_setopt(3)\fP option \fICURLOPT_ERRORBUFFER\fP is +a good idea as it will give you a human readable error string that may offer +more details about the cause of the error than just the error code. +\fIcurl_easy_strerror(3)\fP can be called to get an error string from a +given CURLcode number. + +CURLcode is one of the following: +.IP "CURLE_OK (0)" +All fine. Proceed as usual. +.IP "CURLE_UNSUPPORTED_PROTOCOL (1)" +The URL you passed to libcurl used a protocol that this libcurl does not +support. The support might be a compile-time option that you didn't use, it +can be a misspelled protocol string or just a protocol libcurl has no code +for. +.IP "CURLE_FAILED_INIT (2)" +Very early initialization code failed. This is likely to be an internal error +or problem, or a resource problem where something fundamental couldn't get +done at init time. +.IP "CURLE_URL_MALFORMAT (3)" +The URL was not properly formatted. +.IP "CURLE_NOT_BUILT_IN (4)" +A requested feature, protocol or option was not found built-in in this libcurl +due to a build-time decision. This means that a feature or option was not +enabled or explicitly disabled when libcurl was built and in order to get it +to function you have to get a rebuilt libcurl. +.IP "CURLE_COULDNT_RESOLVE_PROXY (5)" +Couldn't resolve proxy. The given proxy host could not be resolved. +.IP "CURLE_COULDNT_RESOLVE_HOST (6)" +Couldn't resolve host. The given remote host was not resolved. +.IP "CURLE_COULDNT_CONNECT (7)" +Failed to connect() to host or proxy. +.IP "CURLE_FTP_WEIRD_SERVER_REPLY (8)" +After connecting to a FTP server, libcurl expects to get a certain reply +back. This error code implies that it got a strange or bad reply. The given +remote server is probably not an OK FTP server. +.IP "CURLE_REMOTE_ACCESS_DENIED (9)" +We were denied access to the resource given in the URL. For FTP, this occurs +while trying to change to the remote directory. +.IP "CURLE_FTP_ACCEPT_FAILED (10)" +While waiting for the server to connect back when an active FTP session is +used, an error code was sent over the control connection or similar. +.IP "CURLE_FTP_WEIRD_PASS_REPLY (11)" +After having sent the FTP password to the server, libcurl expects a proper +reply. This error code indicates that an unexpected code was returned. +.IP "CURLE_FTP_ACCEPT_TIMEOUT (12)" +During an active FTP session while waiting for the server to connect, the +\fICURLOPT_ACCEPTTIMOUT_MS\fP (or the internal default) timeout expired. +.IP "CURLE_FTP_WEIRD_PASV_REPLY (13)" +libcurl failed to get a sensible result back from the server as a response to +either a PASV or a EPSV command. The server is flawed. +.IP "CURLE_FTP_WEIRD_227_FORMAT (14)" +FTP servers return a 227-line as a response to a PASV command. If libcurl +fails to parse that line, this return code is passed back. +.IP "CURLE_FTP_CANT_GET_HOST (15)" +An internal failure to lookup the host used for the new connection. +.IP "CURLE_FTP_COULDNT_SET_TYPE (17)" +Received an error when trying to set the transfer mode to binary or ASCII. +.IP "CURLE_PARTIAL_FILE (18)" +A file transfer was shorter or larger than expected. This happens when the +server first reports an expected transfer size, and then delivers data that +doesn't match the previously given size. +.IP "CURLE_FTP_COULDNT_RETR_FILE (19)" +This was either a weird reply to a 'RETR' command or a zero byte transfer +complete. +.IP "CURLE_QUOTE_ERROR (21)" +When sending custom "QUOTE" commands to the remote server, one of the commands +returned an error code that was 400 or higher (for FTP) or otherwise +indicated unsuccessful completion of the command. +.IP "CURLE_HTTP_RETURNED_ERROR (22)" +This is returned if CURLOPT_FAILONERROR is set TRUE and the HTTP server +returns an error code that is >= 400. +.IP "CURLE_WRITE_ERROR (23)" +An error occurred when writing received data to a local file, or an error was +returned to libcurl from a write callback. +.IP "CURLE_UPLOAD_FAILED (25)" +Failed starting the upload. For FTP, the server typically denied the STOR +command. The error buffer usually contains the server's explanation for this. +.IP "CURLE_READ_ERROR (26)" +There was a problem reading a local file or an error returned by the read +callback. +.IP "CURLE_OUT_OF_MEMORY (27)" +A memory allocation request failed. This is serious badness and +things are severely screwed up if this ever occurs. +.IP "CURLE_OPERATION_TIMEDOUT (28)" +Operation timeout. The specified time-out period was reached according to the +conditions. +.IP "CURLE_FTP_PORT_FAILED (30)" +The FTP PORT command returned error. This mostly happens when you haven't +specified a good enough address for libcurl to use. See \fICURLOPT_FTPPORT\fP. +.IP "CURLE_FTP_COULDNT_USE_REST (31)" +The FTP REST command returned error. This should never happen if the server is +sane. +.IP "CURLE_RANGE_ERROR (33)" +The server does not support or accept range requests. +.IP "CURLE_HTTP_POST_ERROR (34)" +This is an odd error that mainly occurs due to internal confusion. +.IP "CURLE_SSL_CONNECT_ERROR (35)" +A problem occurred somewhere in the SSL/TLS handshake. You really want the +error buffer and read the message there as it pinpoints the problem slightly +more. Could be certificates (file formats, paths, permissions), passwords, and +others. +.IP "CURLE_BAD_DOWNLOAD_RESUME (36)" +The download could not be resumed because the specified offset was out of the +file boundary. +.IP "CURLE_FILE_COULDNT_READ_FILE (37)" +A file given with FILE:// couldn't be opened. Most likely because the file +path doesn't identify an existing file. Did you check file permissions? +.IP "CURLE_LDAP_CANNOT_BIND (38)" +LDAP cannot bind. LDAP bind operation failed. +.IP "CURLE_LDAP_SEARCH_FAILED (39)" +LDAP search failed. +.IP "CURLE_FUNCTION_NOT_FOUND (41)" +Function not found. A required zlib function was not found. +.IP "CURLE_ABORTED_BY_CALLBACK (42)" +Aborted by callback. A callback returned "abort" to libcurl. +.IP "CURLE_BAD_FUNCTION_ARGUMENT (43)" +Internal error. A function was called with a bad parameter. +.IP "CURLE_INTERFACE_FAILED (45)" +Interface error. A specified outgoing interface could not be used. Set which +interface to use for outgoing connections' source IP address with +CURLOPT_INTERFACE. +.IP "CURLE_TOO_MANY_REDIRECTS (47)" +Too many redirects. When following redirects, libcurl hit the maximum amount. +Set your limit with CURLOPT_MAXREDIRS. +.IP "CURLE_UNKNOWN_OPTION (48)" +An option passed to libcurl is not recognized/known. Refer to the appropriate +documentation. This is most likely a problem in the program that uses +libcurl. The error buffer might contain more specific information about which +exact option it concerns. +.IP "CURLE_TELNET_OPTION_SYNTAX (49)" +A telnet option string was Illegally formatted. +.IP "CURLE_PEER_FAILED_VERIFICATION (51)" +The remote server's SSL certificate or SSH md5 fingerprint was deemed not OK. +.IP "CURLE_GOT_NOTHING (52)" +Nothing was returned from the server, and under the circumstances, getting +nothing is considered an error. +.IP "CURLE_SSL_ENGINE_NOTFOUND (53)" +The specified crypto engine wasn't found. +.IP "CURLE_SSL_ENGINE_SETFAILED (54)" +Failed setting the selected SSL crypto engine as default! +.IP "CURLE_SEND_ERROR (55)" +Failed sending network data. +.IP "CURLE_RECV_ERROR (56)" +Failure with receiving network data. +.IP "CURLE_SSL_CERTPROBLEM (58)" +problem with the local client certificate. +.IP "CURLE_SSL_CIPHER (59)" +Couldn't use specified cipher. +.IP "CURLE_SSL_CACERT (60)" +Peer certificate cannot be authenticated with known CA certificates. +.IP "CURLE_BAD_CONTENT_ENCODING (61)" +Unrecognized transfer encoding. +.IP "CURLE_LDAP_INVALID_URL (62)" +Invalid LDAP URL. +.IP "CURLE_FILESIZE_EXCEEDED (63)" +Maximum file size exceeded. +.IP "CURLE_USE_SSL_FAILED (64)" +Requested FTP SSL level failed. +.IP "CURLE_SEND_FAIL_REWIND (65)" +When doing a send operation curl had to rewind the data to retransmit, but the +rewinding operation failed. +.IP "CURLE_SSL_ENGINE_INITFAILED (66)" +Initiating the SSL Engine failed. +.IP "CURLE_LOGIN_DENIED (67)" +The remote server denied curl to login (Added in 7.13.1) +.IP "CURLE_TFTP_NOTFOUND (68)" +File not found on TFTP server. +.IP "CURLE_TFTP_PERM (69)" +Permission problem on TFTP server. +.IP "CURLE_REMOTE_DISK_FULL (70)" +Out of disk space on the server. +.IP "CURLE_TFTP_ILLEGAL (71)" +Illegal TFTP operation. +.IP "CURLE_TFTP_UNKNOWNID (72)" +Unknown TFTP transfer ID. +.IP "CURLE_REMOTE_FILE_EXISTS (73)" +File already exists and will not be overwritten. +.IP "CURLE_TFTP_NOSUCHUSER (74)" +This error should never be returned by a properly functioning TFTP server. +.IP "CURLE_CONV_FAILED (75)" +Character conversion failed. +.IP "CURLE_CONV_REQD (76)" +Caller must register conversion callbacks. +.IP "CURLE_SSL_CACERT_BADFILE (77)" +Problem with reading the SSL CA cert (path? access rights?) +.IP "CURLE_REMOTE_FILE_NOT_FOUND (78)" +The resource referenced in the URL does not exist. +.IP "CURLE_SSH (79)" +An unspecified error occurred during the SSH session. +.IP "CURLE_SSL_SHUTDOWN_FAILED (80)" +Failed to shut down the SSL connection. +.IP "CURLE_AGAIN (81)" +Socket is not ready for send/recv wait till it's ready and try again. This +return code is only returned from \fIcurl_easy_recv(3)\fP and +\fIcurl_easy_send(3)\fP (Added in 7.18.2) +.IP "CURLE_SSL_CRL_BADFILE (82)" +Failed to load CRL file (Added in 7.19.0) +.IP "CURLE_SSL_ISSUER_ERROR (83)" +Issuer check failed (Added in 7.19.0) +.IP "CURLE_FTP_PRET_FAILED (84)" +The FTP server does not understand the PRET command at all or does not support +the given argument. Be careful when using \fICURLOPT_CUSTOMREQUEST\fP, a +custom LIST command will be sent with PRET CMD before PASV as well. (Added in +7.20.0) +.IP "CURLE_RTSP_CSEQ_ERROR (85)" +Mismatch of RTSP CSeq numbers. +.IP "CURLE_RTSP_SESSION_ERROR (86)" +Mismatch of RTSP Session Identifiers. +.IP "CURLE_FTP_BAD_FILE_LIST (87)" +Unable to parse FTP file list (during FTP wildcard downloading). +.IP "CURLE_CHUNK_FAILED (88)" +Chunk callback reported error. +.IP "CURLE_OBSOLETE*" +These error codes will never be returned. They were used in an old libcurl +version and are currently unused. +.SH "CURLMcode" +This is the generic return code used by functions in the libcurl multi +interface. Also consider \fIcurl_multi_strerror(3)\fP. +.IP "CURLM_CALL_MULTI_PERFORM (-1)" +This is not really an error. It means you should call +\fIcurl_multi_perform(3)\fP again without doing select() or similar in +between. Before version 7.20.0 this could be returned by +\fIcurl_multi_perform(3)\fP, but in later versions this return code is never +used. +.IP "CURLM_OK (0)" +Things are fine. +.IP "CURLM_BAD_HANDLE (1)" +The passed-in handle is not a valid CURLM handle. +.IP "CURLM_BAD_EASY_HANDLE (2)" +An easy handle was not good/valid. It could mean that it isn't an easy handle +at all, or possibly that the handle already is in used by this or another +multi handle. +.IP "CURLM_OUT_OF_MEMORY (3)" +You are doomed. +.IP "CURLM_INTERNAL_ERROR (4)" +This can only be returned if libcurl bugs. Please report it to us! +.IP "CURLM_BAD_SOCKET (5)" +The passed-in socket is not a valid one that libcurl already knows about. +(Added in 7.15.4) +.IP "CURLM_UNKNOWN_OPTION (6)" +curl_multi_setopt() with unsupported option +(Added in 7.15.4) +.SH "CURLSHcode" +The "share" interface will return a CURLSHcode to indicate when an error has +occurred. Also consider \fIcurl_share_strerror(3)\fP. +.IP "CURLSHE_OK (0)" +All fine. Proceed as usual. +.IP "CURLSHE_BAD_OPTION (1)" +An invalid option was passed to the function. +.IP "CURLSHE_IN_USE (2)" +The share object is currently in use. +.IP "CURLSHE_INVALID (3)" +An invalid share object was passed to the function. +.IP "CURLSHE_NOMEM (4)" +Not enough memory was available. +(Added in 7.12.0) +.IP "CURLSHE_NOT_BUILT_IN (5)" +The requested sharing could not be done because the library you use don't have +that particular feature enabled. (Added in 7.23.0) diff --git a/docs/libcurl/libcurl-multi.3 b/docs/libcurl/libcurl-multi.3 new file mode 100644 index 000000000..2af029961 --- /dev/null +++ b/docs/libcurl/libcurl-multi.3 @@ -0,0 +1,151 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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 libcurl-multi 3 "3 Feb 2007" "libcurl 7.16.0" "libcurl multi interface" +.SH NAME +libcurl-multi \- how to use the multi interface +.SH DESCRIPTION +This is an overview on how to use the libcurl multi interface in your C +programs. There are specific man pages for each function mentioned in +here. There's also the \fIlibcurl-tutorial(3)\fP man page for a complete +tutorial to programming with libcurl and the \fIlibcurl-easy(3)\fP man page +for an overview of the libcurl easy interface. + +All functions in the multi interface are prefixed with curl_multi. +.SH "OBJECTIVES" +The multi interface offers several abilities that the easy interface doesn't. +They are mainly: + +1. Enable a "pull" interface. The application that uses libcurl decides where +and when to ask libcurl to get/send data. + +2. Enable multiple simultaneous transfers in the same thread without making it +complicated for the application. + +3. Enable the application to wait for action on its own file descriptors and +curl's file descriptors simultaneous easily. +.SH "ONE MULTI HANDLE MANY EASY HANDLES" +To use the multi interface, you must first create a 'multi handle' with +\fIcurl_multi_init(3)\fP. This handle is then used as input to all further +curl_multi_* functions. + +Each single transfer is built up with an easy handle. You must create them, +and setup the appropriate options for each easy handle, as outlined in the +\fIlibcurl(3)\fP man page, using \fIcurl_easy_setopt(3)\fP. + +When the easy handle is setup for a transfer, then instead of using +\fIcurl_easy_perform(3)\fP (as when using the easy interface for transfers), +you should instead add the easy handle to the multi handle using +\fIcurl_multi_add_handle(3)\fP. The multi handle is sometimes referred to as a +\'multi stack\' because of the fact that it may hold a large amount of easy +handles. + +Should you change your mind, the easy handle is again removed from the multi +stack using \fIcurl_multi_remove_handle(3)\fP. Once removed from the multi +handle, you can again use other easy interface functions like +\fIcurl_easy_perform(3)\fP on the handle or whatever you think is necessary. + +Adding the easy handle to the multi handle does not start the transfer. +Remember that one of the main ideas with this interface is to let your +application drive. You drive the transfers by invoking +\fIcurl_multi_perform(3)\fP. libcurl will then transfer data if there is +anything available to transfer. It'll use the callbacks and everything else +you have setup in the individual easy handles. It'll transfer data on all +current transfers in the multi stack that are ready to transfer anything. It +may be all, it may be none. + +Your application can acquire knowledge from libcurl when it would like to get +invoked to transfer data, so that you don't have to busy-loop and call that +\fIcurl_multi_perform(3)\fP like crazy. \fIcurl_multi_fdset(3)\fP offers an +interface using which you can extract fd_sets from libcurl to use in select() +or poll() calls in order to get to know when the transfers in the multi stack +might need attention. This also makes it very easy for your program to wait +for input on your own private file descriptors at the same time or perhaps +timeout every now and then, should you want that. + +\fIcurl_multi_perform(3)\fP stores the number of still running transfers in +one of its input arguments, and by reading that you can figure out when all +the transfers in the multi handles are done. 'done' does not mean +successful. One or more of the transfers may have failed. Tracking when this +number changes, you know when one or more transfers are done. + +To get information about completed transfers, to figure out success or not and +similar, \fIcurl_multi_info_read(3)\fP should be called. It can return a +message about a current or previous transfer. Repeated invokes of the function +get more messages until the message queue is empty. The information you +receive there includes an easy handle pointer which you may use to identify +which easy handle the information regards. + +When a single transfer is completed, the easy handle is still left added to +the multi stack. You need to first remove the easy handle with +\fIcurl_multi_remove_handle(3)\fP and then close it with +\fIcurl_easy_cleanup(3)\fP, or possibly set new options to it and add it again +with \fIcurl_multi_add_handle(3)\fP to start another transfer. + +When all transfers in the multi stack are done, cleanup the multi handle with +\fIcurl_multi_cleanup(3)\fP. Be careful and please note that you \fBMUST\fP +invoke separate \fIcurl_easy_cleanup(3)\fP calls on every single easy handle +to clean them up properly. + +If you want to re-use an easy handle that was added to the multi handle for +transfer, you must first remove it from the multi stack and then re-add it +again (possibly after having altered some options at your own choice). +.SH "MULTI_SOCKET" +\fIcurl_multi_socket_action(3)\fP function offers a way for applications to +not only avoid being forced to use select(), but it also offers a much more +high-performance API that will make a significant difference for applications +using large numbers of simultaneous connections. + +\fIcurl_multi_socket_action(3)\fP is then used instead of +\fIcurl_multi_perform(3)\fP. + +When using this API, you add easy handles to the multi handle just as with the +normal multi interface. Then you also set two callbacks with the +CURLMOPT_SOCKETFUNCTION and CURLMOPT_TIMERFUNCTION options to +\fIcurl_multi_setopt(3)\fP. + +The API is then designed to inform your application about which sockets +libcurl is currently using and for what activities (read and/or write) on +those sockets your application is expected to wait for. + +Your application must then make sure to receive all sockets informed about in +the CURLMOPT_SOCKETFUNCTION callback and make sure it reacts on the given +activity on them. When a socket has the given activity, you call +\fIcurl_multi_socket_action(3)\fP specifying which socket and action there +are. + +The CURLMOPT_TIMERFUNCTION callback is called to set a timeout. When that +timeout expires, your application should call the +\fIcurl_multi_socket_action(3)\fP function saying it was due to a timeout. +.SH "BLOCKING" +A few areas in the code are still using blocking code, even when used from the +multi interface. While we certainly want and intend for these to get fixed in +the future, you should be aware of the following current restrictions: + +.nf + - Name resolves unless the c-ares or threaded-resolver backends are used + - NSS SSL connections + - HTTP proxy CONNECT operations + - SOCKS proxy handshakes + - file:// transfers + - TELNET transfers +.fi diff --git a/docs/libcurl/libcurl-share.3 b/docs/libcurl/libcurl-share.3 new file mode 100644 index 000000000..583902152 --- /dev/null +++ b/docs/libcurl/libcurl-share.3 @@ -0,0 +1,62 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2012, 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 libcurl-share 3 "8 Aug 2003" "libcurl 7.10.7" "libcurl share interface" +.SH NAME +libcurl-share \- how to use the share interface +.SH DESCRIPTION +This is an overview on how to use the libcurl share interface in your C +programs. There are specific man pages for each function mentioned in +here. + +All functions in the share interface are prefixed with curl_share. + +.SH "OBJECTIVES" +The share interface was added to enable sharing of data between curl +\&"handles". +.SH "ONE SET OF DATA - MANY TRANSFERS" +You can have multiple easy handles share data between them. Have them update +and use the \fBsame\fP cookie database or DNS cache! This way, each single +transfer will take advantage from data updates made by the other transfer(s). +.SH "SHARE OBJECT" +You create a shared object with \fIcurl_share_init(3)\fP. It returns a handle +for a newly created one. + +You tell the shared object what data you want it to share by using +\fIcurl_share_setopt(3)\fP. + +Since you can use this share from multiple threads, and libcurl has no +internal thread synchronization, you must provide mutex callbacks if you're +using this multi-threaded. You set lock and unlock functions with +\fIcurl_share_setopt(3)\fP too. + +Then, you make an easy handle to use this share, you set the +\fICURLOPT_SHARE\fP option with \fIcurl_easy_setopt(3)\fP, and pass in share +handle. You can make any number of easy handles share the same share handle. + +To make an easy handle stop using that particular share, you set +\fICURLOPT_SHARE\fP to NULL for that easy handle. To make a handle stop +sharing a particular data, you can \fICURLSHOPT_UNSHARE\fP it. + +When you're done using the share, make sure that no easy handle is still using +it, and call \fIcurl_share_cleanup(3)\fP on the handle. +.SH "SEE ALSO" +.BR curl_share_init "(3), " curl_share_setopt "(3), " curl_share_cleanup "(3)" diff --git a/docs/libcurl/libcurl-tutorial.3 b/docs/libcurl/libcurl-tutorial.3 new file mode 100644 index 000000000..1cca23f33 --- /dev/null +++ b/docs/libcurl/libcurl-tutorial.3 @@ -0,0 +1,1369 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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 libcurl-tutorial 3 "4 Mar 2009" "libcurl" "libcurl programming" +.SH NAME +libcurl-tutorial \- libcurl programming tutorial +.SH "Objective" +This document attempts to describe the general principles and some basic +approaches to consider when programming with libcurl. The text will focus +mainly on the C interface but might apply fairly well on other interfaces as +well as they usually follow the C one pretty closely. + +This document will refer to 'the user' as the person writing the source code +that uses libcurl. That would probably be you or someone in your position. +What will be generally referred to as 'the program' will be the collected +source code that you write that is using libcurl for transfers. The program +is outside libcurl and libcurl is outside of the program. + +To get more details on all options and functions described herein, please +refer to their respective man pages. + +.SH "Building" +There are many different ways to build C programs. This chapter will assume a +UNIX-style build process. If you use a different build system, you can still +read this to get general information that may apply to your environment as +well. +.IP "Compiling the Program" +Your compiler needs to know where the libcurl headers are located. Therefore +you must set your compiler's include path to point to the directory where you +installed them. The 'curl-config'[3] tool can be used to get this information: + +$ curl-config --cflags + +.IP "Linking the Program with libcurl" +When having compiled the program, you need to link your object files to create +a single executable. For that to succeed, you need to link with libcurl and +possibly also with other libraries that libcurl itself depends on. Like the +OpenSSL libraries, but even some standard OS libraries may be needed on the +command line. To figure out which flags to use, once again the 'curl-config' +tool comes to the rescue: + +$ curl-config --libs + +.IP "SSL or Not" +libcurl can be built and customized in many ways. One of the things that +varies from different libraries and builds is the support for SSL-based +transfers, like HTTPS and FTPS. If a supported SSL library was detected +properly at build-time, libcurl will be built with SSL support. To figure out +if an installed libcurl has been built with SSL support enabled, use +\&'curl-config' like this: + +$ curl-config --feature + +And if SSL is supported, the keyword 'SSL' will be written to stdout, +possibly together with a few other features that could be either on or off on +for different libcurls. + +See also the "Features libcurl Provides" further down. +.IP "autoconf macro" +When you write your configure script to detect libcurl and setup variables +accordingly, we offer a prewritten macro that probably does everything you +need in this area. See docs/libcurl/libcurl.m4 file - it includes docs on how +to use it. + +.SH "Portable Code in a Portable World" +The people behind libcurl have put a considerable effort to make libcurl work +on a large amount of different operating systems and environments. + +You program libcurl the same way on all platforms that libcurl runs on. There +are only very few minor considerations that differ. If you just make sure to +write your code portable enough, you may very well create yourself a very +portable program. libcurl shouldn't stop you from that. + +.SH "Global Preparation" +The program must initialize some of the libcurl functionality globally. That +means it should be done exactly once, no matter how many times you intend to +use the library. Once for your program's entire life time. This is done using + + curl_global_init() + +and it takes one parameter which is a bit pattern that tells libcurl what to +initialize. Using \fICURL_GLOBAL_ALL\fP will make it initialize all known +internal sub modules, and might be a good default option. The current two bits +that are specified are: +.RS +.IP "CURL_GLOBAL_WIN32" +which only does anything on Windows machines. When used on +a Windows machine, it'll make libcurl initialize the win32 socket +stuff. Without having that initialized properly, your program cannot use +sockets properly. You should only do this once for each application, so if +your program already does this or of another library in use does it, you +should not tell libcurl to do this as well. +.IP CURL_GLOBAL_SSL +which only does anything on libcurls compiled and built SSL-enabled. On these +systems, this will make libcurl initialize the SSL library properly for this +application. This only needs to be done once for each application so if your +program or another library already does this, this bit should not be needed. +.RE + +libcurl has a default protection mechanism that detects if +\fIcurl_global_init(3)\fP hasn't been called by the time +\fIcurl_easy_perform(3)\fP is called and if that is the case, libcurl runs the +function itself with a guessed bit pattern. Please note that depending solely +on this is not considered nice nor very good. + +When the program no longer uses libcurl, it should call +\fIcurl_global_cleanup(3)\fP, which is the opposite of the init call. It will +then do the reversed operations to cleanup the resources the +\fIcurl_global_init(3)\fP call initialized. + +Repeated calls to \fIcurl_global_init(3)\fP and \fIcurl_global_cleanup(3)\fP +should be avoided. They should only be called once each. + +.SH "Features libcurl Provides" +It is considered best-practice to determine libcurl features at run-time +rather than at build-time (if possible of course). By calling +\fIcurl_version_info(3)\fP and checking out the details of the returned +struct, your program can figure out exactly what the currently running libcurl +supports. + +.SH "Handle the Easy libcurl" +libcurl first introduced the so called easy interface. All operations in the +easy interface are prefixed with 'curl_easy'. + +Recent libcurl versions also offer the multi interface. More about that +interface, what it is targeted for and how to use it is detailed in a separate +chapter further down. You still need to understand the easy interface first, +so please continue reading for better understanding. + +To use the easy interface, you must first create yourself an easy handle. You +need one handle for each easy session you want to perform. Basically, you +should use one handle for every thread you plan to use for transferring. You +must never share the same handle in multiple threads. + +Get an easy handle with + + easyhandle = curl_easy_init(); + +It returns an easy handle. Using that you proceed to the next step: setting +up your preferred actions. A handle is just a logic entity for the upcoming +transfer or series of transfers. + +You set properties and options for this handle using +\fIcurl_easy_setopt(3)\fP. They control how the subsequent transfer or +transfers will be made. Options remain set in the handle until set again to +something different. Alas, multiple requests using the same handle will use +the same options. + +Many of the options you set in libcurl are "strings", pointers to data +terminated with a zero byte. When you set strings with +\fIcurl_easy_setopt(3)\fP, libcurl makes its own copy so that they don't +need to be kept around in your application after being set[4]. + +One of the most basic properties to set in the handle is the URL. You set +your preferred URL to transfer with CURLOPT_URL in a manner similar to: + +.nf + curl_easy_setopt(handle, CURLOPT_URL, "http://domain.com/"); +.fi + +Let's assume for a while that you want to receive data as the URL identifies a +remote resource you want to get here. Since you write a sort of application +that needs this transfer, I assume that you would like to get the data passed +to you directly instead of simply getting it passed to stdout. So, you write +your own function that matches this prototype: + + size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp); + +You tell libcurl to pass all data to this function by issuing a function +similar to this: + + curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, write_data); + +You can control what data your callback function gets in the fourth argument +by setting another property: + + curl_easy_setopt(easyhandle, CURLOPT_WRITEDATA, &internal_struct); + +Using that property, you can easily pass local data between your application +and the function that gets invoked by libcurl. libcurl itself won't touch the +data you pass with \fICURLOPT_WRITEDATA\fP. + +libcurl offers its own default internal callback that will take care of the data +if you don't set the callback with \fICURLOPT_WRITEFUNCTION\fP. It will then +simply output the received data to stdout. You can have the default callback +write the data to a different file handle by passing a 'FILE *' to a file +opened for writing with the \fICURLOPT_WRITEDATA\fP option. + +Now, we need to take a step back and have a deep breath. Here's one of those +rare platform-dependent nitpicks. Did you spot it? On some platforms[2], +libcurl won't be able to operate on files opened by the program. Thus, if you +use the default callback and pass in an open file with +\fICURLOPT_WRITEDATA\fP, it will crash. You should therefore avoid this to +make your program run fine virtually everywhere. + +(\fICURLOPT_WRITEDATA\fP was formerly known as \fICURLOPT_FILE\fP. Both names +still work and do the same thing). + +If you're using libcurl as a win32 DLL, you MUST use the +\fICURLOPT_WRITEFUNCTION\fP if you set \fICURLOPT_WRITEDATA\fP - or you will +experience crashes. + +There are of course many more options you can set, and we'll get back to a few +of them later. Let's instead continue to the actual transfer: + + success = curl_easy_perform(easyhandle); + +\fIcurl_easy_perform(3)\fP will connect to the remote site, do the necessary +commands and receive the transfer. Whenever it receives data, it calls the +callback function we previously set. The function may get one byte at a time, +or it may get many kilobytes at once. libcurl delivers as much as possible as +often as possible. Your callback function should return the number of bytes it +\&"took care of". If that is not the exact same amount of bytes that was +passed to it, libcurl will abort the operation and return with an error code. + +When the transfer is complete, the function returns a return code that informs +you if it succeeded in its mission or not. If a return code isn't enough for +you, you can use the CURLOPT_ERRORBUFFER to point libcurl to a buffer of yours +where it'll store a human readable error message as well. + +If you then want to transfer another file, the handle is ready to be used +again. Mind you, it is even preferred that you re-use an existing handle if +you intend to make another transfer. libcurl will then attempt to re-use the +previous connection. + +For some protocols, downloading a file can involve a complicated process of +logging in, setting the transfer mode, changing the current directory and +finally transferring the file data. libcurl takes care of all that +complication for you. Given simply the URL to a file, libcurl will take care +of all the details needed to get the file moved from one machine to another. + +.SH "Multi-threading Issues" +The first basic rule is that you must \fBnever\fP simultaneously share a +libcurl handle (be it easy or multi or whatever) between multiple +threads. Only use one handle in one thread at any time. You can pass the +handles around among threads, but you must never use a single handle from more +than one thread at any given time. + +libcurl is completely thread safe, except for two issues: signals and SSL/TLS +handlers. Signals are used for timing out name resolves (during DNS lookup) - +when built without c-ares support and not on Windows. + +If you are accessing HTTPS or FTPS URLs in a multi-threaded manner, you are +then of course using the underlying SSL library multi-threaded and those libs +might have their own requirements on this issue. Basically, you need to +provide one or two functions to allow it to function properly. For all +details, see this: + +OpenSSL + + http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION + +GnuTLS + + http://www.gnu.org/software/gnutls/manual/html_node/Multi_002dthreaded-applications.html + +NSS + + is claimed to be thread-safe already without anything required. + +PolarSSL + + Required actions unknown. + +yassl + + Required actions unknown. + +axTLS + + Required actions unknown. + +When using multiple threads you should set the CURLOPT_NOSIGNAL option to 1 +for all handles. Everything will or might work fine except that timeouts are +not honored during the DNS lookup - which you can work around by building +libcurl with c-ares support. c-ares is a library that provides asynchronous +name resolves. On some platforms, libcurl simply will not function properly +multi-threaded unless this option is set. + +Also, note that CURLOPT_DNS_USE_GLOBAL_CACHE is not thread-safe. + +.SH "When It Doesn't Work" +There will always be times when the transfer fails for some reason. You might +have set the wrong libcurl option or misunderstood what the libcurl option +actually does, or the remote server might return non-standard replies that +confuse the library which then confuses your program. + +There's one golden rule when these things occur: set the CURLOPT_VERBOSE +option to 1. It'll cause the library to spew out the entire protocol +details it sends, some internal info and some received protocol data as well +(especially when using FTP). If you're using HTTP, adding the headers in the +received output to study is also a clever way to get a better understanding +why the server behaves the way it does. Include headers in the normal body +output with CURLOPT_HEADER set 1. + +Of course, there are bugs left. We need to know about them to be able +to fix them, so we're quite dependent on your bug reports! When you do report +suspected bugs in libcurl, please include as many details as you possibly can: a +protocol dump that CURLOPT_VERBOSE produces, library version, as much as +possible of your code that uses libcurl, operating system name and version, +compiler name and version etc. + +If CURLOPT_VERBOSE is not enough, you increase the level of debug data your +application receive by using the CURLOPT_DEBUGFUNCTION. + +Getting some in-depth knowledge about the protocols involved is never wrong, +and if you're trying to do funny things, you might very well understand +libcurl and how to use it better if you study the appropriate RFC documents +at least briefly. + +.SH "Upload Data to a Remote Site" +libcurl tries to keep a protocol independent approach to most transfers, thus +uploading to a remote FTP site is very similar to uploading data to a HTTP +server with a PUT request. + +Of course, first you either create an easy handle or you re-use one existing +one. Then you set the URL to operate on just like before. This is the remote +URL, that we now will upload. + +Since we write an application, we most likely want libcurl to get the upload +data by asking us for it. To make it do that, we set the read callback and +the custom pointer libcurl will pass to our read callback. The read callback +should have a prototype similar to: + + size_t function(char *bufptr, size_t size, size_t nitems, void *userp); + +Where bufptr is the pointer to a buffer we fill in with data to upload and +size*nitems is the size of the buffer and therefore also the maximum amount +of data we can return to libcurl in this call. The 'userp' pointer is the +custom pointer we set to point to a struct of ours to pass private data +between the application and the callback. + + curl_easy_setopt(easyhandle, CURLOPT_READFUNCTION, read_function); + + curl_easy_setopt(easyhandle, CURLOPT_READDATA, &filedata); + +Tell libcurl that we want to upload: + + curl_easy_setopt(easyhandle, CURLOPT_UPLOAD, 1L); + +A few protocols won't behave properly when uploads are done without any prior +knowledge of the expected file size. So, set the upload file size using the +CURLOPT_INFILESIZE_LARGE for all known file sizes like this[1]: + +.nf + /* in this example, file_size must be an curl_off_t variable */ + curl_easy_setopt(easyhandle, CURLOPT_INFILESIZE_LARGE, file_size); +.fi + +When you call \fIcurl_easy_perform(3)\fP this time, it'll perform all the +necessary operations and when it has invoked the upload it'll call your +supplied callback to get the data to upload. The program should return as much +data as possible in every invoke, as that is likely to make the upload perform +as fast as possible. The callback should return the number of bytes it wrote +in the buffer. Returning 0 will signal the end of the upload. + +.SH "Passwords" +Many protocols use or even require that user name and password are provided +to be able to download or upload the data of your choice. libcurl offers +several ways to specify them. + +Most protocols support that you specify the name and password in the URL +itself. libcurl will detect this and use them accordingly. This is written +like this: + + protocol://user:password@example.com/path/ + +If you need any odd letters in your user name or password, you should enter +them URL encoded, as %XX where XX is a two-digit hexadecimal number. + +libcurl also provides options to set various passwords. The user name and +password as shown embedded in the URL can instead get set with the +CURLOPT_USERPWD option. The argument passed to libcurl should be a char * to +a string in the format "user:password". In a manner like this: + + curl_easy_setopt(easyhandle, CURLOPT_USERPWD, "myname:thesecret"); + +Another case where name and password might be needed at times, is for those +users who need to authenticate themselves to a proxy they use. libcurl offers +another option for this, the CURLOPT_PROXYUSERPWD. It is used quite similar +to the CURLOPT_USERPWD option like this: + + curl_easy_setopt(easyhandle, CURLOPT_PROXYUSERPWD, "myname:thesecret"); + +There's a long time UNIX "standard" way of storing ftp user names and +passwords, namely in the $HOME/.netrc file. The file should be made private +so that only the user may read it (see also the "Security Considerations" +chapter), as it might contain the password in plain text. libcurl has the +ability to use this file to figure out what set of user name and password to +use for a particular host. As an extension to the normal functionality, +libcurl also supports this file for non-FTP protocols such as HTTP. To make +curl use this file, use the CURLOPT_NETRC option: + + curl_easy_setopt(easyhandle, CURLOPT_NETRC, 1L); + +And a very basic example of how such a .netrc file may look like: + +.nf + machine myhost.mydomain.com + login userlogin + password secretword +.fi + +All these examples have been cases where the password has been optional, or +at least you could leave it out and have libcurl attempt to do its job +without it. There are times when the password isn't optional, like when +you're using an SSL private key for secure transfers. + +To pass the known private key password to libcurl: + + curl_easy_setopt(easyhandle, CURLOPT_KEYPASSWD, "keypassword"); + +.SH "HTTP Authentication" +The previous chapter showed how to set user name and password for getting +URLs that require authentication. When using the HTTP protocol, there are +many different ways a client can provide those credentials to the server and +you can control which way libcurl will (attempt to) use them. The default HTTP +authentication method is called 'Basic', which is sending the name and +password in clear-text in the HTTP request, base64-encoded. This is insecure. + +At the time of this writing, libcurl can be built to use: Basic, Digest, NTLM, +Negotiate, GSS-Negotiate and SPNEGO. You can tell libcurl which one to use +with CURLOPT_HTTPAUTH as in: + + curl_easy_setopt(easyhandle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); + +And when you send authentication to a proxy, you can also set authentication +type the same way but instead with CURLOPT_PROXYAUTH: + + curl_easy_setopt(easyhandle, CURLOPT_PROXYAUTH, CURLAUTH_NTLM); + +Both these options allow you to set multiple types (by ORing them together), +to make libcurl pick the most secure one out of the types the server/proxy +claims to support. This method does however add a round-trip since libcurl +must first ask the server what it supports: + + curl_easy_setopt(easyhandle, CURLOPT_HTTPAUTH, + CURLAUTH_DIGEST|CURLAUTH_BASIC); + +For convenience, you can use the 'CURLAUTH_ANY' define (instead of a list +with specific types) which allows libcurl to use whatever method it wants. + +When asking for multiple types, libcurl will pick the available one it +considers "best" in its own internal order of preference. + +.SH "HTTP POSTing" +We get many questions regarding how to issue HTTP POSTs with libcurl the +proper way. This chapter will thus include examples using both different +versions of HTTP POST that libcurl supports. + +The first version is the simple POST, the most common version, that most HTML +pages using the <form> tag uses. We provide a pointer to the data and tell +libcurl to post it all to the remote site: + +.nf + char *data="name=daniel&project=curl"; + curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDS, data); + curl_easy_setopt(easyhandle, CURLOPT_URL, "http://posthere.com/"); + + curl_easy_perform(easyhandle); /* post away! */ +.fi + +Simple enough, huh? Since you set the POST options with the +CURLOPT_POSTFIELDS, this automatically switches the handle to use POST in the +upcoming request. + +Ok, so what if you want to post binary data that also requires you to set the +Content-Type: header of the post? Well, binary posts prevent libcurl from +being able to do strlen() on the data to figure out the size, so therefore we +must tell libcurl the size of the post data. Setting headers in libcurl +requests are done in a generic way, by building a list of our own headers and +then passing that list to libcurl. + +.nf + struct curl_slist *headers=NULL; + headers = curl_slist_append(headers, "Content-Type: text/xml"); + + /* post binary data */ + curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDS, binaryptr); + + /* set the size of the postfields data */ + curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDSIZE, 23L); + + /* pass our list of custom made headers */ + curl_easy_setopt(easyhandle, CURLOPT_HTTPHEADER, headers); + + curl_easy_perform(easyhandle); /* post away! */ + + curl_slist_free_all(headers); /* free the header list */ +.fi + +While the simple examples above cover the majority of all cases where HTTP +POST operations are required, they don't do multi-part formposts. Multi-part +formposts were introduced as a better way to post (possibly large) binary data +and were first documented in the RFC1867 (updated in RFC2388). They're called +multi-part because they're built by a chain of parts, each part being a single +unit of data. Each part has its own name and contents. You can in fact create +and post a multi-part formpost with the regular libcurl POST support described +above, but that would require that you build a formpost yourself and provide +to libcurl. To make that easier, libcurl provides \fIcurl_formadd(3)\fP. Using +this function, you add parts to the form. When you're done adding parts, you +post the whole form. + +The following example sets two simple text parts with plain textual contents, +and then a file with binary contents and uploads the whole thing. + +.nf + struct curl_httppost *post=NULL; + struct curl_httppost *last=NULL; + curl_formadd(&post, &last, + CURLFORM_COPYNAME, "name", + CURLFORM_COPYCONTENTS, "daniel", CURLFORM_END); + curl_formadd(&post, &last, + CURLFORM_COPYNAME, "project", + CURLFORM_COPYCONTENTS, "curl", CURLFORM_END); + curl_formadd(&post, &last, + CURLFORM_COPYNAME, "logotype-image", + CURLFORM_FILECONTENT, "curl.png", CURLFORM_END); + + /* Set the form info */ + curl_easy_setopt(easyhandle, CURLOPT_HTTPPOST, post); + + curl_easy_perform(easyhandle); /* post away! */ + + /* free the post data again */ + curl_formfree(post); +.fi + +Multipart formposts are chains of parts using MIME-style separators and +headers. It means that each one of these separate parts get a few headers set +that describe the individual content-type, size etc. To enable your +application to handicraft this formpost even more, libcurl allows you to +supply your own set of custom headers to such an individual form part. You can +of course supply headers to as many parts as you like, but this little example +will show how you set headers to one specific part when you add that to the +post handle: + +.nf + struct curl_slist *headers=NULL; + headers = curl_slist_append(headers, "Content-Type: text/xml"); + + curl_formadd(&post, &last, + CURLFORM_COPYNAME, "logotype-image", + CURLFORM_FILECONTENT, "curl.xml", + CURLFORM_CONTENTHEADER, headers, + CURLFORM_END); + + curl_easy_perform(easyhandle); /* post away! */ + + curl_formfree(post); /* free post */ + curl_slist_free_all(headers); /* free custom header list */ +.fi + +Since all options on an easyhandle are "sticky", they remain the same until +changed even if you do call \fIcurl_easy_perform(3)\fP, you may need to tell +curl to go back to a plain GET request if you intend to do one as your +next request. You force an easyhandle to go back to GET by using the +CURLOPT_HTTPGET option: + + curl_easy_setopt(easyhandle, CURLOPT_HTTPGET, 1L); + +Just setting CURLOPT_POSTFIELDS to "" or NULL will *not* stop libcurl from +doing a POST. It will just make it POST without any data to send! + +.SH "Showing Progress" + +For historical and traditional reasons, libcurl has a built-in progress meter +that can be switched on and then makes it present a progress meter in your +terminal. + +Switch on the progress meter by, oddly enough, setting CURLOPT_NOPROGRESS to +zero. This option is set to 1 by default. + +For most applications however, the built-in progress meter is useless and +what instead is interesting is the ability to specify a progress +callback. The function pointer you pass to libcurl will then be called on +irregular intervals with information about the current transfer. + +Set the progress callback by using CURLOPT_PROGRESSFUNCTION. And pass a +pointer to a function that matches this prototype: + +.nf + int progress_callback(void *clientp, + double dltotal, + double dlnow, + double ultotal, + double ulnow); +.fi + +If any of the input arguments is unknown, a 0 will be passed. The first +argument, the 'clientp' is the pointer you pass to libcurl with +CURLOPT_PROGRESSDATA. libcurl won't touch it. + +.SH "libcurl with C++" + +There's basically only one thing to keep in mind when using C++ instead of C +when interfacing libcurl: + +The callbacks CANNOT be non-static class member functions + +Example C++ code: + +.nf +class AClass { + static size_t write_data(void *ptr, size_t size, size_t nmemb, + void *ourpointer) + { + /* do what you want with the data */ + } + } +.fi + +.SH "Proxies" + +What "proxy" means according to Merriam-Webster: "a person authorized to act +for another" but also "the agency, function, or office of a deputy who acts as +a substitute for another". + +Proxies are exceedingly common these days. Companies often only offer Internet +access to employees through their proxies. Network clients or user-agents ask +the proxy for documents, the proxy does the actual request and then it returns +them. + +libcurl supports SOCKS and HTTP proxies. When a given URL is wanted, libcurl +will ask the proxy for it instead of trying to connect to the actual host +identified in the URL. + +If you're using a SOCKS proxy, you may find that libcurl doesn't quite support +all operations through it. + +For HTTP proxies: the fact that the proxy is a HTTP proxy puts certain +restrictions on what can actually happen. A requested URL that might not be a +HTTP URL will be still be passed to the HTTP proxy to deliver back to +libcurl. This happens transparently, and an application may not need to +know. I say "may", because at times it is very important to understand that +all operations over a HTTP proxy use the HTTP protocol. For example, you +can't invoke your own custom FTP commands or even proper FTP directory +listings. + +.IP "Proxy Options" + +To tell libcurl to use a proxy at a given port number: + + curl_easy_setopt(easyhandle, CURLOPT_PROXY, "proxy-host.com:8080"); + +Some proxies require user authentication before allowing a request, and you +pass that information similar to this: + + curl_easy_setopt(easyhandle, CURLOPT_PROXYUSERPWD, "user:password"); + +If you want to, you can specify the host name only in the CURLOPT_PROXY +option, and set the port number separately with CURLOPT_PROXYPORT. + +Tell libcurl what kind of proxy it is with CURLOPT_PROXYTYPE (if not, it will +default to assume a HTTP proxy): + + curl_easy_setopt(easyhandle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4); + +.IP "Environment Variables" + +libcurl automatically checks and uses a set of environment variables to know +what proxies to use for certain protocols. The names of the variables are +following an ancient de facto standard and are built up as "[protocol]_proxy" +(note the lower casing). Which makes the variable \&'http_proxy' checked for a +name of a proxy to use when the input URL is HTTP. Following the same rule, +the variable named 'ftp_proxy' is checked for FTP URLs. Again, the proxies are +always HTTP proxies, the different names of the variables simply allows +different HTTP proxies to be used. + +The proxy environment variable contents should be in the format +\&"[protocol://][user:password@]machine[:port]". Where the protocol:// part is +simply ignored if present (so http://proxy and bluerk://proxy will do the +same) and the optional port number specifies on which port the proxy operates +on the host. If not specified, the internal default port number will be used +and that is most likely *not* the one you would like it to be. + +There are two special environment variables. 'all_proxy' is what sets proxy +for any URL in case the protocol specific variable wasn't set, and +\&'no_proxy' defines a list of hosts that should not use a proxy even though a +variable may say so. If 'no_proxy' is a plain asterisk ("*") it matches all +hosts. + +To explicitly disable libcurl's checking for and using the proxy environment +variables, set the proxy name to "" - an empty string - with CURLOPT_PROXY. +.IP "SSL and Proxies" + +SSL is for secure point-to-point connections. This involves strong encryption +and similar things, which effectively makes it impossible for a proxy to +operate as a "man in between" which the proxy's task is, as previously +discussed. Instead, the only way to have SSL work over a HTTP proxy is to ask +the proxy to tunnel trough everything without being able to check or fiddle +with the traffic. + +Opening an SSL connection over a HTTP proxy is therefor a matter of asking the +proxy for a straight connection to the target host on a specified port. This +is made with the HTTP request CONNECT. ("please mr proxy, connect me to that +remote host"). + +Because of the nature of this operation, where the proxy has no idea what kind +of data that is passed in and out through this tunnel, this breaks some of the +very few advantages that come from using a proxy, such as caching. Many +organizations prevent this kind of tunneling to other destination port numbers +than 443 (which is the default HTTPS port number). + +.IP "Tunneling Through Proxy" +As explained above, tunneling is required for SSL to work and often even +restricted to the operation intended for SSL; HTTPS. + +This is however not the only time proxy-tunneling might offer benefits to +you or your application. + +As tunneling opens a direct connection from your application to the remote +machine, it suddenly also re-introduces the ability to do non-HTTP +operations over a HTTP proxy. You can in fact use things such as FTP +upload or FTP custom commands this way. + +Again, this is often prevented by the administrators of proxies and is +rarely allowed. + +Tell libcurl to use proxy tunneling like this: + + curl_easy_setopt(easyhandle, CURLOPT_HTTPPROXYTUNNEL, 1L); + +In fact, there might even be times when you want to do plain HTTP +operations using a tunnel like this, as it then enables you to operate on +the remote server instead of asking the proxy to do so. libcurl will not +stand in the way for such innovative actions either! + +.IP "Proxy Auto-Config" + +Netscape first came up with this. It is basically a web page (usually using a +\&.pac extension) with a Javascript that when executed by the browser with the +requested URL as input, returns information to the browser on how to connect +to the URL. The returned information might be "DIRECT" (which means no proxy +should be used), "PROXY host:port" (to tell the browser where the proxy for +this particular URL is) or "SOCKS host:port" (to direct the browser to a SOCKS +proxy). + +libcurl has no means to interpret or evaluate Javascript and thus it doesn't +support this. If you get yourself in a position where you face this nasty +invention, the following advice have been mentioned and used in the past: + +- Depending on the Javascript complexity, write up a script that translates it +to another language and execute that. + +- Read the Javascript code and rewrite the same logic in another language. + +- Implement a Javascript interpreter; people have successfully used the +Mozilla Javascript engine in the past. + +- Ask your admins to stop this, for a static proxy setup or similar. + +.SH "Persistence Is The Way to Happiness" + +Re-cycling the same easy handle several times when doing multiple requests is +the way to go. + +After each single \fIcurl_easy_perform(3)\fP operation, libcurl will keep the +connection alive and open. A subsequent request using the same easy handle to +the same host might just be able to use the already open connection! This +reduces network impact a lot. + +Even if the connection is dropped, all connections involving SSL to the same +host again, will benefit from libcurl's session ID cache that drastically +reduces re-connection time. + +FTP connections that are kept alive save a lot of time, as the command- +response round-trips are skipped, and also you don't risk getting blocked +without permission to login again like on many FTP servers only allowing N +persons to be logged in at the same time. + +libcurl caches DNS name resolving results, to make lookups of a previously +looked up name a lot faster. + +Other interesting details that improve performance for subsequent requests +may also be added in the future. + +Each easy handle will attempt to keep the last few connections alive for a +while in case they are to be used again. You can set the size of this "cache" +with the CURLOPT_MAXCONNECTS option. Default is 5. There is very seldom any +point in changing this value, and if you think of changing this it is often +just a matter of thinking again. + +To force your upcoming request to not use an already existing connection (it +will even close one first if there happens to be one alive to the same host +you're about to operate on), you can do that by setting CURLOPT_FRESH_CONNECT +to 1. In a similar spirit, you can also forbid the upcoming request to be +"lying" around and possibly get re-used after the request by setting +CURLOPT_FORBID_REUSE to 1. + +.SH "HTTP Headers Used by libcurl" +When you use libcurl to do HTTP requests, it'll pass along a series of headers +automatically. It might be good for you to know and understand these. You +can replace or remove them by using the CURLOPT_HTTPHEADER option. + +.IP "Host" +This header is required by HTTP 1.1 and even many 1.0 servers and should be +the name of the server we want to talk to. This includes the port number if +anything but default. + +.IP "Accept" +\&"*/*". + +.IP "Expect" +When doing POST requests, libcurl sets this header to \&"100-continue" to ask +the server for an "OK" message before it proceeds with sending the data part +of the post. If the POSTed data amount is deemed "small", libcurl will not use +this header. + +.SH "Customizing Operations" +There is an ongoing development today where more and more protocols are built +upon HTTP for transport. This has obvious benefits as HTTP is a tested and +reliable protocol that is widely deployed and has excellent proxy-support. + +When you use one of these protocols, and even when doing other kinds of +programming you may need to change the traditional HTTP (or FTP or...) +manners. You may need to change words, headers or various data. + +libcurl is your friend here too. + +.IP CUSTOMREQUEST +If just changing the actual HTTP request keyword is what you want, like when +GET, HEAD or POST is not good enough for you, CURLOPT_CUSTOMREQUEST is there +for you. It is very simple to use: + + curl_easy_setopt(easyhandle, CURLOPT_CUSTOMREQUEST, "MYOWNREQUEST"); + +When using the custom request, you change the request keyword of the actual +request you are performing. Thus, by default you make a GET request but you can +also make a POST operation (as described before) and then replace the POST +keyword if you want to. You're the boss. + +.IP "Modify Headers" +HTTP-like protocols pass a series of headers to the server when doing the +request, and you're free to pass any amount of extra headers that you +think fit. Adding headers is this easy: + +.nf + struct curl_slist *headers=NULL; /* init to NULL is important */ + + headers = curl_slist_append(headers, "Hey-server-hey: how are you?"); + headers = curl_slist_append(headers, "X-silly-content: yes"); + + /* pass our list of custom made headers */ + curl_easy_setopt(easyhandle, CURLOPT_HTTPHEADER, headers); + + curl_easy_perform(easyhandle); /* transfer http */ + + curl_slist_free_all(headers); /* free the header list */ +.fi + +\&... and if you think some of the internally generated headers, such as +Accept: or Host: don't contain the data you want them to contain, you can +replace them by simply setting them too: + +.nf + headers = curl_slist_append(headers, "Accept: Agent-007"); + headers = curl_slist_append(headers, "Host: munged.host.line"); +.fi + +.IP "Delete Headers" +If you replace an existing header with one with no contents, you will prevent +the header from being sent. For instance, if you want to completely prevent the +\&"Accept:" header from being sent, you can disable it with code similar to this: + + headers = curl_slist_append(headers, "Accept:"); + +Both replacing and canceling internal headers should be done with careful +consideration and you should be aware that you may violate the HTTP protocol +when doing so. + +.IP "Enforcing chunked transfer-encoding" + +By making sure a request uses the custom header "Transfer-Encoding: chunked" +when doing a non-GET HTTP operation, libcurl will switch over to "chunked" +upload, even though the size of the data to upload might be known. By default, +libcurl usually switches over to chunked upload automatically if the upload +data size is unknown. + +.IP "HTTP Version" + +All HTTP requests includes the version number to tell the server which version +we support. libcurl speaks HTTP 1.1 by default. Some very old servers don't +like getting 1.1-requests and when dealing with stubborn old things like that, +you can tell libcurl to use 1.0 instead by doing something like this: + + curl_easy_setopt(easyhandle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); + +.IP "FTP Custom Commands" + +Not all protocols are HTTP-like, and thus the above may not help you when +you want to make, for example, your FTP transfers to behave differently. + +Sending custom commands to a FTP server means that you need to send the +commands exactly as the FTP server expects them (RFC959 is a good guide +here), and you can only use commands that work on the control-connection +alone. All kinds of commands that require data interchange and thus need +a data-connection must be left to libcurl's own judgement. Also be aware +that libcurl will do its very best to change directory to the target +directory before doing any transfer, so if you change directory (with CWD +or similar) you might confuse libcurl and then it might not attempt to +transfer the file in the correct remote directory. + +A little example that deletes a given file before an operation: + +.nf + headers = curl_slist_append(headers, "DELE file-to-remove"); + + /* pass the list of custom commands to the handle */ + curl_easy_setopt(easyhandle, CURLOPT_QUOTE, headers); + + curl_easy_perform(easyhandle); /* transfer ftp data! */ + + curl_slist_free_all(headers); /* free the header list */ +.fi + +If you would instead want this operation (or chain of operations) to happen +_after_ the data transfer took place the option to \fIcurl_easy_setopt(3)\fP +would instead be called CURLOPT_POSTQUOTE and used the exact same way. + +The custom FTP command will be issued to the server in the same order they are +added to the list, and if a command gets an error code returned back from the +server, no more commands will be issued and libcurl will bail out with an +error code (CURLE_QUOTE_ERROR). Note that if you use CURLOPT_QUOTE to send +commands before a transfer, no transfer will actually take place when a quote +command has failed. + +If you set the CURLOPT_HEADER to 1, you will tell libcurl to get +information about the target file and output "headers" about it. The headers +will be in "HTTP-style", looking like they do in HTTP. + +The option to enable headers or to run custom FTP commands may be useful to +combine with CURLOPT_NOBODY. If this option is set, no actual file content +transfer will be performed. + +.IP "FTP Custom CUSTOMREQUEST" +If you do want to list the contents of a FTP directory using your own defined FTP +command, CURLOPT_CUSTOMREQUEST will do just that. "NLST" is the default one +for listing directories but you're free to pass in your idea of a good +alternative. + +.SH "Cookies Without Chocolate Chips" +In the HTTP sense, a cookie is a name with an associated value. A server sends +the name and value to the client, and expects it to get sent back on every +subsequent request to the server that matches the particular conditions +set. The conditions include that the domain name and path match and that the +cookie hasn't become too old. + +In real-world cases, servers send new cookies to replace existing ones to +update them. Server use cookies to "track" users and to keep "sessions". + +Cookies are sent from server to clients with the header Set-Cookie: and +they're sent from clients to servers with the Cookie: header. + +To just send whatever cookie you want to a server, you can use CURLOPT_COOKIE +to set a cookie string like this: + + curl_easy_setopt(easyhandle, CURLOPT_COOKIE, "name1=var1; name2=var2;"); + +In many cases, that is not enough. You might want to dynamically save +whatever cookies the remote server passes to you, and make sure those cookies +are then used accordingly on later requests. + +One way to do this, is to save all headers you receive in a plain file and +when you make a request, you tell libcurl to read the previous headers to +figure out which cookies to use. Set the header file to read cookies from with +CURLOPT_COOKIEFILE. + +The CURLOPT_COOKIEFILE option also automatically enables the cookie parser in +libcurl. Until the cookie parser is enabled, libcurl will not parse or +understand incoming cookies and they will just be ignored. However, when the +parser is enabled the cookies will be understood and the cookies will be kept +in memory and used properly in subsequent requests when the same handle is +used. Many times this is enough, and you may not have to save the cookies to +disk at all. Note that the file you specify to CURLOPT_COOKIEFILE doesn't have +to exist to enable the parser, so a common way to just enable the parser and +not read any cookies is to use the name of a file you know doesn't exist. + +If you would rather use existing cookies that you've previously received with +your Netscape or Mozilla browsers, you can make libcurl use that cookie file +as input. The CURLOPT_COOKIEFILE is used for that too, as libcurl will +automatically find out what kind of file it is and act accordingly. + +Perhaps the most advanced cookie operation libcurl offers, is saving the +entire internal cookie state back into a Netscape/Mozilla formatted cookie +file. We call that the cookie-jar. When you set a file name with +CURLOPT_COOKIEJAR, that file name will be created and all received cookies +will be stored in it when \fIcurl_easy_cleanup(3)\fP is called. This enables +cookies to get passed on properly between multiple handles without any +information getting lost. + +.SH "FTP Peculiarities We Need" + +FTP transfers use a second TCP/IP connection for the data transfer. This is +usually a fact you can forget and ignore but at times this fact will come +back to haunt you. libcurl offers several different ways to customize how the +second connection is being made. + +libcurl can either connect to the server a second time or tell the server to +connect back to it. The first option is the default and it is also what works +best for all the people behind firewalls, NATs or IP-masquerading setups. +libcurl then tells the server to open up a new port and wait for a second +connection. This is by default attempted with EPSV first, and if that doesn't +work it tries PASV instead. (EPSV is an extension to the original FTP spec +and does not exist nor work on all FTP servers.) + +You can prevent libcurl from first trying the EPSV command by setting +CURLOPT_FTP_USE_EPSV to zero. + +In some cases, you will prefer to have the server connect back to you for the +second connection. This might be when the server is perhaps behind a firewall +or something and only allows connections on a single port. libcurl then +informs the remote server which IP address and port number to connect to. +This is made with the CURLOPT_FTPPORT option. If you set it to "-", libcurl +will use your system's "default IP address". If you want to use a particular +IP, you can set the full IP address, a host name to resolve to an IP address +or even a local network interface name that libcurl will get the IP address +from. + +When doing the "PORT" approach, libcurl will attempt to use the EPRT and the +LPRT before trying PORT, as they work with more protocols. You can disable +this behavior by setting CURLOPT_FTP_USE_EPRT to zero. + +.SH "Headers Equal Fun" + +Some protocols provide "headers", meta-data separated from the normal +data. These headers are by default not included in the normal data stream, +but you can make them appear in the data stream by setting CURLOPT_HEADER to +1. + +What might be even more useful, is libcurl's ability to separate the headers +from the data and thus make the callbacks differ. You can for example set a +different pointer to pass to the ordinary write callback by setting +CURLOPT_WRITEHEADER. + +Or, you can set an entirely separate function to receive the headers, by +using CURLOPT_HEADERFUNCTION. + +The headers are passed to the callback function one by one, and you can +depend on that fact. It makes it easier for you to add custom header parsers +etc. + +\&"Headers" for FTP transfers equal all the FTP server responses. They aren't +actually true headers, but in this case we pretend they are! ;-) + +.SH "Post Transfer Information" + + [ curl_easy_getinfo ] + +.SH "Security Considerations" + +The libcurl project takes security seriously. The library is written with +caution and precautions are taken to mitigate many kinds of risks encountered +while operating with potentially malicious servers on the Internet. It is a +powerful library, however, which allows application writers to make trade offs +between ease of writing and exposure to potential risky operations. If +used the right way, you can use libcurl to transfer data pretty safely. + +Many applications are used in closed networks where users and servers +can be trusted, but many others are used on arbitrary servers and are fed +input from potentially untrusted users. Following is a discussion about +some risks in the ways in which applications commonly use libcurl and +potential mitigations of those risks. It is by no means comprehensive, but +shows classes of attacks that robust applications should consider. The +Common Weakness Enumeration project at http://cwe.mitre.org/ is a good +reference for many of these and similar types of weaknesses of which +application writers should be aware. + +.IP "Command Lines" +If you use a command line tool (such as curl) that uses libcurl, and you give +options to the tool on the command line those options can very likely get read +by other users of your system when they use 'ps' or other tools to list +currently running processes. + +To avoid this problem, never feed sensitive things to programs using command +line options. Write them to a protected file and use the \-K option to +avoid this. + +.IP ".netrc" +\&.netrc is a pretty handy file/feature that allows you to login quickly and +automatically to frequently visited sites. The file contains passwords in +clear text and is a real security risk. In some cases, your .netrc is also +stored in a home directory that is NFS mounted or used on another network +based file system, so the clear text password will fly through your network +every time anyone reads that file! + +To avoid this problem, don't use .netrc files and never store passwords in +plain text anywhere. + +.IP "Clear Text Passwords" +Many of the protocols libcurl supports send name and password unencrypted as +clear text (HTTP Basic authentication, FTP, TELNET etc). It is very easy for +anyone on your network or a network nearby yours to just fire up a network +analyzer tool and eavesdrop on your passwords. Don't let the fact that HTTP +Basic uses base64 encoded passwords fool you. They may not look readable at a +first glance, but they very easily "deciphered" by anyone within seconds. + +To avoid this problem, use HTTP authentication methods or other protocols that +don't let snoopers see your password: HTTP with Digest, NTLM or GSS +authentication, HTTPS, FTPS, SCP, SFTP and FTP-Kerberos are a few examples. + +.IP "Redirects" +The CURLOPT_FOLLOWLOCATION option automatically follows HTTP redirects sent +by a remote server. These redirects can refer to any kind of URL, not just +HTTP. A redirect to a file: URL would cause the libcurl to read (or write) +arbitrary files from the local filesystem. If the application returns +the data back to the user (as would happen in some kinds of CGI scripts), +an attacker could leverage this to read otherwise forbidden data (e.g. +file://localhost/etc/passwd). + +If authentication credentials are stored in the ~/.netrc file, or Kerberos +is in use, any other URL type (not just file:) that requires +authentication is also at risk. A redirect such as +ftp://some-internal-server/private-file would then return data even when +the server is password protected. + +In the same way, if an unencrypted SSH private key has been configured for +the user running the libcurl application, SCP: or SFTP: URLs could access +password or private-key protected resources, +e.g. sftp://user@some-internal-server/etc/passwd + +The CURLOPT_REDIR_PROTOCOLS and CURLOPT_NETRC options can be used to +mitigate against this kind of attack. + +A redirect can also specify a location available only on the machine running +libcurl, including servers hidden behind a firewall from the attacker. +e.g. http://127.0.0.1/ or http://intranet/delete-stuff.cgi?delete=all or +tftp://bootp-server/pc-config-data + +Apps can mitigate against this by disabling CURLOPT_FOLLOWLOCATION and +handling redirects itself, sanitizing URLs as necessary. Alternately, an +app could leave CURLOPT_FOLLOWLOCATION enabled but set CURLOPT_REDIR_PROTOCOLS +and install a CURLOPT_OPENSOCKETFUNCTION callback function in which addresses +are sanitized before use. + +.IP "Private Resources" +A user who can control the DNS server of a domain being passed in within +a URL can change the address of the host to a local, private address +which the libcurl application will then use. e.g. The innocuous URL +http://fuzzybunnies.example.com/ could actually resolve to the IP address +of a server behind a firewall, such as 127.0.0.1 or 10.1.2.3 +Apps can mitigate against this by setting a CURLOPT_OPENSOCKETFUNCTION +and checking the address before a connection. + +All the malicious scenarios regarding redirected URLs apply just as well +to non-redirected URLs, if the user is allowed to specify an arbitrary URL +that could point to a private resource. For example, a web app providing +a translation service might happily translate file://localhost/etc/passwd +and display the result. Apps can mitigate against this with the +CURLOPT_PROTOCOLS option as well as by similar mitigation techniques for +redirections. + +A malicious FTP server could in response to the PASV command return an +IP address and port number for a server local to the app running libcurl +but behind a firewall. Apps can mitigate against this by using the +CURLOPT_FTP_SKIP_PASV_IP option or CURLOPT_FTPPORT. + +.IP Uploads +When uploading, a redirect can cause a local (or remote) file to be +overwritten. Apps must not allow any unsanitized URL to be passed in +for uploads. Also, CURLOPT_FOLLOWLOCATION should not be used on uploads. +Instead, the app should handle redirects itself, sanitizing each URL first. + +.IP Authentication +Use of CURLOPT_UNRESTRICTED_AUTH could cause authentication information to +be sent to an unknown second server. Apps can mitigate against this +by disabling CURLOPT_FOLLOWLOCATION and handling redirects itself, +sanitizing where necessary. + +Use of the CURLAUTH_ANY option to CURLOPT_HTTPAUTH could result in user +name and password being sent in clear text to an HTTP server. Instead, +use CURLAUTH_ANYSAFE which ensures that the password is encrypted over +the network, or else fail the request. + +Use of the CURLUSESSL_TRY option to CURLOPT_USE_SSL could result in user +name and password being sent in clear text to an FTP server. Instead, +use CURLUSESSL_CONTROL to ensure that an encrypted connection is used or +else fail the request. + +.IP Cookies +If cookies are enabled and cached, then a user could craft a URL which +performs some malicious action to a site whose authentication is already +stored in a cookie. e.g. http://mail.example.com/delete-stuff.cgi?delete=all +Apps can mitigate against this by disabling cookies or clearing them +between requests. + +.IP "Dangerous URLs" +SCP URLs can contain raw commands within the scp: URL, which is a side effect +of how the SCP protocol is designed. e.g. +scp://user:pass@host/a;date >/tmp/test; +Apps must not allow unsanitized SCP: URLs to be passed in for downloads. + +.IP "Denial of Service" +A malicious server could cause libcurl to effectively hang by sending +a trickle of data through, or even no data at all but just keeping the TCP +connection open. This could result in a denial-of-service attack. The +CURLOPT_TIMEOUT and/or CURLOPT_LOW_SPEED_LIMIT options can be used to +mitigate against this. + +A malicious server could cause libcurl to effectively hang by starting to +send data, then severing the connection without cleanly closing the +TCP connection. The app could install a CURLOPT_SOCKOPTFUNCTION callback +function and set the TCP SO_KEEPALIVE option to mitigate against this. +Setting one of the timeout options would also work against this attack. + +A malicious server could cause libcurl to download an infinite amount of +data, potentially causing all of memory or disk to be filled. Setting +the CURLOPT_MAXFILESIZE_LARGE option is not sufficient to guard against this. +Instead, the app should monitor the amount of data received within the +write or progress callback and abort once the limit is reached. + +A malicious HTTP server could cause an infinite redirection loop, causing a +denial-of-service. This can be mitigated by using the CURLOPT_MAXREDIRS +option. + +.IP "Arbitrary Headers" +User-supplied data must be sanitized when used in options like +CURLOPT_USERAGENT, CURLOPT_HTTPHEADER, CURLOPT_POSTFIELDS and others that +are used to generate structured data. Characters like embedded carriage +returns or ampersands could allow the user to create additional headers or +fields that could cause malicious transactions. + +.IP "Server-supplied Names" +A server can supply data which the application may, in some cases, use as +a file name. The curl command-line tool does this with --remote-header-name, +using the Content-disposition: header to generate a file name. An application +could also use CURLINFO_EFFECTIVE_URL to generate a file name from a +server-supplied redirect URL. Special care must be taken to sanitize such +names to avoid the possibility of a malicious server supplying one like +"/etc/passwd", "\autoexec.bat" or even ".bashrc". + +.IP "Server Certificates" +A secure application should never use the CURLOPT_SSL_VERIFYPEER option to +disable certificate validation. There are numerous attacks that are enabled +by apps that fail to properly validate server TLS/SSL certificates, +thus enabling a malicious server to spoof a legitimate one. HTTPS without +validated certificates is potentially as insecure as a plain HTTP connection. + +.IP "Showing What You Do" +On a related issue, be aware that even in situations like when you have +problems with libcurl and ask someone for help, everything you reveal in order +to get best possible help might also impose certain security related +risks. Host names, user names, paths, operating system specifics, etc (not to +mention passwords of course) may in fact be used by intruders to gain +additional information of a potential target. + +To avoid this problem, you must of course use your common sense. Often, you +can just edit out the sensitive data or just search/replace your true +information with faked data. + +.SH "Multiple Transfers Using the multi Interface" + +The easy interface as described in detail in this document is a synchronous +interface that transfers one file at a time and doesn't return until it is +done. + +The multi interface, on the other hand, allows your program to transfer +multiple files in both directions at the same time, without forcing you +to use multiple threads. The name might make it seem that the multi +interface is for multi-threaded programs, but the truth is almost the +reverse. The multi interface can allow a single-threaded application +to perform the same kinds of multiple, simultaneous transfers that +multi-threaded programs can perform. It allows many of the benefits +of multi-threaded transfers without the complexity of managing and +synchronizing many threads. + +To use this interface, you are better off if you first understand the basics +of how to use the easy interface. The multi interface is simply a way to make +multiple transfers at the same time by adding up multiple easy handles into +a "multi stack". + +You create the easy handles you want and you set all the options just like you +have been told above, and then you create a multi handle with +\fIcurl_multi_init(3)\fP and add all those easy handles to that multi handle +with \fIcurl_multi_add_handle(3)\fP. + +When you've added the handles you have for the moment (you can still add new +ones at any time), you start the transfers by calling +\fIcurl_multi_perform(3)\fP. + +\fIcurl_multi_perform(3)\fP is asynchronous. It will only execute as little as +possible and then return back control to your program. It is designed to never +block. + +The best usage of this interface is when you do a select() on all possible +file descriptors or sockets to know when to call libcurl again. This also +makes it easy for you to wait and respond to actions on your own application's +sockets/handles. You figure out what to select() for by using +\fIcurl_multi_fdset(3)\fP, that fills in a set of fd_set variables for you +with the particular file descriptors libcurl uses for the moment. + +When you then call select(), it'll return when one of the file handles signal +action and you then call \fIcurl_multi_perform(3)\fP to allow libcurl to do +what it wants to do. Take note that libcurl does also feature some time-out +code so we advise you to never use very long timeouts on select() before you +call \fIcurl_multi_perform(3)\fP, which thus should be called unconditionally +every now and then even if none of its file descriptors have signaled +ready. Another precaution you should use: always call +\fIcurl_multi_fdset(3)\fP immediately before the select() call since the +current set of file descriptors may change when calling a curl function. + +If you want to stop the transfer of one of the easy handles in the stack, you +can use \fIcurl_multi_remove_handle(3)\fP to remove individual easy +handles. Remember that easy handles should be \fIcurl_easy_cleanup(3)\fPed. + +When a transfer within the multi stack has finished, the counter of running +transfers (as filled in by \fIcurl_multi_perform(3)\fP) will decrease. When +the number reaches zero, all transfers are done. + +\fIcurl_multi_info_read(3)\fP can be used to get information about completed +transfers. It then returns the CURLcode for each easy transfer, to allow you +to figure out success on each individual transfer. + +.SH "SSL, Certificates and Other Tricks" + + [ seeding, passwords, keys, certificates, ENGINE, ca certs ] + +.SH "Sharing Data Between Easy Handles" +You can share some data between easy handles when the easy interface is used, +and some data is share automatically when you use the multi interface. + +When you add easy handles to a multi handle, these easy handles will +automatically share a lot of the data that otherwise would be kept on a +per-easy handle basis when the easy interface is used. + +The DNS cache is shared between handles within a multi handle, making +subsequent name resolvings faster and the connection pool that is kept to +better allow persistent connections and connection re-use is shared. If you're +using the easy interface, you can still share these between specific easy +handles by using the share interface, see \fIlibcurl-share(3)\fP. + +Some things are never shared automatically, not within multi handles, like for +example cookies so the only way to share that is with the share interface. +.SH "Footnotes" + +.IP "[1]" +libcurl 7.10.3 and later have the ability to switch over to chunked +Transfer-Encoding in cases where HTTP uploads are done with data of an unknown +size. +.IP "[2]" +This happens on Windows machines when libcurl is built and used as a +DLL. However, you can still do this on Windows if you link with a static +library. +.IP "[3]" +The curl-config tool is generated at build-time (on UNIX-like systems) and +should be installed with the 'make install' or similar instruction that +installs the library, header files, man pages etc. +.IP "[4]" +This behavior was different in versions before 7.17.0, where strings had to +remain valid past the end of the \fIcurl_easy_setopt(3)\fP call. diff --git a/docs/libcurl/libcurl.3 b/docs/libcurl/libcurl.3 new file mode 100644 index 000000000..d2dcd7838 --- /dev/null +++ b/docs/libcurl/libcurl.3 @@ -0,0 +1,222 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2011, 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 libcurl 3 "19 March 2002" "libcurl 7.9.6" "libcurl overview" +.SH NAME +libcurl \- client-side URL transfers +.SH DESCRIPTION +This is a short overview on how to use libcurl in your C programs. There are +specific man pages for each function mentioned in here. There are also the +\fIlibcurl-easy(3)\fP man page, the \fIlibcurl-multi(3)\fP man page, the +\fIlibcurl-share(3)\fP man page and the \fIlibcurl-tutorial(3)\fP man page for +in-depth understanding on how to program with libcurl. + +There are more than thirty custom bindings available that bring libcurl access +to your favourite language. Look elsewhere for documentation on those. + +libcurl has a global constant environment that you must set up and +maintain while using libcurl. This essentially means you call +\fIcurl_global_init(3)\fP at the start of your program and +\fIcurl_global_cleanup(3)\fP at the end. See GLOBAL CONSTANTS below +for details. + +To transfer files, you always set up an "easy handle" using +\fIcurl_easy_init(3)\fP, but when you want the file(s) transferred you have +the option of using the "easy" interface, or the "multi" interface. + +The easy interface is a synchronous interface with which you call +\fIcurl_easy_perform(3)\fP and let it perform the transfer. When it is +completed, the function returns and you can continue. More details are found in +the \fIlibcurl-easy(3)\fP man page. + +The multi interface on the other hand is an asynchronous interface, that you +call and that performs only a little piece of the transfer on each invoke. It +is perfect if you want to do things while the transfer is in progress, or +similar. The multi interface allows you to select() on libcurl action, and +even to easily download multiple files simultaneously using a single thread. See further details in the \fIlibcurl-multi(3)\fP man page. + +You can have multiple easy handles share certain data, even if they are used +in different threads. This magic is setup using the share interface, as +described in the \fIlibcurl-share(3)\fP man page. + +There is also a series of other helpful functions to use, including these: +.RS +.IP curl_version_info() +gets detailed libcurl (and other used libraries) version info +.IP curl_getdate() +converts a date string to time_t +.IP curl_easy_getinfo() +get information about a performed transfer +.IP curl_formadd() +helps building an HTTP form POST +.IP curl_formfree() +free a list built with \fIcurl_formadd(3)\fP +.IP curl_slist_append() +builds a linked list +.IP curl_slist_free_all() +frees a whole curl_slist +.RE + +.SH "LINKING WITH LIBCURL" +On unix-like machines, there's a tool named curl-config that gets installed +with the rest of the curl stuff when 'make install' is performed. + +curl-config is added to make it easier for applications to link with libcurl +and developers to learn about libcurl and how to use it. + +Run 'curl-config --libs' to get the (additional) linker options you need to +link with the particular version of libcurl you've installed. See the +\fIcurl-config(1)\fP man page for further details. + +Unix-like operating system that ship libcurl as part of their distributions +often don't provide the curl-config tool, but simply install the library and +headers in the common path for this purpose. + +.SH "LIBCURL SYMBOL NAMES" +All public functions in the libcurl interface are prefixed with 'curl_' (with +a lowercase c). You can find other functions in the library source code, but +other prefixes indicate that the functions are private and may change without +further notice in the next release. + +Only use documented functions and functionality! +.SH "PORTABILITY" +libcurl works +.B exactly +the same, on any of the platforms it compiles and builds on. +.SH "THREADS" +Never ever call curl-functions simultaneously using the same handle from +several threads. libcurl is thread-safe and can be used in any number of +threads, but you must use separate curl handles if you want to use libcurl in +more than one thread simultaneously. + +The global environment functions are not thread-safe. See GLOBAL CONSTANTS +below for details. + +.SH "PERSISTENT CONNECTIONS" +Persistent connections means that libcurl can re-use the same connection for +several transfers, if the conditions are right. + +libcurl will \fBalways\fP attempt to use persistent connections. Whenever you +use \fIcurl_easy_perform(3)\fP or \fIcurl_multi_perform(3)\fP, libcurl will +attempt to use an existing connection to do the transfer, and if none exists +it'll open a new one that will be subject for re-use on a possible following +call to \fIcurl_easy_perform(3)\fP or \fIcurl_multi_perform(3)\fP. + +To allow libcurl to take full advantage of persistent connections, you should +do as many of your file transfers as possible using the same curl handle. When +you call \fIcurl_easy_cleanup(3)\fP, all the possibly open connections held by +libcurl will be closed and forgotten. + +Note that the options set with \fIcurl_easy_setopt(3)\fP will be used on +every repeated \fIcurl_easy_perform(3)\fP call. + +.SH "GLOBAL CONSTANTS" +There are a variety of constants that libcurl uses, mainly through its +internal use of other libraries, which are too complicated for the +library loader to set up. Therefore, a program must call a library +function after the program is loaded and running to finish setting up +the library code. For example, when libcurl is built for SSL +capability via the GNU TLS library, there is an elaborate tree inside +that library that describes the SSL protocol. + +\fIcurl_global_init()\fP is the function that you must call. This may +allocate resources (e.g. the memory for the GNU TLS tree mentioned +above), so the companion function \fIcurl_global_cleanup()\fP releases +them. + +The basic rule for constructing a program that uses libcurl is this: +Call \fIcurl_global_init()\fP, with a \fICURL_GLOBAL_ALL\fP argument, +immediately after the program starts, while it is still only one +thread and before it uses libcurl at all. Call +\fIcurl_global_cleanup()\fP immediately before the program exits, when +the program is again only one thread and after its last use of +libcurl. + +You can call both of these multiple times, as long as all calls meet +these requirements and the number of calls to each is the same. + +It isn't actually required that the functions be called at the beginning +and end of the program -- that's just usually the easiest way to do it. +It \fIis\fP required that the functions be called when no other thread +in the program is running. + +These global constant functions are \fInot thread safe\fP, so you must +not call them when any other thread in the program is running. It +isn't good enough that no other thread is using libcurl at the time, +because these functions internally call similar functions of other +libraries, and those functions are similarly thread-unsafe. You can't +generally know what these libraries are, or whether other threads are +using them. + +The global constant situation merits special consideration when the +code you are writing to use libcurl is not the main program, but rather +a modular piece of a program, e.g. another library. As a module, +your code doesn't know about other parts of the program -- it doesn't +know whether they use libcurl or not. And its code doesn't necessarily +run at the start and end of the whole program. + +A module like this must have global constant functions of its own, +just like \fIcurl_global_init()\fP and \fIcurl_global_cleanup()\fP. +The module thus has control at the beginning and end of the program +and has a place to call the libcurl functions. Note that if multiple +modules in the program use libcurl, they all will separately call the +libcurl functions, and that's OK because only the first +\fIcurl_global_init()\fP and the last \fIcurl_global_cleanup()\fP in a +program change anything. (libcurl uses a reference count in static +memory). + +In a C++ module, it is common to deal with the global constant +situation by defining a special class that represents the global +constant environment of the module. A program always has exactly one +object of the class, in static storage. That way, the program +automatically calls the constructor of the object as the program +starts up and the destructor as it terminates. As the author of this +libcurl-using module, you can make the constructor call +\fIcurl_global_init()\fP and the destructor call +\fIcurl_global_cleanup()\fP and satisfy libcurl's requirements without +your user having to think about it. + +\fIcurl_global_init()\fP has an argument that tells what particular +parts of the global constant environment to set up. In order to +successfully use any value except \fICURL_GLOBAL_ALL\fP (which says to +set up the whole thing), you must have specific knowledge of internal +workings of libcurl and all other parts of the program of which it is +part. + +A special part of the global constant environment is the identity of +the memory allocator. \fIcurl_global_init()\fP selects the system +default memory allocator, but you can use \fIcurl_global_init_mem()\fP +to supply one of your own. However, there is no way to use +\fIcurl_global_init_mem()\fP in a modular program -- all modules in +the program that might use libcurl would have to agree on one +allocator. + +There is a failsafe in libcurl that makes it usable in simple +situations without you having to worry about the global constant +environment at all: \fIcurl_easy_init()\fP sets up the environment +itself if it hasn't been done yet. The resources it acquires to do so +get released by the operating system automatically when the program +exits. + +This failsafe feature exists mainly for backward compatibility because +there was a time when the global functions didn't exist. Because it +is sufficient only in the simplest of programs, it is not recommended +for any program to rely on it. diff --git a/docs/libcurl/libcurl.m4 b/docs/libcurl/libcurl.m4 new file mode 100644 index 000000000..d7d5a5259 --- /dev/null +++ b/docs/libcurl/libcurl.m4 @@ -0,0 +1,251 @@ +# LIBCURL_CHECK_CONFIG ([DEFAULT-ACTION], [MINIMUM-VERSION], +# [ACTION-IF-YES], [ACTION-IF-NO]) +# ---------------------------------------------------------- +# David Shaw <dshaw@jabberwocky.com> May-09-2006 +# +# Checks for libcurl. DEFAULT-ACTION is the string yes or no to +# specify whether to default to --with-libcurl or --without-libcurl. +# If not supplied, DEFAULT-ACTION is yes. MINIMUM-VERSION is the +# minimum version of libcurl to accept. Pass the version as a regular +# version number like 7.10.1. If not supplied, any version is +# accepted. ACTION-IF-YES is a list of shell commands to run if +# libcurl was successfully found and passed the various tests. +# ACTION-IF-NO is a list of shell commands that are run otherwise. +# Note that using --without-libcurl does run ACTION-IF-NO. +# +# This macro #defines HAVE_LIBCURL if a working libcurl setup is +# found, and sets @LIBCURL@ and @LIBCURL_CPPFLAGS@ to the necessary +# values. Other useful defines are LIBCURL_FEATURE_xxx where xxx are +# the various features supported by libcurl, and LIBCURL_PROTOCOL_yyy +# where yyy are the various protocols supported by libcurl. Both xxx +# and yyy are capitalized. See the list of AH_TEMPLATEs at the top of +# the macro for the complete list of possible defines. Shell +# variables $libcurl_feature_xxx and $libcurl_protocol_yyy are also +# defined to 'yes' for those features and protocols that were found. +# Note that xxx and yyy keep the same capitalization as in the +# curl-config list (e.g. it's "HTTP" and not "http"). +# +# Users may override the detected values by doing something like: +# LIBCURL="-lcurl" LIBCURL_CPPFLAGS="-I/usr/myinclude" ./configure +# +# For the sake of sanity, this macro assumes that any libcurl that is +# found is after version 7.7.2, the first version that included the +# curl-config script. Note that it is very important for people +# packaging binary versions of libcurl to include this script! +# Without curl-config, we can only guess what protocols are available, +# or use curl_version_info to figure it out at runtime. + +AC_DEFUN([LIBCURL_CHECK_CONFIG], +[ + AH_TEMPLATE([LIBCURL_FEATURE_SSL],[Defined if libcurl supports SSL]) + AH_TEMPLATE([LIBCURL_FEATURE_KRB4],[Defined if libcurl supports KRB4]) + AH_TEMPLATE([LIBCURL_FEATURE_IPV6],[Defined if libcurl supports IPv6]) + AH_TEMPLATE([LIBCURL_FEATURE_LIBZ],[Defined if libcurl supports libz]) + AH_TEMPLATE([LIBCURL_FEATURE_ASYNCHDNS],[Defined if libcurl supports AsynchDNS]) + AH_TEMPLATE([LIBCURL_FEATURE_IDN],[Defined if libcurl supports IDN]) + AH_TEMPLATE([LIBCURL_FEATURE_SSPI],[Defined if libcurl supports SSPI]) + AH_TEMPLATE([LIBCURL_FEATURE_NTLM],[Defined if libcurl supports NTLM]) + + AH_TEMPLATE([LIBCURL_PROTOCOL_HTTP],[Defined if libcurl supports HTTP]) + AH_TEMPLATE([LIBCURL_PROTOCOL_HTTPS],[Defined if libcurl supports HTTPS]) + AH_TEMPLATE([LIBCURL_PROTOCOL_FTP],[Defined if libcurl supports FTP]) + AH_TEMPLATE([LIBCURL_PROTOCOL_FTPS],[Defined if libcurl supports FTPS]) + AH_TEMPLATE([LIBCURL_PROTOCOL_FILE],[Defined if libcurl supports FILE]) + AH_TEMPLATE([LIBCURL_PROTOCOL_TELNET],[Defined if libcurl supports TELNET]) + AH_TEMPLATE([LIBCURL_PROTOCOL_LDAP],[Defined if libcurl supports LDAP]) + AH_TEMPLATE([LIBCURL_PROTOCOL_DICT],[Defined if libcurl supports DICT]) + AH_TEMPLATE([LIBCURL_PROTOCOL_TFTP],[Defined if libcurl supports TFTP]) + AH_TEMPLATE([LIBCURL_PROTOCOL_RTSP],[Defined if libcurl supports RTSP]) + AH_TEMPLATE([LIBCURL_PROTOCOL_POP3],[Defined if libcurl supports POP3]) + AH_TEMPLATE([LIBCURL_PROTOCOL_IMAP],[Defined if libcurl supports IMAP]) + AH_TEMPLATE([LIBCURL_PROTOCOL_SMTP],[Defined if libcurl supports SMTP]) + + AC_ARG_WITH(libcurl, + AC_HELP_STRING([--with-libcurl=PREFIX],[look for the curl library in PREFIX/lib and headers in PREFIX/include]), + [_libcurl_with=$withval],[_libcurl_with=ifelse([$1],,[yes],[$1])]) + + if test "$_libcurl_with" != "no" ; then + + AC_PROG_AWK + + _libcurl_version_parse="eval $AWK '{split(\$NF,A,\".\"); X=256*256*A[[1]]+256*A[[2]]+A[[3]]; print X;}'" + + _libcurl_try_link=yes + + if test -d "$_libcurl_with" ; then + LIBCURL_CPPFLAGS="-I$withval/include" + _libcurl_ldflags="-L$withval/lib" + AC_PATH_PROG([_libcurl_config],[curl-config],[], + ["$withval/bin"]) + else + AC_PATH_PROG([_libcurl_config],[curl-config],[],[$PATH]) + fi + + if test x$_libcurl_config != "x" ; then + AC_CACHE_CHECK([for the version of libcurl], + [libcurl_cv_lib_curl_version], + [libcurl_cv_lib_curl_version=`$_libcurl_config --version | $AWK '{print $[]2}'`]) + + _libcurl_version=`echo $libcurl_cv_lib_curl_version | $_libcurl_version_parse` + _libcurl_wanted=`echo ifelse([$2],,[0],[$2]) | $_libcurl_version_parse` + + if test $_libcurl_wanted -gt 0 ; then + AC_CACHE_CHECK([for libcurl >= version $2], + [libcurl_cv_lib_version_ok], + [ + if test $_libcurl_version -ge $_libcurl_wanted ; then + libcurl_cv_lib_version_ok=yes + else + libcurl_cv_lib_version_ok=no + fi + ]) + fi + + if test $_libcurl_wanted -eq 0 || test x$libcurl_cv_lib_version_ok = xyes ; then + if test x"$LIBCURL_CPPFLAGS" = "x" ; then + LIBCURL_CPPFLAGS=`$_libcurl_config --cflags` + fi + if test x"$LIBCURL" = "x" ; then + LIBCURL=`$_libcurl_config --libs` + + # This is so silly, but Apple actually has a bug in their + # curl-config script. Fixed in Tiger, but there are still + # lots of Panther installs around. + case "${host}" in + powerpc-apple-darwin7*) + LIBCURL=`echo $LIBCURL | sed -e 's|-arch i386||g'` + ;; + esac + fi + + # All curl-config scripts support --feature + _libcurl_features=`$_libcurl_config --feature` + + # Is it modern enough to have --protocols? (7.12.4) + if test $_libcurl_version -ge 461828 ; then + _libcurl_protocols=`$_libcurl_config --protocols` + fi + else + _libcurl_try_link=no + fi + + unset _libcurl_wanted + fi + + if test $_libcurl_try_link = yes ; then + + # we didn't find curl-config, so let's see if the user-supplied + # link line (or failing that, "-lcurl") is enough. + LIBCURL=${LIBCURL-"$_libcurl_ldflags -lcurl"} + + AC_CACHE_CHECK([whether libcurl is usable], + [libcurl_cv_lib_curl_usable], + [ + _libcurl_save_cppflags=$CPPFLAGS + CPPFLAGS="$LIBCURL_CPPFLAGS $CPPFLAGS" + _libcurl_save_libs=$LIBS + LIBS="$LIBCURL $LIBS" + + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <curl/curl.h>]],[[ +/* Try and use a few common options to force a failure if we are + missing symbols or can't link. */ +int x; +curl_easy_setopt(NULL,CURLOPT_URL,NULL); +x=CURL_ERROR_SIZE; +x=CURLOPT_WRITEFUNCTION; +x=CURLOPT_FILE; +x=CURLOPT_ERRORBUFFER; +x=CURLOPT_STDERR; +x=CURLOPT_VERBOSE; +if (x) ; +]])],libcurl_cv_lib_curl_usable=yes,libcurl_cv_lib_curl_usable=no) + + CPPFLAGS=$_libcurl_save_cppflags + LIBS=$_libcurl_save_libs + unset _libcurl_save_cppflags + unset _libcurl_save_libs + ]) + + if test $libcurl_cv_lib_curl_usable = yes ; then + + # Does curl_free() exist in this version of libcurl? + # If not, fake it with free() + + _libcurl_save_cppflags=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $LIBCURL_CPPFLAGS" + _libcurl_save_libs=$LIBS + LIBS="$LIBS $LIBCURL" + + AC_CHECK_FUNC(curl_free,, + AC_DEFINE(curl_free,free, + [Define curl_free() as free() if our version of curl lacks curl_free.])) + + CPPFLAGS=$_libcurl_save_cppflags + LIBS=$_libcurl_save_libs + unset _libcurl_save_cppflags + unset _libcurl_save_libs + + AC_DEFINE(HAVE_LIBCURL,1, + [Define to 1 if you have a functional curl library.]) + AC_SUBST(LIBCURL_CPPFLAGS) + AC_SUBST(LIBCURL) + + for _libcurl_feature in $_libcurl_features ; do + AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_feature_$_libcurl_feature),[1]) + eval AS_TR_SH(libcurl_feature_$_libcurl_feature)=yes + done + + if test "x$_libcurl_protocols" = "x" ; then + + # We don't have --protocols, so just assume that all + # protocols are available + _libcurl_protocols="HTTP FTP FILE TELNET LDAP DICT TFTP" + + if test x$libcurl_feature_SSL = xyes ; then + _libcurl_protocols="$_libcurl_protocols HTTPS" + + # FTPS wasn't standards-compliant until version + # 7.11.0 (0x070b00 == 461568) + if test $_libcurl_version -ge 461568; then + _libcurl_protocols="$_libcurl_protocols FTPS" + fi + fi + + # RTSP, IMAP, POP3 and SMTP were added in + # 7.20.0 (0x071400 == 463872) + if test $_libcurl_version -ge 463872; then + _libcurl_protocols="$_libcurl_protocols RTSP IMAP POP3 SMTP" + fi + fi + + for _libcurl_protocol in $_libcurl_protocols ; do + AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_protocol_$_libcurl_protocol),[1]) + eval AS_TR_SH(libcurl_protocol_$_libcurl_protocol)=yes + done + else + unset LIBCURL + unset LIBCURL_CPPFLAGS + fi + fi + + unset _libcurl_try_link + unset _libcurl_version_parse + unset _libcurl_config + unset _libcurl_feature + unset _libcurl_features + unset _libcurl_protocol + unset _libcurl_protocols + unset _libcurl_version + unset _libcurl_ldflags + fi + + if test x$_libcurl_with = xno || test x$libcurl_cv_lib_curl_usable != xyes ; then + # This is the IF-NO path + ifelse([$4],,:,[$4]) + else + # This is the IF-YES path + ifelse([$3],,:,[$3]) + fi + + unset _libcurl_with +])dnl diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions new file mode 100644 index 000000000..1de1aceb7 --- /dev/null +++ b/docs/libcurl/symbols-in-versions @@ -0,0 +1,705 @@ + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + + This document lists defines and other symbols present in libcurl, together + with exact information about the first libcurl version that provides the + symbol, the first version in which the symbol was marked as deprecated and + for a few symbols the last version that featured it. The names appear in + alphabetical order. + + Name Introduced Deprecated Removed + +CURLAUTH_ANY 7.10.6 +CURLAUTH_ANYSAFE 7.10.6 +CURLAUTH_BASIC 7.10.6 +CURLAUTH_DIGEST 7.10.6 +CURLAUTH_DIGEST_IE 7.19.3 +CURLAUTH_GSSNEGOTIATE 7.10.6 +CURLAUTH_NONE 7.10.6 +CURLAUTH_NTLM 7.10.6 +CURLAUTH_NTLM_WB 7.22.0 +CURLAUTH_ONLY 7.21.3 +CURLCLOSEPOLICY_CALLBACK 7.7 +CURLCLOSEPOLICY_LEAST_RECENTLY_USED 7.7 +CURLCLOSEPOLICY_LEAST_TRAFFIC 7.7 +CURLCLOSEPOLICY_NONE 7.7 +CURLCLOSEPOLICY_OLDEST 7.7 +CURLCLOSEPOLICY_SLOWEST 7.7 +CURLE_ABORTED_BY_CALLBACK 7.1 +CURLE_AGAIN 7.18.2 +CURLE_ALREADY_COMPLETE 7.7.2 +CURLE_BAD_CALLING_ORDER 7.1 7.17.0 +CURLE_BAD_CONTENT_ENCODING 7.10 +CURLE_BAD_DOWNLOAD_RESUME 7.10 +CURLE_BAD_FUNCTION_ARGUMENT 7.1 +CURLE_BAD_PASSWORD_ENTERED 7.4.2 7.17.0 +CURLE_CHUNK_FAILED 7.21.0 +CURLE_CONV_FAILED 7.15.4 +CURLE_CONV_REQD 7.15.4 +CURLE_COULDNT_CONNECT 7.1 +CURLE_COULDNT_RESOLVE_HOST 7.1 +CURLE_COULDNT_RESOLVE_PROXY 7.1 +CURLE_FAILED_INIT 7.1 +CURLE_FILESIZE_EXCEEDED 7.10.8 +CURLE_FILE_COULDNT_READ_FILE 7.1 +CURLE_FTP_ACCEPT_FAILED 7.24.0 +CURLE_FTP_ACCEPT_TIMEOUT 7.24.0 +CURLE_FTP_ACCESS_DENIED 7.1 +CURLE_FTP_BAD_DOWNLOAD_RESUME 7.1 7.1 +CURLE_FTP_BAD_FILE_LIST 7.21.0 +CURLE_FTP_CANT_GET_HOST 7.1 +CURLE_FTP_CANT_RECONNECT 7.1 7.17.0 +CURLE_FTP_COULDNT_GET_SIZE 7.1 7.17.0 +CURLE_FTP_COULDNT_RETR_FILE 7.1 +CURLE_FTP_COULDNT_SET_ASCII 7.1 7.17.0 +CURLE_FTP_COULDNT_SET_BINARY 7.1 7.17.0 +CURLE_FTP_COULDNT_SET_TYPE 7.17.0 +CURLE_FTP_COULDNT_STOR_FILE 7.1 +CURLE_FTP_COULDNT_USE_REST 7.1 +CURLE_FTP_PARTIAL_FILE 7.1 7.1 +CURLE_FTP_PORT_FAILED 7.1 +CURLE_FTP_PRET_FAILED 7.20.0 +CURLE_FTP_QUOTE_ERROR 7.1 7.17.0 +CURLE_FTP_SSL_FAILED 7.11.0 7.17.0 +CURLE_FTP_USER_PASSWORD_INCORRECT 7.1 7.17.0 +CURLE_FTP_WEIRD_227_FORMAT 7.1 +CURLE_FTP_WEIRD_PASS_REPLY 7.1 +CURLE_FTP_WEIRD_PASV_REPLY 7.1 +CURLE_FTP_WEIRD_SERVER_REPLY 7.1 +CURLE_FTP_WEIRD_USER_REPLY 7.1 7.17.0 +CURLE_FTP_WRITE_ERROR 7.1 7.17.0 +CURLE_FUNCTION_NOT_FOUND 7.1 +CURLE_GOT_NOTHING 7.9.1 +CURLE_HTTP_NOT_FOUND 7.1 +CURLE_HTTP_PORT_FAILED 7.3 7.12.0 +CURLE_HTTP_POST_ERROR 7.1 +CURLE_HTTP_RANGE_ERROR 7.1 7.17.0 +CURLE_HTTP_RETURNED_ERROR 7.10.3 +CURLE_INTERFACE_FAILED 7.12.0 +CURLE_LDAP_CANNOT_BIND 7.1 +CURLE_LDAP_INVALID_URL 7.10.8 +CURLE_LDAP_SEARCH_FAILED 7.1 +CURLE_LIBRARY_NOT_FOUND 7.1 7.17.0 +CURLE_LOGIN_DENIED 7.13.1 +CURLE_MALFORMAT_USER 7.1 7.17.0 +CURLE_NOT_BUILT_IN 7.21.5 +CURLE_OK 7.1 +CURLE_OPERATION_TIMEDOUT 7.10.2 +CURLE_OPERATION_TIMEOUTED 7.1 7.17.0 +CURLE_OUT_OF_MEMORY 7.1 +CURLE_PARTIAL_FILE 7.1 +CURLE_PEER_FAILED_VERIFICATION 7.17.1 +CURLE_QUOTE_ERROR 7.17.0 +CURLE_RANGE_ERROR 7.17.0 +CURLE_READ_ERROR 7.1 +CURLE_RECV_ERROR 7.10 +CURLE_REMOTE_ACCESS_DENIED 7.17.0 +CURLE_REMOTE_DISK_FULL 7.17.0 +CURLE_REMOTE_FILE_EXISTS 7.17.0 +CURLE_REMOTE_FILE_NOT_FOUND 7.16.1 +CURLE_RTSP_CSEQ_ERROR 7.20.0 +CURLE_RTSP_SESSION_ERROR 7.20.0 +CURLE_SEND_ERROR 7.10 +CURLE_SEND_FAIL_REWIND 7.12.3 +CURLE_SHARE_IN_USE 7.9.6 7.17.0 +CURLE_SSH 7.16.1 +CURLE_SSL_CACERT 7.10 +CURLE_SSL_CACERT_BADFILE 7.16.0 +CURLE_SSL_CERTPROBLEM 7.10 +CURLE_SSL_CIPHER 7.10 +CURLE_SSL_CONNECT_ERROR 7.1 +CURLE_SSL_CRL_BADFILE 7.19.0 +CURLE_SSL_ENGINE_INITFAILED 7.12.3 +CURLE_SSL_ENGINE_NOTFOUND 7.9.3 +CURLE_SSL_ENGINE_SETFAILED 7.9.3 +CURLE_SSL_ISSUER_ERROR 7.19.0 +CURLE_SSL_PEER_CERTIFICATE 7.8 7.17.1 +CURLE_SSL_SHUTDOWN_FAILED 7.16.1 +CURLE_TELNET_OPTION_SYNTAX 7.7 +CURLE_TFTP_DISKFULL 7.15.0 7.17.0 +CURLE_TFTP_EXISTS 7.15.0 7.17.0 +CURLE_TFTP_ILLEGAL 7.15.0 +CURLE_TFTP_NOSUCHUSER 7.15.0 +CURLE_TFTP_NOTFOUND 7.15.0 +CURLE_TFTP_PERM 7.15.0 +CURLE_TFTP_UNKNOWNID 7.15.0 +CURLE_TOO_MANY_REDIRECTS 7.5 +CURLE_UNKNOWN_OPTION 7.21.5 +CURLE_UNKNOWN_TELNET_OPTION 7.7 +CURLE_UNSUPPORTED_PROTOCOL 7.1 +CURLE_UPLOAD_FAILED 7.16.3 +CURLE_URL_MALFORMAT 7.1 +CURLE_URL_MALFORMAT_USER 7.1 7.17.0 +CURLE_USE_SSL_FAILED 7.17.0 +CURLE_WRITE_ERROR 7.1 +CURLFILETYPE_DEVICE_BLOCK 7.21.0 +CURLFILETYPE_DEVICE_CHAR 7.21.0 +CURLFILETYPE_DIRECTORY 7.21.0 +CURLFILETYPE_DOOR 7.21.0 +CURLFILETYPE_FILE 7.21.0 +CURLFILETYPE_NAMEDPIPE 7.21.0 +CURLFILETYPE_SOCKET 7.21.0 +CURLFILETYPE_SYMLINK 7.21.0 +CURLFILETYPE_UNKNOWN 7.21.0 +CURLFINFOFLAG_KNOWN_FILENAME 7.21.0 +CURLFINFOFLAG_KNOWN_FILETYPE 7.21.0 +CURLFINFOFLAG_KNOWN_GID 7.21.0 +CURLFINFOFLAG_KNOWN_HLINKCOUNT 7.21.0 +CURLFINFOFLAG_KNOWN_PERM 7.21.0 +CURLFINFOFLAG_KNOWN_SIZE 7.21.0 +CURLFINFOFLAG_KNOWN_TIME 7.21.0 +CURLFINFOFLAG_KNOWN_UID 7.21.0 +CURLFORM_ARRAY 7.9.1 +CURLFORM_ARRAY_END 7.9.1 7.9.5 7.9.6 +CURLFORM_ARRAY_START 7.9.1 7.9.5 7.9.6 +CURLFORM_BUFFER 7.9.8 +CURLFORM_BUFFERLENGTH 7.9.8 +CURLFORM_BUFFERPTR 7.9.8 +CURLFORM_CONTENTHEADER 7.9.3 +CURLFORM_CONTENTSLENGTH 7.9 +CURLFORM_CONTENTTYPE 7.9 +CURLFORM_COPYCONTENTS 7.9 +CURLFORM_COPYNAME 7.9 +CURLFORM_END 7.9 +CURLFORM_FILE 7.9 +CURLFORM_FILECONTENT 7.9.1 +CURLFORM_FILENAME 7.9.6 +CURLFORM_NAMELENGTH 7.9 +CURLFORM_NOTHING 7.9 +CURLFORM_PTRCONTENTS 7.9 +CURLFORM_PTRNAME 7.9 +CURLFORM_STREAM 7.18.2 +CURLFTPAUTH_DEFAULT 7.12.2 +CURLFTPAUTH_SSL 7.12.2 +CURLFTPAUTH_TLS 7.12.2 +CURLFTPMETHOD_DEFAULT 7.15.3 +CURLFTPMETHOD_MULTICWD 7.15.3 +CURLFTPMETHOD_NOCWD 7.15.3 +CURLFTPMETHOD_SINGLECWD 7.15.3 +CURLFTPSSL_ALL 7.11.0 7.17.0 +CURLFTPSSL_CCC_ACTIVE 7.16.2 +CURLFTPSSL_CCC_NONE 7.16.2 +CURLFTPSSL_CCC_PASSIVE 7.16.1 +CURLFTPSSL_CONTROL 7.11.0 7.17.0 +CURLFTPSSL_NONE 7.11.0 7.17.0 +CURLFTPSSL_TRY 7.11.0 7.17.0 +CURLFTP_CREATE_DIR 7.19.4 +CURLFTP_CREATE_DIR_NONE 7.19.4 +CURLFTP_CREATE_DIR_RETRY 7.19.4 +CURLGSSAPI_DELEGATION_FLAG 7.22.0 +CURLGSSAPI_DELEGATION_NONE 7.22.0 +CURLGSSAPI_DELEGATION_POLICY_FLAG 7.22.0 +CURLINFO_APPCONNECT_TIME 7.19.0 +CURLINFO_CERTINFO 7.19.1 +CURLINFO_CONDITION_UNMET 7.19.4 +CURLINFO_CONNECT_TIME 7.4.1 +CURLINFO_CONTENT_LENGTH_DOWNLOAD 7.6.1 +CURLINFO_CONTENT_LENGTH_UPLOAD 7.6.1 +CURLINFO_CONTENT_TYPE 7.9.4 +CURLINFO_COOKIELIST 7.14.1 +CURLINFO_DATA_IN 7.9.6 +CURLINFO_DATA_OUT 7.9.6 +CURLINFO_DOUBLE 7.4.1 +CURLINFO_EFFECTIVE_URL 7.4 +CURLINFO_END 7.9.6 +CURLINFO_FILETIME 7.5 +CURLINFO_FTP_ENTRY_PATH 7.15.4 +CURLINFO_HEADER_IN 7.9.6 +CURLINFO_HEADER_OUT 7.9.6 +CURLINFO_HEADER_SIZE 7.4.1 +CURLINFO_HTTPAUTH_AVAIL 7.10.8 +CURLINFO_HTTP_CODE 7.4.1 7.10.8 +CURLINFO_HTTP_CONNECTCODE 7.10.7 +CURLINFO_LASTONE 7.4.1 +CURLINFO_LASTSOCKET 7.15.2 +CURLINFO_LOCAL_IP 7.21.0 +CURLINFO_LOCAL_PORT 7.21.0 +CURLINFO_LONG 7.4.1 +CURLINFO_MASK 7.4.1 +CURLINFO_NAMELOOKUP_TIME 7.4.1 +CURLINFO_NONE 7.4.1 +CURLINFO_NUM_CONNECTS 7.12.3 +CURLINFO_OS_ERRNO 7.12.2 +CURLINFO_PRETRANSFER_TIME 7.4.1 +CURLINFO_PRIMARY_IP 7.19.0 +CURLINFO_PRIMARY_PORT 7.21.0 +CURLINFO_PRIVATE 7.10.3 +CURLINFO_PROXYAUTH_AVAIL 7.10.8 +CURLINFO_REDIRECT_COUNT 7.9.7 +CURLINFO_REDIRECT_TIME 7.9.7 +CURLINFO_REDIRECT_URL 7.18.2 +CURLINFO_REQUEST_SIZE 7.4.1 +CURLINFO_RESPONSE_CODE 7.10.8 +CURLINFO_RTSP_CLIENT_CSEQ 7.20.0 +CURLINFO_RTSP_CSEQ_RECV 7.20.0 +CURLINFO_RTSP_SERVER_CSEQ 7.20.0 +CURLINFO_RTSP_SESSION_ID 7.20.0 +CURLINFO_SIZE_DOWNLOAD 7.4.1 +CURLINFO_SIZE_UPLOAD 7.4.1 +CURLINFO_SLIST 7.12.3 +CURLINFO_SPEED_DOWNLOAD 7.4.1 +CURLINFO_SPEED_UPLOAD 7.4.1 +CURLINFO_SSL_DATA_IN 7.12.1 +CURLINFO_SSL_DATA_OUT 7.12.1 +CURLINFO_SSL_ENGINES 7.12.3 +CURLINFO_SSL_VERIFYRESULT 7.5 +CURLINFO_STARTTRANSFER_TIME 7.9.2 +CURLINFO_STRING 7.4.1 +CURLINFO_TEXT 7.9.6 +CURLINFO_TOTAL_TIME 7.4.1 +CURLINFO_TYPEMASK 7.4.1 +CURLIOCMD_NOP 7.12.3 +CURLIOCMD_RESTARTREAD 7.12.3 +CURLIOE_FAILRESTART 7.12.3 +CURLIOE_OK 7.12.3 +CURLIOE_UNKNOWNCMD 7.12.3 +CURLKHMATCH_MISMATCH 7.19.6 +CURLKHMATCH_MISSING 7.19.6 +CURLKHMATCH_OK 7.19.6 +CURLKHSTAT_DEFER 7.19.6 +CURLKHSTAT_FINE 7.19.6 +CURLKHSTAT_FINE_ADD_TO_FILE 7.19.6 +CURLKHSTAT_REJECT 7.19.6 +CURLKHTYPE_DSS 7.19.6 +CURLKHTYPE_RSA 7.19.6 +CURLKHTYPE_RSA1 7.19.6 +CURLKHTYPE_UNKNOWN 7.19.6 +CURLMOPT_MAXCONNECTS 7.16.3 +CURLMOPT_PIPELINING 7.16.0 +CURLMOPT_SOCKETDATA 7.15.4 +CURLMOPT_SOCKETFUNCTION 7.15.4 +CURLMOPT_TIMERDATA 7.16.0 +CURLMOPT_TIMERFUNCTION 7.16.0 +CURLMSG_DONE 7.9.6 +CURLMSG_NONE 7.9.6 +CURLM_BAD_EASY_HANDLE 7.9.6 +CURLM_BAD_HANDLE 7.9.6 +CURLM_BAD_SOCKET 7.15.4 +CURLM_CALL_MULTI_PERFORM 7.9.6 +CURLM_CALL_MULTI_SOCKET 7.15.5 +CURLM_INTERNAL_ERROR 7.9.6 +CURLM_OK 7.9.6 +CURLM_OUT_OF_MEMORY 7.9.6 +CURLM_UNKNOWN_OPTION 7.15.4 +CURLOPTTYPE_FUNCTIONPOINT 7.1 +CURLOPTTYPE_LONG 7.1 +CURLOPTTYPE_OBJECTPOINT 7.1 +CURLOPTTYPE_OFF_T 7.11.0 +CURLOPT_ACCEPTTIMEOUT_MS 7.24.0 +CURLOPT_ACCEPT_ENCODING 7.21.6 +CURLOPT_ADDRESS_SCOPE 7.19.0 +CURLOPT_APPEND 7.17.0 +CURLOPT_AUTOREFERER 7.1 +CURLOPT_BUFFERSIZE 7.10 +CURLOPT_CAINFO 7.4.2 +CURLOPT_CAPATH 7.9.8 +CURLOPT_CERTINFO 7.19.1 +CURLOPT_CHUNK_BGN_FUNCTION 7.21.0 +CURLOPT_CHUNK_DATA 7.21.0 +CURLOPT_CHUNK_END_FUNCTION 7.21.0 +CURLOPT_CLOSEFUNCTION 7.7 7.11.1 7.15.5 +CURLOPT_CLOSEPOLICY 7.7 7.16.1 +CURLOPT_CLOSESOCKETDATA 7.21.7 +CURLOPT_CLOSESOCKETFUNCTION 7.21.7 +CURLOPT_CONNECTTIMEOUT 7.7 +CURLOPT_CONNECTTIMEOUT_MS 7.16.2 +CURLOPT_CONNECT_ONLY 7.15.2 +CURLOPT_CONV_FROM_NETWORK_FUNCTION 7.15.4 +CURLOPT_CONV_FROM_UTF8_FUNCTION 7.15.4 +CURLOPT_CONV_TO_NETWORK_FUNCTION 7.15.4 +CURLOPT_COOKIE 7.1 +CURLOPT_COOKIEFILE 7.1 +CURLOPT_COOKIEJAR 7.9 +CURLOPT_COOKIELIST 7.14.1 +CURLOPT_COOKIESESSION 7.9.7 +CURLOPT_COPYPOSTFIELDS 7.17.1 +CURLOPT_CRLF 7.1 +CURLOPT_CRLFILE 7.19.0 +CURLOPT_CUSTOMREQUEST 7.1 +CURLOPT_DEBUGDATA 7.9.6 +CURLOPT_DEBUGFUNCTION 7.9.6 +CURLOPT_DIRLISTONLY 7.17.0 +CURLOPT_DNS_CACHE_TIMEOUT 7.9.3 +CURLOPT_DNS_SERVERS 7.24.0 +CURLOPT_DNS_USE_GLOBAL_CACHE 7.9.3 7.11.1 +CURLOPT_EGDSOCKET 7.7 +CURLOPT_ENCODING 7.10 +CURLOPT_ERRORBUFFER 7.1 +CURLOPT_FAILONERROR 7.1 +CURLOPT_FILE 7.1 7.9.7 +CURLOPT_FILETIME 7.5 +CURLOPT_FNMATCH_DATA 7.21.0 +CURLOPT_FNMATCH_FUNCTION 7.21.0 +CURLOPT_FOLLOWLOCATION 7.1 +CURLOPT_FORBID_REUSE 7.7 +CURLOPT_FRESH_CONNECT 7.7 +CURLOPT_FTPAPPEND 7.1 7.16.4 +CURLOPT_FTPASCII 7.1 7.11.1 7.15.5 +CURLOPT_FTPLISTONLY 7.1 7.16.4 +CURLOPT_FTPPORT 7.1 +CURLOPT_FTPSSLAUTH 7.12.2 +CURLOPT_FTP_ACCOUNT 7.13.0 +CURLOPT_FTP_ALTERNATIVE_TO_USER 7.15.5 +CURLOPT_FTP_CREATE_MISSING_DIRS 7.10.7 +CURLOPT_FTP_FILEMETHOD 7.15.1 +CURLOPT_FTP_RESPONSE_TIMEOUT 7.10.8 +CURLOPT_FTP_SKIP_PASV_IP 7.15.0 +CURLOPT_FTP_SSL 7.11.0 7.16.4 +CURLOPT_FTP_SSL_CCC 7.16.1 +CURLOPT_FTP_USE_EPRT 7.10.5 +CURLOPT_FTP_USE_EPSV 7.9.2 +CURLOPT_FTP_USE_PRET 7.20.0 +CURLOPT_GSSAPI_DELEGATION 7.22.0 +CURLOPT_HEADER 7.1 +CURLOPT_HEADERDATA 7.10 +CURLOPT_HEADERFUNCTION 7.7.2 +CURLOPT_HTTP200ALIASES 7.10.3 +CURLOPT_HTTPAUTH 7.10.6 +CURLOPT_HTTPGET 7.8.1 +CURLOPT_HTTPHEADER 7.1 +CURLOPT_HTTPPOST 7.1 +CURLOPT_HTTPPROXYTUNNEL 7.3 +CURLOPT_HTTPREQUEST 7.1 - 7.15.5 +CURLOPT_HTTP_CONTENT_DECODING 7.16.2 +CURLOPT_HTTP_TRANSFER_DECODING 7.16.2 +CURLOPT_HTTP_VERSION 7.9.1 +CURLOPT_IGNORE_CONTENT_LENGTH 7.14.1 +CURLOPT_INFILE 7.1 7.9.7 +CURLOPT_INFILESIZE 7.1 +CURLOPT_INFILESIZE_LARGE 7.11.0 +CURLOPT_INTERFACE 7.3 +CURLOPT_INTERLEAVEDATA 7.20.0 +CURLOPT_INTERLEAVEFUNCTION 7.20.0 +CURLOPT_IOCTLDATA 7.12.3 +CURLOPT_IOCTLFUNCTION 7.12.3 +CURLOPT_IPRESOLVE 7.10.8 +CURLOPT_ISSUERCERT 7.19.0 +CURLOPT_KEYPASSWD 7.17.0 +CURLOPT_KRB4LEVEL 7.3 7.17.0 +CURLOPT_KRBLEVEL 7.16.4 +CURLOPT_LOCALPORT 7.15.2 +CURLOPT_LOCALPORTRANGE 7.15.2 +CURLOPT_LOW_SPEED_LIMIT 7.1 +CURLOPT_LOW_SPEED_TIME 7.1 +CURLOPT_MAIL_AUTH 7.25.0 +CURLOPT_MAIL_FROM 7.20.0 +CURLOPT_MAIL_RCPT 7.20.0 +CURLOPT_MAXCONNECTS 7.7 +CURLOPT_MAXFILESIZE 7.10.8 +CURLOPT_MAXFILESIZE_LARGE 7.11.0 +CURLOPT_MAXREDIRS 7.5 +CURLOPT_MAX_RECV_SPEED_LARGE 7.15.5 +CURLOPT_MAX_SEND_SPEED_LARGE 7.15.5 +CURLOPT_MUTE 7.1 7.8 7.15.5 +CURLOPT_NETRC 7.1 +CURLOPT_NETRC_FILE 7.11.0 +CURLOPT_NEW_DIRECTORY_PERMS 7.16.4 +CURLOPT_NEW_FILE_PERMS 7.16.4 +CURLOPT_NOBODY 7.1 +CURLOPT_NOPROGRESS 7.1 +CURLOPT_NOPROXY 7.19.4 +CURLOPT_NOSIGNAL 7.10 +CURLOPT_NOTHING 7.1.1 7.11.1 7.11.0 +CURLOPT_OPENSOCKETDATA 7.17.1 +CURLOPT_OPENSOCKETFUNCTION 7.17.1 +CURLOPT_PASSWDDATA 7.4.2 7.11.1 7.15.5 +CURLOPT_PASSWDFUNCTION 7.4.2 7.11.1 7.15.5 +CURLOPT_PASSWORD 7.19.1 +CURLOPT_PASV_HOST 7.12.1 7.16.0 7.15.5 +CURLOPT_PORT 7.1 +CURLOPT_POST 7.1 +CURLOPT_POST301 7.17.1 7.19.1 +CURLOPT_POSTFIELDS 7.1 +CURLOPT_POSTFIELDSIZE 7.2 +CURLOPT_POSTFIELDSIZE_LARGE 7.11.1 +CURLOPT_POSTQUOTE 7.1 +CURLOPT_POSTREDIR 7.19.1 +CURLOPT_PREQUOTE 7.9.5 +CURLOPT_PRIVATE 7.10.3 +CURLOPT_PROGRESSDATA 7.1 +CURLOPT_PROGRESSFUNCTION 7.1 +CURLOPT_PROTOCOLS 7.19.4 +CURLOPT_PROXY 7.1 +CURLOPT_PROXYAUTH 7.10.7 +CURLOPT_PROXYPASSWORD 7.19.1 +CURLOPT_PROXYPORT 7.1 +CURLOPT_PROXYTYPE 7.10 +CURLOPT_PROXYUSERNAME 7.19.1 +CURLOPT_PROXYUSERPWD 7.1 +CURLOPT_PROXY_TRANSFER_MODE 7.18.0 +CURLOPT_PUT 7.1 +CURLOPT_QUOTE 7.1 +CURLOPT_RANDOM_FILE 7.7 +CURLOPT_RANGE 7.1 +CURLOPT_READDATA 7.9.7 +CURLOPT_READFUNCTION 7.1 +CURLOPT_REDIR_PROTOCOLS 7.19.4 +CURLOPT_REFERER 7.1 +CURLOPT_RESOLVE 7.21.3 +CURLOPT_RESUME_FROM 7.1 +CURLOPT_RESUME_FROM_LARGE 7.11.0 +CURLOPT_RTSPHEADER 7.20.0 +CURLOPT_RTSP_CLIENT_CSEQ 7.20.0 +CURLOPT_RTSP_REQUEST 7.20.0 +CURLOPT_RTSP_SERVER_CSEQ 7.20.0 +CURLOPT_RTSP_SESSION_ID 7.20.0 +CURLOPT_RTSP_STREAM_URI 7.20.0 +CURLOPT_RTSP_TRANSPORT 7.20.0 +CURLOPT_SEEKDATA 7.18.0 +CURLOPT_SEEKFUNCTION 7.18.0 +CURLOPT_SERVER_RESPONSE_TIMEOUT 7.20.0 +CURLOPT_SHARE 7.10 +CURLOPT_SOCKOPTDATA 7.16.0 +CURLOPT_SOCKOPTFUNCTION 7.16.0 +CURLOPT_SOCKS5_GSSAPI_NEC 7.19.4 +CURLOPT_SOCKS5_GSSAPI_SERVICE 7.19.4 +CURLOPT_SOURCE_HOST 7.12.1 - 7.15.5 +CURLOPT_SOURCE_PATH 7.12.1 - 7.15.5 +CURLOPT_SOURCE_PORT 7.12.1 - 7.15.5 +CURLOPT_SOURCE_POSTQUOTE 7.12.1 - 7.15.5 +CURLOPT_SOURCE_PREQUOTE 7.12.1 - 7.15.5 +CURLOPT_SOURCE_QUOTE 7.13.0 - 7.15.5 +CURLOPT_SOURCE_URL 7.13.0 - 7.15.5 +CURLOPT_SOURCE_USERPWD 7.12.1 - 7.15.5 +CURLOPT_SSH_AUTH_TYPES 7.16.1 +CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 7.17.1 +CURLOPT_SSH_KEYDATA 7.19.6 +CURLOPT_SSH_KEYFUNCTION 7.19.6 +CURLOPT_SSH_KNOWNHOSTS 7.19.6 +CURLOPT_SSH_PRIVATE_KEYFILE 7.16.1 +CURLOPT_SSH_PUBLIC_KEYFILE 7.16.1 +CURLOPT_SSLCERT 7.1 +CURLOPT_SSLCERTPASSWD 7.1.1 7.17.0 +CURLOPT_SSLCERTTYPE 7.9.3 +CURLOPT_SSLENGINE 7.9.3 +CURLOPT_SSLENGINE_DEFAULT 7.9.3 +CURLOPT_SSLKEY 7.9.3 +CURLOPT_SSLKEYPASSWD 7.9.3 7.17.0 +CURLOPT_SSLKEYTYPE 7.9.3 +CURLOPT_SSLVERSION 7.1 +CURLOPT_SSL_CIPHER_LIST 7.9 +CURLOPT_SSL_CTX_DATA 7.10.6 +CURLOPT_SSL_CTX_FUNCTION 7.10.6 +CURLOPT_SSL_OPTIONS 7.25.0 +CURLOPT_SSL_SESSIONID_CACHE 7.16.0 +CURLOPT_SSL_VERIFYHOST 7.8.1 +CURLOPT_SSL_VERIFYPEER 7.4.2 +CURLOPT_STDERR 7.1 +CURLOPT_TCP_KEEPALIVE 7.25.0 +CURLOPT_TCP_KEEPIDLE 7.25.0 +CURLOPT_TCP_KEEPINTVL 7.25.0 +CURLOPT_TCP_NODELAY 7.11.2 +CURLOPT_TELNETOPTIONS 7.7 +CURLOPT_TFTP_BLKSIZE 7.19.4 +CURLOPT_TIMECONDITION 7.1 +CURLOPT_TIMEOUT 7.1 +CURLOPT_TIMEOUT_MS 7.16.2 +CURLOPT_TIMEVALUE 7.1 +CURLOPT_TLSAUTH_PASSWORD 7.21.4 +CURLOPT_TLSAUTH_TYPE 7.21.4 +CURLOPT_TLSAUTH_USERNAME 7.21.4 +CURLOPT_TRANSFERTEXT 7.1.1 +CURLOPT_TRANSFER_ENCODING 7.21.6 +CURLOPT_UNRESTRICTED_AUTH 7.10.4 +CURLOPT_UPLOAD 7.1 +CURLOPT_URL 7.1 +CURLOPT_USERAGENT 7.1 +CURLOPT_USERNAME 7.19.1 +CURLOPT_USERPWD 7.1 +CURLOPT_USE_SSL 7.17.0 +CURLOPT_VERBOSE 7.1 +CURLOPT_WILDCARDMATCH 7.21.0 +CURLOPT_WRITEDATA 7.9.7 +CURLOPT_WRITEFUNCTION 7.1 +CURLOPT_WRITEHEADER 7.1 +CURLOPT_WRITEINFO 7.1 +CURLPAUSE_ALL 7.18.0 +CURLPAUSE_CONT 7.18.0 +CURLPAUSE_RECV 7.18.0 +CURLPAUSE_RECV_CONT 7.18.0 +CURLPAUSE_SEND 7.18.0 +CURLPAUSE_SEND_CONT 7.18.0 +CURLPROTO_ALL 7.19.4 +CURLPROTO_DICT 7.19.4 +CURLPROTO_FILE 7.19.4 +CURLPROTO_FTP 7.19.4 +CURLPROTO_FTPS 7.19.4 +CURLPROTO_GOPHER 7.21.2 +CURLPROTO_HTTP 7.19.4 +CURLPROTO_HTTPS 7.19.4 +CURLPROTO_IMAP 7.20.0 +CURLPROTO_IMAPS 7.20.0 +CURLPROTO_LDAP 7.19.4 +CURLPROTO_LDAPS 7.19.4 +CURLPROTO_POP3 7.20.0 +CURLPROTO_POP3S 7.20.0 +CURLPROTO_RTMP 7.21.0 +CURLPROTO_RTMPE 7.21.0 +CURLPROTO_RTMPS 7.21.0 +CURLPROTO_RTMPT 7.21.0 +CURLPROTO_RTMPTE 7.21.0 +CURLPROTO_RTMPTS 7.21.0 +CURLPROTO_RTSP 7.20.0 +CURLPROTO_SCP 7.19.4 +CURLPROTO_SFTP 7.19.4 +CURLPROTO_SMTP 7.20.0 +CURLPROTO_SMTPS 7.20.0 +CURLPROTO_TELNET 7.19.4 +CURLPROTO_TFTP 7.19.4 +CURLPROXY_HTTP 7.10 +CURLPROXY_HTTP_1_0 7.19.4 +CURLPROXY_SOCKS4 7.10 +CURLPROXY_SOCKS4A 7.18.0 +CURLPROXY_SOCKS5 7.10 +CURLPROXY_SOCKS5_HOSTNAME 7.18.0 +CURLSHE_BAD_OPTION 7.10.3 +CURLSHE_INVALID 7.10.3 +CURLSHE_IN_USE 7.10.3 +CURLSHE_NOMEM 7.12.0 +CURLSHE_NOT_BUILT_IN 7.23.0 +CURLSHE_OK 7.10.3 +CURLSHOPT_LOCKFUNC 7.10.3 +CURLSHOPT_NONE 7.10.3 +CURLSHOPT_SHARE 7.10.3 +CURLSHOPT_UNLOCKFUNC 7.10.3 +CURLSHOPT_UNSHARE 7.10.3 +CURLSHOPT_USERDATA 7.10.3 +CURLSOCKTYPE_ACCEPT 7.28.0 +CURLSOCKTYPE_IPCXN 7.16.0 +CURLSSH_AUTH_AGENT 7.28.0 +CURLSSH_AUTH_ANY 7.16.1 +CURLSSH_AUTH_DEFAULT 7.16.1 +CURLSSH_AUTH_HOST 7.16.1 +CURLSSH_AUTH_KEYBOARD 7.16.1 +CURLSSH_AUTH_NONE 7.16.1 +CURLSSH_AUTH_PASSWORD 7.16.1 +CURLSSH_AUTH_PUBLICKEY 7.16.1 +CURLSSLOPT_ALLOW_BEAST 7.25.0 +CURLUSESSL_ALL 7.17.0 +CURLUSESSL_CONTROL 7.17.0 +CURLUSESSL_NONE 7.17.0 +CURLUSESSL_TRY 7.17.0 +CURLVERSION_FIRST 7.10 +CURLVERSION_FOURTH 7.16.1 +CURLVERSION_NOW 7.10 +CURLVERSION_SECOND 7.11.1 +CURLVERSION_THIRD 7.12.0 +CURL_CHUNK_BGN_FUNC_FAIL 7.21.0 +CURL_CHUNK_BGN_FUNC_OK 7.21.0 +CURL_CHUNK_BGN_FUNC_SKIP 7.21.0 +CURL_CHUNK_END_FUNC_FAIL 7.21.0 +CURL_CHUNK_END_FUNC_OK 7.21.0 +CURL_CSELECT_ERR 7.16.3 +CURL_CSELECT_IN 7.16.3 +CURL_CSELECT_OUT 7.16.3 +CURL_EASY_NONE 7.14.0 - 7.15.4 +CURL_EASY_TIMEOUT 7.14.0 - 7.15.4 +CURL_ERROR_SIZE 7.1 +CURL_FNMATCHFUNC_FAIL 7.21.0 +CURL_FNMATCHFUNC_MATCH 7.21.0 +CURL_FNMATCHFUNC_NOMATCH 7.21.0 +CURL_FORMADD_DISABLED 7.12.1 +CURL_FORMADD_ILLEGAL_ARRAY 7.9.8 +CURL_FORMADD_INCOMPLETE 7.9.8 +CURL_FORMADD_MEMORY 7.9.8 +CURL_FORMADD_NULL 7.9.8 +CURL_FORMADD_OK 7.9.8 +CURL_FORMADD_OPTION_TWICE 7.9.8 +CURL_FORMADD_UNKNOWN_OPTION 7.9.8 +CURL_GLOBAL_ALL 7.8 +CURL_GLOBAL_DEFAULT 7.8 +CURL_GLOBAL_NOTHING 7.8 +CURL_GLOBAL_SSL 7.8 +CURL_GLOBAL_WIN32 7.8.1 +CURL_HTTP_VERSION_1_0 7.9.1 +CURL_HTTP_VERSION_1_1 7.9.1 +CURL_HTTP_VERSION_NONE 7.9.1 +CURL_IPRESOLVE_V4 7.10.8 +CURL_IPRESOLVE_V6 7.10.8 +CURL_IPRESOLVE_WHATEVER 7.10.8 +CURL_LOCK_ACCESS_NONE 7.10.3 +CURL_LOCK_ACCESS_SHARED 7.10.3 +CURL_LOCK_ACCESS_SINGLE 7.10.3 +CURL_LOCK_DATA_CONNECT 7.10.3 +CURL_LOCK_DATA_COOKIE 7.10.3 +CURL_LOCK_DATA_DNS 7.10.3 +CURL_LOCK_DATA_NONE 7.10.3 +CURL_LOCK_DATA_SHARE 7.10.4 +CURL_LOCK_DATA_SSL_SESSION 7.10.3 +CURL_LOCK_TYPE_CONNECT 7.10 - 7.10.2 +CURL_LOCK_TYPE_COOKIE 7.10 - 7.10.2 +CURL_LOCK_TYPE_DNS 7.10 - 7.10.2 +CURL_LOCK_TYPE_NONE 7.10 - 7.10.2 +CURL_LOCK_TYPE_SSL_SESSION 7.10 - 7.10.2 +CURL_MAX_HTTP_HEADER 7.19.7 +CURL_MAX_WRITE_SIZE 7.9.7 +CURL_NETRC_IGNORED 7.9.8 +CURL_NETRC_OPTIONAL 7.9.8 +CURL_NETRC_REQUIRED 7.9.8 +CURL_POLL_IN 7.14.0 +CURL_POLL_INOUT 7.14.0 +CURL_POLL_NONE 7.14.0 +CURL_POLL_OUT 7.14.0 +CURL_POLL_REMOVE 7.14.0 +CURL_PROGRESS_BAR 7.1.1 - 7.4.1 +CURL_PROGRESS_STATS 7.1.1 - 7.4.1 +CURL_READFUNC_ABORT 7.12.1 +CURL_READFUNC_PAUSE 7.18.0 +CURL_REDIR_GET_ALL 7.19.1 +CURL_REDIR_POST_301 7.19.1 +CURL_REDIR_POST_302 7.19.1 +CURL_REDIR_POST_303 7.25.1 +CURL_REDIR_POST_ALL 7.19.1 +CURL_RTSPREQ_ANNOUNCE 7.20.0 +CURL_RTSPREQ_DESCRIBE 7.20.0 +CURL_RTSPREQ_GET_PARAMETER 7.20.0 +CURL_RTSPREQ_NONE 7.20.0 +CURL_RTSPREQ_OPTIONS 7.20.0 +CURL_RTSPREQ_PAUSE 7.20.0 +CURL_RTSPREQ_PLAY 7.20.0 +CURL_RTSPREQ_RECEIVE 7.20.0 +CURL_RTSPREQ_RECORD 7.20.0 +CURL_RTSPREQ_SETUP 7.20.0 +CURL_RTSPREQ_SET_PARAMETER 7.20.0 +CURL_RTSPREQ_TEARDOWN 7.20.0 +CURL_SEEKFUNC_CANTSEEK 7.19.5 +CURL_SEEKFUNC_FAIL 7.19.5 +CURL_SEEKFUNC_OK 7.19.5 +CURL_SOCKET_BAD 7.14.0 +CURL_SOCKET_TIMEOUT 7.14.0 +CURL_SOCKOPT_ALREADY_CONNECTED 7.21.5 +CURL_SOCKOPT_ERROR 7.21.5 +CURL_SOCKOPT_OK 7.21.5 +CURL_SSLVERSION_DEFAULT 7.9.2 +CURL_SSLVERSION_SSLv2 7.9.2 +CURL_SSLVERSION_SSLv3 7.9.2 +CURL_SSLVERSION_TLSv1 7.9.2 +CURL_TIMECOND_IFMODSINCE 7.9.7 +CURL_TIMECOND_IFUNMODSINCE 7.9.7 +CURL_TIMECOND_LASTMOD 7.9.7 +CURL_TIMECOND_NONE 7.9.7 +CURL_TLSAUTH_NONE 7.21.4 +CURL_TLSAUTH_SRP 7.21.4 +CURL_VERSION_ASYNCHDNS 7.10.7 +CURL_VERSION_CONV 7.15.4 +CURL_VERSION_CURLDEBUG 7.19.6 +CURL_VERSION_DEBUG 7.10.6 +CURL_VERSION_GSSNEGOTIATE 7.10.6 +CURL_VERSION_IDN 7.12.0 +CURL_VERSION_IPV6 7.10 +CURL_VERSION_KERBEROS4 7.10 +CURL_VERSION_LARGEFILE 7.11.1 +CURL_VERSION_LIBZ 7.10 +CURL_VERSION_NTLM 7.10.6 +CURL_VERSION_NTLM_WB 7.22.0 +CURL_VERSION_SPNEGO 7.10.8 +CURL_VERSION_SSL 7.10 +CURL_VERSION_SSPI 7.13.2 +CURL_VERSION_TLSAUTH_SRP 7.21.4 +CURL_WAIT_POLLIN 7.28.0 +CURL_WAIT_POLLOUT 7.28.0 +CURL_WAIT_POLLPRI 7.28.0 +CURL_WRITEFUNC_PAUSE 7.18.0 diff --git a/docs/libcurl/symbols.pl b/docs/libcurl/symbols.pl new file mode 100755 index 000000000..d1ff7a656 --- /dev/null +++ b/docs/libcurl/symbols.pl @@ -0,0 +1,100 @@ +#!/usr/bin/perl +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 2011, 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. +# +########################################################################### +# +# Experience has shown that the symbols-in-versions file is very useful to +# applications that want to build with a wide range of libcurl versions. +# It is however easy to get it wrong and the source gets a bit messy with all +# the fixed numerical comparisions. +# +# The point of this script is to provide an easy-to-use macro for libcurl- +# using applications to do preprocessor checks for specific libcurl defines, +# and yet make the code clearly show what the macro is used for. +# +# Run this script and generate libcurl-symbols.h and then use that header in +# a fashion similar to: +# +# #include "libcurl-symbols.h" +# +# #if LIBCURL_HAS(CURLOPT_MUTE) +# has mute +# #else +# no mute +# #endif +# +# +open F, "<symbols-in-versions"; + +sub str2num { + my ($str)=@_; + if($str =~ /([0-9]*)\.([0-9]*)\.*([0-9]*)/) { + return sprintf("0x%06x", $1<<16 | $2 << 8 | $3); + } +} + +print <<EOS + +#include <curl/curl.h> + +#define LIBCURL_HAS(x) \\ + (defined(x ## _FIRST) && (x ## _FIRST <= LIBCURL_VERSION_NUM) && \\ + (!defined(x ## _LAST) || ( x ## _LAST >= LIBCURL_VERSION_NUM))) + +EOS + ; + +while(<F>) { + if(/^(CURL[^ ]*)[ \t]*(.*)/) { + my ($sym, $vers)=($1, $2); + + my $intr; + my $rm; + my $dep; + + # is there removed info? + if($vers =~ /([\d.]+)[ \t-]+([\d.]+)[ \t]+([\d.]+)/) { + ($intr, $dep, $rm)=($1, $2, $3); + } + # is it a dep-only line? + elsif($vers =~ /([\d.]+)[ \t-]+([\d.]+)/) { + ($intr, $dep)=($1, $2); + } + else { + $intr = $vers; + } + + my $inum = str2num($intr); + + print <<EOS +#define ${sym}_FIRST $inum /* Added in $intr */ +EOS +; + my $irm = str2num($rm); + if($rm) { + print <<EOS +#define ${sym}_LAST $irm /* Last featured in $rm */ +EOS +; + } + + } +} diff --git a/docs/mk-ca-bundle.1 b/docs/mk-ca-bundle.1 new file mode 100644 index 000000000..f7904398f --- /dev/null +++ b/docs/mk-ca-bundle.1 @@ -0,0 +1,51 @@ +.Dd April 27, 2012 +.Dt MK-CA-BUNDLE 1 +.Os +.Sh NAME +.Nm mk-ca-bundle +.Nd create a new ca-bundle.crt from mozilla's certdata.txt +.Sh SYNOPSIS +.Nm +.Op Fl bilnqtuv +.Or outputfile +.Sh DESCRIPTION +The +.Nm +tool downloads the certdata.txt file from Mozilla's source tree, then +parses certdata.txt and extracts CA Root Certificates into PEM format. +These are then processed with the OpenSSL commandline tool to produce the +final ca-bundle.crt file. +.Sh OPTIONS +The following options are supported by +.Nm : +.Bl -tag -width _h +.It Fl b +backup an existing version of ca-bundle.crt +.It Fl i +print version info about used modules +.It Fl l +print license info about certdata.txt +.It Fl n +no download of certdata.txt (to use existing) +.It Fl q +be really quiet (no progress output at all) +.It Fl t +include plain text listing of certificates +.It Fl u +unlink (remove) certdata.txt after processing +.It Fl v +be verbose and print out processed CAs +.El +.Sh EXIT STATUS +.Ex -std +.Sh SEE ALSO +.Xr curl 1 +.Sh HISTORY +.Nm +was based on the parse-certs script written by +.An Roland Krikava +and hacked by +.An Guenter Knauf . +This manual page was written by +.An Jan Schaumann +.Aq jschauma@netmeister.org . |