mirror of
https://github.com/moparisthebest/curl
synced 2024-10-31 15:45:12 -04:00
Added the recycle handles chapter
Added most of the Customizing Operations chapter
This commit is contained in:
parent
a8dd13db4c
commit
cc2f1d4894
@ -630,14 +630,156 @@ Proxies
|
|||||||
|
|
||||||
Persistancy Is The Way to Happiness
|
Persistancy Is The Way to Happiness
|
||||||
|
|
||||||
[ re-use connections, options that control/disable this, the effect on
|
Re-cycling the same easy handle several times when doing multiple requests is
|
||||||
protocols such as FTP, why this is Good For You ]
|
the way to go.
|
||||||
|
|
||||||
|
After each single curl_easy_perform() 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 drasticly
|
||||||
|
reduces re-connection time.
|
||||||
|
|
||||||
|
FTP connections that are kept alive saves a lot of time, as the command-
|
||||||
|
response roundtrips 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. It 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.
|
||||||
|
|
||||||
|
When the connection cache gets filled, libcurl must close an existing
|
||||||
|
connection in order to get room for the new one. To know which connection to
|
||||||
|
close, libcurl uses a "close policy" that you can affect with the
|
||||||
|
CURLOPT_CLOSEPOLICY option. There's only two polices implemented as of this
|
||||||
|
writing (libcurl 7.9.4) and they are:
|
||||||
|
|
||||||
|
CURLCLOSEPOLICY_LEAST_RECENTLY_USED simply close the one that hasn't been
|
||||||
|
used for the longest time. This is the default behavior.
|
||||||
|
|
||||||
|
CURLCLOSEPOLICY_OLDEST closes the oldest connection, the one that was
|
||||||
|
createst the longest time ago.
|
||||||
|
|
||||||
|
There are, or at least were, plans to support a close policy that would call
|
||||||
|
a user-specified callback to let the user be able to decide which connection
|
||||||
|
to dump when this is necessary and therefor is the CURLOPT_CLOSEFUNCTION an
|
||||||
|
existing option still today. Nothing ever uses this though and this will not
|
||||||
|
be used within the forseeable future either.
|
||||||
|
|
||||||
|
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 TRUE. 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 TRUE.
|
||||||
|
|
||||||
|
|
||||||
Customizing Operations
|
Customizing Operations
|
||||||
|
|
||||||
[ custom requests, custom headers, replacing headers, custom FTP commands
|
There is an ongoing development today where more and more protocols are built
|
||||||
before transfer, after transfer and without transfer ]
|
upon HTTP for transport. This has obvious benefits as HTTP is a tested and
|
||||||
|
reliable protocol that is widely deployed and have 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.
|
||||||
|
|
||||||
|
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, "MYOWNRUQUEST");
|
||||||
|
|
||||||
|
When using the custom request, you change the request keyword of the actual
|
||||||
|
request you are performing. Thus, by default you make 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.
|
||||||
|
|
||||||
|
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 are this easy:
|
||||||
|
|
||||||
|
struct curl_slist *headers;
|
||||||
|
|
||||||
|
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 */
|
||||||
|
|
||||||
|
... and if you think some of the internally generated headers, such as
|
||||||
|
User-Agent:, Accept: or Host: don't contain the data you want them to
|
||||||
|
contain, you can replace them by simply setting them too:
|
||||||
|
|
||||||
|
headers = curl_slist_append(headers, "User-Agent: 007");
|
||||||
|
headers = curl_slist_append(headers, "Host: munged.host.line");
|
||||||
|
|
||||||
|
If you replace an existing header with one with no contents, you will prevent
|
||||||
|
the header from being sent. Like if you want to completely prevent the
|
||||||
|
"Accept:" header to be sent, you can disable it with code similar to this:
|
||||||
|
|
||||||
|
headers = curl_slist_append(headers, "Accept:");
|
||||||
|
|
||||||
|
Both replacing and cancelling internal headers should be done with careful
|
||||||
|
consideration and you should be aware that you may violate the HTTP protocol
|
||||||
|
when doing so.
|
||||||
|
|
||||||
|
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
|
||||||
|
comands 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 requires data interchange and thus needs 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:
|
||||||
|
|
||||||
|
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 */
|
||||||
|
|
||||||
|
If you would instead want this operation (or chain of operations) to happen
|
||||||
|
_after_ the data transfer took place the option to curl_easy_setopt() 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 built in 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. Note that if you use CURLOPT_QUOTE to send commands before a
|
||||||
|
transfer, no transfer will actually take place then.
|
||||||
|
|
||||||
|
[ custom FTP commands without transfer, FTP "header-only", HTTP 1.0 ]
|
||||||
|
|
||||||
|
Cookies Without Chocolate Chips
|
||||||
|
|
||||||
|
[ set cookies, read cookies from file, cookie-jar ]
|
||||||
|
|
||||||
|
|
||||||
Headers Equal Fun
|
Headers Equal Fun
|
||||||
|
Loading…
Reference in New Issue
Block a user