From 380ade924fe187bd3df50867c140ae1fb872497c Mon Sep 17 00:00:00 2001 From: yggverse Date: Fri, 17 Jan 2025 08:57:46 +0200 Subject: [PATCH] draft redirection features --- src/app/browser/window/tab/item/page.rs | 5 ++- .../tab/item/page/client/driver/gemini.rs | 40 ++++++++++++++----- .../window/tab/item/page/client/response.rs | 3 +- 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/app/browser/window/tab/item/page.rs b/src/app/browser/window/tab/item/page.rs index ef73c8f0..69bb3197 100644 --- a/src/app/browser/window/tab/item/page.rs +++ b/src/app/browser/window/tab/item/page.rs @@ -302,11 +302,12 @@ impl Page { } }, Response::Redirect { + referrer, request, is_foreground, } => { - // Some protocols may support foreground redirects - // for example status code `31` in Gemini + // Some clients may support foreground redirects + // e.g. status code `31` in Gemini protocol if is_foreground { navigation .request diff --git a/src/app/browser/window/tab/item/page/client/driver/gemini.rs b/src/app/browser/window/tab/item/page/client/driver/gemini.rs index 80be04ea..ae0c29a3 100644 --- a/src/app/browser/window/tab/item/page/client/driver/gemini.rs +++ b/src/app/browser/window/tab/item/page/client/driver/gemini.rs @@ -4,7 +4,7 @@ use super::{ }; use gtk::{ gio::Cancellable, - glib::{Priority, Uri}, + glib::{Priority, Uri, UriFlags}, }; use std::rc::Rc; @@ -94,15 +94,37 @@ pub fn handle( } // @TODO handle `None` } // https://geminiprotocol.net/docs/protocol-specification.gmi#status-30-temporary-redirection - Status::Redirect => callback(Response::Redirect { - request: base, - is_foreground: false, - }), + Status::Redirect => callback(match response.meta.data { + Some(data) => match Uri::parse_relative(&base, &data.value, UriFlags::NONE) { + Ok(request) => Response::Redirect { + referrer: base, + request, + is_foreground: false, + }, + Err(e) => Response::Failure(Failure::Error { + message: format!("Could not parse target address: {}", e.message()), + }), + }, + None => Response::Failure(Failure::Error { + message: "Target address not found".to_string(), + }), + }), // @TODO validate redirect count // https://geminiprotocol.net/docs/protocol-specification.gmi#status-31-permanent-redirection - Status::PermanentRedirect => callback(Response::Redirect { - request: base, - is_foreground: true, - }), + Status::PermanentRedirect => callback(match response.meta.data { + Some(data) => match Uri::parse_relative(&base, &data.value, UriFlags::NONE) { + Ok(request) => Response::Redirect { + referrer: base, + request, + is_foreground: true, + }, + Err(e) => Response::Failure(Failure::Error { + message: format!("Could not parse target address: {}", e.message()), + }), + }, + None => Response::Failure(Failure::Error { + message: "Target address not found".to_string(), + }), + }), // @TODO validate redirect count // https://geminiprotocol.net/docs/protocol-specification.gmi#status-60 Status::CertificateRequest => callback(Response::Certificate(Certificate::Request { title: match response.meta.data { diff --git a/src/app/browser/window/tab/item/page/client/response.rs b/src/app/browser/window/tab/item/page/client/response.rs index 58c51d76..559b7e56 100644 --- a/src/app/browser/window/tab/item/page/client/response.rs +++ b/src/app/browser/window/tab/item/page/client/response.rs @@ -29,8 +29,9 @@ pub enum Response { }, Input(Input), Redirect { - request: Uri, is_foreground: bool, + referrer: Uri, + request: Uri, }, Stream { base: Uri,