git ssb

0+

cel / dillo-history



Tree: b9f9b0d3e41bae8e43e88364803fdbc7f7656dc1

Files: b9f9b0d3e41bae8e43e88364803fdbc7f7656dc1 / dillo-patch.diff

9671 bytesRaw
1diff --git a/src/cache.c b/src/cache.c
2index bdda48fd..6d2fa56b 100644
3--- a/src/cache.c
4+++ b/src/cache.c
5@@ -15,9 +15,12 @@
6
7 #include <sys/types.h>
8
9+#include <errno.h>
10 #include <limits.h>
11 #include <stdlib.h>
12 #include <string.h>
13+#include <time.h>
14+#include <unistd.h>
15
16 #include "msg.h"
17 #include "IO/Url.h"
18@@ -35,6 +38,8 @@
19 #include "timeout.hh"
20 #include "uicmd.hh"
21
22+#include <mbedtls/sha256.h>
23+
24 /* Maximum initial size for the automatically-growing data buffer */
25 #define MAX_INIT_BUF 1024*1024
26 /* Maximum filesize for a URL, before offering a download */
27@@ -62,6 +67,7 @@ typedef struct {
28 int ExpectedSize; /* Goal size of the HTTP transfer (0 if unknown)*/
29 int TransferSize; /* Actual length of the HTTP transfer */
30 uint_t Flags; /* See Flag Defines in cache.h */
31+ mbedtls_sha256_context Hash; /* sha256 hash state */
32 } CacheEntry_t;
33
34
35@@ -207,6 +213,7 @@ static void Cache_entry_init(CacheEntry_t *NewEntry, const DilloUrl *Url)
36 NewEntry->ExpectedSize = 0;
37 NewEntry->TransferSize = 0;
38 NewEntry->Flags = CA_IsEmpty | CA_InProgress | CA_KeepAlive;
39+ mbedtls_sha256_init(&NewEntry->Hash);
40 }
41
42 /*
43@@ -247,6 +254,7 @@ static CacheEntry_t *Cache_entry_search_with_redirect(const DilloUrl *Url)
44 */
45 static CacheEntry_t *Cache_entry_add(const DilloUrl *Url)
46 {
47+ int rc;
48 CacheEntry_t *old_entry, *new_entry;
49
50 if ((old_entry = Cache_entry_search(Url))) {
51@@ -256,6 +264,10 @@ static CacheEntry_t *Cache_entry_add(const DilloUrl *Url)
52
53 new_entry = dNew(CacheEntry_t, 1);
54 Cache_entry_init(new_entry, Url); /* Set safe values */
55+ rc = mbedtls_sha256_starts_ret(&new_entry->Hash, 0);
56+ if (rc < 0) {
57+ MSG_WARN("Failed to start SHA-256 calculation.\n");
58+ }
59 dList_insert_sorted(CachedURLs, new_entry, Cache_entry_cmp);
60 return new_entry;
61 }
62@@ -312,6 +324,7 @@ static void Cache_entry_free(CacheEntry_t *entry)
63 a_Decode_transfer_free(entry->TransferDecoder);
64 if (entry->ContentDecoder)
65 a_Decode_free(entry->ContentDecoder);
66+ mbedtls_sha256_init(&entry->Hash);
67 dFree(entry);
68 }
69
70@@ -845,6 +858,143 @@ static int Cache_get_header(CacheEntry_t *entry,
71 return 0;
72 }
73
74+static char *dGetblobsdir ()
75+{
76+ static char *blobsdir = NULL;
77+
78+ if (!blobsdir) {
79+ blobsdir = dStrconcat(dGethomedir(), "/.ssb/blobs", NULL);
80+ }
81+ return blobsdir;
82+}
83+
84+static int hash_to_path(char *buf, size_t *lenp, unsigned char id[32])
85+{
86+ int len = snprintf(buf, *lenp, "%s/sha256/%02x/"
87+ "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
88+ dGetblobsdir(),
89+ id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7],
90+ id[8], id[9], id[10], id[11], id[12], id[13], id[14], id[15],
91+ id[16], id[17], id[18], id[19], id[20], id[21], id[22], id[23],
92+ id[24], id[25], id[26], id[27], id[28], id[29], id[30], id[31]);
93+ if (len < 0 || len >= (int)*lenp) { errno = EMSGSIZE; return -1; }
94+ *lenp = len;
95+ return 0;
96+}
97+
98+static void Cache_finish_write(CacheEntry_t *entry)
99+{
100+ int rc;
101+ FILE *entry_fp, *history_fp;
102+ unsigned char hash_result[32];
103+ char *hash_b64;
104+ char filename_tmp[512], filename[512], history_filename[512];
105+ char history_line[512];
106+ char time_str[64];
107+ const char *url = URL_STR_(entry->Url);
108+ int url_len = strlen(url);
109+ size_t filename_len = sizeof(filename);
110+ size_t history_line_len;
111+ time_t tmp_time;
112+ static unsigned int tmp_i = 0;
113+
114+ rc = mbedtls_sha256_finish_ret(&entry->Hash, hash_result);
115+ if (rc < 0) {
116+ MSG_WARN("Failed to finish SHA-256 calculation.\n");
117+ return;
118+ }
119+
120+ hash_b64 = a_Misc_encode_base64_2((char *)hash_result, 32);
121+
122+ tmp_time = time(NULL);
123+ rc = snprintf(filename_tmp, sizeof(filename_tmp), "%s/tmp/%d-%d",
124+ dGetblobsdir(), (int)tmp_time, tmp_i++);
125+ if (rc < 0 || rc > (int)sizeof(filename_tmp)) {
126+ MSG_WARN("Failed to calculate filename.\n");
127+ return;
128+ }
129+
130+ rc = hash_to_path(filename, &filename_len, hash_result);
131+ if (rc < 0) {
132+ MSG_WARN("Failed to calculate path. %s\n", dStrerror(errno));
133+ unlink(filename);
134+ return;
135+ }
136+
137+ if (access(filename, F_OK) != 0) {
138+ entry_fp = fopen(filename_tmp, "w");
139+ if (entry_fp == NULL) {
140+ MSG_WARN("Unable to open file for writing. "
141+ "Error: %s. Filename: %s URL: %s\n",
142+ dStrerror(errno), filename_tmp, url);
143+ return;
144+ }
145+
146+ if (fwrite(entry->Data->str, (size_t)entry->Data->len, 1, entry_fp) != 1) {
147+ MSG_WARN("Failed to write blob file. %s\n", dStrerror(errno));
148+ fclose(entry_fp);
149+ unlink(filename_tmp);
150+ return;
151+ }
152+
153+ if (fclose(entry_fp) != 0) {
154+ MSG_WARN("Failed to close blob file. %s\n", dStrerror(errno));
155+ unlink(filename_tmp);
156+ return;
157+ }
158+
159+ rc = rename(filename_tmp, filename);
160+ if (rc < 0) {
161+ MSG_WARN("Failed to rename blob file. %s\n", dStrerror(errno));
162+ unlink(filename_tmp);
163+ return;
164+ }
165+ _MSG("Saved blob %s\n", filename);
166+ }
167+
168+ /* write it to history file */
169+
170+ rc = snprintf(history_filename, sizeof(history_filename),
171+ "%s/.dillo/history.txt",
172+ dGethomedir());
173+ if (rc < 0 || rc > (int)sizeof(history_filename)) {
174+ MSG_WARN("Failed to calculate history filename.\n");
175+ return;
176+ }
177+
178+ if (strftime(time_str, sizeof(time_str), "%F %T %z", gmtime(&tmp_time)) == 0) {
179+ MSG_WARN("Failed to format timestamp.\n");
180+ return;
181+ }
182+
183+ history_fp = fopen(history_filename, "a");
184+ if (history_fp == NULL) {
185+ MSG_WARN("Failed to open history file.\n");
186+ return;
187+ }
188+
189+ if (!strncmp(url, "data:", 5)) url_len = 0;
190+
191+ history_line_len = snprintf(history_line, sizeof(history_line),
192+ "%s\t&%s.sha256\t%.*s\n",
193+ time_str,
194+ hash_b64,
195+ url_len,
196+ url);
197+ if (history_line_len <= 0 || history_line_len > (int)sizeof(history_line)) {
198+ MSG_WARN("Failed to create history entry.\n");
199+ fclose(history_fp);
200+ return;
201+ }
202+
203+ if (fwrite(history_line, history_line_len, 1, history_fp) != 1) {
204+ MSG_WARN("Failed to write history entry. %s\n", dStrerror(errno));
205+ fclose(history_fp);
206+ return;
207+ }
208+ fclose(history_fp);
209+}
210+
211 static void Cache_finish_msg(CacheEntry_t *entry)
212 {
213 if (!(entry->Flags & CA_InProgress)) {
214@@ -872,6 +1022,8 @@ static void Cache_finish_msg(CacheEntry_t *entry)
215 }
216 dStr_fit(entry->Data); /* fit buffer size! */
217
218+ Cache_finish_write(entry);
219+
220 if ((entry = Cache_process_queue(entry))) {
221 if (entry->Flags & CA_GotHeader) {
222 Cache_unref_data(entry);
223@@ -891,6 +1043,7 @@ bool_t a_Cache_process_dbuf(int Op, const char *buf, size_t buf_size,
224 const DilloUrl *Url)
225 {
226 int offset, len;
227+ int rc;
228 const char *str;
229 Dstr *dstr1, *dstr2, *dstr3;
230 bool_t done = FALSE;
231@@ -932,6 +1085,10 @@ bool_t a_Cache_process_dbuf(int Op, const char *buf, size_t buf_size,
232 len = dstr2->len;
233 }
234 dStr_append_l(entry->Data, str, len);
235+ rc = mbedtls_sha256_update_ret(&entry->Hash, (unsigned char *)str, len);
236+ if (rc < 0) {
237+ MSG_WARN("Failed to update SHA-256 calculation.\n");
238+ }
239 if (entry->CharsetDecoder && entry->UTF8Data) {
240 dstr3 = a_Decode_process(entry->CharsetDecoder, str, len);
241 dStr_append_l(entry->UTF8Data, dstr3->str, dstr3->len);
242diff --git a/src/misc.c b/src/misc.c
243index 00589999..dfd85b50 100644
244--- a/src/misc.c
245+++ b/src/misc.c
246@@ -456,6 +456,40 @@ char *a_Misc_encode_base64(const char *in)
247 return out;
248 }
249
250+char *a_Misc_encode_base64_2(const char *in, int len)
251+{
252+ static const char *const base64_hex = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
253+ "abcdefghijklmnopqrstuvwxyz"
254+ "0123456789+/";
255+ char *out = NULL;
256+ int i = 0;
257+
258+ if (in == NULL) return NULL;
259+
260+ out = (char *)dMalloc((len + 2) / 3 * 4 + 1);
261+
262+ for (; len >= 3; len -= 3) {
263+ out[i++] = base64_hex[in[0] >> 2];
264+ out[i++] = base64_hex[((in[0]<<4) & 0x30) | (in[1]>>4)];
265+ out[i++] = base64_hex[((in[1]<<2) & 0x3c) | (in[2]>>6)];
266+ out[i++] = base64_hex[in[2] & 0x3f];
267+ in += 3;
268+ }
269+
270+ if (len > 0) {
271+ unsigned char fragment;
272+ out[i++] = base64_hex[in[0] >> 2];
273+ fragment = (in[0] << 4) & 0x30;
274+ if (len > 1) fragment |= in[1] >> 4;
275+ out[i++] = base64_hex[fragment];
276+ out[i++] = (len < 2) ? '=' : base64_hex[(in[1] << 2) & 0x3c];
277+ out[i++] = '=';
278+ }
279+ out[i] = '\0';
280+ return out;
281+}
282+
283+
284 /*
285 * Load a local file into a dStr.
286 * Return value: dStr on success, NULL on error.
287diff --git a/src/misc.h b/src/misc.h
288index 75f0f78a..340dd45e 100644
289--- a/src/misc.h
290+++ b/src/misc.h
291@@ -19,6 +19,7 @@ int a_Misc_content_type_cmp(const char* ct1, const char *ct2);
292 int a_Misc_parse_geometry(char *geom, int *x, int *y, int *w, int *h);
293 int a_Misc_parse_search_url(char *source, char **label, char **urlstr);
294 char *a_Misc_encode_base64(const char *in);
295+char *a_Misc_encode_base64_2(const char *in, int len);
296 Dstr *a_Misc_file2dstr(const char *filename);
297
298 #ifdef __cplusplus
299

Built with git-ssb-web