Respond to REQ errors properly with CLOSED

This commit is contained in:
Mike Dilger 2024-02-21 09:30:10 +13:00
parent 3abe43a771
commit 9b2d6365f0
3 changed files with 37 additions and 16 deletions

View File

@ -17,7 +17,7 @@ FriendlyConfig(
// This is a bad idea in production, but useful for testing or for dumping
// your entire relay
allow_scraping: true,
allow_scraping: false,
max_subscriptions: 32,
serve_ephemeral: true,
serve_relay_lists: true,

View File

@ -115,6 +115,9 @@ pub enum ChorusError {
// Too many errors
TooManyErrors,
// Too many subscriptions
TooManySubscriptions,
// URL Parse
UrlParse(url::ParseError),
@ -174,6 +177,7 @@ impl std::fmt::Display for ChorusError {
ChorusError::Tungstenite(e) => write!(f, "{e}"),
ChorusError::Scraper => write!(f, "Filter is underspecified. Scrapers are not allowed"),
ChorusError::TooManyErrors => write!(f, "Too many errors"),
ChorusError::TooManySubscriptions => write!(f, "Too many subscriptions"),
ChorusError::UrlParse(e) => write!(f, "{e}"),
ChorusError::Utf8(e) => write!(f, "{e}"),
ChorusError::Utf8Error => write!(f, "UTF-8 error"),

View File

@ -60,19 +60,6 @@ impl WebSocketService {
outpos += outlen;
verify_char(input, b'"', &mut inpos)?; // FIXME: json_unescape should eat the closing quote
let max_subscriptions = GLOBALS.config.get().unwrap().max_subscriptions;
if self.subscriptions.len() >= max_subscriptions {
let reply = NostrReply::Closed(
&subid,
NostrReplyPrefix::RateLimited,
format!(
"No more than {max_subscriptions} subscriptions are allowed at any one time"
),
);
self.websocket.send(Message::text(reply.as_json())).await?;
return Ok(());
}
// Read the filter into the session buffer
let mut filters: Vec<OwnedFilter> = Vec::new();
loop {
@ -91,6 +78,36 @@ impl WebSocketService {
filters.push(OwnedFilter(filterbytes));
}
if let Err(e) = self.req_inner(&subid, filters).await {
let reply = match e.inner {
ChorusError::TooManySubscriptions => {
let max_subscriptions = GLOBALS.config.get().unwrap().max_subscriptions;
NostrReply::Closed(
&subid,
NostrReplyPrefix::Blocked,
format!(
"No more than {max_subscriptions} subscriptions are allowed at any one time"
),
)
}
ChorusError::Scraper => {
NostrReply::Closed(&subid, NostrReplyPrefix::Invalid, format!("{e}"))
}
_ => NostrReply::Closed(&subid, NostrReplyPrefix::Error, format!("{e}")),
};
self.websocket.send(Message::text(reply.as_json())).await?;
}
Ok(())
}
async fn req_inner(&mut self, subid: &String, filters: Vec<OwnedFilter>) -> Result<(), Error> {
let max_subscriptions = GLOBALS.config.get().unwrap().max_subscriptions;
if self.subscriptions.len() >= max_subscriptions {
return Err(ChorusError::TooManySubscriptions.into());
}
let user = self.user;
let authorized_user = authorized_user(&user).await;
@ -126,12 +143,12 @@ impl WebSocketService {
events.dedup();
for event in events.drain(..) {
let reply = NostrReply::Event(&subid, event);
let reply = NostrReply::Event(subid, event);
self.websocket.send(Message::text(reply.as_json())).await?;
}
// eose
let reply = NostrReply::Eose(&subid);
let reply = NostrReply::Eose(subid);
self.websocket.send(Message::text(reply.as_json())).await?;
}