#include #include #include #include #include #include #include "glibcurl.h" #include "config.h" #include "web.h" #include "web_request.h" #include "web_utils.h" WebRequest * web_request_copy (WebRequest *request) { WebRequest *new_request = g_new (WebRequest, 1); new_request->url = g_strdup (request->url); new_request->parent = request->parent; new_request->type = request->type; new_request->data = request->data; new_request->handle = request->handle; return new_request; } void web_request_free (WebRequest *request) { g_free (request->url); g_free (request); } gint web_request_find_cb (gconstpointer a, gconstpointer b) { WebRequest *request = (WebRequest *)a; const gchar *string = (const gchar *)b; return strcmp (request->url, string); } void web_request_close (WebRequest *request) { CURLMsg *msg; CURL *handle; int in_queue; while (1) { if (!request) { msg = curl_multi_info_read ( glibcurl_handle (), &in_queue); if (!msg) break; if (msg->msg != CURLMSG_DONE) continue; if (curl_easy_getinfo (msg->easy_handle, CURLINFO_PRIVATE, &request) != CURLE_OK) request = NULL; handle = msg->easy_handle; } else handle = (CURL *)request->handle; if (request) { long error_code; gchar *url; gboolean keep_request = FALSE; request->parent->parent->backend->close ( request->parent->parent->backend_data, request->parent->page_data, request); request->parent->requests = g_list_remove ( request->parent->requests, request); if (curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &error_code) != CURLE_OK) error_code = 200; if (curl_easy_getinfo (handle, CURLINFO_EFFECTIVE_URL, &url) != CURLE_OK) url = NULL; /* g_debug ("Completed [%d] (%s)", error_code, url);*/ if (url && (strcmp (request->url, url) != 0)) { if ((error_code >= 300) && (error_code < 400)) { if (request->type == WEB_LINK) web_go (request->parent, request->url, TRUE); else if (request->type == WEB_DATA) { web_request_perform (request); keep_request = TRUE; } } g_free (url); } if (!keep_request) web_request_free (request); request = NULL; } glibcurl_remove(handle); curl_easy_cleanup (handle); } } static size_t web_request_header_cb (void *buffer, size_t size, size_t nmemb, void *userp) { WebRequest *request = userp; gint real_size = (gint)(size *nmemb); gchar *header; header = g_strndup (buffer, real_size); /* g_debug ("Header received: %s", header);*/ if (strstr (header, "Location: ")) { const gchar *end = strstr (header + 10, "\r"); request->url = end ? g_strndup (header + 10, end - (header + 10)) : g_strdup (header + 10); } g_free (header); return (size_t)real_size; } void web_request_remove (WebRequest *request) { /* g_debug ("Removing request (%s)", request->url);*/ glibcurl_remove(request->handle); curl_easy_cleanup (request->handle); request->parent->requests = g_list_remove ( request->parent->requests, request); web_request_free (request); } static size_t web_request_read_cb (void *buffer, size_t size, size_t nmemb, void *userp) { WebRequest *request = userp; gint real_size = (gint)(size * nmemb); if (real_size > 0) request->parent->parent->backend->write ( request->parent->parent->backend_data, request->parent->page_data, request, (gchar *)buffer, real_size); return (size_t)real_size; } void web_request_perform (WebRequest *request) { CURL *handle = curl_easy_init(); if (request->type == WEB_LINK) g_debug ("Url[%d] requested: %s", request->type, request->url); request->parent->requests = g_list_append ( request->parent->requests, request); request->handle = handle; curl_easy_setopt (handle, CURLOPT_URL, request->url); curl_easy_setopt (handle, CURLOPT_WRITEFUNCTION, web_request_read_cb); curl_easy_setopt (handle, CURLOPT_WRITEDATA, request); /* curl_easy_setopt (handle, CURLOPT_FOLLOWLOCATION, TRUE);*/ curl_easy_setopt (handle, CURLOPT_PRIVATE, request); curl_easy_setopt (handle, CURLOPT_HEADERFUNCTION, web_request_header_cb); curl_easy_setopt (handle, CURLOPT_HEADERDATA, request); glibcurl_add (handle); } void web_request_init () { glibcurl_init (); glibcurl_set_callback(web_request_close, NULL); }