summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Bursa <james@netsurf-browser.org>2003-08-29 12:57:14 +0000
committerJames Bursa <james@netsurf-browser.org>2003-08-29 12:57:14 +0000
commit5c310d84dc6153b62e33d5aa28a1f75e2e776ea6 (patch)
treea7efa6f8fb1a1b27bb1939bd569b7b3a7115e4d7
parentbe34d32e4677f4d2c527d157cf0016ac8d8ad798 (diff)
downloadnetsurf-5c310d84dc6153b62e33d5aa28a1f75e2e776ea6.tar.gz
netsurf-5c310d84dc6153b62e33d5aa28a1f75e2e776ea6.tar.bz2
[project @ 2003-08-29 12:57:14 by bursa]
Better handling of server HTTP errors. svn path=/import/netsurf/; revision=259
-rw-r--r--!NetSurf/Resources/en/Messages3
-rw-r--r--content/fetch.c79
-rw-r--r--content/fetch.h5
-rw-r--r--content/fetchcache.c5
-rw-r--r--content/fetchcache.h3
-rw-r--r--css/css.c6
-rw-r--r--debug/netsurfd.c3
-rw-r--r--desktop/browser.c2
-rw-r--r--render/html.c12
9 files changed, 71 insertions, 47 deletions
diff --git a/!NetSurf/Resources/en/Messages b/!NetSurf/Resources/en/Messages
index b1764fd95..5635197f5 100644
--- a/!NetSurf/Resources/en/Messages
+++ b/!NetSurf/Resources/en/Messages
@@ -25,3 +25,6 @@ Reload:Reload this page
# Download window
Downloaded:Download complete, %lu bytes
+
+Not2xx:Server returned an error
+
diff --git a/content/fetch.c b/content/fetch.c
index eb79afae3..300b68023 100644
--- a/content/fetch.c
+++ b/content/fetch.c
@@ -18,27 +18,30 @@
*/
#include <assert.h>
+#include <stdbool.h>
#include <string.h>
#include <strings.h>
#include <time.h>
#include "curl/curl.h"
#include "libxml/uri.h"
#include "netsurf/content/fetch.h"
-#include "netsurf/utils/utils.h"
-#include "netsurf/utils/log.h"
-#include "netsurf/desktop/options.h"
#ifdef riscos
#include "netsurf/desktop/gui.h"
#endif
+#include "netsurf/desktop/options.h"
+#include "netsurf/utils/log.h"
+#include "netsurf/utils/messages.h"
+#include "netsurf/utils/utils.h"
struct fetch
{
time_t start_time;
CURL * curl_handle;
void (*callback)(fetch_msg msg, void *p, char *data, unsigned long size);
- int had_headers : 1;
- int in_callback : 1;
- int aborting : 1;
+ bool had_headers;
+ bool in_callback;
+ bool aborting;
+ bool only_2xx;
char *url;
char *referer;
char error_buffer[CURL_ERROR_SIZE];
@@ -60,7 +63,7 @@ static struct fetch *fetch_list = 0;
static size_t fetch_curl_data(void * data, size_t size, size_t nmemb, struct fetch *f);
static size_t fetch_curl_header(char * data, size_t size, size_t nmemb, struct fetch *f);
-static int fetch_process_headers(struct fetch *f);
+static bool fetch_process_headers(struct fetch *f);
#ifdef riscos
extern const char * const NETSURF_DIR;
@@ -115,7 +118,8 @@ void fetch_quit(void)
*/
struct fetch * fetch_start(char *url, char *referer,
- void (*callback)(fetch_msg msg, void *p, char *data, unsigned long size), void *p)
+ void (*callback)(fetch_msg msg, void *p, char *data, unsigned long size),
+ void *p, bool only_2xx)
{
struct fetch *fetch = xcalloc(1, sizeof(*fetch)), *host_fetch;
CURLcode code;
@@ -133,9 +137,10 @@ struct fetch * fetch_start(char *url, char *referer,
/* construct a new fetch structure */
fetch->start_time = time(0);
fetch->callback = callback;
- fetch->had_headers = 0;
- fetch->in_callback = 0;
- fetch->aborting = 0;
+ fetch->had_headers = false;
+ fetch->in_callback = false;
+ fetch->aborting = false;
+ fetch->only_2xx = only_2xx;
fetch->url = xstrdup(url);
fetch->referer = 0;
if (referer != 0)
@@ -223,10 +228,10 @@ struct fetch * fetch_start(char *url, char *referer,
/* use proxy if options dictate this */
if (OPTIONS.http)
{
- code = curl_easy_setopt(fetch->curl_handle, CURLOPT_PROXY, OPTIONS.http_proxy);
- assert(code == CURLE_OK);
- code = curl_easy_setopt(fetch->curl_handle, CURLOPT_PROXYPORT, (long)OPTIONS.http_port);
- assert(code == CURLE_OK);
+ code = curl_easy_setopt(fetch->curl_handle, CURLOPT_PROXY, OPTIONS.http_proxy);
+ assert(code == CURLE_OK);
+ code = curl_easy_setopt(fetch->curl_handle, CURLOPT_PROXYPORT, (long)OPTIONS.http_port);
+ assert(code == CURLE_OK);
}
@@ -251,7 +256,7 @@ void fetch_abort(struct fetch *f)
if (f->in_callback) {
LOG(("in callback: will abort later"));
- f->aborting = 1;
+ f->aborting = true;
return;
}
@@ -325,7 +330,8 @@ void fetch_poll(void)
{
CURLcode code;
CURLMcode codem;
- int running, queue, finished;
+ int running, queue;
+ bool finished;
CURLMsg * curl_msg;
struct fetch *f;
void *p;
@@ -349,7 +355,7 @@ void fetch_poll(void)
LOG(("CURLMSG_DONE, result %i", curl_msg->data.result));
/* inform the caller that the fetch is done */
- finished = 0;
+ finished = false;
callback = f->callback;
p = f->p;
if (curl_msg->data.result == CURLE_OK) {
@@ -357,7 +363,7 @@ void fetch_poll(void)
if (!f->had_headers && fetch_process_headers(f))
; /* redirect with no body or similar */
else
- finished = 1;
+ finished = true;
} else if (curl_msg->data.result != CURLE_WRITE_ERROR) {
/* CURLE_WRITE_ERROR occurs when fetch_curl_data
* returns 0, which we use to abort intentionally */
@@ -387,18 +393,20 @@ void fetch_poll(void)
size_t fetch_curl_data(void * data, size_t size, size_t nmemb, struct fetch *f)
{
- f->in_callback = 1;
+ f->in_callback = true;
LOG(("fetch %p, size %u", f, size * nmemb));
- if (!f->had_headers && fetch_process_headers(f))
+ if (!f->had_headers && fetch_process_headers(f)) {
+ f->in_callback = false;
return 0;
+ }
/* send data to the caller */
LOG(("FETCH_DATA"));
f->callback(FETCH_DATA, f->p, data, size * nmemb);
- f->in_callback = 0;
+ f->in_callback = false;
return size * nmemb;
}
@@ -435,28 +443,37 @@ size_t fetch_curl_header(char * data, size_t size, size_t nmemb, struct fetch *f
/**
* Find the status code and content type and inform the caller.
+ *
+ * Return true if the fetch is being aborted.
*/
-int fetch_process_headers(struct fetch *f)
+bool fetch_process_headers(struct fetch *f)
{
long http_code;
const char *type;
CURLcode code;
- f->had_headers = 1;
+ f->had_headers = true;
code = curl_easy_getinfo(f->curl_handle, CURLINFO_HTTP_CODE, &http_code);
assert(code == CURLE_OK);
LOG(("HTTP status code %li", http_code));
+ /* handle HTTP redirects (3xx response codes) */
if (300 <= http_code && http_code < 400 && f->location != 0) {
- /* redirect */
LOG(("FETCH_REDIRECT, '%s'", f->location));
f->callback(FETCH_REDIRECT, f->p, f->location, 0);
- f->in_callback = 0;
- return 1;
+ return true;
}
+ /* handle HTTP errors (non 2xx response codes) */
+ if (f->only_2xx && strncmp(f->url, "http", 4) == 0 &&
+ (http_code < 200 || 299 < http_code)) {
+ f->callback(FETCH_ERROR, f->p, messages_get("Not2xx"), 0);
+ return true;
+ }
+
+ /* find MIME type from headers or filetype for local files */
code = curl_easy_getinfo(f->curl_handle, CURLINFO_CONTENT_TYPE, &type);
assert(code == CURLE_OK);
@@ -472,12 +489,10 @@ int fetch_process_headers(struct fetch *f)
LOG(("FETCH_TYPE, '%s'", type));
f->callback(FETCH_TYPE, f->p, type, f->content_length);
- if (f->aborting) {
- f->in_callback = 0;
- return 1;
- }
+ if (f->aborting)
+ return true;
- return 0;
+ return false;
}
diff --git a/content/fetch.h b/content/fetch.h
index 7bf144f44..cc52cd414 100644
--- a/content/fetch.h
+++ b/content/fetch.h
@@ -35,6 +35,8 @@
#ifndef _NETSURF_DESKTOP_FETCH_H_
#define _NETSURF_DESKTOP_FETCH_H_
+#include <stdbool.h>
+
typedef enum {FETCH_TYPE, FETCH_DATA, FETCH_FINISHED, FETCH_ERROR, FETCH_REDIRECT} fetch_msg;
struct content;
@@ -42,7 +44,8 @@ struct fetch;
void fetch_init(void);
struct fetch * fetch_start(char *url, char *referer,
- void (*callback)(fetch_msg msg, void *p, char *data, unsigned long size), void *p);
+ void (*callback)(fetch_msg msg, void *p, char *data, unsigned long size),
+ void *p, bool only_2xx);
void fetch_abort(struct fetch *f);
void fetch_poll(void);
void fetch_quit(void);
diff --git a/content/fetchcache.c b/content/fetchcache.c
index 1c950ba4b..4996edd81 100644
--- a/content/fetchcache.c
+++ b/content/fetchcache.c
@@ -21,7 +21,8 @@ static void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned lon
struct content * fetchcache(const char *url0, char *referer,
void (*callback)(content_msg msg, struct content *c, void *p1,
void *p2, const char *error),
- void *p1, void *p2, unsigned long width, unsigned long height)
+ void *p1, void *p2, unsigned long width, unsigned long height,
+ bool only_2xx)
{
struct content *c;
char *url = xstrdup(url0);
@@ -45,7 +46,7 @@ struct content * fetchcache(const char *url0, char *referer,
c->fetch_size = 0;
c->width = width;
c->height = height;
- c->fetch = fetch_start(url, referer, fetchcache_callback, c);
+ c->fetch = fetch_start(url, referer, fetchcache_callback, c, only_2xx);
if (c->fetch == 0) {
LOG(("warning: fetch_start failed"));
cache_destroy(c);
diff --git a/content/fetchcache.h b/content/fetchcache.h
index ddfc2fa76..6f7a083eb 100644
--- a/content/fetchcache.h
+++ b/content/fetchcache.h
@@ -13,6 +13,7 @@
struct content * fetchcache(const char *url, char *referer,
void (*callback)(content_msg msg, struct content *c, void *p1,
void *p2, const char *error),
- void *p1, void *p2, unsigned long width, unsigned long height);
+ void *p1, void *p2, unsigned long width, unsigned long height,
+ bool only_2xx);
#endif
diff --git a/css/css.c b/css/css.c
index da82cf9d1..91d0a061f 100644
--- a/css/css.c
+++ b/css/css.c
@@ -146,7 +146,7 @@ void css_revive(struct content *c, unsigned int width, unsigned int height)
c->data.css.import_content[i] = fetchcache(
c->data.css.import_url[i], c->url,
css_atimport_callback, c, i,
- c->width, c->height);
+ c->width, c->height, true);
if (c->data.css.import_content[i] == 0)
continue;
if (c->data.css.import_content[i]->status != CONTENT_STATUS_DONE)
@@ -297,7 +297,7 @@ void css_atimport(struct content *c, struct node *node)
c->data.css.import_url[i] = url_join(url, c->url);
c->data.css.import_content[i] = fetchcache(
c->data.css.import_url[i], c->url, css_atimport_callback,
- c, i, c->width, c->height);
+ c, i, c->width, c->height, true);
if (c->data.css.import_content[i] &&
c->data.css.import_content[i]->status != CONTENT_STATUS_DONE)
c->active++;
@@ -345,7 +345,7 @@ void css_atimport_callback(content_msg msg, struct content *css,
c->data.css.import_url[i] = xstrdup(error);
c->data.css.import_content[i] = fetchcache(
c->data.css.import_url[i], c->url, css_atimport_callback,
- c, i, css->width, css->height);
+ c, i, css->width, css->height, true);
if (c->data.css.import_content[i] &&
c->data.css.import_content[i]->status != CONTENT_STATUS_DONE)
c->active++;
diff --git a/debug/netsurfd.c b/debug/netsurfd.c
index 4d21a5495..d9f14d026 100644
--- a/debug/netsurfd.c
+++ b/debug/netsurfd.c
@@ -5,6 +5,7 @@
* Copyright 2003 James Bursa <bursa@users.sourceforge.net>
*/
+#include <stdbool.h>
#include <string.h>
#include "netsurf/content/fetch.h"
#include "netsurf/content/cache.h"
@@ -41,7 +42,7 @@ int main(int argc, char *argv[])
while (1) {
puts("=== URL:");
gets(url);
- c = fetchcache(url, 0, callback, 0, 0, 100, 1000);
+ c = fetchcache(url, 0, callback, 0, 0, 100, 1000, false);
if (c) {
done = c->status == CONTENT_STATUS_DONE;
while (!done)
diff --git a/desktop/browser.c b/desktop/browser.c
index d296ddaea..454a31085 100644
--- a/desktop/browser.c
+++ b/desktop/browser.c
@@ -233,7 +233,7 @@ void browser_window_open_location_historical(struct browser_window* bw, const ch
browser_window_start_throbber(bw);
bw->time0 = clock();
bw->loading_content = fetchcache(url, 0, browser_window_callback, bw, 0,
- gui_window_get_width(bw->window), 0);
+ gui_window_get_width(bw->window), 0, false);
if (bw->loading_content == 0) {
browser_window_set_status(bw, "Unable to fetch document");
return;
diff --git a/render/html.c b/render/html.c
index a6e6d9e7d..e41a61633 100644
--- a/render/html.c
+++ b/render/html.c
@@ -181,7 +181,7 @@ void html_convert_css_callback(content_msg msg, struct content *css,
c->active--;
c->data.html.stylesheet_content[i] = fetchcache(
error, c->url, html_convert_css_callback,
- c, i, css->width, css->height);
+ c, i, css->width, css->height, true);
if (c->data.html.stylesheet_content[i] != 0 &&
c->data.html.stylesheet_content[i]->status != CONTENT_STATUS_DONE)
c->active++;
@@ -234,7 +234,7 @@ void html_find_stylesheets(struct content *c, xmlNode *head)
#endif
c->url,
html_convert_css_callback,
- c, 0, c->width, c->height);
+ c, 0, c->width, c->height, true);
assert(c->data.html.stylesheet_content[0] != 0);
if (c->data.html.stylesheet_content[0]->status != CONTENT_STATUS_DONE)
c->active++;
@@ -285,7 +285,7 @@ void html_find_stylesheets(struct content *c, xmlNode *head)
(i + 1) * sizeof(*c->data.html.stylesheet_content));
c->data.html.stylesheet_content[i] = fetchcache(url, c->url,
html_convert_css_callback, c, i,
- c->width, c->height);
+ c->width, c->height, true);
if (c->data.html.stylesheet_content[i] &&
c->data.html.stylesheet_content[i]->status != CONTENT_STATUS_DONE)
c->active++;
@@ -368,7 +368,7 @@ void html_fetch_object(struct content *c, char *url, struct box *box)
c->data.html.object[i].content = fetchcache(url, c->url,
html_object_callback,
c, i,
- c->width, c->height); /* we don't know the object's
+ c->width, c->height, true); /* we don't know the object's
dimensions yet; use
parent's as an estimate */
if (c->data.html.object[i].content) {
@@ -463,7 +463,7 @@ void html_object_callback(content_msg msg, struct content *object,
c->data.html.object[i].url = xstrdup(error);
c->data.html.object[i].content = fetchcache(
error, c->url, html_object_callback,
- c, i, 0, 0);
+ c, i, 0, 0, true);
if (c->data.html.object[i].content &&
c->data.html.object[i].content->status != CONTENT_STATUS_DONE)
c->active++;
@@ -530,7 +530,7 @@ void html_revive(struct content *c, unsigned int width, unsigned int height)
c->data.html.object[i].content = fetchcache(
c->data.html.object[i].url, c->url,
html_object_callback,
- c, i, 0, 0);
+ c, i, 0, 0, true);
if (c->data.html.object[i].content &&
c->data.html.object[i].content->status != CONTENT_STATUS_DONE)
c->active++;