more work
This commit is contained in:
parent
26ac52e74b
commit
1951ddae5e
4 changed files with 57 additions and 54 deletions
|
@ -11,9 +11,12 @@ omegaupload-common = { path = "../common" }
|
||||||
getrandom = { version = "*", features = ["js"] }
|
getrandom = { version = "*", features = ["js"] }
|
||||||
|
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
|
bytes = "1"
|
||||||
downcast-rs = "1"
|
downcast-rs = "1"
|
||||||
gloo-console = "0.1"
|
gloo-console = "0.1"
|
||||||
http = "0.2"
|
http = "0.2"
|
||||||
|
reqwest = { version = "0.11", default_features = false, features = ["tokio-rustls"] }
|
||||||
web-sys = { version = "0.3", features = ["Request", "Window"] }
|
web-sys = { version = "0.3", features = ["Request", "Window"] }
|
||||||
yew = { version = "0.18", features = ["wasm-bindgen-futures"] }
|
yew = { version = "0.18", features = ["wasm-bindgen-futures"] }
|
||||||
yew-router = "0.15"
|
yew-router = "0.15"
|
||||||
|
yewtil = "0.4"
|
13
web/dist/index.html
vendored
13
web/dist/index.html
vendored
|
@ -1,13 +1,18 @@
|
||||||
<!DOCTYPE html><html><head>
|
<!DOCTYPE html><html><head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Omegaupload</title>
|
<title>Omegaupload</title>
|
||||||
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.3.1/styles/default.min.css">
|
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.3.1/styles/github-dark.min.css">
|
||||||
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.3.1/highlight.min.js"></script>
|
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.3.1/highlight.min.js"></script>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<link rel="preload" href="/index-2ccb59df4818eaff_bg.wasm" as="fetch" type="application/wasm" crossorigin="">
|
<link rel="preload" href="/index-c5eae97b1d11880a_bg.wasm" as="fetch" type="application/wasm" crossorigin="">
|
||||||
<link rel="modulepreload" href="/index-2ccb59df4818eaff.js"></head>
|
<link rel="modulepreload" href="/index-c5eae97b1d11880a.js"></head>
|
||||||
|
|
||||||
<body><script type="module">import init from '/index-2ccb59df4818eaff.js';init('/index-2ccb59df4818eaff_bg.wasm');</script><script>(function () {
|
<body><script type="module">import init from '/index-c5eae97b1d11880a.js';init('/index-c5eae97b1d11880a_bg.wasm');</script><script>(function () {
|
||||||
var url = 'ws://' + window.location.host + '/_trunk/ws';
|
var url = 'ws://' + window.location.host + '/_trunk/ws';
|
||||||
var poll_interval = 5000;
|
var poll_interval = 5000;
|
||||||
var reload_upon_connect = () => {
|
var reload_upon_connect = () => {
|
||||||
|
|
|
@ -4,8 +4,13 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>Omegaupload</title>
|
<title>Omegaupload</title>
|
||||||
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.3.1/styles/default.min.css">
|
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.3.1/styles/github-dark.min.css">
|
||||||
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.3.1/highlight.min.js"></script>
|
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.3.1/highlight.min.js"></script>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
</html>
|
</html>
|
|
@ -1,22 +1,21 @@
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::rc::Rc;
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use anyhow::{anyhow, bail};
|
use anyhow::{anyhow, bail};
|
||||||
|
use bytes::Bytes;
|
||||||
use downcast_rs::{impl_downcast, Downcast};
|
use downcast_rs::{impl_downcast, Downcast};
|
||||||
use gloo_console::log;
|
use http::uri::PathAndQuery;
|
||||||
use http::uri::{Authority, PathAndQuery};
|
use http::{StatusCode, Uri};
|
||||||
use omegaupload_common::crypto::{open, Key, Nonce};
|
use omegaupload_common::crypto::{open, Key, Nonce};
|
||||||
use omegaupload_common::{ParsedUrl, PartialParsedUrl};
|
use omegaupload_common::PartialParsedUrl;
|
||||||
use yew::format::{Binary, Nothing};
|
use yew::format::Nothing;
|
||||||
use yew::services::fetch::{FetchTask, Request, Response, StatusCode, Uri};
|
|
||||||
use yew::services::FetchService;
|
|
||||||
use yew::utils::window;
|
use yew::utils::window;
|
||||||
use yew::Properties;
|
use yew::Properties;
|
||||||
use yew::{html, Component, ComponentLink, Html, ShouldRender};
|
use yew::{html, Component, ComponentLink, Html, ShouldRender};
|
||||||
use yew_router::router::Router;
|
use yew_router::router::Router;
|
||||||
use yew_router::Switch;
|
use yew_router::Switch;
|
||||||
|
use yewtil::future::LinkFuture;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
yew::start_app::<App>();
|
yew::start_app::<App>();
|
||||||
|
@ -71,8 +70,6 @@ fn render_route(route: Route) -> Html {
|
||||||
|
|
||||||
struct Paste {
|
struct Paste {
|
||||||
state: Box<dyn PasteState>,
|
state: Box<dyn PasteState>,
|
||||||
// Need to keep this alive so that the fetch request doesn't get dropped
|
|
||||||
_fetch_handle: Option<FetchTask>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Component for Paste {
|
impl Component for Paste {
|
||||||
|
@ -91,18 +88,22 @@ impl Component for Paste {
|
||||||
};
|
};
|
||||||
|
|
||||||
let link_clone = link.clone();
|
let link_clone = link.clone();
|
||||||
|
link.send_future(async move {
|
||||||
let fetch = FetchService::fetch_binary(
|
match reqwest::get(&request_uri.to_string()).await {
|
||||||
Request::get(&request_uri).body(Nothing).unwrap(),
|
Ok(resp) if resp.status() == StatusCode::OK => {
|
||||||
link.callback_once(move |resp: Response<Binary>| match resp.status() {
|
let partial = match resp.bytes().await {
|
||||||
StatusCode::OK => {
|
Ok(bytes) => PastePartial::new(
|
||||||
let partial = PastePartial::new(
|
bytes,
|
||||||
resp,
|
url.split_once('#')
|
||||||
url.split_once('#')
|
.map(|(_, fragment)| PartialParsedUrl::from(fragment))
|
||||||
.map(|(_, fragment)| PartialParsedUrl::from(fragment))
|
.unwrap_or_default(),
|
||||||
.unwrap_or_default(),
|
link_clone,
|
||||||
link_clone,
|
),
|
||||||
);
|
Err(e) => {
|
||||||
|
return Box::new(PasteError(anyhow!("Got resp error: {}", e)))
|
||||||
|
as Box<dyn PasteState>
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if let Ok(completed) = PasteComplete::try_from(partial.clone()) {
|
if let Ok(completed) = PasteComplete::try_from(partial.clone()) {
|
||||||
Box::new(completed) as Box<dyn PasteState>
|
Box::new(completed) as Box<dyn PasteState>
|
||||||
|
@ -110,22 +111,15 @@ impl Component for Paste {
|
||||||
Box::new(partial) as Box<dyn PasteState>
|
Box::new(partial) as Box<dyn PasteState>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StatusCode::NOT_FOUND => Box::new(PasteNotFound) as Box<dyn PasteState>,
|
Ok(err) => Box::new(PasteError(anyhow!("Got resp error: {}", err.status())))
|
||||||
code => {
|
as Box<dyn PasteState>,
|
||||||
Box::new(PasteError(anyhow!("Got resp error: {}", code))) as Box<dyn PasteState>
|
Err(err) => {
|
||||||
|
Box::new(PasteError(anyhow!("Got resp error: {}", err))) as Box<dyn PasteState>
|
||||||
}
|
}
|
||||||
}),
|
}
|
||||||
);
|
});
|
||||||
|
Self {
|
||||||
match fetch {
|
state: Box::new(PasteLoading),
|
||||||
Ok(task) => Self {
|
|
||||||
state: Box::new(PasteLoading),
|
|
||||||
_fetch_handle: Some(task),
|
|
||||||
},
|
|
||||||
Err(e) => Self {
|
|
||||||
state: Box::new(PasteError(e)) as Box<dyn PasteState>,
|
|
||||||
_fetch_handle: None,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,7 +173,7 @@ struct PasteError(anyhow::Error);
|
||||||
#[derive(Properties, Clone, Debug)]
|
#[derive(Properties, Clone, Debug)]
|
||||||
struct PastePartial {
|
struct PastePartial {
|
||||||
parent: ComponentLink<Paste>,
|
parent: ComponentLink<Paste>,
|
||||||
data: Option<Rc<Vec<u8>>>,
|
data: Option<Bytes>,
|
||||||
key: Option<Key>,
|
key: Option<Key>,
|
||||||
nonce: Option<Nonce>,
|
nonce: Option<Nonce>,
|
||||||
password: Option<Key>,
|
password: Option<Key>,
|
||||||
|
@ -188,7 +182,7 @@ struct PastePartial {
|
||||||
|
|
||||||
#[derive(Properties, Clone)]
|
#[derive(Properties, Clone)]
|
||||||
struct PasteComplete {
|
struct PasteComplete {
|
||||||
data: Rc<Vec<u8>>,
|
data: Bytes,
|
||||||
key: Key,
|
key: Key,
|
||||||
nonce: Nonce,
|
nonce: Nonce,
|
||||||
password: Option<Key>,
|
password: Option<Key>,
|
||||||
|
@ -204,13 +198,13 @@ impl PasteState for PasteComplete {}
|
||||||
|
|
||||||
impl PastePartial {
|
impl PastePartial {
|
||||||
fn new(
|
fn new(
|
||||||
resp: Response<Binary>,
|
resp: Bytes,
|
||||||
partial_parsed_url: PartialParsedUrl,
|
partial_parsed_url: PartialParsedUrl,
|
||||||
parent: ComponentLink<Paste>,
|
parent: ComponentLink<Paste>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
parent,
|
parent,
|
||||||
data: Some(Rc::new(resp.into_body().unwrap())),
|
data: Some(resp),
|
||||||
key: partial_parsed_url.decryption_key,
|
key: partial_parsed_url.decryption_key,
|
||||||
nonce: partial_parsed_url.nonce,
|
nonce: partial_parsed_url.nonce,
|
||||||
password: None,
|
password: None,
|
||||||
|
@ -244,17 +238,13 @@ impl Component for PastePartial {
|
||||||
match (self.data.clone(), self.key, self.nonce, self.password) {
|
match (self.data.clone(), self.key, self.nonce, self.password) {
|
||||||
(Some(data), Some(key), Some(nonce), Some(password)) if self.needs_pw => {
|
(Some(data), Some(key), Some(nonce), Some(password)) if self.needs_pw => {
|
||||||
self.parent.callback(move |Nothing| {
|
self.parent.callback(move |Nothing| {
|
||||||
Box::new(PasteComplete::new(
|
Box::new(PasteComplete::new(data.clone(), key, nonce, Some(password)))
|
||||||
Rc::clone(&data),
|
as Box<dyn PasteState>
|
||||||
key,
|
|
||||||
nonce,
|
|
||||||
Some(password),
|
|
||||||
)) as Box<dyn PasteState>
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
(Some(data), Some(key), Some(nonce), None) if !self.needs_pw => {
|
(Some(data), Some(key), Some(nonce), None) if !self.needs_pw => {
|
||||||
self.parent.callback(move |Nothing| {
|
self.parent.callback(move |Nothing| {
|
||||||
Box::new(PasteComplete::new(Rc::clone(&data), key, nonce, None))
|
Box::new(PasteComplete::new(data.clone(), key, nonce, None))
|
||||||
as Box<dyn PasteState>
|
as Box<dyn PasteState>
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -312,7 +302,7 @@ impl TryFrom<PastePartial> for PasteComplete {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PasteComplete {
|
impl PasteComplete {
|
||||||
fn new(data: Rc<Vec<u8>>, key: Key, nonce: Nonce, password: Option<Key>) -> Self {
|
fn new(data: Bytes, key: Key, nonce: Nonce, password: Option<Key>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
data,
|
data,
|
||||||
key,
|
key,
|
||||||
|
|
Loading…
Reference in a new issue