Author: bursa
Date: Sat Jan 13 00:21:15 2007
New Revision: 3140
URL:
http://svn.semichrome.net?rev=3140&view=rev
Log:
Fix parsing error when an empty HTML data is returned. Add HTTP status and other
information to status bar.
Modified:
trunk/netsurf/!NetSurf/Resources/en/Messages
trunk/netsurf/content/content.c
trunk/netsurf/content/content.h
trunk/netsurf/content/fetchcache.c
trunk/netsurf/desktop/browser.c
trunk/netsurf/desktop/browser.h
trunk/netsurf/render/html.c
Modified: trunk/netsurf/!NetSurf/Resources/en/Messages
URL:
http://svn.semichrome.net/trunk/netsurf/%21NetSurf/Resources/en/Messages?...
==============================================================================
--- trunk/netsurf/!NetSurf/Resources/en/Messages (original)
+++ trunk/netsurf/!NetSurf/Resources/en/Messages Sat Jan 13 00:21:15 2007
@@ -450,11 +450,7 @@
Redirecting:Redirecting...
Processing:Processing document
Formatting:Formatting document
-FetchObjs:Loading %u %s
-FetchObjs2:Loading %u %s: %s
Done:Document done
-FetchStyle:Loading %u %s
-FetchStyle2:Loading %u %s: %s
# Fetch warning/error messages - displayed in status bar
#
@@ -471,6 +467,47 @@
MNGError:MNG library error.
BadSprite:Invalid or corrupt Sprite data.
+# HTTP status codes
+#
+HTTP0:OK
+HTTP200:OK
+HTTP201:Created
+HTTP202:Accepted
+HTTP203:Non-authoritative information
+HTTP204:No content
+HTTP205:Reset content
+HTTP206:Partial content
+HTTP300:Multiple choices
+HTTP301:Moved permanently
+HTTP302:Found
+HTTP303:See other
+HTTP304:Not modified
+HTTP305:Use proxy
+HTTP307:Temporary redirect
+HTTP400:Bad request
+HTTP401:Unauthorized
+HTTP402:Payment required
+HTTP403:Forbidden
+HTTP404:Not found
+HTTP405:Method not allowed
+HTTP406:Not acceptable
+HTTP407:Proxy authentication required
+HTTP408:Request timeout
+HTTP409:Conflict
+HTTP410:Gone
+HTTP411:Length required
+HTTP412:Precondition failed
+HTTP413:Request entity too large
+HTTP414:Request-URI too long
+HTTP415:Unsupported media type
+HTTP416:Requested range not satisfiable
+HTTP417:Expectation failed
+HTTP500:Internal server error
+HTTP501:Not implemented
+HTTP502:Bad gateway
+HTTP503:Service unavailable
+HTTP504:Gateway timeout
+HTTP505:HTTP version not supported
# User interface
# ==============
Modified: trunk/netsurf/content/content.c
URL:
http://svn.semichrome.net/trunk/netsurf/content/content.c?rev=3140&r1...
==============================================================================
--- trunk/netsurf/content/content.c (original)
+++ trunk/netsurf/content/content.c Sat Jan 13 00:21:15 2007
@@ -2,7 +2,7 @@
* This file is part of NetSurf,
http://netsurf-browser.org/
* Licensed under the GNU General Public License,
*
http://www.opensource.org/licenses/gpl-license
- * Copyright 2005 James Bursa <bursa(a)users.sourceforge.net>
+ * Copyright 2005-2007 James Bursa <bursa(a)users.sourceforge.net>
*/
/** \file
@@ -18,6 +18,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <time.h>
#include "netsurf/utils/config.h"
#include "netsurf/content/content.h"
#include "netsurf/content/fetch.h"
@@ -304,6 +305,7 @@
#define HANDLER_MAP_COUNT (sizeof(handler_map) / sizeof(handler_map[0]))
+static void content_update_status(struct content *c);
static void content_destroy(struct content *c);
static void content_stop_check(struct content *c);
@@ -373,6 +375,7 @@
c->refresh = 0;
c->bitmap = 0;
c->fresh = false;
+ c->time = clock();
c->size = 0;
c->title = 0;
c->active = 0;
@@ -380,13 +383,14 @@
user_sentinel->p1 = user_sentinel->p2 = 0;
user_sentinel->next = 0;
c->user_list = user_sentinel;
- content_set_status(c, messages_get("Loading"));
+ c->sub_status[0] = 0;
c->locked = false;
c->fetch = 0;
c->source_data = 0;
c->source_size = 0;
c->source_allocated = 0;
c->total_size = 0;
+ c->http_code = 0;
c->no_error_pages = false;
c->download = false;
c->error_count = 0;
@@ -399,6 +403,8 @@
c->cache_data->no_cache = false;
c->cache_data->etag = 0;
c->cache_data->last_modified = 0;
+
+ content_set_status(c, messages_get("Loading"));
c->prev = 0;
c->next = content_list;
@@ -592,11 +598,38 @@
int len;
va_start(ap, status_message);
- if ((len = vsnprintf(c->status_message, sizeof (c->status_message),
+ if ((len = vsnprintf(c->sub_status, sizeof (c->sub_status),
status_message, ap)) < 0 ||
- (int)sizeof (c->status_message) <= len)
- c->status_message[sizeof (c->status_message) - 1] = '\0';
+ (int)sizeof (c->sub_status) <= len)
+ c->sub_status[sizeof (c->sub_status) - 1] = '\0';
va_end(ap);
+
+ content_update_status(c);
+}
+
+
+void content_update_status(struct content *c)
+{
+ char token[20];
+ const char *status;
+ clock_t time;
+
+ snprintf(token, sizeof token, "HTTP%li", c->http_code);
+ status = messages_get(token);
+ if (status == token)
+ status = token + 4;
+
+ if (c->status == CONTENT_STATUS_TYPE_UNKNOWN ||
+ c->status == CONTENT_STATUS_LOADING ||
+ c->status == CONTENT_STATUS_READY)
+ time = clock() - c->time;
+ else
+ time = c->time;
+
+ snprintf(c->status_message, sizeof (c->status_message),
+ "%s (%.1fs) %s", status,
+ (float) time / CLOCKS_PER_SEC, c->sub_status);
+ /* LOG(("%s", c->status_message)); */
}
@@ -704,7 +737,22 @@
c->status == CONTENT_STATUS_DONE);
content_broadcast(c, CONTENT_MSG_READY, msg_data);
if (c->status == CONTENT_STATUS_DONE)
- content_broadcast(c, CONTENT_MSG_DONE, msg_data);
+ content_set_done(c);
+}
+
+
+/**
+ * Put a content in status CONTENT_STATUS_DONE.
+ */
+
+void content_set_done(struct content *c)
+{
+ union content_msg_data msg_data;
+
+ c->status = CONTENT_STATUS_DONE;
+ c->time = clock() - c->time;
+ content_update_status(c);
+ content_broadcast(c, CONTENT_MSG_DONE, msg_data);
}
Modified: trunk/netsurf/content/content.h
URL:
http://svn.semichrome.net/trunk/netsurf/content/content.h?rev=3140&r1...
==============================================================================
--- trunk/netsurf/content/content.h (original)
+++ trunk/netsurf/content/content.h Sat Jan 13 00:21:15 2007
@@ -2,7 +2,7 @@
* This file is part of NetSurf,
http://netsurf-browser.org/
* Licensed under the GNU General Public License,
*
http://www.opensource.org/licenses/gpl-license
- * Copyright 2005 James Bursa <bursa(a)users.sourceforge.net>
+ * Copyright 2005-2007 James Bursa <bursa(a)users.sourceforge.net>
* Copyright 2003 Philip Pemberton <philpem(a)users.sourceforge.net>
*/
@@ -16,6 +16,7 @@
#define _NETSURF_DESKTOP_CONTENT_H_
#include <stdint.h>
+#include <time.h>
#include "netsurf/utils/config.h"
#include "netsurf/content/content_type.h"
#include "netsurf/css/css.h"
@@ -178,6 +179,9 @@
* shared between users. */
bool fresh;
struct cache_data *cache_data; /**< Cache control data */
+ clock_t time; /**< Creation time, if TYPE_UNKNOWN,
+ LOADING or READY,
+ otherwise total time. */
unsigned int size; /**< Estimated size of all data
associated with this content, except
@@ -186,7 +190,8 @@
unsigned int active; /**< Number of child fetches or
conversions currently in progress. */
struct content_user *user_list; /**< List of users. */
- char status_message[80]; /**< Text for status bar. */
+ char status_message[120]; /**< Full text for status bar. */
+ char sub_status[80]; /**< Status of content. */
/** Content is being processed: data structures may be inconsistent
* and content must not be redrawn or modified. */
bool locked;
@@ -196,6 +201,7 @@
unsigned long source_size; /**< Amount of data fetched so far. */
unsigned long source_allocated; /**< Amount of space allocated so far. */
unsigned long total_size; /**< Total data size, 0 if unknown. */
+ long http_code; /**< HTTP status code, 0 if not HTTP. */
bool no_error_pages; /**< Used by fetchcache(). */
bool download; /**< Used by fetchcache(). */
@@ -226,6 +232,7 @@
bool content_process_data(struct content *c, const char *data,
unsigned int size);
void content_convert(struct content *c, int width, int height);
+void content_set_done(struct content *c);
void content_reformat(struct content *c, int width, int height);
void content_clean(void);
void content_reset(struct content *c);
Modified: trunk/netsurf/content/fetchcache.c
URL:
http://svn.semichrome.net/trunk/netsurf/content/fetchcache.c?rev=3140&...
==============================================================================
--- trunk/netsurf/content/fetchcache.c (original)
+++ trunk/netsurf/content/fetchcache.c Sat Jan 13 00:21:15 2007
@@ -376,6 +376,7 @@
switch (msg) {
case FETCH_TYPE:
c->total_size = size;
+ c->http_code = fetch_http_code(c->fetch);
mime_type = fetchcache_parse_type(data, ¶ms);
if (!mime_type) {
msg_data.error = messages_get("NoMemory");
Modified: trunk/netsurf/desktop/browser.c
URL:
http://svn.semichrome.net/trunk/netsurf/desktop/browser.c?rev=3140&r1...
==============================================================================
--- trunk/netsurf/desktop/browser.c (original)
+++ trunk/netsurf/desktop/browser.c Sat Jan 13 00:21:15 2007
@@ -20,7 +20,6 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
-#include <time.h>
#include "curl/curl.h"
#include "netsurf/utils/config.h"
#include "netsurf/content/fetch.h"
@@ -286,7 +285,6 @@
browser_window_set_status(bw, messages_get("Loading"));
bw->history_add = history_add;
- bw->time0 = clock();
c = fetchcache(url2, browser_window_callback, (intptr_t) bw, 0,
width, height, false,
post_urlenc, post_multipart, true, download);
@@ -347,6 +345,7 @@
url[sizeof url - 1] = 0;
gui_window_set_url(bw->window, url);
bw->refresh_interval = -1;
+ browser_window_set_status(bw, c->status_message);
}
break;
@@ -414,10 +413,7 @@
assert(bw->current_content == c);
browser_window_update(bw, false);
- sprintf(status, messages_get("Complete"),
- ((float) (clock() - bw->time0)) /
- CLOCKS_PER_SEC);
- browser_window_set_status(bw, status);
+ browser_window_set_status(bw, c->status_message);
browser_window_stop_throbber(bw);
history_update(bw->history, c);
hotlist_visited(c);
Modified: trunk/netsurf/desktop/browser.h
URL:
http://svn.semichrome.net/trunk/netsurf/desktop/browser.h?rev=3140&r1...
==============================================================================
--- trunk/netsurf/desktop/browser.h (original)
+++ trunk/netsurf/desktop/browser.h Sat Jan 13 00:21:15 2007
@@ -74,8 +74,6 @@
bool throbbing;
/** Add loading_content to the window history when it loads. */
bool history_add;
- /** Start time of fetching loading_content. */
- clock_t time0;
/** Fragment identifier for current_content. */
char *frag_id;
Modified: trunk/netsurf/render/html.c
URL:
http://svn.semichrome.net/trunk/netsurf/render/html.c?rev=3140&r1=313...
==============================================================================
--- trunk/netsurf/render/html.c (original)
+++ trunk/netsurf/render/html.c Sat Jan 13 00:21:15 2007
@@ -55,6 +55,20 @@
static void html_object_refresh(void *p);
static void html_destroy_frameset(struct content_html_frames *frameset);
static void html_destroy_iframe(struct content_html_iframe *iframe);
+static void html_set_status(struct content *c, const char *extra);
+
+static const char empty_document[] =
+ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\""
+ " \"http://www.w3.org/TR/html4/strict.dtd\">"
+ "<html>"
+ "<head>"
+ "<title>Empty document</title>"
+ "</head>"
+ "<body>"
+ "<h1>Empty document</h1>"
+ "<p>The document sent by the server is empty.</p>"
+ "</body>"
+ "</html>";
/**
@@ -264,11 +278,15 @@
union content_msg_data msg_data;
/* finish parsing */
+ if (c->source_size == 0)
+ htmlParseChunk(c->data.html.parser, empty_document,
+ sizeof empty_document, 0);
htmlParseChunk(c->data.html.parser, "", 0, 1);
document = c->data.html.parser->myDoc;
/*xmlDebugDumpDocument(stderr, c->data.html.parser->myDoc);*/
htmlFreeParserCtxt(c->data.html.parser);
c->data.html.parser = 0;
+
if (!document) {
LOG(("Parsing failed"));
msg_data.error = messages_get("ParsingFail");
@@ -353,135 +371,21 @@
xmlFreeDoc(document);
/* layout the box tree */
- content_set_status(c, messages_get("Formatting"));
+ html_set_status(c, messages_get("Formatting"));
content_broadcast(c, CONTENT_MSG_STATUS, msg_data);
LOG(("Layout document"));
html_reformat(c, width, height);
/*box_dump(c->data.html.layout->children, 0);*/
- if (c->active == 0) {
+ if (c->active == 0)
c->status = CONTENT_STATUS_DONE;
- content_set_status(c, messages_get("Done"));
- } else {
+ else
c->status = CONTENT_STATUS_READY;
- content_set_status(c, messages_get("FetchObjs"), c->active,
- messages_get((c->active == 1) ? "obj" : "objs"));
- }
+ html_set_status(c, "");
return true;
}
-/**
- * Search for meta refresh
- *
- *
http://wp.netscape.com/assist/net_sites/pushpull.html
- *
- * \param c content structure
- * \param head xml node of head element
- * \return true on success, false otherwise (error reported)
- */
-
-bool html_meta_refresh(struct content *c, xmlNode *head)
-{
- xmlNode *n;
- xmlChar *equiv, *content;
- union content_msg_data msg_data;
- char *url, *end, *refresh;
- url_func_result res;
-
- for (n = head == 0 ? 0 : head->children; n; n = n->next) {
- if (n->type != XML_ELEMENT_NODE)
- continue;
-
- if (strcmp((const char *)n->name, "meta"))
- continue;
-
- equiv = xmlGetProp(n, (const xmlChar *)"http-equiv");
- if (!equiv)
- continue;
-
- if (strcasecmp((const char *)equiv, "refresh")) {
- xmlFree(equiv);
- continue;
- }
-
- xmlFree(equiv);
-
- content = xmlGetProp(n, (const xmlChar *)"content");
- if (!content)
- continue;
-
- end = (char *)content + strlen(content);
-
- msg_data.delay = (int)strtol((char *) content, &url, 10);
-
- if (url == end) {
- /* Just delay specified, so refresh current page */
- xmlFree(content);
-
- c->refresh = talloc_strdup(c, c->url);
- if (!c->refresh) {
- msg_data.error = messages_get("NoMemory");
- content_broadcast(c,
- CONTENT_MSG_ERROR, msg_data);
- return false;
- }
-
- content_broadcast(c, CONTENT_MSG_REFRESH, msg_data);
- break;
- }
-
- for ( ; url <= end - 4; url++) {
- if (!strncasecmp(url, "url=", 4))
- break;
- }
-
- /*
mail.google.com sends out the broken format "<n>,
url='<url>'", so
- * special case this */
- if (url <= end - 4) {
- if ((url[4] == '\'') && (end[-1] == '\'')) {
- *--end = '\0';
- url++;
- }
- }
-
- if (url <= end - 4) {
- res = url_join(url + 4, c->data.html.base_url,
- &refresh);
-
- xmlFree(content);
-
- if (res == URL_FUNC_NOMEM) {
- msg_data.error = messages_get("NoMemory");
- content_broadcast(c,
- CONTENT_MSG_ERROR, msg_data);
- return false;
- }
- else if (res == URL_FUNC_FAILED) {
- /* This isn't fatal so carry on looking */
- continue;
- }
-
- c->refresh = talloc_strdup(c, refresh);
-
- free(refresh);
-
- if (!c->refresh) {
- msg_data.error = messages_get("NoMemory");
- content_broadcast(c,
- CONTENT_MSG_ERROR, msg_data);
- return false;
- }
-
- content_broadcast(c, CONTENT_MSG_REFRESH, msg_data);
- break;
- }
-
- xmlFree(content);
- }
-
- return true;
-}
/**
* Process elements in <head>.
@@ -549,6 +453,119 @@
}
}
}
+ return true;
+}
+
+
+/**
+ * Search for meta refresh
+ *
+ *
http://wp.netscape.com/assist/net_sites/pushpull.html
+ *
+ * \param c content structure
+ * \param head xml node of head element
+ * \return true on success, false otherwise (error reported)
+ */
+
+bool html_meta_refresh(struct content *c, xmlNode *head)
+{
+ xmlNode *n;
+ xmlChar *equiv, *content;
+ union content_msg_data msg_data;
+ char *url, *end, *refresh;
+ url_func_result res;
+
+ for (n = head == 0 ? 0 : head->children; n; n = n->next) {
+ if (n->type != XML_ELEMENT_NODE)
+ continue;
+
+ if (strcmp((const char *)n->name, "meta"))
+ continue;
+
+ equiv = xmlGetProp(n, (const xmlChar *)"http-equiv");
+ if (!equiv)
+ continue;
+
+ if (strcasecmp((const char *)equiv, "refresh")) {
+ xmlFree(equiv);
+ continue;
+ }
+
+ xmlFree(equiv);
+
+ content = xmlGetProp(n, (const xmlChar *)"content");
+ if (!content)
+ continue;
+
+ end = (char *)content + strlen(content);
+
+ msg_data.delay = (int)strtol((char *) content, &url, 10);
+
+ if (url == end) {
+ /* Just delay specified, so refresh current page */
+ xmlFree(content);
+
+ c->refresh = talloc_strdup(c, c->url);
+ if (!c->refresh) {
+ msg_data.error = messages_get("NoMemory");
+ content_broadcast(c,
+ CONTENT_MSG_ERROR, msg_data);
+ return false;
+ }
+
+ content_broadcast(c, CONTENT_MSG_REFRESH, msg_data);
+ break;
+ }
+
+ for ( ; url <= end - 4; url++) {
+ if (!strncasecmp(url, "url=", 4))
+ break;
+ }
+
+ /*
mail.google.com sends out the broken format "<n>,
url='<url>'", so
+ * special case this */
+ if (url <= end - 4) {
+ if ((url[4] == '\'') && (end[-1] == '\'')) {
+ *--end = '\0';
+ url++;
+ }
+ }
+
+ if (url <= end - 4) {
+ res = url_join(url + 4, c->data.html.base_url,
+ &refresh);
+
+ xmlFree(content);
+
+ if (res == URL_FUNC_NOMEM) {
+ msg_data.error = messages_get("NoMemory");
+ content_broadcast(c,
+ CONTENT_MSG_ERROR, msg_data);
+ return false;
+ }
+ else if (res == URL_FUNC_FAILED) {
+ /* This isn't fatal so carry on looking */
+ continue;
+ }
+
+ c->refresh = talloc_strdup(c, refresh);
+
+ free(refresh);
+
+ if (!c->refresh) {
+ msg_data.error = messages_get("NoMemory");
+ content_broadcast(c,
+ CONTENT_MSG_ERROR, msg_data);
+ return false;
+ }
+
+ content_broadcast(c, CONTENT_MSG_REFRESH, msg_data);
+ break;
+ }
+
+ xmlFree(content);
+ }
+
return true;
}
@@ -762,9 +779,7 @@
/* complete the fetches */
while (c->active != 0) {
if (c->active != last_active) {
- content_set_status(c, messages_get("FetchStyle"),
- c->active,
- messages_get((c->active == 1) ? "styl" : "styls"));
+ html_set_status(c, "");
content_broadcast(c, CONTENT_MSG_STATUS, msg_data);
last_active = c->active;
}
@@ -820,7 +835,7 @@
c->data.html.stylesheet_content[i] = 0;
c->active--;
content_add_error(c, "NotCSS", 0);
- content_set_status(c, messages_get("NotCSS"));
+ html_set_status(c, messages_get("NotCSS"));
content_broadcast(c, CONTENT_MSG_STATUS, data);
content_remove_user(css,
html_convert_css_callback,
@@ -854,10 +869,7 @@
break;
case CONTENT_MSG_STATUS:
- content_set_status(c, messages_get("FetchStyle2"),
- c->active,
- messages_get((c->active == 1) ? "styl" : "styls"),
- css->status_message);
+ html_set_status(c, css->status_message);
content_broadcast(c, CONTENT_MSG_STATUS, data);
break;
@@ -1063,7 +1075,7 @@
c->data.html.object[i].content = 0;
c->active--;
content_add_error(c, "?", 0);
- content_set_status(c, messages_get("BadObject"));
+ html_set_status(c, messages_get("BadObject"));
content_broadcast(c, CONTENT_MSG_STATUS, data);
content_remove_user(object, html_object_callback,
(intptr_t) c, i);
@@ -1094,18 +1106,14 @@
c->data.html.object[i].content = 0;
c->active--;
content_add_error(c, "?", 0);
- content_set_status(c, messages_get("ObjError"),
- data.error);
+ html_set_status(c, data.error);
content_broadcast(c, CONTENT_MSG_STATUS, data);
html_object_failed(box, c,
c->data.html.object[i].background);
break;
case CONTENT_MSG_STATUS:
- content_set_status(c, messages_get("FetchObjs2"),
- c->active,
- messages_get((c->active == 1) ? "obj" : "objs"),
- object->status_message);
+ html_set_status(c, object->status_message);
/* content_broadcast(c, CONTENT_MSG_STATUS, 0); */
break;
@@ -1202,13 +1210,11 @@
msg == CONTENT_MSG_AUTH)) {
/* all objects have arrived */
content_reformat(c, c->available_width, c->height);
- c->status = CONTENT_STATUS_DONE;
- content_set_status(c, messages_get("Done"));
- content_broadcast(c, CONTENT_MSG_DONE, data);
+ html_set_status(c, "");
+ content_set_done(c);
}
if (c->status == CONTENT_STATUS_READY)
- content_set_status(c, messages_get("FetchObjs"), c->active,
- messages_get((c->active == 1) ? "obj" : "objs"));
+ html_set_status(c, "");
}
@@ -1537,6 +1543,30 @@
/**
+ * Set the content status.
+ */
+
+void html_set_status(struct content *c, const char *extra)
+{
+ unsigned int stylesheets = 0, objects = 0;
+ if (c->data.html.object_count == 0)
+ stylesheets = c->data.html.stylesheet_count - c->active;
+ else {
+ stylesheets = c->data.html.stylesheet_count;
+ objects = c->data.html.object_count - c->active;
+ }
+ content_set_status(c, "%u/%u %s %u/%u %s %s",
+ stylesheets, c->data.html.stylesheet_count,
+ messages_get((c->data.html.stylesheet_count == 1) ?
+ "styl" : "styls"),
+ objects, c->data.html.object_count,
+ messages_get((c->data.html.object_count == 1) ?
+ "obj" : "objs"),
+ extra);
+}
+
+
+/**
* Handle a window containing a CONTENT_HTML being opened.
*/