#include "main.h"
#include "message.h"
#include "html.h"
+#include "url.h"
sig_atomic_t tags_sorted = 0;
return bsearch (&key, tag_defs, G_N_ELEMENTS (tag_defs), sizeof (struct html_tag), tag_cmp);
}
+static void
+parse_tag_url (struct worker_task *task, struct mime_text_part *part, tag_id_t id, char *tag_text)
+{
+ char *c = NULL, *p;
+ int len, rc;
+ char *url_text;
+ struct uri *url;
+ gboolean got_quote = FALSE;
+
+ /* For A tags search for href= and for IMG tags search for src= */
+ if (id == Tag_A) {
+ c = strcasestr (tag_text, "href=");
+ len = sizeof ("href=") - 1;
+ }
+ else if (id == Tag_IMG) {
+ c = strcasestr (tag_text, "src=");
+ len = sizeof ("src=") - 1;
+ }
+
+ if (c != NULL) {
+ /* First calculate length */
+ c += len;
+ len = 0;
+ p = c;
+ while (*p) {
+ if (*p == '\r' || *p == '\n' || (got_quote && *p == '"')) {
+ break;
+ }
+ if (*p != '"') {
+ got_quote = !got_quote;
+ len ++;
+ }
+ p ++;
+ }
+
+ if (got_quote) {
+ c++;
+ }
+
+ url_text = memory_pool_alloc (task->task_pool, len + 1);
+ g_strlcpy (url_text, c, len + 1);
+ url = memory_pool_alloc (task->task_pool, sizeof (struct uri));
+ rc = parse_uri (url, url_text, task->task_pool);
+
+ if (rc != URI_ERRNO_EMPTY && rc != URI_ERRNO_NO_HOST) {
+ if (part->html_urls && g_tree_lookup (part->html_urls, url_text) == NULL) {
+ g_tree_insert (part->html_urls, url_text, url);
+ task->urls = g_list_prepend (task->urls, url);
+ }
+ }
+ }
+}
+
gboolean
-add_html_node (memory_pool_t *pool, struct mime_text_part *part, char *tag_text, GNode **cur_level)
+add_html_node (struct worker_task *task, memory_pool_t *pool, struct mime_text_part *part, char *tag_text, GNode **cur_level)
{
GNode *new;
struct html_node *data;
part->html_nodes = new;
memory_pool_add_destructor (pool, (pool_destruct_func)g_node_destroy, part->html_nodes);
/* Call once again with root node */
- return add_html_node (pool, part, tag_text, cur_level);
+ return add_html_node (task, pool, part, tag_text, cur_level);
}
else {
new = construct_html_node (pool, tag_text);
return -1;
}
data = new->data;
+ if (data->tag->id == Tag_A || data->tag->id == Tag_IMG) {
+ parse_tag_url (task, part, data->tag->id, tag_text);
+ }
if (data->flags & FL_CLOSING) {
if (! *cur_level) {
msg_debug ("add_html_node: bad parent node");
int flags;
};
-gboolean add_html_node (memory_pool_t *pool, struct mime_text_part *part, char *tag_text, GNode **cur_level);
+/* Forwarded declaration */
+struct worker_task;
+
+gboolean add_html_node (struct worker_task *task, memory_pool_t *pool, struct mime_text_part *part, char *tag_text, GNode **cur_level);
struct html_tag * get_tag_by_name (const char *name);
#endif
#include "modules.h"
GByteArray*
-strip_html_tags (memory_pool_t *pool, struct mime_text_part *part, GByteArray *src, int *stateptr)
+strip_html_tags (struct worker_task *task, memory_pool_t *pool, struct mime_text_part *part, GByteArray *src, int *stateptr)
{
uint8_t *tbuf = NULL, *p, *tp = NULL, *rp, *tbegin = NULL, c, lc;
int br, i = 0, depth = 0, in_q = 0;
lc = '>';
in_q = state = 0;
*p = '\0';
- add_html_node (pool, part, tbegin, &level_ptr);
+ add_html_node (task, pool, part, tbegin, &level_ptr);
*p = '>';
break;
text_part->is_html = TRUE;
text_part->is_balanced = TRUE;
text_part->html_nodes = NULL;
- text_part->content = strip_html_tags (task->task_pool, text_part, part_content, NULL);
+
text_part->html_urls = g_tree_new ( (GCompareFunc)g_ascii_strcasecmp);
text_part->urls = g_tree_new ( (GCompareFunc)g_ascii_strcasecmp);
+ text_part->content = strip_html_tags (task, task->task_pool, text_part, part_content, NULL);
+
if (text_part->html_nodes == NULL) {
url_parse_text (task->task_pool, task, text_part, FALSE);
}
string intact, make a copy before calling this function. */
static void
-url_unescape (char *s)
+url_unescape (char *s, unsigned int *len)
{
char *t = s; /* t - tortoise */
char *h = s; /* h - hare */
goto copychar;
*t = c;
h += 2;
+ *len -=2;
}
}
*t = '\0';
don't), but to support binary characters (which will have been
converted to %HH by reencode_escapes). */
if (strchr (uri->host, '%')) {
- url_unescape (uri->host);
+ url_unescape (uri->host, &uri->hostlen);
}
path_simplify (uri->data);
if (new != NULL) {
rc = parse_uri (new, url_str, pool);
if (rc != URI_ERRNO_EMPTY && rc != URI_ERRNO_NO_HOST) {
- g_tree_insert (is_html ? part->html_urls : part->urls, url_str, new);
- task->urls = g_list_prepend (task->urls, new);
+ if (g_tree_lookup (is_html ? part->html_urls : part->urls, url_str) == NULL) {
+ g_tree_insert (is_html ? part->html_urls : part->urls, url_str, new);
+ task->urls = g_list_prepend (task->urls, new);
+ }
}
}
}