summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrew Clayton <a.clayton@nginx.com>2024-01-29 11:35:13 +0000
committerAndrew Clayton <a.clayton@nginx.com>2024-02-21 16:20:32 +0000
commitac3a54d67181bb8bfbe6753058941c91dd200c63 (patch)
tree80ffa344a4405d8551e484c781b4d289a9c6b2c1
parent79c817724799a3c6ce88693b188926b4e626807f (diff)
downloadunit-ac3a54d67181bb8bfbe6753058941c91dd200c63.tar.gz
unit-ac3a54d67181bb8bfbe6753058941c91dd200c63.tar.bz2
Wasm-wc: Improve request buffer handling
When Unit receives a request, if the body of that request is greater than a certain amount (16KiB by default) then it is written to a temporary file. When a language module goes to read the request body in such situations it will end up using read(2). The wasm-wasi-component language module was failing to properly read request bodies of around 2GiB or more. This is because (on Linux at least) read(2) (and other related system calls) will only read (or write) at most 0x7ffff000 (2,147,479,552) bytes, this is the case for both 32 and 64-bit systems. Regardless, it's probably not a good idea doing IO in such large chunks anyway. This patch changes the wasm-wasi-component language module to read the request buffer in 32MiB chunks (this matches the original 'wasm' language module). We are still limited to a 4GiB address space and can only upload files a little under 4GiB. Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
-rw-r--r--src/wasm-wasi-component/src/lib.rs21
1 files changed, 14 insertions, 7 deletions
diff --git a/src/wasm-wasi-component/src/lib.rs b/src/wasm-wasi-component/src/lib.rs
index da78ea6e..032878f5 100644
--- a/src/wasm-wasi-component/src/lib.rs
+++ b/src/wasm-wasi-component/src/lib.rs
@@ -495,14 +495,21 @@ impl NxtRequestInfo {
fn request_read(&mut self, dst: &mut BytesMut) {
unsafe {
let rest = dst.spare_capacity_mut();
- let amt = bindings::nxt_unit_request_read(
- self.info,
- rest.as_mut_ptr().cast(),
- rest.len(),
- );
+ let mut total_bytes_read = 0;
+ loop {
+ let amt = bindings::nxt_unit_request_read(
+ self.info,
+ rest.as_mut_ptr().wrapping_add(total_bytes_read).cast(),
+ 32 * 1024 * 1024,
+ );
+ total_bytes_read += amt as usize;
+ if total_bytes_read >= rest.len() {
+ break;
+ }
+ }
// TODO: handle failure when `amt` is negative
- let amt: usize = amt.try_into().unwrap();
- dst.set_len(dst.len() + amt);
+ let total_bytes_read: usize = total_bytes_read.try_into().unwrap();
+ dst.set_len(dst.len() + total_bytes_read);
}
}