mirror of
https://github.com/YGGverse/Yoda.git
synced 2025-01-29 20:44:25 +00:00
keep all redirects chain, add referrer holder
This commit is contained in:
parent
ff3f064534
commit
ae5399e68e
@ -155,7 +155,7 @@ impl Page {
|
|||||||
pub fn load(&self, is_history: bool) {
|
pub fn load(&self, is_history: bool) {
|
||||||
/// Global limit to prevent infinitive redirects (ALL protocols)
|
/// Global limit to prevent infinitive redirects (ALL protocols)
|
||||||
/// * every protocol implementation has own value checker, according to specification
|
/// * every protocol implementation has own value checker, according to specification
|
||||||
const DEFAULT_MAX_REDIRECT_COUNT: i8 = 10;
|
const DEFAULT_MAX_REDIRECT_COUNT: usize = 10;
|
||||||
|
|
||||||
// Reset widgets
|
// Reset widgets
|
||||||
self.input.unset();
|
self.input.unset();
|
||||||
@ -163,40 +163,29 @@ impl Page {
|
|||||||
// Create shared variant value
|
// Create shared variant value
|
||||||
let id = self.id.clone();
|
let id = self.id.clone();
|
||||||
|
|
||||||
// Try **take** request value from Redirect holder first
|
// Prevent infinitive redirection
|
||||||
let request = if let Some(redirect) = self.meta.take_redirect() {
|
if self.meta.total_redirects() > DEFAULT_MAX_REDIRECT_COUNT {
|
||||||
// Update redirect counter
|
todo!()
|
||||||
self.meta
|
}
|
||||||
.set_redirect_count(match self.meta.redirect_count() {
|
|
||||||
Some(value) => {
|
|
||||||
// Prevent infinitive redirection
|
|
||||||
if value > DEFAULT_MAX_REDIRECT_COUNT {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
// Increase
|
|
||||||
Some(value + 1)
|
|
||||||
}
|
|
||||||
// Set initial value
|
|
||||||
None => Some(1),
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update navigation on redirect `is_foreground`
|
// Try redirect request
|
||||||
if redirect.is_foreground() {
|
let request = if let Some(redirect) = self.meta.last_redirect() {
|
||||||
|
if redirect.is_foreground {
|
||||||
self.navigation
|
self.navigation
|
||||||
.request
|
.request
|
||||||
.widget
|
.widget
|
||||||
.entry
|
.entry
|
||||||
.set_text(redirect.request().as_str());
|
.set_text(&redirect.request);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return value from redirection holder
|
// Return value from redirection holder
|
||||||
Request::from(&redirect.request())
|
Request::from(&redirect.request, redirect.referrer.as_ref())
|
||||||
} else {
|
} else {
|
||||||
// Reset redirect counter as request value taken from user input
|
// Reset redirect counter as request value taken from user input
|
||||||
self.meta.unset_redirect_count();
|
self.meta.redirect.borrow_mut().clear();
|
||||||
|
|
||||||
// Return value from navigation entry
|
// Return value from navigation entry
|
||||||
Request::from(&self.navigation.request.widget.entry.text())
|
Request::from(&self.navigation.request.widget.entry.text(), None)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Update
|
// Update
|
||||||
@ -773,7 +762,7 @@ impl Page {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
// Client MUST limit the number of redirects they follow to 5 (by protocol specification)
|
// Client MUST limit the number of redirects they follow to 5 (by protocol specification)
|
||||||
} else if meta.redirect_count() > Some(5) {
|
} else if meta.total_redirects() > 5 {
|
||||||
// Update meta
|
// Update meta
|
||||||
meta.set_status(Status::Failure)
|
meta.set_status(Status::Failure)
|
||||||
.set_title("Oops");
|
.set_title("Oops");
|
||||||
@ -790,12 +779,14 @@ impl Page {
|
|||||||
// then call page reload action to apply it by the parental controller
|
// then call page reload action to apply it by the parental controller
|
||||||
} else {
|
} else {
|
||||||
meta.set_redirect(
|
meta.set_redirect(
|
||||||
// Skip query and fragment by protocol requirements
|
// skip query and fragment by protocol requirements
|
||||||
// @TODO review fragment specification
|
// @TODO review fragment specification
|
||||||
resolved_uri.to_string_partial(
|
resolved_uri.to_string_partial(
|
||||||
UriHideFlags::FRAGMENT | UriHideFlags::QUERY
|
UriHideFlags::FRAGMENT | UriHideFlags::QUERY
|
||||||
),
|
),
|
||||||
// Set follow policy based on status code
|
// referrer
|
||||||
|
Some(navigation.request.widget.entry.text()),
|
||||||
|
// set follow policy based on status code
|
||||||
matches!(response.meta.status, gemini::client::connection::response::meta::Status::PermanentRedirect),
|
matches!(response.meta.status, gemini::client::connection::response::meta::Status::PermanentRedirect),
|
||||||
)
|
)
|
||||||
.set_status(Status::Redirect) // @TODO is this status really wanted?
|
.set_status(Status::Redirect) // @TODO is this status really wanted?
|
||||||
|
@ -29,10 +29,9 @@ pub enum Status {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Meta {
|
pub struct Meta {
|
||||||
status: RefCell<Status>,
|
pub status: RefCell<Status>,
|
||||||
title: RefCell<GString>,
|
pub title: RefCell<GString>,
|
||||||
redirect: RefCell<Option<Redirect>>,
|
pub redirect: RefCell<Vec<Redirect>>,
|
||||||
redirect_count: RefCell<Option<i8>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Meta {
|
impl Meta {
|
||||||
@ -42,8 +41,7 @@ impl Meta {
|
|||||||
Self {
|
Self {
|
||||||
status: RefCell::new(status),
|
status: RefCell::new(status),
|
||||||
title: RefCell::new(title),
|
title: RefCell::new(title),
|
||||||
redirect: RefCell::new(None),
|
redirect: RefCell::new(Vec::new()),
|
||||||
redirect_count: RefCell::new(None),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,30 +57,18 @@ impl Meta {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_redirect(&self, request: GString, is_foreground: bool) -> &Self {
|
pub fn set_redirect(
|
||||||
|
&self,
|
||||||
|
request: GString,
|
||||||
|
referrer: Option<GString>,
|
||||||
|
is_foreground: bool,
|
||||||
|
) -> &Self {
|
||||||
self.redirect
|
self.redirect
|
||||||
.replace(Some(Redirect::new(request, is_foreground)));
|
.borrow_mut()
|
||||||
|
.push(Redirect::new(request, referrer, is_foreground));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_redirect_count(&self, redirect_count: Option<i8>) -> &Self {
|
|
||||||
self.redirect_count.replace(redirect_count);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn unset_redirect_count(&self) -> &Self {
|
|
||||||
if self.redirect_count.borrow().is_some() {
|
|
||||||
self.set_redirect_count(None);
|
|
||||||
}
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/* @TODO not in use
|
|
||||||
pub fn unset_redirect(&self) -> &Self {
|
|
||||||
self.redirect.replace(None);
|
|
||||||
self
|
|
||||||
} */
|
|
||||||
|
|
||||||
// Getters
|
// Getters
|
||||||
|
|
||||||
pub fn status(&self) -> Status {
|
pub fn status(&self) -> Status {
|
||||||
@ -93,15 +79,12 @@ impl Meta {
|
|||||||
self.title.borrow().clone()
|
self.title.borrow().clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn redirect_count(&self) -> Option<i8> {
|
pub fn total_redirects(&self) -> usize {
|
||||||
*self.redirect_count.borrow()
|
self.redirect.borrow().len() + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
/// WARNING!
|
pub fn last_redirect(&self) -> Option<Redirect> {
|
||||||
///
|
self.redirect.borrow().last().cloned()
|
||||||
/// This function **take** the `Redirect` without clone semantics
|
|
||||||
pub fn take_redirect(&self) -> Option<Redirect> {
|
|
||||||
self.redirect.take()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
|
@ -12,28 +12,21 @@ use gtk::glib::GString;
|
|||||||
/// * `request` - destination
|
/// * `request` - destination
|
||||||
/// * currently, it's raw `GString` not [Uri](https://docs.gtk.org/glib/struct.Uri.html)
|
/// * 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
|
/// because of compatibility with request field as it could contain any other, not parsable values
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
pub struct Redirect {
|
pub struct Redirect {
|
||||||
is_foreground: bool,
|
pub is_foreground: bool,
|
||||||
request: GString,
|
pub referrer: Option<GString>,
|
||||||
|
pub request: GString,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Redirect {
|
impl Redirect {
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
pub fn new(request: GString, is_foreground: bool) -> Self {
|
pub fn new(request: GString, referrer: Option<GString>, is_foreground: bool) -> Self {
|
||||||
Self {
|
Self {
|
||||||
is_foreground,
|
is_foreground,
|
||||||
|
referrer,
|
||||||
request,
|
request,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Getters
|
|
||||||
|
|
||||||
pub fn request(&self) -> GString {
|
|
||||||
self.request.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_foreground(&self) -> bool {
|
|
||||||
self.is_foreground
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use gtk::glib::{Uri, UriFlags};
|
use gtk::glib::{GString, Uri, UriFlags};
|
||||||
|
|
||||||
/// Request type for `Page` with optional value parsed
|
/// Request type for `Page` with optional value parsed
|
||||||
pub enum Request {
|
pub enum Request {
|
||||||
@ -12,7 +12,9 @@ impl Request {
|
|||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
/// Create new `Self` from `request` string
|
/// Create new `Self` from `request` string
|
||||||
pub fn from(request: &str) -> Self {
|
/// * if some `referrer` given, make additional check in previous request
|
||||||
|
pub fn from(request: &str, referrer: Option<&GString>) -> Self {
|
||||||
|
// check in request
|
||||||
if let Some(postfix) = request.strip_prefix("source:") {
|
if let Some(postfix) = request.strip_prefix("source:") {
|
||||||
if let Ok(uri) = Uri::parse(postfix, UriFlags::NONE) {
|
if let Ok(uri) = Uri::parse(postfix, UriFlags::NONE) {
|
||||||
return Self::Source(uri);
|
return Self::Source(uri);
|
||||||
@ -25,10 +27,25 @@ impl Request {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check in referrer @TODO tmp
|
||||||
|
if referrer.is_some_and(|this| this.starts_with("source:")) {
|
||||||
|
if let Ok(uri) = Uri::parse(request, UriFlags::NONE) {
|
||||||
|
return Self::Source(uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if referrer.is_some_and(|this| this.starts_with("download:")) {
|
||||||
|
if let Ok(uri) = Uri::parse(request, UriFlags::NONE) {
|
||||||
|
return Self::Download(uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// is default
|
||||||
if let Ok(uri) = Uri::parse(request, UriFlags::NONE) {
|
if let Ok(uri) = Uri::parse(request, UriFlags::NONE) {
|
||||||
return Self::Default(uri);
|
return Self::Default(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// is search
|
||||||
Self::Search(request.to_string())
|
Self::Search(request.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user