summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Mark Bell <jmb@netsurf-browser.org>2006-02-07 00:44:52 +0000
committerJohn Mark Bell <jmb@netsurf-browser.org>2006-02-07 00:44:52 +0000
commit6be0b8e60c81013ece5376779f4c3f30292c93c9 (patch)
treecf51ab910b64d55437daf67bb4d23b76470998a2
parent0f228ada91a9460d1042b1a854fb1a0a32ed3f10 (diff)
downloadnetsurf-6be0b8e60c81013ece5376779f4c3f30292c93c9.tar.gz
netsurf-6be0b8e60c81013ece5376779f4c3f30292c93c9.tar.bz2
[project @ 2006-02-07 00:44:52 by jmb]
Squash leaks and fake ETag header for local objects. svn path=/import/netsurf/; revision=2060
-rw-r--r--content/fetch.c71
1 files changed, 40 insertions, 31 deletions
diff --git a/content/fetch.c b/content/fetch.c
index 11f23feee..9f1b93652 100644
--- a/content/fetch.c
+++ b/content/fetch.c
@@ -69,6 +69,7 @@ struct fetch {
struct curl_httppost *post_multipart; /**< Multipart post data, or 0. */
struct cache_data cachedata; /**< Cache control data */
time_t last_modified; /**< If-Modified-Since time */
+ time_t file_etag; /**< ETag for local objects */
struct fetch *queue_prev; /**< Previous fetch for this host. */
struct fetch *queue_next; /**< Next fetch for this host. */
struct fetch *prev; /**< Previous active fetch in ::fetch_list. */
@@ -285,6 +286,7 @@ struct fetch * fetch_start(char *url, char *referer,
fetch->cachedata.no_cache = false;
fetch->cachedata.etag = 0;
fetch->last_modified = 0;
+ fetch->file_etag = 0;
fetch->queue_prev = 0;
fetch->queue_next = 0;
fetch->prev = 0;
@@ -338,6 +340,13 @@ struct fetch * fetch_start(char *url, char *referer,
/* do nothing */;
fetch->last_modified = curl_getdate(d, NULL);
}
+ else if (strncasecmp(headers[i], "If-None-Match:", 14) == 0) {
+ char *d = headers[i] + 14;
+ for (; *d && (*d == ' ' || *d == '\t' || *d == '"');
+ d++)
+ /* do nothing */;
+ fetch->file_etag = atoi(d);
+ }
APPEND(fetch->headers, headers[i]);
}
@@ -878,6 +887,7 @@ bool fetch_process_headers(struct fetch *f)
const char *type;
CURLcode code;
struct stat s;
+ char *url_path = 0;
f->had_headers = true;
@@ -889,28 +899,6 @@ bool fetch_process_headers(struct fetch *f)
assert(code == CURLE_OK);
LOG(("HTTP status code %li", http_code));
- if (f->last_modified) {
- /* Fake up HTTP cache control for local files */
- char *url_path = 0;
-
- if (strncmp(f->url, "file:///", 8) == 0) {
- url_path = curl_unescape(f->url + 7,
- (int) strlen(f->url) - 7);
- }
- else if (strncmp(f->url, "file:/", 6) == 0) {
- url_path = curl_unescape(f->url + 5,
- (int) strlen(f->url) - 5);
- }
-
- if (url_path && stat(url_path, &s) == 0) {
- if (f->last_modified > s.st_mtime) {
- f->callback(FETCH_NOTMODIFIED, f->p,
- (const char *)&f->cachedata, 0);
- return true;
- }
- }
- }
-
if (http_code == 304 && !f->post_urlenc && !f->post_multipart) {
/* Not Modified && GET request */
f->callback(FETCH_NOTMODIFIED, f->p,
@@ -944,21 +932,42 @@ bool fetch_process_headers(struct fetch *f)
code = curl_easy_getinfo(f->curl_handle, CURLINFO_CONTENT_TYPE, &type);
assert(code == CURLE_OK);
+ if (strncmp(f->url, "file:///", 8) == 0)
+ url_path = curl_unescape(f->url + 7,
+ (int) strlen(f->url) - 7);
+ else if (strncmp(f->url, "file:/", 6) == 0)
+ url_path = curl_unescape(f->url + 5,
+ (int) strlen(f->url) - 5);
+
+ if (url_path && stat(url_path, &s) == 0) {
+ /* file: URL and file exists */
+ /* create etag */
+ free(f->cachedata.etag);
+ f->cachedata.etag = malloc(13);
+ if (f->cachedata.etag)
+ sprintf(f->cachedata.etag,
+ "\"%10d\"", (int)s.st_mtime);
+
+ /* If performed a conditional request and unmodified ... */
+ if (f->last_modified && f->file_etag &&
+ f->last_modified > s.st_mtime &&
+ f->file_etag == s.st_mtime) {
+ f->callback(FETCH_NOTMODIFIED, f->p,
+ (const char *)&f->cachedata, 0);
+ curl_free(url_path);
+ return true;
+ }
+ }
+
if (type == 0) {
type = "text/html";
- if (strncmp(f->url, "file:///", 8) == 0) {
- char *url_path;
- url_path = curl_unescape(f->url + 7, (int) strlen(f->url) - 7);
- type = fetch_filetype(url_path);
- curl_free(url_path);
- } else if (strncmp(f->url, "file:/", 6) == 0) {
- char *url_path;
- url_path = curl_unescape(f->url + 5, (int) strlen(f->url) - 5);
+ if (url_path) {
type = fetch_filetype(url_path);
- curl_free(url_path);
}
}
+ curl_free(url_path);
+
LOG(("FETCH_TYPE, '%s'", type));
f->callback(FETCH_TYPE, f->p, type, f->content_length);
if (f->abort)