Hotfix for v0.4.8 (#87)

Fixes a regression in v0.4.8 that caused some JSON output to not be
properly escaped, leading it to not correctly display in the browser.
This commit is contained in:
Daniel Sockwell 2020-03-11 13:26:11 -04:00 committed by GitHub
parent ed75905fa3
commit ebe9aeccbc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 30 deletions

View File

@ -18,7 +18,7 @@
use super::receiver::Receiver; use super::receiver::Receiver;
use crate::{config, parse_client_request::user::User}; use crate::{config, parse_client_request::user::User};
use futures::{Async, Poll}; use futures::{Async, Poll};
use serde_json::{json, Value}; use serde_json::Value;
use std::sync; use std::sync;
use tokio::io::Error; use tokio::io::Error;
use uuid::Uuid; use uuid::Uuid;
@ -71,7 +71,7 @@ impl ClientAgent {
/// The stream that the `ClientAgent` manages. `Poll` is the only method implemented. /// The stream that the `ClientAgent` manages. `Poll` is the only method implemented.
impl futures::stream::Stream for ClientAgent { impl futures::stream::Stream for ClientAgent {
type Item = Value; type Item = Toot;
type Error = Error; type Error = Error;
/// Checks for any new messages that should be sent to the client. /// Checks for any new messages that should be sent to the client.
@ -102,17 +102,18 @@ impl futures::stream::Stream for ClientAgent {
let toot = Toot::from_json(value); let toot = Toot::from_json(value);
toot.filter(&user) toot.filter(&user)
} }
Ok(inner_value) => Ok(inner_value), Ok(Async::Ready(None)) => Ok(Async::Ready(None)),
Ok(Async::NotReady) => Ok(Async::NotReady),
Err(e) => Err(e), Err(e) => Err(e),
} }
} }
} }
/// The message to send to the client (which might not literally be a toot in some cases). /// The message to send to the client (which might not literally be a toot in some cases).
struct Toot { pub struct Toot {
category: String, pub category: String,
payload: Value, pub payload: Value,
language: Option<String>, pub language: Option<String>,
} }
impl Toot { impl Toot {
@ -132,29 +133,20 @@ impl Toot {
} }
} }
/// Convert a `Toot` to JSON inside an Option.
fn to_optional_json(&self) -> Option<Value> {
Some(json!(
{"event": self.category,
"payload": self.payload,}
))
}
/// Filter out any `Toot`'s that fail the provided filter. /// Filter out any `Toot`'s that fail the provided filter.
fn filter(&self, user: &User) -> Result<Async<Option<Value>>, Error> { fn filter(self, user: &User) -> Result<Async<Option<Self>>, Error> {
let toot = self; let toot = self;
let (send_msg, skip_msg) = ( let category = toot.category.clone();
Ok(Async::Ready(toot.to_optional_json())), let toot_language = &toot.language.clone().expect("Valid lanugage");
Ok(Async::NotReady), let (send_msg, skip_msg) = (Ok(Async::Ready(Some(toot))), Ok(Async::NotReady));
);
if toot.category == "update" { if category == "update" {
use crate::parse_client_request::user::Filter; use crate::parse_client_request::user::Filter;
let toot_language = &toot.language.clone().expect("Valid lanugage");
match &user.filter { match &user.filter {
Filter::NoFilter => send_msg, Filter::NoFilter => send_msg,
Filter::Notification if toot.category == "notification" => send_msg, Filter::Notification if category == "notification" => send_msg,
// If not, skip it // If not, skip it
Filter::Notification => skip_msg, Filter::Notification => skip_msg,
Filter::Language if user.langs.is_none() => send_msg, Filter::Language if user.langs.is_none() => send_msg,

View File

@ -6,6 +6,7 @@ pub mod redis;
pub use client_agent::ClientAgent; pub use client_agent::ClientAgent;
use futures::{future::Future, stream::Stream, Async}; use futures::{future::Future, stream::Stream, Async};
use log; use log;
use serde_json::json;
use std::time; use std::time;
/// Send a stream of replies to a Server Sent Events client. /// Send a stream of replies to a Server Sent Events client.
@ -16,9 +17,9 @@ pub fn send_updates_to_sse(
) -> impl warp::reply::Reply { ) -> impl warp::reply::Reply {
let event_stream = tokio::timer::Interval::new(time::Instant::now(), update_interval) let event_stream = tokio::timer::Interval::new(time::Instant::now(), update_interval)
.filter_map(move |_| match client_agent.poll() { .filter_map(move |_| match client_agent.poll() {
Ok(Async::Ready(Some(json_value))) => Some(( Ok(Async::Ready(Some(toot))) => Some((
warp::sse::event(json_value["event"].clone().to_string()), warp::sse::event(toot.category),
warp::sse::data(json_value["payload"].clone()), warp::sse::data(toot.payload),
)), )),
_ => None, _ => None,
}); });
@ -89,10 +90,15 @@ pub fn send_updates_to_ws(
// Every time you get an event from that stream, send it through the pipe // Every time you get an event from that stream, send it through the pipe
event_stream event_stream
.for_each(move |_instant| { .for_each(move |_instant| {
if let Ok(Async::Ready(Some(json_value))) = client_agent.poll() { if let Ok(Async::Ready(Some(toot))) = client_agent.poll() {
let toot = json_value["payload"]["content"].clone(); let txt = &toot.payload["content"];
log::warn!("toot: {}\n in TL: {}\nuser: {}({})", toot, tl, email, id); log::warn!("toot: {}\n in TL: {}\nuser: {}({})", txt, tl, email, id);
let msg = warp::ws::Message::text(json_value.to_string());
let msg = warp::ws::Message::text(
json!({"event": toot.category,
"payload": toot.payload.to_string()})
.to_string(),
);
tx.unbounded_send(msg).expect("No send error"); tx.unbounded_send(msg).expect("No send error");
}; };