[project @ 2003-12-26 00:17:55 by bursa]

New url_join using liburi, <base href=...>.

svn path=/import/netsurf/; revision=441
This commit is contained in:
James Bursa 2003-12-26 00:17:55 +00:00
parent 3b4de07169
commit f1b59814f8
12 changed files with 214 additions and 189 deletions

View File

@ -602,6 +602,11 @@ bool fetch_process_headers(struct fetch *f)
url_path = curl_unescape(f->url + 8, (int) strlen(f->url) - 8); url_path = curl_unescape(f->url + 8, (int) strlen(f->url) - 8);
type = fetch_filetype(url_path); type = fetch_filetype(url_path);
curl_free(url_path); curl_free(url_path);
} else if (strncmp(f->url, "file:/", 6) == 0) {
char *url_path;
url_path = curl_unescape(f->url + 6, (int) strlen(f->url) - 6);
type = fetch_filetype(url_path);
curl_free(url_path);
} }
} }

View File

@ -147,8 +147,12 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size)
/* redirect URLs must be absolute by HTTP/1.1, but many sites send /* redirect URLs must be absolute by HTTP/1.1, but many sites send
* relative ones: treat them as relative to requested URL */ * relative ones: treat them as relative to requested URL */
url = url_join(data, c->url); url = url_join(data, c->url);
if (url) {
content_broadcast(c, CONTENT_MSG_REDIRECT, url); content_broadcast(c, CONTENT_MSG_REDIRECT, url);
xfree(url); xfree(url);
} else {
content_broadcast(c, CONTENT_MSG_ERROR, "Bad redirect");
}
if (c->cache) if (c->cache)
cache_destroy(c); cache_destroy(c);
content_destroy(c); content_destroy(c);

View File

