# curl_easy_perform

Definition: | include builtins\libcurl.e CURLcode res = curl_easy_perform(atom curl)
Description: | Perform a blocking file transfer synchronously. Invoke this function after curl_easy_init and all the curl_easy_setopt calls are made, to perform the transfer as described in the options. It must be called with the same easy_handle as input as the curl_easy_init call returned. Return value: CURLE_OK (0) means everything was ok, non-zero means an error occurred - see CURLcode. If the CURLOPT_ERRORBUFFER was set with curl_easy_setopt there will be a readable error message in the error buffer when non-zero is returned.
pwa/p2js: | Not supported.
Comments: | curl_easy_perform performs the entire request in a blocking manner and returns when done, or if it failed. For non-blocking behavior, see curl_multi_perform(). You can do any amount of calls to curl_easy_perform while using the same easy_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 curl_easy_setopt 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 easy_handle. Let the function return first before invoking it another time. If you want parallel transfers, you must use several curl easy_handles. While the easy_handle is added to a multi handle, it cannot be used by curl_easy_perform.
Utility Functions | object res = curl_easy_perform_ex(object curl) curl: as above, a result from curl_easy_init that has been passed to a few curl_easy_setopt, or just a plain string url. Returns: if an integer is returned, it is a CURLcode (except for CURLE_OK), otherwise it is a single string containing the entire file contents (which can be text or binary). Note this is not really suitable for multi-megabyte downloads, whereas the following routine is. CURLcode res = curl_easy_get_file(string url, proxy, filename="") Save the text/binary from url to a new file on your local PC specified by filename. Proxy details can also be set, "" to not use a proxy. The shorthand form curl_easy_get_file(url, filename) is treated as curl_easy_get_file(url, "", filename), ie no proxy. Returns: CURLE_OK on success, any other return value represents an error. If the specified filename cannot be opened, returns CURLE_CANT_OPEN_FILE curl_easy_get_file(), and curl_easy_perform_ex() when passed a string, automatically perform curl_global_init() and curl_global_cleanup() when required, and also curl_easy_init() and curl_easy_cleanup() (every time). By default libcurl keeps connections open and caches DNS entries automatically. However, curl_easy_get_file() (and curl_eaxy_perform_ex(string)) start and stop a curl_session for each file downloaded, so they will not be as efficient, as several direct curl_easy_setopt() and curl_easy_perform() calls, when performing multiple downloads, then again there will probably be no measurable difference for a single file/url download. Also note that CURLOPT_ERRORBUFFER is not used and is not a natural fit for use with curl_easy_get_file(), along with most other debugging techniques, however the fairly trivial code of the included demo download.exw serves as a perfectly good template for something better.
Example 1: | Copy
    include builtins\libcurl.e
    curl_global_init()
    atom curl = curl_easy_init()
    curl_easy_setopt(curl, CURLOPT_URL, "http://example.com")
    CURLcode res = curl_easy_perform(curl)
    curl_easy_cleanup(curl)
    curl_global_cleanup()
Example 2: | Copy
    include builtins\libcurl.e
        -- save remote file to local drive
        CURLcode res = curl_easy_get_file("http://example.com", "", "example.html")
        if res!=CURLE_OK then
            ?"error"
        end if
See Also: | curl_easy_init, curl_easy_cleanup, curl_easy_setopt, curl_multi_add_handle, curl_multi_perform, CURLcode