mirror of
https://github.com/YGGverse/Yoda.git
synced 2025-02-10 18:34:14 +00:00
draft redirection referrer feature
This commit is contained in:
parent
4665a7ff6a
commit
86a6ad058a
@ -302,12 +302,12 @@ impl Page {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
Response::Redirect(this) => match this {
|
Response::Redirect(this) => match this {
|
||||||
Redirect::Background { source, target } => todo!(), // @TODO
|
Redirect::Background(request) => todo!(), // @TODO
|
||||||
Redirect::Foreground { source, target } => navigation
|
Redirect::Foreground(request) => {navigation
|
||||||
.request
|
.request
|
||||||
.widget
|
.widget
|
||||||
.entry
|
.entry
|
||||||
.set_text(&target.to_string()) // @TODO
|
.set_text(&request.uri().unwrap().to_string())} // @TODO handle
|
||||||
}
|
}
|
||||||
Response::TextGemini { base, source, is_source_request } => {
|
Response::TextGemini { base, source, is_source_request } => {
|
||||||
let widget = if is_source_request {
|
let widget = if is_source_request {
|
||||||
|
@ -64,6 +64,7 @@ impl Driver {
|
|||||||
/// Make new async `Feature` request
|
/// Make new async `Feature` request
|
||||||
/// * return `Response` in callback function
|
/// * return `Response` in callback function
|
||||||
pub fn request_async(&self, request: Request, callback: impl FnOnce(Response) + 'static) {
|
pub fn request_async(&self, request: Request, callback: impl FnOnce(Response) + 'static) {
|
||||||
|
let referrer = request.to_referrer();
|
||||||
match request.feature {
|
match request.feature {
|
||||||
Feature::Download(protocol) => match protocol {
|
Feature::Download(protocol) => match protocol {
|
||||||
Protocol::Gemini {
|
Protocol::Gemini {
|
||||||
@ -73,13 +74,16 @@ impl Driver {
|
|||||||
} => gemini::request_async(
|
} => gemini::request_async(
|
||||||
&self.profile,
|
&self.profile,
|
||||||
&self.gemini,
|
&self.gemini,
|
||||||
uri.clone(),
|
&uri,
|
||||||
cancellable.clone(),
|
&cancellable,
|
||||||
priority,
|
&priority,
|
||||||
|
{
|
||||||
|
let base = uri.clone();
|
||||||
|
let cancellable = cancellable.clone();
|
||||||
move |result| {
|
move |result| {
|
||||||
callback(match result {
|
callback(match result {
|
||||||
Ok(response) => Response::Download {
|
Ok(response) => Response::Download {
|
||||||
base: uri,
|
base,
|
||||||
stream: response.connection.stream(),
|
stream: response.connection.stream(),
|
||||||
cancellable,
|
cancellable,
|
||||||
},
|
},
|
||||||
@ -87,6 +91,7 @@ impl Driver {
|
|||||||
message: e.to_string(),
|
message: e.to_string(),
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
_ => callback(Response::Failure(Failure::Error {
|
_ => callback(Response::Failure(Failure::Error {
|
||||||
@ -101,17 +106,30 @@ impl Driver {
|
|||||||
} => gemini::request_async(
|
} => gemini::request_async(
|
||||||
&self.profile,
|
&self.profile,
|
||||||
&self.gemini,
|
&self.gemini,
|
||||||
uri.clone(),
|
&uri,
|
||||||
cancellable.clone(),
|
&cancellable,
|
||||||
priority,
|
&priority,
|
||||||
|
{
|
||||||
|
let cancellable = cancellable.clone();
|
||||||
|
let uri = uri.clone();
|
||||||
|
|
||||||
move |result| {
|
move |result| {
|
||||||
gemini::handle(result, uri, cancellable, priority, false, callback)
|
gemini::handle(
|
||||||
|
result,
|
||||||
|
uri,
|
||||||
|
cancellable,
|
||||||
|
priority,
|
||||||
|
referrer,
|
||||||
|
false,
|
||||||
|
callback,
|
||||||
|
)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
Protocol::Titan { .. } => todo!(),
|
Protocol::Titan { .. } => todo!(),
|
||||||
Protocol::Unsupported => todo!(),
|
Protocol::Unsupported => todo!(),
|
||||||
},
|
},
|
||||||
Feature::Source(protocol) => match protocol {
|
Feature::Source(ref protocol) => match protocol {
|
||||||
Protocol::Gemini {
|
Protocol::Gemini {
|
||||||
uri,
|
uri,
|
||||||
cancellable,
|
cancellable,
|
||||||
@ -119,11 +137,24 @@ impl Driver {
|
|||||||
} => gemini::request_async(
|
} => gemini::request_async(
|
||||||
&self.profile,
|
&self.profile,
|
||||||
&self.gemini,
|
&self.gemini,
|
||||||
uri.clone(),
|
uri,
|
||||||
cancellable.clone(),
|
cancellable,
|
||||||
priority,
|
priority,
|
||||||
|
{
|
||||||
|
let cancellable = cancellable.clone();
|
||||||
|
let priority = *priority;
|
||||||
|
let uri = uri.clone();
|
||||||
move |result| {
|
move |result| {
|
||||||
gemini::handle(result, uri, cancellable, priority, true, callback)
|
gemini::handle(
|
||||||
|
result,
|
||||||
|
uri,
|
||||||
|
cancellable,
|
||||||
|
priority,
|
||||||
|
request.referrer.to_vec(),
|
||||||
|
true,
|
||||||
|
callback,
|
||||||
|
)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
_ => callback(Response::Failure(Failure::Error {
|
_ => callback(Response::Failure(Failure::Error {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use super::{
|
use super::{
|
||||||
response::{Certificate, Failure, Input, Redirect},
|
response::{Certificate, Failure, Input, Redirect},
|
||||||
Profile, Response,
|
Profile, Request, Response,
|
||||||
};
|
};
|
||||||
use gtk::{
|
use gtk::{
|
||||||
gio::Cancellable,
|
gio::Cancellable,
|
||||||
@ -12,16 +12,16 @@ use std::rc::Rc;
|
|||||||
pub fn request_async(
|
pub fn request_async(
|
||||||
profile: &Rc<Profile>,
|
profile: &Rc<Profile>,
|
||||||
client: &Rc<ggemini::Client>,
|
client: &Rc<ggemini::Client>,
|
||||||
uri: Uri,
|
uri: &Uri,
|
||||||
cancellable: Cancellable,
|
cancellable: &Cancellable,
|
||||||
priority: Priority,
|
priority: &Priority,
|
||||||
callback: impl FnOnce(Result<ggemini::client::Response, ggemini::client::Error>) + 'static,
|
callback: impl FnOnce(Result<ggemini::client::Response, ggemini::client::Error>) + 'static,
|
||||||
) {
|
) {
|
||||||
let request = uri.to_string();
|
let request = uri.to_string();
|
||||||
client.request_async(
|
client.request_async(
|
||||||
ggemini::client::Request::gemini(uri),
|
ggemini::client::Request::gemini(uri.clone()),
|
||||||
priority,
|
priority.clone(),
|
||||||
cancellable,
|
cancellable.clone(),
|
||||||
// Search for user certificate match request
|
// Search for user certificate match request
|
||||||
// * @TODO this feature does not support multi-protocol yet
|
// * @TODO this feature does not support multi-protocol yet
|
||||||
match profile.identity.gemini.match_scope(&request) {
|
match profile.identity.gemini.match_scope(&request) {
|
||||||
@ -42,6 +42,7 @@ pub fn handle(
|
|||||||
base: Uri,
|
base: Uri,
|
||||||
cancellable: Cancellable,
|
cancellable: Cancellable,
|
||||||
priority: Priority,
|
priority: Priority,
|
||||||
|
referrer: Vec<Request>,
|
||||||
is_source_request: bool, // @TODO yet partial implementation
|
is_source_request: bool, // @TODO yet partial implementation
|
||||||
callback: impl FnOnce(Response) + 'static,
|
callback: impl FnOnce(Response) + 'static,
|
||||||
) {
|
) {
|
||||||
@ -68,8 +69,8 @@ pub fn handle(
|
|||||||
Some(mime) => match mime.as_str() {
|
Some(mime) => match mime.as_str() {
|
||||||
"text/gemini" => Text::from_stream_async(
|
"text/gemini" => Text::from_stream_async(
|
||||||
response.connection.stream(),
|
response.connection.stream(),
|
||||||
priority,
|
priority.clone(),
|
||||||
cancellable,
|
cancellable.clone(),
|
||||||
move |result| match result {
|
move |result| match result {
|
||||||
Ok(text) => callback(Response::TextGemini {
|
Ok(text) => callback(Response::TextGemini {
|
||||||
base,
|
base,
|
||||||
@ -100,10 +101,12 @@ pub fn handle(
|
|||||||
// https://geminiprotocol.net/docs/protocol-specification.gmi#status-30-temporary-redirection
|
// https://geminiprotocol.net/docs/protocol-specification.gmi#status-30-temporary-redirection
|
||||||
Status::Redirect => callback(match response.meta.data {
|
Status::Redirect => callback(match response.meta.data {
|
||||||
Some(data) => match Uri::parse_relative(&base, data.as_str(), UriFlags::NONE) {
|
Some(data) => match Uri::parse_relative(&base, data.as_str(), UriFlags::NONE) {
|
||||||
Ok(target) => Response::Redirect(Redirect::Foreground {
|
Ok(target) => Response::Redirect(Redirect::Foreground(Request::build(
|
||||||
source: base,
|
&target.to_string(),
|
||||||
target,
|
Some(referrer),
|
||||||
}),
|
cancellable,
|
||||||
|
priority,
|
||||||
|
))),
|
||||||
Err(e) => Response::Failure(Failure::Error {
|
Err(e) => Response::Failure(Failure::Error {
|
||||||
message: format!("Could not parse target address: {e}"),
|
message: format!("Could not parse target address: {e}"),
|
||||||
}),
|
}),
|
||||||
@ -115,10 +118,12 @@ pub fn handle(
|
|||||||
// https://geminiprotocol.net/docs/protocol-specification.gmi#status-31-permanent-redirection
|
// https://geminiprotocol.net/docs/protocol-specification.gmi#status-31-permanent-redirection
|
||||||
Status::PermanentRedirect => callback(match response.meta.data {
|
Status::PermanentRedirect => callback(match response.meta.data {
|
||||||
Some(data) => match Uri::parse_relative(&base, data.as_str(), UriFlags::NONE) {
|
Some(data) => match Uri::parse_relative(&base, data.as_str(), UriFlags::NONE) {
|
||||||
Ok(target) => Response::Redirect(Redirect::Background {
|
Ok(target) => Response::Redirect(Redirect::Background(Request::build(
|
||||||
source: base,
|
&target.to_string(),
|
||||||
target,
|
Some(referrer),
|
||||||
}),
|
cancellable,
|
||||||
|
priority,
|
||||||
|
))),
|
||||||
Err(e) => Response::Failure(Failure::Error {
|
Err(e) => Response::Failure(Failure::Error {
|
||||||
message: format!("Could not parse target address: {e}"),
|
message: format!("Could not parse target address: {e}"),
|
||||||
}),
|
}),
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
pub mod feature;
|
pub mod feature;
|
||||||
pub use feature::Feature;
|
pub use feature::Feature;
|
||||||
|
|
||||||
use gtk::{gio::Cancellable, glib::Priority};
|
use gtk::{
|
||||||
|
gio::Cancellable,
|
||||||
|
glib::{Priority, Uri},
|
||||||
|
};
|
||||||
|
|
||||||
/// Request data wrapper for `Client`
|
/// Request data wrapper for `Client`
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct Request {
|
pub struct Request {
|
||||||
pub feature: Feature,
|
pub feature: Feature,
|
||||||
/// Requests chain in order to process redirection rules
|
/// Requests chain in order to process redirection rules
|
||||||
@ -25,4 +29,17 @@ impl Request {
|
|||||||
referrer: referrer.unwrap_or_default(),
|
referrer: referrer.unwrap_or_default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
|
||||||
|
/// Copy `Self` to new `referrer` vector
|
||||||
|
pub fn to_referrer(&self) -> Vec<Request> {
|
||||||
|
let mut referrer = self.referrer.to_vec();
|
||||||
|
referrer.push(self.clone());
|
||||||
|
referrer
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn uri(&self) -> Option<&Uri> {
|
||||||
|
self.feature.uri()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
pub mod protocol;
|
pub mod protocol;
|
||||||
pub use protocol::Protocol;
|
pub use protocol::Protocol;
|
||||||
|
|
||||||
use gtk::{gio::Cancellable, glib::Priority};
|
use gtk::{
|
||||||
|
gio::Cancellable,
|
||||||
|
glib::{Priority, Uri},
|
||||||
|
};
|
||||||
|
|
||||||
/// Feature wrapper for client `Request`
|
/// Feature wrapper for client `Request`
|
||||||
|
#[derive(Clone)]
|
||||||
pub enum Feature {
|
pub enum Feature {
|
||||||
Default(Protocol),
|
Default(Protocol),
|
||||||
Download(Protocol),
|
Download(Protocol),
|
||||||
@ -26,4 +30,14 @@ impl Feature {
|
|||||||
|
|
||||||
Self::Default(Protocol::build(query, cancellable, priority))
|
Self::Default(Protocol::build(query, cancellable, priority))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
|
||||||
|
pub fn uri(&self) -> Option<&Uri> {
|
||||||
|
match self {
|
||||||
|
Self::Default(protocol) | Self::Download(protocol) | Self::Source(protocol) => {
|
||||||
|
protocol.uri()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ use gtk::{
|
|||||||
glib::{Priority, Uri, UriFlags},
|
glib::{Priority, Uri, UriFlags},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub enum Protocol {
|
pub enum Protocol {
|
||||||
Gemini {
|
Gemini {
|
||||||
uri: Uri,
|
uri: Uri,
|
||||||
@ -55,4 +56,22 @@ impl Protocol {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
|
||||||
|
pub fn uri(&self) -> Option<&Uri> {
|
||||||
|
match self {
|
||||||
|
Self::Gemini {
|
||||||
|
uri,
|
||||||
|
cancellable: _,
|
||||||
|
priority: _,
|
||||||
|
}
|
||||||
|
| Self::Titan {
|
||||||
|
uri,
|
||||||
|
cancellable: _,
|
||||||
|
priority: _,
|
||||||
|
} => Some(&uri),
|
||||||
|
Self::Unsupported => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use gtk::glib::Uri;
|
use crate::app::browser::window::tab::item::page::client::Request;
|
||||||
|
|
||||||
pub enum Redirect {
|
pub enum Redirect {
|
||||||
Foreground { source: Uri, target: Uri },
|
Foreground(Request),
|
||||||
Background { source: Uri, target: Uri },
|
Background(Request),
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user