@ -129,29 +129,25 @@ int css_convert(struct content *c, unsigned int width, unsigned int height)
buffer = css__scan_buffer(c->data.css.data, c->data.css.length + 2, buffer = css__scan_buffer(c->data.css.data, c->data.css.length + 2,
c->data.css.css->lexer); c->data.css.css->lexer);
assert(buffer); assert(buffer);
while ((token = css_lex(c->data.css.css->lexer)) && while (token = css_lex(c->data.css.css->lexer)) {
!param.syntax_error) {
css_parser_(c->data.css.css->parser, token, css_parser_(c->data.css.css->parser, token,
xstrdup(css_get_text(c->data.css.css->lexer)), xstrdup(css_get_text(c->data.css.css->lexer)),
&param); &param);
if (param.syntax_error) {
int line = css_get_lineno(c->data.css.css->lexer);
LOG(("syntax error near line %i", line));
param.syntax_error = false;
}
} }
css__delete_buffer(buffer, c->data.css.css->lexer); css__delete_buffer(buffer, c->data.css.css->lexer);
free(c->data.css.data); free(c->data.css.data);
if (!param.syntax_error)
css_parser_(c->data.css.css->parser, 0, 0, &param); css_parser_(c->data.css.css->parser, 0, 0, &param);
css_parser_Free(c->data.css.css->parser, free); css_parser_Free(c->data.css.css->parser, free);
if (param.syntax_error) {
int line = css_get_lineno(c->data.css.css->lexer);
css_lex_destroy(c->data.css.css->lexer);
LOG(("syntax error near line %i", line));
/*css_destroy(c);*/
return 1;
}
css_lex_destroy(c->data.css.css->lexer); css_lex_destroy(c->data.css.css->lexer);
css_dump_stylesheet(c->data.css.css); /*css_dump_stylesheet(c->data.css.css);*/
/* complete fetch of any imported stylesheets */ /* complete fetch of any imported stylesheets */
while (c->active != 0) { while (c->active != 0) {
@ -261,7 +257,7 @@ char *css_unquote(char *s)
void css_atimport(struct content *c, struct css_node *node) void css_atimport(struct content *c, struct css_node *node)
{ {
char *s, *url; char *s, *url, *url1;
int string = 0, screen = 1; int string = 0, screen = 1;
unsigned int i; unsigned int i;
@ -322,6 +318,12 @@ void css_atimport(struct content *c, struct css_node *node)
return; return;
} }
url1 = url_join(url, c->url);
if (!url1) {
free(url);
return;
}
/* start the fetch */ /* start the fetch */
c->data.css.import_count++; c->data.css.import_count++;
c->data.css.import_url = xrealloc(c->data.css.import_url, c->data.css.import_url = xrealloc(c->data.css.import_url,
@ -330,7 +332,7 @@ void css_atimport(struct content *c, struct css_node *node)
c->data.css.import_count * sizeof(*c->data.css.import_content)); c->data.css.import_count * sizeof(*c->data.css.import_content));
i = c->data.css.import_count - 1; i = c->data.css.import_count - 1;
c->data.css.import_url[i] = url_join(url, c->url); c->data.css.import_url[i] = url1;
c->data.css.import_content[i] = fetchcache( c->data.css.import_content[i] = fetchcache(
c->data.css.import_url[i], c->url, css_atimport_callback, c->data.css.import_url[i], c->url, css_atimport_callback,
c, i, c->width, c->height, true, 0, 0); c, i, c->width, c->height, true, 0, 0);

View File

@ -251,6 +251,8 @@ void browser_window_open_location_post(struct browser_window* bw,
LOG(("bw = %p, url = %s", bw, url)); LOG(("bw = %p, url = %s", bw, url));
assert(bw != 0 && url != 0); assert(bw != 0 && url != 0);
url1 = url_join(url, 0); url1 = url_join(url, 0);
if (!url1)
return;
browser_window_open_location_historical(bw, url1, post_urlenc, post_multipart); browser_window_open_location_historical(bw, url1, post_urlenc, post_multipart);
bw->history_add = true; bw->history_add = true;
free(url1); free(url1);
@ -292,14 +294,11 @@ void browser_window_callback(content_msg msg, struct content *c,
previous_safety = gui_window_set_redraw_safety(bw->window, UNSAFE); previous_safety = gui_window_set_redraw_safety(bw->window, UNSAFE);
if (bw->loading_content == c) { if (bw->loading_content == c) {
struct gui_message gmsg;
if (bw->url != 0) if (bw->url != 0)
xfree(bw->url); xfree(bw->url);
bw->url = xstrdup(c->url); bw->url = xstrdup(c->url);
gmsg.type = msg_SET_URL; gui_window_set_url(bw->window, bw->url);
gmsg.data.set_url.url = bw->url;
gui_window_message(bw->window, &gmsg);
if (bw->current_content != NULL) if (bw->current_content != NULL)
{ {
@ -1215,26 +1214,28 @@ void browser_window_follow_link(struct browser_window* bw,
continue; continue;
if (click_boxes[i].box->href != NULL) if (click_boxes[i].box->href != NULL)
{ {
char *url = url_join((char*) click_boxes[i].box->href,
bw->current_content->data.html.base_url);
if (!url)
continue;
if (click_type == 1) { if (click_type == 1) {
char *url = url_join((char*) click_boxes[i].box->href, bw->url);
browser_window_open_location(bw, url); browser_window_open_location(bw, url);
free(url);
} }
else if (click_type == 2) else if (click_type == 2)
{ {
char *url = url_join((char*) click_boxes[i].box->href, bw->url);
struct browser_window* bw_new; struct browser_window* bw_new;
bw_new = create_browser_window(browser_TITLE | browser_TOOLBAR bw_new = create_browser_window(browser_TITLE | browser_TOOLBAR
| browser_SCROLL_X_ALWAYS | browser_SCROLL_Y_ALWAYS, 640, 480, NULL); | browser_SCROLL_X_ALWAYS | browser_SCROLL_Y_ALWAYS, 640, 480, NULL);
gui_window_show(bw_new->window); gui_window_show(bw_new->window);
browser_window_open_location(bw_new, url); browser_window_open_location(bw_new, url);
free(url);
} }
else if (click_type == 0) else if (click_type == 0)
{ {
browser_window_set_status(bw, (char*) click_boxes[i].box->href); browser_window_set_status(bw, url);
done = 1; done = 1;
} }
free(url);
break; break;
} }
if (click_type == 0 && click_boxes[i].box->title != NULL) if (click_type == 0 && click_boxes[i].box->title != NULL)
@ -1572,37 +1573,37 @@ void browser_window_redraw_boxes(struct browser_window* bw, struct box_position*
void browser_form_submit(struct browser_window *bw, struct form *form, void browser_form_submit(struct browser_window *bw, struct form *form,
struct form_control *submit_button) struct form_control *submit_button)
{ {
char *data, *url, *url1; char *data = 0, *url = 0, *url1 = 0, *base;
struct form_successful_control *success; struct form_successful_control *success;
assert(form); assert(form);
assert(bw->current_content->type == CONTENT_HTML);
success = form_successful_controls(form, submit_button); success = form_successful_controls(form, submit_button);
base = bw->current_content->data.html.base_url;
switch (form->method) { switch (form->method) {
case method_GET: case method_GET:
data = form_url_encode(success); data = form_url_encode(success);
url = xcalloc(1, strlen(form->action) + strlen(data) + 2); url = xcalloc(1, strlen(form->action) + strlen(data) + 2);
sprintf(url, "%s?%s", form->action, data); sprintf(url, "%s?%s", form->action, data);
url1 = url_join(url, bw->url); url1 = url_join(url, base);
free(data); if (!url1)
free(url); break;
browser_window_open_location(bw, url1); browser_window_open_location(bw, url1);
free(url1);
break; break;
case method_POST_URLENC: case method_POST_URLENC:
data = form_url_encode(success); data = form_url_encode(success);
url = url_join(form->action, bw->url); url = url_join(form->action, base);
if (!url)
break;
browser_window_open_location_post(bw, url, data, 0); browser_window_open_location_post(bw, url, data, 0);
free(url);
free(data);
break; break;
case method_POST_MULTIPART: case method_POST_MULTIPART:
url = url_join(form->action, bw->url); url = url_join(form->action, base);
browser_window_open_location_post(bw, url, 0, success); browser_window_open_location_post(bw, url, 0, success);
free(url);
break; break;
default: default:
@ -1610,4 +1611,7 @@ void browser_form_submit(struct browser_window *bw, struct form *form,
} }
form_free_successful(success); form_free_successful(success);
free(data);
free(url);
free(url1);
} }

View File

@ -18,18 +18,6 @@ typedef struct gui_window gui_window;
#include <stdbool.h> #include <stdbool.h>
#include "netsurf/desktop/browser.h" #include "netsurf/desktop/browser.h"
struct gui_message
{
enum { msg_SET_URL } type;
union {
struct {
char* url;
} set_url;
} data;
};
typedef struct gui_message gui_message;
gui_window *gui_create_browser_window(struct browser_window *bw); gui_window *gui_create_browser_window(struct browser_window *bw);
gui_window *gui_create_download_window(struct content *content); gui_window *gui_create_download_window(struct content *content);
void gui_window_destroy(gui_window* g); void gui_window_destroy(gui_window* g);
@ -43,8 +31,7 @@ unsigned long gui_window_get_width(gui_window* g);
void gui_window_set_extent(gui_window* g, unsigned long width, unsigned long height); void gui_window_set_extent(gui_window* g, unsigned long width, unsigned long height);
void gui_window_set_status(gui_window* g, const char* text); void gui_window_set_status(gui_window* g, const char* text);
void gui_window_set_title(gui_window* g, char* title); void gui_window_set_title(gui_window* g, char* title);
void gui_window_set_url(gui_window *g, char *url);
void gui_window_message(gui_window* g, gui_message* msg);
void gui_download_window_update_status(gui_window *g); void gui_download_window_update_status(gui_window *g);
void gui_download_window_done(gui_window *g); void gui_download_window_done(gui_window *g);

View File

@ -31,8 +31,9 @@ WARNFLAGS = -W -Wall -Wundef -Wpointer-arith -Wbad-function-cast -Wcast-qual \
CFLAGS = -std=c9x -D_BSD_SOURCE -Driscos -DBOOL_DEFINED -O $(WARNFLAGS) -I.. \ CFLAGS = -std=c9x -D_BSD_SOURCE -Driscos -DBOOL_DEFINED -O $(WARNFLAGS) -I.. \
-mpoke-function-name -mpoke-function-name
CFLAGS_DEBUG = -std=c9x -D_BSD_SOURCE $(WARNFLAGS) -I.. -I/usr/include/libxml2 -g CFLAGS_DEBUG = -std=c9x -D_BSD_SOURCE $(WARNFLAGS) -I.. -I/usr/include/libxml2 -g
LDFLAGS = -L/riscos/lib -lxml2 -lz -lcurl -lssl -lcrypto -lares -lanim -lpng -lifc -loslib LDFLAGS = -L/riscos/lib -lxml2 -lz -lcurl -lssl -lcrypto -lares -lanim -lpng \
LDFLAGS_DEBUG = -L/usr/lib -lxml2 -lz -lm -lcurl -lssl -lcrypto -ldl -lifc -loslib -luri
LDFLAGS_DEBUG = -L/usr/lib -lxml2 -lz -lm -lcurl -lssl -lcrypto -ldl -luri
OBJDIR = $(shell $(CC) -dumpmachine) OBJDIR = $(shell $(CC) -dumpmachine)
SOURCES=$(OBJECTS:.o=.c) SOURCES=$(OBJECTS:.o=.c)

View File

@ -706,7 +706,10 @@ struct result box_image(xmlNode *n, struct status *status,
if (!(s = (char *) xmlGetProp(n, (const xmlChar *) "src"))) if (!(s = (char *) xmlGetProp(n, (const xmlChar *) "src")))
return (struct result) {box, 0}; return (struct result) {box, 0};
url = url_join(s, status->content->url); url = url_join(s, status->content->data.html.base_url);
if (!url)
return (struct result) {box, 0};
LOG(("image '%s'", url)); LOG(("image '%s'", url));
xmlFree(s); xmlFree(s);
@ -1014,7 +1017,8 @@ struct result box_input(xmlNode *n, struct status *status,
gadget->box = box; gadget->box = box;
gadget->type = GADGET_IMAGE; gadget->type = GADGET_IMAGE;
if ((s = (char *) xmlGetProp(n, (const xmlChar*) "src"))) { if ((s = (char *) xmlGetProp(n, (const xmlChar*) "src"))) {
url = url_join(s, status->content->url); url = url_join(s, status->content->data.html.base_url);
if (url)
html_fetch_object(status->content, url, box); html_fetch_object(status->content, url, box);
xmlFree(s); xmlFree(s);
} }
@ -1673,9 +1677,13 @@ struct result box_object(xmlNode *n, struct status *status,
/* object data */ /* object data */
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "data"))) { if ((s = (char *) xmlGetProp(n, (const xmlChar *) "data"))) {
url = url_join(s, status->content->data.html.base_url);
if (!url) {
free(po);
xmlFree(s);
return (struct result) {box, 1};
}
po->data = strdup(s); po->data = strdup(s);
url = url_join(strdup(s), status->content->url);
LOG(("object '%s'", po->data)); LOG(("object '%s'", po->data));
xmlFree(s); xmlFree(s);
} }
@ -1797,10 +1805,14 @@ struct result box_embed(xmlNode *n, struct status *status,
/* embed src */ /* embed src */
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "src"))) { if ((s = (char *) xmlGetProp(n, (const xmlChar *) "src"))) {
url = url_join(s, status->content->data.html.base_url);
po->data = strdup(s); if (!url) {
url = url_join(strdup(s), status->content->url); free(po);
xmlFree(s);
return (struct result) {box, 0};
}
LOG(("embed '%s'", url)); LOG(("embed '%s'", url));
po->data = strdup(s);
xmlFree(s); xmlFree(s);
} }
@ -1863,10 +1875,14 @@ struct result box_applet(xmlNode *n, struct status *status,
/* code */ /* code */
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "code"))) { if ((s = (char *) xmlGetProp(n, (const xmlChar *) "code"))) {
url = url_join(s, status->content->data.html.base_url);
po->classid = strdup(s); if (!url) {
url = url_join(strdup(s), status->content->url); free(po);
xmlFree(s);
return (struct result) {box, 1};
}
LOG(("applet '%s'", url)); LOG(("applet '%s'", url));
po->classid = strdup(s);
xmlFree(s); xmlFree(s);
} }
@ -1962,10 +1978,14 @@ struct result box_iframe(xmlNode *n, struct status *status,
/* iframe src */ /* iframe src */
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "src"))) { if ((s = (char *) xmlGetProp(n, (const xmlChar *) "src"))) {
url = url_join(s, status->content->data.html.base_url);
po->data = strdup(s); if (!url) {
url = url_join(strdup(s), status->content->url); free(po);
xmlFree(s);
return (struct result) {box, 0};
}
LOG(("embed '%s'", url)); LOG(("embed '%s'", url));
po->data = strdup(s);
xmlFree(s); xmlFree(s);
} }
@ -1985,22 +2005,27 @@ struct result box_iframe(xmlNode *n, struct status *status,
* necessary as there are multiple ways of declaring an object's attributes. * necessary as there are multiple ways of declaring an object's attributes.
* *
* Returns false if the object could not be handled. * Returns false if the object could not be handled.
*
* TODO: reformat, plug failure leaks
*/ */
bool plugin_decode(struct content* content, char* url, struct box* box, bool plugin_decode(struct content* content, char* url, struct box* box,
struct object_params* po) struct object_params* po)
{ {
struct plugin_params * pp; struct plugin_params * pp;
/* Set basehref */
po->basehref = strdup(content->url);
/* Check if the codebase attribute is defined. /* Check if the codebase attribute is defined.
* If it is not, set it to the codebase of the current document. * If it is not, set it to the codebase of the current document.
*/ */
if(po->codebase == 0) if(po->codebase == 0)
po->codebase = url_join("./", content->url); po->codebase = url_join("./", content->data.html.base_url);
else else
po->codebase = url_join(po->codebase, content->url); po->codebase = url_join(po->codebase, content->data.html.base_url);
if (!po->codebase)
return false;
/* Set basehref */
po->basehref = strdup(content->data.html.base_url);
/* Check that we have some data specified. /* Check that we have some data specified.
* First, check the data attribute. * First, check the data attribute.
@ -2019,11 +2044,16 @@ bool plugin_decode(struct content* content, char* url, struct box* box,
for(pp = po->params; pp != 0 && for(pp = po->params; pp != 0 &&
(strcasecmp(pp->name, "movie") != 0); (strcasecmp(pp->name, "movie") != 0);
pp = pp->next); pp = pp->next);
if(pp != 0) if(pp == 0)
return false;
url = url_join(pp->value, po->basehref); url = url_join(pp->value, po->basehref);
else return false; if (!url)
return false;
/* munge the codebase */ /* munge the codebase */
po->codebase = url_join("./", content->url); po->codebase = url_join("./",
content->data.html.base_url);
if (!po->codebase)
return false;
} }
else { else {
LOG(("ActiveX object - n0")); LOG(("ActiveX object - n0"));
@ -2032,6 +2062,8 @@ bool plugin_decode(struct content* content, char* url, struct box* box,
} }
else { else {
url = url_join(po->classid, po->codebase); url = url_join(po->classid, po->codebase);
if (!url)
return false;
/* The java plugin doesn't need the .class extension /* The java plugin doesn't need the .class extension
* so we strip it. * so we strip it.
@ -2043,6 +2075,8 @@ bool plugin_decode(struct content* content, char* url, struct box* box,
} }
else { else {
url = url_join(po->data, po->codebase); url = url_join(po->data, po->codebase);
if (!url)
return false;
} }
/* Check if the declared mime type is understandable. /* Check if the declared mime type is understandable.

View File

@ -23,7 +23,7 @@
static void html_convert_css_callback(content_msg msg, struct content *css, static void html_convert_css_callback(content_msg msg, struct content *css,
void *p1, void *p2, const char *error); void *p1, void *p2, const char *error);
static void html_title(struct content *c, xmlNode *head); static void html_head(struct content *c, xmlNode *head);
static void html_find_stylesheets(struct content *c, xmlNode *head); static void html_find_stylesheets(struct content *c, xmlNode *head);
static void html_object_callback(content_msg msg, struct content *object, static void html_object_callback(content_msg msg, struct content *object,
void *p1, void *p2, const char *error); void *p1, void *p2, const char *error);
@ -37,6 +37,7 @@ void html_create(struct content *c)
c->data.html.fonts = NULL; c->data.html.fonts = NULL;
c->data.html.length = 0; c->data.html.length = 0;
c->data.html.source = xcalloc(0, 1); c->data.html.source = xcalloc(0, 1);
c->data.html.base_url = xstrdup(c->url);
c->data.html.background_colour = TRANSPARENT; c->data.html.background_colour = TRANSPARENT;
} }
@ -96,7 +97,7 @@ int html_convert(struct content *c, unsigned int width, unsigned int height)
} }
if (head != 0) if (head != 0)
html_title(c, head); html_head(c, head);
/* get stylesheets */ /* get stylesheets */
html_find_stylesheets(c, head); html_find_stylesheets(c, head);
@ -203,19 +204,31 @@ void html_convert_css_callback(content_msg msg, struct content *css,
} }
void html_title(struct content *c, xmlNode *head)
/**
* Process elements in <head>.
*/
void html_head(struct content *c, xmlNode *head)
{ {
xmlNode *node; xmlNode *node;
xmlChar *title;
c->title = 0; c->title = 0;
for (node = head->children; node != 0; node = node->next) { for (node = head->children; node != 0; node = node->next) {
if (strcmp(node->name, "title") == 0) { if (!c->title && strcmp(node->name, "title") == 0) {
title = xmlNodeGetContent(node); xmlChar *title = xmlNodeGetContent(node);
c->title = squash_tolat1(title); c->title = squash_tolat1(title);
xmlFree(title); xmlFree(title);
return;
} else if (strcmp(node->name, "base") == 0) {
char *href = (char *) xmlGetProp(node, (const xmlChar *) "href");
if (href) {
char *url = url_join(href, 0);
if (url)
c->data.html.base_url = url;
xmlFree(href);
}
} }
} }
} }
@ -286,9 +299,12 @@ void html_find_stylesheets(struct content *c, xmlNode *head)
/* TODO: only the first preferred stylesheets (ie. those with a /* TODO: only the first preferred stylesheets (ie. those with a
* title attribute) should be loaded (see HTML4 14.3) */ * title attribute) should be loaded (see HTML4 14.3) */
url = url_join(href, c->url); url = url_join(href, c->data.html.base_url);
LOG(("linked stylesheet %i '%s'", i, url));
xmlFree(href); xmlFree(href);
if (!url)
continue;
LOG(("linked stylesheet %i '%s'", i, url));
/* start fetch */ /* start fetch */
c->data.html.stylesheet_content = xrealloc(c->data.html.stylesheet_content, c->data.html.stylesheet_content = xrealloc(c->data.html.stylesheet_content,
@ -325,7 +341,8 @@ void html_find_stylesheets(struct content *c, xmlNode *head)
/* create stylesheet */ /* create stylesheet */
LOG(("style element")); LOG(("style element"));
if (c->data.html.stylesheet_content[1] == 0) { if (c->data.html.stylesheet_content[1] == 0) {
c->data.html.stylesheet_content[1] = content_create(c->url); c->data.html.stylesheet_content[1] =
content_create(c->data.html.base_url);
content_set_type(c->data.html.stylesheet_content[1], CONTENT_CSS, "text/css"); content_set_type(c->data.html.stylesheet_content[1], CONTENT_CSS, "text/css");
} }
@ -567,5 +584,6 @@ void html_destroy(struct content *c)
xfree(c->title); xfree(c->title);
if (c->data.html.source != 0) if (c->data.html.source != 0)
xfree(c->data.html.source); xfree(c->data.html.source);
free(c->data.html.base_url);
} }

View File

@ -29,6 +29,7 @@ struct content_html_data {
htmlParserCtxt *parser; htmlParserCtxt *parser;
char *source; char *source;
int length; int length;
char *base_url; /**< Base URL (may be a copy of content->url). */
struct box *layout; struct box *layout;
colour background_colour; colour background_colour;
unsigned int stylesheet_count; unsigned int stylesheet_count;

View File

@ -299,21 +299,14 @@ void gui_window_set_status(gui_window* g, const char* text)
} }
void gui_window_message(gui_window* g, gui_message* msg) /**
{ * Set the contents of a window's address bar.
if (g == NULL || msg == NULL) */
return;
switch (msg->type) void gui_window_set_url(gui_window *g, char *url)
{ {
case msg_SET_URL: strncpy(g->url, url, 255);
fprintf(stderr, "Set URL '%s'\n", msg->data.set_url.url);
strncpy(g->url, msg->data.set_url.url, 255);
wimp_set_icon_state(g->data.browser.toolbar, ICON_TOOLBAR_URL, 0, 0); wimp_set_icon_state(g->data.browser.toolbar, ICON_TOOLBAR_URL, 0, 0);
break;
default:
break;
}
} }
@ -712,7 +705,21 @@ bool ro_gui_window_keypress(gui_window *g, int key, bool toolbar)
browser_window_open_location(g->data.browser.bw, browser_window_open_location(g->data.browser.bw,
"file:///%3CWimp$ScrapDir%3E/WWW/NetSurf/About"); "file:///%3CWimp$ScrapDir%3E/WWW/NetSurf/About");
} else { } else {
browser_window_open_location(g->data.browser.bw, g->url); char *url = xcalloc(1, 10 + strlen(g->url));
char *url2;
if (g->url[strspn(g->url, "abcdefghijklmnopqrstuvwxyz")] != ':') {
strcpy(url, "http://");
strcpy(url + 7, g->url);
} else {
strcpy(url, g->url);
}
url2 = url_join(url, 0);
free(url);
if (url2) {
gui_window_set_url(g, url2);
browser_window_open_location(g->data.browser.bw, url2);
free(url2);
}
} }
return true; return true;

View File

@ -12,6 +12,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <uri.h>
#include "libxml/encoding.h" #include "libxml/encoding.h"
#include "libxml/uri.h" #include "libxml/uri.h"
#include "netsurf/utils/log.h" #include "netsurf/utils/log.h"
@ -165,99 +166,60 @@ char *squash_tolat1(xmlChar *s)
return squash; return squash;
} }
char *url_join(const char* new, const char* base)
/**
* Calculate a URL from a relative and base URL.
*
* base may be 0 for a new URL, in which case the URL is cannonicalized and
* returned. Returns 0 in case of error.
*/
char *url_join(char *rel_url, char *base_url)
{ {
char* ret, *nn; char *res;
int i,j,k; uri_t *base = 0, *rel = 0, *abs;
LOG(("new = %s, base = %s", new, base)); LOG(("rel_url = %s, base_url = %s", rel_url, base_url));
/* deal with spaces and quotation marks in URLs etc. if (!base_url) {
also removes spaces from end of links. res = uri_cannonicalize_string(rel_url, strlen(rel_url),
There's definitely a better way to do this */ URI_STRING_URI_STYLE);
nn = xcalloc(strlen(new) * 3 + 40, sizeof(char)); LOG(("res = %s", res));
j=0; if (res)
for(i=0;i<strlen(new);i++){ return xstrdup(res);
return 0;
if(new[i] == ' '){ /* space */
nn[j] = '%';
nn[j+1] = '2';
nn[j+2] = '0';
j+=2;
}
else if(new[i] == '"'){ /* quotes */
nn[j] = '%';
nn[j+1] = '2';
nn[j+2] = '2';
j+=2;
k = j;
}
else{
nn[j] = new[i];
k = j;
} }
j++; base = uri_alloc(base_url, strlen(base_url));
} rel = uri_alloc(rel_url, strlen(rel_url));
if(k < j){ if (!base || !rel)
nn[k+1] = '\0'; goto fail;
LOG(("before: %s after: %s", new, nn)); if (!base->scheme)
} goto fail;
new = nn; abs = uri_abs_1(base, rel);
if (base == 0) res = xstrdup(uri_uri(abs));
{
/* no base, so make an absolute URL */
ret = xcalloc(strlen(new) + 10, sizeof(char));
/* check if a scheme is present */ uri_free(base);
i = strspn(new, "abcdefghijklmnopqrstuvwxyz"); uri_free(rel);
if (new[i] == ':')
{
strcpy(ret, new);
i += 3;
}
else
{
strcpy(ret, "http://");
strcat(ret, new);
i = 7;
}
/* make server name lower case */ LOG(("res = %s", res));
for (; ret[i] != 0 && ret[i] != '/'; i++) return res;
ret[i] = tolower(ret[i]);
xmlNormalizeURIPath(ret + i); fail:
if (base)
uri_free(base);
if (rel)
uri_free(rel);
/* http://www.example.com -> http://www.example.com/ */ LOG(("error"));
if (ret[i] == 0)
{
ret[i] = '/';
ret[i+1] = 0;
}
}
else
{
/* relative url */
ret = xmlBuildURI(new, base);
}
LOG(("ret = %s", ret)); return 0;
if (ret == NULL)
{
ret = xcalloc(strlen(new) + 10, sizeof(char));
strcpy(ret, new);
}
xfree(nn);
return ret;
} }
char *get_host_from_url (char *url) { char *get_host_from_url (char *url) {
char *host = xcalloc(strlen(url)+10, sizeof(char)); char *host = xcalloc(strlen(url)+10, sizeof(char));

View File

@ -24,7 +24,7 @@ char * squash_whitespace(const char * s);
char * tolat1(xmlChar * s); char * tolat1(xmlChar * s);
char * tolat1_pre(xmlChar * s); char * tolat1_pre(xmlChar * s);
char *squash_tolat1(xmlChar *s); char *squash_tolat1(xmlChar *s);
char *url_join(const char* new, const char* base); char *url_join(char *rel_url, char *base_url);
char *get_host_from_url(char* url); char *get_host_from_url(char* url);
bool is_dir(const char *path); bool is_dir(const char *path);