feat: std.http read buffers grow on demand toward read_buf_cap
read_buf_cap is now the per-request LIMIT, not a preallocation: slots start at 16K, double when full (one-step sizing when a Content-Length declares the body), and keep their grown capacity for slot reuse. At the limit the refusal distinguishes oversized headers (431) from an oversized body (413). Unblocks A1: distd accepts multi-hundred-MB artifact uploads — preallocating that per slot was never an option. examples/1633 adds a body past the initial capacity echoing intact.
This commit is contained in:
@@ -155,6 +155,34 @@ main :: () -> i32 {
|
||||
socket.close(c2);
|
||||
print("404 routing ok\n");
|
||||
|
||||
// ── 5b. a body past READ_BUF_INITIAL forces the buffer to grow ────
|
||||
big_n := 50000;
|
||||
payload : [*]u8 = xx context.allocator.alloc_bytes(xx big_n);
|
||||
f := 0;
|
||||
while f < big_n { payload[f] = 97 + cast(u8)(f % 26); f += 1; }
|
||||
breq := concat("POST /echo HTTP/1.1\r\nHost: t\r\nContent-Length: ", concat(int_to_string(big_n), "\r\n\r\n"));
|
||||
breq = concat(breq, string.{ ptr = payload, len = xx big_n });
|
||||
c2b := dial();
|
||||
if c2b < 0 { print("dial2b failed\n"); return 1; }
|
||||
bigbuf : [*]u8 = xx context.allocator.alloc_bytes(xx (big_n + 4096));
|
||||
socket.write(c2b, breq.ptr, xx breq.len);
|
||||
btotal : i64 = 0;
|
||||
btries := 0;
|
||||
while btries < 2000 {
|
||||
srv.tick(5) catch {};
|
||||
bn, bre := socket.read_nb(c2b, @bigbuf[btotal], xx (big_n + 4096 - btotal));
|
||||
if !bre { btotal += bn; }
|
||||
else if bre == error.Closed { break; }
|
||||
if resp_complete(bigbuf, btotal) { break; }
|
||||
btries += 1;
|
||||
}
|
||||
bresp := string.{ ptr = bigbuf, len = xx btotal };
|
||||
if !contains(bresp, "HTTP/1.1 200 OK") { print("case5b: big echo not 200\n"); return 1; }
|
||||
if !contains(bresp, concat("Content-Length: ", int_to_string(big_n))) { print("case5b: wrong echo length\n"); return 1; }
|
||||
if bigbuf[btotal - 1] != 97 + cast(u8)((big_n - 1) % 26) { print("case5b: tail byte wrong\n"); return 1; }
|
||||
socket.close(c2b);
|
||||
print("big body grows the buffer and echoes intact\n");
|
||||
|
||||
// ── 6. half a header is evicted at the request deadline, while a
|
||||
// healthy client keeps being served ──────────────────────────
|
||||
c3 := dial();
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -917,6 +917,9 @@ declare void @Server.run(ptr, ptr) #0
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.accept_ready(ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i1 @Server.grow_read_buf(ptr, ptr, i64, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.read_more(ptr, ptr, i64) #0
|
||||
|
||||
|
||||
@@ -1409,6 +1409,9 @@ declare void @Server.run(ptr, ptr) #0
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.accept_ready(ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i1 @Server.grow_read_buf(ptr, ptr, i64, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.read_more(ptr, ptr, i64) #0
|
||||
|
||||
|
||||
@@ -1425,6 +1425,9 @@ declare void @Server.run(ptr, ptr) #0
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.accept_ready(ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i1 @Server.grow_read_buf(ptr, ptr, i64, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.read_more(ptr, ptr, i64) #0
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1401,6 +1401,9 @@ declare void @Server.run(ptr, ptr) #0
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.accept_ready(ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i1 @Server.grow_read_buf(ptr, ptr, i64, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.read_more(ptr, ptr, i64) #0
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1427,6 +1427,9 @@ declare void @Server.run(ptr, ptr) #0
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.accept_ready(ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i1 @Server.grow_read_buf(ptr, ptr, i64, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.read_more(ptr, ptr, i64) #0
|
||||
|
||||
|
||||
@@ -1403,6 +1403,9 @@ declare void @Server.run(ptr, ptr) #0
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.accept_ready(ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i1 @Server.grow_read_buf(ptr, ptr, i64, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.read_more(ptr, ptr, i64) #0
|
||||
|
||||
|
||||
@@ -1401,6 +1401,9 @@ declare void @Server.run(ptr, ptr) #0
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.accept_ready(ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i1 @Server.grow_read_buf(ptr, ptr, i64, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.read_more(ptr, ptr, i64) #0
|
||||
|
||||
|
||||
@@ -1401,6 +1401,9 @@ declare void @Server.run(ptr, ptr) #0
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.accept_ready(ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i1 @Server.grow_read_buf(ptr, ptr, i64, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.read_more(ptr, ptr, i64) #0
|
||||
|
||||
|
||||
@@ -1401,6 +1401,9 @@ declare void @Server.run(ptr, ptr) #0
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.accept_ready(ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i1 @Server.grow_read_buf(ptr, ptr, i64, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.read_more(ptr, ptr, i64) #0
|
||||
|
||||
|
||||
@@ -1401,6 +1401,9 @@ declare void @Server.run(ptr, ptr) #0
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.accept_ready(ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i1 @Server.grow_read_buf(ptr, ptr, i64, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.read_more(ptr, ptr, i64) #0
|
||||
|
||||
|
||||
@@ -1401,6 +1401,9 @@ declare void @Server.run(ptr, ptr) #0
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.accept_ready(ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i1 @Server.grow_read_buf(ptr, ptr, i64, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.read_more(ptr, ptr, i64) #0
|
||||
|
||||
|
||||
@@ -1401,6 +1401,9 @@ declare void @Server.run(ptr, ptr) #0
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.accept_ready(ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i1 @Server.grow_read_buf(ptr, ptr, i64, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.read_more(ptr, ptr, i64) #0
|
||||
|
||||
|
||||
@@ -1401,6 +1401,9 @@ declare void @Server.run(ptr, ptr) #0
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.accept_ready(ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i1 @Server.grow_read_buf(ptr, ptr, i64, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.read_more(ptr, ptr, i64) #0
|
||||
|
||||
|
||||
@@ -1401,6 +1401,9 @@ declare void @Server.run(ptr, ptr) #0
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.accept_ready(ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i1 @Server.grow_read_buf(ptr, ptr, i64, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.read_more(ptr, ptr, i64) #0
|
||||
|
||||
|
||||
@@ -924,6 +924,9 @@ declare void @Server.run(ptr, ptr) #0
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.accept_ready(ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i1 @Server.grow_read_buf(ptr, ptr, i64, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.read_more(ptr, ptr, i64) #0
|
||||
|
||||
|
||||
@@ -3,5 +3,6 @@ keep-alive reuse ok
|
||||
request cap: close + EOF
|
||||
POST echo ok
|
||||
404 routing ok
|
||||
big body grows the buffer and echoes intact
|
||||
slow client evicted, healthy client served
|
||||
http server ok
|
||||
|
||||
Reference in New Issue
Block a user