#![allow(deprecated)]
use std::time::Duration;
const DEFAULT_MAX_DECODING_MESSAGE_SIZE: usize = 4 * 1024 * 1024;
const DEFAULT_MAX_ENCODING_MESSAGE_SIZE: usize = 4 * 1024 * 1024;
const DEFAULT_REQUEST_TIMEOUT: Duration = Duration::from_secs(30);
const DEFAULT_MAX_CONCURRENT_CONNECTIONS: usize = 1000;
#[deprecated(
since = "0.2.0",
note = "Use `GrpcServerSettings` with the `#[settings]` macro instead."
)]
#[derive(Debug, Clone)]
pub struct GrpcServerConfig {
max_decoding_message_size: usize,
max_encoding_message_size: usize,
request_timeout: Duration,
max_concurrent_connections: usize,
}
impl GrpcServerConfig {
pub fn builder() -> GrpcServerConfigBuilder {
GrpcServerConfigBuilder::default()
}
pub fn max_decoding_message_size(&self) -> usize {
self.max_decoding_message_size
}
pub fn max_encoding_message_size(&self) -> usize {
self.max_encoding_message_size
}
pub fn max_message_size(&self) -> usize {
self.max_decoding_message_size
}
pub fn request_timeout(&self) -> Duration {
self.request_timeout
}
pub fn max_concurrent_connections(&self) -> usize {
self.max_concurrent_connections
}
}
impl Default for GrpcServerConfig {
fn default() -> Self {
Self {
max_decoding_message_size: DEFAULT_MAX_DECODING_MESSAGE_SIZE,
max_encoding_message_size: DEFAULT_MAX_ENCODING_MESSAGE_SIZE,
request_timeout: DEFAULT_REQUEST_TIMEOUT,
max_concurrent_connections: DEFAULT_MAX_CONCURRENT_CONNECTIONS,
}
}
}
#[derive(Debug, Clone)]
pub struct GrpcServerConfigBuilder {
max_decoding_message_size: usize,
max_encoding_message_size: usize,
request_timeout: Duration,
max_concurrent_connections: usize,
}
impl GrpcServerConfigBuilder {
pub fn max_decoding_message_size(mut self, size: usize) -> Self {
self.max_decoding_message_size = size;
self
}
pub fn max_encoding_message_size(mut self, size: usize) -> Self {
self.max_encoding_message_size = size;
self
}
pub fn max_message_size(mut self, size: usize) -> Self {
self.max_decoding_message_size = size;
self.max_encoding_message_size = size;
self
}
pub fn request_timeout(mut self, timeout: Duration) -> Self {
self.request_timeout = timeout;
self
}
pub fn max_concurrent_connections(mut self, max: usize) -> Self {
self.max_concurrent_connections = max;
self
}
pub fn build(self) -> GrpcServerConfig {
GrpcServerConfig {
max_decoding_message_size: self.max_decoding_message_size,
max_encoding_message_size: self.max_encoding_message_size,
request_timeout: self.request_timeout,
max_concurrent_connections: self.max_concurrent_connections,
}
}
}
impl Default for GrpcServerConfigBuilder {
fn default() -> Self {
Self {
max_decoding_message_size: DEFAULT_MAX_DECODING_MESSAGE_SIZE,
max_encoding_message_size: DEFAULT_MAX_ENCODING_MESSAGE_SIZE,
request_timeout: DEFAULT_REQUEST_TIMEOUT,
max_concurrent_connections: DEFAULT_MAX_CONCURRENT_CONNECTIONS,
}
}
}
pub trait MessageSizeLimiter: Sized {
fn apply_message_size_limits(self, config: &GrpcServerConfig) -> Self;
}
#[cfg(test)]
mod tests {
use super::*;
use rstest::rstest;
#[rstest]
fn default_config_has_4mb_limits() {
let expected_size = 4 * 1024 * 1024;
let config = GrpcServerConfig::default();
assert_eq!(config.max_decoding_message_size(), expected_size);
assert_eq!(config.max_encoding_message_size(), expected_size);
}
#[rstest]
fn default_config_has_30s_request_timeout() {
let config = GrpcServerConfig::default();
assert_eq!(config.request_timeout(), Duration::from_secs(30));
}
#[rstest]
fn default_config_has_1000_max_connections() {
let config = GrpcServerConfig::default();
assert_eq!(config.max_concurrent_connections(), 1000);
}
#[rstest]
fn max_message_size_returns_decoding_size() {
let config = GrpcServerConfig::builder()
.max_decoding_message_size(2 * 1024 * 1024)
.build();
assert_eq!(config.max_message_size(), 2 * 1024 * 1024);
assert_eq!(
config.max_message_size(),
config.max_decoding_message_size()
);
}
#[rstest]
fn builder_default_matches_default_config() {
let default_config = GrpcServerConfig::default();
let builder_config = GrpcServerConfig::builder().build();
assert_eq!(
builder_config.max_decoding_message_size(),
default_config.max_decoding_message_size()
);
assert_eq!(
builder_config.max_encoding_message_size(),
default_config.max_encoding_message_size()
);
assert_eq!(
builder_config.request_timeout(),
default_config.request_timeout()
);
assert_eq!(
builder_config.max_concurrent_connections(),
default_config.max_concurrent_connections()
);
}
#[rstest]
fn builder_sets_custom_decoding_limit() {
let custom_size = 8 * 1024 * 1024;
let config = GrpcServerConfig::builder()
.max_decoding_message_size(custom_size)
.build();
assert_eq!(config.max_decoding_message_size(), custom_size);
assert_eq!(
config.max_encoding_message_size(),
DEFAULT_MAX_ENCODING_MESSAGE_SIZE
);
}
#[rstest]
fn builder_sets_custom_encoding_limit() {
let custom_size = 16 * 1024 * 1024;
let config = GrpcServerConfig::builder()
.max_encoding_message_size(custom_size)
.build();
assert_eq!(
config.max_decoding_message_size(),
DEFAULT_MAX_DECODING_MESSAGE_SIZE
);
assert_eq!(config.max_encoding_message_size(), custom_size);
}
#[rstest]
fn builder_sets_both_limits() {
let decoding_size = 2 * 1024 * 1024; let encoding_size = 8 * 1024 * 1024;
let config = GrpcServerConfig::builder()
.max_decoding_message_size(decoding_size)
.max_encoding_message_size(encoding_size)
.build();
assert_eq!(config.max_decoding_message_size(), decoding_size);
assert_eq!(config.max_encoding_message_size(), encoding_size);
}
#[rstest]
fn builder_sets_max_message_size_for_both() {
let size = 2 * 1024 * 1024;
let config = GrpcServerConfig::builder().max_message_size(size).build();
assert_eq!(config.max_decoding_message_size(), size);
assert_eq!(config.max_encoding_message_size(), size);
}
#[rstest]
fn builder_sets_custom_request_timeout() {
let config = GrpcServerConfig::builder()
.request_timeout(Duration::from_secs(60))
.build();
assert_eq!(config.request_timeout(), Duration::from_secs(60));
}
#[rstest]
fn builder_sets_custom_max_concurrent_connections() {
let config = GrpcServerConfig::builder()
.max_concurrent_connections(500)
.build();
assert_eq!(config.max_concurrent_connections(), 500);
}
#[rstest]
fn builder_sets_all_custom_values() {
let decoding = 2 * 1024 * 1024;
let encoding = 8 * 1024 * 1024;
let timeout = Duration::from_secs(60);
let max_conns = 500;
let config = GrpcServerConfig::builder()
.max_decoding_message_size(decoding)
.max_encoding_message_size(encoding)
.request_timeout(timeout)
.max_concurrent_connections(max_conns)
.build();
assert_eq!(config.max_decoding_message_size(), decoding);
assert_eq!(config.max_encoding_message_size(), encoding);
assert_eq!(config.request_timeout(), timeout);
assert_eq!(config.max_concurrent_connections(), max_conns);
}
#[rstest]
fn config_clone_preserves_values() {
let config = GrpcServerConfig::builder()
.max_decoding_message_size(1024)
.max_encoding_message_size(2048)
.request_timeout(Duration::from_secs(45))
.max_concurrent_connections(200)
.build();
let cloned = config.clone();
assert_eq!(
cloned.max_decoding_message_size(),
config.max_decoding_message_size()
);
assert_eq!(
cloned.max_encoding_message_size(),
config.max_encoding_message_size()
);
assert_eq!(cloned.request_timeout(), config.request_timeout());
assert_eq!(
cloned.max_concurrent_connections(),
config.max_concurrent_connections()
);
}
#[rstest]
fn builder_allows_zero_size() {
let config = GrpcServerConfig::builder()
.max_decoding_message_size(0)
.max_encoding_message_size(0)
.build();
assert_eq!(config.max_decoding_message_size(), 0);
assert_eq!(config.max_encoding_message_size(), 0);
}
struct MockService {
max_decoding: Option<usize>,
max_encoding: Option<usize>,
}
impl MockService {
fn new() -> Self {
Self {
max_decoding: None,
max_encoding: None,
}
}
}
impl MessageSizeLimiter for MockService {
fn apply_message_size_limits(mut self, config: &GrpcServerConfig) -> Self {
self.max_decoding = Some(config.max_decoding_message_size());
self.max_encoding = Some(config.max_encoding_message_size());
self
}
}
#[rstest]
fn message_size_limiter_applies_config() {
let config = GrpcServerConfig::builder()
.max_decoding_message_size(1024 * 1024)
.max_encoding_message_size(2 * 1024 * 1024)
.build();
let service = MockService::new();
let service = service.apply_message_size_limits(&config);
assert_eq!(service.max_decoding, Some(1024 * 1024));
assert_eq!(service.max_encoding, Some(2 * 1024 * 1024));
}
#[rstest]
fn message_size_limiter_applies_defaults() {
let config = GrpcServerConfig::default();
let service = MockService::new();
let service = service.apply_message_size_limits(&config);
assert_eq!(
service.max_decoding,
Some(DEFAULT_MAX_DECODING_MESSAGE_SIZE)
);
assert_eq!(
service.max_encoding,
Some(DEFAULT_MAX_ENCODING_MESSAGE_SIZE)
);
}
}