12e863645aef61e4b27cc40c8d44d50b2d7eb9df
[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 http::http()
16 {
17     curl = curl_easy_init();
18     curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
19     curl_easy_setopt(curl, CURLOPT_TIMEOUT, HTTP_GET_TIMEOUT);
20     curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);
21     curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
22     curl_easy_setopt(curl, CURLOPT_TCP_KEEPIDLE, 120L);
23     curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, 60L);
24     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, http::curl_write_data);
25     stream = NULL;
26 }
27
28 http::~http()
29 {
30     curl_easy_cleanup(curl);
31     destroy_giostream();
32 }
33
34 size_t http::curl_write_data(char* ptr, size_t size, size_t nmemb, void* data_ptr) {
35     struct Data* data = (struct Data *) data_ptr;
36     size_t realsize = size * nmemb;
37     
38     char *input = (char *) g_realloc(data->memory, data->size + realsize + 1);
39     if(input == NULL) {
40         /* out of memory! */
41         g_warning("not enough memory (realloc returned NULL)");
42         return 0;
43     }
44     
45     data->memory = input;
46     memcpy(&(data->memory[data->size]), ptr, realsize);
47     data->size += realsize;
48     data->memory[data->size] = 0;
49     
50     return realsize;
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