diff --git a/src/app/browser/window/tab/item/page.rs b/src/app/browser/window/tab/item/page.rs index 9dc97035..d59d1cc0 100644 --- a/src/app/browser/window/tab/item/page.rs +++ b/src/app/browser/window/tab/item/page.rs @@ -164,12 +164,12 @@ impl Page { let id = self.id.clone(); // Prevent infinitive redirection - if self.meta.total_redirects() > DEFAULT_MAX_REDIRECT_COUNT { + if self.meta.redirects() > DEFAULT_MAX_REDIRECT_COUNT { todo!() } // Try redirect request - let request = if let Some(redirect) = self.meta.last_redirect() { + let request = if let Some(redirect) = self.meta.redirect() { if redirect.is_foreground { self.navigation .request @@ -762,7 +762,7 @@ impl Page { ) ); // Client MUST limit the number of redirects they follow to 5 (by protocol specification) - } else if meta.total_redirects() > 5 { + } else if meta.redirects() > 5 { // Update meta meta.set_status(Status::Failure) .set_title("Oops"); @@ -778,7 +778,7 @@ impl Page { // Redirection value looks valid, create new redirect (stored in meta `Redirect` holder) // then call page reload action to apply it by the parental controller } else { - meta.set_redirect( + meta.add_redirect( // skip query and fragment by protocol requirements // @TODO review fragment specification resolved_uri.to_string_partial( diff --git a/src/app/browser/window/tab/item/page/meta.rs b/src/app/browser/window/tab/item/page/meta.rs index f79c6980..4f4ad14a 100644 --- a/src/app/browser/window/tab/item/page/meta.rs +++ b/src/app/browser/window/tab/item/page/meta.rs @@ -5,7 +5,7 @@ use redirect::Redirect; use gtk::glib::GString; use sqlite::Transaction; -use std::cell::RefCell; +use std::cell::{Cell, RefCell}; #[derive(Debug, Clone)] pub enum Status { @@ -57,15 +57,18 @@ impl Meta { self } - pub fn set_redirect( + pub fn add_redirect( &self, request: GString, referrer: Option, is_foreground: bool, ) -> &Self { - self.redirect - .borrow_mut() - .push(Redirect::new(request, referrer, is_foreground)); + self.redirect.borrow_mut().push(Redirect { + request, + referrer, + is_foreground, + is_processed: Cell::new(false), + }); self } @@ -79,12 +82,17 @@ impl Meta { self.title.borrow().clone() } - pub fn total_redirects(&self) -> usize { + pub fn redirects(&self) -> usize { self.redirect.borrow().len() + 1 } - pub fn last_redirect(&self) -> Option { - self.redirect.borrow().last().cloned() + pub fn redirect(&self) -> Option { + if let Some(redirect) = self.redirect.borrow().last() { + if !redirect.is_processed.replace(true) { + return Some(redirect.clone()); + } + } + None } // Actions diff --git a/src/app/browser/window/tab/item/page/meta/redirect.rs b/src/app/browser/window/tab/item/page/meta/redirect.rs index 62c547c9..4173628e 100644 --- a/src/app/browser/window/tab/item/page/meta/redirect.rs +++ b/src/app/browser/window/tab/item/page/meta/redirect.rs @@ -1,32 +1,10 @@ use gtk::glib::GString; +use std::cell::Cell; -/// # Redirection data holder -/// -/// This component does nothing, -/// but useful as the container for temporary redirection data -/// operated by external controller -/// -/// ## Members -/// -/// * `is_foreground` - indicates how to process this redirect -/// * `request` - destination -/// * currently, it's raw `GString` not [Uri](https://docs.gtk.org/glib/struct.Uri.html) -/// because of compatibility with request field as it could contain any other, not parsable values #[derive(Clone, Debug)] pub struct Redirect { pub is_foreground: bool, + pub is_processed: Cell, pub referrer: Option, pub request: GString, } - -impl Redirect { - // Constructors - - pub fn new(request: GString, referrer: Option, is_foreground: bool) -> Self { - Self { - is_foreground, - referrer, - request, - } - } -}