Ecore_Con_Url - Managing cookies

This example shows how to use an Ecore_Con_Url and enable it to receive/send cookies.

These cookies can be set by the server, saved to a file, loaded later from this file and sent again to the server. The complete example can be found at ecore_con_url_cookies_example.c

First we are setting some callbacks for events that will be sent when data arrives in our connection (the data is the content of the file being downloaded), and when the download is completed. The _url_data_cb and _url_complete_cb are these callbacks:

static Eina_Bool
_url_progress_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event_info)
{
Ecore_Con_Event_Url_Progress *url_progress = event_info;
float percent;
if (url_progress->down.total > 0)
{
struct _request *req = ecore_con_url_data_get(url_progress->url_con);
req->size = url_progress->down.now;
percent = (url_progress->down.now / url_progress->down.total) * 100;
printf("Total of download complete: %0.1f (%0.0f)%%\n",
percent, url_progress->down.now);
}
printf("status: %d\n", ecore_con_url_status_code_get(url_progress->url_con));
return EINA_TRUE;
}
static Eina_Bool
_url_complete_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event_info)
{
Ecore_Con_Event_Url_Complete *url_complete = event_info;
struct _request *req = ecore_con_url_data_get(url_complete->url_con);
int nbytes = ecore_con_url_received_bytes_get(url_complete->url_con);
printf("\n");
printf("download completed with status code: %d\n", url_complete->status);
printf("Total size of downloaded file: %ld bytes\n", req->size);
printf("Total size of downloaded file: %d bytes "
"(from received_bytes_get)\n", nbytes);
ECORE_CON_API int ecore_con_url_received_bytes_get(Ecore_Con_Url *url_con)
Retrieves the number of bytes received.
Definition: ecore_con_url.c:1279
ECORE_CON_API int ecore_con_url_status_code_get(Ecore_Con_Url *url_con)
Gets the returned HTTP STATUS code.
Definition: ecore_con_url.c:1286
ECORE_CON_API void * ecore_con_url_data_get(Ecore_Con_Url *url_con)
Retrieves data associated with a Ecore_Con_Url connection object.
Definition: ecore_con_url.c:830
void ecore_main_loop_quit(void)
Quits the main loop once all the events currently on the queue have been processed.
Definition: ecore_main.c:1321
#define EINA_TRUE
boolean value TRUE (numerical value 1)
Definition: eina_types.h:539
unsigned char Eina_Bool
Type to mimic a boolean.
Definition: eina_types.h:527
#define EINA_UNUSED
Used to indicate that a function parameter is purposely unused.
Definition: eina_types.h:339
Used as the data param for the ECORE_CON_EVENT_URL_COMPLETE event.
Definition: Ecore_Con.h:586
Ecore_Con_Url * url_con
a pointer to the connection object
Definition: Ecore_Con.h:587
int status
HTTP status code of the operation (200, 404, 401, etc.)
Definition: Ecore_Con.h:588
Used as the data param for the ECORE_CON_EVENT_URL_PROGRESS event.
Definition: Ecore_Con.h:597
Ecore_Con_Url * url_con
a pointer to the connection object
Definition: Ecore_Con.h:598
double now
current size of the downloading data (in bytes)
Definition: Ecore_Con.h:602
double total
total size of the downloading data (in bytes)
Definition: Ecore_Con.h:601
struct _Ecore_Con_Event_Url_Progress::@27 down
download info
return EINA_TRUE;
}

In the main function we parse some parameter from the command line. These parameters are the url that we are connecting to, and cookie use policy.

After that we initialize the libraries and create a handler to our request using the given url:

int
main(int argc, const char *argv[])
{
Ecore_Con_Url *ec_url = NULL;
struct _request *req;
int fd;
const char *filename = "downloadedfile.dat";
if (argc < 2)
{
printf("need one parameter: <url>\n");
return -1;
}
fd = open(filename, O_CREAT | O_BINARY | O_WRONLY | O_TRUNC, 0644);
if (fd == -1)
{
printf("error: could not open file for writing: \"%s\"\n",
filename);
return -1;
}
ec_url = ecore_con_url_new(argv[1]);
if (!ec_url)
{
printf("error when creating ecore con url object.\n");
goto end;
ECORE_CON_API int ecore_con_init(void)
Initializes the Ecore_Con library.
Definition: ecore_con.c:68
ECORE_CON_API Ecore_Con_Url * ecore_con_url_new(const char *url)
Creates and initializes a new Ecore_Con_Url connection object.
Definition: ecore_con_url.c:782
ECORE_CON_API int ecore_con_url_init(void)
Initializes the Ecore_Con_Url library.
Definition: ecore_con_url.c:45
struct _Ecore_Con_Url Ecore_Con_Url
Used to provide legacy API/ABI compatibility with non-Eo applications.
Definition: Ecore_Con.h:323
EAPI int ecore_init(void)
Sets up connections, signal handlers, sockets etc.
Definition: ecore.c:230
}

We also set the event handlers for this request and add a header to it, that will inform our custom user agent:

Now we start playing with cookies. First, let's call ecore_con_url_cookies_init() to inform that we want cookies enabled. We also set a file from which we are loading previously set (old) cookies, in case that we don't want to clear old cookies or old session cookies.

After that we set the file where we are going to save all valid cookies in the Ecore_Con_Url object. This includes previously loaded cookies (that weren't cleared) and new cookies set by the response header "Set-Cookie" that comes with the response to our request:

And finally, before performing the request, we check the command passed as argument in the command line and use it to choose between clearing old cookies, clearing just old session cookies, or ignoring old session cookies.

After that we just finish our code as expected:

Notice that in this code, if we want to clear old cookies, we also don't load them from the file. This is a bit confusing and the API isn't clear, but ecore_con_url_cookies_file_add() will load cookies from the specified files just when the operation is really performed (i.e. ecore_con_url_get() is called). So if ecore_con_url_cookies_clear() is called before ecore_con_url_get(), the old cookies may not have been loaded yet, so they are not cleared. To avoid having old cookies loaded, don't add any cookie file with ecore_con_url_cookies_file_add().

The function ecore_con_url_cookies_clear() is just useful to clear cookies that are already loaded/valid in the Ecore_Con_Url object (from a previous request, for example).