mirror of
https://github.com/TxtDot/vigi.git
synced 2025-02-22 04:03:14 +03:00
feat: gemini support
This commit is contained in:
parent
15c43e3482
commit
d96b863ea8
26 changed files with 448 additions and 93 deletions
34
src-tauri/Cargo.lock
generated
34
src-tauri/Cargo.lock
generated
|
@ -258,9 +258,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
|||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.6.1"
|
||||
version = "1.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952"
|
||||
checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
@ -603,9 +603,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "dalet"
|
||||
version = "1.0.0-pre6"
|
||||
version = "1.0.0-pre9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8bc4c347533f8341633bd820799dea680f600e50891310b74bc914740681e8c2"
|
||||
checksum = "2095f83b5256dc9a981639c3250aba53c02736a3601c1e6b2c54c27ec786274a"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"enum-procs",
|
||||
|
@ -3093,6 +3093,15 @@ dependencies = [
|
|||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simd-adler32"
|
||||
version = "0.3.7"
|
||||
|
@ -3685,8 +3694,11 @@ dependencies = [
|
|||
"bytes",
|
||||
"libc",
|
||||
"mio",
|
||||
"parking_lot",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
|
@ -3704,6 +3716,17 @@ dependencies = [
|
|||
"webpki-roots",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-native-tls"
|
||||
version = "0.3.1"
|
||||
|
@ -4006,6 +4029,7 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
|||
name = "vigi"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"dalet",
|
||||
"mime",
|
||||
"reqwest 0.12.5",
|
||||
|
@ -4013,7 +4037,9 @@ dependencies = [
|
|||
"serde_json",
|
||||
"tauri",
|
||||
"tauri-build",
|
||||
"tokio",
|
||||
"tokio-gemini",
|
||||
"tokio-rustls",
|
||||
"url",
|
||||
]
|
||||
|
||||
|
|
|
@ -26,7 +26,14 @@ tauri = { version = "1", features = [
|
|||
] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
dalet = "1.0.0-pre6"
|
||||
dalet = "1.0.0-pre9"
|
||||
|
||||
tokio = { version = "1.39.2", features = ["full"] }
|
||||
tokio-rustls = { version = "0.26.0", default-features = false, features = [
|
||||
"ring",
|
||||
] }
|
||||
|
||||
bytes = "1.7.1"
|
||||
|
||||
reqwest = "0.12.5"
|
||||
tokio-gemini = "0.1.0"
|
||||
|
|
|
@ -7,7 +7,7 @@ mod process_input;
|
|||
mod types;
|
||||
mod utils;
|
||||
|
||||
use tauri::async_runtime::Mutex;
|
||||
use tokio::sync::Mutex;
|
||||
use types::{VigiError, VigiJsState, VigiState};
|
||||
use utils::{read_or_create_jsonl, read_or_create_number};
|
||||
|
||||
|
|
56
src-tauri/src/process_input/insecure_gemini_client.rs
Normal file
56
src-tauri/src/process_input/insecure_gemini_client.rs
Normal file
|
@ -0,0 +1,56 @@
|
|||
use tokio_rustls::rustls::{
|
||||
client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier},
|
||||
ClientConfig, SignatureScheme,
|
||||
};
|
||||
|
||||
/// TODO: update to secure version when supported
|
||||
pub fn insecure_gemini_client() -> tokio_gemini::Client {
|
||||
tokio_gemini::Client::from(
|
||||
ClientConfig::builder()
|
||||
.dangerous()
|
||||
.with_custom_certificate_verifier(std::sync::Arc::new(NoCertVerification {}))
|
||||
.with_no_client_auth(),
|
||||
)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct NoCertVerification;
|
||||
|
||||
impl ServerCertVerifier for NoCertVerification {
|
||||
fn verify_server_cert(
|
||||
&self,
|
||||
_end_entity: &tokio_rustls::rustls::pki_types::CertificateDer<'_>,
|
||||
_intermediates: &[tokio_rustls::rustls::pki_types::CertificateDer<'_>],
|
||||
_server_name: &tokio_rustls::rustls::pki_types::ServerName<'_>,
|
||||
_ocsp_response: &[u8],
|
||||
_now: tokio_rustls::rustls::pki_types::UnixTime,
|
||||
) -> Result<ServerCertVerified, tokio_rustls::rustls::Error> {
|
||||
Ok(ServerCertVerified::assertion())
|
||||
}
|
||||
|
||||
fn verify_tls12_signature(
|
||||
&self,
|
||||
_message: &[u8],
|
||||
_cert: &tokio_rustls::rustls::pki_types::CertificateDer<'_>,
|
||||
_dss: &tokio_rustls::rustls::DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, tokio_rustls::rustls::Error> {
|
||||
Ok(HandshakeSignatureValid::assertion())
|
||||
}
|
||||
|
||||
fn verify_tls13_signature(
|
||||
&self,
|
||||
_message: &[u8],
|
||||
_cert: &tokio_rustls::rustls::pki_types::CertificateDer<'_>,
|
||||
_dss: &tokio_rustls::rustls::DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, tokio_rustls::rustls::Error> {
|
||||
Ok(HandshakeSignatureValid::assertion())
|
||||
}
|
||||
|
||||
fn supported_verify_schemes(&self) -> Vec<tokio_rustls::rustls::SignatureScheme> {
|
||||
vec![
|
||||
SignatureScheme::ECDSA_NISTP256_SHA256,
|
||||
SignatureScheme::ECDSA_NISTP384_SHA384,
|
||||
SignatureScheme::ECDSA_NISTP521_SHA512,
|
||||
]
|
||||
}
|
||||
}
|
|
@ -1,15 +1,16 @@
|
|||
use crate::types::{VigiError, VigiOutput};
|
||||
use bytes::Bytes;
|
||||
use mime::Mime;
|
||||
use url::Url;
|
||||
|
||||
mod insecure_gemini_client;
|
||||
mod process_data;
|
||||
mod process_url;
|
||||
|
||||
use process_data::process_data;
|
||||
use process_url::process_url;
|
||||
|
||||
type Data = Vec<u8>;
|
||||
type ReqResult = (Mime, Data);
|
||||
type ReqResult = (Mime, Bytes);
|
||||
|
||||
pub async fn process_input(input: &String) -> Result<VigiOutput, VigiError> {
|
||||
let parsed = Url::parse(input);
|
||||
|
|
|
@ -1,25 +1,41 @@
|
|||
use dalet::{daletl::ToDaletlPage, typed::Tag::*};
|
||||
use bytes::Bytes;
|
||||
use dalet::{daletl::ToDaletlPage, parsers::gemtext::parse_gemtext, typed::Tag::*};
|
||||
use mime::Mime;
|
||||
use std::str;
|
||||
|
||||
use crate::types::{VigiError, VigiOutput};
|
||||
|
||||
pub async fn process_data(mime: Mime, data: Vec<u8>) -> Result<VigiOutput, VigiError> {
|
||||
pub async fn process_data(mime: Mime, data: Bytes) -> Result<VigiOutput, VigiError> {
|
||||
let result = match (mime.type_().as_str(), mime.subtype().as_str()) {
|
||||
("text", "plain") => {
|
||||
process_text(String::from_utf8(data).map_err(|_| VigiError::TextIsNotUtf8)?).await
|
||||
process_text(str::from_utf8(&data).map_err(|_| VigiError::InvalidCharset)?).await
|
||||
}
|
||||
("text", "gemini") => {
|
||||
process_gemini(str::from_utf8(&data).map_err(|_| VigiError::InvalidCharset)?).await?
|
||||
}
|
||||
// ("text", "gemini") => {
|
||||
// process_text(String::from_utf8(data).map_err(|_| VigiError::TextIsNotUtf8)?).await
|
||||
// }
|
||||
_ => Err(VigiError::UnsupportedMimeType)?,
|
||||
};
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
async fn process_text(data: String) -> VigiOutput {
|
||||
let mut truncated = data.clone();
|
||||
async fn process_text(data: &str) -> VigiOutput {
|
||||
let mut truncated = data.to_owned();
|
||||
truncated.truncate(50);
|
||||
|
||||
VigiOutput::new(truncated, vec![El(data.into())].to_dl_page())
|
||||
}
|
||||
|
||||
async fn process_gemini(data: &str) -> Result<VigiOutput, VigiError> {
|
||||
let mut truncated = data.to_owned();
|
||||
truncated.truncate(50);
|
||||
|
||||
let res = VigiOutput::new(
|
||||
truncated,
|
||||
parse_gemtext(data)
|
||||
.map_err(|_| VigiError::Parse)?
|
||||
.to_dl_page(),
|
||||
);
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
use bytes::Bytes;
|
||||
use mime::Mime;
|
||||
use reqwest::header::CONTENT_TYPE;
|
||||
use tokio::io::AsyncReadExt;
|
||||
use url::Url;
|
||||
|
||||
use crate::types::VigiError;
|
||||
|
||||
use super::ReqResult;
|
||||
use super::{insecure_gemini_client, ReqResult};
|
||||
|
||||
pub async fn process_url(url: Url) -> Result<ReqResult, VigiError> {
|
||||
let result = match url.scheme() {
|
||||
"http" | "https" => process_http(url.to_string()).await?,
|
||||
// "gemini" => process_gemini(url.to_string()).await?,
|
||||
"gemini" => process_gemini(url.to_string()).await?,
|
||||
_ => Err(VigiError::UnsupportedProtocol)?,
|
||||
};
|
||||
|
||||
|
@ -37,16 +39,21 @@ async fn process_http(url: String) -> Result<ReqResult, VigiError> {
|
|||
))
|
||||
}
|
||||
|
||||
// async fn process_gemini(url: String) -> Result<ReqResult, VigiError> {
|
||||
// let res = tokio_gemini::Client::default()
|
||||
// .request(&url)
|
||||
// .await
|
||||
// .map_err(|e| {
|
||||
// println!("{:#?}", e);
|
||||
// VigiError::Network
|
||||
// })?;
|
||||
async fn process_gemini(url: String) -> Result<ReqResult, VigiError> {
|
||||
let mut res = insecure_gemini_client::insecure_gemini_client()
|
||||
.request(&url)
|
||||
.await
|
||||
.map_err(|_| VigiError::Network)?;
|
||||
|
||||
// let mime_type = res.mime().map_err(|_| VigiError::InvalidMimeType)?;
|
||||
let mime_type = res.mime().map_err(|_| VigiError::InvalidMimeType)?;
|
||||
|
||||
// Ok((mime_type, res.message().as_bytes().into()))
|
||||
// }
|
||||
let mut buffer = Vec::new();
|
||||
|
||||
let tls_stream = res.body();
|
||||
tls_stream
|
||||
.read_to_end(&mut buffer)
|
||||
.await
|
||||
.map_err(|_| VigiError::Network)?;
|
||||
|
||||
Ok((mime_type, Bytes::from(buffer).into()))
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ pub enum VigiError {
|
|||
UnsupportedMimeType,
|
||||
InvalidMimeType,
|
||||
|
||||
TextIsNotUtf8,
|
||||
InvalidCharset,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
Loading…
Add table
Reference in a new issue