time out a stalled frame body and drop the dead serde defaults
a peer that sends a length then stalls is cut after 30s; idle pooled connections waiting for the next request are left alone. the serde defaults were no-ops under a positional binary format.
This commit is contained in:
parent
5c35bef330
commit
0f563891c5
4 changed files with 9 additions and 13 deletions
|
|
@ -3,25 +3,15 @@ use crate::game::AccountRef;
|
|||
use serde::{Deserialize, Serialize};
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct DeviceInfo {
|
||||
#[serde(default)]
|
||||
pub udid: Option<String>,
|
||||
#[serde(default)]
|
||||
pub open_udid: Option<String>,
|
||||
#[serde(default)]
|
||||
pub device: Option<String>,
|
||||
#[serde(default)]
|
||||
pub os_version: Option<String>,
|
||||
#[serde(default)]
|
||||
pub android: bool,
|
||||
#[serde(default)]
|
||||
pub preferred_language: String,
|
||||
#[serde(default)]
|
||||
pub client_major_version: i32,
|
||||
#[serde(default)]
|
||||
pub client_minor_version: i32,
|
||||
#[serde(default)]
|
||||
pub client_build: i32,
|
||||
#[serde(default)]
|
||||
pub resource_sha: Option<String>,
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ pub enum RpcError {
|
|||
FrameTooLarge { actual: usize, limit: usize },
|
||||
#[error("peer closed the connection")]
|
||||
Closed,
|
||||
#[error("peer stalled mid-frame")]
|
||||
Timeout,
|
||||
#[error("service rejected the call: {0}")]
|
||||
Rejected(String),
|
||||
#[error("service is unavailable: {0}")]
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@ use crate::error::{RpcError, RpcResult, WireError};
|
|||
use serde::{de::DeserializeOwned, Serialize};
|
||||
use std::sync::Arc;
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
use tokio::time::{timeout, Duration};
|
||||
use tokio::net::{TcpListener, TcpStream};
|
||||
pub const MAX_FRAME_LEN: usize = 8 * 1024 * 1024;
|
||||
pub const BODY_READ_TIMEOUT: Duration = Duration::from_secs(30);
|
||||
#[async_trait::async_trait]
|
||||
pub trait RpcService: Send + Sync + 'static {
|
||||
type Request: DeserializeOwned + Send;
|
||||
|
|
@ -56,8 +58,11 @@ pub async fn read_frame(stream: &mut TcpStream) -> RpcResult<Vec<u8>> {
|
|||
});
|
||||
}
|
||||
let mut payload = vec![0u8; length];
|
||||
stream.read_exact(&mut payload).await?;
|
||||
Ok(payload)
|
||||
match timeout(BODY_READ_TIMEOUT, stream.read_exact(&mut payload)).await {
|
||||
Ok(Ok(_)) => Ok(payload),
|
||||
Ok(Err(error)) => Err(error.into()),
|
||||
Err(_) => Err(RpcError::Timeout),
|
||||
}
|
||||
}
|
||||
pub async fn write_frame(stream: &mut TcpStream, payload: &[u8]) -> RpcResult<()> {
|
||||
if payload.len() > MAX_FRAME_LEN {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ use serde::{Deserialize, Serialize};
|
|||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct WireMessage {
|
||||
pub message_type: u16,
|
||||
#[serde(default)]
|
||||
pub message_version: u16,
|
||||
pub payload: Vec<u8>,
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue