1 /* Document (meta) refresh. */
2 
3 #ifdef HAVE_CONFIG_H
4 #include "config.h"
5 #endif
6 
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 
11 #include "elinks.h"
12 
13 #include "config/options.h"
14 #include "document/document.h"
15 #include "document/refresh.h"
16 #include "document/view.h"
17 #include "main/timer.h"
18 #include "protocol/uri.h"
19 #include "session/download.h"
20 #include "session/session.h"
21 #include "session/task.h"
22 #include "util/error.h"
23 #include "util/memory.h"
24 #include "util/string.h"
25 
26 
27 struct document_refresh *
init_document_refresh(unsigned char * url,unsigned long seconds)28 init_document_refresh(unsigned char *url, unsigned long seconds)
29 {
30 	struct document_refresh *refresh;
31 
32 	refresh = mem_alloc(sizeof(*refresh));
33 	if (!refresh) return NULL;
34 
35 	refresh->uri = get_uri(url, 0);
36 	if (!refresh->uri) {
37 		mem_free(refresh);
38 		return NULL;
39 	}
40 
41 	refresh->seconds = seconds;
42 	refresh->timer = TIMER_ID_UNDEF;
43 	refresh->restart = 1;
44 
45 	return refresh;
46 }
47 
48 void
kill_document_refresh(struct document_refresh * refresh)49 kill_document_refresh(struct document_refresh *refresh)
50 {
51 	kill_timer(&refresh->timer);
52 }
53 
54 void
done_document_refresh(struct document_refresh * refresh)55 done_document_refresh(struct document_refresh *refresh)
56 {
57 	kill_document_refresh(refresh);
58 	done_uri(refresh->uri);
59 	mem_free(refresh);
60 }
61 
62 static void
do_document_refresh(void * data)63 do_document_refresh(void *data)
64 {
65 	struct session *ses = data;
66 	struct document_refresh *refresh = ses->doc_view->document->refresh;
67 	struct type_query *type_query;
68 
69 	assert(refresh);
70 
71 	refresh->timer = TIMER_ID_UNDEF;
72 
73 	/* When refreshing documents that will trigger a download (like
74 	 * sourceforge's download pages) make sure that we do not endlessly
75 	 * trigger the download (bug 289). */
76 	foreach (type_query, ses->type_queries)
77 		if (compare_uri(refresh->uri, type_query->uri, URI_BASE))
78 			return;
79 
80 	if (compare_uri(refresh->uri, ses->doc_view->document->uri, 0)) {
81 		/* If the refreshing is for the current URI, force a reload. */
82 		reload(ses, CACHE_MODE_FORCE_RELOAD);
83 	} else {
84 		/* This makes sure that we send referer. */
85 		goto_uri_frame(ses, refresh->uri, NULL, CACHE_MODE_NORMAL);
86 		/* XXX: A possible very wrong work-around for refreshing used when
87 		 * downloading files. */
88 		refresh->restart = 0;
89 	}
90 }
91 
92 void
start_document_refresh(struct document_refresh * refresh,struct session * ses)93 start_document_refresh(struct document_refresh *refresh, struct session *ses)
94 {
95 	milliseconds_T minimum = (milliseconds_T) get_opt_int("document.browse.minimum_refresh_time");
96 	milliseconds_T refresh_delay = sec_to_ms(refresh->seconds);
97 	milliseconds_T time = ms_max(refresh_delay, minimum);
98 	struct type_query *type_query;
99 
100 	/* FIXME: This is just a work-around for stopping more than one timer
101 	 * from being started at anytime. The refresh timer should maybe belong
102 	 * to the session? The multiple refresh timers is triggered by
103 	 * http://ttforums.owenrudge.net/login.php when pressing 'Log in' and
104 	 * waiting for it to refresh. --jonas */
105 	if (!refresh->restart
106 	    || refresh->timer != TIMER_ID_UNDEF)
107 		return;
108 
109 	/* Like bug 289 another sourceforge download thingy this time with
110 	 * number 434. It should take care when refreshing to the same URI or
111 	 * what ever the cause is. */
112 	foreach (type_query, ses->type_queries)
113 		if (compare_uri(refresh->uri, type_query->uri, URI_BASE))
114 			return;
115 
116 	install_timer(&refresh->timer, time, do_document_refresh, ses);
117 }
118