/* @history_funcs{"go"} */ static JSBool history_go(JSContext *ctx, unsigned int argc, jsval *rval) { struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx); struct document_view *doc_view = interpreter->vs->doc_view; struct session *ses = doc_view->session; jsval *argv = JS_ARGV(ctx, rval); int index; struct location *loc; if (argc != 1) return JS_TRUE; index = atol(jsval_to_string(ctx, &argv[0])); for (loc = cur_loc(ses); loc != (struct location *) &ses->history.history; loc = index > 0 ? loc->next : loc->prev) { if (!index) { go_history(ses, loc); break; } index += index > 0 ? -1 : 1; } JS_SET_RVAL(ctx, rval, JSVAL_NULL); return 2; }
/** If @a loaded_in_frame is set, this was called just to indicate a move inside * a frameset, and we basically just reset the appropriate frame's view_state in * that case. When clicking on a link inside a frame, the frame URI is somehow * updated and added to the files-to-load queue, then ses_forward() is called * with @a loaded_in_frame unset, duplicating the whole frameset's location, * then later the file-to-load callback calls it for the particular frame with * @a loaded_in_frame set. */ struct view_state * ses_forward(struct session *ses, int loaded_in_frame) { struct location *loc = NULL; struct view_state *vs; if (!loaded_in_frame) { free_files(ses); mem_free_set(&ses->search_word, NULL); } x: if (!loaded_in_frame) { loc = mem_calloc(1, sizeof(*loc)); if (!loc) return NULL; copy_struct(&loc->download, &ses->loading); } if (ses->task.target.frame && *ses->task.target.frame) { struct frame *frame; assertm(have_location(ses), "no location yet"); if_assert_failed return NULL; if (!loaded_in_frame) { copy_location(loc, cur_loc(ses)); add_to_history(&ses->history, loc); } frame = ses_find_frame(ses, ses->task.target.frame); if (!frame) { if (!loaded_in_frame) { del_from_history(&ses->history, loc); destroy_location(loc); } mem_free_set(&ses->task.target.frame, NULL); goto x; } vs = &frame->vs; if (!loaded_in_frame) { destroy_vs(vs, 1); init_vs(vs, ses->loading_uri, vs->plain); } else { done_uri(vs->uri); vs->uri = get_uri_reference(ses->loading_uri); if (vs->doc_view) { /* vs->doc_view itself will get detached in * render_document_frames(), but that's too * late for us. */ vs->doc_view->vs = NULL; vs->doc_view = NULL; } #ifdef CONFIG_ECMASCRIPT vs->ecmascript_fragile = 1; #endif } } else {
static enum evhook_status script_hook_goto_url(va_list ap, void *data) { unsigned char **url = va_arg(ap, unsigned char **); struct session *ses = va_arg(ap, struct session *); int error; VALUE args[2]; VALUE result; if (*url == NULL) return EVENT_HOOK_STATUS_NEXT; args[0] = rb_str_new(*url, strlen((const char *)*url)); if (!ses || !have_location(ses)) { args[1] = Qnil; } else { args[1] = rb_str_new(struri(cur_loc(ses)->vs.uri), strlen((const char *)struri(cur_loc(ses)->vs.uri))); } result = erb_protected_method_call("goto_url_hook", 2, args, &error); if (error) { erb_report_error(ses, error); return EVENT_HOOK_STATUS_NEXT; } switch (rb_type(result)) { case T_STRING: { unsigned char *new_url; new_url = memacpy(RSTRING(result)->ptr, RSTRING(result)->len); if (new_url) { mem_free_set(url, new_url); } break; } case T_NIL: break; default: alert_ruby_error(ses, "goto_url_hook must return a string or nil"); } return EVENT_HOOK_STATUS_NEXT; }
static void auth_ok(void *data) { struct dialog *dlg = (struct dialog *)data; struct auth_entry *entry = (struct auth_entry *)dlg->udata2; struct session *ses = (struct session *)dlg->udata; entry->blocked = 0; entry->valid = auth_entry_has_userinfo(entry); #ifdef CONFIG_FORMHIST if (get_opt_bool((const unsigned char *)"document.browse.forms.show_formhist", ses)) { unsigned char *url = get_uri_string(entry->uri, URI_HTTP_AUTH); if (url) { struct form form = {}; form.action = url; INIT_LIST_OF(struct submitted_value, submit); struct submitted_value *user, *password; user = init_submitted_value((unsigned char *)"user", entry->user, FC_TEXT, NULL, 0); if (user) { add_to_list(submit, user); } password = init_submitted_value((unsigned char *)"password", entry->password, FC_PASSWORD, NULL, 0); if (password) { add_to_list(submit, password); } memorize_form(ses, &submit, &form); done_submitted_value_list(&submit); mem_free(url); } } #endif if (entry->valid && have_location(ses)) { struct location *loc = cur_loc(ses); struct uri *uri = loc->vs.uri; /* Make a 'fake' redirect to a URI without user/password so that * the user/password from the URI will not override what the * user just entered in the dialog. */ if ((uri->userlen && strlcmp(entry->user, -1, uri->user, uri->userlen)) || (uri->password && strlcmp(entry->password, -1, uri->password, uri->passwordlen))) { uri = get_composed_uri(uri, URI_HTTP_AUTH | URI_DATA | URI_POST); if (uri) { goto_uri_frame(ses, uri, NULL, CACHE_MODE_INCREMENT); done_uri(uri); return; } } } reload(ses, CACHE_MODE_INCREMENT); }
struct option * get_domain_option_from_session(unsigned char *name, struct session *ses) { struct uri *uri; assert(ses); assert(name); if (!have_location(ses)) return NULL; uri = cur_loc(ses)->vs.uri; if (!uri->host || !uri->hostlen) return NULL; return get_domain_option(uri->host, uri->hostlen, name); }
static enum evhook_status goto_url_hook(va_list ap, void *data) { unsigned char **url = va_arg(ap, unsigned char **); struct session *ses = va_arg(ap, struct session *); unsigned char *uu = NULL; unsigned char *arg = ""; unsigned char *argstart = *url + strcspn(*url, " :"); if (get_smart_enable() && *argstart) { unsigned char bucket = *argstart; *argstart = '\0'; uu = get_uri_rewrite_prefix(URI_REWRITE_SMART, *url); *argstart = bucket; arg = argstart + 1; } if (get_dumb_enable() && !uu && !*argstart) uu = get_uri_rewrite_prefix(URI_REWRITE_DUMB, *url); if (!uu && !strchr((const char *)*url, ':') && !strchr((const char *)*url, '.') && !strchr((const char *)*url, '/')) { uu = get_opt_str("protocol.rewrite.default_template", NULL); if (uu && *uu) { arg = *url; } else { uu = NULL; } } if (uu) { struct uri *uri = ses && have_location(ses) ? cur_loc(ses)->vs.uri : NULL; uu = rewrite_uri(uu, uri, arg); if (uu) { mem_free(*url); *url = uu; } } return EVENT_HOOK_STATUS_NEXT; }
static inline void do_script_hook_goto_url(struct session *ses, unsigned char **url) { int count; dSP; /* Keep in variables declaration block. */ ENTER; SAVETMPS; PUSHMARK(SP); my_XPUSHs(*url, strlen((const char *)*url)); if (!ses || !have_location(ses)) { XPUSHs(sv_2mortal(newSV(0))); } else { unsigned char *uri = struri(cur_loc(ses)->vs.uri); my_XPUSHs(uri, strlen((const char *)uri)); } PUTBACK; count = call_pv("goto_url_hook", G_EVAL | G_SCALAR); if (SvTRUE(ERRSV)) count = 0; /* FIXME: error message ? */ SPAGAIN; if (count == 1) { #ifndef CONFIG_PERL_POPPX_WITHOUT_N_A STRLEN n_a; /* Used by POPpx macro. */ #endif unsigned char *new_url = POPpx; if (new_url) { unsigned char *n = stracpy(new_url); if (n) { mem_free_set(url, n); } } } PUTBACK; FREETMPS; LEAVE; }