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