mirror of
https://github.com/mailscope/kumomta.git
synced 2026-08-25 05:38:18 +00:00
http inject: add integration test for request_body_limit
This commit doesn't change any behavior, it just adds an explicit test for exceeding request_body_limit, and expands on the docs for request_body_limit to clarify the response when the limit is exceeded.
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
use crate::kumod::{DaemonWithMaildir, MailGenParams};
|
||||
use anyhow::Context;
|
||||
use k9::assert_equal;
|
||||
|
||||
/// Asserts that request_body_limit is effective and has a
|
||||
/// known response
|
||||
#[tokio::test]
|
||||
async fn http_inject_size_limit() -> anyhow::Result<()> {
|
||||
let mut daemon = DaemonWithMaildir::start()
|
||||
.await
|
||||
.context("DaemonWithMaildir::start")?;
|
||||
|
||||
let content = MailGenParams {
|
||||
// Ask for 2MB of mail body. The overall request
|
||||
// size will therefore be > 2MB, which is the
|
||||
// default value of `request_body_limit` set
|
||||
// in the http listener.
|
||||
size: Some(2 * 1024 * 1024),
|
||||
..Default::default()
|
||||
}
|
||||
.generate()?;
|
||||
|
||||
let payload = serde_json::json!({
|
||||
"envelope_sender": "sender@example.com",
|
||||
"recipients": [
|
||||
{
|
||||
"email": "user@example.com",
|
||||
"name": "Test User"
|
||||
}
|
||||
],
|
||||
"content": content,
|
||||
});
|
||||
|
||||
let json_data = serde_json::to_vec(&payload)?;
|
||||
|
||||
let client = reqwest::Client::new();
|
||||
let response = client
|
||||
.post(&format!(
|
||||
"http://{}/api/inject/v1",
|
||||
daemon.source.listener("http")
|
||||
))
|
||||
.header("Content-Type", "application/json")
|
||||
.body(json_data)
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
let status = response.status();
|
||||
let body_bytes = response
|
||||
.bytes()
|
||||
.await
|
||||
.context("failed to read error response body")?;
|
||||
|
||||
assert_equal!(status, 413, "Should be too large");
|
||||
assert_equal!(
|
||||
&*body_bytes,
|
||||
b"Failed to buffer the request body: length limit exceeded"
|
||||
);
|
||||
|
||||
daemon.stop_both().await.context("stop_both")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Asserts that request_body_limit is effective and has a
|
||||
/// known response when using compressed requests
|
||||
#[tokio::test]
|
||||
async fn http_inject_size_limit_compressed() -> anyhow::Result<()> {
|
||||
let mut daemon = DaemonWithMaildir::start()
|
||||
.await
|
||||
.context("DaemonWithMaildir::start")?;
|
||||
|
||||
let content = MailGenParams {
|
||||
// Ask for 2MB of mail body. The overall request
|
||||
// size will therefore be > 2MB, which is the
|
||||
// default value of `request_body_limit` set
|
||||
// in the http listener.
|
||||
size: Some(2 * 1024 * 1024),
|
||||
..Default::default()
|
||||
}
|
||||
.generate()?;
|
||||
|
||||
let payload = serde_json::json!({
|
||||
"envelope_sender": "sender@example.com",
|
||||
"recipients": [
|
||||
{
|
||||
"email": "user@example.com",
|
||||
"name": "Test User"
|
||||
}
|
||||
],
|
||||
"content": content,
|
||||
});
|
||||
|
||||
let json_data = serde_json::to_vec(&payload)?;
|
||||
|
||||
// Compress with gzip
|
||||
use flate2::write::GzEncoder;
|
||||
use flate2::Compression;
|
||||
use std::io::Write;
|
||||
let mut encoder = GzEncoder::new(Vec::new(), Compression::default());
|
||||
encoder.write_all(&json_data)?;
|
||||
let compressed_data = encoder.finish()?;
|
||||
|
||||
eprintln!(
|
||||
"Original size: {}, Compressed size: {}",
|
||||
json_data.len(),
|
||||
compressed_data.len()
|
||||
);
|
||||
|
||||
let client = reqwest::Client::new();
|
||||
let response = client
|
||||
.post(&format!(
|
||||
"http://{}/api/inject/v1",
|
||||
daemon.source.listener("http")
|
||||
))
|
||||
.header("Content-Encoding", "gzip")
|
||||
.header("Content-Type", "application/json")
|
||||
.body(compressed_data)
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
let status = response.status();
|
||||
let body_bytes = response
|
||||
.bytes()
|
||||
.await
|
||||
.context("failed to read error response body")?;
|
||||
|
||||
// We still expect the 2MB limit to apply, even though compression
|
||||
// means that we sent only about 600KB on the wire.
|
||||
assert_equal!(status, 413, "Should be too large");
|
||||
assert_equal!(
|
||||
&*body_bytes,
|
||||
b"Failed to buffer the request body: length limit exceeded"
|
||||
);
|
||||
|
||||
daemon.stop_both().await.context("stop_both")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -15,6 +15,7 @@ mod end_to_end_webhook_batch;
|
||||
mod expires;
|
||||
mod http_auth;
|
||||
mod http_inject_compression;
|
||||
mod http_inject_size_limit;
|
||||
mod log_oob_arf;
|
||||
mod maildir_batch;
|
||||
mod maildir_batch_452;
|
||||
|
||||
@@ -2,9 +2,13 @@
|
||||
|
||||
{{since('2024.06.10-84e84b89')}}
|
||||
|
||||
Specifies the maximum acceptable size of an incoming HTTP request, in bytes.
|
||||
The default is 2MB.
|
||||
Specifies the maximum acceptable size of an incoming HTTP request, *after*
|
||||
decompressing any compressed body, in bytes. This option limits the RAM
|
||||
usage rather than the wire usage.
|
||||
|
||||
The default limit is 2MB.
|
||||
|
||||
If an incoming request exceeds this limit, a `413 Payload Too Large` HTTP
|
||||
response will be returned.
|
||||
response will be returned, with the body `Failed to buffer the request body:
|
||||
length limit exceeded`.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user