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