e6547ebffd9b95ecadb7e1823fea1de91d4ab596
[claws.git] / src / plugins / litehtml_viewer / http.cpp
1 #include <string.h>
2 #include "http.h"
3
4 struct Data {
5   char *memory;
6   size_t size;
7 };
8
9 http::http()
10 {
11     curl = curl_easy_init();
12     curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
13     curl_easy_setopt(curl, CURLOPT_TIMEOUT, HTTP_GET_TIMEOUT);
14     curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);
15     curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
16     curl_easy_setopt(curl, CURLOPT_TCP_KEEPIDLE, 120L);
17     curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, 60L);
18     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, http::curl_write_data);
19 }
20
21 http::~http()
22 {
23     curl_easy_cleanup(curl);
24 }
25
26 size_t http::curl_write_data(char* ptr, size_t size, size_t nmemb, void* data_ptr) {
27     struct Data* data = (struct Data *) data_ptr;
28     size_t realsize = size * nmemb;
29     
30     char *input = (char *) g_realloc(data->memory, data->size + realsize + 1);
31     if(input == NULL) {
32         /* out of memory! */
33         g_log(NULL, G_LOG_LEVEL_WARNING, "not enough memory (realloc returned NULL)");
34         return 0;
35     }
36     
37     data->memory = input;
38     memcpy(&(data->memory[data->size]), ptr, realsize);
39     data->size += realsize;
40     data->memory[data->size] = 0;
41     
42     return realsize;
43 }
44
45 void http::destroy_giostream(gpointer data) {
46     GInputStream* gio;
47     if (data) {
48         gio = G_INPUT_STREAM(data);
49         g_input_stream_close(gio, NULL, NULL);
50         gio = NULL;
51     }
52 }
53
54 GInputStream *http::load_url(const gchar *url, GError **error)
55 {
56     GError* _error = NULL;
57     CURLcode res = CURLE_OK;
58     gsize len;
59     gchar* content;
60     GInputStream* stream = NULL;
61     struct Data data;
62
63     data.memory = (char *) g_malloc(1);
64     data.size = 0;
65     
66     if (!strncmp(url, "file:///", 8) || g_file_test(url, G_FILE_TEST_EXISTS)) {
67         gchar* newurl = g_filename_from_uri(url, NULL, NULL);
68         if (g_file_get_contents(newurl ? newurl : url, &content, &len, &_error)) {
69             stream = g_memory_input_stream_new_from_data(content, len, http::destroy_giostream);
70         } else {
71             g_log(NULL, G_LOG_LEVEL_MESSAGE, "%s", _error->message);
72         }
73         g_free(newurl);
74     } else {
75         if (!curl) return NULL;
76         curl_easy_setopt(curl, CURLOPT_URL, url);
77         curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_data);
78         curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&data);
79         res = curl_easy_perform(curl);
80         if (res != CURLE_OK) {
81             _error = g_error_new_literal(G_FILE_ERROR, res, curl_easy_strerror(res));
82         } else {
83             stream = g_memory_input_stream_new_from_data(g_memdup(data.memory, data.size), data.size, http::destroy_giostream);
84             g_free(data.memory);
85         }
86     }
87
88     if (error && _error) *error = _error;
89
90     return stream;
91 }
92