|
Location: Desktop development - C/C++ License: The Intelliproject Open License (IPOL) Using CURL to download a remote file from a valid URL in c++Posted by Silviu CarageaDescribe how to download a remote file from a valid URL in c++ |
Skill: IntermediatePosted: 22/02/2009Views: 2865Rating: 4.00 /5Popularity: 0.00 |
| Sign Up to vote for this article |
Curl is an open source solution that compiles and runs under a wide variety of operating systems. It's used for transferring files with URL syntax, supporting FTP, FTPS, HTTP, HTTPS, SCP, SFTP, TFTP, TELNET, DICT, LDAP, LDAPS and FILE.
Curl supports SSL certificates, HTTP POST, HTTP PUT, FTP uploading, HTTP form based upload, proxies, cookies, user+password authentication (Basic, Digest, NTLM, Negotiate, kerberos...), file transfer resume, proxy tunneling and a busload of other useful tricks.
This article assume that you have Ubuntu as OS and Eclipse as IDE . To install Curl open "Synaptic Package Manager" (System → Administration) . And install the following packages :

After you creating a new Eclipse project (C++ project) go to "Project properties->C/C++ Build->Settings->Tool Settings tab".At "GCC C++ Linker" in "Libraries (-l)" list add "curl" . This is all we must to do to be able to link with libcurl.

To use libcurl you must include in your project "curl/curl.h" . This file must be listed in your "Includes" section from your Eclipse project (probably in "/usr/include/curl").
Before calling any function from libcurl you must call the following function:
CURLcode curl_global_init(long flags);
This function sets up the program environment that libcurl needs. Think of it as an extension of the library loader. The flags option is a bit pattern that tells libcurl exactly what features to init . 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.
After you call curl_global_init you must create a Curl handle . To do that you must call CURL *curl_easy_init( ). At the end of your application or when you want do release your Curl handle call void curl_easy_cleanup(CURL * handle );
After you have created your handle you must to tell libcurl how to behave. By using the appropriate options to curl_easy_setopt, you can change libcurl's behavior.
All options are set with the option followed by a parameter. That parameter can be a long, a function pointer, an object pointer or a curl_off_t, depending on what the specific option expects. Read curl 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.
To perfrom the file transfer ,call CURLcode curl_easy_perform(CURL * handle );
This function is called after the init and all the curl_easy_setopt() calls are made, and will perform the transfer as described in the options.
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.
The following source code can be used to download a file from a valid URL . Also if you want you can retrieve the server headers.
In our application we must define the following structure :
std::string* pstr - used as buffer. The URL content will be stored in this member.bool bGrab - indicate if we want to grab the content or we just want to send an request to the server without downloading content.
This is a callback function which gets called by libcurl as soon as there is data received that needs to be saved. The size of the data pointed to by ptr is size multiplied with nmemb, 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 and it will abort the transfer and return CURLE_WRITE_ERROR.
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 data that can be passed to the write callback is defined in the curl.h header file: CURL_MAX_WRITE_SIZE.
In the following lines we set the curl handle options . For a detailed description of these you can visit the libcurl documentation.
Hereinafter I will make a short presentation of all important curl options used in this article.
curl_easy_setopt(curl_handle, CURLOPT_URL, strUrl.c_str()) - set the URL address which will be grabbed.curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, writefunction) - set the address of the callback function which will be used to retrieve the URL bodycurl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&data) - set the buffer where the callback function will store the body.curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, writefunction) - set the address of the callback function which will be used to retrieve the headers. The same function used to grab the URL body . We change just the storage buffer. Using the CURLOPT_WRITEHEADER option.curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER, (void *)&headers_data)- set the buffer where the callback function will store the headers.
As you can see the following application save the URL body to a file (out.html) and the headers are printed to the app console .

As you can see the main purpose and use for cURL is to automate unattended file transfers or sequences of operations. For example, it is a good tool for simulating a user's actions at a web browser.
This article, along with any associated source code and files, is licensed under The Intelliproject Open License (IPOL)
| Silviu Caragea
| Silviu Caragea is the Founder, Administrator and Chief Editor who wrote and runs The IntelliProject. He's been programming since 2000 and now he's student at The Faculty of Economic Cybernetics, Statistics and Informatics from Bucharest. In the same time he's working as software developer at Cratima Software, a Romanian software and web design company that activates both on the local and foreign market, providing its customers with software development services, internet and intranet solutions, web design, graphic design and IT consultancy. His programming experience includes: - C,C++, Visual C++(Win32 API, MFC, ADO, STL, DAO, ODBC, ATL, COM, DirectShow, DirectDraw, WTL) - Open Source libraries :CURL & Boost - HTML, CSS - Java (SE,ME) - JavaScript, Ajax, Google Web Toolkit (GWT) - Php, MySQL -Oracle, PL SQL - C# .NET -Objective C, IPhone SDK, Cocoa Location: |
Sign up to post message on the article message board!