WIP: Make the MMM parser run in linear time #14
|
@ -2028,6 +2028,7 @@ dependencies = [
|
|||
"miette 7.2.0",
|
||||
"percent-encoding",
|
||||
"quick-xml",
|
||||
"rand",
|
||||
"reqwest",
|
||||
"rsa",
|
||||
"serde",
|
||||
|
|
|
@ -62,6 +62,7 @@ quick-xml = "0.36"
|
|||
redis = "0.26"
|
||||
regex = "1.9"
|
||||
rmp-serde = "1.3"
|
||||
rand = "0.8"
|
||||
rsa = "0.9"
|
||||
reqwest = "0.12"
|
||||
sea-orm = "1"
|
||||
|
|
|
@ -40,6 +40,7 @@ hyper = { workspace = true, features = ["full"] }
|
|||
percent-encoding = { workspace = true }
|
||||
reqwest = { workspace = true, features = ["stream", "hickory-dns"] }
|
||||
|
||||
rand = { workspace = true }
|
||||
ed25519-dalek = { workspace = true, features = [
|
||||
"pem",
|
||||
"pkcs8",
|
||||
|
|
|
@ -4,6 +4,7 @@ use http::{HeaderMap, HeaderName, HeaderValue, Method};
|
|||
use indexmap::IndexSet;
|
||||
use serde_json::Value;
|
||||
use sha2::Digest;
|
||||
use std::fmt::Write;
|
||||
use std::{fmt::Display, string::FromUtf8Error, sync::Arc};
|
||||
use thiserror::Error;
|
||||
use tokio::task;
|
||||
|
@ -257,16 +258,17 @@ impl ApClientService for ApClientServiceDefaultProvider {
|
|||
|
||||
let message = components
|
||||
.iter()
|
||||
.map(|(k, v)| format!("{}: {}", k.as_ref(), v))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
.fold(String::new(), |mut acc, (k, v)| {
|
||||
writeln!(&mut acc, "{}: {}", k.as_ref(), v).unwrap();
|
||||
acc
|
||||
});
|
||||
|
||||
let key_id = signing_key.key_id.clone().into_owned();
|
||||
let key = signing_key.into_owned();
|
||||
let signature = task::spawn_blocking(move || {
|
||||
key
|
||||
.key
|
||||
.sign_base64(signing_algorithm, &message.into_bytes())
|
||||
.sign_base64(signing_algorithm, message.trim_end().as_bytes())
|
||||
}).await??;
|
||||
|
||||
Ok(ApSignature {
|
||||
|
@ -329,7 +331,7 @@ impl ApClientService for ApClientServiceDefaultProvider {
|
|||
}
|
||||
|
||||
headers.insert(
|
||||
HeaderName::from_lowercase(b"signature").unwrap(),
|
||||
HeaderName::from_static("signature"),
|
||||
HeaderValue::try_from(signed.to_string())?,
|
||||
);
|
||||
|
||||
|
@ -350,10 +352,9 @@ impl ApClientService for ApClientServiceDefaultProvider {
|
|||
signing_algorithm: SigningAlgorithm,
|
||||
expires: Option<chrono::DateTime<Utc>>,
|
||||
url: &str,
|
||||
body: &Value,
|
||||
body_bytes: Vec<u8>,
|
||||
) -> Result<String, Self::Error> {
|
||||
let url = url.parse()?;
|
||||
let body_bytes = serde_json::to_vec(body)?;
|
||||
// Move in, move out :3
|
||||
let (digest_raw, body_bytes) = task::spawn_blocking(move || {
|
||||
let mut sha = sha2::Sha256::new();
|
||||
|
@ -406,12 +407,12 @@ impl ApClientService for ApClientServiceDefaultProvider {
|
|||
}
|
||||
|
||||
headers.insert(
|
||||
HeaderName::from_lowercase(b"digest").unwrap(),
|
||||
HeaderName::from_static("digest"),
|
||||
HeaderValue::try_from(digest_base64)?,
|
||||
);
|
||||
|
||||
headers.insert(
|
||||
HeaderName::from_lowercase(b"signature").unwrap(),
|
||||
HeaderName::from_static("signature"),
|
||||
HeaderValue::try_from(signed.to_string())?,
|
||||
);
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ use rsa::pkcs1::DecodeRsaPrivateKey;
|
|||
use rsa::pkcs1::DecodeRsaPublicKey;
|
||||
use rsa::pkcs8::DecodePrivateKey;
|
||||
use rsa::pkcs8::DecodePublicKey;
|
||||
use rsa::signature::Verifier;
|
||||
use rsa::signature::{RandomizedSigner, Verifier};
|
||||
use rsa::{
|
||||
sha2::{Sha256, Sha512},
|
||||
signature::Signer,
|
||||
|
@ -268,10 +268,10 @@ impl ApHttpSigningKey<'_> {
|
|||
) -> Result<Vec<u8>, ApSigningError> {
|
||||
match (self, algorithm) {
|
||||
(Self::RsaSha256(key), SigningAlgorithm::RsaSha256 | SigningAlgorithm::Hs2019) => {
|
||||
Ok(Box::<[u8]>::from(key.sign(message)).into_vec())
|
||||
Ok(Box::<[u8]>::from(key.sign_with_rng(&mut rand::thread_rng(), message)).into_vec())
|
||||
}
|
||||
(Self::RsaSha512(key), SigningAlgorithm::Hs2019) => {
|
||||
Ok(Box::<[u8]>::from(key.sign(message)).into_vec())
|
||||
Ok(Box::<[u8]>::from(key.sign_with_rng(&mut rand::thread_rng(), message)).into_vec())
|
||||
}
|
||||
(Self::Ed25519(key), SigningAlgorithm::Hs2019) => {
|
||||
Ok(key.sign(message).to_bytes().to_vec())
|
||||
|
|
|
@ -171,6 +171,6 @@ pub trait ApClientService: Send + Sync {
|
|||
signing_algorithm: SigningAlgorithm,
|
||||
expires: Option<chrono::DateTime<Utc>>,
|
||||
url: &str,
|
||||
body: &Value,
|
||||
body: Vec<u8>,
|
||||
) -> Result<String, Self::Error>;
|
||||
}
|
||||
|
|
|
@ -74,10 +74,10 @@ const showTicker =
|
|||
display: flex;
|
||||
align-items: center;
|
||||
white-space: nowrap;
|
||||
justify-self: flex-end;
|
||||
border-radius: 100px;
|
||||
font-size: 0.8em;
|
||||
text-shadow: 0 2px 2px var(--shadow);
|
||||
gap: 0 0.1em;
|
||||
|
||||
> .avatar {
|
||||
width: 3.7em;
|
||||
|
@ -99,6 +99,8 @@ const showTicker =
|
|||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
gap: 0.1em 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
|
@ -151,7 +153,6 @@ const showTicker =
|
|||
margin: 0 0.5em 0 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
align-self: flex-start;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
v-tooltip="
|
||||
capitalize(
|
||||
magTransProperty(instance, 'software_name', 'softwareName') ??
|
||||
'?',
|
||||
'?'
|
||||
)
|
||||
"
|
||||
ref="ticker"
|
||||
|
@ -40,7 +40,7 @@ const instance = props.instance ?? {
|
|||
name: instanceName,
|
||||
themeColor: (
|
||||
document.querySelector(
|
||||
'meta[name="theme-color-orig"]',
|
||||
'meta[name="theme-color-orig"]'
|
||||
) as HTMLMetaElement
|
||||
)?.content,
|
||||
softwareName: (Instance.softwareName || "Magnetar") as string | null,
|
||||
|
@ -61,18 +61,18 @@ const bg = {
|
|||
};
|
||||
|
||||
function getInstanceIcon(
|
||||
instance?: Misskey.entities.User["instance"] | types.InstanceTicker | null,
|
||||
instance?: Misskey.entities.User["instance"] | types.InstanceTicker | null
|
||||
): string {
|
||||
if (!instance) return "/client-assets/dummy.png";
|
||||
|
||||
return (
|
||||
getProxiedImageUrlNullable(
|
||||
magTransProperty(instance, "icon_url", "iconUrl"),
|
||||
"preview",
|
||||
"preview"
|
||||
) ??
|
||||
getProxiedImageUrlNullable(
|
||||
magTransProperty(instance, "favicon_url", "faviconUrl"),
|
||||
"preview",
|
||||
"preview"
|
||||
) ??
|
||||
"/client-assets/dummy.png"
|
||||
);
|
||||
|
@ -90,6 +90,7 @@ function getInstanceIcon(
|
|||
font-size: 0.8em;
|
||||
text-shadow: 0 2px 2px var(--shadow);
|
||||
overflow: hidden;
|
||||
|
||||
.header > .body & {
|
||||
width: max-content;
|
||||
max-width: 100%;
|
||||
|
@ -108,11 +109,9 @@ function getInstanceIcon(
|
|||
font-weight: bold;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
text-shadow:
|
||||
-1px -1px 0 var(--bg),
|
||||
1px -1px 0 var(--bg),
|
||||
-1px 1px 0 var(--bg),
|
||||
1px 1px 0 var(--bg);
|
||||
text-shadow: -1px -1px 0 var(--bg), 1px -1px 0 var(--bg),
|
||||
-1px 1px 0 var(--bg), 1px 1px 0 var(--bg);
|
||||
|
||||
.article > .main &,
|
||||
.header > .body & {
|
||||
display: unset;
|
||||
|
|
|
@ -23,7 +23,7 @@ struct RpcApGet {
|
|||
struct RpcApPost {
|
||||
user_id: String,
|
||||
url: String,
|
||||
body: serde_json::Value,
|
||||
body: String,
|
||||
}
|
||||
|
||||
pub fn create_rpc_router() -> MagRpc {
|
||||
|
@ -90,7 +90,7 @@ pub fn create_rpc_router() -> MagRpc {
|
|||
.create_signing_key(&key_id, SigningAlgorithm::RsaSha256)?;
|
||||
let result = service
|
||||
.ap_client
|
||||
.signed_post(signing_key, SigningAlgorithm::RsaSha256, None, &url, &body)
|
||||
.signed_post(signing_key, SigningAlgorithm::RsaSha256, None, &url, body.into_bytes())
|
||||
.await?;
|
||||
Result::<_, DeliveryError>::Ok(result)
|
||||
},
|
||||
|
|
|
@ -12,7 +12,7 @@ use std::net::SocketAddr;
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::pin::Pin;
|
||||
use std::sync::Arc;
|
||||
use tokio::io::{AsyncRead, AsyncReadExt, AsyncWriteExt, BufReader};
|
||||
use tokio::io::{AsyncRead, AsyncReadExt, AsyncWriteExt, BufReader, BufWriter};
|
||||
use tokio::net::{TcpListener, UnixSocket};
|
||||
use tokio::select;
|
||||
use tokio::task::JoinSet;
|
||||
|
@ -223,15 +223,16 @@ impl MagRpc {
|
|||
debug!("RPC TCP connection accepted: {:?}", remote_addr);
|
||||
|
||||
let (cancel_send, cancel_recv) = tokio::sync::oneshot::channel::<()>();
|
||||
let (read_half, mut write_half) = stream.into_split();
|
||||
let (read_half, write_half) = stream.into_split();
|
||||
let buf_read = BufReader::new(read_half);
|
||||
let mut buf_write = BufWriter::new(write_half);
|
||||
let context = context.clone();
|
||||
let rx_dec = rx_dec.clone();
|
||||
let fut = async move {
|
||||
let src = rx_dec
|
||||
.stream_decode(buf_read, cancel_recv)
|
||||
.map_ok(process(context))
|
||||
.try_buffer_unordered(100)
|
||||
.try_buffer_unordered(400)
|
||||
.boxed();
|
||||
|
||||
futures::pin_mut!(src);
|
||||
|
@ -241,14 +242,14 @@ impl MagRpc {
|
|||
continue;
|
||||
};
|
||||
|
||||
write_half.write_u8(b'M').await.into_diagnostic()?;
|
||||
write_half.write_u64(serial).await.into_diagnostic()?;
|
||||
write_half
|
||||
buf_write.write_u8(b'M').await.into_diagnostic()?;
|
||||
buf_write.write_u64(serial).await.into_diagnostic()?;
|
||||
buf_write
|
||||
.write_u32(bytes.len() as u32)
|
||||
.await
|
||||
.into_diagnostic()?;
|
||||
write_half.write_all(&bytes).await.into_diagnostic()?;
|
||||
write_half.flush().await.into_diagnostic()?;
|
||||
buf_write.write_all(&bytes).await.into_diagnostic()?;
|
||||
buf_write.flush().await.into_diagnostic()?;
|
||||
}
|
||||
|
||||
Ok(remote_addr)
|
||||
|
@ -313,15 +314,16 @@ impl MagRpc {
|
|||
debug!("RPC Unix connection accepted: {:?}", remote_addr);
|
||||
|
||||
let (cancel_send, cancel_recv) = tokio::sync::oneshot::channel::<()>();
|
||||
let (read_half, mut write_half) = stream.into_split();
|
||||
let (read_half, write_half) = stream.into_split();
|
||||
let buf_read = BufReader::new(read_half);
|
||||
let mut buf_write = BufWriter::new(write_half);
|
||||
let context = context.clone();
|
||||
let rx_dec = rx_dec.clone();
|
||||
let fut = async move {
|
||||
let src = rx_dec
|
||||
.stream_decode(buf_read, cancel_recv)
|
||||
.map_ok(process(context))
|
||||
.try_buffer_unordered(100)
|
||||
.try_buffer_unordered(400)
|
||||
.boxed();
|
||||
|
||||
futures::pin_mut!(src);
|
||||
|
@ -331,14 +333,14 @@ impl MagRpc {
|
|||
continue;
|
||||
};
|
||||
|
||||
write_half.write_u8(b'M').await.into_diagnostic()?;
|
||||
write_half.write_u64(serial).await.into_diagnostic()?;
|
||||
write_half
|
||||
buf_write.write_u8(b'M').await.into_diagnostic()?;
|
||||
buf_write.write_u64(serial).await.into_diagnostic()?;
|
||||
buf_write
|
||||
.write_u32(bytes.len() as u32)
|
||||
.await
|
||||
.into_diagnostic()?;
|
||||
write_half.write_all(&bytes).await.into_diagnostic()?;
|
||||
write_half.flush().await.into_diagnostic()?;
|
||||
buf_write.write_all(&bytes).await.into_diagnostic()?;
|
||||
buf_write.flush().await.into_diagnostic()?;
|
||||
}
|
||||
|
||||
miette::Result::<()>::Ok(())
|
||||
|
|
Loading…
Reference in New Issue