summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--content/content.h3
-rw-r--r--content/fetch.c15
-rw-r--r--content/fetch.h2
-rw-r--r--content/fetchcache.c8
-rw-r--r--desktop/401login.h14
-rw-r--r--desktop/browser.c15
-rw-r--r--desktop/loginlist.c137
-rw-r--r--makefile2
-rw-r--r--render/html.c6
-rw-r--r--riscos/401login.c52
-rw-r--r--utils/utils.c25
-rw-r--r--utils/utils.h1
12 files changed, 234 insertions, 46 deletions
diff --git a/content/content.h b/content/content.h
index 249e21192..72034b316 100644
--- a/content/content.h
+++ b/content/content.h
@@ -71,7 +71,8 @@ typedef enum {
CONTENT_MSG_ERROR, /**< error occurred */
CONTENT_MSG_STATUS, /**< new status string */
CONTENT_MSG_REDIRECT, /**< replacement URL */
- CONTENT_MSG_REFORMAT /**< content_reformat done */
+ CONTENT_MSG_REFORMAT, /**< content_reformat done */
+ CONTENT_MSG_AUTH /**< authentication required */
} content_msg;
/** Linked list of users of a content. */
diff --git a/content/fetch.c b/content/fetch.c
index b7f48b506..391aa14d3 100644
--- a/content/fetch.c
+++ b/content/fetch.c
@@ -150,6 +150,7 @@ struct fetch * fetch_start(char *url, char *referer,
CURLcode code;
CURLMcode codem;
xmlURI *uri;
+ struct login *li;
LOG(("fetch %p, url '%s'", fetch, url));
@@ -268,12 +269,11 @@ struct fetch * fetch_start(char *url, char *referer,
code = curl_easy_setopt(fetch->curl_handle, CURLOPT_HTTPAUTH, (long)CURLAUTH_BASIC);
assert(code == CURLE_OK);
-#ifdef riscos
- if (LOGIN.string != NULL) {
- code = curl_easy_setopt(fetch->curl_handle, CURLOPT_USERPWD, LOGIN.string);
+ if ((li=login_list_get(url)) != NULL) {
+ code = curl_easy_setopt(fetch->curl_handle, CURLOPT_USERPWD, li->logindetails);
+
assert(code == CURLE_OK);
}
-#endif
/* POST */
if (fetch->post_urlenc) {
@@ -545,16 +545,11 @@ bool fetch_process_headers(struct fetch *f)
return true;
}
-#ifdef riscos
/* handle HTTP 401 (Authentication errors) */
if (http_code == 401) {
- /* this shouldn't be here... */
- ro_gui_401login_open(xstrdup(f->host), xstrdup(f->realm),
- xstrdup(f->url));
- f->callback(FETCH_ERROR, f->p, "",0);
+ f->callback(FETCH_AUTH, f->p, xstrdup(f->realm),0);
return true;
}
-#endif
/* handle HTTP errors (non 2xx response codes) */
if (f->only_2xx && strncmp(f->url, "http", 4) == 0 &&
diff --git a/content/fetch.h b/content/fetch.h
index 762664923..492645df9 100644
--- a/content/fetch.h
+++ b/content/fetch.h
@@ -14,7 +14,7 @@
#include <stdbool.h>
-typedef enum {FETCH_TYPE, FETCH_DATA, FETCH_FINISHED, FETCH_ERROR, FETCH_REDIRECT} fetch_msg;
+typedef enum {FETCH_TYPE, FETCH_DATA, FETCH_FINISHED, FETCH_ERROR, FETCH_REDIRECT, FETCH_AUTH} fetch_msg;
struct content;
struct fetch;
diff --git a/content/fetchcache.c b/content/fetchcache.c
index 13ddbc9c5..28c098034 100644
--- a/content/fetchcache.c
+++ b/content/fetchcache.c
@@ -154,6 +154,14 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size)
content_destroy(c);
break;
+ case FETCH_AUTH:
+ /* data -> string containing the Realm */
+ LOG(("FETCH_AUTH, '%s'", data));
+ c->fetch = 0;
+ content_broadcast(c, CONTENT_MSG_AUTH, data);
+ cache_destroy(c);
+ break;
+
default:
assert(0);
}
diff --git a/desktop/401login.h b/desktop/401login.h
index f9a999ebd..d9262c54c 100644
--- a/desktop/401login.h
+++ b/desktop/401login.h
@@ -8,11 +8,21 @@
#ifndef NETSURF_DESKTOP_401LOGIN_H
#define NETSURF_DESKTOP_401LOGIN_H
+#include "netsurf/content/content.h"
+#include "netsurf/desktop/browser.h"
+
struct login {
- char *string;
+ char *host; /**< hostname */
+ char *logindetails; /**< string containing "username:password" */
+ struct login *next; /**< next in list */
+ struct login *prev; /**< previous in list */
};
-extern struct login LOGIN;
+void gui_401login_open(struct browser_window *bw, struct content *c,
+ char *realm);
+void login_list_add(char *host, char *logindets);
+struct login *login_list_get(char *host);
+void login_list_remove(char *host);
#endif
diff --git a/desktop/browser.c b/desktop/browser.c
index 16fc03126..8e311eee8 100644
--- a/desktop/browser.c
+++ b/desktop/browser.c
@@ -18,6 +18,7 @@
#include "netsurf/content/cache.h"
#include "netsurf/content/fetchcache.h"
#include "netsurf/css/css.h"
+#include "netsurf/desktop/401login.h"
#include "netsurf/desktop/browser.h"
#include "netsurf/render/box.h"
#include "netsurf/render/font.h"
@@ -208,6 +209,7 @@ void browser_window_destroy(struct browser_window* bw)
if (bw->current_content->status == CONTENT_STATUS_DONE)
content_remove_instance(bw->current_content, bw, 0, 0, 0, &bw->current_content_state);
content_remove_user(bw->current_content, browser_window_callback, bw, 0);
+ login_list_remove(bw->current_content->url);
}
if (bw->loading_content != NULL) {
content_remove_user(bw->loading_content, browser_window_callback, bw, 0);
@@ -248,10 +250,18 @@ void browser_window_open_location_historical(struct browser_window* bw,
const char* url, char *post_urlenc,
struct form_successful_control *post_multipart)
{
+ struct login *li;
LOG(("bw = %p, url = %s", bw, url));
assert(bw != 0 && url != 0);
+ if ((li = login_list_get(url)) == NULL) {
+
+ if (bw->current_content != NULL) {
+ login_list_remove(bw->current_content->url);
+ }
+ }
+
browser_window_set_status(bw, "Opening page...");
browser_window_start_throbber(bw);
bw->time0 = clock();
@@ -376,7 +386,6 @@ void browser_window_callback(content_msg msg, struct content *c,
case CONTENT_MSG_REDIRECT:
bw->loading_content = 0;
- bw->url = xstrdup(error);
browser_window_set_status(bw, "Redirecting");
/* error actually holds the new URL */
browser_window_open_location(bw, error);
@@ -386,6 +395,10 @@ void browser_window_callback(content_msg msg, struct content *c,
browser_window_reformat(bw, 0);
break;
+ case CONTENT_MSG_AUTH:
+ gui_401login_open(bw, c, error);
+ break;
+
default:
assert(0);
}
diff --git a/desktop/loginlist.c b/desktop/loginlist.c
new file mode 100644
index 000000000..08b1822c1
--- /dev/null
+++ b/desktop/loginlist.c
@@ -0,0 +1,137 @@
+/*
+ * This file is part of NetSurf, http://netsurf.sourceforge.net/
+ * Licensed under the GNU General Public License,
+ * http://www.opensource.org/licenses/gpl-license
+ * Copyright 2003 John M Bell <jmb202@ecs.soton.ac.uk>
+ */
+
+#include <assert.h>
+#include <string.h>
+#include "netsurf/desktop/401login.h"
+#include "netsurf/utils/log.h"
+#include "netsurf/utils/utils.h"
+
+#define NDEBUG
+
+void login_list_dump(void);
+
+/**
+ * Pointer into the linked list
+ */
+static struct login login = {0, 0, &login, &login};
+static struct login *loginlist = &login;
+
+/**
+ * Adds an item to the list of login details
+ */
+void login_list_add(char *host, char* logindets) {
+
+ struct login *nli = xcalloc(1, sizeof(*nli));
+ char *temp = xstrdup(host);
+ char *i;
+
+ /* Go back to the path base ie strip the document name
+ * eg. http://www.blah.com/blah/test.htm becomes
+ * http://www.blah.com/blah/
+ * This does, however, mean that directories MUST have a '/' at the end
+ */
+ if (temp[strlen(temp)-1] != '/') {
+ i = strrchr(temp, '/');
+ temp[(i-temp)+1] = 0;
+ }
+
+ nli->host = xstrdup(temp);
+ nli->logindetails = xstrdup(logindets);
+ nli->prev = loginlist->prev;
+ nli->next = loginlist;
+ loginlist->prev->next = nli;
+ loginlist->prev = nli;
+
+ LOG(("Adding %s : %s", temp, logindets));
+#ifndef NDEBUG
+ login_list_dump();
+#endif
+ xfree(temp);
+}
+
+/**
+ * Retrieves an element from the login list
+ */
+struct login *login_list_get(char *host) {
+
+ struct login *nli;
+ char *temp, *temphost;
+ char* i;
+
+ if (host == NULL)
+ return NULL;
+
+ temphost = get_host_from_url(host);
+ temp = xstrdup(host);
+
+ /* Work backwards through the path, directory at at time.
+ * Finds the closest match.
+ * eg. http://www.blah.com/moo/ matches the url
+ * http://www.blah.com/moo/test/index.htm
+ * This allows multiple realms (and login details) per host.
+ * Only one set of login details per realm are allowed.
+ */
+ while (strcasecmp(temp, temphost) != 0) {
+
+ LOG(("%s, %d", temp, strlen(temp)));
+
+ for (nli = loginlist->next; nli != loginlist &&
+ (strcasecmp(nli->host, temp)!=0);
+ nli = nli->next) ;
+
+ if (temp[strlen(temp)-1] == '/') {
+ temp[strlen(temp)-1] = 0;
+ }
+
+ i = strrchr(temp, '/');
+
+ temp[(i-temp)+1] = 0;
+
+ if (nli != loginlist) {
+ LOG(("Got %s", nli->host));
+ xfree(temphost);
+ return nli;
+ }
+ }
+
+ xfree(temphost);
+ return NULL;
+}
+
+/**
+ * Remove a realm's login details from the list
+ */
+void login_list_remove(char *host) {
+
+ struct login *nli = login_list_get(host);
+
+ if (nli != NULL) {
+ nli->prev->next = nli->next;
+ nli->next->prev = nli->prev;
+ xfree(nli->logindetails);
+ xfree(nli->host);
+ xfree(nli);
+ }
+
+ LOG(("Removing %s", host));
+#ifndef NDEBUG
+ login_list_dump();
+#endif
+}
+
+/**
+ * Dumps the list of login details (base paths only)
+ */
+void login_list_dump(void) {
+
+ struct login *nli;
+
+ for (nli = loginlist->next; nli != loginlist; nli = nli->next) {
+ LOG(("%s", nli->host));
+ }
+}
diff --git a/makefile b/makefile
index 1efd0c5ae..78e2143b5 100644
--- a/makefile
+++ b/makefile
@@ -11,7 +11,7 @@ OBJECTS_COMMON = cache.o content.o fetch.o fetchcache.o other.o \
box.o form.o html.o layout.o textplain.o \
messages.o utils.o
OBJECTS = $(OBJECTS_COMMON) \
- browser.o netsurf.o \
+ browser.o loginlist.o netsurf.o \
htmlredraw.o \
401login.o dialog.o download.o gui.o menus.o mouseactions.o \
options.o textselection.o theme.o \
diff --git a/render/html.c b/render/html.c
index e023de9e8..30fb0dec5 100644
--- a/render/html.c
+++ b/render/html.c
@@ -191,6 +191,9 @@ void html_convert_css_callback(content_msg msg, struct content *css,
c->active++;
break;
+ case CONTENT_MSG_AUTH:
+ break;
+
default:
assert(0);
}
@@ -479,6 +482,9 @@ void html_object_callback(content_msg msg, struct content *object,
case CONTENT_MSG_REFORMAT:
break;
+ case CONTENT_MSG_AUTH:
+ break;
+
default:
assert(0);
}
diff --git a/riscos/401login.c b/riscos/401login.c
index edd081cc0..81f4ba75e 100644
--- a/riscos/401login.c
+++ b/riscos/401login.c
@@ -6,8 +6,11 @@
*/
#include <assert.h>
+#include <ctype.h>
#include <string.h>
#include "oslib/wimp.h"
+#include "netsurf/content/content.h"
+#include "netsurf/desktop/browser.h"
#include "netsurf/desktop/401login.h"
#include "netsurf/desktop/gui.h"
#include "netsurf/riscos/gui.h"
@@ -16,7 +19,6 @@
#include "netsurf/utils/utils.h"
static void get_unamepwd(void);
-static void do_thing(void);
static wimp_window *dialog_401;
extern wimp_w dialog_401li;
@@ -26,6 +28,7 @@ struct login LOGIN;
static char *uname;
static char* url;
static char *pwd;
+static struct browser_window *bwin;
/**
* Load the 401 login window template.
@@ -50,6 +53,21 @@ void ro_gui_401login_init(void)
wimp_NO_FONTS, name, 0, 0, 0);
}
+void gui_401login_open(struct browser_window *bw, struct content *c, char *realm) {
+
+ char *murl, *host;
+ int i;
+
+ murl = c->url;
+ host = get_host_from_url(murl);
+ bwin = bw;
+
+ ro_gui_401login_open(host, realm, murl);
+
+ xfree(host);
+}
+
+
/**
* Open a 401 login window.
*/
@@ -62,7 +80,7 @@ void ro_gui_401login_open(char *host, char* realm, char *fetchurl)
/* fill in download window icons */
dialog_401->icons[ICON_401LOGIN_HOST].data.indirected_text.text =
- host;
+ xstrdup(host);
dialog_401->icons[ICON_401LOGIN_HOST].data.indirected_text.size =
strlen(host) + 1;
dialog_401->icons[ICON_401LOGIN_REALM].data.indirected_text.text =
@@ -90,12 +108,9 @@ void ro_gui_401login_click(wimp_pointer *pointer) {
switch (pointer->i) {
case ICON_401LOGIN_LOGIN:
if (pointer->buttons == wimp_CLICK_SELECT) {
- LOG(("here"));
get_unamepwd();
ro_gui_dialog_close(dialog_401li);
- do_thing();
- LOGIN.string = 0; /* TODO: keep the details until we
- * access a new site */
+ browser_window_open_location(bwin, url);
}
else
ro_gui_dialog_close(dialog_401li);
@@ -106,9 +121,7 @@ void ro_gui_401login_click(wimp_pointer *pointer) {
else {
get_unamepwd();
ro_gui_dialog_close(dialog_401li);
- do_thing();
- LOGIN.string = 0; /* TODO: keep the details until we
- * access a new site */
+ browser_window_open_location(bwin, url);
}
break;
default: break;
@@ -117,24 +130,9 @@ void ro_gui_401login_click(wimp_pointer *pointer) {
void get_unamepwd() {
- LOGIN.string = xcalloc(strlen(uname)+strlen(pwd)+2, sizeof(char));
-
- sprintf(LOGIN.string, "%s:%s", uname, pwd);
- LOG(("%s", LOGIN.string));
-}
+ char *lidets = xcalloc(strlen(uname)+strlen(pwd)+2, sizeof(char));
-void do_thing() {
+ sprintf(lidets, "%s:%s", uname, pwd);
- struct gui_window *gw;
-
- /* TODO: fix this. For now we just open the page in the
- * first window in the list. */
- for (gw=window_list; gw!=NULL; gw=gw->next) {
- if (gw->type == GUI_BROWSER_WINDOW /*&&
- (strcasecmp(gw->url, url)==0 ||
- strcasecmp(gw->data.browser.bw->url, url)==0)*/)
- break;
- }
- if (gw != NULL)
- browser_window_open_location_historical(gw->data.browser.bw, url, 0, 0);
+ login_list_add(url, lidets);
}
diff --git a/utils/utils.c b/utils/utils.c
index bc912fdc7..ca7d7f2fc 100644
--- a/utils/utils.c
+++ b/utils/utils.c
@@ -197,14 +197,14 @@ char *url_join(const char* new, const char* base)
nn[j] = new[i];
k = j;
}
-
+
j++;
}
if(k < j){
nn[k+1] = '\0';
LOG(("before: %s after: %s", new, nn));
}
-
+
new = nn;
if (base == 0)
@@ -252,7 +252,26 @@ char *url_join(const char* new, const char* base)
strcpy(ret, new);
}
- xfree(nn);
+ xfree(nn);
return ret;
}
+char *get_host_from_url (char *url) {
+
+ char *host = xcalloc(strlen(url)+10, sizeof(char));
+ int i;
+
+ i = strspn(url, "abcdefghijklmnopqrstuvwxyz");
+ if (url[i] == ':') {
+ strcpy(host, url);
+ i += 3;
+ }
+
+ for (; host[i] != 0 && host[i] != '/'; i++)
+ host[i] = tolower(host[i]);
+
+ host[i] = '/';
+ host[i+1] = 0;
+
+ return host;
+}
diff --git a/utils/utils.h b/utils/utils.h
index 9403d194e..30050b0ae 100644
--- a/utils/utils.h
+++ b/utils/utils.h
@@ -24,5 +24,6 @@ char * tolat1(xmlChar * s);
char * tolat1_pre(xmlChar * s);
char *squash_tolat1(xmlChar *s);
char *url_join(const char* new, const char* base);
+char *get_host_from_url(char* url);
#endif