summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Bursa <james@netsurf-browser.org>2003-12-26 00:17:55 +0000
committerJames Bursa <james@netsurf-browser.org>2003-12-26 00:17:55 +0000
commitf1b59814f8da2f3e235d47adfb332edf8a093b31 (patch)
tree760327fafeb70a0ed342abba3455da00a684eabc
parent3b4de07169777f6f820f08ac1422e9af901b3ee2 (diff)
downloadnetsurf-f1b59814f8da2f3e235d47adfb332edf8a093b31.tar.gz
netsurf-f1b59814f8da2f3e235d47adfb332edf8a093b31.tar.bz2
[project @ 2003-12-26 00:17:55 by bursa]
New url_join using liburi, <base href=...>. svn path=/import/netsurf/; revision=441
-rw-r--r--content/fetch.c5
-rw-r--r--content/fetchcache.c8
-rw-r--r--css/css.c30
-rw-r--r--desktop/browser.c42
-rw-r--r--desktop/gui.h15
-rw-r--r--makefile5
-rw-r--r--render/box.c94
-rw-r--r--render/html.c38
-rw-r--r--render/html.h1
-rw-r--r--riscos/window.c37
-rw-r--r--utils/utils.c136
-rw-r--r--utils/utils.h2
12 files changed, 219 insertions, 194 deletions
diff --git a/content/fetch.c b/content/fetch.c
index f03cfc615..f7197a7aa 100644
--- a/content/fetch.c
+++ b/content/fetch.c
@@ -602,6 +602,11 @@ bool fetch_process_headers(struct fetch *f)
url_path = curl_unescape(f->url + 8, (int) strlen(f->url) - 8);
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 + 6, (int) strlen(f->url) - 6);
+ type = fetch_filetype(url_path);
+ curl_free(url_path);
}
}
diff --git a/content/fetchcache.c b/content/fetchcache.c
index 28c098034..63bd5be35 100644
--- a/content/fetchcache.c
+++ b/content/fetchcache.c
@@ -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
* relative ones: treat them as relative to requested URL */
url = url_join(data, c->url);
- content_broadcast(c, CONTENT_MSG_REDIRECT, url);
- xfree(url);
+ if (url) {
+ content_broadcast(c, CONTENT_MSG_REDIRECT, url);
+ xfree(url);
+ } else {
+ content_broadcast(c, CONTENT_MSG_ERROR, "Bad redirect");
+ }
if (c->cache)
cache_destroy(c);
content_destroy(c);
diff --git a/css/css.c b/css/css.c
index d0580a095..f719eca7c 100644
--- a/css/css.c
+++ b/css/css.c
@@ -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,
c->data.css.css->lexer);
assert(buffer);
- while ((token = css_lex(c->data.css.css->lexer)) &&
- !param.syntax_error) {
+ while (token = css_lex(c->data.css.css->lexer)) {
css_parser_(c->data.css.css->parser, token,
xstrdup(css_get_text(c->data.css.css->lexer)),
&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);
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);
- 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_dump_stylesheet(c->data.css.css);
+ /*css_dump_stylesheet(c->data.css.css);*/
/* complete fetch of any imported stylesheets */
while (c->active != 0) {
@@ -261,7 +257,7 @@ char *css_unquote(char *s)
void css_atimport(struct content *c, struct css_node *node)
{
- char *s, *url;
+ char *s, *url, *url1;
int string = 0, screen = 1;
unsigned int i;
@@ -322,6 +318,12 @@ void css_atimport(struct content *c, struct css_node *node)
return;
}
+ url1 = url_join(url, c->url);
+ if (!url1) {
+ free(url);
+ return;
+ }
+
/* start the fetch */
c->data.css.import_count++;
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));
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_url[i], c->url, css_atimport_callback,
c, i, c->width, c->height, true, 0, 0);
diff --git a/desktop/browser.c b/desktop/browser.c
index b2a9c27d6..54a91b7b8 100644
--- a/desktop/browser.c
+++ b/desktop/browser.c
@@ -251,6 +251,8 @@ void browser_window_open_location_post(struct browser_window* bw,
LOG(("bw = %p, url = %s", bw, url));
assert(bw != 0 && url != 0);
url1 = url_join(url, 0);
+ if (!url1)
+ return;
browser_window_open_location_historical(bw, url1, post_urlenc, post_multipart);
bw->history_add = true;
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);
if (bw->loading_content == c) {
- struct gui_message gmsg;
if (bw->url != 0)
xfree(bw->url);
bw->url = xstrdup(c->url);
- gmsg.type = msg_SET_URL;
- gmsg.data.set_url.url = bw->url;
- gui_window_message(bw->window, &gmsg);
+ gui_window_set_url(bw->window, bw->url);
if (bw->current_content != NULL)
{
@@ -1215,26 +1214,28 @@ void browser_window_follow_link(struct browser_window* bw,
continue;
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) {
- char *url = url_join((char*) click_boxes[i].box->href, bw->url);
browser_window_open_location(bw, url);
- free(url);
}
else if (click_type == 2)
{
- char *url = url_join((char*) click_boxes[i].box->href, bw->url);
struct browser_window* bw_new;
bw_new = create_browser_window(browser_TITLE | browser_TOOLBAR
| browser_SCROLL_X_ALWAYS | browser_SCROLL_Y_ALWAYS, 640, 480, NULL);
gui_window_show(bw_new->window);
browser_window_open_location(bw_new, url);
- free(url);
}
else if (click_type == 0)
{
- browser_window_set_status(bw, (char*) click_boxes[i].box->href);
+ browser_window_set_status(bw, url);
done = 1;
}
+ free(url);
break;
}
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,
struct form_control *submit_button)
{
- char *data, *url, *url1;
+ char *data = 0, *url = 0, *url1 = 0, *base;
struct form_successful_control *success;
assert(form);
+ assert(bw->current_content->type == CONTENT_HTML);
success = form_successful_controls(form, submit_button);
+ base = bw->current_content->data.html.base_url;
switch (form->method) {
case method_GET:
data = form_url_encode(success);
url = xcalloc(1, strlen(form->action) + strlen(data) + 2);
sprintf(url, "%s?%s", form->action, data);
- url1 = url_join(url, bw->url);
- free(data);
- free(url);
+ url1 = url_join(url, base);
+ if (!url1)
+ break;
browser_window_open_location(bw, url1);
- free(url1);
break;
case method_POST_URLENC:
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);
- free(url);
- free(data);
break;
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);
- free(url);
break;
default:
@@ -1610,4 +1611,7 @@ void browser_form_submit(struct browser_window *bw, struct form *form,
}
form_free_successful(success);
+ free(data);
+ free(url);
+ free(url1);
}
diff --git a/desktop/gui.h b/desktop/gui.h
index 5ca8e038d..72ead54b4 100644
--- a/desktop/gui.h
+++ b/desktop/gui.h
@@ -18,18 +18,6 @@ typedef struct gui_window gui_window;
#include <stdbool.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_download_window(struct content *content);
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_status(gui_window* g, const char* text);
void gui_window_set_title(gui_window* g, char* title);
-
-void gui_window_message(gui_window* g, gui_message* msg);
+void gui_window_set_url(gui_window *g, char *url);
void gui_download_window_update_status(gui_window *g);
void gui_download_window_done(gui_window *g);
diff --git a/makefile b/makefile
index f3192f77f..951c48bd8 100644
--- a/makefile
+++ b/makefile
@@ -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.. \
-mpoke-function-name
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_DEBUG = -L/usr/lib -lxml2 -lz -lm -lcurl -lssl -lcrypto -ldl
+LDFLAGS = -L/riscos/lib -lxml2 -lz -lcurl -lssl -lcrypto -lares -lanim -lpng \
+ -lifc -loslib -luri
+LDFLAGS_DEBUG = -L/usr/lib -lxml2 -lz -lm -lcurl -lssl -lcrypto -ldl -luri
OBJDIR = $(shell $(CC) -dumpmachine)
SOURCES=$(OBJECTS:.o=.c)
diff --git a/render/box.c b/render/box.c
index e62fd0cd7..e565be0a6 100644
--- a/render/box.c
+++ b/render/box.c
@@ -706,7 +706,10 @@ struct result box_image(xmlNode *n, struct status *status,
if (!(s = (char *) xmlGetProp(n, (const xmlChar *) "src")))
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));
xmlFree(s);
@@ -1014,8 +1017,9 @@ struct result box_input(xmlNode *n, struct status *status,
gadget->box = box;
gadget->type = GADGET_IMAGE;
if ((s = (char *) xmlGetProp(n, (const xmlChar*) "src"))) {
- url = url_join(s, status->content->url);
- html_fetch_object(status->content, url, box);
+ url = url_join(s, status->content->data.html.base_url);
+ if (url)
+ html_fetch_object(status->content, url, box);
xmlFree(s);
}
}
@@ -1673,9 +1677,13 @@ struct result box_object(xmlNode *n, struct status *status,
/* object 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);
- url = url_join(strdup(s), status->content->url);
LOG(("object '%s'", po->data));
xmlFree(s);
}
@@ -1797,10 +1805,14 @@ struct result box_embed(xmlNode *n, struct status *status,
/* embed src */
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "src"))) {
-
- po->data = strdup(s);
- url = url_join(strdup(s), status->content->url);
+ url = url_join(s, status->content->data.html.base_url);
+ if (!url) {
+ free(po);
+ xmlFree(s);
+ return (struct result) {box, 0};
+ }
LOG(("embed '%s'", url));
+ po->data = strdup(s);
xmlFree(s);
}
@@ -1861,14 +1873,18 @@ struct result box_applet(xmlNode *n, struct status *status,
po->classid = 0;
po->params = 0;
- /* code */
+ /* code */
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "code"))) {
-
- po->classid = strdup(s);
- url = url_join(strdup(s), status->content->url);
- LOG(("applet '%s'", url));
- xmlFree(s);
- }
+ url = url_join(s, status->content->data.html.base_url);
+ if (!url) {
+ free(po);
+ xmlFree(s);
+ return (struct result) {box, 1};
+ }
+ LOG(("applet '%s'", url));
+ po->classid = strdup(s);
+ xmlFree(s);
+ }
/* object codebase */
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "codebase"))) {
@@ -1962,12 +1978,16 @@ struct result box_iframe(xmlNode *n, struct status *status,
/* iframe src */
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "src"))) {
-
- po->data = strdup(s);
- url = url_join(strdup(s), status->content->url);
- LOG(("embed '%s'", url));
- xmlFree(s);
- }
+ url = url_join(s, status->content->data.html.base_url);
+ if (!url) {
+ free(po);
+ xmlFree(s);
+ return (struct result) {box, 0};
+ }
+ LOG(("embed '%s'", url));
+ po->data = strdup(s);
+ xmlFree(s);
+ }
box->object_params = po;
@@ -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.
*
* 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,
struct object_params* po)
{
struct plugin_params * pp;
- /* Set basehref */
- po->basehref = strdup(content->url);
-
/* Check if the codebase attribute is defined.
* If it is not, set it to the codebase of the current document.
*/
if(po->codebase == 0)
- po->codebase = url_join("./", content->url);
+ po->codebase = url_join("./", content->data.html.base_url);
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.
* 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 &&
(strcasecmp(pp->name, "movie") != 0);
pp = pp->next);
- if(pp != 0)
- url = url_join(pp->value, po->basehref);
- else return false;
+ if(pp == 0)
+ return false;
+ url = url_join(pp->value, po->basehref);
+ if (!url)
+ return false;
/* munge the codebase */
- po->codebase = url_join("./", content->url);
+ po->codebase = url_join("./",
+ content->data.html.base_url);
+ if (!po->codebase)
+ return false;
}
else {
LOG(("ActiveX object - n0"));
@@ -2032,6 +2062,8 @@ bool plugin_decode(struct content* content, char* url, struct box* box,
}
else {
url = url_join(po->classid, po->codebase);
+ if (!url)
+ return false;
/* The java plugin doesn't need the .class extension
* so we strip it.
@@ -2043,6 +2075,8 @@ bool plugin_decode(struct content* content, char* url, struct box* box,
}
else {
url = url_join(po->data, po->codebase);
+ if (!url)
+ return false;
}
/* Check if the declared mime type is understandable.
diff --git a/render/html.c b/render/html.c
index e3953597e..73bda84ed 100644
--- a/render/html.c
+++ b/render/html.c
@@ -23,7 +23,7 @@
static void html_convert_css_callback(content_msg msg, struct content *css,
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_object_callback(content_msg msg, struct content *object,
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.length = 0;
c->data.html.source = xcalloc(0, 1);
+ c->data.html.base_url = xstrdup(c->url);
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)
- html_title(c, head);
+ html_head(c, head);
/* get stylesheets */
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;
- xmlChar *title;
c->title = 0;
for (node = head->children; node != 0; node = node->next) {
- if (strcmp(node->name, "title") == 0) {
- title = xmlNodeGetContent(node);
+ if (!c->title && strcmp(node->name, "title") == 0) {
+ xmlChar *title = xmlNodeGetContent(node);
c->title = squash_tolat1(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
* title attribute) should be loaded (see HTML4 14.3) */
- url = url_join(href, c->url);
- LOG(("linked stylesheet %i '%s'", i, url));
+ url = url_join(href, c->data.html.base_url);
xmlFree(href);
+ if (!url)
+ continue;
+
+ LOG(("linked stylesheet %i '%s'", i, url));
/* start fetch */
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 */
LOG(("style element"));
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");
}
@@ -567,5 +584,6 @@ void html_destroy(struct content *c)
xfree(c->title);
if (c->data.html.source != 0)
xfree(c->data.html.source);
+ free(c->data.html.base_url);
}
diff --git a/render/html.h b/render/html.h
index db41f7f11..8a5047cc2 100644
--- a/render/html.h
+++ b/render/html.h
@@ -29,6 +29,7 @@ struct content_html_data {
htmlParserCtxt *parser;
char *source;
int length;
+ char *base_url; /**< Base URL (may be a copy of content->url). */
struct box *layout;
colour background_colour;
unsigned int stylesheet_count;
diff --git a/riscos/window.c b/riscos/window.c
index e6493ef94..206205a30 100644
--- a/riscos/window.c
+++ b/riscos/window.c
@@ -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)
-{
- if (g == NULL || msg == NULL)
- return;
+/**
+ * Set the contents of a window's address bar.
+ */
- switch (msg->type)
- {
- case msg_SET_URL:
- 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);
- break;
- default:
- break;
- }
+void gui_window_set_url(gui_window *g, char *url)
+{
+ strncpy(g->url, url, 255);
+ wimp_set_icon_state(g->data.browser.toolbar, ICON_TOOLBAR_URL, 0, 0);
}
@@ -712,7 +705,21 @@ bool ro_gui_window_keypress(gui_window *g, int key, bool toolbar)
browser_window_open_location(g->data.browser.bw,
"file:///%3CWimp$ScrapDir%3E/WWW/NetSurf/About");
} 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;
diff --git a/utils/utils.c b/utils/utils.c
index 004fa3fa7..1487ac1c7 100644
--- a/utils/utils.c
+++ b/utils/utils.c
@@ -12,6 +12,7 @@
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
+#include <uri.h>
#include "libxml/encoding.h"
#include "libxml/uri.h"
#include "netsurf/utils/log.h"
@@ -165,98 +166,59 @@ char *squash_tolat1(xmlChar *s)
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;
- int i,j,k;
-
- LOG(("new = %s, base = %s", new, base));
-
- /* deal with spaces and quotation marks in URLs etc.
- also removes spaces from end of links.
- There's definitely a better way to do this */
- nn = xcalloc(strlen(new) * 3 + 40, sizeof(char));
- j=0;
- for(i=0;i<strlen(new);i++){
-
- 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++;
- }
- if(k < j){
- nn[k+1] = '\0';
- LOG(("before: %s after: %s", new, nn));
- }
+ char *res;
+ uri_t *base = 0, *rel = 0, *abs;
+
+ LOG(("rel_url = %s, base_url = %s", rel_url, base_url));
+
+ if (!base_url) {
+ res = uri_cannonicalize_string(rel_url, strlen(rel_url),
+ URI_STRING_URI_STYLE);
+ LOG(("res = %s", res));
+ if (res)
+ return xstrdup(res);
+ return 0;
+ }
- new = nn;
-
- if (base == 0)
- {
- /* no base, so make an absolute URL */
- ret = xcalloc(strlen(new) + 10, sizeof(char));
-
- /* check if a scheme is present */
- i = strspn(new, "abcdefghijklmnopqrstuvwxyz");
- if (new[i] == ':')
- {
- strcpy(ret, new);
- i += 3;
- }
- else
- {
- strcpy(ret, "http://");
- strcat(ret, new);
- i = 7;
- }
-
- /* make server name lower case */
- for (; ret[i] != 0 && ret[i] != '/'; i++)
- ret[i] = tolower(ret[i]);
-
- xmlNormalizeURIPath(ret + i);
-
- /* http://www.example.com -> http://www.example.com/ */
- if (ret[i] == 0)
- {
- ret[i] = '/';
- ret[i+1] = 0;
- }
- }
- else
- {
- /* relative url */
- ret = xmlBuildURI(new, base);
- }
+ base = uri_alloc(base_url, strlen(base_url));
+ rel = uri_alloc(rel_url, strlen(rel_url));
+ if (!base || !rel)
+ goto fail;
+ if (!base->scheme)
+ goto fail;
- LOG(("ret = %s", ret));
- if (ret == NULL)
- {
- ret = xcalloc(strlen(new) + 10, sizeof(char));
- strcpy(ret, new);
- }
+ abs = uri_abs_1(base, rel);
+
+ res = xstrdup(uri_uri(abs));
+
+ uri_free(base);
+ uri_free(rel);
+
+ LOG(("res = %s", res));
+ return res;
+
+fail:
+ if (base)
+ uri_free(base);
+ if (rel)
+ uri_free(rel);
+
+ LOG(("error"));
- xfree(nn);
- return ret;
+ return 0;
}
+
+
char *get_host_from_url (char *url) {
diff --git a/utils/utils.h b/utils/utils.h
index fb6255511..3ca3072af 100644
--- a/utils/utils.h
+++ b/utils/utils.h
@@ -24,7 +24,7 @@ char * squash_whitespace(const char * s);
char * tolat1(xmlChar * s);
char * tolat1_pre(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);
bool is_dir(const char *path);